diff --git a/.gitignore b/.gitignore index cff0e374..55ad4693 100644 --- a/.gitignore +++ b/.gitignore @@ -31,6 +31,7 @@ pubspec.lock .pub-cache/ .pub/ /build/ +/ios/Frameworks/ # Web related lib/generated_plugin_registrant.dart diff --git a/Application.kt b/Application.kt new file mode 100644 index 00000000..0708653a --- /dev/null +++ b/Application.kt @@ -0,0 +1,35 @@ +//package com.cloud.diplomaticquarterapp +package com.ejada.hmg + +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) + } + + override fun registerWith(registry: PluginRegistry) { + io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin.registerWith(registry?.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin")); + } +} + +//import io.flutter.app.FlutterApplication +//import io.flutter.plugin.common.PluginRegistry +//import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback +//import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService +// +//class Application : FlutterApplication(), PluginRegistrantCallback { +// override fun onCreate() { +// super.onCreate() +// FlutterFirebaseMessagingService.setPluginRegistrant(this) +// } +// +// override fun registerWith(registry: PluginRegistry?) { +// FirebaseCloudMessagingPluginRegistrant.registerWith(registry) +// } +//} \ No newline at end of file diff --git a/Certs/Apple Pay UAT/Apple Pay UAT.zip b/Certs/Apple Pay UAT/Apple Pay UAT.zip new file mode 100644 index 00000000..fa08b99a Binary files /dev/null and b/Certs/Apple Pay UAT/Apple Pay UAT.zip differ diff --git a/Certs/Apple Pay UAT/ApplePayMerchantIdentityCertProd.certSigningRequest b/Certs/Apple Pay UAT/ApplePayMerchantIdentityCertProd.certSigningRequest new file mode 100644 index 00000000..ce03b2e3 --- /dev/null +++ b/Certs/Apple Pay UAT/ApplePayMerchantIdentityCertProd.certSigningRequest @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICajCCAVICAQAwJTEjMCEGCSqGSIb3DQEJARYUSGFyb29uNjEzOEBnbWFpbC5j +b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC4E8y9zluekbsXX6+i +HLa0GrZE+r8rJsmcNyhiONDkpCTQuuidRb4PH+DWPpxwtndKpgzPemCXavaAPY8I +vSf5/aLTzClLvuX4OqNsb9Y8v8jlt7uYud6hPYK+VKZmIyynqeHldur0+RQScVY7 +Z4MbgxWYAXd0K49o1Vj8KcYP1G37XIaUwOf+Ib3az4abnrsou7w9PSHnKREPU1A8 +syBR56/Zcm3I9e+4nLyk2kjhkp6zR8KKW3s0teqHkW+V2nqd6eU+ZwOOmP3FVuwl +X+kfVabTc42Nb7toDaIvxEI+LlrNCUTCptE5uvY+vId0bwjcL88Ti9zshPETgLd8 +F7mHAgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAQEAMTsBtXA79BL7aJoe87iHwCaR +lyOoeG5vUVJhQxhkb7pXD6TT00H3DEn43MCD+Nu9KNq3ZAARTsbnoB1MzYQ+Qs0w +uIx3K+sKKqzo3tKY78cjpKYW68qSY8QHPH8z0PJ/a18Mz1VGjhV9sanRc57fkf8Y +SfzG+jKB+y9AeC4R5PAVkv/EScZKVyb8+hFNZRMBOfnME7QRWm51MlnzfgavB/Sr +SSb9KrKzA65UKM9fv0JhNftiFVwsMDA42RuwSE7rVqzoejb47sFNnEBprt4Jel+5 +FJt/C//NKspMlW2cdRbPek7adaBuZCvEO+b0TDnvMQXnJTO5K0LCzGb5MRuGUg== +-----END CERTIFICATE REQUEST----- diff --git a/Certs/Apple Pay UAT/ApplePayPaymentProcessingCertProd.certSigningRequest b/Certs/Apple Pay UAT/ApplePayPaymentProcessingCertProd.certSigningRequest new file mode 100644 index 00000000..168f3bc9 --- /dev/null +++ b/Certs/Apple Pay UAT/ApplePayPaymentProcessingCertProd.certSigningRequest @@ -0,0 +1,8 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIH6MIGfAgEAMD0xIzAhBgkqhkiG9w0BCQEWFEhhcm9vbjYxMzhAZ21haWwuY29t +MQkwBwYDVQQDDAAxCzAJBgNVBAYTAkFFMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcD +QgAEiHGgNfm6LyD0k41YUNxGibQT5t2T9+QTVb6v5YrfCYslJIurcpeia8pzl/HJ +p1f4qxCR04cEYE3tcunyzkJd26AAMAwGCCqGSM49BAMCBQADSAAwRQIhAJWZqbmD +e9jyqPHW578V6xsf5Axgf64GBBFMpZ8+ZukDAiAYu0BbgeiU4RwCrezA71iH95yZ +ge9MoPuNHejpDKGeQQ== +-----END CERTIFICATE REQUEST----- diff --git a/Certs/Apple Pay UAT/Password.rtf b/Certs/Apple Pay UAT/Password.rtf new file mode 100644 index 00000000..aec586f3 --- /dev/null +++ b/Certs/Apple Pay UAT/Password.rtf @@ -0,0 +1,8 @@ +{\rtf1\ansi\ansicpg1252\cocoartf2758 +\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +{\*\expandedcolortbl;;} +\paperw11900\paperh16840\margl1440\margr1440\vieww11520\viewh8400\viewkind0 +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 + +\f0\fs24 \cf0 HMG@54321} \ No newline at end of file diff --git a/Certs/Apple Pay UAT/apple-developer-merchantid-domain-association.txt b/Certs/Apple Pay UAT/apple-developer-merchantid-domain-association.txt new file mode 100644 index 00000000..da84c377 --- /dev/null +++ b/Certs/Apple Pay UAT/apple-developer-merchantid-domain-association.txt @@ -0,0 +1,74 @@ +MIIQaQYJKoZIhvcNAQcCoIIQWjCCEFYCAQExCzAJBgUrDgMCGgUAMHgGCSqGSIb3DQEHAaBrBGl7 +InRlYW1JZCI6IjNBMzU5RTg2WkYiLCJkb21haW4iOiJ1YXQuaG1nd2Vic2VydmljZXMuY29tIiwi +ZGF0ZUNyZWF0ZWQiOiIyMDI1LTA0LTA5LDA4OjUzOjAzIiwidmVyc2lvbiI6MX2ggg0_MIIENDCC +AxygAwIBAgIIPVn4N-rR2J8wDQYJKoZIhvcNAQELBQAwczEtMCsGA1UEAwwkQXBwbGUgaVBob25l +IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSAwHgYDVQQLDBdDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 +eTETMBEGA1UECgwKQXBwbGUgSW5jLjELMAkGA1UEBhMCVVMwHhcNMjQxMjE2MTkyMTAxWhcNMjkx +MjExMTgxMzU5WjBZMTUwMwYDVQQDDCxBcHBsZSBpUGhvbmUgT1MgUHJvdmlzaW9uaW5nIFByb2Zp +bGUgU2lnbmluZzETMBEGA1UECgwKQXBwbGUgSW5jLjELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQDQkzGr-FMe360eL2T3yU3Xlr5fSz15ZFxD7inDQNL6LxygtrwR +c-_wIrDf3vn5zlXj9UIBtSNlQRI793xGfYkTRZVE7JaVYmaXkAMA2eCuxdmxnCAtluCF7W9r01LT +gzzUASMl6eXG1BHYeaoIwt0VWPXvipNLDUvuDbaHk3UREFXLDHgH2zdwRjuX-sTreCng9Ox442Ha +QFeAB7uInKXHSW3IJtOVH00hoo1oc4Me5llahZZVVLCVLiXcdw1hh4GNiaQDezwAdyyJalnTZETZ +dKVbirFSYV9uBDDU8-IQNAyVjEvhe9YrhYPyJzmNcAgj4hSI_5P0LW1MJuKLN4YtAgMBAAGjgeUw +geIwDAYDVR0TAQH_BAIwADAfBgNVHSMEGDAWgBRv8ZUYYlzgyPHF7WwYyeDTZFKYIDBABggrBgEF +BQcBAQQ0MDIwMAYIKwYBBQUHMAGGJGh0dHA6Ly9vY3NwLmFwcGxlLmNvbS9vY3NwMDMtYWlwY2Ew +NzAvBgNVHR8EKDAmMCSgIqAghh5odHRwOi8vY3JsLmFwcGxlLmNvbS9haXBjYS5jcmwwHQYDVR0O +BBYEFLy1xem9_MvQntyUsB74IZRc_wkuMA4GA1UdDwEB_wQEAwIHgDAPBgkqhkiG92NkBjoEAgUA +MA0GCSqGSIb3DQEBCwUAA4IBAQAyNMLpd6pf4MbKovN3WeeKZ7jxUfP7sPaXv7ERo-GhPLsjkukS +k6JxHbzxmnFvpDxvNpK24EeCopPj57iPu98lRGICz8289_uNiglweGXCGU0ly3JiIeSpaPkQmi56 +Dyi-pgMG0VVhH698-JTUcQ7i0yVUi86t1WgHW70te8diRXm5qYdM-Bg7gK4QS3HYeCvmCq-a59lN +zOpbt6OXVWvsDaB4x8Cwz8vcEEwwkhNxlNav4OzJ6cmbziUy7hENIRcki_GVLiJiRkV_4NvXFlTB +uT7T2oq5Zfa0tCN_eF3ZcnZkY6cIVcfZt5TbI7_zk6fUBERDDcriVrIrlCikPXKHMIIERDCCAyyg +AwIBAgIIXGPK5Eo3U8kwDQYJKoZIhvcNAQELBQAwYjELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkFw +cGxlIEluYy4xJjAkBgNVBAsTHUFwcGxlIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRYwFAYDVQQD +Ew1BcHBsZSBSb290IENBMB4XDTE3MDUxMDIxMjczMFoXDTMwMTIzMTAwMDAwMFowczEtMCsGA1UE +AwwkQXBwbGUgaVBob25lIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSAwHgYDVQQLDBdDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eTETMBEGA1UECgwKQXBwbGUgSW5jLjELMAkGA1UEBhMCVVMwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDJRWoBDz6DBIbH_L_cXvAege4XMHNjJi7ePXokzZM- +TzlHunW-88DS8Vmiqx_-CoY82S2aB_IOa7kpkRpfIgqL8XJYBa5MS0TFeaeAPLCI4IwMJ4RdGeWH +GTbL48V2t7D0QXJR9AVcg0uibaZRuPEm33terWUMxrKYUYy7fRtMwU7ICMfS7WQLtN0bjU9AfRuP +SJaSW_PQmH7ZvKQZDplhu0FdAcxbd3p9JNDc01P_w9zFlCy2Wk2OGCM5vdnGUj7R8vQliqEqh_3Y +DEYpUf_tF2yJJWuHv4ppFJ93n8MVt2iziEW9hOYGAkFkD60qKLgVyeCsp4q6cgQ0sniM-LKFAgMB +AAGjgewwgekwDwYDVR0TAQH_BAUwAwEB_zAfBgNVHSMEGDAWgBQr0GlHlHYJ_vRrjS5ApvdHTX8I +XjBEBggrBgEFBQcBAQQ4MDYwNAYIKwYBBQUHMAGGKGh0dHA6Ly9vY3NwLmFwcGxlLmNvbS9vY3Nw +MDMtYXBwbGVyb290Y2EwLgYDVR0fBCcwJTAjoCGgH4YdaHR0cDovL2NybC5hcHBsZS5jb20vcm9v +dC5jcmwwHQYDVR0OBBYEFG_xlRhiXODI8cXtbBjJ4NNkUpggMA4GA1UdDwEB_wQEAwIBBjAQBgoq +hkiG92NkBgISBAIFADANBgkqhkiG9w0BAQsFAAOCAQEAOs-smI2-kiAhCa2V87FcIfo2LVcgRHRz +ZJIIs5as922X-ls0OCfPEkbTPBHwB8mZkLHR6BEJpeOla2xjCD-eJfrVmZxM5uXOjrJNaOyLq6Oi +T4oRFT7cFCscxkS2b2fFW0-VKS2HXD_cgx53T-3aVKct5xOBwWPEVAsbSwpqKCII1DeSfH9nKF-v +PT-3rFkdODRkWu4zShlCRCnEyhhr4cFTLS30TcIV9jMyGHjxJm-KTeuUTKPo_w-zA4tl2usu2GVQ +n9yfit8xqIRU3FJSQdKyEx0xRkeIXz7uw_KMIwSV66yKPoJsBp8u44tDmmJbNA30mc8s7rpyhhkj +pfyOtTCCBLswggOjoAMCAQICAQIwDQYJKoZIhvcNAQEFBQAwYjELMAkGA1UEBhMCVVMxEzARBgNV +BAoTCkFwcGxlIEluYy4xJjAkBgNVBAsTHUFwcGxlIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRYw +FAYDVQQDEw1BcHBsZSBSb290IENBMB4XDTA2MDQyNTIxNDAzNloXDTM1MDIwOTIxNDAzNlowYjEL +MAkGA1UEBhMCVVMxEzARBgNVBAoTCkFwcGxlIEluYy4xJjAkBgNVBAsTHUFwcGxlIENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5MRYwFAYDVQQDEw1BcHBsZSBSb290IENBMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEA5JGpCR-R2x5HUOsF7V55hC3rNqJXTFXsixmJ3vlLbPUHqyIwAugYPvhQ +CdN_QaiY-dHKZpwkaxHQo7vkGyrDH5WeegykR4tb1BY3M8vED03OFGnRyRly9V0O1X9fm_IlA7pV +j01dDfFkNSMVSxVZHbOU9_acns9QusFYUGePCLQg98usLCBvcLY_ATCMt0PPD5098ytJKBrI_s61 +uQ7ZXhzWyz21Oq30Dw4AkguxIRYudNU8DdtiFqujcZJHU1XBry9Bs_j743DN5qNMRX4fTGtQlkGJ +xHRiCxCDQYczioGxMFjsWgQyjGizjx3eZXP_Z15lvEnYdp8zFGWhd5TJLQIDAQABo4IBejCCAXYw +DgYDVR0PAQH_BAQDAgEGMA8GA1UdEwEB_wQFMAMBAf8wHQYDVR0OBBYEFCvQaUeUdgn-9GuNLkCm +90dNfwheMB8GA1UdIwQYMBaAFCvQaUeUdgn-9GuNLkCm90dNfwheMIIBEQYDVR0gBIIBCDCCAQQw +ggEABgkqhkiG92NkBQEwgfIwKgYIKwYBBQUHAgEWHmh0dHBzOi8vd3d3LmFwcGxlLmNvbS9hcHBs +ZWNhLzCBwwYIKwYBBQUHAgIwgbYagbNSZWxpYW5jZSBvbiB0aGlzIGNlcnRpZmljYXRlIGJ5IGFu +eSBwYXJ0eSBhc3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFy +ZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRlIHBvbGljeSBhbmQgY2Vy +dGlmaWNhdGlvbiBwcmFjdGljZSBzdGF0ZW1lbnRzLjANBgkqhkiG9w0BAQUFAAOCAQEAXDaZTC14 +t-2Mm9zzd5vydtJ3ME_BH4WDhRuZPUc38qmbQI4s1LGQEti-9HOb7tJkD8t5TzTYoj75eP9ryAfs +fTmDi1Mg0zjEsb-aTwpr_yv8WacFCXwXQFYRHnTTt4sjO0ej1W8k4uvRt3DfD0XhJ8rxbXjt57UX +F6jcfiI1yiXV2Q_Wa9SiJCMR96Gsj3OBYMYbWwkvkrL4REjwYDieFfU9JmcgijNq9w2Cz97roy_5 +U2pbZMBjM3f3OgcsVuvaDyEO2rpzGU-12TZ_wYdV2aeZuTJC-9jVcZ5-oVK3G72TQiQSKscPHbZN +nF5jyEuAF1CqitXa5PzQCQc3sHV1ITGCAoUwggKBAgEBMH8wczEtMCsGA1UEAwwkQXBwbGUgaVBo +b25lIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSAwHgYDVQQLDBdDZXJ0aWZpY2F0aW9uIEF1dGhv +cml0eTETMBEGA1UECgwKQXBwbGUgSW5jLjELMAkGA1UEBhMCVVMCCD1Z-Dfq0difMAkGBSsOAwIa +BQCggdwwGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMjUwNDA5MDg1 +MzAzWjAjBgkqhkiG9w0BCQQxFgQUAFaGI1aIk0pvFl6XU5VvRpeio9QwKQYJKoZIhvcNAQk0MRww +GjAJBgUrDgMCGgUAoQ0GCSqGSIb3DQEBAQUAMFIGCSqGSIb3DQEJDzFFMEMwCgYIKoZIhvcNAwcw +DgYIKoZIhvcNAwICAgCAMA0GCCqGSIb3DQMCAgFAMAcGBSsOAwIHMA0GCCqGSIb3DQMCAgEoMA0G +CSqGSIb3DQEBAQUABIIBAHdhBvowTL1e7Q-KFo3GAoa_c3I5iQH79ks6sZ9U4zu3xhpjrReRlA5d +ORAcMvUnUT0sjDj2ISsLKzUnDXNlcPE8fqfkMI_7LYlWvnNalVtrJmL6CUheBuTKMQ_Z_lZLLI4o +J46YUzCU9M4vpcgO6EpOQTNrqLx2sOs-V_my1p-Hig7UqdHNviX4gL4xjg7yUXNoevZ9ixPLXI4C +aPmg5q2NCECPxS7g36hJ_gHtRC6awR8qvK3-mSZPPfMzh0sHih76h2RWcv13UHSNygn3SF0MLhsS +5m9tf6r1sJOCAr2_ri-65d2GN1vhGXfoXQ0KFy9N2Cao3IsRs5unBb6pk5c diff --git a/Certs/Apple Pay UAT/apple_pay.cer b/Certs/Apple Pay UAT/apple_pay.cer new file mode 100644 index 00000000..e7103ace Binary files /dev/null and b/Certs/Apple Pay UAT/apple_pay.cer differ diff --git a/Certs/Apple Pay UAT/merchant_id.cer b/Certs/Apple Pay UAT/merchant_id.cer new file mode 100644 index 00000000..66bcbab8 Binary files /dev/null and b/Certs/Apple Pay UAT/merchant_id.cer differ diff --git a/Certs/VOIP Certs/HMGVoIPCSR.certSigningRequest b/Certs/VOIP Certs/HMGVoIPCSR.certSigningRequest new file mode 100644 index 00000000..15f18c68 --- /dev/null +++ b/Certs/VOIP Certs/HMGVoIPCSR.certSigningRequest @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICgjCCAWoCAQAwPTEjMCEGCSqGSIb3DQEJARYUSGFyb29uNjEzOEBnbWFpbC5j +b20xCTAHBgNVBAMMADELMAkGA1UEBhMCQUUwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQDHadAER62mSf+wOxPu9rF1EvifDxbAEv6znZIHvwimgShdPLLS +rkFdN4VpSHMzrASqpHnlSL3wxO6eym9pATH3WfLvKIQxnn9OkO5fScjQi0RkFbe0 +JqTqN2LaFxrSFrhqQ/1p/izr690HqjrfquRI8t8evatyTku67/xcCj6uSIVLfJoS +8YCDVn0Y+w9n2Vw/+kHiNY6P96qp/CfXZgMLFpUu0mqcmZl97htfmB9AH2tC45yh +mKxDJiKEnk69zVCh/bkc9tFE1tUDkkKblJTCEyWfdDUUYM4ET3t3fBqWB78F4J3m +XglByGZmHgY2+7nsSQBiq7k9tFN2c7FZ9BD3AgMBAAGgADANBgkqhkiG9w0BAQsF +AAOCAQEAJxqoyfEJ7V83ffCAqkYNNEcCQMIRi1Y4cTTm/5KZGA/UPeDeX48/bm4K +XIf2zbv88OGASInBrvMDp0x0zs13Dx2yXxofGN+iQSBwN6jPV/upmm0DjgTmgUGh +BJste70LaU228ADzWDw8UJm/GKjK8WvE0XOGpPKYq9cuVW3M+6QRoRHXy0eJc2PX +VgopsuhHUyA5trxM7k4yc6GgYVx+fAwMaplovTwn5U8XK6bDEIvCjImfat/u4Wp8 +R31p0BQzQaeyWfpp9Ucn/fvQSeB+wtjhHuA1ukcyWY1kBYOyCMIHymFrJLaTpUj7 +aQFYZDV28HYv0yWhWIAD9Pu+aDHWpA== +-----END CERTIFICATE REQUEST----- diff --git a/Certs/VOIP Certs/VOIP.pem b/Certs/VOIP Certs/VOIP.pem new file mode 100644 index 00000000..029e2a7a --- /dev/null +++ b/Certs/VOIP Certs/VOIP.pem @@ -0,0 +1,74 @@ +Bag Attributes + friendlyName: VoIP Services: com.HMG.HMG-Smartphone + localKeyID: 70 4A 99 03 F8 D7 92 FA F7 2F DD 3B D8 BF 2C F0 BD CE 21 C8 +subject=/UID=com.HMG.HMG-Smartphone.voip/CN=VoIP Services: com.HMG.HMG-Smartphone/OU=3A359E86ZF/O=Dr Sulaiman Al Habib Medical Center/C=SA +issuer=/CN=Apple Worldwide Developer Relations Certification Authority/OU=G4/O=Apple Inc./C=US +-----BEGIN CERTIFICATE----- +MIIGkTCCBXmgAwIBAgIQFB+/PYFlrZ6SCzSX9cqOBDANBgkqhkiG9w0BAQsFADB1 +MUQwQgYDVQQDDDtBcHBsZSBXb3JsZHdpZGUgRGV2ZWxvcGVyIFJlbGF0aW9ucyBD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTELMAkGA1UECwwCRzQxEzARBgNVBAoMCkFw +cGxlIEluYy4xCzAJBgNVBAYTAlVTMB4XDTI0MDYwOTEyMDc1MVoXDTI1MDcwOTEy +MDc1MFowga0xKzApBgoJkiaJk/IsZAEBDBtjb20uSE1HLkhNRy1TbWFydHBob25l +LnZvaXAxLjAsBgNVBAMMJVZvSVAgU2VydmljZXM6IGNvbS5ITUcuSE1HLVNtYXJ0 +cGhvbmUxEzARBgNVBAsMCjNBMzU5RTg2WkYxLDAqBgNVBAoMI0RyIFN1bGFpbWFu +IEFsIEhhYmliIE1lZGljYWwgQ2VudGVyMQswCQYDVQQGEwJTQTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAMdp0ARHraZJ/7A7E+72sXUS+J8PFsAS/rOd +kge/CKaBKF08stKuQV03hWlIczOsBKqkeeVIvfDE7p7Kb2kBMfdZ8u8ohDGef06Q +7l9JyNCLRGQVt7QmpOo3YtoXGtIWuGpD/Wn+LOvr3QeqOt+q5Ejy3x69q3JOS7rv +/FwKPq5IhUt8mhLxgINWfRj7D2fZXD/6QeI1jo/3qqn8J9dmAwsWlS7SapyZmX3u +G1+YH0Afa0LjnKGYrEMmIoSeTr3NUKH9uRz20UTW1QOSQpuUlMITJZ90NRRgzgRP +e3d8GpYHvwXgneZeCUHIZmYeBjb7uexJAGKruT20U3ZzsVn0EPcCAwEAAaOCAuIw +ggLeMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUW9n6HeeaGgujmXYiUIY+kchb +d6gwcAYIKwYBBQUHAQEEZDBiMC0GCCsGAQUFBzAChiFodHRwOi8vY2VydHMuYXBw +bGUuY29tL3d3ZHJnNC5kZXIwMQYIKwYBBQUHMAGGJWh0dHA6Ly9vY3NwLmFwcGxl +LmNvbS9vY3NwMDMtd3dkcmc0MDUwggEeBgNVHSAEggEVMIIBETCCAQ0GCSqGSIb3 +Y2QFATCB/zCBwwYIKwYBBQUHAgIwgbYMgbNSZWxpYW5jZSBvbiB0aGlzIGNlcnRp +ZmljYXRlIGJ5IGFueSBwYXJ0eSBhc3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRo +ZW4gYXBwbGljYWJsZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1 +c2UsIGNlcnRpZmljYXRlIHBvbGljeSBhbmQgY2VydGlmaWNhdGlvbiBwcmFjdGlj +ZSBzdGF0ZW1lbnRzLjA3BggrBgEFBQcCARYraHR0cHM6Ly93d3cuYXBwbGUuY29t +L2NlcnRpZmljYXRlYXV0aG9yaXR5LzATBgNVHSUEDDAKBggrBgEFBQcDAjAyBgNV +HR8EKzApMCegJaAjhiFodHRwOi8vY3JsLmFwcGxlLmNvbS93d2RyZzQtNi5jcmww +HQYDVR0OBBYEFHBKmQP415L69y/dO9i/LPC9ziHIMA4GA1UdDwEB/wQEAwIHgDAQ +BgoqhkiG92NkBgMBBAIFADAQBgoqhkiG92NkBgMCBAIFADBDBgoqhkiG92NkBgME +BDUMM2NvbS5ITUcuSE1HLVNtYXJ0cGhvbmUsIGNvbS5ITUcuSE1HLVNtYXJ0cGhv +bmUudm9pcDAQBgoqhkiG92NkBgMFBAIFADAmBgoqhkiG92NkBgMDBBgMFmNvbS5I +TUcuSE1HLVNtYXJ0cGhvbmUwDQYJKoZIhvcNAQELBQADggEBAJAcIzSskk8/GbxQ +7nGUPPEWFswL66xTt3GusHmeXkKDXG3ac+4jLk8yU7gunos77CNDm+9TkShdJ2Rg +tTRopK4ockqwoPrCeEVrooHR4e42YvmkB6AfYKJRnQZQVJIpW0OES7vrtoWVGoNj +ktHOV+wFIuAQPI9P4z0RFyRw85MHr+jFqxeLU/1500PwCxIiNHkIcUtzZgrnr22R +7rgkxav+RrjLjXVQvC4VJispKCU7yR69Xv1rsC5zc7OTCuCkbQ9FvnfsiUz5ZDzp +3D0gGojU9wmJ1yVk9HiZsuiVwmg/LbDHI3pSYbxz3n1UHB6Pu0jX3c3Uxkx674HD +/0uvHzg= +-----END CERTIFICATE----- +Bag Attributes + localKeyID: 70 4A 99 03 F8 D7 92 FA F7 2F DD 3B D8 BF 2C F0 BD CE 21 C8 +Key Attributes: +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDHadAER62mSf+w +OxPu9rF1EvifDxbAEv6znZIHvwimgShdPLLSrkFdN4VpSHMzrASqpHnlSL3wxO6e +ym9pATH3WfLvKIQxnn9OkO5fScjQi0RkFbe0JqTqN2LaFxrSFrhqQ/1p/izr690H +qjrfquRI8t8evatyTku67/xcCj6uSIVLfJoS8YCDVn0Y+w9n2Vw/+kHiNY6P96qp +/CfXZgMLFpUu0mqcmZl97htfmB9AH2tC45yhmKxDJiKEnk69zVCh/bkc9tFE1tUD +kkKblJTCEyWfdDUUYM4ET3t3fBqWB78F4J3mXglByGZmHgY2+7nsSQBiq7k9tFN2 +c7FZ9BD3AgMBAAECggEBALTXH58SBcd86hS+rsgSDkJ2ruNIQsBzOWpYJjtCIi0l +ih5r0lu/TWWk2SbuXhLpF95MhILLIf18Ck4UlU5rmA2SE/6RBrkc3KS6SII/no6J +Db+Z9lu4g+wnyEyxkVAe7KTp/aGmsMROxMaTuQpnptkE8BSnuxhRKtpfksNBQzC2 +19OkEy4JAO7xWbm9w/ASiCtYf0Vj26DQo982Fe44cpG08iB2v1uUJINQkGzmg+85 +vvn5A1ECpSpgd/eOa68ojxeNSU7iFGZPbpjuincLPBFlC5zp9KD1Bt6p2KwIizBl +GPYTp6a1DnWly6n0PuLN0fl/nRmI6ar48Ja1Qzk8NvECgYEA5iQo9lnjNOHjT6bk +hj5QXMz3MDMCPdJo6jQyADtmsC/F4RjufujfXPhMv2v8JLAjQjNMgfhTSF68zYHf +i1qW8e/CgWu7mGQEIhWtxiTkLou8zW3VjxwpgfeUsGI5L+PxoN53ZUVcetLz4Y58 +8ATEhlxh02uGmG2k3HbvFu9NBT8CgYEA3dHJfFX2xv53ZD1E2IE1rM3j7a32s7VB +k/YX8ODrAJxwNmy/vm4gd5h6ofqVS1/IV4NHFbmQ5c1tzB44YGOEZH5Ta9hhHgHU +xoa3q6t+kjR9KrQvxjTSe9mW5x/jAgU0Wp/XrAfMZxc2eukb4/sJAGKG0kyFeX5O +5abVixWj7kkCgYAafd8ZPI+i7r2z1YpIybOGezGZIsYHR8k77HY1AKF5doZYuv35 +LeVIVmy/PDbyIjRs0mrkKymrEvy4y1JoQC1P/EFvlG8rw5eWNNikDmsV0JATNal3 +p84/X7iF9UiP8rVFx1YHGkzi9pWMSVKobmQQ82FvbNk5gqWPm0E6aqF7EQKBgQDB +mE0PlT9SIdk1xTuG8g5UiUV6tS/xXCql5kyy0LqJx/8voO4gV6FCf/PX1wnhxPDn +YA30agaKaiZ/1YhCp9hulMpd/3WTaOm5cu5uh7hqBiGP2b8wb/2cViWcBnpr0vsE +dSkYXZ4KA3pq/3R2HyyWB2e/t0Vu6cwWJuuM/hAa8QKBgGNRStNVSMPvzx2X7mB6 +EqdlWqVbfSTHJiZKyNPWHlSuZgdQ14BRwq7KZ0ysZy+kOX4rh1rIfqzrKc62xEXB +E+fmIpu+DUOM5ojEPCf9Om87r3fMJ54SjM7z1dtVc+Muy4TnFZ4UQcN9txWbnkAo +++H5gC9DBedOEXkwoCYjoeuM +-----END PRIVATE KEY----- diff --git a/Certs/VOIP Certs/p12 pass.pdf b/Certs/VOIP Certs/p12 pass.pdf new file mode 100644 index 00000000..d38d0f4e Binary files /dev/null and b/Certs/VOIP Certs/p12 pass.pdf differ diff --git a/Certs/VOIP Certs/voip_services.cer b/Certs/VOIP Certs/voip_services.cer new file mode 100644 index 00000000..a4c7342b Binary files /dev/null and b/Certs/VOIP Certs/voip_services.cer differ diff --git a/FirebaseCloudMessagingPluginRegistrant.kt b/FirebaseCloudMessagingPluginRegistrant.kt new file mode 100644 index 00000000..9ac064cb --- /dev/null +++ b/FirebaseCloudMessagingPluginRegistrant.kt @@ -0,0 +1,23 @@ +//package com.cloud.diplomaticquarterapp +package com.ejada.hmg + +import io.flutter.plugin.common.PluginRegistry +import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin + +object FirebaseCloudMessagingPluginRegistrant { + fun registerWith(registry: PluginRegistry?) { + if (alreadyRegisteredWith(registry)) { + return + } + FirebaseMessagingPlugin.registerWith(registry?.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin")) + } + + private fun alreadyRegisteredWith(registry: PluginRegistry?): Boolean { + val key: String? = FirebaseCloudMessagingPluginRegistrant::class.java.canonicalName + if (registry?.hasPlugin(key)!!) { + return true + } + registry.registrarFor(key) + return false + } +} \ No newline at end of file diff --git a/Google Play Signing Certs/deployment_cert.der b/Google Play Signing Certs/deployment_cert.der new file mode 100644 index 00000000..46c10c23 Binary files /dev/null and b/Google Play Signing Certs/deployment_cert.der differ diff --git a/Google Play Signing Certs/upload_cert.der b/Google Play Signing Certs/upload_cert.der new file mode 100644 index 00000000..46c10c23 Binary files /dev/null and b/Google Play Signing Certs/upload_cert.der differ diff --git a/GoogleService-Info.plist b/GoogleService-Info.plist deleted file mode 100644 index 0c093a2a..00000000 --- a/GoogleService-Info.plist +++ /dev/null @@ -1,36 +0,0 @@ - - - - - CLIENT_ID - 864393916058-ekeb4s8tgfo58dutv0l54399t7ivr06r.apps.googleusercontent.com - REVERSED_CLIENT_ID - com.googleusercontent.apps.864393916058-ekeb4s8tgfo58dutv0l54399t7ivr06r - API_KEY - AIzaSyA_6ayGCk4fly7o7eTVBrj9kuHBYHMAOfs - GCM_SENDER_ID - 864393916058 - PLIST_VERSION - 1 - BUNDLE_ID - com.cloud.diplomaticquarterapp - PROJECT_ID - diplomaticquarter-d2385 - STORAGE_BUCKET - diplomaticquarter-d2385.appspot.com - IS_ADS_ENABLED - - IS_ANALYTICS_ENABLED - - IS_APPINVITE_ENABLED - - IS_GCM_ENABLED - - IS_SIGNIN_ENABLED - - GOOGLE_APP_ID - 1:864393916058:ios:13f787bbfe6051f8b97923 - DATABASE_URL - https://diplomaticquarter-d2385.firebaseio.com - - \ No newline at end of file diff --git a/PatientAppAPNSAuthKey.p8 b/PatientAppAPNSAuthKey.p8 new file mode 100755 index 00000000..0515964e --- /dev/null +++ b/PatientAppAPNSAuthKey.p8 @@ -0,0 +1,6 @@ +-----BEGIN PRIVATE KEY----- +MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgJ5XRSnefd1apSG/z +YJTQ55ffLMlPgKlGM9edg88mUZagCgYIKoZIzj0DAQehRANCAATSA2MbS+J0cQsc +uBU0xaoxOUgGvnHCQSEK4t22i8eeKPPhH6RHJhK1ugPvj+Eyadf7j6pn3QRonEJu +mIL+qvqC +-----END PRIVATE KEY----- \ No newline at end of file diff --git a/android/CustomFlutterFirebaseMessagingService.java b/android/CustomFlutterFirebaseMessagingService.java index 0a4d83be..113f256f 100644 --- a/android/CustomFlutterFirebaseMessagingService.java +++ b/android/CustomFlutterFirebaseMessagingService.java @@ -2,14 +2,33 @@ package io.flutter.plugins.firebasemessaging; import android.content.Intent; +import java.util.concurrent.TimeUnit; + import com.google.firebase.messaging.RemoteMessage; +//public class CustomFlutterFirebaseMessagingService extends FlutterFirebaseMessagingService { +// @Override +// public void onMessageReceived(RemoteMessage remoteMessage) { +// if (remoteMessage.getData().containsKey("is_call")) { +// Intent intent = getPackageManager().getLaunchIntentForPackage(getPackageName()); +// startActivity(intent); +// super.onMessageReceived(remoteMessage); +// } else +// super.onMessageReceived(remoteMessage); +// } +//} + public class CustomFlutterFirebaseMessagingService extends FlutterFirebaseMessagingService { @Override public void onMessageReceived(RemoteMessage remoteMessage) { if (remoteMessage.getData().containsKey("is_call")) { Intent intent = getPackageManager().getLaunchIntentForPackage(getPackageName()); + intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); startActivity(intent); + try { + TimeUnit.SECONDS.sleep(5); + } catch (Exception e) { + } super.onMessageReceived(remoteMessage); } else super.onMessageReceived(remoteMessage); diff --git a/android/FlutterFirebaseMessagingReceiver.java b/android/FlutterFirebaseMessagingReceiver.java new file mode 100644 index 00000000..8226a09b --- /dev/null +++ b/android/FlutterFirebaseMessagingReceiver.java @@ -0,0 +1,114 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package io.flutter.plugins.firebase.messaging; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.util.Log; + +import java.util.Timer; +import java.util.TimerTask; + +import androidx.localbroadcastmanager.content.LocalBroadcastManager; + +import com.google.firebase.messaging.RemoteMessage; + +import java.util.HashMap; +import java.util.concurrent.TimeUnit; + +public class FlutterFirebaseMessagingReceiver extends BroadcastReceiver { + private static final String TAG = "FLTFireMsgReceiver"; + static HashMap notifications = new HashMap<>(); + + @Override + public void onReceive(Context context, Intent intent) { + Log.d(TAG, "broadcast received for message"); + if (ContextHolder.getApplicationContext() == null) { + ContextHolder.setApplicationContext(context.getApplicationContext()); + } + + if (intent.getExtras() == null) { + Log.d( + TAG, + "broadcast received but intent contained no extras to process RemoteMessage. Operation cancelled."); + return; + } + + RemoteMessage remoteMessage = new RemoteMessage(intent.getExtras()); + + // Store the RemoteMessage if the message contains a notification payload. + if (remoteMessage.getNotification() != null) { + notifications.put(remoteMessage.getMessageId(), remoteMessage); + FlutterFirebaseMessagingStore.getInstance().storeFirebaseMessage(remoteMessage); + } + + // |-> --------------------- + // App in Foreground + // ------------------------ + if (FlutterFirebaseMessagingUtils.isApplicationForeground(context)) { + Intent onMessageIntent = new Intent(FlutterFirebaseMessagingUtils.ACTION_REMOTE_MESSAGE); + onMessageIntent.putExtra(FlutterFirebaseMessagingUtils.EXTRA_REMOTE_MESSAGE, remoteMessage); + LocalBroadcastManager.getInstance(context).sendBroadcast(onMessageIntent); + return; + } + + // |-> --------------------- + // App in Background/Quit + // ------------------------ + + + if (remoteMessage.getData().containsKey("is_call")) { + Intent intent12 = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName()); + intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); + context.startActivity(intent12); + try { + new Timer().schedule(new TimerTask() { + @Override + public void run() { + Intent onMessageIntent = new Intent(FlutterFirebaseMessagingUtils.ACTION_REMOTE_MESSAGE); + onMessageIntent.putExtra(FlutterFirebaseMessagingUtils.EXTRA_REMOTE_MESSAGE, remoteMessage); + LocalBroadcastManager.getInstance(context).sendBroadcast(onMessageIntent); + } + }, 5000); + } catch (Exception e) { + Log.e("AppCallingException", e.getMessage()); + } + // super.onMessageReceived(remoteMessage); + } //else + // super.onMessageReceived(remoteMessage); +// +// if (remoteMessage.getData().containsKey("is_call")) { +// Log.e("AppCalling", "started..."); +// Intent intent12 = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName()); +// intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); +// context.startActivity(intent12); +// try { +// Log.e("AppCalling", "going to sleep..."); +// TimeUnit.SECONDS.sleep(10); +// Log.e("AppCalling", "sendig to broadcast receiver..."); +// Log.e("AppCalling:DAta", remoteMessage.getData().containsKey("is_call") + ""); +// Intent onBackgroundMessageIntent = +// new Intent(context, FlutterFirebaseMessagingBackgroundService.class); +// onBackgroundMessageIntent.putExtra( +// FlutterFirebaseMessagingUtils.EXTRA_REMOTE_MESSAGE, remoteMessage); +// FlutterFirebaseMessagingBackgroundService.enqueueMessageProcessing( +// context, onBackgroundMessageIntent); +// //return; +// } catch (Exception e) { +// Log.e("AppCallingException", e.getMessage()); +// } +// +// } + + + Intent onBackgroundMessageIntent = + new Intent(context, FlutterFirebaseMessagingBackgroundService.class); + onBackgroundMessageIntent.putExtra( + FlutterFirebaseMessagingUtils.EXTRA_REMOTE_MESSAGE, remoteMessage); + FlutterFirebaseMessagingBackgroundService.enqueueMessageProcessing( + context, onBackgroundMessageIntent); + } +} 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/agconnect-services.json b/android/app/agconnect-services.json new file mode 100644 index 00000000..91aad2c7 --- /dev/null +++ b/android/app/agconnect-services.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" + } + } + ] +} diff --git a/android/app/build.gradle b/android/app/build.gradle index 11e99a2a..5136988a 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -21,39 +21,96 @@ if (flutterVersionName == null) { flutterVersionName = '1.0' } +def keystoreProperties = new Properties() +def keystorePropertiesFile = rootProject.file('key.properties') +if (keystorePropertiesFile.exists()) { + keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) +} + apply plugin: 'com.android.application' +apply plugin: 'com.huawei.agconnect' apply plugin: 'kotlin-android' apply plugin: 'com.google.gms.google-services' +//apply plugin: 'com.google.firebase.crashlytics' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +configurations.all { + c -> + c.resolutionStrategy.eachDependency { + DependencyResolveDetails dependency -> + println dependency.requested.group + if (dependency.requested.group == 'org.bouncycastle') { + dependency.useTarget 'org.bouncycastle:bcprov-jdk15to18:1.68' + } + } +} + +//configurations.all { +// resolutionStrategy { +// force 'androidx.core:core-ktx:1.6.0' +// } +//} + android { - compileSdkVersion 30 + compileSdkVersion 34 +// ndkVersion "24.0.8215888" + + buildFeatures { + viewBinding true + dataBinding true + } sourceSets { main.java.srcDirs += 'src/main/kotlin' } lintOptions { - disable 'InvalidPackage' + disable 'MissingTranslation' + checkReleaseBuilds false } + defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). - applicationId "com.cloud.diplomaticquarterapp" - minSdkVersion 21 - targetSdkVersion 30 + applicationId "com.ejada.hmg" + minSdkVersion 26 + targetSdkVersion 34 versionCode flutterVersionCode.toInteger() versionName flutterVersionName multiDexEnabled true + } + sourceSets.main { + jniLibs.srcDir 'src/main/libs' + jni.srcDirs = [] //disable automatic ndk-build call } - buildTypes { - debug {} + signingConfigs { release { - // TODO: Add your own signing config for the release build. - // Signing with the debug keys for now, so `flutter run --release` works. + keyAlias keystoreProperties['keyAlias'] + keyPassword keystoreProperties['keyPassword'] + storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null + storePassword keystoreProperties['storePassword'] + } + } + + buildTypes { + debug { + debuggable true signingConfig signingConfigs.debug + minifyEnabled false + shrinkResources false +// ndk { +// abiFilters 'arm64-v8a', 'armeabi-v7a', 'x86_64' +// } + } + release { + debuggable false + signingConfig signingConfigs.release + minifyEnabled true + shrinkResources true + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } staging { // Specifies a sorted list of fallback build types that the @@ -64,6 +121,25 @@ android { matchingFallbacks = ['debug', 'qa', 'release'] } } + + packagingOptions { + exclude 'META-INF/proguard/androidx-annotations.pro' + pickFirst 'lib/x86/libc++_shared.so' + pickFirst 'lib/x86_64/libc++_shared.so' + pickFirst 'lib/armeabi-v7a/libc++_shared.so' + pickFirst 'lib/arm64-v8a/libc++_shared.so' + pickFirst '**/*.so' + } + + + compileOptions { +// coreLibraryDesugaringEnabled true + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = '1.8' + } } flutter { @@ -71,15 +147,17 @@ flutter { } dependencies { +// coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4' + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "com.google.firebase:firebase-messaging:21.0.0" // implementation ('com.google.firebase:firebase-inappmessaging-display:19.1.2',{ // exclude group: 'com.google.protobuf',module: 'protobuf-javalite' // exclude group: 'com.google.protobuf',module: 'protobuf-lite' // }) - implementation 'pub.devrel:easypermissions:0.4.0' + implementation 'pub.devrel:easypermissions:3.0.0' // implementation 'com.google.firebase:firebase-inappmessaging-display:17.2.0' - // implementation 'com.google.firebase:firebase-inappmessaging-display:17.2.0' + // implementation 'com.google.firebase:firebase-inappmessaging-display:17.2.0' implementation 'com.google.guava:guava:27.0.1-android' // Dependency on local binaries implementation fileTree(dir: 'libs', include: ['*.jar']) @@ -89,11 +167,65 @@ dependencies { // implementation 'com.example.android:app-magic:12.3' + implementation "us.zoom.videosdk:zoomvideosdk-core:1.10.1" + implementation "us.zoom.videosdk:zoomvideosdk-annotation:1.10.1" + implementation "us.zoom.videosdk:zoomvideosdk-videoeffects:1.10.1" + // Native Dependency - implementation "org.jetbrains.anko:anko-commons:0.10.4" + +// implementation "us.zoom.videosdk:ZoomVideoSDK:1.10.11" +// implementation group: 'us.zoom.videosdk', name: 'zoomvideosdk-core', version: '1.10.11' + +// implementation "us.zoom.videosdk:zoomvideosdk-core:1.10.1" +// implementation "us.zoom.videosdk:zoomvideosdk-annotation:1.10.1" +// implementation "us.zoom.videosdk:zoomvideosdk-videoeffects:1.10.1" + + implementation 'com.squareup.okhttp3:logging-interceptor:4.9.3' + implementation 'com.squareup.retrofit2:retrofit:2.9.0' + implementation 'com.squareup.retrofit2:converter-gson:2.9.0' + implementation 'com.squareup.retrofit2:adapter-java8:2.4.0' + implementation 'com.google.code.gson:gson:2.8.9' + implementation 'com.google.android.gms:play-services-location:21.3.0' + implementation 'com.squareup.okhttp3:okhttp:4.10.0' + implementation 'androidx.test.ext:junit:1.1.5' + implementation 'com.android.volley:volley:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:2.2.0' + implementation 'androidx.navigation:navigation-fragment-ktx:2.8.5' + implementation 'androidx.navigation:navigation-ui-ktx:2.8.5' + implementation 'androidx.activity:activity:1.9.3' + def room_version = "2.4.0-alpha04" + implementation "androidx.room:room-runtime:$room_version" + annotationProcessor "androidx.room:room-compiler:$room_version" + implementation 'net.zetetic:android-database-sqlcipher:4.5.2' + implementation 'com.intuit.ssp:ssp-android:1.1.0' + implementation 'com.intuit.sdp:sdp-android:1.1.0' + implementation 'com.github.bumptech.glide:glide:4.12.0' + annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0' + +// implementation "com.mapbox.maps:android:10.16.6" + implementation 'com.mapbox.maps:android:11.3.1' + + implementation files('libs/PenNavUI.aar') + implementation files('libs/Penguin.aar') + implementation files('libs/PenguinRenderer.aar') + +// implementation "org.jetbrains.anko:anko-commons:0.10.4" implementation 'com.github.kittinunf.fuel:fuel:2.3.0' //for JVM implementation 'com.github.kittinunf.fuel:fuel-android:2.3.0' implementation 'com.google.android.gms:play-services-location:17.1.0'//for Android - 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.21.4" + implementation 'com.facebook.stetho:stetho:1.5.1' + implementation 'com.facebook.stetho:stetho-urlconnection:1.5.1' + implementation 'androidx.core:core-ktx:1.6.0' + implementation 'androidx.appcompat:appcompat:1.3.1' + implementation 'com.google.android.material:material:1.9.0' + implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.22' + androidTestImplementation "androidx.test:core:1.4.0" +// implementation 'com.airbnb.android:lottie:5.2.0' +// implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.22' + implementation 'com.whatsapp.otp:whatsapp-otp-android-sdk:0.1.0' + + implementation 'com.whatsapp.otp:whatsapp-otp-android-sdk:0.1.0' } diff --git a/android/app/google-services.json b/android/app/google-services.json index a4655794..3707617c 100644 --- a/android/app/google-services.json +++ b/android/app/google-services.json @@ -1,35 +1,42 @@ { "project_info": { - "project_number": "864393916058", - "firebase_url": "https://diplomaticquarter-d2385.firebaseio.com", - "project_id": "diplomaticquarter-d2385", - "storage_bucket": "diplomaticquarter-d2385.appspot.com" + "project_number": "815750722565", + "firebase_url": "https://api-project-815750722565.firebaseio.com", + "project_id": "api-project-815750722565", + "storage_bucket": "api-project-815750722565.appspot.com" }, "client": [ { "client_info": { - "mobilesdk_app_id": "1:864393916058:android:5b5a65cd6d8c18b4b97923", + "mobilesdk_app_id": "1:815750722565:android:62281cd3e5df4063", "android_client_info": { - "package_name": "com.cloud.diplomaticquarterapp" + "package_name": "com.ejada.hmg" } }, "oauth_client": [ { - "client_id": "864393916058-tphjrn8j39ntevt32ekcvmll8aue7qql.apps.googleusercontent.com", + "client_id": "815750722565-3a0gc7neins0eoahdrimrfksk0sqice8.apps.googleusercontent.com", "client_type": 3 } ], "api_key": [ { - "current_key": "AIzaSyBdV3mos1BPhUzNKCj2KANJtiO3o2zh9IM" + "current_key": "AIzaSyDZDeWcBlRE3YfJWYt_DCiToVnANfaj8qg" } ], "services": { "appinvite_service": { "other_platform_oauth_client": [ { - "client_id": "864393916058-tphjrn8j39ntevt32ekcvmll8aue7qql.apps.googleusercontent.com", + "client_id": "815750722565-3a0gc7neins0eoahdrimrfksk0sqice8.apps.googleusercontent.com", "client_type": 3 + }, + { + "client_id": "815750722565-0cq9366orvsk5ipivq6lijcj56u03fr7.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "com.void.demo" + } } ] } diff --git a/android/app/gradle/wrapper/gradle-wrapper.properties b/android/app/gradle/wrapper/gradle-wrapper.properties index 8fc3bbec..a2c20300 100644 --- a/android/app/gradle/wrapper/gradle-wrapper.properties +++ b/android/app/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip +#distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip diff --git a/android/app/key b/android/app/key new file mode 100644 index 00000000..15b9f5d1 Binary files /dev/null and b/android/app/key differ diff --git a/flutter_tts-voice_enhancement/ios/Assets/.gitkeep b/android/app/keystores/keystore similarity index 100% rename from flutter_tts-voice_enhancement/ios/Assets/.gitkeep rename to android/app/keystores/keystore diff --git a/android/app/libs/PenNavUI.aar b/android/app/libs/PenNavUI.aar new file mode 100644 index 00000000..d423bc11 Binary files /dev/null and b/android/app/libs/PenNavUI.aar differ diff --git a/android/app/libs/Penguin.aar b/android/app/libs/Penguin.aar new file mode 100644 index 00000000..5c789c6f Binary files /dev/null and b/android/app/libs/Penguin.aar differ diff --git a/android/app/libs/PenguinRenderer.aar b/android/app/libs/PenguinRenderer.aar new file mode 100644 index 00000000..b657ac66 Binary files /dev/null and b/android/app/libs/PenguinRenderer.aar differ diff --git a/android/app/proguard-rules.pro b/android/app/proguard-rules.pro index 4ace459d..ab7b2ca4 100644 --- a/android/app/proguard-rules.pro +++ b/android/app/proguard-rules.pro @@ -1,4 +1,72 @@ -keep class tvi.webrtc.** { *; } -keep class com.twilio.video.** { *; } -keep class com.twilio.common.** { *; } --keepattributes InnerClasses \ No newline at end of file +-keepattributes InnerClasses + +-keep class com.ejada.** { *; } +-keep class org.webrtc.** { *; } + +-keep class com.builttoroam.devicecalendar.** { *; } + +-ignorewarnings +-keepattributes *Annotation* +-keepattributes Exceptions +-keepattributes InnerClasses +-keepattributes Signature +-keep class com.hianalytics.android.**{*;} +-keep class com.huawei.updatesdk.**{*;} +-keep class com.huawei.hms.**{*;} + +## Flutter wrapper +-keep class io.flutter.app.** { *; } +-keep class io.flutter.plugin.** { *; } +-keep class io.flutter.util.** { *; } +-keep class io.flutter.view.** { *; } +-keep class io.flutter.** { *; } +-keep class io.flutter.plugins.** { *; } +-dontwarn io.flutter.embedding.** +-keep class com.huawei.hms.flutter.** { *; } +-repackageclasses + +## Flutter WebRTC +-keep class com.cloudwebrtc.webrtc.** { *; } +-keep class org.webrtc.** { *; } + +## Flutter OpenTok +-keep class com.opentok.android.** { *; } +-keep class com.opentok.otc.** { *; } +-keep class org.otwebrtc.** { *; } + + +##Flutter Zoom +-keep class us.zoom**{ + *; +} +-keep interface us.zoom**{ + *; +} +-keep class org.webrtc**{ + *; +} +-keep class com.zipow**{ + *; +} + +-dontwarn com.opentok.android.** +-dontwarn com.opentok.otc.** + +-dontwarn penguin.com.pennav.Model.Navigation.NearLandmark + +-keep,includedescriptorclasses class net.sqlcipher.** { *; } +-keep,includedescriptorclasses interface net.sqlcipher.** { *; } + +-keep class retrofit2.** { *; } +-keep class okhttp3.** { *; } +-dontwarn retrofit2.** + +-keep class com.google.gson.** { *; } +-dontwarn com.google.gson.** + +# Penguin classes +-keep class com.peng.pennavmap.models.** { *; } +-keep class com.peng.pennavmap.db.** { *; } \ No newline at end of file diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml index d8fd4e88..6c937f09 100644 --- a/android/app/src/debug/AndroidManifest.xml +++ b/android/app/src/debug/AndroidManifest.xml @@ -1,7 +1,7 @@ + package="com.ejada.hmg"> - + \ No newline at end of file diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 1a3d4cfe..e9bc7171 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,112 +1,273 @@ + - - + FlutterApplication and put your custom class here. + --> + + + + + + + + + + + + + - + + + + + + + + + + + + + + - + + + + + + - - + + + + - - - - + + + + + + + + + + + - - + + + + tools:replace="android:extractNativeLibs,android:label"> + + + + + + + + - + to determine the Window background behind the Flutter UI. + --> - + Flutter's first frame. + --> + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + - - + + - - - - - - + - - + - + + + + + + + + - + - - - - - - - + + + + + + + + - - - - - - + \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/Application.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/Application.kt new file mode 100644 index 00000000..e179bc6a --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/Application.kt @@ -0,0 +1,59 @@ +//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.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) { + // io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin.registerWith(registry?.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin")); + } +} + +//import io.flutter.app.FlutterApplication +//import io.flutter.plugin.common.PluginRegistry +//import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback +//import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService +// +//class Application : FlutterApplication(), PluginRegistrantCallback { +// override fun onCreate() { +// super.onCreate() +// FlutterFirebaseMessagingService.setPluginRegistrant(this) +// } +// +// override fun registerWith(registry: PluginRegistry?) { +// FirebaseCloudMessagingPluginRegistrant.registerWith(registry) +// } +//} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/FirebaseCloudMessagingPluginRegistrant.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/FirebaseCloudMessagingPluginRegistrant.kt new file mode 100644 index 00000000..df471796 --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/FirebaseCloudMessagingPluginRegistrant.kt @@ -0,0 +1,25 @@ +//package com.cloud.diplomaticquarterapp +package com.ejada.hmg + +import io.flutter.plugin.common.PluginRegistry +//import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin + +object FirebaseCloudMessagingPluginRegistrant { + fun registerWith(registry: PluginRegistry?) { + if (alreadyRegisteredWith(registry)) { + return + } + // FirebaseMessagingPlugin.registerWith(registry?.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin")) + } + + private fun alreadyRegisteredWith(registry: PluginRegistry?): Boolean { + val key: String? = FirebaseCloudMessagingPluginRegistrant::class.java.canonicalName + if (key?.let { registry?.hasPlugin(it) }!!) { + return true + } + if (registry != null) { + registry.registrarFor(key) + } + return false + } +} \ No newline at end of file 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 e67f646f..c874ea4d 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/MainActivity.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/MainActivity.kt @@ -1,30 +1,73 @@ -package com.cloud.diplomaticquarterapp -import android.os.Bundle +package com.ejada.hmg +import android.app.PendingIntent +import android.content.Intent +import android.content.pm.PackageManager +import android.os.Build import android.util.Log +import android.view.WindowManager import androidx.annotation.NonNull; -import com.cloud.diplomaticquarterapp.utils.* +import androidx.annotation.RequiresApi +import com.cloud.diplomaticquarterapp.PenguinInPlatformBridge +import com.cloud.diplomaticquarterapp.whatsapp.AppSignatureRetriever +import com.ejada.hmg.utils.* import io.flutter.embedding.android.FlutterFragmentActivity - import io.flutter.embedding.engine.FlutterEngine -import io.flutter.plugin.common.MethodChannel +import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugins.GeneratedPluginRegistrant +import com.cloud.diplomaticquarterapp.whatsapp.WhatsApp +import com.cloud.diplomaticquarterapp.whatsapp.WhatsAppOtpPlatformBridge + class MainActivity: FlutterFragmentActivity() { + @RequiresApi(Build.VERSION_CODES.O) override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { - GeneratedPluginRegistrant.registerWith(flutterEngine); - // Create Flutter Platform Bridge - PlatformBridge(flutterEngine.dartExecutor.binaryMessenger, this).create() - - val time = timeToMillis("04:00:00", "HH:mm:ss") - print(time) - -// val d1 = Logs.list(this) -// val d2 = Logs.raw(this) -// val d3 = Logs.RegisterGeofence.list(this) -// val d4 = Logs.RegisterGeofence.raw(this) -// val d5 = Logs.GeofenceEvent.list(this) -// val d6 = Logs.GeofenceEvent.raw(this) - print("") - } + GeneratedPluginRegistrant.registerWith(flutterEngine); + // Create Flutter Platform Bridge + this.window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON or WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD or WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON) + + PlatformBridge(flutterEngine, this).create() + OpenTokPlatformBridge(flutterEngine, this).create() + PenguinInPlatformBridge(flutterEngine, this).create() + WhatsAppOtpPlatformBridge(flutterEngine, this).invoke() + AppSignatureRetriever().logSignatures(this) +// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {x +// val mChannel = NotificationChannel("video_call_noti", "video call", NotificationManager.IMPORTANCE_HIGH) +// val soundUri = Uri.parse("android.resource://" + getApplicationContext() +// .getPackageName() + "/" + R.raw.alert) +// System.out.println("soundUri"); +// System.out.println("soundUri: $soundUri"); +// System.out.println("soundUri : ${soundUri.path}"); +// val att = AudioAttributes.Builder() +// .setUsage(AudioAttributes.USAGE_NOTIFICATION) +// .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH) +// .build(); +// mChannel.setSound(soundUri , att) +// mChannel.description = "Video Call Notifications" +// val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager +// notificationManager.createNotificationChannel(mChannel) +// } + +// val time = timeToMillis("04:00:00", "HH:mm:ss") + + } + override fun onRequestPermissionsResult( + requestCode: Int, + permissions: Array, + grantResults: IntArray + ) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + + val granted = grantResults.all { it == PackageManager.PERMISSION_GRANTED } + val intent = Intent("PERMISSION_RESULT_ACTION").apply { + putExtra("PERMISSION_GRANTED", granted) + } + sendBroadcast(intent) + + // Log the request code and permission results + Log.d("PermissionsResult", "Request Code: $requestCode") + Log.d("PermissionsResult", "Permissions: ${permissions.joinToString()}") + Log.d("PermissionsResult", "Grant Results: ${grantResults.joinToString()}") + + } override fun onResume() { super.onResume() diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PenguinInPlatformBridge.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PenguinInPlatformBridge.kt new file mode 100644 index 00000000..373ed06a --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PenguinInPlatformBridge.kt @@ -0,0 +1,53 @@ +package com.cloud.diplomaticquarterapp + +import com.ejada.hmg.MainActivity +import android.os.Build +import android.util.Log +import androidx.annotation.RequiresApi +import com.cloud.diplomaticquarterapp.penguin.PenguinView +import io.flutter.embedding.engine.FlutterEngine +import io.flutter.plugin.common.MethodCall +import io.flutter.plugin.common.MethodChannel + +class PenguinInPlatformBridge( + private var flutterEngine: FlutterEngine, + private var mainActivity: MainActivity +) { + + private lateinit var channel: MethodChannel + + companion object { + private const val CHANNEL = "launch_penguin_ui" + } + + @RequiresApi(Build.VERSION_CODES.O) + fun create() { +// openTok = OpenTok(mainActivity, flutterEngine) + channel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL) + channel.setMethodCallHandler { call: MethodCall, result: MethodChannel.Result -> + when (call.method) { + "launchPenguin" -> { + print("the platform channel is being called") + val args = call.arguments as Map? + Log.d("TAG", "configureFlutterEngine: $args") + println("args") + args?.let { + PenguinView( + mainActivity, + 100, + args, + flutterEngine.dartExecutor.binaryMessenger, + activity = mainActivity, + channel + ) + } + } + + else -> { + result.notImplemented() + } + } + } + } + +} diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PermissionManager/PermissionHelper.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PermissionManager/PermissionHelper.kt new file mode 100644 index 00000000..b308af05 --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PermissionManager/PermissionHelper.kt @@ -0,0 +1,28 @@ +package com.cloud.diplomaticquarterapp.PermissionManager + +import android.Manifest +import android.os.Build + +object PermissionHelper { + + fun getRequiredPermissions(): Array { + val permissions = mutableListOf( + Manifest.permission.INTERNET, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_NETWORK_STATE, + Manifest.permission.BLUETOOTH, + Manifest.permission.BLUETOOTH_ADMIN, +// Manifest.permission.ACTIVITY_RECOGNITION + ) + + // For Android 12 (API level 31) and above, add specific permissions + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { // Android 12 (API 31) and above + permissions.add(Manifest.permission.BLUETOOTH_SCAN) + permissions.add(Manifest.permission.BLUETOOTH_CONNECT) + permissions.add(Manifest.permission.HIGH_SAMPLING_RATE_SENSORS) + } + + return permissions.toTypedArray() + } +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PermissionManager/PermissionManager.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PermissionManager/PermissionManager.kt new file mode 100644 index 00000000..81f2a6f0 --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PermissionManager/PermissionManager.kt @@ -0,0 +1,50 @@ +package com.cloud.diplomaticquarterapp.PermissionManager + +import android.app.Activity +import android.content.Context +import android.content.pm.PackageManager +import android.os.Build +import androidx.core.app.ActivityCompat +import androidx.core.content.ContextCompat + +class PermissionManager( + private val context: Context, + val listener: PermissionListener, + private val requestCode: Int, + vararg permissions: String +) { + + private val permissionsArray = permissions + + interface PermissionListener { + fun onPermissionGranted() + fun onPermissionDenied() + } + + fun arePermissionsGranted(): Boolean { + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + permissionsArray.all { + ContextCompat.checkSelfPermission(context, it) == PackageManager.PERMISSION_GRANTED + } + } else { + true + } + } + + fun requestPermissions(activity: Activity) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + ActivityCompat.requestPermissions(activity, permissionsArray, requestCode) + } + } + + fun handlePermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { + if (this.requestCode == requestCode) { + val allGranted = grantResults.all { it == PackageManager.PERMISSION_GRANTED } + if (allGranted) { + listener.onPermissionGranted() + } else { + listener.onPermissionDenied() + } + } + } +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PermissionManager/PermissionResultReceiver.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PermissionManager/PermissionResultReceiver.kt new file mode 100644 index 00000000..33765192 --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PermissionManager/PermissionResultReceiver.kt @@ -0,0 +1,15 @@ +package com.cloud.diplomaticquarterapp.PermissionManager + +// PermissionResultReceiver.kt +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent + +class PermissionResultReceiver( + private val callback: (Boolean) -> Unit +) : BroadcastReceiver() { + override fun onReceive(context: Context?, intent: Intent?) { + val granted = intent?.getBooleanExtra("PERMISSION_GRANTED", false) ?: false + callback(granted) + } +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/bkp_files/CustomFlutterHmsMessageService.java b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/bkp_files/CustomFlutterHmsMessageService.java new file mode 100644 index 00000000..c96a60af --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/bkp_files/CustomFlutterHmsMessageService.java @@ -0,0 +1,56 @@ +/* +* --------------- +* Note: Todo +* --------------- +* Need to be place in huawei_push (package com.huawei.hms.flutter.push.hms) and define in huawei_push manifest.xml +* */ + +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.util.Log; + +import com.huawei.hms.flutter.push.hms.FlutterHmsMessageService; +import com.huawei.hms.flutter.push.utils.ApplicationUtils; + +import org.json.JSONObject; + +//package com.huawei.hms.flutter.push.hms +// +// +//import android.content.Context; +//import android.content.Intent; +//import android.content.SharedPreferences; +// +//import com.huawei.hms.flutter.push.hms.FlutterHmsMessageService; +//import com.huawei.hms.flutter.push.utils.ApplicationUtils; +//import com.huawei.hms.push.RemoteMessage; +// +//import org.json.JSONObject; +// +//public class CustomFlutterHmsMessageService extends FlutterHmsMessageService { +// @Override +// public void onMessageReceived(RemoteMessage remoteMessage) { +// super.onMessageReceived(remoteMessage); +// try { +// String jsonStr = remoteMessage.getData(); +// JSONObject json_data = new JSONObject(jsonStr); +// JSONObject json_data_data = new JSONObject(json_data.getString("data")); +// if(json_data_data.getString("is_call").equalsIgnoreCase("true")){ +// boolean isApplicationInForeground = ApplicationUtils.isApplicationInForeground(this); +// if(!isApplicationInForeground){ +// SharedPreferences preferences = getSharedPreferences("FlutterSharedPreferences", Context.MODE_PRIVATE); +// preferences.edit().putString("flutter.call_data", json_data.getString("data")).apply(); +// +// Intent intent = getPackageManager().getLaunchIntentForPackage(getPackageName()); +// intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); +// startActivity(intent); +// Log.v("onMessageReceived", "startActivity(intent) called"); +// } +// } +// +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +//} diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeoZoneModel.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeoZoneModel.kt index b3fb4f56..16ed0939 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeoZoneModel.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeoZoneModel.kt @@ -1,4 +1,4 @@ -package com.cloud.diplomaticquarterapp.geofence +package com.ejada.hmg.geofence import com.google.android.gms.location.Geofence import com.google.gson.Gson diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/HMG_Geofence.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/HMG_Geofence.kt index 840075eb..8452a083 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/HMG_Geofence.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/HMG_Geofence.kt @@ -1,4 +1,4 @@ -package com.cloud.diplomaticquarterapp.geofence +package com.ejada.hmg.geofence import android.Manifest import android.app.PendingIntent @@ -8,9 +8,9 @@ import android.content.SharedPreferences import android.content.pm.PackageManager import android.location.Location import androidx.core.content.ContextCompat -import com.cloud.diplomaticquarterapp.geofence.intent_receivers.GeofenceBroadcastReceiver -import com.cloud.diplomaticquarterapp.geofence.intent_receivers.ReregisterGeofenceJobService -import com.cloud.diplomaticquarterapp.utils.* +import com.ejada.hmg.geofence.intent_receivers.GeofenceBroadcastReceiver +import com.ejada.hmg.geofence.intent_receivers.ReregisterGeofenceJobService +import com.ejada.hmg.utils.* import com.google.android.gms.location.Geofence import com.google.android.gms.location.GeofencingClient import com.google.android.gms.location.GeofencingRequest @@ -30,12 +30,12 @@ enum class GeofenceTransition(val value: Int) { fun fromInt(value: Int) = GeofenceTransition.values().first { it.value == value } } - fun named():String{ - if (value == 1)return "Enter" - if (value == 2)return "Exit" - if (value == 4)return "dWell" - if (value == (ENTER.value or EXIT.value))return "Enter or Exit" - if (value == (DWELL.value or EXIT.value))return "DWell or Exit" + fun named(): String { + if (value == 1) return "Enter" + if (value == 2) return "Exit" + if (value == 4) return "dWell" + if (value == (ENTER.value or EXIT.value)) return "Enter or Exit" + if (value == (DWELL.value or EXIT.value)) return "DWell or Exit" return "unknown" } } @@ -44,63 +44,65 @@ class HMG_Geofence { // https://developer.android.com/training/location/geofencing#java private lateinit var context: Context - private lateinit var preferences:SharedPreferences + private lateinit var preferences: SharedPreferences private val gson = Gson() - private lateinit var geofencingClient:GeofencingClient + private lateinit var geofencingClient: GeofencingClient private val geofencePendingIntent: PendingIntent by lazy { val intent = Intent(context, GeofenceBroadcastReceiver::class.java) PendingIntent.getBroadcast( - context, - 0, - intent, - PendingIntent.FLAG_UPDATE_CURRENT) + context, + 0, + intent, + PendingIntent.FLAG_IMMUTABLE + ) } - companion object{ + companion object { var instance: HMG_Geofence? = null - fun shared(context: Context) : HMG_Geofence { - if (instance == null) { + fun shared(context: Context): HMG_Geofence { + if (instance == null) { instance = HMG_Geofence() instance?.context = context instance?.geofencingClient = LocationServices.getGeofencingClient(context) - instance?.preferences = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE) + instance?.preferences = + context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE) } - return instance!! + return instance!! } } - fun limitize(zones: List):List{ + private fun limitize(zones: List): List { var geoZones_ = zones - if(zones.size > 100) + if (zones.size > 100) geoZones_ = zones.subList(0, 99) return geoZones_ } - fun register(completion:((Boolean, java.lang.Exception?)->Unit)){ + fun register(completion: ((Boolean, java.lang.Exception?) -> Unit)) { unRegisterAll { status, exception -> val geoZones = getGeoZonesFromPreference(context) - doRegister(geoZones){ status_, error -> + doRegister(geoZones) { status_, error -> completion.let { it(status_, error) } } } } - fun unRegisterAll(completion: (status: Boolean, exception: Exception?) -> Unit){ + fun unRegisterAll(completion: (status: Boolean, exception: Exception?) -> Unit) { getActiveGeofences({ success -> removeActiveGeofences() - if(success.isNotEmpty()) + if (success.isNotEmpty()) geofencingClient - .removeGeofences(success) - .addOnSuccessListener { - completion(true, null) - } - .addOnFailureListener { - completion(false, it) - saveLog(context, "error:REMOVE_GEOFENCES", it.localizedMessage) - } + .removeGeofences(success) + .addOnSuccessListener { + completion(true, null) + } + .addOnFailureListener { + completion(false, it) + saveLog(context, "error:REMOVE_GEOFENCES", it.localizedMessage) + } else completion(true, null) @@ -109,7 +111,10 @@ class HMG_Geofence { }) } - private fun doRegister(geoZones: List, completion:((Boolean, java.lang.Exception?)->Unit)? = null){ + private fun doRegister( + geoZones: List, + completion: ((Boolean, java.lang.Exception?) -> Unit)? = null + ) { if (geoZones.isEmpty()) return @@ -117,9 +122,9 @@ class HMG_Geofence { fun buildGeofencingRequest(geofences: List): GeofencingRequest { return GeofencingRequest.Builder() - .setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_DWELL) - .addGeofences(geofences) - .build() + .setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_DWELL) + .addGeofences(geofences) + .build() } getActiveGeofences({ active -> @@ -135,26 +140,41 @@ class HMG_Geofence { if (checkPermission() && geofences.isNotEmpty()) { geofencingClient - .addGeofences(buildGeofencingRequest(geofences), geofencePendingIntent) - .addOnSuccessListener { - Logs.RegisterGeofence.save(context,"SUCCESS", "Successfuly registered the geofences", Logs.STATUS.SUCCESS) - saveActiveGeofence(geofences.map { it.requestId }, listOf()) - completion?.let { it(true,null) } - } - .addOnFailureListener { exc -> - Logs.RegisterGeofence.save(context,"FAILED_TO_REGISTER", "Failed to register geofence",Logs.STATUS.ERROR) - completion?.let { it(false,exc) } - } + .addGeofences(buildGeofencingRequest(geofences), geofencePendingIntent) + .addOnSuccessListener { + Logs.RegisterGeofence.save( + context, + "SUCCESS", + "Successfuly registered the geofences", + Logs.STATUS.SUCCESS + ) + saveActiveGeofence(geofences.map { it.requestId }, listOf()) + completion?.let { it(true, null) } + } + .addOnFailureListener { exc -> + Logs.RegisterGeofence.save( + context, + "FAILED_TO_REGISTER", + "Failed to register geofence", + Logs.STATUS.ERROR + ) + completion?.let { it(false, exc) } + } // Schedule the job to register after specified duration (due to: events not calling after long period.. days or days [Needs to register fences again]) - HMGUtils.scheduleJob(context, ReregisterGeofenceJobService::class.java,ReregisterGeofenceJobService.JobID, ReregisterGeofenceJobService.TriggerIntervalDuration) + HMGUtils.scheduleJob( + context, + ReregisterGeofenceJobService::class.java, + ReregisterGeofenceJobService.JobID, + ReregisterGeofenceJobService.TriggerIntervalDuration + ) } }, null) } - fun getGeoZonesFromPreference(context: Context):List{ + fun getGeoZonesFromPreference(context: Context): List { val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE) val json = pref.getString(PREF_KEY_HMG_ZONES, "[]") @@ -162,26 +182,29 @@ class HMG_Geofence { return geoZones } - fun saveActiveGeofence(success: List, failed: List){ + fun saveActiveGeofence(success: List, failed: List) { val jsonSuccess = gson.toJson(success) val jsonFailure = gson.toJson(failed) preferences.edit().putString(PREF_KEY_SUCCESS, jsonSuccess).apply() preferences.edit().putString(PREF_KEY_FAILED, jsonFailure).apply() } - fun removeActiveGeofences(){ + fun removeActiveGeofences() { preferences.edit().putString(PREF_KEY_SUCCESS, "[]").apply() preferences.edit().putString(PREF_KEY_FAILED, "[]").apply() } - fun getActiveGeofences(success: (success: List) -> Unit, failure: ((failed: List) -> Unit)?){ - val type = object : TypeToken?>() {}.type + fun getActiveGeofences( + success: (success: List) -> Unit, + failure: ((failed: List) -> Unit)? + ) { + val type = object : TypeToken?>() {}.type val jsonSuccess = preferences.getString(PREF_KEY_SUCCESS, "[]") val success = gson.fromJson>(jsonSuccess, type) success(success) - if(failure != null){ + if (failure != null) { val jsonFailure = preferences.getString(PREF_KEY_FAILED, "[]") val failed = gson.fromJson>(jsonFailure, type) failure(failed) @@ -189,47 +212,74 @@ class HMG_Geofence { } - private fun checkPermission() : Boolean{ - return ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED + private fun checkPermission(): Boolean { + return ContextCompat.checkSelfPermission( + context, + Manifest.permission.ACCESS_FINE_LOCATION + ) == PackageManager.PERMISSION_GRANTED } - fun getPatientID():Int?{ + fun getPatientID(): Int? { var profileJson = preferences.getString("flutter.imei-user-data", null) if (profileJson == null) profileJson = preferences.getString("flutter.user-profile", null) val type = object : TypeToken?>() {}.type return gson.fromJson?>(profileJson, type) - ?.get("PatientID") - .toString() - .toDoubleOrNull() - ?.toInt() + ?.get("PatientID") + .toString() + .toDoubleOrNull() + ?.toInt() } - fun handleEvent(triggerGeofences: List, location: Location, transition: GeofenceTransition) { + fun handleEvent( + triggerGeofences: List, + location: Location, + transition: GeofenceTransition + ) { getPatientID()?.let { patientId -> getActiveGeofences({ activeGeofences -> triggerGeofences.forEach { geofence -> // Extract PointID from 'geofence.requestId' and find from active geofences - val pointID = activeGeofences.firstOrNull { it == geofence.requestId }?.split('_')?.first() + val pointID = + activeGeofences.firstOrNull { it == geofence.requestId }?.split('_') + ?.first() if (!pointID.isNullOrEmpty() && pointID.toIntOrNull() != null) { val body = mutableMapOf( - "PointsID" to pointID.toIntOrNull(), - "GeoType" to transition.value, - "PatientID" to patientId + "PointsID" to pointID.toIntOrNull(), + "GeoType" to transition.value, + "PatientID" to patientId ) body.putAll(HMGUtils.defaultHTTPParams(context)) httpPost>(API.LOG_GEOFENCE, body, { response -> - saveLog(context, "HMG_GEOFENCE_NOTIFY", "Success: Notified to server\uD83D\uDE0E.") - sendNotification(context, transition.named(), geofence.requestId, "Notified to server.😎") + saveLog( + context, + "HMG_GEOFENCE_NOTIFY", + "Success: Notified to server\uD83D\uDE0E." + ) + sendNotification( + context, + transition.named(), + geofence.requestId, + "Notified to server.😎" + ) }, { exception -> val errorMessage = "${transition.named()}, ${geofence.requestId}" - saveLog(context, "HMG_GEOFENCE_NOTIFY", "failed: $errorMessage | error: ${exception.localizedMessage}") - sendNotification(context, transition.named(), geofence.requestId, "Failed to notify server😔 -> ${exception.localizedMessage}") + saveLog( + context, + "HMG_GEOFENCE_NOTIFY", + "failed: $errorMessage | error: ${exception.localizedMessage}" + ) + sendNotification( + context, + transition.named(), + geofence.requestId, + "Failed to notify server😔 -> ${exception.localizedMessage}" + ) }) } diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiver.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiver.kt index 77df1572..2ed2daf4 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiver.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiver.kt @@ -1,49 +1,71 @@ +package com.ejada.hmg.geofence.intent_receivers - -package com.cloud.diplomaticquarterapp.geofence.intent_receivers - +import android.annotation.SuppressLint import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.util.Log -import com.cloud.diplomaticquarterapp.geofence.GeofenceTransition -import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence -import com.cloud.diplomaticquarterapp.utils.Logs +import com.ejada.hmg.geofence.GeofenceTransition +import com.ejada.hmg.geofence.HMG_Geofence +import com.ejada.hmg.utils.Logs import com.google.android.gms.location.GeofenceStatusCodes import com.google.android.gms.location.GeofencingEvent class GeofenceBroadcastReceiver : BroadcastReceiver() { - private val LOG_TAG = "GeofenceBroadcastReceiver" - override fun onReceive(context: Context, intent: Intent) { - - val geofencingEvent = GeofencingEvent.fromIntent(intent) - if (geofencingEvent.hasError()) { - val errorMessage = GeofenceErrorMessages.getErrorString(context, geofencingEvent.errorCode) - Log.e(LOG_TAG, errorMessage) - - Logs.GeofenceEvent.save(context,LOG_TAG,"Error while triggering geofence event",Logs.STATUS.ERROR) - doReRegisterIfRequired(context,geofencingEvent.errorCode) - - return - } + private val LOG_TAG = "GeofenceBroadcastReceiver" + + @SuppressLint("LongLogTag") + override fun onReceive(context: Context, intent: Intent) { + + val geofencingEvent = GeofencingEvent.fromIntent(intent) + if (geofencingEvent != null) { + if (geofencingEvent.hasError()) { + val errorMessage = + GeofenceErrorMessages.getErrorString(context, geofencingEvent.errorCode) + Log.e(LOG_TAG, errorMessage) - Logs.GeofenceEvent.save(context,LOG_TAG,"Geofence event triggered: ${GeofenceTransition.fromInt(geofencingEvent.geofenceTransition).value} for ${geofencingEvent.triggeringGeofences.map {it.requestId}}",Logs.STATUS.SUCCESS) - HMG_Geofence.shared(context).handleEvent(geofencingEvent.triggeringGeofences,geofencingEvent.triggeringLocation, GeofenceTransition.fromInt(geofencingEvent.geofenceTransition)); - - } + Logs.GeofenceEvent.save( + context, + LOG_TAG, + "Error while triggering geofence event", + Logs.STATUS.ERROR + ) + doReRegisterIfRequired(context, geofencingEvent.errorCode) - fun doReRegisterIfRequired(context: Context, errorCode: Int){ - val errorRequiredReregister = listOf( + return + } + } + if (geofencingEvent != null) { + Logs.GeofenceEvent.save( + context, + LOG_TAG, + "Geofence event triggered: ${GeofenceTransition.fromInt(geofencingEvent.geofenceTransition).value} for ${geofencingEvent.triggeringGeofences?.map { it.requestId }}", + Logs.STATUS.SUCCESS + ) + geofencingEvent.triggeringLocation?.let { + geofencingEvent.triggeringGeofences?.let { it1 -> + HMG_Geofence.shared(context).handleEvent( + it1, + it, GeofenceTransition.fromInt(geofencingEvent.geofenceTransition) + ) + } + } + }; + + } + + fun doReRegisterIfRequired(context: Context, errorCode: Int) { + val errorRequiredReregister = listOf( GeofenceStatusCodes.GEOFENCE_NOT_AVAILABLE, GeofenceStatusCodes.GEOFENCE_TOO_MANY_GEOFENCES, GeofenceStatusCodes.GEOFENCE_TOO_MANY_PENDING_INTENTS, GeofenceStatusCodes.GEOFENCE_REQUEST_TOO_FREQUENT - ) + ) - if(errorRequiredReregister.contains(errorCode)) - HMG_Geofence.shared(context).register(){ status, error -> + if (errorRequiredReregister.contains(errorCode)) + HMG_Geofence.shared(context).register() { status, error -> - } + } - } + } } \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiverWithJobService.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiverWithJobService.kt index a9924ca1..4e4f19ff 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiverWithJobService.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiverWithJobService.kt @@ -1,11 +1,11 @@ -package com.cloud.diplomaticquarterapp.geofence.intent_receivers +package com.ejada.hmg.geofence.intent_receivers import android.content.BroadcastReceiver import android.content.Context import android.content.Intent -import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence +import com.ejada.hmg.geofence.HMG_Geofence import com.google.android.gms.location.GeofenceStatusCodes class GeofenceBroadcastReceiverWithJobService : BroadcastReceiver() { diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceErrorMessages.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceErrorMessages.kt index 01377d49..94ceaa3d 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceErrorMessages.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceErrorMessages.kt @@ -1,10 +1,10 @@ -package com.cloud.diplomaticquarterapp.geofence.intent_receivers +package com.ejada.hmg.geofence.intent_receivers import android.content.Context -import com.cloud.diplomaticquarterapp.R -import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence +import com.ejada.hmg.R +import com.ejada.hmg.geofence.HMG_Geofence import com.google.android.gms.common.api.ApiException import com.google.android.gms.location.GeofenceStatusCodes diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceTransitionsJobIntentService.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceTransitionsJobIntentService.kt index 214957cf..b083e04e 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceTransitionsJobIntentService.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceTransitionsJobIntentService.kt @@ -29,15 +29,15 @@ */ -package com.cloud.diplomaticquarterapp.geofence.intent_receivers +package com.ejada.hmg.geofence.intent_receivers import android.content.Context import android.content.Intent import android.util.Log import androidx.core.app.JobIntentService -import com.cloud.diplomaticquarterapp.geofence.GeofenceTransition -import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence -import com.cloud.diplomaticquarterapp.utils.saveLog +import com.ejada.hmg.geofence.GeofenceTransition +import com.ejada.hmg.geofence.HMG_Geofence +import com.ejada.hmg.utils.saveLog import com.google.android.gms.location.GeofenceStatusCodes import com.google.android.gms.location.GeofencingEvent @@ -59,18 +59,25 @@ class GeofenceTransitionsJobIntentService : JobIntentService() { override fun onHandleWork(intent: Intent) { val geofencingEvent = GeofencingEvent.fromIntent(intent) - if (geofencingEvent.hasError()) { - val errorMessage = GeofenceErrorMessages.getErrorString(context_!!, geofencingEvent.errorCode) - Log.e(LOG_TAG, errorMessage) + if (geofencingEvent != null) { + if (geofencingEvent.hasError()) { + val errorMessage = GeofenceErrorMessages.getErrorString(context_!!, geofencingEvent.errorCode) + Log.e(LOG_TAG, errorMessage) - saveLog(context_!!,LOG_TAG,errorMessage) - doReRegisterIfRequired(context_!!, geofencingEvent.errorCode) + saveLog(context_!!,LOG_TAG,errorMessage) + doReRegisterIfRequired(context_!!, geofencingEvent.errorCode) - return - } + return + } + } - HMG_Geofence.shared(context_!!).handleEvent(geofencingEvent.triggeringGeofences,geofencingEvent.triggeringLocation, GeofenceTransition.fromInt(geofencingEvent.geofenceTransition)); + if (geofencingEvent != null) { + geofencingEvent.triggeringGeofences?.let { geofencingEvent.triggeringLocation?.let { it1 -> + HMG_Geofence.shared(context_!!).handleEvent(it, + it1, GeofenceTransition.fromInt(geofencingEvent.geofenceTransition)) + } } + }; } diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofencingRebootBroadcastReceiver.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofencingRebootBroadcastReceiver.kt index 6421b327..809f92bc 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofencingRebootBroadcastReceiver.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofencingRebootBroadcastReceiver.kt @@ -1,12 +1,12 @@ -package com.cloud.diplomaticquarterapp.geofence.intent_receivers +package com.ejada.hmg.geofence.intent_receivers import android.content.BroadcastReceiver import android.content.Context import android.content.Intent -import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence -import com.cloud.diplomaticquarterapp.utils.PREFS_STORAGE +import com.ejada.hmg.geofence.HMG_Geofence +import com.ejada.hmg.utils.PREFS_STORAGE class GeofencingRebootBroadcastReceiver : BroadcastReceiver(){ override fun onReceive(context: Context, intent: Intent) { diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/LocationProviderChangeReceiver.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/LocationProviderChangeReceiver.kt index 273ca8f5..8c34dedb 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/LocationProviderChangeReceiver.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/LocationProviderChangeReceiver.kt @@ -1,14 +1,14 @@ -package com.cloud.diplomaticquarterapp.geofence.intent_receivers +package com.ejada.hmg.geofence.intent_receivers import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.location.LocationManager -import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence -import com.cloud.diplomaticquarterapp.utils.HMGUtils -import com.cloud.diplomaticquarterapp.utils.PREFS_STORAGE +import com.ejada.hmg.geofence.HMG_Geofence +import com.ejada.hmg.utils.HMGUtils +import com.ejada.hmg.utils.PREFS_STORAGE class LocationProviderChangeReceiver : BroadcastReceiver() { private val LOG_TAG = "LocationProviderChangeReceiver" diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/ReregisterGeofenceJobService.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/ReregisterGeofenceJobService.kt index 0bc496bc..e7c0a82d 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/ReregisterGeofenceJobService.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/ReregisterGeofenceJobService.kt @@ -1,9 +1,9 @@ -package com.cloud.diplomaticquarterapp.geofence.intent_receivers +package com.ejada.hmg.geofence.intent_receivers import android.app.job.JobParameters import android.app.job.JobService -import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence -import com.cloud.diplomaticquarterapp.utils.Logs +import com.ejada.hmg.geofence.HMG_Geofence +import com.ejada.hmg.utils.Logs class ReregisterGeofenceJobService : JobService(){ companion object{ diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/HMG_Guest.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/HMG_Guest.kt index 61433596..7b3cc2d1 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/HMG_Guest.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/HMG_Guest.kt @@ -1,26 +1,29 @@ -package com.cloud.diplomaticquarterapp.hmgwifi +package com.ejada.hmg.hmgwifi +import android.annotation.SuppressLint import android.content.Context -import android.net.ConnectivityManager -import android.net.wifi.WifiConfiguration -import android.net.wifi.WifiInfo -import android.net.wifi.WifiManager +import android.content.Intent +import android.net.* +import android.net.wifi.* import android.os.Build +import android.os.PatternMatcher +import android.provider.Settings import android.util.Log -import android.widget.Toast -import com.cloud.diplomaticquarterapp.MainActivity -import com.cloud.diplomaticquarterapp.utils.FlutterText -import com.cloud.diplomaticquarterapp.utils.HMGUtils +import androidx.annotation.RequiresApi +import com.ejada.hmg.MainActivity +import com.ejada.hmg.utils.HMGUtils -class HMG_Guest(context: MainActivity) { - private var wifiManager: WifiManager? = context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager? - private var connectivityManager: ConnectivityManager? = context.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager? - private var context = context + + +class HMG_Guest(private var context: MainActivity, ssid: String) { private val TAG = "HMG_Guest" private val TEST = false - private var SSID = """"HMG-MobileApp"""" + private var SSID = ssid +// private var SSID = "HMG-MOHEMM" + + val wifiManager = context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager? private lateinit var completionListener: ((status: Boolean, message: String) -> Unit) @@ -28,126 +31,189 @@ class HMG_Guest(context: MainActivity) { completionListener(status, message) } + fun enableWifi(){ + if(Build.VERSION.SDK_INT < Build.VERSION_CODES.Q){ + wifiManager?.setWifiEnabled(true) + HMGUtils.popFlutterText(context,"enablingWifi"); + HMGUtils.timer(2000,false){ + connectApiLessThen29() + } + }else { + val panelIntent = Intent(Settings.Panel.ACTION_WIFI) + context.startActivityForResult(panelIntent, 1) + } + } /* * Helpful: * http://stackoverflow.com/questions/8818290/how-to-connect-to-a-specific-wifi-network-in-android-programmatically */ fun connectToHMGGuestNetwork(completion: (status: Boolean, message: String) -> Unit) { + completionListener = completion wifiManager?.let { wm -> - completionListener = completion - if (!wm.isWifiEnabled){ - wm.isWifiEnabled = true - HMGUtils.popFlutterText(context,"enablingWifi"); + enableWifi() + }else{ + connectWifi() + } + } + + } + + private fun errorConnecting(){ + completionOnUiThread(false, "errorConnectingHmgNetwork") + } + + fun connectWifi(){ + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q){ + connectApiGreaterThen28() + }else { + connectApiLessThen29() + } + } + + // I }else{f CompileSDK is greater and equals to APILevel 29 + @RequiresApi(Build.VERSION_CODES.Q) + private fun connectApiGreaterThen28(){ + Log.e(TAG, "connection wifi with Android Q+") + + val networkRequest: NetworkRequest = NetworkRequest.Builder() + .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) + .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED) + .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) //removeCapability added for hotspots without internet + .setNetworkSpecifier( + WifiNetworkSpecifier.Builder() + .setSsid(SSID) + .build() + + ).build() + + val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + val networkCallback = object : ConnectivityManager.NetworkCallback() { + override fun onAvailable(network: Network) { + super.onAvailable(network) + connectivityManager.bindProcessToNetwork(network) HMGUtils.timer(2000,false){ - connect() + completionListener(true, "Success") } - }else{ - connect() + Log.e(TAG, "onAvailable") + } + + override fun onLosing(network: Network, maxMsToLive: Int) { + super.onLosing(network, maxMsToLive) + Log.e(TAG, "onLosing") + completionListener(false, "fail") + } + + override fun onLost(network: Network) { + super.onLost(network) + Log.e(TAG, "onLosing") + Log.e(TAG, "losing active connection") + completionListener(false, "fail") + } + + override fun onUnavailable() { + super.onUnavailable() + Log.e(TAG, "onUnavailable") + completionListener(false, "fail") } } + //timeout add because "No devices found" wasn't handled correct and doesn't throw Unavailable + connectivityManager.requestNetwork(networkRequest, networkCallback, 30000) } - private fun connect(){ - val security = "OPEN" - val networkPass = "" - Log.d(TAG, "Connecting to SSID \"$SSID\" with password \"$networkPass\" and with security \"$security\" ...") - // You need to create WifiConfiguration instance like this: - val conf = WifiConfiguration() - conf.SSID = SSID - conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE) - conf.networkId = ssidToNetworkId(SSID) + fun connectApiLessThen29(){ + val wifi = WifiConfiguration() + wifi.SSID = """"$SSID"""" + wifi.status = WifiConfiguration.Status.ENABLED + wifi.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE) - val wm = wifiManager!! - - if (conf.networkId == -1) { - wm.addNetwork(conf) + wifi.networkId = ssidToNetworkId(wifi.SSID) + if (wifi.networkId == -1) { + wifiManager?.addNetwork(wifi) } else { Log.v(TAG, "WiFi found - updating it.\n") - wm.updateNetwork(conf) + wifiManager?.updateNetwork(wifi) } - conf.networkId = ssidToNetworkId(SSID) - Log.d(TAG, "Network ID: ${conf.networkId}") + Log.v(TAG, "saving config.\n") + wifiManager?.saveConfiguration() + + wifi.networkId = ssidToNetworkId(wifi.SSID) - val networkIdToConnect = conf.networkId + Log.v(TAG, "wifi ID in device = " + wifi.networkId) + + var supState: SupplicantState + val networkIdToConnect = wifi.networkId if (networkIdToConnect >= 0) { - Log.v(TAG, "Start connecting to $SSID Wifi...") + Log.v(TAG, "Start connecting...\n") // We disable the network before connecting, because if this was the last connection before // a disconnect(), this will not reconnect. - wm.disableNetwork(networkIdToConnect) - val result = wm.enableNetwork(networkIdToConnect, true) - if(result){ - HMGUtils.timer(8000,false){ - if(wm.getConnectionInfo().getSSID() == SSID){ - completionOnUiThread(true, "successConnectingHmgNetwork") - - }else{ - errorConnecting() - } - } - - }else{ - errorConnecting() - } + wifiManager?.disableNetwork(networkIdToConnect) + wifiManager?.enableNetwork(networkIdToConnect, true) + val wifiInfo: WifiInfo = wifiManager!!.connectionInfo + HMGUtils.timer(5000,false){ + supState = wifiInfo.supplicantState + Log.i(TAG, "Done connect to network : status = $supState") + val successStates = listOf(SupplicantState.COMPLETED, SupplicantState.ASSOCIATED) + if (successStates.contains(supState)) + completionListener(true,"Connected to internet Wifi") + else + completionListener(false,"errorConnectingHmgNetwork") + } - }else{ - Log.v(TAG, "Cannot connect to $SSID network") - errorConnecting() + } else { + Log.v(TAG, "WifiWizard: cannot connect to network") + completionListener(false,"errorConnectingHmgNetwork") } - } - - private fun errorConnecting(){ - completionOnUiThread(false, "errorConnectingHmgNetwork") - } - // If CompileSDK is greater and equals to APILevel 29 - private fun connectNewer(wm:WifiManager){ - -// Log.e(TAG, "connection wifi Q") +// val wifi = WifiConfiguration() +// wifi.SSID = SSID +// wifi.status = WifiConfiguration.Status.ENABLED +// wifi.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); // -// val wifiNetworkSpecifier: WifiNetworkSpecifier = WifiNetworkSpecifier.Builder() -// .setSsid(ssid) -// .setWpa2Passphrase(password) -// .build() +// wifi.networkId = ssidToNetworkId(SSID) // -// val networkRequest: NetworkRequest = NetworkRequest.Builder() -// .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) -// .setNetworkSpecifier(wifiNetworkSpecifier) -// .build() +// // Set network to highest priority (deprecated in API >= 26) +// if(Build.VERSION.SDK_INT < 26) { +// wifi.priority = getMaxWifiPriority(wifiManager!!) + 1; +// } // -// var connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager -// var networkCallback = object : ConnectivityManager.NetworkCallback() { -// override fun onAvailable(network: Network) { -// super.onAvailable(network) -// connectivityManager.bindProcessToNetwork(network) -// Log.e(TAG, "onAvailable") -// } +// // After processing authentication types, add or update network +// if(wifi.networkId == -1) { // -1 means SSID configuration does not exist yet // -// override fun onLosing(network: Network, maxMsToLive: Int) { -// super.onLosing(network, maxMsToLive) -// Log.e(TAG, "onLosing") -// } +// val newNetId = wifiManager?.addNetwork(wifi)!! +// if( newNetId > -1 ){ +// completionListener(true,"Success") +// } else { +// completionListener(false, "ERROR_ADDING_NETWORK" ) +// } // -// override fun onLost(network: Network) { -// super.onLost(network) -// Log.e(TAG, "onLosing") -// Log.e(TAG, "losing active connection") -// } +// } else { // -// override fun onUnavailable() { -// super.onUnavailable() -// Log.e(TAG, "onUnavailable") -// } +// var updatedNetID = wifiManager?.updateNetwork(wifi) +// +// if(updatedNetID == -1) +// updatedNetID = wifiManager?.addNetwork(wifi) +// +// if(updatedNetID > -1) { +// callbackContext.success( updatedNetID ) +// } else { +// callbackContext.error("ERROR_UPDATING_NETWORK") // } -// connectivityManager.requestNetwork(networkRequest, networkCallback) +// +// } +// +// // WifiManager configurations are presistent for API 26+ +// if(Build.VERSION.SDK_INT < 26) { +// wifiManager?.saveConfiguration(); // Call saveConfiguration for older < 26 API +// } } @@ -156,6 +222,7 @@ class HMG_Guest(context: MainActivity) { * networks, and returns the networkId for the network if the SSID matches. If not, * it returns -1. */ + @SuppressLint("MissingPermission") private fun ssidToNetworkId(ssid: String): Int { val currentNetworks = wifiManager!!.configuredNetworks var networkId = -1 @@ -169,4 +236,22 @@ class HMG_Guest(context: MainActivity) { } return networkId } -} \ No newline at end of file + + companion object{ + + /** + * Figure out what the highest priority network in the network list is and return that priority + */ + @RequiresApi(Build.VERSION_CODES.S) + fun getMaxWifiPriority(wifiManager:WifiManager) : Int { + val configurations = wifiManager.callerConfiguredNetworks + var maxPriority = 0 + configurations.forEach { + if (it.priority > maxPriority) { + maxPriority = it.priority; + } + } + return maxPriority; + } + } +} diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/HMG_Internet.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/HMG_Internet.kt index 332e60a5..dcfa5488 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/HMG_Internet.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/HMG_Internet.kt @@ -1,9 +1,8 @@ -package com.cloud.diplomaticquarterapp.hmgwifi +package com.ejada.hmg.hmgwifi import android.annotation.SuppressLint -import com.cloud.diplomaticquarterapp.utils.API -import com.cloud.diplomaticquarterapp.MainActivity -import com.cloud.diplomaticquarterapp.utils.FlutterText +import com.ejada.hmg.utils.API +import com.ejada.hmg.MainActivity import com.github.kittinunf.fuel.core.extensions.jsonBody import com.github.kittinunf.fuel.httpGet import com.github.kittinunf.fuel.httpPost @@ -14,21 +13,18 @@ import java.util.* @SuppressLint("MissingPermission") class HMG_Internet(flutterMainActivity: MainActivity) { private val TAG = "HMG_Wifi" - private val TEST = false + private val TEST = true private var context = flutterMainActivity; private lateinit var completionListener: ((status: Boolean, message: String) -> Unit) private var SSID = "GUEST-POC" - private var USER_NAME = "" - private var PASSWORD = "" fun completionOnUiThread(status: Boolean, message: String){ completionListener(status, message) // context.runOnUiThread { -// -// FlutterText.with(message){localized -> +// .with(message){localized -> // completionListener(status, localized) // } // } @@ -38,12 +34,10 @@ class HMG_Internet(flutterMainActivity: MainActivity) { * Helpful: * http://stackoverflow.com/questions/8818290/how-to-connect-to-a-specific-wifi-network-in-android-programmatically */ - fun connectToHMGGuestNetwork(patientId: String, completion: (status: Boolean, message: String) -> Unit): HMG_Internet { + fun connectToHMGGuestNetwork(username: String, password: String, completion: (status: Boolean, message: String) -> Unit): HMG_Internet { completionListener = completion - getWifiCredentials(patientId) { - WPA(context,SSID).connect(USER_NAME,PASSWORD) { status, message -> - completionOnUiThread(status,message) - } + WpaEnterprise(context,SSID).connect(username,username) { status, message -> + completionOnUiThread(status,message) } return this } @@ -66,16 +60,28 @@ class HMG_Internet(flutterMainActivity: MainActivity) { } } - private fun getWifiCredentials(patientId:String, success: (() -> Unit)){ + private fun getWifiCredentials(patientId:String, success: ((String?,String?) -> Unit)){ if (TEST){ SSID = "GUEST-POC" - USER_NAME = "0696" - PASSWORD = "0000" - success() + success("2300", "0000") return } - val jsonBody = """{"PatientID":$patientId}""" + val jsonBody = """{ + "PatientID":$patientId + "VersionID": 8.8, + "Channel": 3, + "LanguageID": 2, + "IPAdress": "10.20.10.20", + "generalid": "Cs2020@2016$2958", + "PatientOutSA": 0, + "SessionID": "@admin", + "isDentalAllowedBackend": false, + "DeviceTypeID": 2, + "TokenID": "@admin", + "PatientTypeID": 1, + "PatientType": 1 + }""".trimMargin() API.WIFI_CREDENTIALS. httpPost() .jsonBody(jsonBody, Charsets.UTF_8) @@ -92,9 +98,13 @@ class HMG_Internet(flutterMainActivity: MainActivity) { jsonObject.getJSONArray("Hmg_SMS_Get_By_ProjectID_And_PatientIDList").let { array -> array.getJSONObject(0).let { object_ -> if (object_.has("UserName") && object_.has("UserName")){ - USER_NAME = object_.getString("UserName") - PASSWORD = object_.getString("Password") - success() + try { + val userName = object_.getString("UserName") + val password = object_.getString("Password") + success(userName, password) + }catch (e:Exception){ + success(null, null) + } }else{ completionOnUiThread(false, "somethingWentWrong") } diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/WPA.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/WPA.kt index 86e67def..61cc4f9f 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/WPA.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/WPA.kt @@ -1,4 +1,4 @@ -package com.cloud.diplomaticquarterapp.hmgwifi +package com.ejada.hmg.hmgwifi import android.annotation.SuppressLint import android.content.Context @@ -7,8 +7,8 @@ import android.net.wifi.* import android.net.wifi.SupplicantState.ASSOCIATED import android.net.wifi.SupplicantState.COMPLETED import android.util.Log -import com.cloud.diplomaticquarterapp.MainActivity -import com.cloud.diplomaticquarterapp.utils.HMGUtils +import com.ejada.hmg.MainActivity +import com.ejada.hmg.utils.HMGUtils class WPA(mainActivity: MainActivity, SSID:String) { private var TAG = "WPA" diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/WpaEnterprise.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/WpaEnterprise.kt new file mode 100644 index 00000000..e8e39344 --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/WpaEnterprise.kt @@ -0,0 +1,166 @@ +package com.ejada.hmg.hmgwifi + +import android.annotation.SuppressLint +import android.content.Context +import android.net.ConnectivityManager +import android.net.Network +import android.net.NetworkCapabilities +import android.net.NetworkRequest +import android.net.wifi.* +import android.net.wifi.SupplicantState.ASSOCIATED +import android.net.wifi.SupplicantState.COMPLETED +import android.os.Build +import android.util.Log +import androidx.annotation.RequiresApi +import com.ejada.hmg.MainActivity +import com.ejada.hmg.utils.HMGUtils +import java.security.cert.X509Certificate + +class WpaEnterprise(private val mainActivity: MainActivity, private var SSID: String) { + private var TAG = "WpaEnterprise" + + private lateinit var identity:String + private lateinit var password:String + private lateinit var completion:((status: Boolean, message: String) -> Unit) + + fun connect(identity:String, password:String, completion: (status: Boolean, message: String) -> Unit) { + this.password = password + this.identity = identity + this.completion = completion + + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q){ + apiGreaterThen28() + }else if(Build.VERSION.SDK_INT < Build.VERSION_CODES.Q){ + apiLessThen29() + } + } + + @RequiresApi(Build.VERSION_CODES.LOLLIPOP) + fun apiLessThen29(){ + val wifiManager = mainActivity.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager + + val wifi = WifiConfiguration() + wifi.SSID = """"$SSID"""" + wifi.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP) + wifi.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X) + wifi.enterpriseConfig = enterpriseConfig() + wifi.networkId = ssidToNetworkId(wifi.SSID, wifiManager) + if (wifi.networkId == -1) { + wifiManager.addNetwork(wifi) + } else { + Log.v(TAG, "WiFi found - updating it.\n") + wifiManager.updateNetwork(wifi) + } + Log.v(TAG, "saving config.\n") + wifiManager.saveConfiguration() + wifi.networkId = ssidToNetworkId(wifi.SSID, wifiManager) + + Log.v(TAG, "wifi ID in device = " + wifi.networkId) + + var supState: SupplicantState + val networkIdToConnect = wifi.networkId + if (networkIdToConnect >= 0) { + Log.v(TAG, "Start connecting...\n") + + // We disable the network before connecting, because if this was the last connection before + // a disconnect(), this will not reconnect. + wifiManager.disableNetwork(networkIdToConnect) + wifiManager.enableNetwork(networkIdToConnect, true) + + val wifiInfo: WifiInfo = wifiManager.connectionInfo + + HMGUtils.timer(5000,false){ + supState = wifiInfo.supplicantState + Log.i(TAG, "Done connect to network : status = $supState") + val successStates = listOf(COMPLETED, ASSOCIATED) + if (successStates.contains(supState)) + completion(true,"Connected to internet Wifi") + else + completion(false,"errorConnectingHmgNetwork") + } + + } else { + Log.v(TAG, "WifiWizard: cannot connect to network") + completion(false,"errorConnectingHmgNetwork") + } + } + + /** + * This method takes a given String, searches the current list of configured WiFi + * networks, and returns the networkId for the network if the SSID matches. If not, + * it returns -1. + */ + @SuppressLint("MissingPermission") + private fun ssidToNetworkId(ssid: String, wifiManager: WifiManager): Int { + val currentNetworks = wifiManager.configuredNetworks + var networkId = -1 + // For each network in the list, compare the SSID with the given one + for (test in currentNetworks) { + if (test.SSID == ssid) { + networkId = test.networkId + break + } + } + return networkId + } + + + @RequiresApi(Build.VERSION_CODES.Q) + fun apiGreaterThen28(){ + val connectivityManager = mainActivity.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + + Log.e(TAG, "connection wifi with Android Q+") + val wifiNetworkSpecifier: WifiNetworkSpecifier = WifiNetworkSpecifier.Builder() + .setSsid(SSID) + .setWpa2EnterpriseConfig(enterpriseConfig()) + .build() + + val networkRequest: NetworkRequest = NetworkRequest.Builder() + .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) + .setNetworkSpecifier(wifiNetworkSpecifier) + .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) //removeCapability added for hotspots without internet + .build() + + val networkCallback = object : ConnectivityManager.NetworkCallback() { + override fun onAvailable(network: Network) { + super.onAvailable(network) + connectivityManager.bindProcessToNetwork(network) + completion(true, "200") + Log.e(TAG, "onAvailable") + } + + override fun onLosing(network: Network, maxMsToLive: Int) { + super.onLosing(network, maxMsToLive) + Log.e(TAG, "onLosing") + } + + override fun onLost(network: Network) { + super.onLost(network) + Log.e(TAG, "onLosing") + Log.e(TAG, "losing active connection") + } + + override fun onUnavailable() { + super.onUnavailable() + completion(false, "401") + Log.e(TAG, "onUnavailable") + } + + } + + //timeout add because "No devices found" wasn't handled correct and doesn't throw Unavailable + connectivityManager.requestNetwork(networkRequest, networkCallback, 30000) + } + + fun enterpriseConfig() : WifiEnterpriseConfig{ + // Initialize the WifiConfiguration object + val enterpriseConfig = WifiEnterpriseConfig() + enterpriseConfig.eapMethod = WifiEnterpriseConfig.Eap.PEAP + enterpriseConfig.identity = identity + enterpriseConfig.password = password + enterpriseConfig.phase2Method = WifiEnterpriseConfig.Phase2.NONE +// enterpriseConfig.caCertificates = WifiEnterpriseConfig.Phase2. + return enterpriseConfig; + } + +} \ No newline at end of file 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 new file mode 100644 index 00000000..5142702a --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/opentok/OpenTok.kt @@ -0,0 +1,181 @@ +package com.ejada.hmg.opentok + +import android.content.Context +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 + + +enum class OpenTokSDKState { + LOGGED_OUT, + LOGGED_IN, + WAIT, + ERROR +} + +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 + .platformViewsController + .registry + .registerViewFactory("remote-video-container", RemoteVideoFactory()) + + localVideoPlatformView = LocalVideoFactory.getViewInstance(context) + flutterEngine + .platformViewsController + .registry + .registerViewFactory("local-video-container", LocalVideoFactory()) + } + + 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) + localVideoPlatformView.container.addView(view) + } + + notifyFlutter(OpenTokSDKState.LOGGED_IN) + session.publish(publisher) + } + + override fun onDisconnected(session: Session) { + notifyFlutter(OpenTokSDKState.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) + + remoteVideoPlatformView.container.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 + + remoteVideoPlatformView.container.removeAllViews() + } + } + + override fun onError(session: Session, opentokError: OpentokError) { + Log.d("MainActivity", "Session error: " + opentokError.message) + notifyFlutter(OpenTokSDKState.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(OpenTokSDKState.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(OpenTokSDKState.LOGGED_OUT) + } + + override fun onError(subscriberKit: SubscriberKit, opentokError: OpentokError) { + Log.d("MainActivity", "SubscriberKit onError: " + opentokError.message) + notifyFlutter(OpenTokSDKState.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(OpenTokSDKState.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(true) + } + + fun toggleAudio(call: MethodCall, result: MethodChannel.Result) { + if (publisher != null) { + publisher?.publishAudio = !(publisher!!.publishAudio) + result.success(true) + }else{ + result.success(false) + } + } + + fun toggleVideo(call: MethodCall, result: MethodChannel.Result) { + if (publisher != null) { + publisher?.publishVideo = !(publisher!!.publishVideo) + result.success(true) + }else{ + result.success(false) + } + } + + fun hangupCall(call: MethodCall, result: MethodChannel.Result) { + session?.disconnect() + result.success(true) + } + + 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/RemoteVideo.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/opentok/RemoteVideo.kt new file mode 100644 index 00000000..9116a1e8 --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/opentok/RemoteVideo.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 RemoteVideoFactory : PlatformViewFactory(StandardMessageCodec.INSTANCE) { + + companion object { + private lateinit var view: RemoteVideoPlatformView + + fun getViewInstance(context: Context): RemoteVideoPlatformView { + if(!this::view.isInitialized) { + view = RemoteVideoPlatformView(context) + } + + return view + } + } + + override fun create(context: Context, viewId: Int, args: Any?): PlatformView { + return getViewInstance(context) + } +} + +class RemoteVideoPlatformView(context: Context) : PlatformView { + private val videoContainer: RemoteVideoContainer = RemoteVideoContainer(context) + + val container get() = videoContainer.subscriberContainer + + override fun getView(): View { + return videoContainer + } + + override fun dispose() {} +} + +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 + + init { + val view = LayoutInflater.from(context).inflate(R.layout.remote_video, this, true) + subscriberContainer = view.findViewById(R.id.subscriber_container) + } +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/penguin/PenguinMethod.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/penguin/PenguinMethod.kt new file mode 100644 index 00000000..c76f9784 --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/penguin/PenguinMethod.kt @@ -0,0 +1,13 @@ +package com.cloud.diplomaticquarterapp.penguin + +enum class PenguinMethod { + // initializePenguin("initializePenguin"), + // configurePenguin("configurePenguin"), + // showPenguinUI("showPenguinUI"), + // onPenNavUIDismiss("onPenNavUIDismiss"), + // onReportIssue("onReportIssue"), + // onPenNavSuccess("onPenNavSuccess"), + onPenNavInitializationError // onLocationOffCampus("onLocationOffCampus"), + // navigateToPOI("navigateToPOI"), + // openSharedLocation("openSharedLocation"); +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/penguin/PenguinNavigator.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/penguin/PenguinNavigator.kt new file mode 100644 index 00000000..98245cc9 --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/penguin/PenguinNavigator.kt @@ -0,0 +1,97 @@ +package com.cloud.diplomaticquarterapp.penguin + +import android.content.Context +import com.google.gson.Gson +import com.peng.pennavmap.PlugAndPlaySDK +import com.peng.pennavmap.connections.ApiController +import com.peng.pennavmap.interfaces.RefIdDelegate +import com.peng.pennavmap.models.TokenModel +import com.peng.pennavmap.models.postmodels.PostToken +import com.peng.pennavmap.utils.AppSharedData +import okhttp3.ResponseBody +import retrofit2.Call +import retrofit2.Callback +import retrofit2.Response +import android.util.Log + + +class PenguinNavigator() { + + fun navigateTo(mContext: Context, refID: String, delegate: RefIdDelegate,clientID : String,clientKey : String ) { + val postToken = PostToken(clientID, clientKey) + getToken(mContext, postToken, object : RefIdDelegate { + override fun onRefByIDSuccess(PoiId: String?) { + Log.e("navigateTo", "PoiId is+++++++ $PoiId") + + PlugAndPlaySDK.navigateTo(mContext, refID, object : RefIdDelegate { + override fun onRefByIDSuccess(PoiId: String?) { + Log.e("navigateTo", "PoiId 2is+++++++ $PoiId") + + delegate.onRefByIDSuccess(refID) + + } + + override fun onGetByRefIDError(error: String?) { + delegate.onRefByIDSuccess(error) + } + + }) + + + } + + override fun onGetByRefIDError(error: String?) { + delegate.onRefByIDSuccess(error) + } + + }) + + } + + fun getToken(mContext: Context, postToken: PostToken?, apiTokenCallBack: RefIdDelegate) { + try { + // Create the API call + val purposesCall: Call = ApiController.getInstance(mContext) + .apiMethods + .getToken(postToken) + + // Enqueue the call for asynchronous execution + purposesCall.enqueue(object : Callback { + override fun onResponse( + call: Call, + response: Response + ) { + if (response.isSuccessful() && response.body() != null) { + try { + response.body()?.use { responseBody -> + val responseBodyString: String = responseBody.string() // Use `string()` to get the actual response content + if (responseBodyString.isNotEmpty()) { + val tokenModel = Gson().fromJson(responseBodyString, TokenModel::class.java) + if (tokenModel != null && tokenModel.token != null) { + AppSharedData.apiToken = tokenModel.token + apiTokenCallBack.onRefByIDSuccess(tokenModel.token) + } else { + apiTokenCallBack.onGetByRefIDError("Failed to parse token model") + } + } else { + apiTokenCallBack.onGetByRefIDError("Response body is empty") + } + } + } catch (e: Exception) { + apiTokenCallBack.onGetByRefIDError("An error occurred: ${e.message}") + } + } else { + apiTokenCallBack.onGetByRefIDError("Unsuccessful response: " + response.code()) + } + } + + override fun onFailure(call: Call, t: Throwable) { + apiTokenCallBack.onGetByRefIDError(t.message) + } + }) + } catch (error: Exception) { + apiTokenCallBack.onGetByRefIDError("Exception during API call: $error") + } + } + +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/penguin/PenguinView.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/penguin/PenguinView.kt new file mode 100644 index 00000000..9f74103f --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/penguin/PenguinView.kt @@ -0,0 +1,321 @@ +package com.cloud.diplomaticquarterapp.penguin + +import android.app.Activity +import android.content.Context +import android.content.Context.RECEIVER_EXPORTED +import android.content.IntentFilter +import android.graphics.Color +import android.os.Build +import android.util.Log +import android.view.View +import android.view.ViewGroup +import android.widget.RelativeLayout +import android.widget.Toast +import androidx.annotation.RequiresApi +import com.cloud.diplomaticquarterapp.PermissionManager.PermissionHelper +import com.cloud.diplomaticquarterapp.PermissionManager.PermissionManager +import com.cloud.diplomaticquarterapp.PermissionManager.PermissionResultReceiver +import com.ejada.hmg.MainActivity +import com.peng.pennavmap.PlugAndPlayConfiguration +import com.peng.pennavmap.PlugAndPlaySDK +import com.peng.pennavmap.enums.InitializationErrorType +import com.peng.pennavmap.interfaces.PenNavUIDelegate +import com.peng.pennavmap.utils.Languages +import io.flutter.plugin.common.BinaryMessenger +import io.flutter.plugin.common.MethodCall +import io.flutter.plugin.common.MethodChannel +import io.flutter.plugin.platform.PlatformView +import com.cloud.diplomaticquarterapp.penguin.PenguinNavigator +import com.peng.pennavmap.interfaces.PIEventsDelegate +import com.peng.pennavmap.interfaces.PILocationDelegate +import com.peng.pennavmap.interfaces.RefIdDelegate +import com.peng.pennavmap.models.PIReportIssue +/** + * Custom PlatformView for displaying Penguin UI components within a Flutter app. + * Implements `PlatformView` for rendering the view, `MethodChannel.MethodCallHandler` for handling method calls, + * and `PenNavUIDelegate` for handling SDK events. + */ +@RequiresApi(Build.VERSION_CODES.O) +internal class PenguinView( + context: Context, + id: Int, + val creationParams: Map, + messenger: BinaryMessenger, + activity: MainActivity, + val channel: MethodChannel +) : PlatformView, MethodChannel.MethodCallHandler, PenNavUIDelegate { + // The layout for displaying the Penguin UI + private val mapLayout: RelativeLayout = RelativeLayout(context) + private val _context: Context = context + + private val permissionResultReceiver: PermissionResultReceiver + private val permissionIntentFilter = IntentFilter("PERMISSION_RESULT_ACTION") + + private companion object { + const val PERMISSIONS_REQUEST_CODE = 1 + } + + private lateinit var permissionManager: PermissionManager + + // Reference to the main activity + private var _activity: Activity = activity + + private lateinit var mContext: Context + + lateinit var navigator: PenguinNavigator + + init { + // Set layout parameters for the mapLayout + mapLayout.layoutParams = ViewGroup.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT + ) + + mContext = context + + + permissionResultReceiver = PermissionResultReceiver { granted -> + if (granted) { + onPermissionsGranted() + } else { + onPermissionsDenied() + } + } + if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + mContext.registerReceiver( + permissionResultReceiver, + permissionIntentFilter, + RECEIVER_EXPORTED + ) + } else { + mContext.registerReceiver( + permissionResultReceiver, + permissionIntentFilter, + ) + } + + // Set the background color of the layout + mapLayout.setBackgroundColor(Color.RED) + + permissionManager = PermissionManager( + context = mContext, + listener = object : PermissionManager.PermissionListener { + override fun onPermissionGranted() { + // Handle permissions granted + onPermissionsGranted() + } + + override fun onPermissionDenied() { + // Handle permissions denied + onPermissionsDenied() + } + }, + requestCode = PERMISSIONS_REQUEST_CODE, + *PermissionHelper.getRequiredPermissions() + ) + + if (!permissionManager.arePermissionsGranted()) { + permissionManager.requestPermissions(_activity) + } else { + // Permissions already granted + permissionManager.listener.onPermissionGranted() + } + + + } + + private fun onPermissionsGranted() { + // Handle the actions when permissions are granted + Log.d("PermissionsResult", "onPermissionsGranted") + // Register the platform view factory for creating custom views + + // Initialize the Penguin SDK + initPenguin() + + + } + + private fun onPermissionsDenied() { + // Handle the actions when permissions are denied + Log.d("PermissionsResult", "onPermissionsDenied") + + } + + /** + * Returns the view associated with this PlatformView. + * + * @return The main view for this PlatformView. + */ + override fun getView(): View { + return mapLayout + } + + /** + * Cleans up resources associated with this PlatformView. + */ + override fun dispose() { + // Cleanup code if needed + } + + /** + * Handles method calls from Dart code. + * + * @param call The method call from Dart. + * @param result The result callback to send responses back to Dart. + */ + override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { + // Handle method calls from Dart code here + } + + /** + * Initializes the Penguin SDK with custom configuration and delegates. + */ + private fun initPenguin() { + navigator = PenguinNavigator() + // Configure the PlugAndPlaySDK + val language = when (creationParams["languageCode"] as String) { + "ar" -> Languages.ar + "en" -> Languages.en + else -> { + Languages.en + } + } + Log.d( + "TAG", + "initPenguin: ${Languages.getLanguageEnum(creationParams["languageCode"] as String)}" + ) + PlugAndPlaySDK.configuration = PlugAndPlayConfiguration.Builder() + .setBaseUrl( + creationParams["dataURL"] as String, + creationParams["positionURL"] as String + ) + .setServiceName( + creationParams["dataServiceName"] as String, + creationParams["positionServiceName"] as String + ) + .setClientData( + creationParams["clientID"] as String, + creationParams["clientKey"] as String + ) + .setUserName(creationParams["username"] as String) +// .setLanguageID(Languages.en) + .setLanguageID(language) + .setSimulationModeEnabled(creationParams["isSimulationModeEnabled"] as Boolean) + .setEnableBackButton(true) +// .setDeepLinkData("deeplink") + .setCustomizeColor("#2CA0AF") + .setDeepLinkSchema("") + .setIsEnableReportIssue(true) + .build() + + // Set location delegate to handle location updates +// PlugAndPlaySDK.setPiLocationDelegate { + // Example code to handle location updates + // Uncomment and modify as needed + // if (location.size() > 0) + // Toast.makeText(_context, "Location Info Latitude: ${location[0]}, Longitude: ${location[1]}", Toast.LENGTH_SHORT).show() +// } + + // Set events delegate for reporting issues +// PlugAndPlaySDK.setPiEventsDelegate(new PIEventsDelegate() { +// @Override +// public void onReportIssue(PIReportIssue issue) { +// Log.e("Issue Reported: ", issue.getReportType()); +// } +// // Implement issue reporting logic here } +// @Override +// public void onSharedLocation(String link) { +// // Implement Shared location logic here +// } +// }) + + // Start the Penguin SDK + PlugAndPlaySDK.start(mContext, this) + } + + + /** + * Navigates to the specified reference ID. + * + * @param refID The reference ID to navigate to. + */ + fun navigateTo(refID: String) { + try { + if (refID.isBlank()) { + Log.e("navigateTo", "Invalid refID: The reference ID is blank.") + } +// referenceId = refID + navigator.navigateTo(mContext, refID,object : RefIdDelegate { + override fun onRefByIDSuccess(PoiId: String?) { + Log.e("navigateTo", "PoiId is penguin view+++++++ $PoiId") + +// channelFlutter.invokeMethod( +// PenguinMethod.navigateToPOI.name, +// "navigateTo Success" +// ) + } + + override fun onGetByRefIDError(error: String?) { + Log.e("navigateTo", "error is penguin view+++++++ $error") + +// channelFlutter.invokeMethod( +// PenguinMethod.navigateToPOI.name, +// "navigateTo Failed: Invalid refID" +// ) + } + } , creationParams["clientID"] as String, creationParams["clientKey"] as String ) + + } catch (e: Exception) { + Log.e("navigateTo", "Exception occurred during navigation: ${e.message}", e) +// channelFlutter.invokeMethod( +// PenguinMethod.navigateToPOI.name, +// "Failed: Exception - ${e.message}" +// ) + } + } + + /** + * Called when Penguin UI setup is successful. + * + * @param warningCode Optional warning code received from the SDK. + */ + override fun onPenNavSuccess(warningCode: String?) { + val clinicId = creationParams["clinicID"] as String + + if(clinicId.isEmpty()) return + + navigateTo(clinicId) + } + + /** + * Called when there is an initialization error with Penguin UI. + * + * @param description Description of the error. + * @param errorType Type of initialization error. + */ + override fun onPenNavInitializationError( + description: String?, + errorType: InitializationErrorType? + ) { + val arguments: Map = mapOf( + "description" to description, + "type" to errorType?.name + ) + + channel.invokeMethod(PenguinMethod.onPenNavInitializationError.name, arguments) + Toast.makeText(mContext, "Navigation Error: $description", Toast.LENGTH_SHORT).show() + } + + /** + * Called when Penguin UI is dismissed. + */ + override fun onPenNavUIDismiss() { + // Handle UI dismissal if needed + try { + mContext.unregisterReceiver(permissionResultReceiver) + dispose(); + } catch (e: IllegalArgumentException) { + Log.e("PenguinView", "Receiver not registered: $e") + } + } +} + diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/API.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/API.kt index 924bda91..18338e23 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/API.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/API.kt @@ -1,4 +1,4 @@ -package com.cloud.diplomaticquarterapp.utils +package com.ejada.hmg.utils class API { companion object{ diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/Constants.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/Constants.kt index aa0f8ec2..86df85f4 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/Constants.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/Constants.kt @@ -1,4 +1,4 @@ -package com.cloud.diplomaticquarterapp.utils +package com.ejada.hmg.utils const val PREFS_STORAGE = "FlutterSharedPreferences" diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/FlutterText.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/FlutterText.kt index 419eb340..1a650074 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/FlutterText.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/FlutterText.kt @@ -1,4 +1,4 @@ -package com.cloud.diplomaticquarterapp.utils +package com.ejada.hmg.utils import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel.Result @@ -17,7 +17,7 @@ class FlutterText{ } } - override fun error(errorCode: String?, errorMessage: String?, errorDetails: Any?) { + override fun error(errorCode: String, errorMessage: String?, errorDetails: Any?) { completion(key) require(false){ "'localizedValue' $errorMessage" diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMGUtils.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMGUtils.kt index 94bf54e6..57da2eb8 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMGUtils.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMGUtils.kt @@ -1,4 +1,4 @@ -package com.cloud.diplomaticquarterapp.utils +package com.ejada.hmg.utils import android.app.NotificationChannel import android.app.NotificationManager @@ -13,16 +13,16 @@ import android.widget.Toast import androidx.annotation.Nullable import androidx.core.app.NotificationCompat import androidx.core.app.TaskStackBuilder -import com.cloud.diplomaticquarterapp.BuildConfig -import com.cloud.diplomaticquarterapp.MainActivity -import com.cloud.diplomaticquarterapp.R -import com.cloud.diplomaticquarterapp.geofence.GeoZoneModel +import com.ejada.hmg.BuildConfig +import com.ejada.hmg.MainActivity +import com.ejada.hmg.R +import com.ejada.hmg.geofence.GeoZoneModel import com.github.kittinunf.fuel.core.extensions.jsonBody import com.github.kittinunf.fuel.httpPost import com.google.gson.Gson import com.google.gson.reflect.TypeToken import io.flutter.plugin.common.MethodChannel -import org.jetbrains.anko.doAsyncResult +//import org.jetbrains.anko.doAsyncResult import org.json.JSONArray import org.json.JSONException import org.json.JSONObject @@ -149,7 +149,7 @@ fun sendNotification(context: Context, title: String, @Nullable subtitle: String val notificationPendingIntent = stackBuilder.getPendingIntent(getUniqueId(), PendingIntent.FLAG_UPDATE_CURRENT) val notification = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID) - .setSmallIcon(R.mipmap.ic_launcher) + .setSmallIcon(R.mipmap.ic_launcher_local) .setContentIntent(notificationPendingIntent) .setAutoCancel(true) .setContentTitle(title) @@ -208,7 +208,6 @@ fun httpPost(url: String, body: Map, onSuccess: (response: HTTP .header("Content-Type", "application/json") .header("Allow", "*/*") .response { request, response, result -> - result.doAsyncResult { } result.fold({ data -> val dataString = String(data) if (isJSONValid(dataString)) { diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMG_Wifi_.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMG_Wifi_.kt index decc9bdf..c01bb96a 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMG_Wifi_.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMG_Wifi_.kt @@ -1,4 +1,4 @@ -//package com.cloud.diplomaticquarterapp.utils +//package com.ejada.hmg.utils // //import android.annotation.SuppressLint //import android.content.Context @@ -10,8 +10,8 @@ //import android.net.wifi.WifiConfiguration //import android.net.wifi.WifiManager //import android.util.Log -//import com.cloud.diplomaticquarterapp.utils.API -//import com.cloud.diplomaticquarterapp.FlutterMainActivity +//import com.ejada.hmg.utils.API +//import com.ejada.hmg.FlutterMainActivity //import com.github.kittinunf.fuel.core.extensions.jsonBody //import com.github.kittinunf.fuel.httpGet //import com.github.kittinunf.fuel.httpPost diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/Logs.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/Logs.kt index e74f463e..d9dc209e 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/Logs.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/Logs.kt @@ -1,9 +1,9 @@ -package com.cloud.diplomaticquarterapp.utils +package com.ejada.hmg.utils import android.content.Context import android.content.SharedPreferences import android.os.Build -import com.cloud.diplomaticquarterapp.BuildConfig +import com.ejada.hmg.BuildConfig import com.google.gson.Gson class Logs { 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..ebb04456 --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/OpenTokPlatformBridge.kt @@ -0,0 +1,45 @@ +package com.ejada.hmg.utils + +import com.ejada.hmg.MainActivity +import com.ejada.hmg.opentok.OpenTok +import io.flutter.embedding.engine.FlutterEngine +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) + } + "hangupCall" -> { + openTok.hangupCall(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 eb2fff08..9a66f4b3 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 @@ -1,20 +1,26 @@ -package com.cloud.diplomaticquarterapp.utils +package com.ejada.hmg.utils import android.content.Context +import android.content.Intent +import android.content.Intent.getIntent +import android.net.Uri +import android.os.Build +import android.os.Bundle +import android.provider.Settings +import android.widget.Toast +import androidx.core.app.ActivityCompat.startActivityForResult import android.net.wifi.WifiManager import android.util.Log -import com.cloud.diplomaticquarterapp.MainActivity -import com.cloud.diplomaticquarterapp.hmgwifi.HMG_Guest -import com.cloud.diplomaticquarterapp.hmgwifi.HMG_Internet -import com.cloud.diplomaticquarterapp.geofence.GeoZoneModel -import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence -import io.flutter.plugin.common.BinaryMessenger +import com.ejada.hmg.MainActivity +import com.ejada.hmg.hmgwifi.HMG_Guest +import com.ejada.hmg.geofence.GeoZoneModel +import com.ejada.hmg.geofence.HMG_Geofence +import com.ejada.hmg.hmgwifi.WpaEnterprise +import io.flutter.embedding.engine.FlutterEngine 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 @@ -25,103 +31,169 @@ class PlatformBridge(binaryMessenger: BinaryMessenger, flutterMainActivity: Main private const val ENABLE_WIFI_IF_NOT = "enableWifiIfNot" private const val REGISTER_HMG_GEOFENCES = "registerHmgGeofences" private const val UN_REGISTER_HMG_GEOFENCES = "unRegisterHmgGeofences" + private const val IS_DRAW_OVER_APPS_PERMISSION_ALLOWED = "isDrawOverAppsPermissionAllowed" + private const val ASK_DRAW_OVER_APPS_PERMISSION = "askDrawOverAppsPermission" + private const val GET_INTENT = "getIntent" } - fun create(){ - channel = MethodChannel(binaryMessenger, CHANNEL) + fun create() { + channel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL) HMGUtils.setPlatformChannel(channel) channel.setMethodCallHandler { methodCall: MethodCall, result: MethodChannel.Result -> if (methodCall.method == HMG_INTERNET_WIFI_CONNECT_METHOD) { - connectHMGInternetWifi(methodCall,result) - - }else if (methodCall.method == HMG_GUEST_WIFI_CONNECT_METHOD) { - connectHMGGuestWifi(methodCall,result) - - }else if (methodCall.method == ENABLE_WIFI_IF_NOT) { - enableWifiIfNot(methodCall,result) - }else if (methodCall.method == REGISTER_HMG_GEOFENCES) { - registerHmgGeofences(methodCall,result) - }else if (methodCall.method == UN_REGISTER_HMG_GEOFENCES) { - unRegisterHmgGeofences(methodCall,result) - }else{ - + connectHMGInternetWifi(methodCall, result) + + } else if (methodCall.method == HMG_GUEST_WIFI_CONNECT_METHOD) { + connectHMGGuestWifi(methodCall, result) + + } else if (methodCall.method == ENABLE_WIFI_IF_NOT) { + enableWifiIfNot(methodCall, result) + } else if (methodCall.method == REGISTER_HMG_GEOFENCES) { + registerHmgGeofences(methodCall, result) + } else if (methodCall.method == UN_REGISTER_HMG_GEOFENCES) { + unRegisterHmgGeofences(methodCall, result) + } else if (methodCall.method == IS_DRAW_OVER_APPS_PERMISSION_ALLOWED) { + isDrawOverAppsPermissionAllowed(methodCall, result) + } else if (methodCall.method == ASK_DRAW_OVER_APPS_PERMISSION) { + askDrawOverAppsPermission(methodCall, result) + } else if (methodCall.method == GET_INTENT) { + getIntentData(methodCall, result) + } else { result.notImplemented() } } - val res = channel.invokeMethod("localizedValue","errorConnectingHmgNetwork") - print(res) + val res = channel.invokeMethod("localizedValue", "errorConnectingHmgNetwork") + } - private fun connectHMGInternetWifi(methodCall: MethodCall, result: MethodChannel.Result){ + private fun connectHMGInternetWifi(methodCall: MethodCall, result: MethodChannel.Result) { (methodCall.arguments as ArrayList<*>).let { - require(it.size > 0 && (it[0] is String),lazyMessage = { - "Missing or invalid arguments (Must have one argument 'String at 0'" + require(it.size == 3 && (it[0] is String) && (it[1] is String), lazyMessage = { + "Missing or invalid arguments (Must have three argument of 'String'" }) - val patientId = it[0].toString() - HMG_Internet(mainActivity) - .connectToHMGGuestNetwork(patientId){ status, message -> - - mainActivity.runOnUiThread { - result.success(if(status) 1 else 0) - - HMGUtils.popFlutterText(mainActivity, message) - Log.v(this.javaClass.simpleName, "$status | $message") - } - + val ssid = it[0].toString() + val username = it[1].toString() + val password = it[2].toString() + + WpaEnterprise(mainActivity,ssid).connect(username,password) { status, message -> + HMGUtils.timer(2000,false){ + mainActivity.runOnUiThread { + if(status) + result.success(if (status) 1 else 0) + else + result.error(message, null, null) } + } + } + +// HMG_Internet(mainActivity) +// .connectToHMGGuestNetwork(username, password) { status, message -> +// mainActivity.runOnUiThread { +// result.success(if (status) 1 else 0) +// +// HMGUtils.popFlutterText(mainActivity, message) +// Log.v(this.javaClass.simpleName, "$status | $message") +// } +// +// } } } - private fun connectHMGGuestWifi(methodCall: MethodCall, result: MethodChannel.Result){ - HMG_Guest(mainActivity).connectToHMGGuestNetwork { status, message -> - mainActivity.runOnUiThread { - result.success(if(status) 1 else 0) + private fun connectHMGGuestWifi(methodCall: MethodCall, result: MethodChannel.Result) { + (methodCall.arguments as ArrayList<*>).let { + require(it.size == 1 && (it[0] is String), lazyMessage = { + "Missing or invalid arguments (Must have one argument 'String at 0'" + }) + + val ssid = it[0].toString() + HMG_Guest(mainActivity, ssid).connectToHMGGuestNetwork { status, message -> + mainActivity.runOnUiThread { + result.success(if (status) 1 else 0) - HMGUtils.popFlutterText(mainActivity, message) - Log.v(this.javaClass.simpleName, "$status | $message") + HMGUtils.popFlutterText(mainActivity, message) + Log.v(this.javaClass.simpleName, "$status | $message") + } } } } private fun enableWifiIfNot(methodCall: MethodCall, result: MethodChannel.Result) { val wm = mainActivity.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager? - if (wm != null){ + if (wm != null) { if (!wm.isWifiEnabled) wm.isWifiEnabled = true result.success(true) - }else - result.error("101","Error while opening wifi, Please try to open wifi yourself and try again","'WifiManager' service failed"); + } else + result.error("101", "Error while opening wifi, Please try to open wifi yourself and try again", "'WifiManager' service failed"); } private fun registerHmgGeofences(methodCall: MethodCall, result: MethodChannel.Result) { - channel.invokeMethod("getGeoZones",null, object : MethodChannel.Result{ + channel.invokeMethod("getGeoZones", null, object : MethodChannel.Result { override fun success(result: Any?) { - if(result is String) { + if (result is String) { val geoZones = GeoZoneModel().listFrom(result) - HMG_Geofence.shared(mainActivity).register(){ s, e -> } + HMG_Geofence.shared(mainActivity).register() { s, e -> } } } - override fun error(errorCode: String?, errorMessage: String?, errorDetails: Any?) { print(result) } - override fun notImplemented() { print(result) } + override fun error(errorCode: String, errorMessage: String?, errorDetails: Any?) {} + override fun notImplemented() {} }) } - + private fun unRegisterHmgGeofences(methodCall: MethodCall, result: MethodChannel.Result) { HMG_Geofence.shared(mainActivity).unRegisterAll { status, exception -> - if(status) + if (status) result.success(true) else result.error("101", exception?.localizedMessage, exception); } } - + + private fun isDrawOverAppsPermissionAllowed(methodCall: MethodCall, result: MethodChannel.Result) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if ( + Settings.canDrawOverlays(mainActivity) + ) { + result.success(true) + } else { + result.success(false) + } + } else { + result.success(false) + } + } + + private fun askDrawOverAppsPermission(methodCall: MethodCall, result: MethodChannel.Result) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + val intent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION) + val uri = Uri.parse("package:" + mainActivity.getPackageName()) + intent.setData(uri) + startActivityForResult(mainActivity, intent, 102, null) + result.success(true) + } else { + result.success(false) + } + } + + private fun getIntentData(methodCall: MethodCall, result: MethodChannel.Result) { + + val bundle: Bundle? = getIntent("").extras + if (bundle != null) { + val message = bundle.getString("notification") // 1 + System.out.println("BundleExtra:" + message) + Toast.makeText(this.mainActivity, message + "", Toast.LENGTH_SHORT).show() + } else { + Toast.makeText(this.mainActivity, "Bundle Null", Toast.LENGTH_SHORT).show(); + } + result.success(true); + } } diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/whatsapp/AppSignatureRetriever.java b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/whatsapp/AppSignatureRetriever.java new file mode 100644 index 00000000..83e6e917 --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/whatsapp/AppSignatureRetriever.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +package com.cloud.diplomaticquarterapp.whatsapp; + +import static java.sql.DriverManager.println; + +import android.content.Context; +import android.content.ContextWrapper; +import android.content.pm.PackageManager; +import android.content.pm.Signature; +import android.util.Base64; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; +import java.util.Collection; +import java.util.stream.Collectors; + +public class AppSignatureRetriever { + + private static final String HASH_TYPE = "SHA-256"; + public static final int NUM_HASHED_BYTES = 9; + public static final int NUM_BASE64_CHAR = 11; + + + public void logSignatures(Context context) { + Collection appSignatures = getAppSignatures(context); + appSignatures.forEach(signature -> println("Signature: " + signature)); + } + + /** + * Get all the app signatures for the current package. + * + * @return signatures for current app + */ + public Collection getAppSignatures(Context context) { + try { + // Get all package signatures for the current package + String packageName = context.getPackageName(); + println("Package name: " + packageName); + PackageManager packageManager = context.getPackageManager(); + Signature[] signatures = packageManager.getPackageInfo(packageName, + PackageManager.GET_SIGNATURES).signatures; + + // For each signature create a compatible hash + Collection appCodes = Arrays.stream(signatures) + .map(signature -> hash(packageName, signature.toCharsString())) + .collect(Collectors.toList()); + return appCodes; + } catch (PackageManager.NameNotFoundException e) { + println("Unable to find package to obtain hash."); + throw new RuntimeException("Unable to find package to obtain hash.", e); + } + + } + + private String hash(String packageName, String signature) { + String appInfo = packageName + " " + signature; + try { + MessageDigest messageDigest = MessageDigest.getInstance(HASH_TYPE); + messageDigest.update(appInfo.getBytes(StandardCharsets.UTF_8)); + byte[] hashSignature = messageDigest.digest(); + + // truncated into NUM_HASHED_BYTES + hashSignature = Arrays.copyOfRange(hashSignature, 0, NUM_HASHED_BYTES); + // encode into Base64 + String base64Hash = Base64.encodeToString(hashSignature, Base64.NO_PADDING | Base64.NO_WRAP); + base64Hash = base64Hash.substring(0, NUM_BASE64_CHAR); + + println(String.format("pkg: %s -- hash: %s", packageName, base64Hash)); + return base64Hash; + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException("Unable to generate hash for application", e); + } + } +} diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/whatsapp/WhatsApp.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/whatsapp/WhatsApp.kt new file mode 100644 index 00000000..73452e6f --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/whatsapp/WhatsApp.kt @@ -0,0 +1,31 @@ + +package com.cloud.diplomaticquarterapp.whatsapp + +import android.content.Context +import android.content.Intent +import com.whatsapp.otp.android.sdk.WhatsAppOtpHandler +import com.whatsapp.otp.android.sdk.WhatsAppOtpIncomingIntentHandler +import java.lang.ref.WeakReference + +object WhatsApp { + val whatsAppOtpHandler = WhatsAppOtpHandler() + inline fun handleOTP ( intent: Intent, crossinline validateOTP:(code: String )-> Unit) = + WhatsAppOtpIncomingIntentHandler().processOtpCode( + intent, + // call your function to validate + {code -> validateOTP(code) }, + {error,exception-> + println("the error is ${error.name}") + println("the exception stacktrace is ${exception.message}") + println("the exception is cause ${exception.cause}") + }) + + + fun performHandShake(context : WeakReference) = whatsAppOtpHandler.sendOtpIntentToWhatsApp(context.get()!!) + + + + fun isWhatsAppInstalled(context : WeakReference) : Boolean = whatsAppOtpHandler.isWhatsAppInstalled(context.get()!!) + + +} diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/whatsapp/WhatsAppCodeActivity.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/whatsapp/WhatsAppCodeActivity.kt new file mode 100644 index 00000000..5739022e --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/whatsapp/WhatsAppCodeActivity.kt @@ -0,0 +1,17 @@ +package com.cloud.diplomaticquarterapp.whatsapp +import android.app.PendingIntent +import android.content.Intent +import android.os.Bundle +import com.cloud.diplomaticquarterapp.whatsapp.WhatsApp +import com.cloud.diplomaticquarterapp.whatsapp.WhatsAppOtpPlatformBridge +import io.flutter.embedding.android.FlutterFragmentActivity + +class WhatsAppCodeActivity : FlutterFragmentActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + WhatsApp.handleOTP(intent){code -> + WhatsAppOtpPlatformBridge.result?.success(code); + finish() + } + } +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/whatsapp/WhatsAppOtpPlatformBridge.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/whatsapp/WhatsAppOtpPlatformBridge.kt new file mode 100644 index 00000000..5493e8be --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/whatsapp/WhatsAppOtpPlatformBridge.kt @@ -0,0 +1,48 @@ +package com.cloud.diplomaticquarterapp.whatsapp + +import com.ejada.hmg.MainActivity +import io.flutter.embedding.engine.FlutterEngine +import io.flutter.plugin.common.MethodCall +import io.flutter.plugin.common.MethodChannel +import java.lang.ref.WeakReference + +class WhatsAppOtpPlatformBridge( + private var flutterEngine: FlutterEngine, + private var mainActivity: MainActivity +) { + + + private lateinit var channel: MethodChannel + + companion object { + private const val CHANNEL = "whats_app_otp" + var result: MethodChannel.Result? = null + } + + fun invoke() { + channel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL) + channel.setMethodCallHandler { call: MethodCall, result: MethodChannel.Result -> + when (call.method) { + "isWhatsAppInstalled" -> { + val isAppInstalled = + WhatsApp.isWhatsAppInstalled(WeakReference(mainActivity)) + result.success(isAppInstalled) + } + + "performHandShake" -> { + WhatsApp.performHandShake(WeakReference(mainActivity)) + } + + + "startListening" -> { + WhatsAppOtpPlatformBridge.result = result + } + + else -> { + result.notImplemented() + } + + } + } + } +} \ No newline at end of file diff --git a/android/app/src/main/res/drawable/app_icon.png b/android/app/src/main/res/drawable/app_icon.png old mode 100644 new mode 100755 index c4cc798d..2d394f83 Binary files a/android/app/src/main/res/drawable/app_icon.png and b/android/app/src/main/res/drawable/app_icon.png differ diff --git a/android/app/src/main/res/layout/activity_whats_app_code.xml b/android/app/src/main/res/layout/activity_whats_app_code.xml new file mode 100644 index 00000000..3cd824c9 --- /dev/null +++ b/android/app/src/main/res/layout/activity_whats_app_code.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file 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/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index db77bb4b..00000000 Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_local.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_local.png new file mode 100644 index 00000000..348b5116 Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher_local.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index 17987b79..00000000 Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_local.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_local.png new file mode 100644 index 00000000..410b1b1e Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher_local.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index 09d43914..00000000 Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_local.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_local.png new file mode 100644 index 00000000..bb9943af Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_local.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index d5f1c8d3..00000000 Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_local.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_local.png new file mode 100644 index 00000000..0b9d9359 Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_local.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index 4d6372ee..00000000 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_local.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_local.png new file mode 100644 index 00000000..aaa9808d Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_local.png differ diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index 4e107030..6c4ac3df 100644 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -1,22 +1,23 @@ - HMG Patient App + HMG Patient App - + Unknown error: the Geofence service is not available now. - + Geofence service is not available now. Go to Settings>Location>Mode and choose High accuracy. - + Your app has registered too many geofences. - + You have provided too many PendingIntents to the addGeofences() call. - + App do not have permission to access location service. - + Geofence requests happened too frequently. + sk.eyJ1IjoicndhaWQiLCJhIjoiY2x6NWo0bTMzMWZodzJrcGZpemYzc3Z4dSJ9.uSSZuwNSGCcCdPAiORECmg diff --git a/android/app/src/profile/AndroidManifest.xml b/android/app/src/profile/AndroidManifest.xml index d8fd4e88..ab5e631b 100644 --- a/android/app/src/profile/AndroidManifest.xml +++ b/android/app/src/profile/AndroidManifest.xml @@ -1,5 +1,5 @@ + package="com.ejada.hmg"> diff --git a/android/build.gradle b/android/build.gradle index 32bda0b1..1849765a 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,24 +1,81 @@ buildscript { - ext.kotlin_version = '1.3.50' + ext.kotlin_version = '1.8.0' + +// if (System.properties['os.arch'] == "aarch64") { +// // For M1 Users we need to use the NDK 24 which added support for aarch64 +// ndkVersion = "24.0.8215888" +// } else { +// // Otherwise we default to the side-by-side NDK version from AGP. +// ndkVersion = "21.4.7075529" +// } + repositories { google() jcenter() + mavenCentral() + maven { url 'https://developer.huawei.com/repo/' } + maven { + url 'https://api.mapbox.com/downloads/v2/releases/maven' + + credentials { + username = 'mapbox' + password = "sk.eyJ1IjoicndhaWQiLCJhIjoiY2x6NWo0bTMzMWZodzJrcGZpemYzc3Z4dSJ9.uSSZuwNSGCcCdPAiORECmg" +// password = "pk.eyJ1IjoicndhaWQiLCJhIjoiY2x5cGo4aHNjMGNsbTJyc2djempobGQxaSJ9.RCaC6WrUt4A4YnZNfxnONQ" + if (password == null || password == "") { + throw new GradleException("MAPBOX_DOWNLOADS_TOKEN isn't set. Set it to the project properties or to the enviroment variables.") + } + } + authentication { + basic(BasicAuthentication) + } + } + // maven { // url "https://dl.bintray.com/kotlin/kotlin-eap/" // } } dependencies { - classpath 'com.android.tools.build:gradle:4.0.1' + classpath 'com.android.tools.build:gradle:7.1.3' +// classpath 'com.android.tools.build:gradle:8.2.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - classpath 'com.google.gms:google-services:4.3.4' + classpath 'com.google.gms:google-services:4.3.8' +// classpath 'com.google.firebase:firebase-crashlytics-gradle:2.8.1' + classpath 'com.huawei.agconnect:agcp:1.5.2.300' + classpath("com.android.tools:r8:8.2.42") + classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.12' + classpath "com.mapbox.gradle.plugins:access-token:0.4.0" } } allprojects { repositories { google() - jcenter() +// jcenter() + mavenCentral() + flatDir { + dirs 'libs' + } + maven { + url 'https://developer.huawei.com/repo/' + } + maven { + url "https://artifactory.ess-dev.com/artifactory/gradle-dev-local" + } + maven { + url 'https://api.mapbox.com/downloads/v2/releases/maven' + + credentials { + username = 'mapbox' + password = "sk.eyJ1IjoicndhaWQiLCJhIjoiY2x6NWo0bTMzMWZodzJrcGZpemYzc3Z4dSJ9.uSSZuwNSGCcCdPAiORECmg" + if (password == null || password == "") { + throw new GradleException("MAPBOX_DOWNLOADS_TOKEN isn't set. Set it to the project properties or to the enviroment variables.") + } + } + authentication { + basic(BasicAuthentication) + } + } } } @@ -30,6 +87,12 @@ subprojects { project.evaluationDependsOn(':app') } -task clean(type: Delete) { +tasks.register("clean", Delete) { delete rootProject.buildDir } + +configurations.all { + resolutionStrategy { + force 'androidx.core:core-ktx:1.6.0' + } +} diff --git a/android/google-services.json b/android/google-services.json index a4655794..3707617c 100644 --- a/android/google-services.json +++ b/android/google-services.json @@ -1,35 +1,42 @@ { "project_info": { - "project_number": "864393916058", - "firebase_url": "https://diplomaticquarter-d2385.firebaseio.com", - "project_id": "diplomaticquarter-d2385", - "storage_bucket": "diplomaticquarter-d2385.appspot.com" + "project_number": "815750722565", + "firebase_url": "https://api-project-815750722565.firebaseio.com", + "project_id": "api-project-815750722565", + "storage_bucket": "api-project-815750722565.appspot.com" }, "client": [ { "client_info": { - "mobilesdk_app_id": "1:864393916058:android:5b5a65cd6d8c18b4b97923", + "mobilesdk_app_id": "1:815750722565:android:62281cd3e5df4063", "android_client_info": { - "package_name": "com.cloud.diplomaticquarterapp" + "package_name": "com.ejada.hmg" } }, "oauth_client": [ { - "client_id": "864393916058-tphjrn8j39ntevt32ekcvmll8aue7qql.apps.googleusercontent.com", + "client_id": "815750722565-3a0gc7neins0eoahdrimrfksk0sqice8.apps.googleusercontent.com", "client_type": 3 } ], "api_key": [ { - "current_key": "AIzaSyBdV3mos1BPhUzNKCj2KANJtiO3o2zh9IM" + "current_key": "AIzaSyDZDeWcBlRE3YfJWYt_DCiToVnANfaj8qg" } ], "services": { "appinvite_service": { "other_platform_oauth_client": [ { - "client_id": "864393916058-tphjrn8j39ntevt32ekcvmll8aue7qql.apps.googleusercontent.com", + "client_id": "815750722565-3a0gc7neins0eoahdrimrfksk0sqice8.apps.googleusercontent.com", "client_type": 3 + }, + { + "client_id": "815750722565-0cq9366orvsk5ipivq6lijcj56u03fr7.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "com.void.demo" + } } ] } diff --git a/android/gradle.properties b/android/gradle.properties index 38c8d454..9efff7ab 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,4 +1,8 @@ -org.gradle.jvmargs=-Xmx1536M -android.enableR8=true +org.gradle.jvmargs=-Xmx4096m +#android.enableR8=true android.useAndroidX=true android.enableJetifier=true +android.suppressUnsupportedCompileSdk=33 +MAPBOX_USER_NAME = "mapbox" +MAPBOX_DOWNLOADS_TOKEN="sk.eyJ1IjoicndhaWQiLCJhIjoiY2x6NWo0bTMzMWZodzJrcGZpemYzc3Z4dSJ9.uSSZuwNSGCcCdPAiORECmg" +#MAPBOX_DOWNLOADS_TOKEN="pk.eyJ1IjoicndhaWQiLCJhIjoiY2x5cGo4aHNjMGNsbTJyc2djempobGQxaSJ9.RCaC6WrUt4A4YnZNfxnONQ" \ No newline at end of file diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index 1f9de82f..f0c638fd 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Thu Sep 03 16:26:30 EEST 2020 +#Wed Jul 14 15:55:18 AST 2021 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.8-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip diff --git a/android/settings.gradle b/android/settings.gradle index 5a2f14fb..4c1c588e 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -1,4 +1,6 @@ include ':app' +include ':vital-sign-engine' +project(':vital-sign-engine').projectDir = new File('/Users/mohamedmekawy/Documents/Work/DiplomaticQuarter_3.16/packages/vital_sign_camera/android/libs') def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() diff --git a/applepay.json b/applepay.json new file mode 100644 index 00000000..5b00d6d5 --- /dev/null +++ b/applepay.json @@ -0,0 +1,22 @@ +{ + "provider": "apple_pay", + "data": { + "merchantIdentifier": "merchant.com.hmgwebservices", + "displayName": "Sulaiman Al Habib", + "merchantCapabilities": [ + "3DS", + "debit", + "credit" + ], + "supportedNetworks": [ + "amex", + "visa", + "discover", + "masterCard" + ], + "countryCode": "SA", + "currencyCode": "SAR", + "requiredBillingContactFields": null, + "requiredShippingContactFields": null + } +} \ No newline at end of file diff --git a/assets/app_icons/config.json b/assets/app_icons/config.json index e2e1afdb..7c2dda56 100644 --- a/assets/app_icons/config.json +++ b/assets/app_icons/config.json @@ -1,3 +1,4 @@ + { "name": "DQIcons", "css_prefix_text": "", @@ -271,6 +272,184 @@ "search": [ "roboticon" ] + }, + { + "uid": "8ce732688587909ad0a9d8323eaca8ad", + "css": "marquee", + "code": 59590, + "src": "fontelico" + }, + { + "uid": "ec8496ef645f3be7b28147ec60cd9ab1", + "css": "crown-minus", + "code": 59589, + "src": "fontelico" + }, + { + "uid": "36ef9feb0754335302784521267a9ad4", + "css": "crown-plus", + "code": 59588, + "src": "fontelico" + }, + { + "uid": "186dec7a13156bbe2550790c158fb85d", + "css": "crown", + "code": 59587, + "src": "fontelico" + }, + { + "uid": "2a46f1d1c9bd036e17a74e46613c1636", + "css": "ie", + "code": 59586, + "src": "fontelico" + }, + { + "uid": "9c2b737b16ae2c8d66b7bfd29ba5ecd8", + "css": "chrome", + "code": 59584, + "src": "fontelico" + }, + { + "uid": "45861dd1e5ce4fde338bcccf01eeb808", + "css": "opera", + "code": 59585, + "src": "fontelico" + }, + { + "uid": "2bd5f98482d86649958312ea2ab5bb40", + "css": "emo-laugh", + "code": 59576, + "src": "fontelico" + }, + { + "uid": "fc92480dedc439d274d4e3e4b425edf4", + "css": "emo-squint", + "code": 59575, + "src": "fontelico" + }, + { + "uid": "4843d0d6050dd508d4c101a334f46db2", + "css": "emo-shoot", + "code": 59574, + "src": "fontelico" + }, + { + "uid": "04688d76a33ce7a7950e40fae79c08ac", + "css": "emo-cry", + "code": 59573, + "src": "fontelico" + }, + { + "uid": "e4b163acaaa08255819f2f78afe8f075", + "css": "cart_menu_icon", + "code": 59412, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M367.1 624.3H972.6A33.2 33.2 0 0 0 1004.7 601.7L1138.2 164.7A29.6 29.6 0 0 0 1132.9 137.3 34.3 34.3 0 0 0 1106.3 124.9H289.9L266.3 24.5A33 33 0 0 0 233.7 0H33.4A32.4 32.4 0 0 0 0 31.2 32.4 32.4 0 0 0 33.4 62.4H206.9L327.4 569.6A93.8 93.8 0 0 0 267.1 655.5 97.1 97.1 0 0 0 367.2 749.1H972.6A31.3 31.3 0 1 0 972.6 686.7H367.2A31.3 31.3 0 1 1 367.2 624.3ZM1061.9 187.3L947.4 561.9H394L305 187.3ZM1061.9 187.3M315.3 894.6A105.4 105.4 0 1 0 420.7 789.2 105.4 105.4 0 0 0 315.3 894.6ZM420.7 859.4A35.2 35.2 0 1 1 385.6 894.6 35.2 35.2 0 0 1 420.7 859.4ZM420.7 859.4M735.4 894.6A105.4 105.4 0 1 0 840.9 789.2 105.4 105.4 0 0 0 735.4 894.6ZM840.9 859.4A35.2 35.2 0 1 1 805.7 894.6 35.2 35.2 0 0 1 840.9 859.4ZM840.9 859.4", + "width": 1140 + }, + "search": [ + "cart_menu_icon" + ] + }, + { + "uid": "45f50872f02e050e19f0910ca3e0e8e6", + "css": "categories_menu_icon", + "code": 59413, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M332.7 458.9H126.3A126.3 126.3 0 0 1 0 332.7V126.3A126.3 126.3 0 0 1 126.3 0H332.7A126.3 126.3 0 0 1 459 126.3V332.7A126.3 126.3 0 0 1 332.7 458.9ZM126.3 61.2A65.1 65.1 0 0 0 61.2 126.3V332.7A65.1 65.1 0 0 0 126.3 397.8H332.7A65.1 65.1 0 0 0 397.8 332.7V126.3A65.1 65.1 0 0 0 332.7 61.2ZM873.8 458.9H667.3A126.3 126.3 0 0 1 541 332.6V126.3A126.3 126.3 0 0 1 667.3 0H873.9A126.3 126.3 0 0 1 1000.2 126.3V332.7A126.3 126.3 0 0 1 873.8 458.9ZM667.3 61.2A65.1 65.1 0 0 0 602.2 126.3V332.7A65.1 65.1 0 0 0 667.3 397.8H873.9A65.1 65.1 0 0 0 938.9 332.7V126.3A65.1 65.1 0 0 0 873.9 61.3ZM332.7 999.9H126.3A126.3 126.3 0 0 1 0 873.7V667.3A126.3 126.3 0 0 1 126.3 541H332.7A126.3 126.3 0 0 1 459 667.3V873.9A126.3 126.3 0 0 1 332.7 999.9ZM126.3 602.2A65.1 65.1 0 0 0 61.2 667.3V873.9A65.1 65.1 0 0 0 126.3 938.8H332.7A65.1 65.1 0 0 0 397.8 873.8V667.3A65.1 65.1 0 0 0 332.7 602.3ZM873.8 999.9H667.3A126.3 126.3 0 0 1 541 873.7V667.3A126.3 126.3 0 0 1 667.3 541H873.8A126.3 126.3 0 0 1 1000.1 667.3V873.9A126.3 126.3 0 0 1 873.8 999.9ZM667.3 602.2A65.1 65.1 0 0 0 602.2 667.3V873.9A65.1 65.1 0 0 0 667.3 938.8H873.8A65.1 65.1 0 0 0 938.8 873.8V667.3A65.1 65.1 0 0 0 873.8 602.3Z", + "width": 1000 + }, + "search": [ + "categories_menu_icon" + ] + }, + { + "uid": "de65d94899c08a719eb8f9b723f73fc4", + "css": "hmg_logo_icon", + "code": 59414, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M146 835.7S180.9 835.5 205.5 835.5L392.2 836.4C414.4 836.4 433 812.7 434 778.5L434 622.5C434 589.3 448.9 563.3 472 561.7L529.2 561.2C552.3 562.7 568.1 588.9 568.1 622L568.1 778.9C569.2 813.1 584.7 835.5 607.1 835.5L858.4 836.1 858.8 643.3C858.8 610.2 842.9 584.4 819.8 583L718.8 582.5C696.5 582.5 678.9 558.9 677.9 524.7L677.5 472.6C678.6 438.4 696.4 414.8 718.7 414.8L820.2 415.1C843.3 413.6 858.3 386.4 858.3 353.3L858.5 112.8A102.4 102.4 0 0 1 780.8 161.4L610.2 161.4C587.9 161.4 569.4 185.7 568.3 219.9V374.6C567.2 408.8 549.8 432.9 527.5 432.9L475.8 432C453.4 432 435.6 408.6 434.5 374.7L434.5 218.4C433.4 184.3 415.6 161.2 393.4 161.2L145.6 161.2 145.6 353.4C145.6 386.6 161.2 413.1 184.3 414.7L285.8 414.3C308.8 415.8 325.1 443.2 325.1 476.2L324.8 520.7C324.8 553.8 309.1 580.4 286 581.9L184.3 581.7C161.2 583.3 145.6 609.5 145.6 642.6ZM999.3 99.1V902.8A102.2 102.2 0 0 1 896 1000H102.8A101.9 101.9 0 0 1 0 902.8L0 97.6A102.3 102.3 0 0 1 103 0L895.4 0.3A104 104 0 0 1 999.3 99.1Z", + "width": 999 + }, + "search": [ + "hmg_logo_icon" + ] + }, + { + "uid": "baf8798b7336aad03b1d61cacc015142", + "css": "user_menu_icon", + "code": 59415, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M853.6 146.4A500 500 0 0 0 146.4 853.6 500 500 0 0 0 853.6 146.4ZM217 838.5A286.1 286.1 0 0 1 500 586.7 285 285 0 0 1 783 838.5 440.5 440.5 0 0 1 217 838.5ZM500 526.3A151.8 151.8 0 1 1 651.8 374.5 152.1 152.1 0 0 1 500 526.3ZM833.4 788.8A344.4 344.4 0 0 0 617.6 548.7 210.5 210.5 0 1 0 382.1 548.7 344.2 344.2 0 0 0 166.3 788.7 441.4 441.4 0 1 1 833.2 788.7ZM833.4 788.8", + "width": 1000 + }, + "search": [ + "user_menu_icon" + ] + }, + { + "uid": "d3f621623139837ff2fb5fe09cf16994", + "css": "cart_menu_icon-1", + "code": 59416, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M367.1 624.3H972.6A33.2 33.2 0 0 0 1004.7 601.7L1138.2 164.7A29.6 29.6 0 0 0 1132.9 137.3 34.3 34.3 0 0 0 1106.3 124.9H289.9L266.3 24.5A33 33 0 0 0 233.7 0H33.4A32.4 32.4 0 0 0 0 31.2 32.4 32.4 0 0 0 33.4 62.4H206.9L327.4 569.6A93.8 93.8 0 0 0 267.1 655.5 97.1 97.1 0 0 0 367.2 749.1H972.6A31.3 31.3 0 1 0 972.6 686.7H367.2A31.3 31.3 0 1 1 367.2 624.3ZM1061.9 187.3L947.4 561.9H394L305 187.3ZM1061.9 187.3M315.3 894.6A105.4 105.4 0 1 0 420.7 789.2 105.4 105.4 0 0 0 315.3 894.6ZM420.7 859.4A35.2 35.2 0 1 1 385.6 894.6 35.2 35.2 0 0 1 420.7 859.4ZM420.7 859.4M735.4 894.6A105.4 105.4 0 1 0 840.9 789.2 105.4 105.4 0 0 0 735.4 894.6ZM840.9 859.4A35.2 35.2 0 1 1 805.7 894.6 35.2 35.2 0 0 1 840.9 859.4ZM840.9 859.4", + "width": 1140 + }, + "search": [ + "cart_menu_icon" + ] + }, + { + "uid": "6aac6f399374da0b9c4811b6a7110627", + "css": "categories_menu_icon-1", + "code": 59417, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M332.7 458.9H126.3A126.3 126.3 0 0 1 0 332.7V126.3A126.3 126.3 0 0 1 126.3 0H332.7A126.3 126.3 0 0 1 459 126.3V332.7A126.3 126.3 0 0 1 332.7 458.9ZM126.3 61.2A65.1 65.1 0 0 0 61.2 126.3V332.7A65.1 65.1 0 0 0 126.3 397.8H332.7A65.1 65.1 0 0 0 397.8 332.7V126.3A65.1 65.1 0 0 0 332.7 61.2ZM873.8 458.9H667.3A126.3 126.3 0 0 1 541 332.6V126.3A126.3 126.3 0 0 1 667.3 0H873.9A126.3 126.3 0 0 1 1000.2 126.3V332.7A126.3 126.3 0 0 1 873.8 458.9ZM667.3 61.2A65.1 65.1 0 0 0 602.2 126.3V332.7A65.1 65.1 0 0 0 667.3 397.8H873.9A65.1 65.1 0 0 0 938.9 332.7V126.3A65.1 65.1 0 0 0 873.9 61.3ZM332.7 999.9H126.3A126.3 126.3 0 0 1 0 873.7V667.3A126.3 126.3 0 0 1 126.3 541H332.7A126.3 126.3 0 0 1 459 667.3V873.9A126.3 126.3 0 0 1 332.7 999.9ZM126.3 602.2A65.1 65.1 0 0 0 61.2 667.3V873.9A65.1 65.1 0 0 0 126.3 938.8H332.7A65.1 65.1 0 0 0 397.8 873.8V667.3A65.1 65.1 0 0 0 332.7 602.3ZM873.8 999.9H667.3A126.3 126.3 0 0 1 541 873.7V667.3A126.3 126.3 0 0 1 667.3 541H873.8A126.3 126.3 0 0 1 1000.1 667.3V873.9A126.3 126.3 0 0 1 873.8 999.9ZM667.3 602.2A65.1 65.1 0 0 0 602.2 667.3V873.9A65.1 65.1 0 0 0 667.3 938.8H873.8A65.1 65.1 0 0 0 938.8 873.8V667.3A65.1 65.1 0 0 0 873.8 602.3Z", + "width": 1000 + }, + "search": [ + "categories_menu_icon" + ] + }, + { + "uid": "0a4cf1ff2671b9ea852d635e27df1e69", + "css": "hmg_logo_icon-1", + "code": 59418, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M146 835.7S180.9 835.5 205.5 835.5L392.2 836.4C414.4 836.4 433 812.7 434 778.5L434 622.5C434 589.3 448.9 563.3 472 561.7L529.2 561.2C552.3 562.7 568.1 588.9 568.1 622L568.1 778.9C569.2 813.1 584.7 835.5 607.1 835.5L858.4 836.1 858.8 643.3C858.8 610.2 842.9 584.4 819.8 583L718.8 582.5C696.5 582.5 678.9 558.9 677.9 524.7L677.5 472.6C678.6 438.4 696.4 414.8 718.7 414.8L820.2 415.1C843.3 413.6 858.3 386.4 858.3 353.3L858.5 112.8A102.4 102.4 0 0 1 780.8 161.4L610.2 161.4C587.9 161.4 569.4 185.7 568.3 219.9V374.6C567.2 408.8 549.8 432.9 527.5 432.9L475.8 432C453.4 432 435.6 408.6 434.5 374.7L434.5 218.4C433.4 184.3 415.6 161.2 393.4 161.2L145.6 161.2 145.6 353.4C145.6 386.6 161.2 413.1 184.3 414.7L285.8 414.3C308.8 415.8 325.1 443.2 325.1 476.2L324.8 520.7C324.8 553.8 309.1 580.4 286 581.9L184.3 581.7C161.2 583.3 145.6 609.5 145.6 642.6ZM999.3 99.1V902.8A102.2 102.2 0 0 1 896 1000H102.8A101.9 101.9 0 0 1 0 902.8L0 97.6A102.3 102.3 0 0 1 103 0L895.4 0.3A104 104 0 0 1 999.3 99.1Z", + "width": 999 + }, + "search": [ + "hmg_logo_icon" + ] + }, + { + "uid": "d19eb878f1dee49848276b6d0faa6602", + "css": "wishlist_menu_icon", + "code": 59411, + "src": "custom_icons", + "selected": false, + "svg": { + "path": "M877.6 0A394.8 394.8 0 0 0 600.7 112.2 394.8 394.8 0 0 0 323.8 0 332.4 332.4 0 0 0 0 349 515.4 515.4 0 0 0 138.3 679.5 1351.1 1351.1 0 0 0 580.3 995.3 46.9 46.9 0 0 0 621.1 995.3 1351.1 1351.1 0 0 0 1063.1 679.5 515.4 515.4 0 0 0 1201.4 349 332.5 332.5 0 0 0 877.6 0ZM991.8 618.5A1233.8 1233.8 0 0 1 600.7 900.8 1233.7 1233.7 0 0 1 209.5 618.5 418.4 418.4 0 0 1 93.8 349 239.1 239.1 0 0 1 323.8 93.8 297.2 297.2 0 0 1 500.6 150.7 283.5 283.5 0 0 1 562 209.5 46.5 46.5 0 0 0 600.5 230H600.5A46.9 46.9 0 0 0 639.1 209.3 301.2 301.2 0 0 1 877.2 93.8 239.2 239.2 0 0 1 1107.1 349 418.4 418.4 0 0 1 991.8 618.5Z", + "width": 1201 + }, + "search": [ + "wishlist_menu_icon" + ] } ] } \ No newline at end of file diff --git a/assets/app_icons/fonts/DQIcons.ttf b/assets/app_icons/fonts/DQIcons.ttf index bc92c83d..e0a15c88 100644 Binary files a/assets/app_icons/fonts/DQIcons.ttf and b/assets/app_icons/fonts/DQIcons.ttf differ diff --git a/assets/applepay.json b/assets/applepay.json new file mode 100644 index 00000000..7817eb67 --- /dev/null +++ b/assets/applepay.json @@ -0,0 +1,21 @@ +{ + "provider": "apple_pay", + "data": { + "merchantIdentifier": "merchant.com.hmgwebservices", + "displayName": "Sulaiman Al Habib", + "merchantCapabilities": [ + "3DS", + "debit", + "credit" + ], + "supportedNetworks": [ + "visa", + "masterCard", + "mada" + ], + "countryCode": "SA", + "currencyCode": "SAR", + "requiredBillingContactFields": null, + "requiredShippingContactFields": null + } +} \ No newline at end of file diff --git a/assets/fonts/ar/Cairo-Regular/Cairo-Regular.ttf b/assets/fonts/ar/Cairo-Regular/Cairo-Regular.ttf new file mode 100644 index 00000000..3eb09f86 Binary files /dev/null and b/assets/fonts/ar/Cairo-Regular/Cairo-Regular.ttf differ diff --git a/assets/fonts/poppins/Poppins-Black.ttf b/assets/fonts/poppins/Poppins-Black.ttf new file mode 100644 index 00000000..a9520b78 Binary files /dev/null and b/assets/fonts/poppins/Poppins-Black.ttf differ diff --git a/assets/fonts/poppins/Poppins-Bold.ttf b/assets/fonts/poppins/Poppins-Bold.ttf new file mode 100644 index 00000000..b94d47f3 Binary files /dev/null and b/assets/fonts/poppins/Poppins-Bold.ttf differ diff --git a/assets/fonts/poppins/Poppins-ExtraBold.ttf b/assets/fonts/poppins/Poppins-ExtraBold.ttf new file mode 100644 index 00000000..8f008c36 Binary files /dev/null and b/assets/fonts/poppins/Poppins-ExtraBold.ttf differ diff --git a/assets/fonts/poppins/Poppins-ExtraLight.ttf b/assets/fonts/poppins/Poppins-ExtraLight.ttf new file mode 100644 index 00000000..ee623825 Binary files /dev/null and b/assets/fonts/poppins/Poppins-ExtraLight.ttf differ diff --git a/assets/fonts/poppins/Poppins-Light.ttf b/assets/fonts/poppins/Poppins-Light.ttf new file mode 100644 index 00000000..2ab02219 Binary files /dev/null and b/assets/fonts/poppins/Poppins-Light.ttf differ diff --git a/assets/fonts/poppins/Poppins-Medium.ttf b/assets/fonts/poppins/Poppins-Medium.ttf new file mode 100644 index 00000000..e90e87ed Binary files /dev/null and b/assets/fonts/poppins/Poppins-Medium.ttf differ diff --git a/assets/fonts/poppins/Poppins-Regular.ttf b/assets/fonts/poppins/Poppins-Regular.ttf new file mode 100644 index 00000000..be06e7fd Binary files /dev/null and b/assets/fonts/poppins/Poppins-Regular.ttf differ diff --git a/assets/fonts/poppins/Poppins-SemiBold.ttf b/assets/fonts/poppins/Poppins-SemiBold.ttf new file mode 100644 index 00000000..dabf7c24 Binary files /dev/null and b/assets/fonts/poppins/Poppins-SemiBold.ttf differ diff --git a/assets/fonts/poppins/Poppins-Thin.ttf b/assets/fonts/poppins/Poppins-Thin.ttf new file mode 100644 index 00000000..f5c0fdd5 Binary files /dev/null and b/assets/fonts/poppins/Poppins-Thin.ttf differ diff --git a/assets/fonts/sar-Regular.otf b/assets/fonts/sar-Regular.otf new file mode 100644 index 00000000..e906f654 Binary files /dev/null and b/assets/fonts/sar-Regular.otf differ diff --git a/assets/fonts/saudi_riyal.eot b/assets/fonts/saudi_riyal.eot new file mode 100644 index 00000000..f85e9aa1 Binary files /dev/null and b/assets/fonts/saudi_riyal.eot differ diff --git a/assets/fonts/saudi_riyal.ttf b/assets/fonts/saudi_riyal.ttf new file mode 100644 index 00000000..a0f1b762 Binary files /dev/null and b/assets/fonts/saudi_riyal.ttf differ diff --git a/assets/fonts/saudi_riyal.woff b/assets/fonts/saudi_riyal.woff new file mode 100644 index 00000000..7d733e98 Binary files /dev/null and b/assets/fonts/saudi_riyal.woff differ diff --git a/assets/fonts/saudi_riyal.woff2 b/assets/fonts/saudi_riyal.woff2 new file mode 100644 index 00000000..f8072477 Binary files /dev/null and b/assets/fonts/saudi_riyal.woff2 differ diff --git a/assets/images/AlHabibMedicalService/health_calculator/bmi.png b/assets/images/AlHabibMedicalService/health_calculator/bmi.png new file mode 100644 index 00000000..6df6c9f9 Binary files /dev/null and b/assets/images/AlHabibMedicalService/health_calculator/bmi.png differ diff --git a/assets/images/BMI/BMIChart_AR.png b/assets/images/BMI/BMIChart_AR.png deleted file mode 100644 index 405574c0..00000000 Binary files a/assets/images/BMI/BMIChart_AR.png and /dev/null differ diff --git a/assets/images/BMI/BMIChart_EN.png b/assets/images/BMI/BMIChart_EN.png deleted file mode 100644 index 2432e888..00000000 Binary files a/assets/images/BMI/BMIChart_EN.png and /dev/null differ diff --git a/assets/images/BMI/bmi_blue_female_ar.png b/assets/images/BMI/bmi_blue_female_ar.png deleted file mode 100644 index 483cb664..00000000 Binary files a/assets/images/BMI/bmi_blue_female_ar.png and /dev/null differ diff --git a/assets/images/BMI/bmi_blue_female_en.png b/assets/images/BMI/bmi_blue_female_en.png deleted file mode 100644 index 9984736e..00000000 Binary files a/assets/images/BMI/bmi_blue_female_en.png and /dev/null differ diff --git a/assets/images/BMI/bmi_blue_male_ar.png b/assets/images/BMI/bmi_blue_male_ar.png deleted file mode 100644 index d4ff734c..00000000 Binary files a/assets/images/BMI/bmi_blue_male_ar.png and /dev/null differ diff --git a/assets/images/BMI/bmi_blue_male_en.png b/assets/images/BMI/bmi_blue_male_en.png deleted file mode 100644 index ec50a0c6..00000000 Binary files a/assets/images/BMI/bmi_blue_male_en.png and /dev/null differ diff --git a/assets/images/BMI/bmi_green_female_ar.png b/assets/images/BMI/bmi_green_female_ar.png deleted file mode 100644 index f8dc4759..00000000 Binary files a/assets/images/BMI/bmi_green_female_ar.png and /dev/null differ diff --git a/assets/images/BMI/bmi_green_female_en.png b/assets/images/BMI/bmi_green_female_en.png deleted file mode 100644 index b4eb32e0..00000000 Binary files a/assets/images/BMI/bmi_green_female_en.png and /dev/null differ diff --git a/assets/images/BMI/bmi_green_male_ar.png b/assets/images/BMI/bmi_green_male_ar.png deleted file mode 100644 index 380d8384..00000000 Binary files a/assets/images/BMI/bmi_green_male_ar.png and /dev/null differ diff --git a/assets/images/BMI/bmi_green_male_en.png b/assets/images/BMI/bmi_green_male_en.png deleted file mode 100644 index 78693310..00000000 Binary files a/assets/images/BMI/bmi_green_male_en.png and /dev/null differ diff --git a/assets/images/BMI/bmi_orange_female_ar.png b/assets/images/BMI/bmi_orange_female_ar.png deleted file mode 100644 index b2437c14..00000000 Binary files a/assets/images/BMI/bmi_orange_female_ar.png and /dev/null differ diff --git a/assets/images/BMI/bmi_orange_female_en.png b/assets/images/BMI/bmi_orange_female_en.png deleted file mode 100644 index 31779cd3..00000000 Binary files a/assets/images/BMI/bmi_orange_female_en.png and /dev/null differ diff --git a/assets/images/BMI/bmi_orange_male_ar.png b/assets/images/BMI/bmi_orange_male_ar.png deleted file mode 100644 index 291b316e..00000000 Binary files a/assets/images/BMI/bmi_orange_male_ar.png and /dev/null differ diff --git a/assets/images/BMI/bmi_orange_male_en.png b/assets/images/BMI/bmi_orange_male_en.png deleted file mode 100644 index c6ebb5eb..00000000 Binary files a/assets/images/BMI/bmi_orange_male_en.png and /dev/null differ diff --git a/assets/images/BMI/bmi_red_female_ar.png b/assets/images/BMI/bmi_red_female_ar.png deleted file mode 100644 index 0e4d7339..00000000 Binary files a/assets/images/BMI/bmi_red_female_ar.png and /dev/null differ diff --git a/assets/images/BMI/bmi_red_female_en.png b/assets/images/BMI/bmi_red_female_en.png deleted file mode 100644 index 0d5dfe80..00000000 Binary files a/assets/images/BMI/bmi_red_female_en.png and /dev/null differ diff --git a/assets/images/BMI/bmi_red_male_ar.png b/assets/images/BMI/bmi_red_male_ar.png deleted file mode 100644 index 86a47cb2..00000000 Binary files a/assets/images/BMI/bmi_red_male_ar.png and /dev/null differ diff --git a/assets/images/BMI/bmi_red_male_en.png b/assets/images/BMI/bmi_red_male_en.png deleted file mode 100644 index 452aa4f3..00000000 Binary files a/assets/images/BMI/bmi_red_male_en.png and /dev/null differ diff --git a/assets/images/BMI/bmi_yellow_female_ar.png b/assets/images/BMI/bmi_yellow_female_ar.png deleted file mode 100644 index 7453a642..00000000 Binary files a/assets/images/BMI/bmi_yellow_female_ar.png and /dev/null differ diff --git a/assets/images/BMI/bmi_yellow_female_en.png b/assets/images/BMI/bmi_yellow_female_en.png deleted file mode 100644 index d2374c22..00000000 Binary files a/assets/images/BMI/bmi_yellow_female_en.png and /dev/null differ diff --git a/assets/images/BMI/bmi_yellow_male_ar.png b/assets/images/BMI/bmi_yellow_male_ar.png deleted file mode 100644 index 754cf6ea..00000000 Binary files a/assets/images/BMI/bmi_yellow_male_ar.png and /dev/null differ diff --git a/assets/images/BMI/bmi_yellow_male_en.png b/assets/images/BMI/bmi_yellow_male_en.png deleted file mode 100644 index f64decfe..00000000 Binary files a/assets/images/BMI/bmi_yellow_male_en.png and /dev/null differ diff --git a/assets/images/CloseIcon.png b/assets/images/CloseIcon.png deleted file mode 100644 index b8e68fea..00000000 Binary files a/assets/images/CloseIcon.png and /dev/null differ diff --git a/assets/images/DQ/DQ_logo.png b/assets/images/DQ/DQ_logo.png deleted file mode 100644 index 993a1bd3..00000000 Binary files a/assets/images/DQ/DQ_logo.png and /dev/null differ diff --git a/assets/images/DQ/doctor_information_icon.svg b/assets/images/DQ/doctor_information_icon.svg new file mode 100644 index 00000000..0d0fe955 --- /dev/null +++ b/assets/images/DQ/doctor_information_icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/DQ/doctor_qualification_icon.svg b/assets/images/DQ/doctor_qualification_icon.svg new file mode 100644 index 00000000..ab4723c4 --- /dev/null +++ b/assets/images/DQ/doctor_qualification_icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/DQ/dq_logo_icon.png b/assets/images/DQ/dq_logo_icon.png deleted file mode 100644 index 71626bd8..00000000 Binary files a/assets/images/DQ/dq_logo_icon.png and /dev/null differ diff --git a/assets/images/DQ/logo_big.png b/assets/images/DQ/logo_big.png deleted file mode 100644 index 0d9e4a56..00000000 Binary files a/assets/images/DQ/logo_big.png and /dev/null differ diff --git a/assets/images/DQ/medical_card_bg.svg b/assets/images/DQ/medical_card_bg.svg new file mode 100644 index 00000000..389559af --- /dev/null +++ b/assets/images/DQ/medical_card_bg.svg @@ -0,0 +1,314 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/Dr_Schedule_report.png b/assets/images/Dr_Schedule_report.png deleted file mode 100644 index 9519f719..00000000 Binary files a/assets/images/Dr_Schedule_report.png and /dev/null differ diff --git a/assets/images/SmartWatches/distance.png b/assets/images/SmartWatches/distance.png new file mode 100644 index 00000000..d07f3e8a Binary files /dev/null and b/assets/images/SmartWatches/distance.png differ diff --git a/assets/images/SmartWatches/fossil-sport.png b/assets/images/SmartWatches/fossil-sport.png deleted file mode 100644 index 207bbbe3..00000000 Binary files a/assets/images/SmartWatches/fossil-sport.png and /dev/null differ diff --git a/assets/images/SmartWatches/steps.png b/assets/images/SmartWatches/steps.png new file mode 100644 index 00000000..974668ea Binary files /dev/null and b/assets/images/SmartWatches/steps.png differ diff --git a/assets/images/al-habib_onlne_pharmacy_bg.png b/assets/images/al-habib_onlne_pharmacy_bg.png deleted file mode 100644 index d8809570..00000000 Binary files a/assets/images/al-habib_onlne_pharmacy_bg.png and /dev/null differ diff --git a/assets/images/appointment_booking.png b/assets/images/appointment_booking.png deleted file mode 100644 index 14db8d89..00000000 Binary files a/assets/images/appointment_booking.png and /dev/null differ diff --git a/assets/images/ask_doctor.png b/assets/images/ask_doctor.png deleted file mode 100644 index f74ac6a8..00000000 Binary files a/assets/images/ask_doctor.png and /dev/null differ diff --git a/assets/images/ask_doctor_bg.png b/assets/images/ask_doctor_bg.png deleted file mode 100644 index 16e8e9d7..00000000 Binary files a/assets/images/ask_doctor_bg.png and /dev/null differ diff --git a/assets/images/bc_parking.png b/assets/images/bc_parking.png new file mode 100644 index 00000000..64633516 Binary files /dev/null and b/assets/images/bc_parking.png differ diff --git a/assets/images/bg_graphic.png b/assets/images/bg_graphic.png deleted file mode 100644 index 01525404..00000000 Binary files a/assets/images/bg_graphic.png and /dev/null differ diff --git a/assets/images/blood-drop.png b/assets/images/blood-drop.png deleted file mode 100644 index a981e3d3..00000000 Binary files a/assets/images/blood-drop.png and /dev/null differ diff --git a/assets/images/book_appointment_arabic.png b/assets/images/book_appointment_arabic.png deleted file mode 100644 index f0bc5aff..00000000 Binary files a/assets/images/book_appointment_arabic.png and /dev/null differ diff --git a/assets/images/booking_ar.png b/assets/images/booking_ar.png deleted file mode 100644 index b562f288..00000000 Binary files a/assets/images/booking_ar.png and /dev/null differ diff --git a/assets/images/booking_en.png b/assets/images/booking_en.png deleted file mode 100644 index a3ffa8be..00000000 Binary files a/assets/images/booking_en.png and /dev/null differ diff --git a/assets/images/call_down.svg b/assets/images/call_down.svg new file mode 100644 index 00000000..bd4f7f61 --- /dev/null +++ b/assets/images/call_down.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/images/call_on.svg b/assets/images/call_on.svg new file mode 100644 index 00000000..2f54c0e8 --- /dev/null +++ b/assets/images/call_on.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/images/cc_ar.png b/assets/images/cc_ar.png new file mode 100644 index 00000000..e4388ba2 Binary files /dev/null and b/assets/images/cc_ar.png differ diff --git a/assets/images/cc_en.png b/assets/images/cc_en.png new file mode 100644 index 00000000..c11cf5e6 Binary files /dev/null and b/assets/images/cc_en.png differ diff --git a/assets/images/contact_us_bg.png b/assets/images/contact_us_bg.png deleted file mode 100644 index 40564039..00000000 Binary files a/assets/images/contact_us_bg.png and /dev/null differ diff --git a/assets/images/covid_bg_transparent.png b/assets/images/covid_bg_transparent.png deleted file mode 100644 index cd5f12f1..00000000 Binary files a/assets/images/covid_bg_transparent.png and /dev/null differ diff --git a/assets/images/cs_logo_container.png b/assets/images/cs_logo_container.png deleted file mode 100644 index 5f938580..00000000 Binary files a/assets/images/cs_logo_container.png and /dev/null differ diff --git a/assets/images/dashboard_top_bg.png b/assets/images/dashboard_top_bg.png deleted file mode 100644 index 98b4c943..00000000 Binary files a/assets/images/dashboard_top_bg.png and /dev/null differ diff --git a/assets/images/discount_ar.png b/assets/images/discount_ar.png deleted file mode 100644 index 854d1c1f..00000000 Binary files a/assets/images/discount_ar.png and /dev/null differ diff --git a/assets/images/discount_en.png b/assets/images/discount_en.png deleted file mode 100644 index 2af52865..00000000 Binary files a/assets/images/discount_en.png and /dev/null differ diff --git a/assets/images/dq_home_page_bg_image.png b/assets/images/dq_home_page_bg_image.png deleted file mode 100644 index f70df2ae..00000000 Binary files a/assets/images/dq_home_page_bg_image.png and /dev/null differ diff --git a/assets/images/heartbeat.png b/assets/images/heartbeat.png deleted file mode 100644 index 3a83ddee..00000000 Binary files a/assets/images/heartbeat.png and /dev/null differ diff --git a/assets/images/height_icon.png b/assets/images/height_icon.png deleted file mode 100644 index cca88ac0..00000000 Binary files a/assets/images/height_icon.png and /dev/null differ diff --git a/assets/images/hmg_services_bg .png b/assets/images/hmg_services_bg .png deleted file mode 100644 index 508f9a0d..00000000 Binary files a/assets/images/hmg_services_bg .png and /dev/null differ diff --git a/assets/images/home_health_care_icon.png b/assets/images/home_health_care_icon.png deleted file mode 100644 index d80ec015..00000000 Binary files a/assets/images/home_health_care_icon.png and /dev/null differ diff --git a/assets/images/home_healthcare_service_bg.png b/assets/images/home_healthcare_service_bg.png deleted file mode 100644 index 2765b47e..00000000 Binary files a/assets/images/home_healthcare_service_bg.png and /dev/null differ diff --git a/assets/images/icon.png b/assets/images/icon.png new file mode 100644 index 00000000..e802ae3e Binary files /dev/null and b/assets/images/icon.png differ diff --git a/assets/images/inpatient_advance.png b/assets/images/inpatient_advance.png new file mode 100644 index 00000000..38f1b7f4 Binary files /dev/null and b/assets/images/inpatient_advance.png differ diff --git a/assets/images/lang.png b/assets/images/lang.png new file mode 100644 index 00000000..34af3d9a Binary files /dev/null and b/assets/images/lang.png differ diff --git a/assets/images/livecare_white_logo.png b/assets/images/livecare_white_logo.png deleted file mode 100644 index dc223965..00000000 Binary files a/assets/images/livecare_white_logo.png and /dev/null differ diff --git a/assets/images/login/101.png b/assets/images/login/101.png deleted file mode 100644 index 90c1c575..00000000 Binary files a/assets/images/login/101.png and /dev/null differ diff --git a/assets/images/login/102.png b/assets/images/login/102.png deleted file mode 100644 index 8502d197..00000000 Binary files a/assets/images/login/102.png and /dev/null differ diff --git a/assets/images/login/104.png b/assets/images/login/104.png deleted file mode 100644 index ad55ff74..00000000 Binary files a/assets/images/login/104.png and /dev/null differ diff --git a/assets/images/login/fileNum.png b/assets/images/login/fileNum.png deleted file mode 100644 index 386299b7..00000000 Binary files a/assets/images/login/fileNum.png and /dev/null differ diff --git a/assets/images/login/forget.png b/assets/images/login/forget.png deleted file mode 100644 index 57aa7ccc..00000000 Binary files a/assets/images/login/forget.png and /dev/null differ diff --git a/assets/images/login/id.png b/assets/images/login/id.png deleted file mode 100644 index 9260cf11..00000000 Binary files a/assets/images/login/id.png and /dev/null differ diff --git a/assets/images/login/nationalID.png b/assets/images/login/nationalID.png deleted file mode 100644 index 5779d562..00000000 Binary files a/assets/images/login/nationalID.png and /dev/null differ diff --git a/assets/images/logo_HMG.png b/assets/images/logo_HMG.png deleted file mode 100644 index 0d9e4a56..00000000 Binary files a/assets/images/logo_HMG.png and /dev/null differ diff --git a/assets/images/map_markers/driver-pin.png b/assets/images/map_markers/driver-pin.png deleted file mode 100644 index 9d16ceca..00000000 Binary files a/assets/images/map_markers/driver-pin.png and /dev/null differ diff --git a/assets/images/medical/Invoice.png b/assets/images/medical/Invoice.png new file mode 100644 index 00000000..1e3b6f25 Binary files /dev/null and b/assets/images/medical/Invoice.png differ diff --git a/assets/images/medical/my_appointment_icon.png b/assets/images/medical/my_appointment_icon.png deleted file mode 100644 index f5e4c7d4..00000000 Binary files a/assets/images/medical/my_appointment_icon.png and /dev/null differ diff --git a/assets/images/medical/radiology_icon.png b/assets/images/medical/radiology_icon.png deleted file mode 100644 index 9e760d65..00000000 Binary files a/assets/images/medical/radiology_icon.png and /dev/null differ diff --git a/assets/images/medical/vital_sign_icon.png b/assets/images/medical/vital_sign_icon.png deleted file mode 100644 index fbd0908b..00000000 Binary files a/assets/images/medical/vital_sign_icon.png and /dev/null differ diff --git a/assets/images/new-design/HMG_logo.svg b/assets/images/new-design/HMG_logo.svg new file mode 100644 index 00000000..0e4895c3 --- /dev/null +++ b/assets/images/new-design/HMG_logo.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/images/new-design/NFCIcon_option2.png b/assets/images/new-design/NFCIcon_option2.png new file mode 100644 index 00000000..938eec27 Binary files /dev/null and b/assets/images/new-design/NFCIcon_option2.png differ diff --git a/assets/images/new-design/ViewDetailsIco.png b/assets/images/new-design/ViewDetailsIco.png new file mode 100644 index 00000000..cd58bddb Binary files /dev/null and b/assets/images/new-design/ViewDetailsIco.png differ diff --git a/assets/images/new-design/add_user_icon.png b/assets/images/new-design/add_user_icon.png deleted file mode 100644 index b8a1d795..00000000 Binary files a/assets/images/new-design/add_user_icon.png and /dev/null differ diff --git a/assets/images/new-design/advance_payment.png b/assets/images/new-design/advance_payment.png deleted file mode 100644 index 2889e6fc..00000000 Binary files a/assets/images/new-design/advance_payment.png and /dev/null differ diff --git a/assets/images/new-design/alert_icon.svg b/assets/images/new-design/alert_icon.svg new file mode 100644 index 00000000..51bc9f3c --- /dev/null +++ b/assets/images/new-design/alert_icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/new-design/alert_top-bar_icon.png b/assets/images/new-design/alert_top-bar_icon.png deleted file mode 100644 index c275fca9..00000000 Binary files a/assets/images/new-design/alert_top-bar_icon.png and /dev/null differ diff --git a/assets/images/new-design/alert_top-bar_icon_red.png b/assets/images/new-design/alert_top-bar_icon_red.png deleted file mode 100644 index 881ab3ac..00000000 Binary files a/assets/images/new-design/alert_top-bar_icon_red.png and /dev/null differ diff --git a/assets/images/new-design/allow.svg b/assets/images/new-design/allow.svg new file mode 100644 index 00000000..a38817f2 --- /dev/null +++ b/assets/images/new-design/allow.svg @@ -0,0 +1,6 @@ + + + + ✓ + + diff --git a/assets/images/new-design/ambulance.png b/assets/images/new-design/ambulance.png deleted file mode 100644 index 7d8a26c8..00000000 Binary files a/assets/images/new-design/ambulance.png and /dev/null differ diff --git a/assets/images/new-design/applepay.svg b/assets/images/new-design/applepay.svg new file mode 100644 index 00000000..8e0df8c7 --- /dev/null +++ b/assets/images/new-design/applepay.svg @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/new-design/appointment_booking.png b/assets/images/new-design/appointment_booking.png deleted file mode 100644 index 14db8d89..00000000 Binary files a/assets/images/new-design/appointment_booking.png and /dev/null differ diff --git a/assets/images/new-design/appointment_info.png b/assets/images/new-design/appointment_info.png deleted file mode 100644 index 9f2b8c50..00000000 Binary files a/assets/images/new-design/appointment_info.png and /dev/null differ diff --git a/assets/images/new-design/arrow.png b/assets/images/new-design/arrow.png deleted file mode 100644 index 19af7c0b..00000000 Binary files a/assets/images/new-design/arrow.png and /dev/null differ diff --git a/assets/images/new-design/arrow_black.png b/assets/images/new-design/arrow_black.png deleted file mode 100644 index c2132d3e..00000000 Binary files a/assets/images/new-design/arrow_black.png and /dev/null differ diff --git a/assets/images/new-design/arrow_menu_red.png b/assets/images/new-design/arrow_menu_red.png deleted file mode 100644 index de7639ea..00000000 Binary files a/assets/images/new-design/arrow_menu_red.png and /dev/null differ diff --git a/assets/images/new-design/arrow_white.png b/assets/images/new-design/arrow_white.png deleted file mode 100644 index 0c2fa7a4..00000000 Binary files a/assets/images/new-design/arrow_white.png and /dev/null differ diff --git a/assets/images/new-design/attach-prescription.png b/assets/images/new-design/attach-prescription.png deleted file mode 100644 index fc1b649b..00000000 Binary files a/assets/images/new-design/attach-prescription.png and /dev/null differ diff --git a/assets/images/new-design/available_vaccines_to_bar.png b/assets/images/new-design/available_vaccines_to_bar.png deleted file mode 100644 index b988355f..00000000 Binary files a/assets/images/new-design/available_vaccines_to_bar.png and /dev/null differ diff --git a/assets/images/new-design/awesome-star.png b/assets/images/new-design/awesome-star.png deleted file mode 100644 index 36153c59..00000000 Binary files a/assets/images/new-design/awesome-star.png and /dev/null differ diff --git a/assets/images/new-design/blood_pressure_icon.png b/assets/images/new-design/blood_pressure_icon.png deleted file mode 100644 index 0d622094..00000000 Binary files a/assets/images/new-design/blood_pressure_icon.png and /dev/null differ diff --git a/assets/images/new-design/blood_type.png b/assets/images/new-design/blood_type.png deleted file mode 100644 index c0e09ae4..00000000 Binary files a/assets/images/new-design/blood_type.png and /dev/null differ diff --git a/assets/images/new-design/body_icon.png b/assets/images/new-design/body_icon.png deleted file mode 100644 index b9a70b2b..00000000 Binary files a/assets/images/new-design/body_icon.png and /dev/null differ diff --git a/assets/images/new-design/body_mass.png b/assets/images/new-design/body_mass.png deleted file mode 100644 index 01cebfb8..00000000 Binary files a/assets/images/new-design/body_mass.png and /dev/null differ diff --git a/assets/images/new-design/body_mass_icon.png b/assets/images/new-design/body_mass_icon.png deleted file mode 100644 index c93a31cb..00000000 Binary files a/assets/images/new-design/body_mass_icon.png and /dev/null differ diff --git a/assets/images/new-design/book_appointment_arabic.png b/assets/images/new-design/book_appointment_arabic.png deleted file mode 100644 index f0bc5aff..00000000 Binary files a/assets/images/new-design/book_appointment_arabic.png and /dev/null differ diff --git a/assets/images/new-design/booking_icon.png b/assets/images/new-design/booking_icon.png deleted file mode 100644 index 8693a1fe..00000000 Binary files a/assets/images/new-design/booking_icon.png and /dev/null differ diff --git a/assets/images/new-design/calendar_reminder_black_icon.svg b/assets/images/new-design/calendar_reminder_black_icon.svg deleted file mode 100644 index 8885e241..00000000 --- a/assets/images/new-design/calendar_reminder_black_icon.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/assets/images/new-design/call.png b/assets/images/new-design/call.png deleted file mode 100644 index cf6713cb..00000000 Binary files a/assets/images/new-design/call.png and /dev/null differ diff --git a/assets/images/new-design/cancel.png b/assets/images/new-design/cancel.png deleted file mode 100644 index 5aa51245..00000000 Binary files a/assets/images/new-design/cancel.png and /dev/null differ diff --git a/assets/images/new-design/chat_with_us_icon.png b/assets/images/new-design/chat_with_us_icon.png deleted file mode 100644 index 6d2af727..00000000 Binary files a/assets/images/new-design/chat_with_us_icon.png and /dev/null differ diff --git a/assets/images/new-design/check-icon.png b/assets/images/new-design/check-icon.png deleted file mode 100644 index 669a4975..00000000 Binary files a/assets/images/new-design/check-icon.png and /dev/null differ diff --git a/assets/images/new-design/check_icon.svg b/assets/images/new-design/check_icon.svg new file mode 100644 index 00000000..911df584 --- /dev/null +++ b/assets/images/new-design/check_icon.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/images/new-design/clinic-wayfinding-2.png b/assets/images/new-design/clinic-wayfinding-2.png deleted file mode 100644 index 5ac63738..00000000 Binary files a/assets/images/new-design/clinic-wayfinding-2.png and /dev/null differ diff --git a/assets/images/new-design/confirm_appointment_icon.png b/assets/images/new-design/confirm_appointment_icon.png deleted file mode 100644 index 9918f4d5..00000000 Binary files a/assets/images/new-design/confirm_appointment_icon.png and /dev/null differ diff --git a/assets/images/new-design/connect_to_internet_icon.png b/assets/images/new-design/connect_to_internet_icon.png deleted file mode 100644 index 14e7758a..00000000 Binary files a/assets/images/new-design/connect_to_internet_icon.png and /dev/null differ diff --git a/assets/images/new-design/cs_logo.png b/assets/images/new-design/cs_logo.png deleted file mode 100644 index fa03e4f9..00000000 Binary files a/assets/images/new-design/cs_logo.png and /dev/null differ diff --git a/assets/images/new-design/delete.svg b/assets/images/new-design/delete.svg new file mode 100644 index 00000000..49b4d9d9 --- /dev/null +++ b/assets/images/new-design/delete.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/new-design/discount_offers.png b/assets/images/new-design/discount_offers.png deleted file mode 100644 index dd4a0d05..00000000 Binary files a/assets/images/new-design/discount_offers.png and /dev/null differ diff --git a/assets/images/new-design/doctor_book_physical_appointment.png b/assets/images/new-design/doctor_book_physical_appointment.png deleted file mode 100644 index 16458b29..00000000 Binary files a/assets/images/new-design/doctor_book_physical_appointment.png and /dev/null differ diff --git a/assets/images/new-design/doctor_information_icon.png b/assets/images/new-design/doctor_information_icon.png deleted file mode 100644 index cb210a97..00000000 Binary files a/assets/images/new-design/doctor_information_icon.png and /dev/null differ diff --git a/assets/images/new-design/doctor_qualification_icon.png b/assets/images/new-design/doctor_qualification_icon.png deleted file mode 100644 index 29225e6d..00000000 Binary files a/assets/images/new-design/doctor_qualification_icon.png and /dev/null differ diff --git a/assets/images/new-design/doctor_white.png b/assets/images/new-design/doctor_white.png new file mode 100644 index 00000000..bb5944cb Binary files /dev/null and b/assets/images/new-design/doctor_white.png differ diff --git a/assets/images/new-design/download_pharmacy_app.png b/assets/images/new-design/download_pharmacy_app.png deleted file mode 100644 index 89c64085..00000000 Binary files a/assets/images/new-design/download_pharmacy_app.png and /dev/null differ diff --git a/assets/images/new-design/emergency_videocall_icon.png b/assets/images/new-design/emergency_videocall_icon.png deleted file mode 100644 index 0f67e245..00000000 Binary files a/assets/images/new-design/emergency_videocall_icon.png and /dev/null differ diff --git a/assets/images/new-design/envelop_icon.png b/assets/images/new-design/envelop_icon.png deleted file mode 100644 index 86f21eb5..00000000 Binary files a/assets/images/new-design/envelop_icon.png and /dev/null differ diff --git a/assets/images/new-design/family_member_icon_active.png b/assets/images/new-design/family_member_icon_active.png deleted file mode 100644 index 5806c872..00000000 Binary files a/assets/images/new-design/family_member_icon_active.png and /dev/null differ diff --git a/assets/images/new-design/family_member_icon_inactive.png b/assets/images/new-design/family_member_icon_inactive.png deleted file mode 100644 index 59f6c912..00000000 Binary files a/assets/images/new-design/family_member_icon_inactive.png and /dev/null differ diff --git a/assets/images/new-design/family_menu_icon_red.png b/assets/images/new-design/family_menu_icon_red.png deleted file mode 100644 index 7d55094e..00000000 Binary files a/assets/images/new-design/family_menu_icon_red.png and /dev/null differ diff --git a/assets/images/new-design/generate_visit_ticket.png b/assets/images/new-design/generate_visit_ticket.png deleted file mode 100644 index 5d250853..00000000 Binary files a/assets/images/new-design/generate_visit_ticket.png and /dev/null differ diff --git a/assets/images/new-design/health_calculator_general.png b/assets/images/new-design/health_calculator_general.png deleted file mode 100644 index 2cc02679..00000000 Binary files a/assets/images/new-design/health_calculator_general.png and /dev/null differ diff --git a/assets/images/new-design/health_calculator_women.png b/assets/images/new-design/health_calculator_women.png deleted file mode 100644 index 2c292444..00000000 Binary files a/assets/images/new-design/health_calculator_women.png and /dev/null differ diff --git a/assets/images/new-design/heart_icon.png b/assets/images/new-design/heart_icon.png deleted file mode 100644 index 1cf02faf..00000000 Binary files a/assets/images/new-design/heart_icon.png and /dev/null differ diff --git a/assets/images/new-design/height.png b/assets/images/new-design/height.png deleted file mode 100644 index 718f8a5d..00000000 Binary files a/assets/images/new-design/height.png and /dev/null differ diff --git a/assets/images/new-design/height_icon.png b/assets/images/new-design/height_icon.png deleted file mode 100644 index cca88ac0..00000000 Binary files a/assets/images/new-design/height_icon.png and /dev/null differ diff --git a/assets/images/new-design/history_icon.png b/assets/images/new-design/history_icon.png deleted file mode 100644 index 8ef33358..00000000 Binary files a/assets/images/new-design/history_icon.png and /dev/null differ diff --git a/assets/images/new-design/hmg_full_logo.png b/assets/images/new-design/hmg_full_logo.png deleted file mode 100644 index 1449d28d..00000000 Binary files a/assets/images/new-design/hmg_full_logo.png and /dev/null differ diff --git a/assets/images/new-design/hmg_services.png b/assets/images/new-design/hmg_services.png deleted file mode 100644 index 5892dd84..00000000 Binary files a/assets/images/new-design/hmg_services.png and /dev/null differ diff --git a/assets/images/new-design/hmg_services_ar.png b/assets/images/new-design/hmg_services_ar.png deleted file mode 100644 index da5a5085..00000000 Binary files a/assets/images/new-design/hmg_services_ar.png and /dev/null differ diff --git a/assets/images/new-design/home_bottom_bar.png b/assets/images/new-design/home_bottom_bar.png deleted file mode 100644 index 49f4e84a..00000000 Binary files a/assets/images/new-design/home_bottom_bar.png and /dev/null differ diff --git a/assets/images/new-design/home_bottom_bar_active.png b/assets/images/new-design/home_bottom_bar_active.png deleted file mode 100644 index ce642d0b..00000000 Binary files a/assets/images/new-design/home_bottom_bar_active.png and /dev/null differ 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/assets/images/new-design/icon_check_list.png b/assets/images/new-design/icon_check_list.png deleted file mode 100644 index 1fc5ab3e..00000000 Binary files a/assets/images/new-design/icon_check_list.png and /dev/null differ diff --git a/assets/images/new-design/info-icon.png b/assets/images/new-design/info-icon.png deleted file mode 100644 index 49b1bc44..00000000 Binary files a/assets/images/new-design/info-icon.png and /dev/null differ diff --git a/assets/images/new-design/info_icon copy.png b/assets/images/new-design/info_icon copy.png deleted file mode 100644 index 49b1bc44..00000000 Binary files a/assets/images/new-design/info_icon copy.png and /dev/null differ diff --git a/assets/images/new-design/input_calendar_icon.png b/assets/images/new-design/input_calendar_icon.png deleted file mode 100644 index d3a51014..00000000 Binary files a/assets/images/new-design/input_calendar_icon.png and /dev/null differ diff --git a/assets/images/new-design/input_clock_icon.png b/assets/images/new-design/input_clock_icon.png deleted file mode 100644 index 67b15715..00000000 Binary files a/assets/images/new-design/input_clock_icon.png and /dev/null differ diff --git a/assets/images/new-design/ionic-ios-checkmark-circle.svg b/assets/images/new-design/ionic-ios-checkmark-circle.svg new file mode 100644 index 00000000..e38612b7 --- /dev/null +++ b/assets/images/new-design/ionic-ios-checkmark-circle.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/new-design/ionic-ios-eye.png b/assets/images/new-design/ionic-ios-eye.png deleted file mode 100644 index 93eabdfc..00000000 Binary files a/assets/images/new-design/ionic-ios-eye.png and /dev/null differ diff --git a/assets/images/new-design/lakum_icon.png b/assets/images/new-design/lakum_icon.png deleted file mode 100644 index eab11b56..00000000 Binary files a/assets/images/new-design/lakum_icon.png and /dev/null differ diff --git a/assets/images/new-design/list-icon-down.png b/assets/images/new-design/list-icon-down.png deleted file mode 100644 index 02c73b5b..00000000 Binary files a/assets/images/new-design/list-icon-down.png and /dev/null differ diff --git a/assets/images/new-design/list-icon-up.png b/assets/images/new-design/list-icon-up.png deleted file mode 100644 index eb6a6019..00000000 Binary files a/assets/images/new-design/list-icon-up.png and /dev/null differ diff --git a/assets/images/new-design/liveCare_logo_icon.svg b/assets/images/new-design/liveCare_logo_icon.svg new file mode 100644 index 00000000..15bdcff8 --- /dev/null +++ b/assets/images/new-design/liveCare_logo_icon.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/images/new-design/liveCare_logo_icon_white.svg b/assets/images/new-design/liveCare_logo_icon_white.svg new file mode 100644 index 00000000..52bce9b5 --- /dev/null +++ b/assets/images/new-design/liveCare_logo_icon_white.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/new-design/liveCare_logo_icon_white_check.svg b/assets/images/new-design/liveCare_logo_icon_white_check.svg new file mode 100644 index 00000000..52bce9b5 --- /dev/null +++ b/assets/images/new-design/liveCare_logo_icon_white_check.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/new-design/liveCare_mobile_care.svg b/assets/images/new-design/liveCare_mobile_care.svg new file mode 100644 index 00000000..6167aa3e --- /dev/null +++ b/assets/images/new-design/liveCare_mobile_care.svg @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Online Consultation + + + + + + + + + + + + + + + + diff --git a/assets/images/new-design/liveCare_white_logo.svg b/assets/images/new-design/liveCare_white_logo.svg deleted file mode 100644 index 494b3671..00000000 --- a/assets/images/new-design/liveCare_white_logo.svg +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - Online Consultation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/assets/images/new-design/livecare_arabic_logo.svg b/assets/images/new-design/livecare_arabic_logo.svg deleted file mode 100644 index c524a803..00000000 --- a/assets/images/new-design/livecare_arabic_logo.svg +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - استشارة مباشرة - - diff --git a/assets/images/new-design/livecare_white_logo.png b/assets/images/new-design/livecare_white_logo.png deleted file mode 100644 index dc223965..00000000 Binary files a/assets/images/new-design/livecare_white_logo.png and /dev/null differ diff --git a/assets/images/new-design/location-sharp.png b/assets/images/new-design/location-sharp.png deleted file mode 100644 index 9682fde1..00000000 Binary files a/assets/images/new-design/location-sharp.png and /dev/null differ diff --git a/assets/images/new-design/lock_icon.png b/assets/images/new-design/lock_icon.png deleted file mode 100644 index bf8c6aed..00000000 Binary files a/assets/images/new-design/lock_icon.png and /dev/null differ diff --git a/assets/images/new-design/main_user_icon_active.png b/assets/images/new-design/main_user_icon_active.png deleted file mode 100644 index d1005e17..00000000 Binary files a/assets/images/new-design/main_user_icon_active.png and /dev/null differ diff --git a/assets/images/new-design/main_user_icon_inaactive.png b/assets/images/new-design/main_user_icon_inaactive.png deleted file mode 100644 index b203d151..00000000 Binary files a/assets/images/new-design/main_user_icon_inaactive.png and /dev/null differ diff --git a/assets/images/new-design/medical_services.png b/assets/images/new-design/medical_services.png deleted file mode 100644 index 596ac34e..00000000 Binary files a/assets/images/new-design/medical_services.png and /dev/null differ diff --git a/assets/images/new-design/medical_services_ar.png b/assets/images/new-design/medical_services_ar.png deleted file mode 100644 index 082fe5fa..00000000 Binary files a/assets/images/new-design/medical_services_ar.png and /dev/null differ diff --git a/assets/images/new-design/medication-refill.png b/assets/images/new-design/medication-refill.png deleted file mode 100644 index fec82538..00000000 Binary files a/assets/images/new-design/medication-refill.png and /dev/null differ diff --git a/assets/images/new-design/my-prescription.png b/assets/images/new-design/my-prescription.png deleted file mode 100644 index 077c3453..00000000 Binary files a/assets/images/new-design/my-prescription.png and /dev/null differ diff --git a/assets/images/new-design/my_appointment_icon.png b/assets/images/new-design/my_appointment_icon.png deleted file mode 100644 index 94439627..00000000 Binary files a/assets/images/new-design/my_appointment_icon.png and /dev/null differ diff --git a/assets/images/new-design/my_doctor_icon.png b/assets/images/new-design/my_doctor_icon.png deleted file mode 100644 index 4043d64a..00000000 Binary files a/assets/images/new-design/my_doctor_icon.png and /dev/null differ diff --git a/assets/images/new-design/my_file_bottom_bar_active.png b/assets/images/new-design/my_file_bottom_bar_active.png deleted file mode 100644 index d00e22c3..00000000 Binary files a/assets/images/new-design/my_file_bottom_bar_active.png and /dev/null differ diff --git a/assets/images/new-design/navigate.png b/assets/images/new-design/navigate.png deleted file mode 100644 index 99cfa09a..00000000 Binary files a/assets/images/new-design/navigate.png and /dev/null differ diff --git a/assets/images/new-design/no-wait-queue.png b/assets/images/new-design/no-wait-queue.png deleted file mode 100644 index d87a172f..00000000 Binary files a/assets/images/new-design/no-wait-queue.png and /dev/null differ diff --git a/assets/images/new-design/passport.svg b/assets/images/new-design/passport.svg new file mode 100644 index 00000000..a3a060f0 --- /dev/null +++ b/assets/images/new-design/passport.svg @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/new-design/patient_call_icon.png b/assets/images/new-design/patient_call_icon.png deleted file mode 100644 index 51b286e7..00000000 Binary files a/assets/images/new-design/patient_call_icon.png and /dev/null differ diff --git a/assets/images/new-design/patient_referral_icon.png b/assets/images/new-design/patient_referral_icon.png deleted file mode 100644 index 8d417b73..00000000 Binary files a/assets/images/new-design/patient_referral_icon.png and /dev/null differ diff --git a/assets/images/new-design/pay_now.png b/assets/images/new-design/pay_now.png deleted file mode 100644 index 6096d8b9..00000000 Binary files a/assets/images/new-design/pay_now.png and /dev/null differ diff --git a/assets/images/new-design/pharmacy_icon.png b/assets/images/new-design/pharmacy_icon.png deleted file mode 100644 index 141583ee..00000000 Binary files a/assets/images/new-design/pharmacy_icon.png and /dev/null differ diff --git a/assets/images/new-design/refresh_icon.png b/assets/images/new-design/refresh_icon.png deleted file mode 100644 index c9b2db7d..00000000 Binary files a/assets/images/new-design/refresh_icon.png and /dev/null differ diff --git a/assets/images/new-design/reject.svg b/assets/images/new-design/reject.svg new file mode 100644 index 00000000..d2e9b868 --- /dev/null +++ b/assets/images/new-design/reject.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/new-design/remove_icon.png b/assets/images/new-design/remove_icon.png deleted file mode 100644 index 4a8f9479..00000000 Binary files a/assets/images/new-design/remove_icon.png and /dev/null differ diff --git a/assets/images/new-design/reschedule_icon.png b/assets/images/new-design/reschedule_icon.png deleted file mode 100644 index d04a5b49..00000000 Binary files a/assets/images/new-design/reschedule_icon.png and /dev/null differ diff --git a/assets/images/new-design/respiration.png b/assets/images/new-design/respiration.png deleted file mode 100644 index 944d65aa..00000000 Binary files a/assets/images/new-design/respiration.png and /dev/null differ diff --git a/assets/images/new-design/respirtation_icon.png b/assets/images/new-design/respirtation_icon.png deleted file mode 100644 index 75cd719d..00000000 Binary files a/assets/images/new-design/respirtation_icon.png and /dev/null differ diff --git a/assets/images/new-design/rotate_icon.png b/assets/images/new-design/rotate_icon.png deleted file mode 100644 index 1593fe75..00000000 Binary files a/assets/images/new-design/rotate_icon.png and /dev/null differ diff --git a/assets/images/new-design/schedule.png b/assets/images/new-design/schedule.png deleted file mode 100644 index a8a78432..00000000 Binary files a/assets/images/new-design/schedule.png and /dev/null differ diff --git a/assets/images/new-design/schedule_icon.png b/assets/images/new-design/schedule_icon.png deleted file mode 100644 index 555dcd23..00000000 Binary files a/assets/images/new-design/schedule_icon.png and /dev/null differ diff --git a/assets/images/new-design/scheduled_reminder.png b/assets/images/new-design/scheduled_reminder.png deleted file mode 100644 index 40254fb4..00000000 Binary files a/assets/images/new-design/scheduled_reminder.png and /dev/null differ diff --git a/assets/images/new-design/search_by_disease.png b/assets/images/new-design/search_by_disease.png deleted file mode 100644 index b55b2c67..00000000 Binary files a/assets/images/new-design/search_by_disease.png and /dev/null differ diff --git a/assets/images/new-design/search_by_symptom.png b/assets/images/new-design/search_by_symptom.png deleted file mode 100644 index 551f6ec8..00000000 Binary files a/assets/images/new-design/search_by_symptom.png and /dev/null differ diff --git a/assets/images/new-design/search_medicine.png b/assets/images/new-design/search_medicine.png deleted file mode 100644 index f4a1c675..00000000 Binary files a/assets/images/new-design/search_medicine.png and /dev/null differ diff --git a/assets/images/new-design/send-email.png b/assets/images/new-design/send-email.png deleted file mode 100644 index 86f21eb5..00000000 Binary files a/assets/images/new-design/send-email.png and /dev/null differ diff --git a/assets/images/new-design/setting_menu_icon.png b/assets/images/new-design/setting_menu_icon.png deleted file mode 100644 index d4f60540..00000000 Binary files a/assets/images/new-design/setting_menu_icon.png and /dev/null differ diff --git a/assets/images/new-design/sign_in_main_icon.png b/assets/images/new-design/sign_in_main_icon.png deleted file mode 100644 index 9938f32e..00000000 Binary files a/assets/images/new-design/sign_in_main_icon.png and /dev/null differ diff --git a/assets/images/new-design/sign_out_menu_icon.png b/assets/images/new-design/sign_out_menu_icon.png deleted file mode 100644 index e5bc35a4..00000000 Binary files a/assets/images/new-design/sign_out_menu_icon.png and /dev/null differ diff --git a/assets/images/new-design/star_icon.png b/assets/images/new-design/star_icon.png deleted file mode 100644 index 95923936..00000000 Binary files a/assets/images/new-design/star_icon.png and /dev/null differ diff --git a/assets/images/new-design/star_rate_menu_icon.png b/assets/images/new-design/star_rate_menu_icon.png deleted file mode 100644 index 207b1f71..00000000 Binary files a/assets/images/new-design/star_rate_menu_icon.png and /dev/null differ diff --git a/assets/images/new-design/success_icon.png b/assets/images/new-design/success_icon.png deleted file mode 100644 index 617cbe89..00000000 Binary files a/assets/images/new-design/success_icon.png and /dev/null differ diff --git a/assets/images/new-design/switch.svg b/assets/images/new-design/switch.svg new file mode 100644 index 00000000..2283d4a2 --- /dev/null +++ b/assets/images/new-design/switch.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/images/new-design/tamara.png b/assets/images/new-design/tamara.png new file mode 100644 index 00000000..ab58e3ac Binary files /dev/null and b/assets/images/new-design/tamara.png differ diff --git a/assets/images/new-design/temperature.png b/assets/images/new-design/temperature.png deleted file mode 100644 index 22bf5241..00000000 Binary files a/assets/images/new-design/temperature.png and /dev/null differ diff --git a/assets/images/new-design/temperature_icon.png b/assets/images/new-design/temperature_icon.png deleted file mode 100644 index 5d5d1203..00000000 Binary files a/assets/images/new-design/temperature_icon.png and /dev/null differ diff --git a/assets/images/new-design/track_icon.svg b/assets/images/new-design/track_icon.svg new file mode 100644 index 00000000..a4aa9a0f --- /dev/null +++ b/assets/images/new-design/track_icon.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/images/new-design/upcoming_icon_bottom_bar_active.png b/assets/images/new-design/upcoming_icon_bottom_bar_active.png deleted file mode 100644 index cccb9652..00000000 Binary files a/assets/images/new-design/upcoming_icon_bottom_bar_active.png and /dev/null differ diff --git a/assets/images/new-design/update_rocket_image.svg b/assets/images/new-design/update_rocket_image.svg new file mode 100644 index 00000000..6ce85004 --- /dev/null +++ b/assets/images/new-design/update_rocket_image.svg @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/new-design/user_top_bar_icon.png b/assets/images/new-design/user_top_bar_icon.png deleted file mode 100644 index 9b7b9a59..00000000 Binary files a/assets/images/new-design/user_top_bar_icon.png and /dev/null differ diff --git a/assets/images/new-design/vaccines_availability_icon.png b/assets/images/new-design/vaccines_availability_icon.png deleted file mode 100644 index 1bd6f8b3..00000000 Binary files a/assets/images/new-design/vaccines_availability_icon.png and /dev/null differ diff --git a/assets/images/new-design/vida_logo.jpg b/assets/images/new-design/vida_logo.jpg deleted file mode 100644 index 5fcec65c..00000000 Binary files a/assets/images/new-design/vida_logo.jpg and /dev/null differ diff --git a/assets/images/new-design/vidamobile.png b/assets/images/new-design/vidamobile.png deleted file mode 100644 index f096e8a7..00000000 Binary files a/assets/images/new-design/vidamobile.png and /dev/null differ diff --git a/assets/images/new-design/video_call_book_icon.png b/assets/images/new-design/video_call_book_icon.png deleted file mode 100644 index e4db4a57..00000000 Binary files a/assets/images/new-design/video_call_book_icon.png and /dev/null differ diff --git a/assets/images/new-design/video_icon_green_right.svg b/assets/images/new-design/video_icon_green_right.svg new file mode 100644 index 00000000..7f35ea42 --- /dev/null +++ b/assets/images/new-design/video_icon_green_right.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/new-design/virtal_respiration.png b/assets/images/new-design/virtal_respiration.png deleted file mode 100644 index 7e1b4466..00000000 Binary files a/assets/images/new-design/virtal_respiration.png and /dev/null differ diff --git a/assets/images/new-design/virtal_weight.png b/assets/images/new-design/virtal_weight.png deleted file mode 100644 index 5247e924..00000000 Binary files a/assets/images/new-design/virtal_weight.png and /dev/null differ diff --git a/assets/images/new-design/virtual_appointment_icon.png b/assets/images/new-design/virtual_appointment_icon.png deleted file mode 100644 index f91046c6..00000000 Binary files a/assets/images/new-design/virtual_appointment_icon.png and /dev/null differ diff --git a/assets/images/new-design/vital_blood-pressure.png b/assets/images/new-design/vital_blood-pressure.png deleted file mode 100644 index 44c9f2e2..00000000 Binary files a/assets/images/new-design/vital_blood-pressure.png and /dev/null differ diff --git a/assets/images/new-design/vital_blood_type.png b/assets/images/new-design/vital_blood_type.png deleted file mode 100644 index fbb5296f..00000000 Binary files a/assets/images/new-design/vital_blood_type.png and /dev/null differ diff --git a/assets/images/new-design/vital_body_mass.png b/assets/images/new-design/vital_body_mass.png deleted file mode 100644 index 08476c51..00000000 Binary files a/assets/images/new-design/vital_body_mass.png and /dev/null differ diff --git a/assets/images/new-design/vital_heart_rate.png b/assets/images/new-design/vital_heart_rate.png deleted file mode 100644 index e788658b..00000000 Binary files a/assets/images/new-design/vital_heart_rate.png and /dev/null differ diff --git a/assets/images/new-design/vital_height.png b/assets/images/new-design/vital_height.png deleted file mode 100644 index 8c324b2c..00000000 Binary files a/assets/images/new-design/vital_height.png and /dev/null differ diff --git a/assets/images/new-design/vital_temperature .png b/assets/images/new-design/vital_temperature .png deleted file mode 100644 index 7fe657de..00000000 Binary files a/assets/images/new-design/vital_temperature .png and /dev/null differ diff --git a/assets/images/new-design/weather_dashboard_icon.png b/assets/images/new-design/weather_dashboard_icon.png deleted file mode 100644 index 2a73dfac..00000000 Binary files a/assets/images/new-design/weather_dashboard_icon.png and /dev/null differ diff --git a/assets/images/new/Boo_ Appointment.svg b/assets/images/new/Boo_ Appointment.svg new file mode 100644 index 00000000..c25652c3 --- /dev/null +++ b/assets/images/new/Boo_ Appointment.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/images/new/CS/Family_Files.svg b/assets/images/new/CS/Family_Files.svg new file mode 100644 index 00000000..ce47d959 --- /dev/null +++ b/assets/images/new/CS/Family_Files.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/new/CS/Help.svg b/assets/images/new/CS/Help.svg new file mode 100644 index 00000000..31d49e71 --- /dev/null +++ b/assets/images/new/CS/Help.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/new/CS/My_File.svg b/assets/images/new/CS/My_File.svg new file mode 100644 index 00000000..fc5c0096 --- /dev/null +++ b/assets/images/new/CS/My_File.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/images/new/CS/Todo.svg b/assets/images/new/CS/Todo.svg new file mode 100644 index 00000000..98232af9 --- /dev/null +++ b/assets/images/new/CS/Todo.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/new/CS/emergency_request_CS.svg b/assets/images/new/CS/emergency_request_CS.svg new file mode 100644 index 00000000..1796a80c --- /dev/null +++ b/assets/images/new/CS/emergency_request_CS.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/new/CS/home_health_care_CS.svg b/assets/images/new/CS/home_health_care_CS.svg new file mode 100644 index 00000000..8cf044b1 --- /dev/null +++ b/assets/images/new/CS/home_health_care_CS.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/assets/images/new/CS/livecare_CS.svg b/assets/images/new/CS/livecare_CS.svg new file mode 100644 index 00000000..8af91e8a --- /dev/null +++ b/assets/images/new/CS/livecare_CS.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/images/new/CS/loader.gif b/assets/images/new/CS/loader.gif new file mode 100644 index 00000000..3e343727 Binary files /dev/null and b/assets/images/new/CS/loader.gif differ diff --git a/assets/images/new/CS/pharmacy_CS.svg b/assets/images/new/CS/pharmacy_CS.svg new file mode 100644 index 00000000..a3ad2b0c --- /dev/null +++ b/assets/images/new/CS/pharmacy_CS.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/assets/images/new/Comprehensive checkup.svg b/assets/images/new/Comprehensive checkup.svg new file mode 100644 index 00000000..b3f2feb1 --- /dev/null +++ b/assets/images/new/Comprehensive checkup.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/new/CoronaIcon.svg b/assets/images/new/CoronaIcon.svg new file mode 100644 index 00000000..c02f907b --- /dev/null +++ b/assets/images/new/CoronaIcon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/images/new/DriveThru.svg b/assets/images/new/DriveThru.svg new file mode 100644 index 00000000..faa727b7 --- /dev/null +++ b/assets/images/new/DriveThru.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/images/new/E_Referral.svg b/assets/images/new/E_Referral.svg new file mode 100644 index 00000000..fb6b8591 --- /dev/null +++ b/assets/images/new/E_Referral.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/images/new/HHC.svg b/assets/images/new/HHC.svg new file mode 100644 index 00000000..692623c2 --- /dev/null +++ b/assets/images/new/HHC.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/images/new/InPatient.svg b/assets/images/new/InPatient.svg new file mode 100644 index 00000000..d865a66c --- /dev/null +++ b/assets/images/new/InPatient.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/assets/images/new/Indoor_nav_appo.svg b/assets/images/new/Indoor_nav_appo.svg new file mode 100644 index 00000000..81bf654d --- /dev/null +++ b/assets/images/new/Indoor_nav_appo.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/images/new/Live Care.svg b/assets/images/new/Live Care.svg new file mode 100644 index 00000000..b5a367d7 --- /dev/null +++ b/assets/images/new/Live Care.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/images/new/Live_Care.svg b/assets/images/new/Live_Care.svg new file mode 100644 index 00000000..b5a367d7 --- /dev/null +++ b/assets/images/new/Live_Care.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/images/new/NFCCheckIn_QR_gps_HMG.png b/assets/images/new/NFCCheckIn_QR_gps_HMG.png new file mode 100644 index 00000000..20fc0ef6 Binary files /dev/null and b/assets/images/new/NFCCheckIn_QR_gps_HMG.png differ diff --git a/assets/images/new/NFC_Hold.svg b/assets/images/new/NFC_Hold.svg new file mode 100644 index 00000000..fbfa19ea --- /dev/null +++ b/assets/images/new/NFC_Hold.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/new/Pharmacy.svg b/assets/images/new/Pharmacy.svg new file mode 100644 index 00000000..bdb101e5 --- /dev/null +++ b/assets/images/new/Pharmacy.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/images/new/Saudi_Riyal_Symbol.svg b/assets/images/new/Saudi_Riyal_Symbol.svg new file mode 100644 index 00000000..d57d83a1 --- /dev/null +++ b/assets/images/new/Saudi_Riyal_Symbol.svg @@ -0,0 +1,12 @@ + + + + + + + + \ No newline at end of file diff --git a/assets/images/new/WalkIn.svg b/assets/images/new/WalkIn.svg new file mode 100644 index 00000000..c60829cb --- /dev/null +++ b/assets/images/new/WalkIn.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/images/new/add-to-cart.svg b/assets/images/new/add-to-cart.svg new file mode 100644 index 00000000..f01f6033 --- /dev/null +++ b/assets/images/new/add-to-cart.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/images/new/add_to_cart.svg b/assets/images/new/add_to_cart.svg new file mode 100644 index 00000000..f01f6033 --- /dev/null +++ b/assets/images/new/add_to_cart.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/images/new/admission_notice.png b/assets/images/new/admission_notice.png new file mode 100644 index 00000000..50b5c1d5 Binary files /dev/null and b/assets/images/new/admission_notice.png differ diff --git a/assets/images/new/ancillary.svg b/assets/images/new/ancillary.svg new file mode 100644 index 00000000..bde8d0e1 --- /dev/null +++ b/assets/images/new/ancillary.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/images/new/app_setting.svg b/assets/images/new/app_setting.svg new file mode 100644 index 00000000..d97a11ac --- /dev/null +++ b/assets/images/new/app_setting.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/assets/images/new/appointment-rating/1.svg b/assets/images/new/appointment-rating/1.svg new file mode 100644 index 00000000..8c732769 --- /dev/null +++ b/assets/images/new/appointment-rating/1.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/new/appointment-rating/2.svg b/assets/images/new/appointment-rating/2.svg new file mode 100644 index 00000000..60ae2909 --- /dev/null +++ b/assets/images/new/appointment-rating/2.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/new/appointment-rating/3.svg b/assets/images/new/appointment-rating/3.svg new file mode 100644 index 00000000..324918df --- /dev/null +++ b/assets/images/new/appointment-rating/3.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/new/appointment-rating/4.svg b/assets/images/new/appointment-rating/4.svg new file mode 100644 index 00000000..a983815e --- /dev/null +++ b/assets/images/new/appointment-rating/4.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/new/appointment-rating/5.svg b/assets/images/new/appointment-rating/5.svg new file mode 100644 index 00000000..4600b411 --- /dev/null +++ b/assets/images/new/appointment-rating/5.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/new/birth.png b/assets/images/new/birth.png new file mode 100644 index 00000000..39bd3f81 Binary files /dev/null and b/assets/images/new/birth.png differ diff --git a/assets/images/new/blood donation.svg b/assets/images/new/blood donation.svg new file mode 100644 index 00000000..95d0904f --- /dev/null +++ b/assets/images/new/blood donation.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/images/new/blood.svg b/assets/images/new/blood.svg new file mode 100644 index 00000000..7b1f2d0f --- /dev/null +++ b/assets/images/new/blood.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/images/new/blood_pressure.svg b/assets/images/new/blood_pressure.svg new file mode 100644 index 00000000..22cf1a2f --- /dev/null +++ b/assets/images/new/blood_pressure.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/images/new/body_parts/female/abdomin.png b/assets/images/new/body_parts/female/abdomin.png new file mode 100644 index 00000000..f4918d71 Binary files /dev/null and b/assets/images/new/body_parts/female/abdomin.png differ diff --git a/assets/images/new/body_parts/female/anal.png b/assets/images/new/body_parts/female/anal.png new file mode 100644 index 00000000..d96ef288 Binary files /dev/null and b/assets/images/new/body_parts/female/anal.png differ diff --git a/assets/images/new/body_parts/female/axilla.png b/assets/images/new/body_parts/female/axilla.png new file mode 100644 index 00000000..f38be6b3 Binary files /dev/null and b/assets/images/new/body_parts/female/axilla.png differ diff --git a/assets/images/new/body_parts/female/back.png b/assets/images/new/body_parts/female/back.png new file mode 100644 index 00000000..65d9ef19 Binary files /dev/null and b/assets/images/new/body_parts/female/back.png differ diff --git a/assets/images/new/body_parts/female/bikini.png b/assets/images/new/body_parts/female/bikini.png new file mode 100644 index 00000000..a1a68423 Binary files /dev/null and b/assets/images/new/body_parts/female/bikini.png differ diff --git a/assets/images/new/body_parts/female/bikini_line.png b/assets/images/new/body_parts/female/bikini_line.png new file mode 100644 index 00000000..12fc0e6e Binary files /dev/null and b/assets/images/new/body_parts/female/bikini_line.png differ diff --git a/assets/images/new/body_parts/female/buttocks.png b/assets/images/new/body_parts/female/buttocks.png new file mode 100644 index 00000000..b83576f3 Binary files /dev/null and b/assets/images/new/body_parts/female/buttocks.png differ diff --git a/assets/images/new/body_parts/female/cheeks.svg b/assets/images/new/body_parts/female/cheeks.svg new file mode 100644 index 00000000..6305ce65 --- /dev/null +++ b/assets/images/new/body_parts/female/cheeks.svg @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/new/body_parts/female/chest.png b/assets/images/new/body_parts/female/chest.png new file mode 100644 index 00000000..727ebe7a Binary files /dev/null and b/assets/images/new/body_parts/female/chest.png differ diff --git a/assets/images/new/body_parts/female/chest_line.png b/assets/images/new/body_parts/female/chest_line.png new file mode 100644 index 00000000..0b4fecb8 Binary files /dev/null and b/assets/images/new/body_parts/female/chest_line.png differ diff --git a/assets/images/new/body_parts/female/chin.svg b/assets/images/new/body_parts/female/chin.svg new file mode 100644 index 00000000..37da45b4 --- /dev/null +++ b/assets/images/new/body_parts/female/chin.svg @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/new/body_parts/female/ears.svg b/assets/images/new/body_parts/female/ears.svg new file mode 100644 index 00000000..758a69e6 --- /dev/null +++ b/assets/images/new/body_parts/female/ears.svg @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/new/body_parts/female/eyebrows.svg b/assets/images/new/body_parts/female/eyebrows.svg new file mode 100644 index 00000000..9657daa7 --- /dev/null +++ b/assets/images/new/body_parts/female/eyebrows.svg @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/new/body_parts/female/full_body_female.png b/assets/images/new/body_parts/female/full_body_female.png new file mode 100644 index 00000000..fb6a3756 Binary files /dev/null and b/assets/images/new/body_parts/female/full_body_female.png differ diff --git a/assets/images/new/body_parts/female/full_legs.png b/assets/images/new/body_parts/female/full_legs.png new file mode 100644 index 00000000..5a365a7e Binary files /dev/null and b/assets/images/new/body_parts/female/full_legs.png differ diff --git a/assets/images/new/body_parts/female/full_neck.svg b/assets/images/new/body_parts/female/full_neck.svg new file mode 100644 index 00000000..f73f07f8 --- /dev/null +++ b/assets/images/new/body_parts/female/full_neck.svg @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/new/body_parts/female/half_neck.svg b/assets/images/new/body_parts/female/half_neck.svg new file mode 100644 index 00000000..78e4cfab --- /dev/null +++ b/assets/images/new/body_parts/female/half_neck.svg @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/new/body_parts/female/hydra_facial.svg b/assets/images/new/body_parts/female/hydra_facial.svg new file mode 100644 index 00000000..6a468211 --- /dev/null +++ b/assets/images/new/body_parts/female/hydra_facial.svg @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/new/body_parts/female/lower_arm.png b/assets/images/new/body_parts/female/lower_arm.png new file mode 100644 index 00000000..717b2cde Binary files /dev/null and b/assets/images/new/body_parts/female/lower_arm.png differ diff --git a/assets/images/new/body_parts/female/lower_leg.png b/assets/images/new/body_parts/female/lower_leg.png new file mode 100644 index 00000000..88ccacef Binary files /dev/null and b/assets/images/new/body_parts/female/lower_leg.png differ diff --git a/assets/images/new/body_parts/female/shoulders.png b/assets/images/new/body_parts/female/shoulders.png new file mode 100644 index 00000000..e1f253a8 Binary files /dev/null and b/assets/images/new/body_parts/female/shoulders.png differ diff --git a/assets/images/new/body_parts/female/side_burn.svg b/assets/images/new/body_parts/female/side_burn.svg new file mode 100644 index 00000000..123216e7 --- /dev/null +++ b/assets/images/new/body_parts/female/side_burn.svg @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/new/body_parts/female/upper_arm.png b/assets/images/new/body_parts/female/upper_arm.png new file mode 100644 index 00000000..1edb873c Binary files /dev/null and b/assets/images/new/body_parts/female/upper_arm.png differ diff --git a/assets/images/new/body_parts/female/upper_legs.png b/assets/images/new/body_parts/female/upper_legs.png new file mode 100644 index 00000000..a8aa2ec7 Binary files /dev/null and b/assets/images/new/body_parts/female/upper_legs.png differ diff --git a/assets/images/new/body_parts/female/upper_lips.svg b/assets/images/new/body_parts/female/upper_lips.svg new file mode 100644 index 00000000..72043376 --- /dev/null +++ b/assets/images/new/body_parts/female/upper_lips.svg @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/new/body_parts/male/abdomin.png b/assets/images/new/body_parts/male/abdomin.png new file mode 100644 index 00000000..1b180b42 Binary files /dev/null and b/assets/images/new/body_parts/male/abdomin.png differ diff --git a/assets/images/new/body_parts/male/axilla.png b/assets/images/new/body_parts/male/axilla.png new file mode 100644 index 00000000..61af9492 Binary files /dev/null and b/assets/images/new/body_parts/male/axilla.png differ diff --git a/assets/images/new/body_parts/male/back.png b/assets/images/new/body_parts/male/back.png new file mode 100644 index 00000000..224147ec Binary files /dev/null and b/assets/images/new/body_parts/male/back.png differ diff --git a/assets/images/new/body_parts/male/back.svg b/assets/images/new/body_parts/male/back.svg new file mode 100644 index 00000000..7d9aeb46 --- /dev/null +++ b/assets/images/new/body_parts/male/back.svg @@ -0,0 +1,188 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/new/body_parts/male/bikini.png b/assets/images/new/body_parts/male/bikini.png new file mode 100644 index 00000000..aa98ea74 Binary files /dev/null and b/assets/images/new/body_parts/male/bikini.png differ diff --git a/assets/images/new/body_parts/male/bikini_line.png b/assets/images/new/body_parts/male/bikini_line.png new file mode 100644 index 00000000..60ed64e2 Binary files /dev/null and b/assets/images/new/body_parts/male/bikini_line.png differ diff --git a/assets/images/new/body_parts/male/cheek.svg b/assets/images/new/body_parts/male/cheek.svg new file mode 100644 index 00000000..984a59f8 --- /dev/null +++ b/assets/images/new/body_parts/male/cheek.svg @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/new/body_parts/male/chest.png b/assets/images/new/body_parts/male/chest.png new file mode 100644 index 00000000..b7cec070 Binary files /dev/null and b/assets/images/new/body_parts/male/chest.png differ diff --git a/assets/images/new/body_parts/male/chest_line.png b/assets/images/new/body_parts/male/chest_line.png new file mode 100644 index 00000000..41e779f3 Binary files /dev/null and b/assets/images/new/body_parts/male/chest_line.png differ diff --git a/assets/images/new/body_parts/male/chin.svg b/assets/images/new/body_parts/male/chin.svg new file mode 100644 index 00000000..9fdee93e --- /dev/null +++ b/assets/images/new/body_parts/male/chin.svg @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/new/body_parts/male/ears.svg b/assets/images/new/body_parts/male/ears.svg new file mode 100644 index 00000000..1c9600c3 --- /dev/null +++ b/assets/images/new/body_parts/male/ears.svg @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/new/body_parts/male/eyebrows.svg b/assets/images/new/body_parts/male/eyebrows.svg new file mode 100644 index 00000000..ea385230 --- /dev/null +++ b/assets/images/new/body_parts/male/eyebrows.svg @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/new/body_parts/male/full_body_male.png b/assets/images/new/body_parts/male/full_body_male.png new file mode 100644 index 00000000..df304728 Binary files /dev/null and b/assets/images/new/body_parts/male/full_body_male.png differ diff --git a/assets/images/new/body_parts/male/full_legs.png b/assets/images/new/body_parts/male/full_legs.png new file mode 100644 index 00000000..eee2fa07 Binary files /dev/null and b/assets/images/new/body_parts/male/full_legs.png differ diff --git a/assets/images/new/body_parts/male/full_neck.png b/assets/images/new/body_parts/male/full_neck.png new file mode 100644 index 00000000..a75159f6 Binary files /dev/null and b/assets/images/new/body_parts/male/full_neck.png differ diff --git a/assets/images/new/body_parts/male/full_neck.svg b/assets/images/new/body_parts/male/full_neck.svg new file mode 100644 index 00000000..33b755e8 --- /dev/null +++ b/assets/images/new/body_parts/male/full_neck.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/images/new/body_parts/male/half_neck.png b/assets/images/new/body_parts/male/half_neck.png new file mode 100644 index 00000000..5ee0249c Binary files /dev/null and b/assets/images/new/body_parts/male/half_neck.png differ diff --git a/assets/images/new/body_parts/male/half_neck.svg b/assets/images/new/body_parts/male/half_neck.svg new file mode 100644 index 00000000..26b6bc32 --- /dev/null +++ b/assets/images/new/body_parts/male/half_neck.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/images/new/body_parts/male/hydra_facial.svg b/assets/images/new/body_parts/male/hydra_facial.svg new file mode 100644 index 00000000..10516304 --- /dev/null +++ b/assets/images/new/body_parts/male/hydra_facial.svg @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/new/body_parts/male/lower_arm.png b/assets/images/new/body_parts/male/lower_arm.png new file mode 100644 index 00000000..120242ed Binary files /dev/null and b/assets/images/new/body_parts/male/lower_arm.png differ diff --git a/assets/images/new/body_parts/male/lower_legs.png b/assets/images/new/body_parts/male/lower_legs.png new file mode 100644 index 00000000..8367aa8c Binary files /dev/null and b/assets/images/new/body_parts/male/lower_legs.png differ diff --git a/assets/images/new/body_parts/male/shoulders.png b/assets/images/new/body_parts/male/shoulders.png new file mode 100644 index 00000000..907f2dd7 Binary files /dev/null and b/assets/images/new/body_parts/male/shoulders.png differ diff --git a/assets/images/new/body_parts/male/side_burn.svg b/assets/images/new/body_parts/male/side_burn.svg new file mode 100644 index 00000000..156b30f1 --- /dev/null +++ b/assets/images/new/body_parts/male/side_burn.svg @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/new/body_parts/male/upper_arm.png b/assets/images/new/body_parts/male/upper_arm.png new file mode 100644 index 00000000..f80a75da Binary files /dev/null and b/assets/images/new/body_parts/male/upper_arm.png differ diff --git a/assets/images/new/body_parts/male/upper_legs.png b/assets/images/new/body_parts/male/upper_legs.png new file mode 100644 index 00000000..e0c973b7 Binary files /dev/null and b/assets/images/new/body_parts/male/upper_legs.png differ diff --git a/assets/images/new/body_parts/male/upper_lips.svg b/assets/images/new/body_parts/male/upper_lips.svg new file mode 100644 index 00000000..b7ae6e0f --- /dev/null +++ b/assets/images/new/body_parts/male/upper_lips.svg @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/new/book appointment.svg b/assets/images/new/book appointment.svg new file mode 100644 index 00000000..590ea8de --- /dev/null +++ b/assets/images/new/book appointment.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/images/new/booth_image.png b/assets/images/new/booth_image.png new file mode 100644 index 00000000..0a3427e4 Binary files /dev/null and b/assets/images/new/booth_image.png differ diff --git a/assets/images/new/bottom_nav/family_files.svg b/assets/images/new/bottom_nav/family_files.svg new file mode 100644 index 00000000..ce47d959 --- /dev/null +++ b/assets/images/new/bottom_nav/family_files.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/new/bottom_nav/help.svg b/assets/images/new/bottom_nav/help.svg new file mode 100644 index 00000000..31d49e71 --- /dev/null +++ b/assets/images/new/bottom_nav/help.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/new/bottom_nav/home.svg b/assets/images/new/bottom_nav/home.svg new file mode 100644 index 00000000..b363bbc0 --- /dev/null +++ b/assets/images/new/bottom_nav/home.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/new/bottom_nav/my_file.svg b/assets/images/new/bottom_nav/my_file.svg new file mode 100644 index 00000000..fc5c0096 --- /dev/null +++ b/assets/images/new/bottom_nav/my_file.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/images/new/bottom_nav/todo.svg b/assets/images/new/bottom_nav/todo.svg new file mode 100644 index 00000000..98232af9 --- /dev/null +++ b/assets/images/new/bottom_nav/todo.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/new/car_icon.svg b/assets/images/new/car_icon.svg new file mode 100644 index 00000000..f6062e65 --- /dev/null +++ b/assets/images/new/car_icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/new/cart.svg b/assets/images/new/cart.svg new file mode 100644 index 00000000..334b86ba --- /dev/null +++ b/assets/images/new/cart.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/images/new/cart_old.svg b/assets/images/new/cart_old.svg new file mode 100644 index 00000000..334b86ba --- /dev/null +++ b/assets/images/new/cart_old.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/images/new/child vaccines.svg b/assets/images/new/child vaccines.svg new file mode 100644 index 00000000..d3f38a5e --- /dev/null +++ b/assets/images/new/child vaccines.svg @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/new/cloud_logo.svg b/assets/images/new/cloud_logo.svg new file mode 100644 index 00000000..4cf9e0cd --- /dev/null +++ b/assets/images/new/cloud_logo.svg @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/new/cloudy.svg b/assets/images/new/cloudy.svg new file mode 100644 index 00000000..88ccdf85 --- /dev/null +++ b/assets/images/new/cloudy.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/images/new/comprehensive_checkup.svg b/assets/images/new/comprehensive_checkup.svg new file mode 100644 index 00000000..b3f2feb1 --- /dev/null +++ b/assets/images/new/comprehensive_checkup.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/new/consent.jpg b/assets/images/new/consent.jpg new file mode 100644 index 00000000..0d0e7df8 Binary files /dev/null and b/assets/images/new/consent.jpg differ diff --git a/assets/images/new/copy.svg b/assets/images/new/copy.svg new file mode 100644 index 00000000..c34c96d4 --- /dev/null +++ b/assets/images/new/copy.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/assets/images/new/covid drive thru.svg b/assets/images/new/covid drive thru.svg new file mode 100644 index 00000000..563de151 --- /dev/null +++ b/assets/images/new/covid drive thru.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/new/covid_test_drive_thru.svg b/assets/images/new/covid_test_drive_thru.svg new file mode 100644 index 00000000..563de151 --- /dev/null +++ b/assets/images/new/covid_test_drive_thru.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/new/direction.svg b/assets/images/new/direction.svg new file mode 100644 index 00000000..05d10bc2 --- /dev/null +++ b/assets/images/new/direction.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/images/new/download_1.svg b/assets/images/new/download_1.svg new file mode 100644 index 00000000..6bf54066 --- /dev/null +++ b/assets/images/new/download_1.svg @@ -0,0 +1,5 @@ + + + diff --git a/assets/images/new/drive-thru.svg b/assets/images/new/drive-thru.svg new file mode 100644 index 00000000..3bbb8368 --- /dev/null +++ b/assets/images/new/drive-thru.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/new/ear.svg b/assets/images/new/ear.svg new file mode 100644 index 00000000..c5146029 --- /dev/null +++ b/assets/images/new/ear.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/new/email.svg b/assets/images/new/email.svg new file mode 100644 index 00000000..642db68a --- /dev/null +++ b/assets/images/new/email.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/images/new/emergency.svg b/assets/images/new/emergency.svg new file mode 100644 index 00000000..a1a0178a --- /dev/null +++ b/assets/images/new/emergency.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/new/emergency_services.svg b/assets/images/new/emergency_services.svg new file mode 100644 index 00000000..ab63f29b --- /dev/null +++ b/assets/images/new/emergency_services.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/images/new/emergency_services_back.svg b/assets/images/new/emergency_services_back.svg new file mode 100644 index 00000000..13d9f2d2 --- /dev/null +++ b/assets/images/new/emergency_services_back.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/images/new/empty.svg b/assets/images/new/empty.svg new file mode 100644 index 00000000..6a0ddab4 --- /dev/null +++ b/assets/images/new/empty.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/images/new/family_files.svg b/assets/images/new/family_files.svg new file mode 100644 index 00000000..ce3c5c84 --- /dev/null +++ b/assets/images/new/family_files.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/new/h2o.svg b/assets/images/new/h2o.svg new file mode 100644 index 00000000..cab6a705 --- /dev/null +++ b/assets/images/new/h2o.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/new/head.svg b/assets/images/new/head.svg new file mode 100644 index 00000000..50da3a8d --- /dev/null +++ b/assets/images/new/head.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/new/health calculator.svg b/assets/images/new/health calculator.svg new file mode 100644 index 00000000..ac73e868 --- /dev/null +++ b/assets/images/new/health calculator.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/assets/images/new/health converter.svg b/assets/images/new/health converter.svg new file mode 100644 index 00000000..961adc51 --- /dev/null +++ b/assets/images/new/health converter.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/assets/images/new/heart_rate.svg b/assets/images/new/heart_rate.svg new file mode 100644 index 00000000..fe476c3c --- /dev/null +++ b/assets/images/new/heart_rate.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/images/new/height.svg b/assets/images/new/height.svg new file mode 100644 index 00000000..6ee1bef1 --- /dev/null +++ b/assets/images/new/height.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/images/new/hmg_icon.svg b/assets/images/new/hmg_icon.svg new file mode 100644 index 00000000..e09967e2 --- /dev/null +++ b/assets/images/new/hmg_icon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/new/hmg_logo.png b/assets/images/new/hmg_logo.png new file mode 100644 index 00000000..2555cfa9 Binary files /dev/null and b/assets/images/new/hmg_logo.png differ diff --git a/assets/images/new/hospital-visit.svg b/assets/images/new/hospital-visit.svg new file mode 100644 index 00000000..df4d481a --- /dev/null +++ b/assets/images/new/hospital-visit.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/images/new/hospital.png b/assets/images/new/hospital.png new file mode 100644 index 00000000..10c6a1f1 Binary files /dev/null and b/assets/images/new/hospital.png differ diff --git a/assets/images/new/hourglass.svg b/assets/images/new/hourglass.svg new file mode 100644 index 00000000..564ff289 --- /dev/null +++ b/assets/images/new/hourglass.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/new/ic_zoom.svg b/assets/images/new/ic_zoom.svg new file mode 100644 index 00000000..f7449eeb --- /dev/null +++ b/assets/images/new/ic_zoom.svg @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/new/icon.png b/assets/images/new/icon.png new file mode 100644 index 00000000..e802ae3e Binary files /dev/null and b/assets/images/new/icon.png differ diff --git a/assets/images/new/indoor_nav_home.svg b/assets/images/new/indoor_nav_home.svg new file mode 100644 index 00000000..bfe32eec --- /dev/null +++ b/assets/images/new/indoor_nav_home.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/images/new/inpatient/admission.svg b/assets/images/new/inpatient/admission.svg new file mode 100644 index 00000000..3c946928 --- /dev/null +++ b/assets/images/new/inpatient/admission.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/new/inpatient/admission_notice.svg b/assets/images/new/inpatient/admission_notice.svg new file mode 100644 index 00000000..befcf08f --- /dev/null +++ b/assets/images/new/inpatient/admission_notice.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/images/new/inpatient/advance_payment.svg b/assets/images/new/inpatient/advance_payment.svg new file mode 100644 index 00000000..fe41e6ef --- /dev/null +++ b/assets/images/new/inpatient/advance_payment.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/images/new/inpatient/birth_notification.svg b/assets/images/new/inpatient/birth_notification.svg new file mode 100644 index 00000000..7e0c720e --- /dev/null +++ b/assets/images/new/inpatient/birth_notification.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/images/new/inpatient/general_instructions.svg b/assets/images/new/inpatient/general_instructions.svg new file mode 100644 index 00000000..9f42040d --- /dev/null +++ b/assets/images/new/inpatient/general_instructions.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/images/new/inpatient/help_pro.svg b/assets/images/new/inpatient/help_pro.svg new file mode 100644 index 00000000..90b7f300 --- /dev/null +++ b/assets/images/new/inpatient/help_pro.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/images/new/inpatient/meal_plan.svg b/assets/images/new/inpatient/meal_plan.svg new file mode 100644 index 00000000..e5fd1e58 --- /dev/null +++ b/assets/images/new/inpatient/meal_plan.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/images/new/inpatient/medical_instructions.svg b/assets/images/new/inpatient/medical_instructions.svg new file mode 100644 index 00000000..dc060b34 --- /dev/null +++ b/assets/images/new/inpatient/medical_instructions.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/new/inpatient/receive_prescription.svg b/assets/images/new/inpatient/receive_prescription.svg new file mode 100644 index 00000000..21cadf7c --- /dev/null +++ b/assets/images/new/inpatient/receive_prescription.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/images/new/instructions.jpg b/assets/images/new/instructions.jpg new file mode 100644 index 00000000..0b6025f5 Binary files /dev/null and b/assets/images/new/instructions.jpg differ diff --git a/assets/images/new/latest news.svg b/assets/images/new/latest news.svg new file mode 100644 index 00000000..5b9cd805 --- /dev/null +++ b/assets/images/new/latest news.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/assets/images/new/logo.png b/assets/images/new/logo.png new file mode 100644 index 00000000..29719b35 Binary files /dev/null and b/assets/images/new/logo.png differ diff --git a/assets/images/new/logo.svg b/assets/images/new/logo.svg new file mode 100644 index 00000000..e777d9ee --- /dev/null +++ b/assets/images/new/logo.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/new/logout.svg b/assets/images/new/logout.svg new file mode 100644 index 00000000..b767fbff --- /dev/null +++ b/assets/images/new/logout.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/new/mass/health_BMI.svg b/assets/images/new/mass/health_BMI.svg new file mode 100644 index 00000000..081110d8 --- /dev/null +++ b/assets/images/new/mass/health_BMI.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/new/meal_plan.png b/assets/images/new/meal_plan.png new file mode 100644 index 00000000..4368a1df Binary files /dev/null and b/assets/images/new/meal_plan.png differ diff --git a/assets/images/new/medical file.svg b/assets/images/new/medical file.svg new file mode 100644 index 00000000..0849b7a0 --- /dev/null +++ b/assets/images/new/medical file.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/new/medical_file.svg b/assets/images/new/medical_file.svg new file mode 100644 index 00000000..7130396a --- /dev/null +++ b/assets/images/new/medical_file.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/images/new/medical_instructions.png b/assets/images/new/medical_instructions.png new file mode 100644 index 00000000..a6d0e0e2 Binary files /dev/null and b/assets/images/new/medical_instructions.png differ diff --git a/assets/images/new/menu.svg b/assets/images/new/menu.svg new file mode 100644 index 00000000..05654cdb --- /dev/null +++ b/assets/images/new/menu.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/new/my family.svg b/assets/images/new/my family.svg new file mode 100644 index 00000000..41d0b8a9 --- /dev/null +++ b/assets/images/new/my family.svg @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/new/national_id.svg b/assets/images/new/national_id.svg new file mode 100644 index 00000000..a76fd982 --- /dev/null +++ b/assets/images/new/national_id.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/images/new/not_found.svg b/assets/images/new/not_found.svg new file mode 100644 index 00000000..80aed53a --- /dev/null +++ b/assets/images/new/not_found.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/images/new/notifications.svg b/assets/images/new/notifications.svg new file mode 100644 index 00000000..5866a81b --- /dev/null +++ b/assets/images/new/notifications.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/new/parking details.svg b/assets/images/new/parking details.svg new file mode 100644 index 00000000..dc25eb0e --- /dev/null +++ b/assets/images/new/parking details.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/images/new/passport.svg b/assets/images/new/passport.svg new file mode 100644 index 00000000..883287fb --- /dev/null +++ b/assets/images/new/passport.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/assets/images/new/payment.svg b/assets/images/new/payment.svg new file mode 100644 index 00000000..c49fee35 --- /dev/null +++ b/assets/images/new/payment.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/new/payment/Apple_Pay.png b/assets/images/new/payment/Apple_Pay.png new file mode 100644 index 00000000..1dc75042 Binary files /dev/null and b/assets/images/new/payment/Apple_Pay.png differ diff --git a/assets/images/new/payment/Apple_Pay.svg b/assets/images/new/payment/Apple_Pay.svg new file mode 100755 index 00000000..0c6ecafe --- /dev/null +++ b/assets/images/new/payment/Apple_Pay.svg @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/new/payment/Mada.png b/assets/images/new/payment/Mada.png new file mode 100644 index 00000000..905a5ba8 Binary files /dev/null and b/assets/images/new/payment/Mada.png differ diff --git a/assets/images/new/payment/Mastercard.png b/assets/images/new/payment/Mastercard.png new file mode 100644 index 00000000..5d8b1fa5 Binary files /dev/null and b/assets/images/new/payment/Mastercard.png differ diff --git a/assets/images/new/payment/installments.png b/assets/images/new/payment/installments.png new file mode 100644 index 00000000..b2b231bf Binary files /dev/null and b/assets/images/new/payment/installments.png differ diff --git a/assets/images/new/payment/instalmt.svg b/assets/images/new/payment/instalmt.svg new file mode 100644 index 00000000..76fe7a0a --- /dev/null +++ b/assets/images/new/payment/instalmt.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/images/new/payment/tamara_ar.png b/assets/images/new/payment/tamara_ar.png new file mode 100644 index 00000000..f1587ad6 Binary files /dev/null and b/assets/images/new/payment/tamara_ar.png differ diff --git a/assets/images/new/payment/tamara_en.png b/assets/images/new/payment/tamara_en.png new file mode 100644 index 00000000..84d85b2c Binary files /dev/null and b/assets/images/new/payment/tamara_en.png differ diff --git a/assets/images/new/payment/visa.png b/assets/images/new/payment/visa.png new file mode 100644 index 00000000..3a6d90dd Binary files /dev/null and b/assets/images/new/payment/visa.png differ diff --git a/assets/images/new/paymentMethods.png b/assets/images/new/paymentMethods.png new file mode 100644 index 00000000..a2836f13 Binary files /dev/null and b/assets/images/new/paymentMethods.png differ diff --git a/assets/images/new/pendingPayment.svg b/assets/images/new/pendingPayment.svg new file mode 100644 index 00000000..79f29f05 --- /dev/null +++ b/assets/images/new/pendingPayment.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/images/new/pharma.svg b/assets/images/new/pharma.svg new file mode 100644 index 00000000..c3071ac4 --- /dev/null +++ b/assets/images/new/pharma.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/images/new/pharmaicon.svg b/assets/images/new/pharmaicon.svg new file mode 100644 index 00000000..af0f0e29 --- /dev/null +++ b/assets/images/new/pharmaicon.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/images/new/qr_code.svg b/assets/images/new/qr_code.svg new file mode 100644 index 00000000..a8674f00 --- /dev/null +++ b/assets/images/new/qr_code.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/images/new/reach us.svg b/assets/images/new/reach us.svg new file mode 100644 index 00000000..b4634170 --- /dev/null +++ b/assets/images/new/reach us.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/new/reach_us.svg b/assets/images/new/reach_us.svg new file mode 100644 index 00000000..b4634170 --- /dev/null +++ b/assets/images/new/reach_us.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/new/referral.svg b/assets/images/new/referral.svg new file mode 100644 index 00000000..fb6b8591 --- /dev/null +++ b/assets/images/new/referral.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/images/new/respiration_rate.svg b/assets/images/new/respiration_rate.svg new file mode 100644 index 00000000..f544f547 --- /dev/null +++ b/assets/images/new/respiration_rate.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/new/services/active_medication.svg b/assets/images/new/services/active_medication.svg new file mode 100644 index 00000000..aa6eeaea --- /dev/null +++ b/assets/images/new/services/active_medication.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/new/services/add_reminder.svg b/assets/images/new/services/add_reminder.svg new file mode 100644 index 00000000..5866a81b --- /dev/null +++ b/assets/images/new/services/add_reminder.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/new/services/allergies_diagnosed.svg b/assets/images/new/services/allergies_diagnosed.svg new file mode 100644 index 00000000..258658c8 --- /dev/null +++ b/assets/images/new/services/allergies_diagnosed.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/new/services/ancillary.svg b/assets/images/new/services/ancillary.svg new file mode 100644 index 00000000..bde8d0e1 --- /dev/null +++ b/assets/images/new/services/ancillary.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/images/new/services/appointment_list.svg b/assets/images/new/services/appointment_list.svg new file mode 100644 index 00000000..40f61dea --- /dev/null +++ b/assets/images/new/services/appointment_list.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/new/services/ask_doctor.svg b/assets/images/new/services/ask_doctor.svg new file mode 100644 index 00000000..90b7f300 --- /dev/null +++ b/assets/images/new/services/ask_doctor.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/images/new/services/balance_credit.svg b/assets/images/new/services/balance_credit.svg new file mode 100644 index 00000000..268f284f --- /dev/null +++ b/assets/images/new/services/balance_credit.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/assets/images/new/services/bmi.svg b/assets/images/new/services/bmi.svg new file mode 100644 index 00000000..ce3be188 --- /dev/null +++ b/assets/images/new/services/bmi.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/images/new/services/bmr_calc.svg b/assets/images/new/services/bmr_calc.svg new file mode 100644 index 00000000..991cdd08 --- /dev/null +++ b/assets/images/new/services/bmr_calc.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/images/new/services/body_fat_calc.svg b/assets/images/new/services/body_fat_calc.svg new file mode 100644 index 00000000..552715b9 --- /dev/null +++ b/assets/images/new/services/body_fat_calc.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/images/new/services/calories_calc.svg b/assets/images/new/services/calories_calc.svg new file mode 100644 index 00000000..2d4de2fa --- /dev/null +++ b/assets/images/new/services/calories_calc.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/assets/images/new/services/carbs_proteitn_fat.svg b/assets/images/new/services/carbs_proteitn_fat.svg new file mode 100644 index 00000000..ba1c7005 --- /dev/null +++ b/assets/images/new/services/carbs_proteitn_fat.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/images/new/services/chatbot.svg b/assets/images/new/services/chatbot.svg new file mode 100644 index 00000000..cf2a5092 --- /dev/null +++ b/assets/images/new/services/chatbot.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/images/new/services/cholesterol.svg b/assets/images/new/services/cholesterol.svg new file mode 100644 index 00000000..e5686e15 --- /dev/null +++ b/assets/images/new/services/cholesterol.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/images/new/services/contactless.svg b/assets/images/new/services/contactless.svg new file mode 100644 index 00000000..4eb2d478 --- /dev/null +++ b/assets/images/new/services/contactless.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/images/new/services/delivery.svg b/assets/images/new/services/delivery.svg new file mode 100644 index 00000000..2b350b8b --- /dev/null +++ b/assets/images/new/services/delivery.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/images/new/services/eye_measurement.svg b/assets/images/new/services/eye_measurement.svg new file mode 100644 index 00000000..563329c5 --- /dev/null +++ b/assets/images/new/services/eye_measurement.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/assets/images/new/services/fat.svg b/assets/images/new/services/fat.svg new file mode 100644 index 00000000..552715b9 --- /dev/null +++ b/assets/images/new/services/fat.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/images/new/services/hosp_location.svg b/assets/images/new/services/hosp_location.svg new file mode 100644 index 00000000..4d55f56b --- /dev/null +++ b/assets/images/new/services/hosp_location.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/images/new/services/ideal_weight_calc.svg b/assets/images/new/services/ideal_weight_calc.svg new file mode 100644 index 00000000..60d7ecbe --- /dev/null +++ b/assets/images/new/services/ideal_weight_calc.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/new/services/insurance_approval.svg b/assets/images/new/services/insurance_approval.svg new file mode 100644 index 00000000..f6a5885f --- /dev/null +++ b/assets/images/new/services/insurance_approval.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/images/new/services/insurance_card.svg b/assets/images/new/services/insurance_card.svg new file mode 100644 index 00000000..81d91b5e --- /dev/null +++ b/assets/images/new/services/insurance_card.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/images/new/services/internet_connection.svg b/assets/images/new/services/internet_connection.svg new file mode 100644 index 00000000..09176400 --- /dev/null +++ b/assets/images/new/services/internet_connection.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/new/services/invoice_list.svg b/assets/images/new/services/invoice_list.svg new file mode 100644 index 00000000..18fe134f --- /dev/null +++ b/assets/images/new/services/invoice_list.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/new/services/lab_result.svg b/assets/images/new/services/lab_result.svg new file mode 100644 index 00000000..e8507595 --- /dev/null +++ b/assets/images/new/services/lab_result.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/images/new/services/location.svg b/assets/images/new/services/location.svg new file mode 100644 index 00000000..e727476f --- /dev/null +++ b/assets/images/new/services/location.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/images/new/services/medical_report.svg b/assets/images/new/services/medical_report.svg new file mode 100644 index 00000000..186af7a6 --- /dev/null +++ b/assets/images/new/services/medical_report.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/images/new/services/medicine_prescription.svg b/assets/images/new/services/medicine_prescription.svg new file mode 100644 index 00000000..21cadf7c --- /dev/null +++ b/assets/images/new/services/medicine_prescription.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/images/new/services/monthly_report.svg b/assets/images/new/services/monthly_report.svg new file mode 100644 index 00000000..d218855a --- /dev/null +++ b/assets/images/new/services/monthly_report.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/images/new/services/my_doc.svg b/assets/images/new/services/my_doc.svg new file mode 100644 index 00000000..8bec48a5 --- /dev/null +++ b/assets/images/new/services/my_doc.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/new/services/online_payment.svg b/assets/images/new/services/online_payment.svg new file mode 100644 index 00000000..238417d8 --- /dev/null +++ b/assets/images/new/services/online_payment.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/new/services/ovulation.svg b/assets/images/new/services/ovulation.svg new file mode 100644 index 00000000..29650a70 --- /dev/null +++ b/assets/images/new/services/ovulation.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/images/new/services/pendingPayment.svg b/assets/images/new/services/pendingPayment.svg new file mode 100644 index 00000000..79f29f05 --- /dev/null +++ b/assets/images/new/services/pendingPayment.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/images/new/services/qr_code.svg b/assets/images/new/services/qr_code.svg new file mode 100644 index 00000000..55b70919 --- /dev/null +++ b/assets/images/new/services/qr_code.svg @@ -0,0 +1,2 @@ + + diff --git a/assets/images/new/services/radiology.svg b/assets/images/new/services/radiology.svg new file mode 100644 index 00000000..8f1d8a46 --- /dev/null +++ b/assets/images/new/services/radiology.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/new/services/raise_comp.svg b/assets/images/new/services/raise_comp.svg new file mode 100644 index 00000000..74a87bae --- /dev/null +++ b/assets/images/new/services/raise_comp.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/new/services/reminder_icon.svg b/assets/images/new/services/reminder_icon.svg new file mode 100644 index 00000000..9d73af2d --- /dev/null +++ b/assets/images/new/services/reminder_icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/images/new/services/reschedule.svg b/assets/images/new/services/reschedule.svg new file mode 100644 index 00000000..28dbc920 --- /dev/null +++ b/assets/images/new/services/reschedule.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/images/new/services/sick_leave.svg b/assets/images/new/services/sick_leave.svg new file mode 100644 index 00000000..4d8eea5d --- /dev/null +++ b/assets/images/new/services/sick_leave.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/new/services/smart_watch.svg b/assets/images/new/services/smart_watch.svg new file mode 100644 index 00000000..236f64b4 --- /dev/null +++ b/assets/images/new/services/smart_watch.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/images/new/services/sugar-blood-level.svg b/assets/images/new/services/sugar-blood-level.svg new file mode 100644 index 00000000..f1c103f7 --- /dev/null +++ b/assets/images/new/services/sugar-blood-level.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/images/new/services/survey.svg b/assets/images/new/services/survey.svg new file mode 100644 index 00000000..69fb7ad0 --- /dev/null +++ b/assets/images/new/services/survey.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/images/new/services/tracker.svg b/assets/images/new/services/tracker.svg new file mode 100644 index 00000000..7d727cee --- /dev/null +++ b/assets/images/new/services/tracker.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/images/new/services/vaccine_list.svg b/assets/images/new/services/vaccine_list.svg new file mode 100644 index 00000000..7096feb3 --- /dev/null +++ b/assets/images/new/services/vaccine_list.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/images/new/services/vital_signs.svg b/assets/images/new/services/vital_signs.svg new file mode 100644 index 00000000..fe476c3c --- /dev/null +++ b/assets/images/new/services/vital_signs.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/images/new/smart watch.svg b/assets/images/new/smart watch.svg new file mode 100644 index 00000000..0667e31d --- /dev/null +++ b/assets/images/new/smart watch.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/images/new/strips.svg b/assets/images/new/strips.svg new file mode 100644 index 00000000..d93430bc --- /dev/null +++ b/assets/images/new/strips.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/images/new/tap.svg b/assets/images/new/tap.svg new file mode 100644 index 00000000..cf73ddde --- /dev/null +++ b/assets/images/new/tap.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/new/temperature.svg b/assets/images/new/temperature.svg new file mode 100644 index 00000000..3330c310 --- /dev/null +++ b/assets/images/new/temperature.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/images/new/todo.svg b/assets/images/new/todo.svg new file mode 100644 index 00000000..be869c1d --- /dev/null +++ b/assets/images/new/todo.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/new/tooth.svg b/assets/images/new/tooth.svg new file mode 100644 index 00000000..2b2e3430 --- /dev/null +++ b/assets/images/new/tooth.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/new/ultrasound.svg b/assets/images/new/ultrasound.svg new file mode 100644 index 00000000..bc434530 --- /dev/null +++ b/assets/images/new/ultrasound.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/images/new/update insurance card.svg b/assets/images/new/update insurance card.svg new file mode 100644 index 00000000..0139e27d --- /dev/null +++ b/assets/images/new/update insurance card.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/new/verify_face.svg b/assets/images/new/verify_face.svg new file mode 100644 index 00000000..e50d1a60 --- /dev/null +++ b/assets/images/new/verify_face.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/images/new/verify_sms.svg b/assets/images/new/verify_sms.svg new file mode 100644 index 00000000..ae5fa9f7 --- /dev/null +++ b/assets/images/new/verify_sms.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/images/new/verify_thumb.svg b/assets/images/new/verify_thumb.svg new file mode 100644 index 00000000..e626bafc --- /dev/null +++ b/assets/images/new/verify_thumb.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/images/new/verify_whatsapp.svg b/assets/images/new/verify_whatsapp.svg new file mode 100644 index 00000000..09ac85c9 --- /dev/null +++ b/assets/images/new/verify_whatsapp.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/images/new/virtual tour.svg b/assets/images/new/virtual tour.svg new file mode 100644 index 00000000..733f433e --- /dev/null +++ b/assets/images/new/virtual tour.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/images/new/virtual.svg b/assets/images/new/virtual.svg new file mode 100644 index 00000000..d0819a89 --- /dev/null +++ b/assets/images/new/virtual.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/images/new/waitingAppo.svg b/assets/images/new/waitingAppo.svg new file mode 100644 index 00000000..c9bd0096 --- /dev/null +++ b/assets/images/new/waitingAppo.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/new/weight.svg b/assets/images/new/weight.svg new file mode 100644 index 00000000..013e6450 --- /dev/null +++ b/assets/images/new/weight.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/images/new/workplace-icon.svg b/assets/images/new/workplace-icon.svg new file mode 100644 index 00000000..4a2c73a0 --- /dev/null +++ b/assets/images/new/workplace-icon.svg @@ -0,0 +1 @@ +workplace \ No newline at end of file diff --git a/assets/images/new/zoom/chat-send@2x.png b/assets/images/new/zoom/chat-send@2x.png new file mode 100644 index 00000000..73e7cd31 Binary files /dev/null and b/assets/images/new/zoom/chat-send@2x.png differ diff --git a/assets/images/new/zoom/chat-send@3x.png b/assets/images/new/zoom/chat-send@3x.png new file mode 100644 index 00000000..2c18a6b9 Binary files /dev/null and b/assets/images/new/zoom/chat-send@3x.png differ diff --git a/assets/images/new/zoom/default-avatar.png b/assets/images/new/zoom/default-avatar.png new file mode 100644 index 00000000..c5fd1e71 Binary files /dev/null and b/assets/images/new/zoom/default-avatar.png differ diff --git a/assets/images/new/zoom/hamburger@2x.png b/assets/images/new/zoom/hamburger@2x.png new file mode 100644 index 00000000..9b490c25 Binary files /dev/null and b/assets/images/new/zoom/hamburger@2x.png differ diff --git a/assets/images/new/zoom/hamburger@3x.png b/assets/images/new/zoom/hamburger@3x.png new file mode 100644 index 00000000..434601f9 Binary files /dev/null and b/assets/images/new/zoom/hamburger@3x.png differ diff --git a/assets/images/new/zoom/index.ts b/assets/images/new/zoom/index.ts new file mode 100644 index 00000000..fce1d508 --- /dev/null +++ b/assets/images/new/zoom/index.ts @@ -0,0 +1,22 @@ +export const icons = { + chatSend: require('./chat-send.png'), + defaultAvatar: require('./default-avatar.png'), + locked: require('./locked.png'), + more: require('./more.png'), + mute: require('./mute.png'), + muted: require('./muted.png'), + shareOn: require('./share-on.png'), + shareOff: require('./share-off.png'), + speakerOn: require('./speaker-on.png'), + speakerOff: require('./speaker-off.png'), + switchCamera: require('./switch-camera.png'), + hamburger: require('./hamburger.png'), + questionBalloon: require('./question-ballon.png'), + talking: require('./talking.png'), + unmute: require('./unmute.png'), + unlocked: require('./unlocked.png'), + videoOn: require('./video-on.png'), + videoOff: require('./video-off.png'), +}; + +export type IconTypes = keyof typeof icons; diff --git a/assets/images/new/zoom/locked@2x.png b/assets/images/new/zoom/locked@2x.png new file mode 100644 index 00000000..c6d98060 Binary files /dev/null and b/assets/images/new/zoom/locked@2x.png differ diff --git a/assets/images/new/zoom/locked@3x.png b/assets/images/new/zoom/locked@3x.png new file mode 100644 index 00000000..170f6e22 Binary files /dev/null and b/assets/images/new/zoom/locked@3x.png differ diff --git a/assets/images/new/zoom/more@2x.png b/assets/images/new/zoom/more@2x.png new file mode 100644 index 00000000..e98bc18e Binary files /dev/null and b/assets/images/new/zoom/more@2x.png differ diff --git a/assets/images/new/zoom/more@3x.png b/assets/images/new/zoom/more@3x.png new file mode 100644 index 00000000..e69710c6 Binary files /dev/null and b/assets/images/new/zoom/more@3x.png differ diff --git a/assets/images/new/zoom/mute@2x.png b/assets/images/new/zoom/mute@2x.png new file mode 100644 index 00000000..65b555a6 Binary files /dev/null and b/assets/images/new/zoom/mute@2x.png differ diff --git a/assets/images/new/zoom/mute@3x.png b/assets/images/new/zoom/mute@3x.png new file mode 100644 index 00000000..da7b29c3 Binary files /dev/null and b/assets/images/new/zoom/mute@3x.png differ diff --git a/assets/images/new/zoom/muted@2x.png b/assets/images/new/zoom/muted@2x.png new file mode 100644 index 00000000..35043632 Binary files /dev/null and b/assets/images/new/zoom/muted@2x.png differ diff --git a/assets/images/new/zoom/muted@3x.png b/assets/images/new/zoom/muted@3x.png new file mode 100644 index 00000000..808ef3e9 Binary files /dev/null and b/assets/images/new/zoom/muted@3x.png differ diff --git a/assets/images/new/zoom/question-ballon@2x.png b/assets/images/new/zoom/question-ballon@2x.png new file mode 100644 index 00000000..ba79fd3f Binary files /dev/null and b/assets/images/new/zoom/question-ballon@2x.png differ diff --git a/assets/images/new/zoom/question-ballon@3x.png b/assets/images/new/zoom/question-ballon@3x.png new file mode 100644 index 00000000..019c69de Binary files /dev/null and b/assets/images/new/zoom/question-ballon@3x.png differ diff --git a/assets/images/new/zoom/share-off@2x.png b/assets/images/new/zoom/share-off@2x.png new file mode 100644 index 00000000..1dba94cb Binary files /dev/null and b/assets/images/new/zoom/share-off@2x.png differ diff --git a/assets/images/new/zoom/share-off@3x.png b/assets/images/new/zoom/share-off@3x.png new file mode 100644 index 00000000..46989fea Binary files /dev/null and b/assets/images/new/zoom/share-off@3x.png differ diff --git a/assets/images/new/zoom/share-on@2x.png b/assets/images/new/zoom/share-on@2x.png new file mode 100644 index 00000000..285118e0 Binary files /dev/null and b/assets/images/new/zoom/share-on@2x.png differ diff --git a/assets/images/new/zoom/share-on@3x.png b/assets/images/new/zoom/share-on@3x.png new file mode 100644 index 00000000..9ed57131 Binary files /dev/null and b/assets/images/new/zoom/share-on@3x.png differ diff --git a/assets/images/new/zoom/speaker-off.png b/assets/images/new/zoom/speaker-off.png new file mode 100644 index 00000000..9763a5a7 Binary files /dev/null and b/assets/images/new/zoom/speaker-off.png differ diff --git a/assets/images/new/zoom/speaker-on.png b/assets/images/new/zoom/speaker-on.png new file mode 100644 index 00000000..f3355ba0 Binary files /dev/null and b/assets/images/new/zoom/speaker-on.png differ diff --git a/assets/images/new/zoom/switch-camera.png b/assets/images/new/zoom/switch-camera.png new file mode 100644 index 00000000..5927b7b7 Binary files /dev/null and b/assets/images/new/zoom/switch-camera.png differ diff --git a/assets/images/new/zoom/talking@2x.png b/assets/images/new/zoom/talking@2x.png new file mode 100644 index 00000000..676d61dd Binary files /dev/null and b/assets/images/new/zoom/talking@2x.png differ diff --git a/assets/images/new/zoom/talking@3x.png b/assets/images/new/zoom/talking@3x.png new file mode 100644 index 00000000..7028a357 Binary files /dev/null and b/assets/images/new/zoom/talking@3x.png differ diff --git a/assets/images/new/zoom/unlocked@2x.png b/assets/images/new/zoom/unlocked@2x.png new file mode 100644 index 00000000..aa5403e2 Binary files /dev/null and b/assets/images/new/zoom/unlocked@2x.png differ diff --git a/assets/images/new/zoom/unlocked@3x.png b/assets/images/new/zoom/unlocked@3x.png new file mode 100644 index 00000000..25f9390f Binary files /dev/null and b/assets/images/new/zoom/unlocked@3x.png differ diff --git a/assets/images/new/zoom/unmute@2x.png b/assets/images/new/zoom/unmute@2x.png new file mode 100644 index 00000000..4c6d2393 Binary files /dev/null and b/assets/images/new/zoom/unmute@2x.png differ diff --git a/assets/images/new/zoom/unmute@3x.png b/assets/images/new/zoom/unmute@3x.png new file mode 100644 index 00000000..dad68fac Binary files /dev/null and b/assets/images/new/zoom/unmute@3x.png differ diff --git a/assets/images/new/zoom/video-off@2x.png b/assets/images/new/zoom/video-off@2x.png new file mode 100644 index 00000000..3e209dd7 Binary files /dev/null and b/assets/images/new/zoom/video-off@2x.png differ diff --git a/assets/images/new/zoom/video-off@3x.png b/assets/images/new/zoom/video-off@3x.png new file mode 100644 index 00000000..06674059 Binary files /dev/null and b/assets/images/new/zoom/video-off@3x.png differ diff --git a/assets/images/new/zoom/video-on@2x.png b/assets/images/new/zoom/video-on@2x.png new file mode 100644 index 00000000..cdd85446 Binary files /dev/null and b/assets/images/new/zoom/video-on@2x.png differ diff --git a/assets/images/new/zoom/video-on@3x.png b/assets/images/new/zoom/video-on@3x.png new file mode 100644 index 00000000..03e69760 Binary files /dev/null and b/assets/images/new/zoom/video-on@3x.png differ diff --git a/assets/images/nfc/contactless.svg b/assets/images/nfc/contactless.svg new file mode 100644 index 00000000..4eb2d478 --- /dev/null +++ b/assets/images/nfc/contactless.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/images/nfc/ic_done.png b/assets/images/nfc/ic_done.png new file mode 100644 index 00000000..5b802855 Binary files /dev/null and b/assets/images/nfc/ic_done.png differ diff --git a/assets/images/nfc/ic_nfc.png b/assets/images/nfc/ic_nfc.png new file mode 100644 index 00000000..274e1b8c Binary files /dev/null and b/assets/images/nfc/ic_nfc.png differ diff --git a/assets/images/offer_ar.png b/assets/images/offer_ar.png deleted file mode 100644 index 1fdbf749..00000000 Binary files a/assets/images/offer_ar.png and /dev/null differ diff --git a/assets/images/online_payments_bg.png b/assets/images/online_payments_bg.png deleted file mode 100644 index 72f8e331..00000000 Binary files a/assets/images/online_payments_bg.png and /dev/null differ diff --git a/assets/images/pharmacy/Group 1206.svg b/assets/images/pharmacy/Group 1206.svg deleted file mode 100644 index ef8f7473..00000000 --- a/assets/images/pharmacy/Group 1206.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/assets/images/pharmacy/Group 1207.svg b/assets/images/pharmacy/Group 1207.svg deleted file mode 100644 index fd2ffd41..00000000 --- a/assets/images/pharmacy/Group 1207.svg +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/assets/images/pharmacy/Logo Parmacy-green.png b/assets/images/pharmacy/Logo Parmacy-green.png deleted file mode 100644 index 72862b33..00000000 Binary files a/assets/images/pharmacy/Logo Parmacy-green.png and /dev/null differ diff --git a/assets/images/pharmacy/Redheart.svg b/assets/images/pharmacy/Redheart.svg deleted file mode 100644 index 3bba67fa..00000000 --- a/assets/images/pharmacy/Redheart.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/assets/images/pharmacy/aramex_shipping_logo.svg b/assets/images/pharmacy/aramex_shipping_logo.svg deleted file mode 100644 index 30cc03b8..00000000 --- a/assets/images/pharmacy/aramex_shipping_logo.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - diff --git a/assets/images/pharmacy/arrow-left-png.png b/assets/images/pharmacy/arrow-left-png.png deleted file mode 100644 index 18d58c87..00000000 Binary files a/assets/images/pharmacy/arrow-left-png.png and /dev/null differ diff --git a/assets/images/pharmacy/arrow-right-png.png b/assets/images/pharmacy/arrow-right-png.png deleted file mode 100644 index 19af7c0b..00000000 Binary files a/assets/images/pharmacy/arrow-right-png.png and /dev/null differ diff --git a/assets/images/pharmacy/arrow.png b/assets/images/pharmacy/arrow.png deleted file mode 100644 index 19af7c0b..00000000 Binary files a/assets/images/pharmacy/arrow.png and /dev/null differ diff --git a/assets/images/pharmacy/arrow_lef.png b/assets/images/pharmacy/arrow_lef.png deleted file mode 100644 index 19af7c0b..00000000 Binary files a/assets/images/pharmacy/arrow_lef.png and /dev/null differ diff --git a/assets/images/pharmacy/call.svg b/assets/images/pharmacy/call.svg new file mode 100644 index 00000000..677d4123 --- /dev/null +++ b/assets/images/pharmacy/call.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/images/pharmacy/delete_red_icon.svg b/assets/images/pharmacy/delete_red_icon.svg deleted file mode 100644 index 8897a683..00000000 --- a/assets/images/pharmacy/delete_red_icon.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/assets/images/pharmacy/edit_icon.svg b/assets/images/pharmacy/edit_icon.svg deleted file mode 100644 index df7cca2f..00000000 --- a/assets/images/pharmacy/edit_icon.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/assets/images/pharmacy/empty_box.png b/assets/images/pharmacy/empty_box.png new file mode 100644 index 00000000..af3551fd Binary files /dev/null and b/assets/images/pharmacy/empty_box.png differ diff --git a/assets/images/pharmacy/heart-empty.svg b/assets/images/pharmacy/heart-empty.svg deleted file mode 100644 index a682a44e..00000000 --- a/assets/images/pharmacy/heart-empty.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/assets/images/pharmacy/hmg_shipping_greenlogo.svg b/assets/images/pharmacy/hmg_shipping_greenlogo.svg deleted file mode 100644 index 449712a5..00000000 --- a/assets/images/pharmacy/hmg_shipping_greenlogo.svg +++ /dev/null @@ -1,25 +0,0 @@ - - - diff --git a/assets/images/pharmacy/hmg_shipping_logo.svg b/assets/images/pharmacy/hmg_shipping_logo.svg deleted file mode 100644 index 8e9db3d6..00000000 --- a/assets/images/pharmacy/hmg_shipping_logo.svg +++ /dev/null @@ -1,17 +0,0 @@ - - - diff --git a/assets/images/pharmacy/instagram.png b/assets/images/pharmacy/instagram.png new file mode 100644 index 00000000..a03f47bd Binary files /dev/null and b/assets/images/pharmacy/instagram.png differ diff --git a/assets/images/pharmacy/location.svg b/assets/images/pharmacy/location.svg new file mode 100644 index 00000000..a52cc72e --- /dev/null +++ b/assets/images/pharmacy/location.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/pharmacy/offers_banner.png b/assets/images/pharmacy/offers_banner.png new file mode 100644 index 00000000..6eab63fb Binary files /dev/null and b/assets/images/pharmacy/offers_banner.png differ diff --git a/assets/images/pharmacy/offers_banner_ar.png b/assets/images/pharmacy/offers_banner_ar.png new file mode 100644 index 00000000..d987d3c6 Binary files /dev/null and b/assets/images/pharmacy/offers_banner_ar.png differ diff --git a/assets/images/pharmacy/pill_reminder_icon.svg b/assets/images/pharmacy/pill_reminder_icon.svg deleted file mode 100644 index f4fb4ddc..00000000 --- a/assets/images/pharmacy/pill_reminder_icon.svg +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/assets/images/pharmacy/success_check_icon.svg b/assets/images/pharmacy/success_check_icon.svg deleted file mode 100644 index ed1379b8..00000000 --- a/assets/images/pharmacy/success_check_icon.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/assets/images/pharmacy/user.svg b/assets/images/pharmacy/user.svg deleted file mode 100644 index 8e978105..00000000 --- a/assets/images/pharmacy/user.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/assets/images/pharmacy/user_icon.svg b/assets/images/pharmacy/user_icon.svg deleted file mode 100644 index 8e978105..00000000 --- a/assets/images/pharmacy/user_icon.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/assets/images/pharmacy/whatsapp.svg b/assets/images/pharmacy/whatsapp.svg new file mode 100644 index 00000000..ee18370c --- /dev/null +++ b/assets/images/pharmacy/whatsapp.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/pharmacy/wishklist_icon.svg b/assets/images/pharmacy/wishklist_icon.svg deleted file mode 100644 index cd0ce16d..00000000 --- a/assets/images/pharmacy/wishklist_icon.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/assets/images/pharmacy_module/bg_1.png b/assets/images/pharmacy_module/bg_1.png index 9505e556..0155a7b3 100644 Binary files a/assets/images/pharmacy_module/bg_1.png and b/assets/images/pharmacy_module/bg_1.png differ diff --git a/assets/images/pharmacy_module/bg_2.png b/assets/images/pharmacy_module/bg_2.png index 96cfd3bc..0a1bc5cb 100644 Binary files a/assets/images/pharmacy_module/bg_2.png and b/assets/images/pharmacy_module/bg_2.png differ diff --git a/assets/images/pharmacy_module/bg_3.png b/assets/images/pharmacy_module/bg_3.png index 127c2669..3a28d5f9 100644 Binary files a/assets/images/pharmacy_module/bg_3.png and b/assets/images/pharmacy_module/bg_3.png differ diff --git a/assets/images/pharmacy_module/bg_4.png b/assets/images/pharmacy_module/bg_4.png index 423ab421..234ebe7b 100644 Binary files a/assets/images/pharmacy_module/bg_4.png and b/assets/images/pharmacy_module/bg_4.png differ diff --git a/assets/images/pharmacy_module/lakum/akum_transfer.png b/assets/images/pharmacy_module/lakum/akum_transfer.png new file mode 100644 index 00000000..30785b08 Binary files /dev/null and b/assets/images/pharmacy_module/lakum/akum_transfer.png differ diff --git a/assets/images/pharmacy_module/offers_banner.png b/assets/images/pharmacy_module/offers_banner.png new file mode 100644 index 00000000..6eab63fb Binary files /dev/null and b/assets/images/pharmacy_module/offers_banner.png differ 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 00000000..d987d3c6 Binary files /dev/null and b/assets/images/pharmacy_module/offers_banner_ar.png differ diff --git a/assets/images/pharmacy_module/payment.png b/assets/images/pharmacy_module/payment.png new file mode 100644 index 00000000..275aa40a Binary files /dev/null and b/assets/images/pharmacy_module/payment.png differ diff --git a/assets/images/pharmacy_module/payment/applePay.png b/assets/images/pharmacy_module/payment/applePay.png new file mode 100644 index 00000000..fd167e1c Binary files /dev/null and b/assets/images/pharmacy_module/payment/applePay.png differ diff --git a/assets/images/powerd-by.jpg b/assets/images/powerd-by.jpg index 93bdbb18..eda1688c 100644 Binary files a/assets/images/powerd-by.jpg and b/assets/images/powerd-by.jpg differ diff --git a/assets/images/progress-loading-red-crop-1.gif b/assets/images/progress-loading-red-crop-1.gif new file mode 100644 index 00000000..6dba7901 Binary files /dev/null and b/assets/images/progress-loading-red-crop-1.gif differ diff --git a/assets/images/rectangle.png b/assets/images/rectangle.png deleted file mode 100644 index e4bdb0b6..00000000 Binary files a/assets/images/rectangle.png and /dev/null differ diff --git a/assets/images/robort.png b/assets/images/robort.png deleted file mode 100644 index 320afcbc..00000000 Binary files a/assets/images/robort.png and /dev/null differ diff --git a/assets/images/roboticon.png b/assets/images/roboticon.png deleted file mode 100644 index 5b04e287..00000000 Binary files a/assets/images/roboticon.png and /dev/null differ diff --git a/assets/images/search_medicine_icon.png b/assets/images/search_medicine_icon.png deleted file mode 100644 index 349620a5..00000000 Binary files a/assets/images/search_medicine_icon.png and /dev/null differ diff --git a/assets/images/siri-ianzhao.gif b/assets/images/siri-ianzhao.gif deleted file mode 100644 index 8d1c644f..00000000 Binary files a/assets/images/siri-ianzhao.gif and /dev/null differ diff --git a/assets/images/svg/HMC.svg b/assets/images/svg/HMC.svg new file mode 100644 index 00000000..a127cd98 --- /dev/null +++ b/assets/images/svg/HMC.svg @@ -0,0 +1,8 @@ + + + + diff --git a/assets/images/svg/HMG.svg b/assets/images/svg/HMG.svg new file mode 100644 index 00000000..7b199bf5 --- /dev/null +++ b/assets/images/svg/HMG.svg @@ -0,0 +1,8 @@ + + + + diff --git a/assets/images/svg/discount_ar.svg b/assets/images/svg/discount_ar.svg deleted file mode 100644 index d9d6ec27..00000000 --- a/assets/images/svg/discount_ar.svg +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - مصخ - - - - diff --git a/assets/images/svg/discount_en.svg b/assets/images/svg/discount_en.svg deleted file mode 100644 index 294cf19c..00000000 --- a/assets/images/svg/discount_en.svg +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/assets/images/svg/location.svg b/assets/images/svg/location.svg new file mode 100644 index 00000000..19b8bd30 --- /dev/null +++ b/assets/images/svg/location.svg @@ -0,0 +1,10 @@ + + + + + + diff --git a/assets/images/svg/symptom.svg b/assets/images/svg/symptom.svg deleted file mode 100644 index aa670da1..00000000 --- a/assets/images/svg/symptom.svg +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ 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..714a8083 --- /dev/null +++ b/assets/images/svg/tamara.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/images/test-weight.png b/assets/images/test-weight.png deleted file mode 100644 index 934b2467..00000000 Binary files a/assets/images/test-weight.png and /dev/null differ diff --git a/assets/images/undraw_connected_world_wuay.png b/assets/images/undraw_connected_world_wuay.png deleted file mode 100644 index f1bd3f00..00000000 Binary files a/assets/images/undraw_connected_world_wuay.png and /dev/null differ diff --git a/assets/images/weight_icon.png b/assets/images/weight_icon.png deleted file mode 100644 index 5c640114..00000000 Binary files a/assets/images/weight_icon.png and /dev/null differ diff --git a/assets/json/covid-drive-thru-question.json b/assets/json/covid-drive-thru-question.json new file mode 100644 index 00000000..626d702a --- /dev/null +++ b/assets/json/covid-drive-thru-question.json @@ -0,0 +1,85 @@ +[ + { + "id": 1, + "questionEN": "Is the test intended for travel?", + "questionAR": "هل تجري التحليل بغرض السفر؟", + "ans": 2 + }, + { + "id": 2, + "questionEN": "Coming from outside KSA within last 2 weeks?", + "questionAR": "هل قدمت من خارج المملكة خلال الأسبوعين الماضيين؟", + "ans": 2 + }, + { + "id": 3, + "questionEN": "Do you currently have fever?", + "questionAR": "هل تعاني حاليا من حرارة؟", + "ans": 2 + }, + { + "id": 4, + "questionEN": "Did you have fever in last 2 weeks?", + "questionAR": "هل عانيت من حرارة في الأسبوعين الماضيين؟", + "ans": 2 + }, + { + "id": 5, + "questionEN": "Do you have a sore throat?", + "questionAR": "هل لديك التهاب في الحلق؟", + "ans": 2 + }, + { + "id": 6, + "questionEN": "Do you have a runny nose?", + "questionAR": "هل لديك سيلان بالأنف؟" + }, + { + "id": 7, + "questionEN": "Do you have a cough?", + "questionAR": "هل لديك سعال؟", + "ans": 2 + }, + { + "id": 8, + "questionEN": "Do you have shortness of breath?", + "questionAR": "هل تعانين من ضيق في التنفس؟", + "ans": 2 + }, + { + "id": 9, + "questionEN": "Do you have nausea?", + "questionAR": "هل تعانين من غثيان؟", + "ans": 2 + }, + { + "id": 10, + "questionEN": "Do you have vomiting?", + "questionAR": "هل تعاني من القيء؟", + "ans": 2 + }, + { + "id": 11, + "questionEN": "Do you have a headache?", + "questionAR": "هل تعاني من صداع في الرأس؟", + "ans": 2 + }, + { + "id": 12, + "questionEN": "Do you have muscle pain?", + "questionAR": "هل تعانين من آلام عضلية؟", + "ans": 2 + }, + { + "id": 13, + "questionEN": "Do you have joint pain?", + "questionAR": "هل تعانين من آلام المفاصل؟", + "ans": 2 + }, + { + "id": 14, + "questionEN": "Do you have diarrhea?", + "questionAR": "هل لديك اسهال؟", + "ans": 2 + } +] \ No newline at end of file diff --git a/assets/payment_options/payment_options.png b/assets/payment_options/payment_options.png new file mode 100644 index 00000000..4bb83fec Binary files /dev/null and b/assets/payment_options/payment_options.png differ diff --git a/assets/tracker/devices.png b/assets/tracker/devices.png deleted file mode 100644 index f00f9d95..00000000 Binary files a/assets/tracker/devices.png and /dev/null differ diff --git a/encrypted_private_key_path b/encrypted_private_key_path new file mode 100644 index 00000000..50e125b3 Binary files /dev/null and b/encrypted_private_key_path differ diff --git a/encryption_public_key.pem b/encryption_public_key.pem new file mode 100644 index 00000000..f250df1a --- /dev/null +++ b/encryption_public_key.pem @@ -0,0 +1,11 @@ +-----BEGIN PUBLIC KEY----- +MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEApKqued5RaqBjKntLoVhj +rflB5NpGELhAftnKrXO+0lCQGm0huxWeb/KtSgniJpPQ1LXfhGKqjaZwu3zd2xsU +9D6i7Ie1QJvIJlxHwi/zKdBX7nSHx5phK+yRJF+Fnt5wieZ8bzT4Eqn31J6Cdahl +0sZDTjixl/fhM2G+E8gYNsWMihcWnMXejHdKT2yHG+rJXt4FvYYAuwIW/S75vSOM +L4CE4JS5D9UcYpNxU4Cv6KxiAAK/oQmzrrSoU9lJ6mp5wrwJDsBUgwOrXxYPct9N +FoqYgh54fs9xuh5fvHozst8wFY8Kf4hPVmOdPtcUlWQSbtRf0CehJ9yuftHmFxWX +yjyoa9X3MK7yHoZIAFXvbh1n+QUWGMNrCNIdqDtPEtjVBtSAGL5x+lxqfFMMRKJA +OfOtzjG1QDPP3EPrw/vfU2hCXZ75wlOoqEy6vmrVaYWJ5Apx0ftujtUxslSJ15Zz +CghYLtu/JolJT1Hxg5uOFpLaX3VoAs+y9e7+oRgPPVtHAgMBAAE= +-----END PUBLIC KEY----- diff --git a/flutter_tts-voice_enhancement/.github/ISSUE_TEMPLATE/bug_report.md b/flutter_tts-voice_enhancement/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 614a6708..00000000 --- a/flutter_tts-voice_enhancement/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -name: Bug report -about: Create a report to help us improve - ---- - -## 🐛 Bug Report - - - -### Expected behavior - -### Reproduction steps - -### Configuration - -**Version:** 0.1.x - -**Platform:** -- [ ] :iphone: iOS -- [ ] :robot: Android diff --git a/flutter_tts-voice_enhancement/.github/ISSUE_TEMPLATE/feature_request.md b/flutter_tts-voice_enhancement/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index 35a881a3..00000000 --- a/flutter_tts-voice_enhancement/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for this project - ---- - -## 🚀 Feature Requests - - - -### Contextualize the feature - - -### Describe the feature - - -### Platforms affected (mark all that apply) -- [ ] :iphone: iOS -- [ ] :robot: Android diff --git a/flutter_tts-voice_enhancement/.github/ISSUE_TEMPLATE/questions-and-help.md b/flutter_tts-voice_enhancement/.github/ISSUE_TEMPLATE/questions-and-help.md deleted file mode 100644 index ba501f3c..00000000 --- a/flutter_tts-voice_enhancement/.github/ISSUE_TEMPLATE/questions-and-help.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -name: Questions and Help -about: If you have questions, please use this for support - ---- - -## 💬 Questions and Help - -Provide question related to this flutter plugin. diff --git a/flutter_tts-voice_enhancement/.github/workflows/main.yml b/flutter_tts-voice_enhancement/.github/workflows/main.yml deleted file mode 100644 index 832dd069..00000000 --- a/flutter_tts-voice_enhancement/.github/workflows/main.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: github pages - -on: - push: - branches: - - master - -jobs: - deploy: - runs-on: ubuntu-18.04 - steps: - - uses: actions/checkout@v2 - - - name: Setup Flutter - run: | - git clone https://github.com/flutter/flutter.git --depth 1 -b beta _flutter - echo "::add-path::${GITHUB_WORKSPACE}/_flutter/bin" - - - name: Install - run: | - cd example - flutter config --enable-web - flutter pub get - - - name: Build - run: | - cd example - flutter build web - - - name: Deploy - uses: peaceiris/actions-gh-pages@v3 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./example/build/web diff --git a/flutter_tts-voice_enhancement/.gitignore b/flutter_tts-voice_enhancement/.gitignore deleted file mode 100644 index bc0883df..00000000 --- a/flutter_tts-voice_enhancement/.gitignore +++ /dev/null @@ -1,94 +0,0 @@ -# Miscellaneous -*.class -*.lock -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.project -.svn/ -bin/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# Android Studio related -android/.classpath -android/.settings/ - -# Visual Studio Code related -.vscode/ - -# Flutter repo-specific -/bin/cache/ -/bin/mingit/ -/dev/benchmarks/mega_gallery/ -/dev/bots/.recipe_deps -/dev/bots/android_tools/ -/dev/docs/doc/ -/dev/docs/lib/ -/dev/docs/pubspec.yaml -/packages/flutter/coverage/ -version - -# Flutter/Dart/Pub related -**/doc/api/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -build/ -flutter_*.png -linked_*.ds -unlinked.ds -unlinked_spec.ds - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages -example/ios/Flutter/flutter_export_environment.sh diff --git a/flutter_tts-voice_enhancement/CHANGELOG.md b/flutter_tts-voice_enhancement/CHANGELOG.md deleted file mode 100644 index bff8b759..00000000 --- a/flutter_tts-voice_enhancement/CHANGELOG.md +++ /dev/null @@ -1,197 +0,0 @@ -# ChangeLog - -## 1.3.0 - -- All: Adding await speak completion - -## 1.2.7 - -- iOS: Adding utterance settings to synthesizeToFile -- Android: Fix crash when utterance completes after Engine is detached - -## 1.2.6 - -- Android: Fixing new API onAttachedToEngine call - -## 1.2.5 - -- macOS: Adding support - -## 1.2.4 - -- iOS: Deactivate audio session only when needed -- Android: Better exception handling for getLanguages -- Android: Adding getEngines -- Android: Adding new Android plugin APIs - -## 1.2.3 - -- iOS: Adding synthesize to file -- iOS: Fix set category ios - -## 1.2.2 - -- Web: Adding pause and continue - -## 1.2.1 - -- iOS: Fix setting iOS Category -- iOS/Android: Adding additional platform calls - -## 1.2.0 - -- iOS: Adding Set Audio Session Category -- Android: Bug fixes - -## 1.1.0 - -- iOS: Adding Pause -- iOS: Adding set Shared Instance - -## 1.0.0 - -- iOS/Android: Feature - Speech marks -- iOS/Android: Breaking changes to Speech rate - -## 0.9.2 - -- iOS: Changing audio session to playAndRecord - -## 0.9.1 - -- Android: Fixing method call error - -## 0.9.0 - -- Android: Adding synthesize to file - -## 0.8.7 - -- Android: Fix sporadic ANR on initialization - -## 0.8.6 - -- iOS: Reducing volume of other sessions while TTS is playing - -## 0.8.5 - -- Android: Fix Android async platform initialization -- Android: Removing initHandler - -## 0.8.2 - -- Web: Adding isLanguageAvailable method -- All: Fixing isLanguageAvailable platform channel and making it case insensitive - -## 0.8.0 - -- Web: Adding Web Support - -## 0.7.0 - -- iOS: Adding Swift version 4.2 to podspec and correct audio playback category - -## 0.6.0 - -- Android: AndroidX support - -## 0.5.2 - -- Android: Bug Fix on isLanguageAvailable - -## 0.5.1 - -- Applying flutter format to fix health suggestion - -## 0.5.0 - -- Android: Adding silence before speak -- Android: Removing deprecated API - -## 0.2.6 - -- IOS: Add voice selection implementation - -## 0.2.5 - -- Android: Ensure invokeMethod runs on main thread - -## 0.2.4 - -- Android: setting minSDK back to 21 and adding instructions to readme -- Android: Adding fallback for getLanguages and defaultLanguage - -## 0.2.3 - -- IOS: Audio continues with the Ring/Silent switch set to silent - -## 0.2.2 - -- Android: Fixing Locale bug - -## 0.2.1 - -- IOS: Fixing getLanguages bug - -## 0.2.0 - -- Android: Adding exception catch for samsung devices -- Android: Using default com.google.android.tts engine -- Android: Get and Set Voice -- Android: InitHandler -- Cleaning up the example - -## 0.1.2 - -- Support for Android background execution -- Updating Android build gradle version to 3.2.1 - -## 0.1.1 - -- Fixing TTS bound error in the example -- Fixing default voice language not found error on Android - -## 0.1.0 - -- Updating version for improved maintenance score -- Updating package description for improved maintenance score - -## 0.0.8 - -- Adding analysis_options.yaml for improved health score -- Fixing info/errors from flutter analyze - -## 0.0.7 - -- Updating SDK version in pubspec.yaml -- Adding package link to README -- Fixing language string warning received from xcode - -## 0.0.6 - -- Android: Upgrading Gradle 4.1 to 4.4 -- Android: Setting minSdk version to 21 -- Android: Adding try/catch to getAvailableLanguages & getDefaultVoice methods (Issues with API 21 & 22) - -## 0.0.5 - -- Adding IOS/Android isLanguageAvailable -- Rename setRate to setSpeechRate - -## 0.0.4 - -- Simplify podspec for Cocoapods 1.5.0 - -## 0.0.3 - -- Adding IOS/Android speech pitch and volume - -## 0.0.2 - -- Flutter formatting and fixing pubspec sdk versioning - -## 0.0.1 - -- first POC : - - methods : speak, stop, setRate, setLangauge, getLanguages - - a globalHandler for completion diff --git a/flutter_tts-voice_enhancement/CODE_OF_CONDUCT.md b/flutter_tts-voice_enhancement/CODE_OF_CONDUCT.md deleted file mode 100644 index 43989576..00000000 --- a/flutter_tts-voice_enhancement/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,46 +0,0 @@ -# Contributor Covenant Code of Conduct - -## Our Pledge - -In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. - -## Our Standards - -Examples of behavior that contributes to creating a positive environment include: - -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members - -Examples of unacceptable behavior by participants include: - -* The use of sexualized language or imagery and unwelcome sexual attention or advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a professional setting - -## Our Responsibilities - -Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. - -Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. - -## Scope - -This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at eyedea32@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. - -Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] - -[homepage]: http://contributor-covenant.org -[version]: http://contributor-covenant.org/version/1/4/ diff --git a/flutter_tts-voice_enhancement/LICENSE b/flutter_tts-voice_enhancement/LICENSE deleted file mode 100644 index 56dcdf22..00000000 --- a/flutter_tts-voice_enhancement/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2018 Daniel Lutton - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/flutter_tts-voice_enhancement/README.md b/flutter_tts-voice_enhancement/README.md deleted file mode 100644 index 4e32d45d..00000000 --- a/flutter_tts-voice_enhancement/README.md +++ /dev/null @@ -1,194 +0,0 @@ -# Text To Speech - -[![pub package](https://img.shields.io/pub/v/flutter_tts.svg?style=for-the-badge&colorB=green)](https://pub.dartlang.org/packages/flutter_tts) - -A flutter text to speech plugin (Swift,Java) - -## Features - -- [x] Android, iOS, Web, & macOS - - [x] speak - - [x] stop - - [x] get languages - - [x] set language - - [x] set speech rate - - [x] set speech volume - - [x] set speech pitch - - [x] is language available -- [x] Android, iOS - - [x] get voices - - [x] set voice - - [x] speech marks (requires iOS 7+ and Android 26+) - - [x] synthesize to file (requires iOS 13+) -- [x] iOS, Web - - [x] pause -- [x] Android - - [x] set Silence -- [x] iOS - - [x] set shared instance - - [x] set audio session category - -## Usage - -## macOS - -```bash -OSX version: 10.15 -``` - -[Example App](https://github.com/dlutton/flutter_tts/tree/macOS_app) from the macOS_app branch - -## Web - -[Website](https://dlutton.github.io/flutter_tts) from the example directory. - -## Android - -Change the minimum Android sdk version to 21 (or higher) in your `android/app/build.gradle` file. - -```java -minSdkVersion 21 -``` - -## iOS - -There's a known issue with integrating plugins that use Swift into a Flutter project created with the Objective-C template. [Flutter#16049](https://github.com/flutter/flutter/issues/16049) - -[Example](https://github.com/dlutton/flutter_tts/blob/master/example/lib/main.dart) - -To use this plugin : - -- add the dependency to your [pubspec.yaml](https://github.com/dlutton/flutter_tts/blob/master/example/pubspec.yaml) file. - -```yaml - dependencies: - flutter: - sdk: flutter - flutter_tts: -``` - -- instantiate FlutterTts - -```dart -FlutterTts flutterTts = FlutterTts(); - -``` - -To set shared audio [instance](https://developer.apple.com/documentation/avfoundation/avaudiosession/1616504-sharedinstance) (iOS only): - -```dart -await flutterTts.setSharedInstance(true); -``` - -To set audio [category and options](https://developer.apple.com/documentation/avfoundation/avaudiosession) (iOS only): - -```dart -await flutterTts - .setIosAudioCategory(IosTextToSpeechAudioCategory.playAndRecord, [ - IosTextToSpeechAudioCategoryOptions.allowBluetooth, - IosTextToSpeechAudioCategoryOptions.allowBluetoothA2DP, - IosTextToSpeechAudioCategoryOptions.mixWithOthers - ]); -``` - -To await speak completion. - -```dart -await flutterTts.awaitSpeakCompletion(true); -``` - -### speak, stop, getLanguages, setLanguage, setSpeechRate, setVoice, setVolume, setPitch, isLanguageAvailable, setSharedInstance - -```dart -Future _speak() async{ - var result = await flutterTts.speak("Hello World"); - if (result == 1) setState(() => ttsState = TtsState.playing); -} - -Future _stop() async{ - var result = await flutterTts.stop(); - if (result == 1) setState(() => ttsState = TtsState.stopped); -} - -List languages = await flutterTts.getLanguages; - -await flutterTts.setLanguage("en-US"); - -await flutterTts.setSpeechRate(1.0); - -await flutterTts.setVolume(1.0); - -await flutterTts.setPitch(1.0); - -await flutterTts.isLanguageAvailable("en-US"); - -// iOS and Web only -await flutterTts.pause(); - -// iOS, macOS, and Android only -await flutterTts.synthesizeToFile("Hello World", Platform.isAndroid ? "tts.wav" : "tts.caf"); - -await flutterTts.setVoice({"name": "Karen", "locale": "en-AU"}); - -// iOS only -await flutterTts.setSharedInstance(true); - -// Android only -await flutterTts.setSilence(2); - -await flutterTts.getEngines(); -``` - -### Listening for platform calls - -```dart -flutterTts.setStartHandler(() { - setState(() { - ttsState = TtsState.playing; - }); -}); - -flutterTts.setCompletionHandler(() { - setState(() { - ttsState = TtsState.stopped; - }); -}); - -flutterTts.setProgressHandler((String text, int startOffset, int endOffset, String word) { - setState(() { - _currentWord = word; - }); -}); - -flutterTts.setErrorHandler((msg) { - setState(() { - ttsState = TtsState.stopped; - }); -}); - -flutterTts.setCancelHandler((msg) { - setState(() { - ttsState = TtsState.stopped; - }); -}); - -// iOS and Web -flutterTts.setPauseHandler((msg) { - setState(() { - ttsState = TtsState.paused; - }); -}); - -flutterTts.setContinueHandler((msg) { - setState(() { - ttsState = TtsState.continued; - }); -}); -``` - -## Getting Started - -For help getting started with Flutter, view our online -[documentation](https://flutter.dev/). - -For help on editing plugin code, view the [documentation](https://flutter.dev/platform-plugins/#edit-code). diff --git a/flutter_tts-voice_enhancement/analysis_options.yaml b/flutter_tts-voice_enhancement/analysis_options.yaml deleted file mode 100644 index e8779c50..00000000 --- a/flutter_tts-voice_enhancement/analysis_options.yaml +++ /dev/null @@ -1,35 +0,0 @@ -analyzer: - strong-mode: - implicit-casts: false - errors: - unused_import: error - unused_local_variable: error - dead_code: error -linter: - rules: - - avoid_empty_else - - comment_references - - control_flow_in_finally - - empty_statements - - hash_and_equals - - only_throw_errors - - test_types_in_equals - - throw_in_finally - - unrelated_type_equality_checks - - valid_regexps - - avoid_init_to_null - - avoid_return_types_on_setters - - await_only_futures - - camel_case_types - - directives_ordering - - empty_catches - - empty_constructor_bodies - - library_names - - library_prefixes - - non_constant_identifier_names - - omit_local_variable_types - - prefer_final_fields - - prefer_is_not_empty - - prefer_typing_uninitialized_variables - - slash_for_doc_comments - - type_init_formals \ No newline at end of file diff --git a/flutter_tts-voice_enhancement/android/.gitignore b/flutter_tts-voice_enhancement/android/.gitignore deleted file mode 100644 index c6cbe562..00000000 --- a/flutter_tts-voice_enhancement/android/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -*.iml -.gradle -/local.properties -/.idea/workspace.xml -/.idea/libraries -.DS_Store -/build -/captures diff --git a/flutter_tts-voice_enhancement/android/build.gradle b/flutter_tts-voice_enhancement/android/build.gradle deleted file mode 100644 index 1308c920..00000000 --- a/flutter_tts-voice_enhancement/android/build.gradle +++ /dev/null @@ -1,48 +0,0 @@ -def PLUGIN = "flutter_tts"; -def ANDROIDX_WARNING = "flutterPluginsAndroidXWarning"; -gradle.buildFinished { buildResult -> - if (buildResult.failure && !rootProject.ext.has(ANDROIDX_WARNING)) { - println ' *********************************************************' - println 'WARNING: This version of ' + PLUGIN + ' will break your Android build if it or its dependencies aren\'t compatible with AndroidX.' - println ' See https://goo.gl/CP92wY for more information on the problem and how to fix it.' - println ' This warning prints for all Android build failures. The real root cause of the error may be unrelated.' - println ' *********************************************************' - rootProject.ext.set(ANDROIDX_WARNING, true); - } -} - -group 'com.tundralabs.fluttertts' -version '1.0-SNAPSHOT' - -buildscript { - repositories { - google() - jcenter() - } - - dependencies { - classpath 'com.android.tools.build:gradle:3.4.2' - } -} - -rootProject.allprojects { - repositories { - google() - jcenter() - } -} - -apply plugin: 'com.android.library' - -android { - compileSdkVersion 28 - - defaultConfig { - minSdkVersion 21 - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - targetSdkVersion 27 - } - lintOptions { - disable 'InvalidPackage' - } -} diff --git a/flutter_tts-voice_enhancement/android/gradle.properties b/flutter_tts-voice_enhancement/android/gradle.properties deleted file mode 100644 index a6738207..00000000 --- a/flutter_tts-voice_enhancement/android/gradle.properties +++ /dev/null @@ -1,4 +0,0 @@ -org.gradle.jvmargs=-Xmx1536M -android.useAndroidX=true -android.enableJetifier=true -android.enableR8=true diff --git a/flutter_tts-voice_enhancement/android/gradle/wrapper/gradle-wrapper.properties b/flutter_tts-voice_enhancement/android/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 8d9c8a3f..00000000 --- a/flutter_tts-voice_enhancement/android/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Fri Sep 27 12:18:40 PDT 2019 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip diff --git a/flutter_tts-voice_enhancement/android/settings.gradle b/flutter_tts-voice_enhancement/android/settings.gradle deleted file mode 100644 index 26aeb433..00000000 --- a/flutter_tts-voice_enhancement/android/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -rootProject.name = 'flutter_tts' diff --git a/flutter_tts-voice_enhancement/android/src/main/AndroidManifest.xml b/flutter_tts-voice_enhancement/android/src/main/AndroidManifest.xml deleted file mode 100644 index 9cad3a1b..00000000 --- a/flutter_tts-voice_enhancement/android/src/main/AndroidManifest.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - diff --git a/flutter_tts-voice_enhancement/android/src/main/java/com/tundralabs/fluttertts/FlutterTtsPlugin.java b/flutter_tts-voice_enhancement/android/src/main/java/com/tundralabs/fluttertts/FlutterTtsPlugin.java deleted file mode 100644 index 92e6a092..00000000 --- a/flutter_tts-voice_enhancement/android/src/main/java/com/tundralabs/fluttertts/FlutterTtsPlugin.java +++ /dev/null @@ -1,454 +0,0 @@ -package com.tundralabs.fluttertts; - -import android.content.Context; -import android.os.Build; -import android.os.Bundle; -import android.os.Handler; -import android.os.Looper; -import android.speech.tts.TextToSpeech; -import android.speech.tts.UtteranceProgressListener; -import android.speech.tts.Voice; -import android.util.Log; -import androidx.annotation.NonNull; -import io.flutter.embedding.engine.plugins.FlutterPlugin; -import io.flutter.plugin.common.BinaryMessenger; -import io.flutter.plugin.common.MethodCall; -import io.flutter.plugin.common.MethodChannel; -import io.flutter.plugin.common.MethodChannel.MethodCallHandler; -import io.flutter.plugin.common.MethodChannel.Result; -import io.flutter.plugin.common.PluginRegistry.Registrar; -import java.io.File; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Locale; -import java.util.MissingResourceException; -import java.util.UUID; - -/** FlutterTtsPlugin */ -public class FlutterTtsPlugin implements MethodCallHandler, FlutterPlugin { - private Handler handler; - private MethodChannel methodChannel; - private MethodChannel.Result speakResult; - private boolean awaitSpeakCompletion = false; - private boolean speaking = false; - private Context context; - private TextToSpeech tts; - private final String tag = "TTS"; - private final String googleTtsEngine = "com.google.android.tts"; - private boolean isTtsInitialized = false; - private ArrayList pendingMethodCalls = new ArrayList<>(); - private final HashMap utterances = new HashMap<>(); - Bundle bundle; - private int silencems; - private static final String SILENCE_PREFIX = "SIL_"; - private static final String SYNTHESIZE_TO_FILE_PREFIX = "STF_"; - - /** Plugin registration. */ - public static void registerWith(Registrar registrar) { - FlutterTtsPlugin instance = new FlutterTtsPlugin(); - instance.initInstance(registrar.messenger(), registrar.activeContext()); - } - - private void initInstance(BinaryMessenger messenger, Context context) { - this.context = context; - methodChannel = new MethodChannel(messenger, "flutter_tts"); - methodChannel.setMethodCallHandler(this); - handler = new Handler(Looper.getMainLooper()); - bundle = new Bundle(); - tts = new TextToSpeech(context, onInitListener, googleTtsEngine); - } - - /** Android Plugin APIs */ - @Override - public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) { - initInstance(binding.getBinaryMessenger(), binding.getApplicationContext()); - } - - @Override - public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { - stop(); - tts.shutdown(); - context = null; - methodChannel.setMethodCallHandler(null); - methodChannel = null; - } - - private UtteranceProgressListener utteranceProgressListener = - new UtteranceProgressListener() { - @Override - public void onStart(String utteranceId) { - if (utteranceId != null && utteranceId.startsWith(SYNTHESIZE_TO_FILE_PREFIX)) { - invokeMethod("synth.onStart", true); - } else { - Log.d(tag, "Utterance ID has started: " + utteranceId); - invokeMethod("speak.onStart", true); - } - if (Build.VERSION.SDK_INT < 26) { - this.onProgress(utteranceId, 0, utterances.get(utteranceId).length()); - } - } - - @Override - public void onDone(String utteranceId) { - if (utteranceId != null && utteranceId.startsWith(SILENCE_PREFIX)) return; - if (utteranceId != null && utteranceId.startsWith(SYNTHESIZE_TO_FILE_PREFIX)) { - invokeMethod("synth.onComplete", true); - } else { - Log.d(tag, "Utterance ID has completed: " + utteranceId); - if (awaitSpeakCompletion) { - speakCompletion(1); - } - invokeMethod("speak.onComplete", true); - } - utterances.remove(utteranceId); - } - - @Override - public void onStop(String utteranceId, boolean interrupted) { - Log.d( - tag, - "Utterance ID has been stopped: " + utteranceId + ". Interrupted: " + interrupted); - if (awaitSpeakCompletion) { - speaking = false; - } - invokeMethod("speak.onCancel", true); - } - - private void onProgress(String utteranceId, int startAt, int endAt) { - if (utteranceId != null && !utteranceId.startsWith(SYNTHESIZE_TO_FILE_PREFIX)) { - final String text = utterances.get(utteranceId); - final HashMap data = new HashMap<>(); - data.put("text", text); - data.put("start", Integer.toString(startAt)); - data.put("end", Integer.toString(endAt)); - data.put("word", text.substring(startAt, endAt)); - invokeMethod("speak.onProgress", data); - } - } - - // Requires Android 26 or later - @Override - public void onRangeStart(String utteranceId, int startAt, int endAt, int frame) { - if (utteranceId != null && !utteranceId.startsWith(SYNTHESIZE_TO_FILE_PREFIX)) { - super.onRangeStart(utteranceId, startAt, endAt, frame); - this.onProgress(utteranceId, startAt, endAt); - } - } - - @Override - @Deprecated - public void onError(String utteranceId) { - if (utteranceId != null && utteranceId.startsWith(SYNTHESIZE_TO_FILE_PREFIX)) { - invokeMethod("synth.onError", "Error from TextToSpeech (synth)"); - } else { - if (awaitSpeakCompletion) { - speaking = false; - } - invokeMethod("speak.onError", "Error from TextToSpeech (speak)"); - } - } - - @Override - public void onError(String utteranceId, int errorCode) { - if (utteranceId != null && utteranceId.startsWith(SYNTHESIZE_TO_FILE_PREFIX)) { - invokeMethod("synth.onError", "Error from TextToSpeech (synth) - " + errorCode); - } else { - if (awaitSpeakCompletion) { - speaking = false; - } - invokeMethod("speak.onError", "Error from TextToSpeech (speak) - " + errorCode); - } - } - }; - - void speakCompletion(final int success) { - speaking = false; - handler.post( - new Runnable() { - @Override - public void run() { - speakResult.success(success); - } - }); - } - - private TextToSpeech.OnInitListener onInitListener = - new TextToSpeech.OnInitListener() { - @Override - public void onInit(int status) { - if (status == TextToSpeech.SUCCESS) { - tts.setOnUtteranceProgressListener(utteranceProgressListener); - - try { - Locale locale = tts.getDefaultVoice().getLocale(); - if (isLanguageAvailable(locale)) { - tts.setLanguage(locale); - } - } catch (NullPointerException | IllegalArgumentException e) { - Log.e(tag, "getDefaultLocale: " + e.getMessage()); - } - - // Handle pending method calls (sent while TTS was initializing) - isTtsInitialized = true; - for (Runnable call : pendingMethodCalls) { - call.run(); - } - } else { - Log.e(tag, "Failed to initialize TextToSpeech"); - } - } - }; - - @Override - public void onMethodCall(@NonNull final MethodCall call, @NonNull final Result result) { - // If TTS is still loading - if (!isTtsInitialized) { - // Suspend method call until the TTS engine is ready - final Runnable suspendedCall = - new Runnable() { - public void run() { - onMethodCall(call, result); - } - }; - pendingMethodCalls.add(suspendedCall); - return; - } - switch (call.method) { - case "speak": - { - String text = call.arguments.toString(); - if (this.speaking) { - result.success(0); - break; - } - speak(text); - if (this.awaitSpeakCompletion) { - this.speaking = true; - this.speakResult = result; - } else { - result.success(1); - } - break; - } - case "awaitSpeakCompletion": - { - this.awaitSpeakCompletion = Boolean.parseBoolean(call.arguments.toString()); - result.success(1); - break; - } - case "synthesizeToFile": - { - String text = call.argument("text"); - String fileName = call.argument("fileName"); - synthesizeToFile(text, fileName); - result.success(1); - break; - } - case "stop": - stop(); - result.success(1); - break; - case "setSpeechRate": - String rate = call.arguments.toString(); - setSpeechRate(Float.parseFloat(rate)); - result.success(1); - break; - case "setVolume": - String volume = call.arguments.toString(); - setVolume(Float.parseFloat(volume), result); - break; - case "setPitch": - String pitch = call.arguments.toString(); - setPitch(Float.parseFloat(pitch), result); - break; - case "setLanguage": - { - String language = call.arguments.toString(); - setLanguage(language, result); - break; - } - case "getLanguages": - getLanguages(result); - break; - case "getVoices": - getVoices(result); - break; - case "getSpeechRateValidRange": - getSpeechRateValidRange(result); - break; - case "getEngines": - getEngines(result); - break; - case "setVoice": - HashMap voice = call.arguments(); - setVoice(voice, result); - break; - case "isLanguageAvailable": - { - String language = call.arguments().toString(); - Locale locale = Locale.forLanguageTag(language); - result.success(isLanguageAvailable(locale)); - break; - } - case "setSilence": - String silencems = call.arguments.toString(); - this.silencems = Integer.parseInt(silencems); - break; - case "setSharedInstance": - result.success(1); - break; - default: - result.notImplemented(); - break; - } - } - - void setSpeechRate(float rate) { - tts.setSpeechRate(rate); - } - - Boolean isLanguageAvailable(Locale locale) { - return tts.isLanguageAvailable(locale) >= TextToSpeech.LANG_AVAILABLE; - } - - void setLanguage(String language, Result result) { - Locale locale = Locale.forLanguageTag(language); - if (isLanguageAvailable(locale)) { - tts.setLanguage(locale); - result.success(1); - } else { - result.success(0); - } - } - - void setVoice(HashMap voice, Result result) { - for (Voice ttsVoice : tts.getVoices()) { - if (ttsVoice.getName().equals(voice.get("name")) && ttsVoice.getLocale().toLanguageTag().equals(voice.get("locale"))) { - tts.setVoice(ttsVoice); - result.success(1); - return; - } - } - Log.d(tag, "Voice name not found: " + voice); - result.success(0); - } - - void setVolume(float volume, Result result) { - if (volume >= 0.0F && volume <= 1.0F) { - bundle.putFloat(TextToSpeech.Engine.KEY_PARAM_VOLUME, volume); - result.success(1); - } else { - Log.d(tag, "Invalid volume " + volume + " value - Range is from 0.0 to 1.0"); - result.success(0); - } - } - - void setPitch(float pitch, Result result) { - if (pitch >= 0.5F && pitch <= 2.0F) { - tts.setPitch(pitch); - result.success(1); - } else { - Log.d(tag, "Invalid pitch " + pitch + " value - Range is from 0.5 to 2.0"); - result.success(0); - } - } - - void getVoices(Result result) { - ArrayList> voices = new ArrayList<>(); - try { - for (Voice voice : tts.getVoices()) { - HashMap voiceMap = new HashMap<>(); - voiceMap.put("name", voice.getName()); - voiceMap.put("locale", voice.getLocale().toLanguageTag()); - voices.add(voiceMap); - } - result.success(voices); - } catch (NullPointerException e) { - Log.d(tag, "getVoices: " + e.getMessage()); - result.success(null); - } - } - - void getLanguages(Result result) { - ArrayList locales = new ArrayList<>(); - try { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - // While this method was introduced in API level 21, it seems that it - // has not been implemented in the speech service side until API Level 23. - for (Locale locale : tts.getAvailableLanguages()) { - locales.add(locale.toLanguageTag()); - } - } else { - for (Locale locale : Locale.getAvailableLocales()) { - if (locale.getVariant().isEmpty() && isLanguageAvailable(locale)) { - locales.add(locale.toLanguageTag()); - } - } - } - } catch (MissingResourceException | NullPointerException e) { - Log.d(tag, "getLanguages: " + e.getMessage()); - } - result.success(locales); - } - - void getEngines(Result result) { - ArrayList engines = new ArrayList<>(); - try { - for (TextToSpeech.EngineInfo engineInfo : tts.getEngines()) { - engines.add(engineInfo.name); - } - } catch (Exception e) { - Log.d(tag, "getEngines: " + e.getMessage()); - } - result.success(engines); - } - - void getSpeechRateValidRange(Result result) { - // Valid values available in the android documentation. - // https://developer.android.com/reference/android/speech/tts/TextToSpeech#setSpeechRate(float) - final HashMap data = new HashMap(); - data.put("min", "0"); - data.put("normal", "1"); - data.put("max", "3"); - data.put("platform", "android"); - result.success(data); - } - - private void speak(String text) { - String uuid = UUID.randomUUID().toString(); - utterances.put(uuid, text); - if (silencems > 0) { - tts.playSilentUtterance(silencems, TextToSpeech.QUEUE_FLUSH, SILENCE_PREFIX + uuid); - tts.speak(text, TextToSpeech.QUEUE_ADD, bundle, uuid); - } else { - tts.speak(text, TextToSpeech.QUEUE_FLUSH, bundle, uuid); - } - } - - private void stop() { - tts.stop(); - } - - private void synthesizeToFile(String text, String fileName) { - File file = new File(context.getExternalFilesDir(null), fileName); - String uuid = UUID.randomUUID().toString(); - bundle.putString(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, SYNTHESIZE_TO_FILE_PREFIX + uuid); - - int result = tts.synthesizeToFile(text, bundle, file, SYNTHESIZE_TO_FILE_PREFIX + uuid); - if (result == TextToSpeech.SUCCESS) { - Log.d(tag, "Successfully created file : " + file.getPath()); - } else { - Log.d(tag, "Failed creating file : " + file.getPath()); - } - } - - private void invokeMethod(final String method, final Object arguments) { - handler.post( - new Runnable() { - @Override - public void run() { - if (methodChannel != null) methodChannel.invokeMethod(method, arguments); - } - }); - } -} diff --git a/flutter_tts-voice_enhancement/example/.gitignore b/flutter_tts-voice_enhancement/example/.gitignore deleted file mode 100644 index 7e6bbd47..00000000 --- a/flutter_tts-voice_enhancement/example/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -.DS_Store -.dart_tool/ - -.packages -.pub/ - -build/ - -.flutter-plugins -.flutter-plugins-dependencies -lib/generated_plugin_registrant.dart \ No newline at end of file diff --git a/flutter_tts-voice_enhancement/example/.metadata b/flutter_tts-voice_enhancement/example/.metadata deleted file mode 100644 index 3c0dd2c8..00000000 --- a/flutter_tts-voice_enhancement/example/.metadata +++ /dev/null @@ -1,8 +0,0 @@ -# This file tracks properties of this Flutter project. -# Used by Flutter tool to assess capabilities and perform upgrades etc. -# -# This file should be version controlled and should not be manually edited. - -version: - revision: b397406561f5e7a9c94e28f58d9e49fca0dd58b7 - channel: beta diff --git a/flutter_tts-voice_enhancement/example/README.md b/flutter_tts-voice_enhancement/example/README.md deleted file mode 100644 index a1356260..00000000 --- a/flutter_tts-voice_enhancement/example/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# example - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. diff --git a/flutter_tts-voice_enhancement/example/android/.gitignore b/flutter_tts-voice_enhancement/example/android/.gitignore deleted file mode 100644 index 65b7315a..00000000 --- a/flutter_tts-voice_enhancement/example/android/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -*.iml -*.class -.gradle -/local.properties -/.idea/workspace.xml -/.idea/libraries -.DS_Store -/build -/captures -GeneratedPluginRegistrant.java diff --git a/flutter_tts-voice_enhancement/example/android/.settings/org.eclipse.buildship.core.prefs b/flutter_tts-voice_enhancement/example/android/.settings/org.eclipse.buildship.core.prefs deleted file mode 100644 index 9f105273..00000000 --- a/flutter_tts-voice_enhancement/example/android/.settings/org.eclipse.buildship.core.prefs +++ /dev/null @@ -1,2 +0,0 @@ -#Sat Apr 14 11:55:40 PDT 2018 -connection.project.dir= diff --git a/flutter_tts-voice_enhancement/example/android/app/.classpath b/flutter_tts-voice_enhancement/example/android/app/.classpath deleted file mode 100644 index 8d8d85f1..00000000 --- a/flutter_tts-voice_enhancement/example/android/app/.classpath +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/flutter_tts-voice_enhancement/example/android/app/.settings/org.eclipse.buildship.core.prefs b/flutter_tts-voice_enhancement/example/android/app/.settings/org.eclipse.buildship.core.prefs deleted file mode 100644 index 0601ea50..00000000 --- a/flutter_tts-voice_enhancement/example/android/app/.settings/org.eclipse.buildship.core.prefs +++ /dev/null @@ -1,2 +0,0 @@ -#Sat Apr 14 11:55:40 PDT 2018 -connection.project.dir=.. diff --git a/flutter_tts-voice_enhancement/example/android/app/build.gradle b/flutter_tts-voice_enhancement/example/android/app/build.gradle deleted file mode 100644 index 563b8f89..00000000 --- a/flutter_tts-voice_enhancement/example/android/app/build.gradle +++ /dev/null @@ -1,50 +0,0 @@ -def localProperties = new Properties() -def localPropertiesFile = rootProject.file('local.properties') -if (localPropertiesFile.exists()) { - localPropertiesFile.withReader('UTF-8') { reader -> - localProperties.load(reader) - } -} - -def flutterRoot = localProperties.getProperty('flutter.sdk') -if (flutterRoot == null) { - throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") -} - -apply plugin: 'com.android.application' -apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" - -android { - compileSdkVersion 28 - - lintOptions { - disable 'InvalidPackage' - } - - defaultConfig { - applicationId "com.tundralabs.flutterttsexample" - minSdkVersion 21 - targetSdkVersion 28 - versionCode 1 - versionName "1.0" - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - } - - buildTypes { - 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 - } - } -} - -flutter { - source '../..' -} - -dependencies { - testImplementation 'junit:junit:4.12' - androidTestImplementation 'androidx.test:runner:1.1.0' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0' -} diff --git a/flutter_tts-voice_enhancement/example/android/app/src/debug/AndroidManifest.xml b/flutter_tts-voice_enhancement/example/android/app/src/debug/AndroidManifest.xml deleted file mode 100644 index 49f10e46..00000000 --- a/flutter_tts-voice_enhancement/example/android/app/src/debug/AndroidManifest.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - diff --git a/flutter_tts-voice_enhancement/example/android/app/src/main/AndroidManifest.xml b/flutter_tts-voice_enhancement/example/android/app/src/main/AndroidManifest.xml deleted file mode 100644 index 1caca009..00000000 --- a/flutter_tts-voice_enhancement/example/android/app/src/main/AndroidManifest.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/flutter_tts-voice_enhancement/example/android/app/src/main/res/drawable/launch_background.xml b/flutter_tts-voice_enhancement/example/android/app/src/main/res/drawable/launch_background.xml deleted file mode 100644 index 304732f8..00000000 --- a/flutter_tts-voice_enhancement/example/android/app/src/main/res/drawable/launch_background.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - diff --git a/flutter_tts-voice_enhancement/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/flutter_tts-voice_enhancement/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index db77bb4b..00000000 Binary files a/flutter_tts-voice_enhancement/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/flutter_tts-voice_enhancement/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/flutter_tts-voice_enhancement/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index 17987b79..00000000 Binary files a/flutter_tts-voice_enhancement/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/flutter_tts-voice_enhancement/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/flutter_tts-voice_enhancement/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index 09d43914..00000000 Binary files a/flutter_tts-voice_enhancement/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/flutter_tts-voice_enhancement/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/flutter_tts-voice_enhancement/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index d5f1c8d3..00000000 Binary files a/flutter_tts-voice_enhancement/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/flutter_tts-voice_enhancement/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/flutter_tts-voice_enhancement/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index 4d6372ee..00000000 Binary files a/flutter_tts-voice_enhancement/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/flutter_tts-voice_enhancement/example/android/app/src/main/res/values/styles.xml b/flutter_tts-voice_enhancement/example/android/app/src/main/res/values/styles.xml deleted file mode 100644 index 1f83a33f..00000000 --- a/flutter_tts-voice_enhancement/example/android/app/src/main/res/values/styles.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - diff --git a/flutter_tts-voice_enhancement/example/android/app/src/profile/AndroidManifest.xml b/flutter_tts-voice_enhancement/example/android/app/src/profile/AndroidManifest.xml deleted file mode 100644 index 49f10e46..00000000 --- a/flutter_tts-voice_enhancement/example/android/app/src/profile/AndroidManifest.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - diff --git a/flutter_tts-voice_enhancement/example/android/build.gradle b/flutter_tts-voice_enhancement/example/android/build.gradle deleted file mode 100644 index cd23eff8..00000000 --- a/flutter_tts-voice_enhancement/example/android/build.gradle +++ /dev/null @@ -1,29 +0,0 @@ -buildscript { - repositories { - google() - jcenter() - } - - dependencies { - classpath 'com.android.tools.build:gradle:4.0.0' - } -} - -allprojects { - repositories { - google() - jcenter() - } -} - -rootProject.buildDir = '../build' -subprojects { - project.buildDir = "${rootProject.buildDir}/${project.name}" -} -subprojects { - project.evaluationDependsOn(':app') -} - -task clean(type: Delete) { - delete rootProject.buildDir -} diff --git a/flutter_tts-voice_enhancement/example/android/gradle.properties b/flutter_tts-voice_enhancement/example/android/gradle.properties deleted file mode 100644 index b6e61b62..00000000 --- a/flutter_tts-voice_enhancement/example/android/gradle.properties +++ /dev/null @@ -1,4 +0,0 @@ -android.enableJetifier=true -android.useAndroidX=true -org.gradle.jvmargs=-Xmx1536M -android.enableR8=true diff --git a/flutter_tts-voice_enhancement/example/android/gradle/wrapper/gradle-wrapper.properties b/flutter_tts-voice_enhancement/example/android/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 495eba36..00000000 --- a/flutter_tts-voice_enhancement/example/android/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Tue Jul 07 01:11:38 PDT 2020 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip diff --git a/flutter_tts-voice_enhancement/example/android/settings.gradle b/flutter_tts-voice_enhancement/example/android/settings.gradle deleted file mode 100644 index 5a2f14fb..00000000 --- a/flutter_tts-voice_enhancement/example/android/settings.gradle +++ /dev/null @@ -1,15 +0,0 @@ -include ':app' - -def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() - -def plugins = new Properties() -def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') -if (pluginsFile.exists()) { - pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } -} - -plugins.each { name, path -> - def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() - include ":$name" - project(":$name").projectDir = pluginDirectory -} diff --git a/flutter_tts-voice_enhancement/example/android/settings_aar.gradle b/flutter_tts-voice_enhancement/example/android/settings_aar.gradle deleted file mode 100644 index e7b4def4..00000000 --- a/flutter_tts-voice_enhancement/example/android/settings_aar.gradle +++ /dev/null @@ -1 +0,0 @@ -include ':app' diff --git a/flutter_tts-voice_enhancement/example/ios/.gitignore b/flutter_tts-voice_enhancement/example/ios/.gitignore deleted file mode 100644 index 1e1aafd6..00000000 --- a/flutter_tts-voice_enhancement/example/ios/.gitignore +++ /dev/null @@ -1,42 +0,0 @@ -.idea/ -.vagrant/ -.sconsign.dblite -.svn/ - -.DS_Store -*.swp -profile - -DerivedData/ -build/ -GeneratedPluginRegistrant.h -GeneratedPluginRegistrant.m - -*.pbxuser -*.mode1v3 -*.mode2v3 -*.perspectivev3 - -!default.pbxuser -!default.mode1v3 -!default.mode2v3 -!default.perspectivev3 - -xcuserdata - -*.moved-aside - -*.pyc -*sync/ -Icon? -.tags* - -/Flutter/app.flx -/Flutter/app.zip -/Flutter/flutter_assets/ -/Flutter/App.framework -/Flutter/Flutter.framework -/Flutter/Generated.xcconfig -/ServiceDefinitions.json - -Pods/ diff --git a/flutter_tts-voice_enhancement/example/ios/Flutter/.last_build_id b/flutter_tts-voice_enhancement/example/ios/Flutter/.last_build_id deleted file mode 100644 index bfaaeba1..00000000 --- a/flutter_tts-voice_enhancement/example/ios/Flutter/.last_build_id +++ /dev/null @@ -1 +0,0 @@ -b443c2d1b6b1e4df6c6fcc277a981410 \ No newline at end of file diff --git a/flutter_tts-voice_enhancement/example/ios/Flutter/AppFrameworkInfo.plist b/flutter_tts-voice_enhancement/example/ios/Flutter/AppFrameworkInfo.plist deleted file mode 100644 index 6c2de808..00000000 --- a/flutter_tts-voice_enhancement/example/ios/Flutter/AppFrameworkInfo.plist +++ /dev/null @@ -1,30 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - App - CFBundleIdentifier - io.flutter.flutter.app - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - App - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1.0 - UIRequiredDeviceCapabilities - - arm64 - - MinimumOSVersion - 8.0 - - diff --git a/flutter_tts-voice_enhancement/example/ios/Flutter/Debug.xcconfig b/flutter_tts-voice_enhancement/example/ios/Flutter/Debug.xcconfig deleted file mode 100644 index e8efba11..00000000 --- a/flutter_tts-voice_enhancement/example/ios/Flutter/Debug.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" -#include "Generated.xcconfig" diff --git a/flutter_tts-voice_enhancement/example/ios/Flutter/Flutter.podspec b/flutter_tts-voice_enhancement/example/ios/Flutter/Flutter.podspec deleted file mode 100644 index 5ca30416..00000000 --- a/flutter_tts-voice_enhancement/example/ios/Flutter/Flutter.podspec +++ /dev/null @@ -1,18 +0,0 @@ -# -# NOTE: This podspec is NOT to be published. It is only used as a local source! -# - -Pod::Spec.new do |s| - s.name = 'Flutter' - s.version = '1.0.0' - s.summary = 'High-performance, high-fidelity mobile apps.' - s.description = <<-DESC -Flutter provides an easy and productive way to build and deploy high-performance mobile apps for Android and iOS. - DESC - s.homepage = 'https://flutter.io' - s.license = { :type => 'MIT' } - s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' } - s.source = { :git => 'https://github.com/flutter/engine', :tag => s.version.to_s } - s.ios.deployment_target = '8.0' - s.vendored_frameworks = 'Flutter.framework' -end diff --git a/flutter_tts-voice_enhancement/example/ios/Flutter/Release.xcconfig b/flutter_tts-voice_enhancement/example/ios/Flutter/Release.xcconfig deleted file mode 100644 index 399e9340..00000000 --- a/flutter_tts-voice_enhancement/example/ios/Flutter/Release.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" -#include "Generated.xcconfig" diff --git a/flutter_tts-voice_enhancement/example/ios/Podfile b/flutter_tts-voice_enhancement/example/ios/Podfile deleted file mode 100644 index 1e8c3c90..00000000 --- a/flutter_tts-voice_enhancement/example/ios/Podfile +++ /dev/null @@ -1,41 +0,0 @@ -# Uncomment this line to define a global platform for your project -# platform :ios, '9.0' - -# CocoaPods analytics sends network stats synchronously affecting flutter build latency. -ENV['COCOAPODS_DISABLE_STATS'] = 'true' - -project 'Runner', { - 'Debug' => :debug, - 'Profile' => :release, - 'Release' => :release, -} - -def flutter_root - generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) - unless File.exist?(generated_xcode_build_settings_path) - raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" - end - - File.foreach(generated_xcode_build_settings_path) do |line| - matches = line.match(/FLUTTER_ROOT\=(.*)/) - return matches[1].strip if matches - end - raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" -end - -require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) - -flutter_ios_podfile_setup - -target 'Runner' do - use_frameworks! - use_modular_headers! - - flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) -end - -post_install do |installer| - installer.pods_project.targets.each do |target| - flutter_additional_ios_build_settings(target) - end -end diff --git a/flutter_tts-voice_enhancement/example/ios/Runner.xcodeproj/project.pbxproj b/flutter_tts-voice_enhancement/example/ios/Runner.xcodeproj/project.pbxproj deleted file mode 100644 index 28d4b795..00000000 --- a/flutter_tts-voice_enhancement/example/ios/Runner.xcodeproj/project.pbxproj +++ /dev/null @@ -1,488 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; - 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 72BCD356E80F9F5F32A2B586 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BE3436CECE15DEA290DCD6B6 /* Pods_Runner.framework */; }; - 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; - 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; - 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; - 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; -/* End PBXBuildFile section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 9705A1C41CF9048500538489 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* 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 = ""; }; - 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 = ""; }; - 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; - 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; - 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; - 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; - 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - BE3436CECE15DEA290DCD6B6 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - CED86603210BC43D753C699B /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; - CF068A80D9BD19FC43D3FE99 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 97C146EB1CF9000F007C117D /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 72BCD356E80F9F5F32A2B586 /* Pods_Runner.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 04223708A30129901099FE16 /* Frameworks */ = { - isa = PBXGroup; - children = ( - BE3436CECE15DEA290DCD6B6 /* Pods_Runner.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; - 1ED2DC2A248FC04D7FB5EA8C /* Pods */ = { - isa = PBXGroup; - children = ( - CF068A80D9BD19FC43D3FE99 /* Pods-Runner.debug.xcconfig */, - CED86603210BC43D753C699B /* Pods-Runner.release.xcconfig */, - ); - name = Pods; - sourceTree = ""; - }; - 9740EEB11CF90186004384FC /* Flutter */ = { - isa = PBXGroup; - children = ( - 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, - 9740EEB21CF90195004384FC /* Debug.xcconfig */, - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, - 9740EEB31CF90195004384FC /* Generated.xcconfig */, - ); - name = Flutter; - sourceTree = ""; - }; - 97C146E51CF9000F007C117D = { - isa = PBXGroup; - children = ( - 9740EEB11CF90186004384FC /* Flutter */, - 97C146F01CF9000F007C117D /* Runner */, - 97C146EF1CF9000F007C117D /* Products */, - 1ED2DC2A248FC04D7FB5EA8C /* Pods */, - 04223708A30129901099FE16 /* Frameworks */, - ); - sourceTree = ""; - }; - 97C146EF1CF9000F007C117D /* Products */ = { - isa = PBXGroup; - children = ( - 97C146EE1CF9000F007C117D /* Runner.app */, - ); - name = Products; - sourceTree = ""; - }; - 97C146F01CF9000F007C117D /* Runner */ = { - isa = PBXGroup; - children = ( - 97C146FA1CF9000F007C117D /* Main.storyboard */, - 97C146FD1CF9000F007C117D /* Assets.xcassets */, - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, - 97C147021CF9000F007C117D /* Info.plist */, - 97C146F11CF9000F007C117D /* Supporting Files */, - 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, - 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, - 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, - 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, - ); - path = Runner; - sourceTree = ""; - }; - 97C146F11CF9000F007C117D /* Supporting Files */ = { - isa = PBXGroup; - children = ( - ); - name = "Supporting Files"; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 97C146ED1CF9000F007C117D /* Runner */ = { - isa = PBXNativeTarget; - buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; - buildPhases = ( - 3B0CA933DCDA45D4F71410D4 /* [CP] Check Pods Manifest.lock */, - 9740EEB61CF901F6004384FC /* Run Script */, - 97C146EA1CF9000F007C117D /* Sources */, - 97C146EB1CF9000F007C117D /* Frameworks */, - 97C146EC1CF9000F007C117D /* Resources */, - 9705A1C41CF9048500538489 /* Embed Frameworks */, - 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - 46F7EA90EF3F4667EDB9E562 /* [CP] Embed Pods Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = Runner; - productName = Runner; - productReference = 97C146EE1CF9000F007C117D /* Runner.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 97C146E61CF9000F007C117D /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0940; - ORGANIZATIONNAME = "The Chromium Authors"; - TargetAttributes = { - 97C146ED1CF9000F007C117D = { - CreatedOnToolsVersion = 7.3.1; - LastSwiftMigration = 0910; - }; - }; - }; - buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 97C146E51CF9000F007C117D; - productRefGroup = 97C146EF1CF9000F007C117D /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 97C146ED1CF9000F007C117D /* Runner */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 97C146EC1CF9000F007C117D /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, - 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, - 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, - 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Thin Binary"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; - }; - 3B0CA933DCDA45D4F71410D4 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - 46F7EA90EF3F4667EDB9E562 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", - "${PODS_ROOT}/../Flutter/Flutter.framework", - ); - name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - 9740EEB61CF901F6004384FC /* Run Script */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Run Script"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 97C146EA1CF9000F007C117D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, - 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 97C146FA1CF9000F007C117D /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C146FB1CF9000F007C117D /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C147001CF9000F007C117D /* Base */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 97C147031CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 97C147041CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 97C147061CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 1; - ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.tundralabs.flutterTtsExample; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_SWIFT3_OBJC_INFERENCE = On; - SWIFT_VERSION = 4.0; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Debug; - }; - 97C147071CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 1; - ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.tundralabs.flutterTtsExample; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; - SWIFT_SWIFT3_OBJC_INFERENCE = On; - SWIFT_VERSION = 4.0; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147031CF9000F007C117D /* Debug */, - 97C147041CF9000F007C117D /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147061CF9000F007C117D /* Debug */, - 97C147071CF9000F007C117D /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 97C146E61CF9000F007C117D /* Project object */; -} diff --git a/flutter_tts-voice_enhancement/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/flutter_tts-voice_enhancement/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 1d526a16..00000000 --- a/flutter_tts-voice_enhancement/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/flutter_tts-voice_enhancement/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/flutter_tts-voice_enhancement/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d98100..00000000 --- a/flutter_tts-voice_enhancement/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/flutter_tts-voice_enhancement/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/flutter_tts-voice_enhancement/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings deleted file mode 100644 index f9b0d7c5..00000000 --- a/flutter_tts-voice_enhancement/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ /dev/null @@ -1,8 +0,0 @@ - - - - - PreviewsEnabled - - - diff --git a/flutter_tts-voice_enhancement/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/flutter_tts-voice_enhancement/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme deleted file mode 100644 index 4bafc458..00000000 --- a/flutter_tts-voice_enhancement/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ /dev/null @@ -1,91 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/flutter_tts-voice_enhancement/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/flutter_tts-voice_enhancement/example/ios/Runner.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 21a3cc14..00000000 --- a/flutter_tts-voice_enhancement/example/ios/Runner.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - diff --git a/flutter_tts-voice_enhancement/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/flutter_tts-voice_enhancement/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d98100..00000000 --- a/flutter_tts-voice_enhancement/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/flutter_tts-voice_enhancement/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/flutter_tts-voice_enhancement/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings deleted file mode 100644 index f9b0d7c5..00000000 --- a/flutter_tts-voice_enhancement/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ /dev/null @@ -1,8 +0,0 @@ - - - - - PreviewsEnabled - - - diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/AppDelegate.swift b/flutter_tts-voice_enhancement/example/ios/Runner/AppDelegate.swift deleted file mode 100644 index 71cc41e3..00000000 --- a/flutter_tts-voice_enhancement/example/ios/Runner/AppDelegate.swift +++ /dev/null @@ -1,13 +0,0 @@ -import UIKit -import Flutter - -@UIApplicationMain -@objc class AppDelegate: FlutterAppDelegate { - override func application( - _ application: UIApplication, - didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]? - ) -> Bool { - GeneratedPluginRegistrant.register(with: self) - return super.application(application, didFinishLaunchingWithOptions: launchOptions) - } -} diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index d36b1fab..00000000 --- a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,122 +0,0 @@ -{ - "images" : [ - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@3x.png", - "scale" : "3x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@3x.png", - "scale" : "3x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@3x.png", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@2x.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@3x.png", - "scale" : "3x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@1x.png", - "scale" : "1x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@1x.png", - "scale" : "1x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@1x.png", - "scale" : "1x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@2x.png", - "scale" : "2x" - }, - { - "size" : "83.5x83.5", - "idiom" : "ipad", - "filename" : "Icon-App-83.5x83.5@2x.png", - "scale" : "2x" - }, - { - "size" : "1024x1024", - "idiom" : "ios-marketing", - "filename" : "Icon-App-1024x1024@1x.png", - "scale" : "1x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png deleted file mode 100644 index 3d43d11e..00000000 Binary files a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png and /dev/null differ diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png deleted file mode 100644 index 28c6bf03..00000000 Binary files a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png and /dev/null differ diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png deleted file mode 100644 index 2ccbfd96..00000000 Binary files a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png and /dev/null differ diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png deleted file mode 100644 index f091b6b0..00000000 Binary files a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png and /dev/null differ diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png deleted file mode 100644 index 4cde1211..00000000 Binary files a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png and /dev/null differ diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png deleted file mode 100644 index d0ef06e7..00000000 Binary files a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png and /dev/null differ diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png deleted file mode 100644 index dcdc2306..00000000 Binary files a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png and /dev/null differ diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png deleted file mode 100644 index 2ccbfd96..00000000 Binary files a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png and /dev/null differ diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png deleted file mode 100644 index c8f9ed8f..00000000 Binary files a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png and /dev/null differ diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png deleted file mode 100644 index a6d6b860..00000000 Binary files a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png and /dev/null differ diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png deleted file mode 100644 index a6d6b860..00000000 Binary files a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png and /dev/null differ diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png deleted file mode 100644 index 75b2d164..00000000 Binary files a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png and /dev/null differ diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png deleted file mode 100644 index c4df70d3..00000000 Binary files a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png and /dev/null differ diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png deleted file mode 100644 index 6a84f41e..00000000 Binary files a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png and /dev/null differ diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png deleted file mode 100644 index d0e1f585..00000000 Binary files a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png and /dev/null differ diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json deleted file mode 100644 index 0bedcf2f..00000000 --- a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "filename" : "LaunchImage.png", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "LaunchImage@2x.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "filename" : "LaunchImage@3x.png", - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png deleted file mode 100644 index 9da19eac..00000000 Binary files a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png and /dev/null differ diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png deleted file mode 100644 index 9da19eac..00000000 Binary files a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png and /dev/null differ diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png deleted file mode 100644 index 9da19eac..00000000 Binary files a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png and /dev/null differ diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md deleted file mode 100644 index 89c2725b..00000000 --- a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Launch Screen Assets - -You can customize the launch screen with your own desired assets by replacing the image files in this directory. - -You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/flutter_tts-voice_enhancement/example/ios/Runner/Base.lproj/LaunchScreen.storyboard deleted file mode 100644 index f2e259c7..00000000 --- a/flutter_tts-voice_enhancement/example/ios/Runner/Base.lproj/LaunchScreen.storyboard +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Base.lproj/Main.storyboard b/flutter_tts-voice_enhancement/example/ios/Runner/Base.lproj/Main.storyboard deleted file mode 100644 index f3c28516..00000000 --- a/flutter_tts-voice_enhancement/example/ios/Runner/Base.lproj/Main.storyboard +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Info.plist b/flutter_tts-voice_enhancement/example/ios/Runner/Info.plist deleted file mode 100644 index dd2d9263..00000000 --- a/flutter_tts-voice_enhancement/example/ios/Runner/Info.plist +++ /dev/null @@ -1,49 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - flutter_tts_example - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UIRequiredDeviceCapabilities - - arm64 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UIViewControllerBasedStatusBarAppearance - - - diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Runner-Bridging-Header.h b/flutter_tts-voice_enhancement/example/ios/Runner/Runner-Bridging-Header.h deleted file mode 100644 index 7335fdf9..00000000 --- a/flutter_tts-voice_enhancement/example/ios/Runner/Runner-Bridging-Header.h +++ /dev/null @@ -1 +0,0 @@ -#import "GeneratedPluginRegistrant.h" \ No newline at end of file diff --git a/flutter_tts-voice_enhancement/example/lib/main.dart b/flutter_tts-voice_enhancement/example/lib/main.dart deleted file mode 100644 index 97530bbb..00000000 --- a/flutter_tts-voice_enhancement/example/lib/main.dart +++ /dev/null @@ -1,292 +0,0 @@ -import 'dart:async'; -import 'dart:io' show Platform; -import 'package:flutter/foundation.dart' show kIsWeb; - -import 'package:flutter/material.dart'; -import 'package:flutter_tts/flutter_tts.dart'; - -void main() => runApp(MyApp()); - -class MyApp extends StatefulWidget { - @override - _MyAppState createState() => _MyAppState(); -} - -enum TtsState { playing, stopped, paused, continued } - -class _MyAppState extends State { - FlutterTts flutterTts; - dynamic languages; - String language; - double volume = 0.5; - double pitch = 1.0; - double rate = 0.5; - - String _newVoiceText; - - TtsState ttsState = TtsState.stopped; - - get isPlaying => ttsState == TtsState.playing; - - get isStopped => ttsState == TtsState.stopped; - - get isPaused => ttsState == TtsState.paused; - - get isContinued => ttsState == TtsState.continued; - - @override - initState() { - super.initState(); - initTts(); - } - - initTts() { - flutterTts = FlutterTts(); - - _getLanguages(); - - if (!kIsWeb) { - if (Platform.isAndroid) { - _getEngines(); - } - } - - flutterTts.setStartHandler(() { - setState(() { - print("Playing"); - ttsState = TtsState.playing; - }); - }); - - flutterTts.setCompletionHandler(() { - setState(() { - print("Complete"); - ttsState = TtsState.stopped; - }); - }); - - flutterTts.setCancelHandler(() { - setState(() { - print("Cancel"); - ttsState = TtsState.stopped; - }); - }); - - if (kIsWeb || Platform.isIOS) { - flutterTts.setPauseHandler(() { - setState(() { - print("Paused"); - ttsState = TtsState.paused; - }); - }); - - flutterTts.setContinueHandler(() { - setState(() { - print("Continued"); - ttsState = TtsState.continued; - }); - }); - } - - flutterTts.setErrorHandler((msg) { - setState(() { - print("error: $msg"); - ttsState = TtsState.stopped; - }); - }); - } - - Future _getLanguages() async { - languages = await flutterTts.getLanguages; - if (languages != null) setState(() => languages); - } - - Future _getEngines() async { - var engines = await flutterTts.getEngines; - if (engines != null) { - for (dynamic engine in engines) { - print(engine); - } - } - } - - Future _speak() async { - await flutterTts.setVolume(volume); - await flutterTts.setSpeechRate(rate); - await flutterTts.setPitch(pitch); - - if (_newVoiceText != null) { - if (_newVoiceText.isNotEmpty) { - await flutterTts.awaitSpeakCompletion(true); - await flutterTts.speak(_newVoiceText); - } - } - } - - Future _stop() async { - var result = await flutterTts.stop(); - if (result == 1) setState(() => ttsState = TtsState.stopped); - } - - Future _pause() async { - var result = await flutterTts.pause(); - if (result == 1) setState(() => ttsState = TtsState.paused); - } - - @override - void dispose() { - super.dispose(); - flutterTts.stop(); - } - - List> getLanguageDropDownMenuItems() { - var items = List>(); - for (dynamic type in languages) { - items.add( - DropdownMenuItem(value: type as String, child: Text(type as String))); - } - return items; - } - - void changedLanguageDropDownItem(String selectedType) { - setState(() { - language = selectedType; - flutterTts.setLanguage(language); - }); - } - - void _onChange(String text) { - setState(() { - _newVoiceText = text; - }); - } - - @override - Widget build(BuildContext context) { - return MaterialApp( - home: Scaffold( - appBar: AppBar( - title: Text('Flutter TTS'), - ), - body: SingleChildScrollView( - scrollDirection: Axis.vertical, - child: Column(children: [ - _inputSection(), - _btnSection(), - languages != null ? _languageDropDownSection() : Text(""), - _buildSliders() - ])))); - } - - Widget _inputSection() => Container( - alignment: Alignment.topCenter, - padding: EdgeInsets.only(top: 25.0, left: 25.0, right: 25.0), - child: TextField( - onChanged: (String value) { - _onChange(value); - }, - )); - - Widget _btnSection() { - if (!kIsWeb && Platform.isAndroid) { - return Container( - padding: EdgeInsets.only(top: 50.0), - child: - Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - _buildButtonColumn(Colors.green, Colors.greenAccent, - Icons.play_arrow, 'PLAY', _speak), - _buildButtonColumn( - Colors.red, Colors.redAccent, Icons.stop, 'STOP', _stop), - ])); - } else { - return Container( - padding: EdgeInsets.only(top: 50.0), - child: - Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - _buildButtonColumn(Colors.green, Colors.greenAccent, - Icons.play_arrow, 'PLAY', _speak), - _buildButtonColumn( - Colors.red, Colors.redAccent, Icons.stop, 'STOP', _stop), - _buildButtonColumn( - Colors.blue, Colors.blueAccent, Icons.pause, 'PAUSE', _pause), - ])); - } - } - - Widget _languageDropDownSection() => Container( - padding: EdgeInsets.only(top: 50.0), - child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [ - DropdownButton( - value: language, - items: getLanguageDropDownMenuItems(), - onChanged: changedLanguageDropDownItem, - ) - ])); - - Column _buildButtonColumn(Color color, Color splashColor, IconData icon, - String label, Function func) { - return Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - IconButton( - icon: Icon(icon), - color: color, - splashColor: splashColor, - onPressed: () => func()), - Container( - margin: const EdgeInsets.only(top: 8.0), - child: Text(label, - style: TextStyle( - fontSize: 12.0, - fontWeight: FontWeight.w400, - color: color))) - ]); - } - - Widget _buildSliders() { - return Column( - children: [_volume(), _pitch(), _rate()], - ); - } - - Widget _volume() { - return Slider( - value: volume, - onChanged: (newVolume) { - setState(() => volume = newVolume); - }, - min: 0.0, - max: 1.0, - divisions: 10, - label: "Volume: $volume"); - } - - Widget _pitch() { - return Slider( - value: pitch, - onChanged: (newPitch) { - setState(() => pitch = newPitch); - }, - min: 0.5, - max: 2.0, - divisions: 15, - label: "Pitch: $pitch", - activeColor: Colors.red, - ); - } - - Widget _rate() { - return Slider( - value: rate, - onChanged: (newRate) { - setState(() => rate = newRate); - }, - min: 0.0, - max: 1.0, - divisions: 10, - label: "Rate: $rate", - activeColor: Colors.green, - ); - } -} diff --git a/flutter_tts-voice_enhancement/example/macos/.gitignore b/flutter_tts-voice_enhancement/example/macos/.gitignore deleted file mode 100644 index d2fd3772..00000000 --- a/flutter_tts-voice_enhancement/example/macos/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -# Flutter-related -**/Flutter/ephemeral/ -**/Pods/ - -# Xcode-related -**/xcuserdata/ diff --git a/flutter_tts-voice_enhancement/example/macos/Flutter/Flutter-Debug.xcconfig b/flutter_tts-voice_enhancement/example/macos/Flutter/Flutter-Debug.xcconfig deleted file mode 100644 index 785633d3..00000000 --- a/flutter_tts-voice_enhancement/example/macos/Flutter/Flutter-Debug.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" -#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/flutter_tts-voice_enhancement/example/macos/Flutter/Flutter-Release.xcconfig b/flutter_tts-voice_enhancement/example/macos/Flutter/Flutter-Release.xcconfig deleted file mode 100644 index 5fba960c..00000000 --- a/flutter_tts-voice_enhancement/example/macos/Flutter/Flutter-Release.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" -#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/flutter_tts-voice_enhancement/example/macos/Flutter/GeneratedPluginRegistrant.swift b/flutter_tts-voice_enhancement/example/macos/Flutter/GeneratedPluginRegistrant.swift deleted file mode 100644 index 1e6ac53b..00000000 --- a/flutter_tts-voice_enhancement/example/macos/Flutter/GeneratedPluginRegistrant.swift +++ /dev/null @@ -1,12 +0,0 @@ -// -// Generated file. Do not edit. -// - -import FlutterMacOS -import Foundation - -import flutter_tts - -func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { - FlutterTtsPlugin.register(with: registry.registrar(forPlugin: "FlutterTtsPlugin")) -} diff --git a/flutter_tts-voice_enhancement/example/macos/Podfile b/flutter_tts-voice_enhancement/example/macos/Podfile deleted file mode 100644 index 5bf4307c..00000000 --- a/flutter_tts-voice_enhancement/example/macos/Podfile +++ /dev/null @@ -1,82 +0,0 @@ -platform :osx, '10.15' - -# CocoaPods analytics sends network stats synchronously affecting flutter build latency. -ENV['COCOAPODS_DISABLE_STATS'] = 'true' - -project 'Runner', { - 'Debug' => :debug, - 'Profile' => :release, - 'Release' => :release, -} - -def parse_KV_file(file, separator='=') - file_abs_path = File.expand_path(file) - if !File.exists? file_abs_path - return []; - end - pods_ary = [] - skip_line_start_symbols = ["#", "/"] - File.foreach(file_abs_path) { |line| - next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } - plugin = line.split(pattern=separator) - if plugin.length == 2 - podname = plugin[0].strip() - path = plugin[1].strip() - podpath = File.expand_path("#{path}", file_abs_path) - pods_ary.push({:name => podname, :path => podpath}); - else - puts "Invalid plugin specification: #{line}" - end - } - return pods_ary -end - -def pubspec_supports_macos(file) - file_abs_path = File.expand_path(file) - if !File.exists? file_abs_path - return false; - end - File.foreach(file_abs_path) { |line| - return true if line =~ /^\s*macos:/ - } - return false -end - -target 'Runner' do - use_frameworks! - use_modular_headers! - - # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock - # referring to absolute paths on developers' machines. - ephemeral_dir = File.join('Flutter', 'ephemeral') - symlink_dir = File.join(ephemeral_dir, '.symlinks') - symlink_plugins_dir = File.join(symlink_dir, 'plugins') - system("rm -rf #{symlink_dir}") - system("mkdir -p #{symlink_plugins_dir}") - - # Flutter Pods - generated_xcconfig = parse_KV_file(File.join(ephemeral_dir, 'Flutter-Generated.xcconfig')) - if generated_xcconfig.empty? - puts "Flutter-Generated.xcconfig must exist. If you're running pod install manually, make sure flutter packages get is executed first." - end - generated_xcconfig.map { |p| - if p[:name] == 'FLUTTER_FRAMEWORK_DIR' - symlink = File.join(symlink_dir, 'flutter') - File.symlink(File.dirname(p[:path]), symlink) - pod 'FlutterMacOS', :path => File.join(symlink, File.basename(p[:path])) - end - } - - # Plugin Pods - plugin_pods = parse_KV_file('../.flutter-plugins') - plugin_pods.map { |p| - symlink = File.join(symlink_plugins_dir, p[:name]) - File.symlink(p[:path], symlink) - if pubspec_supports_macos(File.join(symlink, 'pubspec.yaml')) - pod p[:name], :path => File.join(symlink, 'macos') - end - } -end - -# Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system. -install! 'cocoapods', :disable_input_output_paths => true diff --git a/flutter_tts-voice_enhancement/example/macos/Runner.xcodeproj/project.pbxproj b/flutter_tts-voice_enhancement/example/macos/Runner.xcodeproj/project.pbxproj deleted file mode 100644 index 39fbd18c..00000000 --- a/flutter_tts-voice_enhancement/example/macos/Runner.xcodeproj/project.pbxproj +++ /dev/null @@ -1,656 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 51; - objects = { - -/* Begin PBXAggregateTarget section */ - 33CC111A2044C6BA0003C045 /* Flutter Assemble */ = { - isa = PBXAggregateTarget; - buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */; - buildPhases = ( - 33CC111E2044C6BF0003C045 /* ShellScript */, - ); - dependencies = ( - ); - name = "Flutter Assemble"; - productName = FLX; - }; -/* End PBXAggregateTarget section */ - -/* Begin PBXBuildFile section */ - 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; }; - 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; }; - 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; - 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; - 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; - 33D1A10422148B71006C7A3E /* FlutterMacOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */; }; - 33D1A10522148B93006C7A3E /* FlutterMacOS.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 3640FC23D5951A8FB0D6ECA0 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A470206CCCE0007DE0E2807A /* Pods_Runner.framework */; }; - D73912F022F37F9E000D13A0 /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D73912EF22F37F9E000D13A0 /* App.framework */; }; - D73912F222F3801D000D13A0 /* App.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = D73912EF22F37F9E000D13A0 /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 33CC10E52044A3C60003C045 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 33CC111A2044C6BA0003C045; - remoteInfo = FLX; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 33CC110E2044A8840003C045 /* Bundle Framework */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - D73912F222F3801D000D13A0 /* App.framework in Bundle Framework */, - 33D1A10522148B93006C7A3E /* FlutterMacOS.framework in Bundle Framework */, - ); - name = "Bundle Framework"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; - 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; - 33CC10ED2044A3C60003C045 /* example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = example.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; - 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; - 33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = ""; }; - 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = ""; }; - 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; }; - 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; }; - 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; }; - 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FlutterMacOS.framework; path = Flutter/ephemeral/FlutterMacOS.framework; sourceTree = SOURCE_ROOT; }; - 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; - 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; - 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; - 517AA5C8DE31A9B49D27971F /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; - 66FE8AA741C2B7FC12BF1304 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; - 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; - A470206CCCE0007DE0E2807A /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - C15A67B64555E7FFE7AD8B76 /* 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 = ""; }; - D73912EF22F37F9E000D13A0 /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/ephemeral/App.framework; sourceTree = SOURCE_ROOT; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 33CC10EA2044A3C60003C045 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - D73912F022F37F9E000D13A0 /* App.framework in Frameworks */, - 33D1A10422148B71006C7A3E /* FlutterMacOS.framework in Frameworks */, - 3640FC23D5951A8FB0D6ECA0 /* Pods_Runner.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 33BA886A226E78AF003329D5 /* Configs */ = { - isa = PBXGroup; - children = ( - 33E5194F232828860026EE4D /* AppInfo.xcconfig */, - 9740EEB21CF90195004384FC /* Debug.xcconfig */, - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, - 333000ED22D3DE5D00554162 /* Warnings.xcconfig */, - ); - path = Configs; - sourceTree = ""; - }; - 33CC10E42044A3C60003C045 = { - isa = PBXGroup; - children = ( - 33FAB671232836740065AC1E /* Runner */, - 33CEB47122A05771004F2AC0 /* Flutter */, - 33CC10EE2044A3C60003C045 /* Products */, - D73912EC22F37F3D000D13A0 /* Frameworks */, - 5F9F48FBDE9334256A3D8D1C /* Pods */, - ); - sourceTree = ""; - }; - 33CC10EE2044A3C60003C045 /* Products */ = { - isa = PBXGroup; - children = ( - 33CC10ED2044A3C60003C045 /* example.app */, - ); - name = Products; - sourceTree = ""; - }; - 33CC11242044D66E0003C045 /* Resources */ = { - isa = PBXGroup; - children = ( - 33CC10F22044A3C60003C045 /* Assets.xcassets */, - 33CC10F42044A3C60003C045 /* MainMenu.xib */, - 33CC10F72044A3C60003C045 /* Info.plist */, - ); - name = Resources; - path = ..; - sourceTree = ""; - }; - 33CEB47122A05771004F2AC0 /* Flutter */ = { - isa = PBXGroup; - children = ( - 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */, - 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */, - 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */, - 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */, - D73912EF22F37F9E000D13A0 /* App.framework */, - 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */, - ); - path = Flutter; - sourceTree = ""; - }; - 33FAB671232836740065AC1E /* Runner */ = { - isa = PBXGroup; - children = ( - 33CC10F02044A3C60003C045 /* AppDelegate.swift */, - 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */, - 33E51913231747F40026EE4D /* DebugProfile.entitlements */, - 33E51914231749380026EE4D /* Release.entitlements */, - 33CC11242044D66E0003C045 /* Resources */, - 33BA886A226E78AF003329D5 /* Configs */, - ); - path = Runner; - sourceTree = ""; - }; - 5F9F48FBDE9334256A3D8D1C /* Pods */ = { - isa = PBXGroup; - children = ( - 66FE8AA741C2B7FC12BF1304 /* Pods-Runner.debug.xcconfig */, - 517AA5C8DE31A9B49D27971F /* Pods-Runner.release.xcconfig */, - C15A67B64555E7FFE7AD8B76 /* Pods-Runner.profile.xcconfig */, - ); - path = Pods; - sourceTree = ""; - }; - D73912EC22F37F3D000D13A0 /* Frameworks */ = { - isa = PBXGroup; - children = ( - A470206CCCE0007DE0E2807A /* Pods_Runner.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 33CC10EC2044A3C60003C045 /* Runner */ = { - isa = PBXNativeTarget; - buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; - buildPhases = ( - 9A62F257D3FF7C7C94E365B2 /* [CP] Check Pods Manifest.lock */, - 33CC10E92044A3C60003C045 /* Sources */, - 33CC10EA2044A3C60003C045 /* Frameworks */, - 33CC10EB2044A3C60003C045 /* Resources */, - 33CC110E2044A8840003C045 /* Bundle Framework */, - 3399D490228B24CF009A79C7 /* ShellScript */, - F7AADAC6A864E8BF8890B1EC /* [CP] Embed Pods Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 33CC11202044C79F0003C045 /* PBXTargetDependency */, - ); - name = Runner; - productName = Runner; - productReference = 33CC10ED2044A3C60003C045 /* example.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 33CC10E52044A3C60003C045 /* Project object */ = { - isa = PBXProject; - attributes = { - LastSwiftUpdateCheck = 0920; - LastUpgradeCheck = 1150; - ORGANIZATIONNAME = "The Flutter Authors"; - TargetAttributes = { - 33CC10EC2044A3C60003C045 = { - CreatedOnToolsVersion = 9.2; - LastSwiftMigration = 1100; - ProvisioningStyle = Automatic; - SystemCapabilities = { - com.apple.Sandbox = { - enabled = 1; - }; - }; - }; - 33CC111A2044C6BA0003C045 = { - CreatedOnToolsVersion = 9.2; - ProvisioningStyle = Manual; - }; - }; - }; - buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */; - compatibilityVersion = "Xcode 8.0"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 33CC10E42044A3C60003C045; - productRefGroup = 33CC10EE2044A3C60003C045 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 33CC10EC2044A3C60003C045 /* Runner */, - 33CC111A2044C6BA0003C045 /* Flutter Assemble */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 33CC10EB2044A3C60003C045 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */, - 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 3399D490228B24CF009A79C7 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - ); - outputFileListPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename\n"; - }; - 33CC111E2044C6BF0003C045 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - Flutter/ephemeral/FlutterInputs.xcfilelist, - ); - inputPaths = ( - Flutter/ephemeral/tripwire, - ); - outputFileListPaths = ( - Flutter/ephemeral/FlutterOutputs.xcfilelist, - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh\ntouch Flutter/ephemeral/tripwire\n"; - }; - 9A62F257D3FF7C7C94E365B2 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - F7AADAC6A864E8BF8890B1EC /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - name = "[CP] Embed Pods Frameworks"; - outputFileListPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 33CC10E92044A3C60003C045 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */, - 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */, - 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 33CC11202044C79F0003C045 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */; - targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin PBXVariantGroup section */ - 33CC10F42044A3C60003C045 /* MainMenu.xib */ = { - isa = PBXVariantGroup; - children = ( - 33CC10F52044A3C60003C045 /* Base */, - ); - name = MainMenu.xib; - path = Runner; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 338D0CE9231458BD00FA5F75 /* Profile */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CODE_SIGN_IDENTITY = "-"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.15; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = macosx; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - }; - name = Profile; - }; - 338D0CEA231458BD00FA5F75 /* Profile */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; - CODE_SIGN_IDENTITY = "-"; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter/ephemeral", - ); - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - ); - PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_VERSION = 5.0; - }; - name = Profile; - }; - 338D0CEB231458BD00FA5F75 /* Profile */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_STYLE = Manual; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Profile; - }; - 33CC10F92044A3C60003C045 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CODE_SIGN_IDENTITY = "-"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.15; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = macosx; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - }; - name = Debug; - }; - 33CC10FA2044A3C60003C045 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CODE_SIGN_IDENTITY = "-"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.15; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = macosx; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - }; - name = Release; - }; - 33CC10FC2044A3C60003C045 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; - CODE_SIGN_IDENTITY = "-"; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter/ephemeral", - ); - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - ); - PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - }; - name = Debug; - }; - 33CC10FD2044A3C60003C045 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; - CODE_SIGN_IDENTITY = "-"; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter/ephemeral", - ); - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - ); - PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_VERSION = 5.0; - }; - name = Release; - }; - 33CC111C2044C6BA0003C045 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_STYLE = Manual; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 33CC111D2044C6BA0003C045 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_STYLE = Automatic; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 33CC10F92044A3C60003C045 /* Debug */, - 33CC10FA2044A3C60003C045 /* Release */, - 338D0CE9231458BD00FA5F75 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 33CC10FC2044A3C60003C045 /* Debug */, - 33CC10FD2044A3C60003C045 /* Release */, - 338D0CEA231458BD00FA5F75 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 33CC111C2044C6BA0003C045 /* Debug */, - 33CC111D2044C6BA0003C045 /* Release */, - 338D0CEB231458BD00FA5F75 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 33CC10E52044A3C60003C045 /* Project object */; -} diff --git a/flutter_tts-voice_enhancement/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/flutter_tts-voice_enhancement/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d98100..00000000 --- a/flutter_tts-voice_enhancement/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/flutter_tts-voice_enhancement/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/flutter_tts-voice_enhancement/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme deleted file mode 100644 index 6111bd0a..00000000 --- a/flutter_tts-voice_enhancement/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ /dev/null @@ -1,97 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/flutter_tts-voice_enhancement/example/macos/Runner.xcworkspace/contents.xcworkspacedata b/flutter_tts-voice_enhancement/example/macos/Runner.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 21a3cc14..00000000 --- a/flutter_tts-voice_enhancement/example/macos/Runner.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - diff --git a/flutter_tts-voice_enhancement/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/flutter_tts-voice_enhancement/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d98100..00000000 --- a/flutter_tts-voice_enhancement/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/flutter_tts-voice_enhancement/example/macos/Runner/AppDelegate.swift b/flutter_tts-voice_enhancement/example/macos/Runner/AppDelegate.swift deleted file mode 100644 index d53ef643..00000000 --- a/flutter_tts-voice_enhancement/example/macos/Runner/AppDelegate.swift +++ /dev/null @@ -1,9 +0,0 @@ -import Cocoa -import FlutterMacOS - -@NSApplicationMain -class AppDelegate: FlutterAppDelegate { - override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { - return true - } -} diff --git a/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index a2ec33f1..00000000 --- a/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "images" : [ - { - "size" : "16x16", - "idiom" : "mac", - "filename" : "app_icon_16.png", - "scale" : "1x" - }, - { - "size" : "16x16", - "idiom" : "mac", - "filename" : "app_icon_32.png", - "scale" : "2x" - }, - { - "size" : "32x32", - "idiom" : "mac", - "filename" : "app_icon_32.png", - "scale" : "1x" - }, - { - "size" : "32x32", - "idiom" : "mac", - "filename" : "app_icon_64.png", - "scale" : "2x" - }, - { - "size" : "128x128", - "idiom" : "mac", - "filename" : "app_icon_128.png", - "scale" : "1x" - }, - { - "size" : "128x128", - "idiom" : "mac", - "filename" : "app_icon_256.png", - "scale" : "2x" - }, - { - "size" : "256x256", - "idiom" : "mac", - "filename" : "app_icon_256.png", - "scale" : "1x" - }, - { - "size" : "256x256", - "idiom" : "mac", - "filename" : "app_icon_512.png", - "scale" : "2x" - }, - { - "size" : "512x512", - "idiom" : "mac", - "filename" : "app_icon_512.png", - "scale" : "1x" - }, - { - "size" : "512x512", - "idiom" : "mac", - "filename" : "app_icon_1024.png", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} diff --git a/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png deleted file mode 100644 index 3c4935a7..00000000 Binary files a/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png and /dev/null differ diff --git a/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png deleted file mode 100644 index ed4cc164..00000000 Binary files a/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png and /dev/null differ diff --git a/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png deleted file mode 100644 index 483be613..00000000 Binary files a/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png and /dev/null differ diff --git a/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png deleted file mode 100644 index bcbf36df..00000000 Binary files a/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png and /dev/null differ diff --git a/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png b/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png deleted file mode 100644 index 9c0a6528..00000000 Binary files a/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png and /dev/null differ diff --git a/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png deleted file mode 100644 index e71a7261..00000000 Binary files a/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png and /dev/null differ diff --git a/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png deleted file mode 100644 index 8a31fe2d..00000000 Binary files a/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png and /dev/null differ diff --git a/flutter_tts-voice_enhancement/example/macos/Runner/Base.lproj/MainMenu.xib b/flutter_tts-voice_enhancement/example/macos/Runner/Base.lproj/MainMenu.xib deleted file mode 100644 index 537341ab..00000000 --- a/flutter_tts-voice_enhancement/example/macos/Runner/Base.lproj/MainMenu.xib +++ /dev/null @@ -1,339 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/flutter_tts-voice_enhancement/example/macos/Runner/Configs/AppInfo.xcconfig b/flutter_tts-voice_enhancement/example/macos/Runner/Configs/AppInfo.xcconfig deleted file mode 100644 index f960fd48..00000000 --- a/flutter_tts-voice_enhancement/example/macos/Runner/Configs/AppInfo.xcconfig +++ /dev/null @@ -1,14 +0,0 @@ -// Application-level settings for the Runner target. -// -// This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the -// future. If not, the values below would default to using the project name when this becomes a -// 'flutter create' template. - -// The application's name. By default this is also the title of the Flutter window. -PRODUCT_NAME = example - -// The application's bundle identifier -PRODUCT_BUNDLE_IDENTIFIER = com.tundralabs.example - -// The copyright displayed in application information -PRODUCT_COPYRIGHT = Copyright © 2020 com.tundralabs. All rights reserved. diff --git a/flutter_tts-voice_enhancement/example/macos/Runner/Configs/Debug.xcconfig b/flutter_tts-voice_enhancement/example/macos/Runner/Configs/Debug.xcconfig deleted file mode 100644 index 36b0fd94..00000000 --- a/flutter_tts-voice_enhancement/example/macos/Runner/Configs/Debug.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include "../../Flutter/Flutter-Debug.xcconfig" -#include "Warnings.xcconfig" diff --git a/flutter_tts-voice_enhancement/example/macos/Runner/Configs/Release.xcconfig b/flutter_tts-voice_enhancement/example/macos/Runner/Configs/Release.xcconfig deleted file mode 100644 index dff4f495..00000000 --- a/flutter_tts-voice_enhancement/example/macos/Runner/Configs/Release.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include "../../Flutter/Flutter-Release.xcconfig" -#include "Warnings.xcconfig" diff --git a/flutter_tts-voice_enhancement/example/macos/Runner/Configs/Warnings.xcconfig b/flutter_tts-voice_enhancement/example/macos/Runner/Configs/Warnings.xcconfig deleted file mode 100644 index 42bcbf47..00000000 --- a/flutter_tts-voice_enhancement/example/macos/Runner/Configs/Warnings.xcconfig +++ /dev/null @@ -1,13 +0,0 @@ -WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings -GCC_WARN_UNDECLARED_SELECTOR = YES -CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES -CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE -CLANG_WARN__DUPLICATE_METHOD_MATCH = YES -CLANG_WARN_PRAGMA_PACK = YES -CLANG_WARN_STRICT_PROTOTYPES = YES -CLANG_WARN_COMMA = YES -GCC_WARN_STRICT_SELECTOR_MATCH = YES -CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES -CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES -GCC_WARN_SHADOW = YES -CLANG_WARN_UNREACHABLE_CODE = YES diff --git a/flutter_tts-voice_enhancement/example/macos/Runner/DebugProfile.entitlements b/flutter_tts-voice_enhancement/example/macos/Runner/DebugProfile.entitlements deleted file mode 100644 index dddb8a30..00000000 --- a/flutter_tts-voice_enhancement/example/macos/Runner/DebugProfile.entitlements +++ /dev/null @@ -1,12 +0,0 @@ - - - - - com.apple.security.app-sandbox - - com.apple.security.cs.allow-jit - - com.apple.security.network.server - - - diff --git a/flutter_tts-voice_enhancement/example/macos/Runner/Info.plist b/flutter_tts-voice_enhancement/example/macos/Runner/Info.plist deleted file mode 100644 index 4789daa6..00000000 --- a/flutter_tts-voice_enhancement/example/macos/Runner/Info.plist +++ /dev/null @@ -1,32 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIconFile - - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - $(FLUTTER_BUILD_NAME) - CFBundleVersion - $(FLUTTER_BUILD_NUMBER) - LSMinimumSystemVersion - $(MACOSX_DEPLOYMENT_TARGET) - NSHumanReadableCopyright - $(PRODUCT_COPYRIGHT) - NSMainNibFile - MainMenu - NSPrincipalClass - NSApplication - - diff --git a/flutter_tts-voice_enhancement/example/macos/Runner/MainFlutterWindow.swift b/flutter_tts-voice_enhancement/example/macos/Runner/MainFlutterWindow.swift deleted file mode 100644 index 2722837e..00000000 --- a/flutter_tts-voice_enhancement/example/macos/Runner/MainFlutterWindow.swift +++ /dev/null @@ -1,15 +0,0 @@ -import Cocoa -import FlutterMacOS - -class MainFlutterWindow: NSWindow { - override func awakeFromNib() { - let flutterViewController = FlutterViewController.init() - let windowFrame = self.frame - self.contentViewController = flutterViewController - self.setFrame(windowFrame, display: true) - - RegisterGeneratedPlugins(registry: flutterViewController) - - super.awakeFromNib() - } -} diff --git a/flutter_tts-voice_enhancement/example/macos/Runner/Release.entitlements b/flutter_tts-voice_enhancement/example/macos/Runner/Release.entitlements deleted file mode 100644 index 852fa1a4..00000000 --- a/flutter_tts-voice_enhancement/example/macos/Runner/Release.entitlements +++ /dev/null @@ -1,8 +0,0 @@ - - - - - com.apple.security.app-sandbox - - - diff --git a/flutter_tts-voice_enhancement/example/pubspec.yaml b/flutter_tts-voice_enhancement/example/pubspec.yaml deleted file mode 100644 index 54cbe6ed..00000000 --- a/flutter_tts-voice_enhancement/example/pubspec.yaml +++ /dev/null @@ -1,59 +0,0 @@ -name: flutter_tts_example -description: Demonstrates how to use the flutter_tts plugin. - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.2 - -dev_dependencies: - flutter_test: - sdk: flutter - - flutter_tts: - path: ../ - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.io/assets-and-images/#resolution-aware. - - # For details regarding adding assets from package dependencies, see - # https://flutter.io/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.io/custom-fonts/#from-packages diff --git a/flutter_tts-voice_enhancement/example/test/widget_test.dart b/flutter_tts-voice_enhancement/example/test/widget_test.dart deleted file mode 100644 index 6db856cd..00000000 --- a/flutter_tts-voice_enhancement/example/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import '../lib/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/flutter_tts-voice_enhancement/example/web/favicon.png b/flutter_tts-voice_enhancement/example/web/favicon.png deleted file mode 100644 index 8aaa46ac..00000000 Binary files a/flutter_tts-voice_enhancement/example/web/favicon.png and /dev/null differ diff --git a/flutter_tts-voice_enhancement/example/web/icons/Icon-192.png b/flutter_tts-voice_enhancement/example/web/icons/Icon-192.png deleted file mode 100644 index b749bfef..00000000 Binary files a/flutter_tts-voice_enhancement/example/web/icons/Icon-192.png and /dev/null differ diff --git a/flutter_tts-voice_enhancement/example/web/icons/Icon-512.png b/flutter_tts-voice_enhancement/example/web/icons/Icon-512.png deleted file mode 100644 index 88cfd48d..00000000 Binary files a/flutter_tts-voice_enhancement/example/web/icons/Icon-512.png and /dev/null differ diff --git a/flutter_tts-voice_enhancement/example/web/index.html b/flutter_tts-voice_enhancement/example/web/index.html deleted file mode 100644 index 20b0c00a..00000000 --- a/flutter_tts-voice_enhancement/example/web/index.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - Flutter TTS example - - - - - diff --git a/flutter_tts-voice_enhancement/example/web/manifest.json b/flutter_tts-voice_enhancement/example/web/manifest.json deleted file mode 100644 index 8c012917..00000000 --- a/flutter_tts-voice_enhancement/example/web/manifest.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "example", - "short_name": "example", - "start_url": ".", - "display": "standalone", - "background_color": "#0175C2", - "theme_color": "#0175C2", - "description": "A new Flutter project.", - "orientation": "portrait-primary", - "prefer_related_applications": false, - "icons": [ - { - "src": "icons/Icon-192.png", - "sizes": "192x192", - "type": "image/png" - }, - { - "src": "icons/Icon-512.png", - "sizes": "512x512", - "type": "image/png" - } - ] -} diff --git a/flutter_tts-voice_enhancement/ios/.gitignore b/flutter_tts-voice_enhancement/ios/.gitignore deleted file mode 100644 index 956c87f3..00000000 --- a/flutter_tts-voice_enhancement/ios/.gitignore +++ /dev/null @@ -1,31 +0,0 @@ -.idea/ -.vagrant/ -.sconsign.dblite -.svn/ - -.DS_Store -*.swp -profile - -DerivedData/ -build/ - -*.pbxuser -*.mode1v3 -*.mode2v3 -*.perspectivev3 - -!default.pbxuser -!default.mode1v3 -!default.mode2v3 -!default.perspectivev3 - -xcuserdata - -*.moved-aside - -*.pyc -*sync/ -Icon? -.tags* - diff --git a/flutter_tts-voice_enhancement/ios/Classes/AudioCategory.swift b/flutter_tts-voice_enhancement/ios/Classes/AudioCategory.swift deleted file mode 100644 index 74e8ea0b..00000000 --- a/flutter_tts-voice_enhancement/ios/Classes/AudioCategory.swift +++ /dev/null @@ -1,21 +0,0 @@ -import AVFoundation - -enum AudioCategory: String { - case iosAudioCategoryAmbientSolo - case iosAudioCategoryAmbient - case iosAudioCategoryPlayback - case iosAudioCategoryPlaybackAndRecord - - func toAVAudioSessionCategory() -> AVAudioSession.Category { - switch self { - case .iosAudioCategoryAmbientSolo: - return .soloAmbient - case .iosAudioCategoryAmbient: - return .ambient - case .iosAudioCategoryPlayback: - return .playback - case .iosAudioCategoryPlaybackAndRecord: - return .playAndRecord - } - } -} diff --git a/flutter_tts-voice_enhancement/ios/Classes/AudioCategoryOptions.swift b/flutter_tts-voice_enhancement/ios/Classes/AudioCategoryOptions.swift deleted file mode 100644 index f593bfdb..00000000 --- a/flutter_tts-voice_enhancement/ios/Classes/AudioCategoryOptions.swift +++ /dev/null @@ -1,42 +0,0 @@ -import AVFoundation - -enum AudioCategoryOptions: String { - case iosAudioCategoryOptionsMixWithOthers - case iosAudioCategoryOptionsDuckOthers - case iosAudioCategoryOptionsInterruptSpokenAudioAndMixWithOthers - case iosAudioCategoryOptionsAllowBluetooth - case iosAudioCategoryOptionsAllowBluetoothA2DP - case iosAudioCategoryOptionsAllowAirPlay - case iosAudioCategoryOptionsDefaultToSpeaker - - func toAVAudioSessionCategoryOptions() -> AVAudioSession.CategoryOptions? { - switch self { - case .iosAudioCategoryOptionsMixWithOthers: - return .mixWithOthers - case .iosAudioCategoryOptionsDuckOthers: - return .duckOthers - case .iosAudioCategoryOptionsInterruptSpokenAudioAndMixWithOthers: - if #available(iOS 9.0, *) { - return .interruptSpokenAudioAndMixWithOthers - } else { - return nil - } - case .iosAudioCategoryOptionsAllowBluetooth: - return .allowBluetooth - case .iosAudioCategoryOptionsAllowBluetoothA2DP: - if #available(iOS 10.0, *) { - return .allowBluetoothA2DP - } else { - return nil - } - case .iosAudioCategoryOptionsAllowAirPlay: - if #available(iOS 10.0, *) { - return .allowAirPlay - } else { - return nil - } - case .iosAudioCategoryOptionsDefaultToSpeaker: - return .defaultToSpeaker - } - } -} diff --git a/flutter_tts-voice_enhancement/ios/Classes/FlutterTtsPlugin.h b/flutter_tts-voice_enhancement/ios/Classes/FlutterTtsPlugin.h deleted file mode 100644 index 13e3a21a..00000000 --- a/flutter_tts-voice_enhancement/ios/Classes/FlutterTtsPlugin.h +++ /dev/null @@ -1,4 +0,0 @@ -#import - -@interface FlutterTtsPlugin : NSObject -@end diff --git a/flutter_tts-voice_enhancement/ios/Classes/FlutterTtsPlugin.m b/flutter_tts-voice_enhancement/ios/Classes/FlutterTtsPlugin.m deleted file mode 100644 index 3a1f187c..00000000 --- a/flutter_tts-voice_enhancement/ios/Classes/FlutterTtsPlugin.m +++ /dev/null @@ -1,8 +0,0 @@ -#import "FlutterTtsPlugin.h" -#import - -@implementation FlutterTtsPlugin -+ (void)registerWithRegistrar:(NSObject*)registrar { - [SwiftFlutterTtsPlugin registerWithRegistrar:registrar]; -} -@end diff --git a/flutter_tts-voice_enhancement/ios/Classes/SwiftFlutterTtsPlugin.swift b/flutter_tts-voice_enhancement/ios/Classes/SwiftFlutterTtsPlugin.swift deleted file mode 100644 index 5c78c135..00000000 --- a/flutter_tts-voice_enhancement/ios/Classes/SwiftFlutterTtsPlugin.swift +++ /dev/null @@ -1,386 +0,0 @@ -import Flutter -import UIKit -import AVFoundation - -public class SwiftFlutterTtsPlugin: NSObject, FlutterPlugin, AVSpeechSynthesizerDelegate { - final var iosAudioCategoryKey = "iosAudioCategoryKey" - final var iosAudioCategoryOptionsKey = "iosAudioCategoryOptionsKey" - - let synthesizer = AVSpeechSynthesizer() - var language: String = AVSpeechSynthesisVoice.currentLanguageCode() - var rate: Float = AVSpeechUtteranceDefaultSpeechRate - var languages = Set() - var volume: Float = 1.0 - var pitch: Float = 1.0 - var voice: AVSpeechSynthesisVoice? - var awaitSpeakCompletion: Bool = false - var speakResult: FlutterResult! - - var channel = FlutterMethodChannel() - lazy var audioSession = AVAudioSession.sharedInstance() - init(channel: FlutterMethodChannel) { - super.init() - self.channel = channel - synthesizer.delegate = self - setLanguages() - - // Allow audio playback when the Ring/Silent switch is set to silent - do { - try audioSession.setCategory(.playAndRecord, options: [.defaultToSpeaker]) - } catch { - print(error) - } - } - - private func setLanguages() { - for voice in AVSpeechSynthesisVoice.speechVoices(){ - self.languages.insert(voice.language) - } - } - - public static func register(with registrar: FlutterPluginRegistrar) { - let channel = FlutterMethodChannel(name: "flutter_tts", binaryMessenger: registrar.messenger()) - let instance = SwiftFlutterTtsPlugin(channel: channel) - registrar.addMethodCallDelegate(instance, channel: channel) - } - - public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { - switch call.method { - case "speak": - let text: String = call.arguments as! String - self.speak(text: text, result: result) - break - case "awaitSpeakCompletion": - self.awaitSpeakCompletion = call.arguments as! Bool - result(1) - break - case "synthesizeToFile": - guard let args = call.arguments as? [String: Any] else { - result("iOS could not recognize flutter arguments in method: (sendParams)") - return - } - let text = args["text"] as! String - let fileName = args["fileName"] as! String - self.synthesizeToFile(text: text, fileName: fileName, result: result) - break - case "pause": - self.pause(result: result) - break - case "setLanguage": - let language: String = call.arguments as! String - self.setLanguage(language: language, result: result) - break - case "setSpeechRate": - let rate: Double = call.arguments as! Double - self.setRate(rate: Float(rate)) - result(1) - break - case "setVolume": - let volume: Double = call.arguments as! Double - self.setVolume(volume: Float(volume), result: result) - break - case "setPitch": - let pitch: Double = call.arguments as! Double - self.setPitch(pitch: Float(pitch), result: result) - break - case "stop": - self.stop() - result(1) - break - case "getLanguages": - self.getLanguages(result: result) - break - case "getSpeechRateValidRange": - self.getSpeechRateValidRange(result: result) - break - case "isLanguageAvailable": - let language: String = call.arguments as! String - self.isLanguageAvailable(language: language, result: result) - break - case "getVoices": - self.getVoices(result: result) - break - case "setVoice": - guard let args = call.arguments as? [String: String] else { - result("iOS could not recognize flutter arguments in method: (sendParams)") - return - } - self.setVoice(voice: args, result: result) - break - case "setSharedInstance": - let sharedInstance = call.arguments as! Bool - self.setSharedInstance(sharedInstance: sharedInstance, result: result) - break - case "setIosAudioCategory": - guard let args = call.arguments as? [String: Any] else { - result("iOS could not recognize flutter arguments in method: (sendParams)") - return - } - let audioCategory = args["iosAudioCategoryKey"] as? String - let audioOptions = args[iosAudioCategoryOptionsKey] as? Array - self.setAudioCategory(audioCategory: audioCategory, audioOptions: audioOptions, result: result) - break - default: - result(FlutterMethodNotImplemented) - } - } - - private func speak(text: String, result: @escaping FlutterResult) { - if (self.synthesizer.isPaused) { - if (self.synthesizer.continueSpeaking()) { - if self.awaitSpeakCompletion { - self.speakResult = result - } else { - result(1) - } - } else { - result(0) - } - } else { - let utterance = AVSpeechUtterance(string: text) - if self.voice != nil { - utterance.voice = self.voice! - } else { - utterance.voice = AVSpeechSynthesisVoice(language: self.language) - } - utterance.rate = self.rate - utterance.volume = self.volume - utterance.pitchMultiplier = self.pitch - - self.synthesizer.speak(utterance) - if self.awaitSpeakCompletion { - self.speakResult = result - } else { - result(1) - } - } - } - - private func synthesizeToFile(text: String, fileName: String, result: FlutterResult) { - var output: AVAudioFile? - var failed = false - let utterance = AVSpeechUtterance(string: text) - - if self.voice != nil { - utterance.voice = self.voice! - } else { - utterance.voice = AVSpeechSynthesisVoice(language: self.language) - } - utterance.rate = self.rate - utterance.volume = self.volume - utterance.pitchMultiplier = self.pitch - - if #available(iOS 13.0, *) { - self.synthesizer.write(utterance) { (buffer: AVAudioBuffer) in - guard let pcmBuffer = buffer as? AVAudioPCMBuffer else { - NSLog("unknow buffer type: \(buffer)") - failed = true - return - } - print(pcmBuffer.format) - if pcmBuffer.frameLength == 0 { - // finished - } else { - // append buffer to file - let fileURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!.appendingPathComponent(fileName) - NSLog("Saving utterance to file: \(fileURL.absoluteString)") - - if output == nil { - do { - output = try AVAudioFile( - forWriting: fileURL, - settings: pcmBuffer.format.settings, - commonFormat: .pcmFormatInt16, - interleaved: false) - } catch { - NSLog(error.localizedDescription) - failed = true - return - } - } - - try! output!.write(from: pcmBuffer) - } - } - } else { - result("Unsupported iOS version") - } - if failed { - result(0) - } - result(1) - } - - private func pause(result: FlutterResult) { - if (self.synthesizer.pauseSpeaking(at: AVSpeechBoundary.word)) { - result(1) - } else { - result(0) - } - } - - private func setLanguage(language: String, result: FlutterResult) { - if !(self.languages.contains(where: {$0.range(of: language, options: [.caseInsensitive, .anchored]) != nil})) { - result(0) - } else { - self.language = language - self.voice = nil - result(1) - } - } - - private func setRate(rate: Float) { - self.rate = rate - } - - private func setVolume(volume: Float, result: FlutterResult) { - if (volume >= 0.0 && volume <= 1.0) { - self.volume = volume - result(1) - } else { - result(0) - } - } - - private func setPitch(pitch: Float, result: FlutterResult) { - if (volume >= 0.5 && volume <= 2.0) { - self.pitch = pitch - result(1) - } else { - result(0) - } - } - - private func setSharedInstance(sharedInstance: Bool, result: FlutterResult) { - do { - try AVAudioSession.sharedInstance().setActive(sharedInstance) - result(1) - } catch { - result(0) - } - } - - private func setAudioCategory(audioCategory: String?, audioOptions: Array?, result: FlutterResult){ - let category: AVAudioSession.Category = AudioCategory(rawValue: audioCategory ?? "")?.toAVAudioSessionCategory() ?? audioSession.category - let options: AVAudioSession.CategoryOptions = audioOptions?.reduce([], { (result, option) -> AVAudioSession.CategoryOptions in - return result.union(AudioCategoryOptions(rawValue: option)?.toAVAudioSessionCategoryOptions() ?? []) - }) ?? [] - - do { - try audioSession.setCategory(category, options: options) - result(1) - } catch { - print(error) - result(0) - } - } - - private func stop() { - self.synthesizer.stopSpeaking(at: AVSpeechBoundary.immediate) - } - - private func getLanguages(result: FlutterResult) { - result(Array(self.languages)) - } - - private func getSpeechRateValidRange(result: FlutterResult) { - let validSpeechRateRange: [String:String] = [ - "min": String(AVSpeechUtteranceMinimumSpeechRate), - "normal": String(AVSpeechUtteranceDefaultSpeechRate), - "max": String(AVSpeechUtteranceMaximumSpeechRate), - "platform": "ios" - ] - result(validSpeechRateRange) - } - - private func isLanguageAvailable(language: String, result: FlutterResult) { - var isAvailable: Bool = false - if (self.languages.contains(where: {$0.range(of: language, options: [.caseInsensitive, .anchored]) != nil})) { - isAvailable = true - } - result(isAvailable); - } - - private func getVoices(result: FlutterResult) { - if #available(iOS 9.0, *) { - let voices = NSMutableArray() - var voiceDict: [String: String] = [:] - for voice in AVSpeechSynthesisVoice.speechVoices() { - voiceDict["name"] = voice.name - voiceDict["locale"] = voice.language - voices.add(voiceDict) - } - result(voices) - } else { - // Since voice selection is not supported below iOS 9, make voice getter and setter - // have the same bahavior as language selection. - getLanguages(result: result) - } - } - - private func setVoice(voice: [String:String], result: FlutterResult) { - if #available(iOS 9.0, *) { - if let voice = AVSpeechSynthesisVoice.speechVoices().first(where: { $0.name == voice["name"]! && $0.language == voice["locale"]! }) { - self.voice = voice - self.language = voice.language - result(1) - return - } - result(0) - } else { - setLanguage(language: voice["name"]!, result: result) - } - } - - private func shouldDeactivateAndNotifyOthers(_ session: AVAudioSession) -> Bool { - var options: AVAudioSession.CategoryOptions = .duckOthers - if #available(iOS 9.0, *) { - options.insert(.interruptSpokenAudioAndMixWithOthers) - } - options.remove(.mixWithOthers) - - return !options.isDisjoint(with: session.categoryOptions) - } - - public func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didFinish utterance: AVSpeechUtterance) { - if shouldDeactivateAndNotifyOthers(audioSession) { - do { - try audioSession.setActive(false, options: .notifyOthersOnDeactivation) - } catch { - print(error) - } - } - if self.awaitSpeakCompletion { - self.speakResult(1) - } - self.channel.invokeMethod("speak.onComplete", arguments: nil) - } - - public func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didStart utterance: AVSpeechUtterance) { - self.channel.invokeMethod("speak.onStart", arguments: nil) - } - - public func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didPause utterance: AVSpeechUtterance) { - self.channel.invokeMethod("speak.onPause", arguments: nil) - } - - public func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didContinue utterance: AVSpeechUtterance) { - self.channel.invokeMethod("speak.onContinue", arguments: nil) - } - - public func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didCancel utterance: AVSpeechUtterance) { - self.channel.invokeMethod("speak.onCancel", arguments: nil) - } - - public func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, willSpeakRangeOfSpeechString characterRange: NSRange, utterance: AVSpeechUtterance) { - let nsWord = utterance.speechString as NSString - let data: [String:String] = [ - "text": utterance.speechString, - "start": String(characterRange.location), - "end": String(characterRange.location + characterRange.length), - "word": nsWord.substring(with: characterRange) - ] - self.channel.invokeMethod("speak.onProgress", arguments: data) - } - -} diff --git a/flutter_tts-voice_enhancement/ios/flutter_tts.podspec b/flutter_tts-voice_enhancement/ios/flutter_tts.podspec deleted file mode 100644 index 03099f45..00000000 --- a/flutter_tts-voice_enhancement/ios/flutter_tts.podspec +++ /dev/null @@ -1,22 +0,0 @@ -# -# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html -# -Pod::Spec.new do |s| - s.name = 'flutter_tts' - s.version = '0.0.1' - s.summary = 'A flutter text to speech plugin.' - s.description = <<-DESC -A flutter text to speech plugin - DESC - s.homepage = 'https://github.com/dlutton/flutter_tts' - s.license = { :file => '../LICENSE' } - s.author = { 'tundralabs' => 'eyedea32@gmail.com' } - s.source = { :path => '.' } - s.source_files = 'Classes/**/*' - s.public_header_files = 'Classes/**/*.h' - s.dependency 'Flutter' - s.ios.deployment_target = '8.0' - s.swift_version = '4.2' - s.static_framework = true -end - diff --git a/flutter_tts-voice_enhancement/lib/flutter_tts.dart b/flutter_tts-voice_enhancement/lib/flutter_tts.dart deleted file mode 100644 index c823a91d..00000000 --- a/flutter_tts-voice_enhancement/lib/flutter_tts.dart +++ /dev/null @@ -1,342 +0,0 @@ -import 'dart:async'; -import 'dart:io' show Platform; - -import 'package:flutter/foundation.dart'; -import 'package:flutter/services.dart'; - -typedef void ErrorHandler(dynamic message); -typedef ProgressHandler = void Function( - String text, int start, int end, String word); - -const String iosAudioCategoryOptionsKey = 'iosAudioCategoryOptionsKey'; -const String iosAudioCategoryKey = 'iosAudioCategoryKey'; -const String iosAudioCategoryAmbientSolo = 'iosAudioCategoryAmbientSolo'; -const String iosAudioCategoryAmbient = 'iosAudioCategoryAmbient'; -const String iosAudioCategoryPlayback = 'iosAudioCategoryPlayback'; -const String iosAudioCategoryPlaybackAndRecord = - 'iosAudioCategoryPlaybackAndRecord'; - -const String iosAudioCategoryOptionsMixWithOthers = - 'iosAudioCategoryOptionsMixWithOthers'; -const String iosAudioCategoryOptionsDuckOthers = - 'iosAudioCategoryOptionsDuckOthers'; -const String iosAudioCategoryOptionsInterruptSpokenAudioAndMixWithOthers = - 'iosAudioCategoryOptionsInterruptSpokenAudioAndMixWithOthers'; -const String iosAudioCategoryOptionsAllowBluetooth = - 'iosAudioCategoryOptionsAllowBluetooth'; -const String iosAudioCategoryOptionsAllowBluetoothA2DP = - 'iosAudioCategoryOptionsAllowBluetoothA2DP'; -const String iosAudioCategoryOptionsAllowAirPlay = - 'iosAudioCategoryOptionsAllowAirPlay'; -const String iosAudioCategoryOptionsDefaultToSpeaker = - 'iosAudioCategoryOptionsDefaultToSpeaker'; - -enum TextToSpeechPlatform { android, ios } - -enum IosTextToSpeechAudioCategory { - /// Audio is silenced by screen lock and the silent switch; audio will not mix - /// with other apps' audio. - ambientSolo, - - /// Audio is silenced by screen lock and the silent switch; audio will mix - /// with other apps' (mixable) audio. - ambient, - - /// Audio is not silenced by screen lock or silent switch; audio will not mix - /// with other apps' audio. - /// - playback, - - /// The category for recording (input) and playback (output) of audio, - /// such as for a Voice over Internet Protocol (VoIP) app. - /// The default value. - playAndRecord, -} - -enum IosTextToSpeechAudioCategoryOptions { - /// An option that indicates whether audio from this session mixes with audio - /// from active sessions in other audio apps. - mixWithOthers, - - /// An option that reduces the volume of other audio session while audio - /// from this session plays. - duckOthers, - - /// An option that determines whether to pause spoken audio content - /// from other sessions when your app plays its audio. - interruptSpokenAudioAndMixWithOthers, - - ///An option that determines whether Bluetooth hands-free devices - /// appear as available input routes. - allowBluetooth, - - ///An option that determines whether you can stream audio - /// from this session to Bluetooth devices that support the Advanced Audio Distribution Profile (A2DP). - allowBluetoothA2DP, - - ///An option that determines whether you can stream audio - /// from this session to AirPlay devices. - allowAirPlay, - - ///An option that determines whether audio - /// from the session defaults to the built-in speaker instead of the receiver. - /// The default value. - defaultToSpeaker, -} - -class SpeechRateValidRange { - final double min; - final double normal; - final double max; - final TextToSpeechPlatform platform; - - SpeechRateValidRange(this.min, this.normal, this.max, this.platform); -} - -// Provides Platform specific TTS services (Android: TextToSpeech, IOS: AVSpeechSynthesizer) -class FlutterTts { - static const MethodChannel _channel = const MethodChannel('flutter_tts'); - - VoidCallback startHandler; - VoidCallback completionHandler; - VoidCallback pauseHandler; - VoidCallback continueHandler; - VoidCallback cancelHandler; - ProgressHandler progressHandler; - ErrorHandler errorHandler; - - FlutterTts() { - _channel.setMethodCallHandler(platformCallHandler); - } - - /// [Future] which sets speak's future to return on completion of the utterance - Future awaitSpeakCompletion(bool awaitCompletion) async => - _channel.invokeMethod('awaitSpeakCompletion', awaitCompletion); - - /// [Future] which invokes the platform specific method for speaking - Future speak(String text) async => - _channel.invokeMethod('speak', text); - - /// [Future] which invokes the platform specific method for pause - /// ***iOS supported only*** - Future pause() async => _channel.invokeMethod('pause'); - - /// [Future] which invokes the platform specific method for synthesizeToFile - /// ***Android and iOS supported only*** - Future synthesizeToFile(String text, String fileName) async => - _channel.invokeMethod('synthesizeToFile', { - "text": text, - "fileName": fileName, - }); - - /// [Future] which invokes the platform specific method for setLanguage - Future setLanguage(String language) async => - _channel.invokeMethod('setLanguage', language); - - /// [Future] which invokes the platform specific method for setSpeechRate - /// Allowed values are in the range from 0.0 (slowest) to 1.0 (fastest) - Future setSpeechRate(double rate) async => - _channel.invokeMethod('setSpeechRate', rate); - - /// [Future] which invokes the platform specific method for setVolume - /// Allowed values are in the range from 0.0 (silent) to 1.0 (loudest) - Future setVolume(double volume) async => - _channel.invokeMethod('setVolume', volume); - - /// [Future] which invokes the platform specific method for shared instance - /// ***iOS supported only*** - Future setSharedInstance(bool sharedSession) async => - _channel.invokeMethod('setSharedInstance', sharedSession); - - /// [Future] which invokes the platform specific method for setting audio category - /// ***Ios supported only*** - Future setIosAudioCategory(IosTextToSpeechAudioCategory category, - List options) async { - const categoryToString = { - IosTextToSpeechAudioCategory.ambientSolo: iosAudioCategoryAmbientSolo, - IosTextToSpeechAudioCategory.ambient: iosAudioCategoryAmbient, - IosTextToSpeechAudioCategory.playback: iosAudioCategoryPlayback - }; - const optionsToString = { - IosTextToSpeechAudioCategoryOptions.mixWithOthers: - 'iosAudioCategoryOptionsMixWithOthers', - IosTextToSpeechAudioCategoryOptions.duckOthers: - 'iosAudioCategoryOptionsDuckOthers', - IosTextToSpeechAudioCategoryOptions.interruptSpokenAudioAndMixWithOthers: - 'iosAudioCategoryOptionsInterruptSpokenAudioAndMixWithOthers', - IosTextToSpeechAudioCategoryOptions.allowBluetooth: - 'iosAudioCategoryOptionsAllowBluetooth', - IosTextToSpeechAudioCategoryOptions.allowBluetoothA2DP: - 'iosAudioCategoryOptionsAllowBluetoothA2DP', - IosTextToSpeechAudioCategoryOptions.allowAirPlay: - 'iosAudioCategoryOptionsAllowAirPlay', - IosTextToSpeechAudioCategoryOptions.defaultToSpeaker: - 'iosAudioCategoryOptionsDefaultToSpeaker', - }; - if (!Platform.isIOS) return; - try { - return _channel - .invokeMethod('setIosAudioCategory', { - iosAudioCategoryKey: categoryToString[category], - iosAudioCategoryOptionsKey: - options.map((o) => optionsToString[o]).toList(), - }); - } on PlatformException catch (e) { - print( - 'setIosAudioCategory error, category: $category, error: ${e.message}'); - } - } - - /// [Future] which invokes the platform specific method for setPitch - /// 1.0 is default and ranges from .5 to 2.0 - Future setPitch(double pitch) async => - _channel.invokeMethod('setPitch', pitch); - - /// [Future] which invokes the platform specific method for setVoice - /// ***Android, iOS, and macOS supported only*** - Future setVoice(Map voice) async => - _channel.invokeMethod('setVoice', voice); - - /// [Future] which invokes the platform specific method for stop - Future stop() async => _channel.invokeMethod('stop'); - - /// [Future] which invokes the platform specific method for getLanguages - /// Android issues with API 21 & 22 - /// Returns a list of available languages - Future get getLanguages async { - final languages = await _channel.invokeMethod('getLanguages'); - return languages; - } - - /// [Future] which invokes the platform specific method for getEngines - /// Returns a list of installed TTS engines - /// ***Android supported only*** - Future get getEngines async { - final engines = await _channel.invokeMethod('getEngines'); - return engines; - } - - /// [Future] which invokes the platform specific method for getVoices - /// Returns a `List` of `Maps` containing a voice name and locale - /// ***Android, iOS, and macOS supported only*** - Future get getVoices async { - final voices = await _channel.invokeMethod('getVoices'); - return voices; - } - - /// [Future] which invokes the platform specific method for isLanguageAvailable - /// Returns `true` or `false` - Future isLanguageAvailable(String language) async => - _channel.invokeMethod('isLanguageAvailable', language); - - Future get getSpeechRateValidRange async { - final validRange = await _channel.invokeMethod('getSpeechRateValidRange') - as Map; - final min = double.parse(validRange['min'].toString()); - final normal = double.parse(validRange['normal'].toString()); - final max = double.parse(validRange['max'].toString()); - final platformStr = validRange['platform'].toString(); - final platform = TextToSpeechPlatform.values - .firstWhere((e) => describeEnum(e) == platformStr); - - return SpeechRateValidRange(min, normal, max, platform); - } - - /// [Future] which invokes the platform specific method for setSilence - /// 0 means start the utterance immediately. If the value is greater than zero a silence period in milliseconds is set according to the parameter - /// ***Android supported only*** - Future setSilence(int timems) async => - _channel.invokeMethod('setSilence', timems ?? 0); - - void setStartHandler(VoidCallback callback) { - startHandler = callback; - } - - void setCompletionHandler(VoidCallback callback) { - completionHandler = callback; - } - - void setContinueHandler(VoidCallback callback) { - continueHandler = callback; - } - - void setPauseHandler(VoidCallback callback) { - pauseHandler = callback; - } - - void setCancelHandler(VoidCallback callback) { - cancelHandler = callback; - } - - void setProgressHandler(ProgressHandler callback) { - progressHandler = callback; - } - - void setErrorHandler(ErrorHandler handler) { - errorHandler = handler; - } - - /// Platform listeners - Future platformCallHandler(MethodCall call) async { - switch (call.method) { - case "speak.onStart": - if (startHandler != null) { - startHandler(); - } - break; - case "synth.onStart": - if (startHandler != null) { - startHandler(); - } - break; - case "speak.onComplete": - if (completionHandler != null) { - completionHandler(); - } - break; - case "synth.onComplete": - if (completionHandler != null) { - completionHandler(); - } - break; - case "speak.onPause": - if (pauseHandler != null) { - pauseHandler(); - } - break; - case "speak.onContinue": - if (continueHandler != null) { - continueHandler(); - } - break; - case "speak.onCancel": - if (cancelHandler != null) { - cancelHandler(); - } - break; - case "speak.onError": - if (errorHandler != null) { - errorHandler(call.arguments); - } - break; - case 'speak.onProgress': - if (progressHandler != null) { - final args = call.arguments as Map; - progressHandler( - args['text'].toString(), - int.parse(args['start'].toString()), - int.parse(args['end'].toString()), - args['word'].toString(), - ); - } - break; - case "synth.onError": - if (errorHandler != null) { - errorHandler(call.arguments); - } - break; - default: - print('Unknowm method ${call.method}'); - } - } -} diff --git a/flutter_tts-voice_enhancement/lib/flutter_tts_web.dart b/flutter_tts-voice_enhancement/lib/flutter_tts_web.dart deleted file mode 100644 index 182e9dfa..00000000 --- a/flutter_tts-voice_enhancement/lib/flutter_tts_web.dart +++ /dev/null @@ -1,184 +0,0 @@ -import 'dart:async'; -import 'dart:html' as html; -import 'dart:js'; - -import 'package:flutter/services.dart'; -import 'package:flutter_web_plugins/flutter_web_plugins.dart'; - -enum TtsState { playing, stopped, paused, continued } - -class FlutterTtsPlugin { - static const String PLATFORM_CHANNEL = "flutter_tts"; - static MethodChannel channel; - bool awaitSpeakCompletion = false; - - TtsState ttsState = TtsState.stopped; - - get isPlaying => ttsState == TtsState.playing; - - get isStopped => ttsState == TtsState.stopped; - - get isPaused => ttsState == TtsState.paused; - - get isContinued => ttsState == TtsState.continued; - - static void registerWith(Registrar registrar) { - channel = MethodChannel( - PLATFORM_CHANNEL, const StandardMethodCodec(), registrar.messenger); - final instance = FlutterTtsPlugin(); - channel.setMethodCallHandler(instance.handleMethodCall); - } - - html.SpeechSynthesis synth; - html.SpeechSynthesisUtterance utterance; - List voices; - List languages; - - FlutterTtsPlugin() { - utterance = html.SpeechSynthesisUtterance(); - synth = html.window.speechSynthesis; - - _listeners(); - } - - void _listeners() { - utterance.onStart.listen((e) { - ttsState = TtsState.playing; - channel.invokeMethod("speak.onStart", null); - }); - utterance.onEnd.listen((e) { - ttsState = TtsState.stopped; - channel.invokeMethod("speak.onComplete", null); - if (awaitSpeakCompletion) { - return 1; - } - }); - utterance.onPause.listen((e) { - ttsState = TtsState.paused; - channel.invokeMethod("speak.onPause", null); - }); - utterance.onResume.listen((e) { - ttsState = TtsState.continued; - channel.invokeMethod("speak.onContinue", null); - }); - utterance.onError.listen((e) { - channel.invokeMethod("speak.onError", e); - if (awaitSpeakCompletion) { - return 0; - } - }); - } - - Future handleMethodCall(MethodCall call) async { - switch (call.method) { - case 'speak': - final text = call.arguments as String; - _speak(text); - if (!awaitSpeakCompletion) { - return 1; - } - break; - case 'awaitSpeakCompletion': - awaitSpeakCompletion = call.arguments as bool; - return 1; - break; - case 'stop': - _stop(); - return 1; - break; - case 'pause': - _pause(); - return 1; - break; - case 'setLanguage': - final language = call.arguments as String; - _setLanguage(language); - return 1; - break; - case 'getLanguages': - return _getLanguages(); - break; - case 'setSpeechRate': - final rate = call.arguments as num; - _setRate(rate); - return 1; - break; - case 'setVolume': - final volume = call.arguments as num; - _setVolume(volume); - return 1; - break; - case 'setPitch': - final pitch = call.arguments as num; - _setPitch(pitch); - return 1; - break; - case 'isLanguageAvailable': - final lang = call.arguments as String; - return _isLanguageAvailable(lang); - break; - default: - throw PlatformException( - code: 'Unimplemented', - details: "The flutter_tts plugin for web doesn't implement " - "the method '${call.method}'"); - } - } - - void _speak(String text) { - if (ttsState == TtsState.stopped || ttsState == TtsState.paused) { - utterance.text = text; - if (ttsState == TtsState.paused) { - synth.resume(); - } else { - synth.speak(utterance); - } - } - } - - void _stop() { - if (ttsState != TtsState.stopped) { - synth.cancel(); - } - } - - void _pause() { - if (ttsState == TtsState.playing || ttsState == TtsState.continued) { - synth.pause(); - } - } - - void _setRate(num rate) => utterance.rate = rate * 2.0; - void _setVolume(num volume) => utterance.volume = volume; - void _setPitch(num pitch) => utterance.pitch = pitch; - void _setLanguage(String language) => utterance.lang = language; - - bool _isLanguageAvailable(String language) { - if (voices?.isEmpty ?? true) _setVoices(); - if (languages?.isEmpty ?? true) _setLanguages(); - for (var lang in languages) { - if (lang.toLowerCase() == language.toLowerCase()) return true; - } - return false; - } - - List _getLanguages() { - if (voices?.isEmpty ?? true) _setVoices(); - if (languages?.isEmpty ?? true) _setLanguages(); - return languages; - } - - void _setVoices() { - voices = - context['speechSynthesis'].callMethod('getVoices') as JsArray; - } - - void _setLanguages() { - var langs = Set(); - for (var v in voices) { - langs.add(v['lang'] as String); - } - - languages = langs.toList(); - } -} diff --git a/flutter_tts-voice_enhancement/macos/Classes/FlutterTtsPlugin.swift b/flutter_tts-voice_enhancement/macos/Classes/FlutterTtsPlugin.swift deleted file mode 100644 index ec4bffa1..00000000 --- a/flutter_tts-voice_enhancement/macos/Classes/FlutterTtsPlugin.swift +++ /dev/null @@ -1,315 +0,0 @@ -import FlutterMacOS -import Foundation -import AVFoundation - -public class FlutterTtsPlugin: NSObject, FlutterPlugin, AVSpeechSynthesizerDelegate { - final var iosAudioCategoryKey = "iosAudioCategoryKey" - final var iosAudioCategoryOptionsKey = "iosAudioCategoryOptionsKey" - - let synthesizer = AVSpeechSynthesizer() - var language: String = AVSpeechSynthesisVoice.currentLanguageCode() - var rate: Float = AVSpeechUtteranceDefaultSpeechRate - var languages = Set() - var volume: Float = 1.0 - var pitch: Float = 1.0 - var voice: AVSpeechSynthesisVoice? - var awaitSpeakCompletion: Bool = false - var speakResult: FlutterResult! - - var channel = FlutterMethodChannel() - init(channel: FlutterMethodChannel) { - super.init() - self.channel = channel - synthesizer.delegate = self - setLanguages() - } - - private func setLanguages() { - for voice in AVSpeechSynthesisVoice.speechVoices(){ - self.languages.insert(voice.language) - } - } - - public static func register(with registrar: FlutterPluginRegistrar) { - let channel = FlutterMethodChannel(name: "flutter_tts", binaryMessenger: registrar.messenger) - let instance = FlutterTtsPlugin(channel: channel) - registrar.addMethodCallDelegate(instance, channel: channel) - } - - public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { - switch call.method { - case "speak": - let text: String = call.arguments as! String - self.speak(text: text, result: result) - break - case "awaitSpeakCompletion": - self.awaitSpeakCompletion = call.arguments as! Bool - result(1) - break - case "synthesizeToFile": - guard let args = call.arguments as? [String: Any] else { - result("iOS could not recognize flutter arguments in method: (sendParams)") - return - } - let text = args["text"] as! String - let fileName = args["fileName"] as! String - self.synthesizeToFile(text: text, fileName: fileName, result: result) - break - case "pause": - self.pause(result: result) - break - case "setLanguage": - let language: String = call.arguments as! String - self.setLanguage(language: language, result: result) - break - case "setSpeechRate": - let rate: Double = call.arguments as! Double - self.setRate(rate: Float(rate)) - result(1) - break - case "setVolume": - let volume: Double = call.arguments as! Double - self.setVolume(volume: Float(volume), result: result) - break - case "setPitch": - let pitch: Double = call.arguments as! Double - self.setPitch(pitch: Float(pitch), result: result) - break - case "stop": - self.stop() - result(1) - break - case "getLanguages": - self.getLanguages(result: result) - break - case "getSpeechRateValidRange": - self.getSpeechRateValidRange(result: result) - break - case "isLanguageAvailable": - let language: String = call.arguments as! String - self.isLanguageAvailable(language: language, result: result) - break - case "getVoices": - self.getVoices(result: result) - break - case "setVoice": - guard let args = call.arguments as? [String: String] else { - result("iOS could not recognize flutter arguments in method: (sendParams)") - return - } - self.setVoice(voice: args, result: result) - break - default: - result(FlutterMethodNotImplemented) - } - } - - private func speak(text: String, result: @escaping FlutterResult) { - if (self.synthesizer.isPaused) { - if (self.synthesizer.continueSpeaking()) { - if self.awaitSpeakCompletion { - self.speakResult = result - } else { - result(1) - } - } else { - result(0) - } - } else { - let utterance = AVSpeechUtterance(string: text) - if self.voice != nil { - utterance.voice = self.voice! - } else { - utterance.voice = AVSpeechSynthesisVoice(language: self.language) - } - utterance.rate = self.rate - utterance.volume = self.volume - utterance.pitchMultiplier = self.pitch - - self.synthesizer.speak(utterance) - if self.awaitSpeakCompletion { - self.speakResult = result - } else { - result(1) - } - } - } - - private func synthesizeToFile(text: String, fileName: String, result: FlutterResult) { - var output: AVAudioFile? - var failed = false - let utterance = AVSpeechUtterance(string: text) - - if #available(iOS 13.0, *) { - self.synthesizer.write(utterance) { (buffer: AVAudioBuffer) in - guard let pcmBuffer = buffer as? AVAudioPCMBuffer else { - NSLog("unknow buffer type: \(buffer)") - failed = true - return - } - print(pcmBuffer.format) - if pcmBuffer.frameLength == 0 { - // finished - } else { - // append buffer to file - let fileURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!.appendingPathComponent(fileName) - NSLog("Saving utterance to file: \(fileURL.absoluteString)") - - if output == nil { - do { - output = try AVAudioFile( - forWriting: fileURL, - settings: pcmBuffer.format.settings, - commonFormat: .pcmFormatInt16, - interleaved: false) - } catch { - NSLog(error.localizedDescription) - failed = true - return - } - } - - try! output!.write(from: pcmBuffer) - } - } - } else { - result("Unsupported iOS version") - } - if failed { - result(0) - } - result(1) - } - - private func pause(result: FlutterResult) { - if (self.synthesizer.pauseSpeaking(at: AVSpeechBoundary.word)) { - result(1) - } else { - result(0) - } - } - - private func setLanguage(language: String, result: FlutterResult) { - if !(self.languages.contains(where: {$0.range(of: language, options: [.caseInsensitive, .anchored]) != nil})) { - result(0) - } else { - self.language = language - self.voice = nil - result(1) - } - } - - private func setRate(rate: Float) { - self.rate = rate - } - - private func setVolume(volume: Float, result: FlutterResult) { - if (volume >= 0.0 && volume <= 1.0) { - self.volume = volume - result(1) - } else { - result(0) - } - } - - private func setPitch(pitch: Float, result: FlutterResult) { - if (volume >= 0.5 && volume <= 2.0) { - self.pitch = pitch - result(1) - } else { - result(0) - } - } - - private func stop() { - self.synthesizer.stopSpeaking(at: AVSpeechBoundary.immediate) - } - - private func getLanguages(result: FlutterResult) { - result(Array(self.languages)) - } - - private func getSpeechRateValidRange(result: FlutterResult) { - let validSpeechRateRange: [String:String] = [ - "min": String(AVSpeechUtteranceMinimumSpeechRate), - "normal": String(AVSpeechUtteranceDefaultSpeechRate), - "max": String(AVSpeechUtteranceMaximumSpeechRate), - "platform": "ios" - ] - result(validSpeechRateRange) - } - - private func isLanguageAvailable(language: String, result: FlutterResult) { - var isAvailable: Bool = false - if (self.languages.contains(where: {$0.range(of: language, options: [.caseInsensitive, .anchored]) != nil})) { - isAvailable = true - } - result(isAvailable); - } - - private func getVoices(result: FlutterResult) { - if #available(iOS 9.0, *) { - let voices = NSMutableArray() - var voiceDict: [String: String] = [:] - for voice in AVSpeechSynthesisVoice.speechVoices() { - voiceDict["name"] = voice.name - voiceDict["locale"] = voice.language - voices.add(voiceDict) - } - result(voices) - } else { - // Since voice selection is not supported below iOS 9, make voice getter and setter - // have the same bahavior as language selection. - getLanguages(result: result) - } - } - - private func setVoice(voice: [String:String], result: FlutterResult) { - if #available(iOS 9.0, *) { - if let voice = AVSpeechSynthesisVoice.speechVoices().first(where: { $0.name == voice["name"]! && $0.language == voice["locale"]! }) { - self.voice = voice - self.language = voice.language - result(1) - return - } - result(0) - } else { - setLanguage(language: voice["name"]!, result: result) - } - } - - public func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didFinish utterance: AVSpeechUtterance) { - if self.awaitSpeakCompletion { - self.speakResult(1) - } - self.channel.invokeMethod("speak.onComplete", arguments: nil) - } - - public func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didStart utterance: AVSpeechUtterance) { - self.channel.invokeMethod("speak.onStart", arguments: nil) - } - - public func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didPause utterance: AVSpeechUtterance) { - self.channel.invokeMethod("speak.onPause", arguments: nil) - } - - public func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didContinue utterance: AVSpeechUtterance) { - self.channel.invokeMethod("speak.onContinue", arguments: nil) - } - - public func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didCancel utterance: AVSpeechUtterance) { - self.channel.invokeMethod("speak.onCancel", arguments: nil) - } - - public func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, willSpeakRangeOfSpeechString characterRange: NSRange, utterance: AVSpeechUtterance) { - let nsWord = utterance.speechString as NSString - let data: [String:String] = [ - "text": utterance.speechString, - "start": String(characterRange.location), - "end": String(characterRange.location + characterRange.length), - "word": nsWord.substring(with: characterRange) - ] - self.channel.invokeMethod("speak.onProgress", arguments: data) - } - -} diff --git a/flutter_tts-voice_enhancement/macos/flutter_tts.podspec b/flutter_tts-voice_enhancement/macos/flutter_tts.podspec deleted file mode 100644 index 2838eb07..00000000 --- a/flutter_tts-voice_enhancement/macos/flutter_tts.podspec +++ /dev/null @@ -1,22 +0,0 @@ -# -# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html -# -Pod::Spec.new do |s| - s.name = 'flutter_tts' - s.version = '0.0.1' - s.summary = 'macOS implementation of the flutter_tts plugin.' - s.description = <<-DESC - A flutter text to speech plugin - DESC - s.homepage = 'https://github.com/dlutton/flutter_tts' - s.license = { :file => '../LICENSE' } - s.author = { 'Daniel Lutton' => 'eyedea32@gmail.com' } - s.source = { :path => '.' } - s.source_files = 'Classes/**/*' - s.dependency 'FlutterMacOS' - - s.platform = :osx, '10.15' - s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' } - s.swift_version = '5.0' - - end \ No newline at end of file diff --git a/flutter_tts-voice_enhancement/pubspec.yaml b/flutter_tts-voice_enhancement/pubspec.yaml deleted file mode 100644 index 06e93f33..00000000 --- a/flutter_tts-voice_enhancement/pubspec.yaml +++ /dev/null @@ -1,28 +0,0 @@ -name: flutter_tts -description: A flutter plugin for Text to Speech. This plugin is supported on iOS, Android, Web, & macOS. -version: 1.3.0 -homepage: https://github.com/dlutton/flutter_tts - -dependencies: - flutter: - sdk: flutter - flutter_web_plugins: - sdk: flutter - -flutter: - plugin: - platforms: - android: - package: com.tundralabs.fluttertts - pluginClass: FlutterTtsPlugin - ios: - pluginClass: FlutterTtsPlugin - macos: - pluginClass: FlutterTtsPlugin - web: - pluginClass: FlutterTtsPlugin - fileName: flutter_tts_web.dart - -environment: - sdk: ">=2.1.0 <3.0.0" - flutter: ">=1.12.13+hotfix.5 <2.0.0" diff --git a/google-services.json b/google-services_DQ.json similarity index 100% rename from google-services.json rename to google-services_DQ.json diff --git a/google-services_HMG.json b/google-services_HMG.json new file mode 100644 index 00000000..5806fa5f --- /dev/null +++ b/google-services_HMG.json @@ -0,0 +1,47 @@ +{ + "project_info": { + "project_number": "815750722565", + "firebase_url": "https://api-project-815750722565.firebaseio.com", + "project_id": "api-project-815750722565", + "storage_bucket": "api-project-815750722565.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:815750722565:android:62281cd3e5df4063", + "android_client_info": { + "package_name": "com.ejada.hmg" + } + }, + "oauth_client": [ + { + "client_id": "815750722565-3a0gc7neins0eoahdrimrfksk0sqice8.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyDUfg6AKM1-00WyzpvLImUBC46wFrq9-qw" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "815750722565-3a0gc7neins0eoahdrimrfksk0sqice8.apps.googleusercontent.com", + "client_type": 3 + }, + { + "client_id": "815750722565-0cq9366orvsk5ipivq6lijcj56u03fr7.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "com.void.demo" + } + } + ] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/google-services_HMG_old.json b/google-services_HMG_old.json new file mode 100644 index 00000000..dd4038cf --- /dev/null +++ b/google-services_HMG_old.json @@ -0,0 +1,42 @@ +{ + "project_info": { + "project_number": "815750722565", + "firebase_url": "https://api-project-815750722565.firebaseio.com", + "project_id": "api-project-815750722565", + "storage_bucket": "api-project-815750722565.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:815750722565:android:62281cd3e5df4063", + "android_client_info": { + "package_name": "com.ejada.hmg" + } + }, + "oauth_client": [ + { + "client_id": "815750722565-3a0gc7neins0eoahdrimrfksk0sqice8.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyDUfg6AKM1-00WyzpvLImUBC46wFrq9-qw" + } + ], + "services": { + "analytics_service": { + "status": 1 + }, + "appinvite_service": { + "status": 1, + "other_platform_oauth_client": [] + }, + "ads_service": { + "status": 2 + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/google-services_old.json b/google-services_old.json new file mode 100644 index 00000000..5806fa5f --- /dev/null +++ b/google-services_old.json @@ -0,0 +1,47 @@ +{ + "project_info": { + "project_number": "815750722565", + "firebase_url": "https://api-project-815750722565.firebaseio.com", + "project_id": "api-project-815750722565", + "storage_bucket": "api-project-815750722565.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:815750722565:android:62281cd3e5df4063", + "android_client_info": { + "package_name": "com.ejada.hmg" + } + }, + "oauth_client": [ + { + "client_id": "815750722565-3a0gc7neins0eoahdrimrfksk0sqice8.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyDUfg6AKM1-00WyzpvLImUBC46wFrq9-qw" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "815750722565-3a0gc7neins0eoahdrimrfksk0sqice8.apps.googleusercontent.com", + "client_type": 3 + }, + { + "client_id": "815750722565-0cq9366orvsk5ipivq6lijcj56u03fr7.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "com.void.demo" + } + } + ] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/heartrate_icon.png b/heartrate_icon.png deleted file mode 100644 index e228bea4..00000000 Binary files a/heartrate_icon.png and /dev/null differ diff --git a/help/.gitignore b/help/.gitignore deleted file mode 100644 index 9d532b18..00000000 --- a/help/.gitignore +++ /dev/null @@ -1,41 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -**/ios/Flutter/.last_build_id -.dart_tool/ -.flutter-plugins -.flutter-plugins-dependencies -.packages -.pub-cache/ -.pub/ -/build/ - -# Web related -lib/generated_plugin_registrant.dart - -# Symbolication related -app.*.symbols - -# Obfuscation related -app.*.map.json diff --git a/help/.metadata b/help/.metadata deleted file mode 100644 index 107fcb7b..00000000 --- a/help/.metadata +++ /dev/null @@ -1,10 +0,0 @@ -# This file tracks properties of this Flutter project. -# Used by Flutter tool to assess capabilities and perform upgrades etc. -# -# This file should be version controlled and should not be manually edited. - -version: - revision: 8874f21e79d7ec66d0457c7ab338348e31b17f1d - channel: stable - -project_type: app diff --git a/help/README.md b/help/README.md deleted file mode 100644 index 4ac021c0..00000000 --- a/help/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# help - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. diff --git a/help/android/.gitignore b/help/android/.gitignore deleted file mode 100644 index 0a741cb4..00000000 --- a/help/android/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -gradle-wrapper.jar -/.gradle -/captures/ -/gradlew -/gradlew.bat -/local.properties -GeneratedPluginRegistrant.java - -# Remember to never publicly share your keystore. -# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app -key.properties diff --git a/help/android/app/build.gradle b/help/android/app/build.gradle deleted file mode 100644 index f44ed6c9..00000000 --- a/help/android/app/build.gradle +++ /dev/null @@ -1,63 +0,0 @@ -def localProperties = new Properties() -def localPropertiesFile = rootProject.file('local.properties') -if (localPropertiesFile.exists()) { - localPropertiesFile.withReader('UTF-8') { reader -> - localProperties.load(reader) - } -} - -def flutterRoot = localProperties.getProperty('flutter.sdk') -if (flutterRoot == null) { - throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") -} - -def flutterVersionCode = localProperties.getProperty('flutter.versionCode') -if (flutterVersionCode == null) { - flutterVersionCode = '1' -} - -def flutterVersionName = localProperties.getProperty('flutter.versionName') -if (flutterVersionName == null) { - flutterVersionName = '1.0' -} - -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' -apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" - -android { - compileSdkVersion 29 - - sourceSets { - main.java.srcDirs += 'src/main/kotlin' - } - - lintOptions { - disable 'InvalidPackage' - } - - defaultConfig { - // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). - applicationId "com.example.help" - minSdkVersion 16 - targetSdkVersion 29 - versionCode flutterVersionCode.toInteger() - versionName flutterVersionName - } - - buildTypes { - 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 - } - } -} - -flutter { - source '../..' -} - -dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" -} diff --git a/help/android/app/src/debug/AndroidManifest.xml b/help/android/app/src/debug/AndroidManifest.xml deleted file mode 100644 index fa2c5cd4..00000000 --- a/help/android/app/src/debug/AndroidManifest.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - diff --git a/help/android/app/src/main/AndroidManifest.xml b/help/android/app/src/main/AndroidManifest.xml deleted file mode 100644 index 125d6242..00000000 --- a/help/android/app/src/main/AndroidManifest.xml +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/help/android/app/src/main/kotlin/com/example/help/MainActivity.kt b/help/android/app/src/main/kotlin/com/example/help/MainActivity.kt deleted file mode 100644 index 75298a08..00000000 --- a/help/android/app/src/main/kotlin/com/example/help/MainActivity.kt +++ /dev/null @@ -1,6 +0,0 @@ -package com.example.help - -import io.flutter.embedding.android.FlutterActivity - -class MainActivity: FlutterActivity() { -} diff --git a/help/android/app/src/main/res/drawable/launch_background.xml b/help/android/app/src/main/res/drawable/launch_background.xml deleted file mode 100644 index 304732f8..00000000 --- a/help/android/app/src/main/res/drawable/launch_background.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - diff --git a/help/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/help/android/app/src/main/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index db77bb4b..00000000 Binary files a/help/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/help/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/help/android/app/src/main/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index 17987b79..00000000 Binary files a/help/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/help/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/help/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index 09d43914..00000000 Binary files a/help/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/help/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/help/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index d5f1c8d3..00000000 Binary files a/help/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/help/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/help/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index 4d6372ee..00000000 Binary files a/help/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/help/android/app/src/main/res/values/styles.xml b/help/android/app/src/main/res/values/styles.xml deleted file mode 100644 index 1f83a33f..00000000 --- a/help/android/app/src/main/res/values/styles.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - diff --git a/help/android/app/src/profile/AndroidManifest.xml b/help/android/app/src/profile/AndroidManifest.xml deleted file mode 100644 index fa2c5cd4..00000000 --- a/help/android/app/src/profile/AndroidManifest.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - diff --git a/help/android/build.gradle b/help/android/build.gradle deleted file mode 100644 index 3100ad2d..00000000 --- a/help/android/build.gradle +++ /dev/null @@ -1,31 +0,0 @@ -buildscript { - ext.kotlin_version = '1.3.50' - repositories { - google() - jcenter() - } - - dependencies { - classpath 'com.android.tools.build:gradle:3.5.0' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - } -} - -allprojects { - repositories { - google() - jcenter() - } -} - -rootProject.buildDir = '../build' -subprojects { - project.buildDir = "${rootProject.buildDir}/${project.name}" -} -subprojects { - project.evaluationDependsOn(':app') -} - -task clean(type: Delete) { - delete rootProject.buildDir -} diff --git a/help/android/gradle.properties b/help/android/gradle.properties deleted file mode 100644 index 94adc3a3..00000000 --- a/help/android/gradle.properties +++ /dev/null @@ -1,3 +0,0 @@ -org.gradle.jvmargs=-Xmx1536M -android.useAndroidX=true -android.enableJetifier=true diff --git a/help/android/gradle/wrapper/gradle-wrapper.properties b/help/android/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 296b146b..00000000 --- a/help/android/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Fri Jun 23 08:50:38 CEST 2017 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip diff --git a/help/android/settings.gradle b/help/android/settings.gradle deleted file mode 100644 index 44e62bcf..00000000 --- a/help/android/settings.gradle +++ /dev/null @@ -1,11 +0,0 @@ -include ':app' - -def localPropertiesFile = new File(rootProject.projectDir, "local.properties") -def properties = new Properties() - -assert localPropertiesFile.exists() -localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } - -def flutterSdkPath = properties.getProperty("flutter.sdk") -assert flutterSdkPath != null, "flutter.sdk not set in local.properties" -apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" diff --git a/help/ios/.gitignore b/help/ios/.gitignore deleted file mode 100644 index e96ef602..00000000 --- a/help/ios/.gitignore +++ /dev/null @@ -1,32 +0,0 @@ -*.mode1v3 -*.mode2v3 -*.moved-aside -*.pbxuser -*.perspectivev3 -**/*sync/ -.sconsign.dblite -.tags* -**/.vagrant/ -**/DerivedData/ -Icon? -**/Pods/ -**/.symlinks/ -profile -xcuserdata -**/.generated/ -Flutter/App.framework -Flutter/Flutter.framework -Flutter/Flutter.podspec -Flutter/Generated.xcconfig -Flutter/app.flx -Flutter/app.zip -Flutter/flutter_assets/ -Flutter/flutter_export_environment.sh -ServiceDefinitions.json -Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!default.mode1v3 -!default.mode2v3 -!default.pbxuser -!default.perspectivev3 diff --git a/help/ios/Flutter/AppFrameworkInfo.plist b/help/ios/Flutter/AppFrameworkInfo.plist deleted file mode 100644 index f2872cf4..00000000 --- a/help/ios/Flutter/AppFrameworkInfo.plist +++ /dev/null @@ -1,26 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - App - CFBundleIdentifier - io.flutter.flutter.app - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - App - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1.0 - MinimumOSVersion - 9.0 - - diff --git a/help/ios/Flutter/Debug.xcconfig b/help/ios/Flutter/Debug.xcconfig deleted file mode 100644 index 592ceee8..00000000 --- a/help/ios/Flutter/Debug.xcconfig +++ /dev/null @@ -1 +0,0 @@ -#include "Generated.xcconfig" diff --git a/help/ios/Flutter/Release.xcconfig b/help/ios/Flutter/Release.xcconfig deleted file mode 100644 index 592ceee8..00000000 --- a/help/ios/Flutter/Release.xcconfig +++ /dev/null @@ -1 +0,0 @@ -#include "Generated.xcconfig" diff --git a/help/ios/Runner.xcodeproj/project.pbxproj b/help/ios/Runner.xcodeproj/project.pbxproj deleted file mode 100644 index 4f158fea..00000000 --- a/help/ios/Runner.xcodeproj/project.pbxproj +++ /dev/null @@ -1,495 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; - 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; - 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; - 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; - 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; -/* End PBXBuildFile section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 9705A1C41CF9048500538489 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* 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 = ""; }; - 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 = ""; }; - 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; - 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; - 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; - 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; - 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 97C146EB1CF9000F007C117D /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 9740EEB11CF90186004384FC /* Flutter */ = { - isa = PBXGroup; - children = ( - 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, - 9740EEB21CF90195004384FC /* Debug.xcconfig */, - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, - 9740EEB31CF90195004384FC /* Generated.xcconfig */, - ); - name = Flutter; - sourceTree = ""; - }; - 97C146E51CF9000F007C117D = { - isa = PBXGroup; - children = ( - 9740EEB11CF90186004384FC /* Flutter */, - 97C146F01CF9000F007C117D /* Runner */, - 97C146EF1CF9000F007C117D /* Products */, - ); - sourceTree = ""; - }; - 97C146EF1CF9000F007C117D /* Products */ = { - isa = PBXGroup; - children = ( - 97C146EE1CF9000F007C117D /* Runner.app */, - ); - name = Products; - sourceTree = ""; - }; - 97C146F01CF9000F007C117D /* Runner */ = { - isa = PBXGroup; - children = ( - 97C146FA1CF9000F007C117D /* Main.storyboard */, - 97C146FD1CF9000F007C117D /* Assets.xcassets */, - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, - 97C147021CF9000F007C117D /* Info.plist */, - 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, - 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, - 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, - 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, - ); - path = Runner; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 97C146ED1CF9000F007C117D /* Runner */ = { - isa = PBXNativeTarget; - buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; - buildPhases = ( - 9740EEB61CF901F6004384FC /* Run Script */, - 97C146EA1CF9000F007C117D /* Sources */, - 97C146EB1CF9000F007C117D /* Frameworks */, - 97C146EC1CF9000F007C117D /* Resources */, - 9705A1C41CF9048500538489 /* Embed Frameworks */, - 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = Runner; - productName = Runner; - productReference = 97C146EE1CF9000F007C117D /* Runner.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 97C146E61CF9000F007C117D /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 1020; - ORGANIZATIONNAME = ""; - TargetAttributes = { - 97C146ED1CF9000F007C117D = { - CreatedOnToolsVersion = 7.3.1; - LastSwiftMigration = 1100; - }; - }; - }; - buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; - compatibilityVersion = "Xcode 9.3"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 97C146E51CF9000F007C117D; - productRefGroup = 97C146EF1CF9000F007C117D /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 97C146ED1CF9000F007C117D /* Runner */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 97C146EC1CF9000F007C117D /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, - 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, - 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, - 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Thin Binary"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; - }; - 9740EEB61CF901F6004384FC /* Run Script */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Run Script"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 97C146EA1CF9000F007C117D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, - 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 97C146FA1CF9000F007C117D /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C146FB1CF9000F007C117D /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C147001CF9000F007C117D /* Base */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 249021D3217E4FDB00AE95B9 /* Profile */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - SUPPORTED_PLATFORMS = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Profile; - }; - 249021D4217E4FDB00AE95B9 /* Profile */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.help; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; - SWIFT_VERSION = 5.0; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Profile; - }; - 97C147031CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 97C147041CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - SUPPORTED_PLATFORMS = iphoneos; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 97C147061CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.help; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Debug; - }; - 97C147071CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.help; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; - SWIFT_VERSION = 5.0; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147031CF9000F007C117D /* Debug */, - 97C147041CF9000F007C117D /* Release */, - 249021D3217E4FDB00AE95B9 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147061CF9000F007C117D /* Debug */, - 97C147071CF9000F007C117D /* Release */, - 249021D4217E4FDB00AE95B9 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 97C146E61CF9000F007C117D /* Project object */; -} diff --git a/help/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/help/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 1d526a16..00000000 --- a/help/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/help/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/help/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d98100..00000000 --- a/help/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/help/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/help/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings deleted file mode 100644 index f9b0d7c5..00000000 --- a/help/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ /dev/null @@ -1,8 +0,0 @@ - - - - - PreviewsEnabled - - - diff --git a/help/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/help/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme deleted file mode 100644 index a28140cf..00000000 --- a/help/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ /dev/null @@ -1,91 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/help/ios/Runner.xcworkspace/contents.xcworkspacedata b/help/ios/Runner.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 1d526a16..00000000 --- a/help/ios/Runner.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/help/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/help/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d98100..00000000 --- a/help/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/help/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/help/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings deleted file mode 100644 index f9b0d7c5..00000000 --- a/help/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ /dev/null @@ -1,8 +0,0 @@ - - - - - PreviewsEnabled - - - diff --git a/help/ios/Runner/AppDelegate.swift b/help/ios/Runner/AppDelegate.swift deleted file mode 100644 index 70693e4a..00000000 --- a/help/ios/Runner/AppDelegate.swift +++ /dev/null @@ -1,13 +0,0 @@ -import UIKit -import Flutter - -@UIApplicationMain -@objc class AppDelegate: FlutterAppDelegate { - override func application( - _ application: UIApplication, - didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? - ) -> Bool { - GeneratedPluginRegistrant.register(with: self) - return super.application(application, didFinishLaunchingWithOptions: launchOptions) - } -} diff --git a/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index d36b1fab..00000000 --- a/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,122 +0,0 @@ -{ - "images" : [ - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@3x.png", - "scale" : "3x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@3x.png", - "scale" : "3x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@3x.png", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@2x.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@3x.png", - "scale" : "3x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@1x.png", - "scale" : "1x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@1x.png", - "scale" : "1x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@1x.png", - "scale" : "1x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@2x.png", - "scale" : "2x" - }, - { - "size" : "83.5x83.5", - "idiom" : "ipad", - "filename" : "Icon-App-83.5x83.5@2x.png", - "scale" : "2x" - }, - { - "size" : "1024x1024", - "idiom" : "ios-marketing", - "filename" : "Icon-App-1024x1024@1x.png", - "scale" : "1x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} diff --git a/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png deleted file mode 100644 index dc9ada47..00000000 Binary files a/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png and /dev/null differ diff --git a/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png deleted file mode 100644 index 28c6bf03..00000000 Binary files a/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png and /dev/null differ diff --git a/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png deleted file mode 100644 index 2ccbfd96..00000000 Binary files a/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png and /dev/null differ diff --git a/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png deleted file mode 100644 index f091b6b0..00000000 Binary files a/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png and /dev/null differ diff --git a/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png deleted file mode 100644 index 4cde1211..00000000 Binary files a/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png and /dev/null differ diff --git a/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png deleted file mode 100644 index d0ef06e7..00000000 Binary files a/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png and /dev/null differ diff --git a/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png deleted file mode 100644 index dcdc2306..00000000 Binary files a/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png and /dev/null differ diff --git a/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png deleted file mode 100644 index 2ccbfd96..00000000 Binary files a/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png and /dev/null differ diff --git a/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png deleted file mode 100644 index c8f9ed8f..00000000 Binary files a/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png and /dev/null differ diff --git a/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png deleted file mode 100644 index a6d6b860..00000000 Binary files a/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png and /dev/null differ diff --git a/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png deleted file mode 100644 index a6d6b860..00000000 Binary files a/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png and /dev/null differ diff --git a/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png deleted file mode 100644 index 75b2d164..00000000 Binary files a/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png and /dev/null differ diff --git a/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png deleted file mode 100644 index c4df70d3..00000000 Binary files a/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png and /dev/null differ diff --git a/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png deleted file mode 100644 index 6a84f41e..00000000 Binary files a/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png and /dev/null differ diff --git a/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png deleted file mode 100644 index d0e1f585..00000000 Binary files a/help/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png and /dev/null differ diff --git a/help/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/help/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json deleted file mode 100644 index 0bedcf2f..00000000 --- a/help/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "filename" : "LaunchImage.png", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "LaunchImage@2x.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "filename" : "LaunchImage@3x.png", - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} diff --git a/help/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/help/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png deleted file mode 100644 index 9da19eac..00000000 Binary files a/help/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png and /dev/null differ diff --git a/help/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/help/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png deleted file mode 100644 index 9da19eac..00000000 Binary files a/help/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png and /dev/null differ diff --git a/help/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/help/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png deleted file mode 100644 index 9da19eac..00000000 Binary files a/help/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png and /dev/null differ diff --git a/help/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/help/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md deleted file mode 100644 index 89c2725b..00000000 --- a/help/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Launch Screen Assets - -You can customize the launch screen with your own desired assets by replacing the image files in this directory. - -You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/help/ios/Runner/Base.lproj/LaunchScreen.storyboard b/help/ios/Runner/Base.lproj/LaunchScreen.storyboard deleted file mode 100644 index f2e259c7..00000000 --- a/help/ios/Runner/Base.lproj/LaunchScreen.storyboard +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/help/ios/Runner/Base.lproj/Main.storyboard b/help/ios/Runner/Base.lproj/Main.storyboard deleted file mode 100644 index f3c28516..00000000 --- a/help/ios/Runner/Base.lproj/Main.storyboard +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/help/ios/Runner/Info.plist b/help/ios/Runner/Info.plist deleted file mode 100644 index 71ce57cb..00000000 --- a/help/ios/Runner/Info.plist +++ /dev/null @@ -1,48 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - help - CFBundlePackageType - APPL - CFBundleShortVersionString - $(FLUTTER_BUILD_NAME) - CFBundleSignature - ???? - CFBundleVersion - $(FLUTTER_BUILD_NUMBER) - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UIViewControllerBasedStatusBarAppearance - - - < key >NSCameraUsageDescription< /key > - < string >Camera permission is required for barcode scanning.< /string > - - diff --git a/help/ios/Runner/Runner-Bridging-Header.h b/help/ios/Runner/Runner-Bridging-Header.h deleted file mode 100644 index 308a2a56..00000000 --- a/help/ios/Runner/Runner-Bridging-Header.h +++ /dev/null @@ -1 +0,0 @@ -#import "GeneratedPluginRegistrant.h" diff --git a/help/lib/main.dart b/help/lib/main.dart deleted file mode 100644 index 11655b66..00000000 --- a/help/lib/main.dart +++ /dev/null @@ -1,117 +0,0 @@ -import 'package:flutter/material.dart'; - -void main() { - runApp(MyApp()); -} - -class MyApp extends StatelessWidget { - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - // This is the theme of your application. - // - // Try running your application with "flutter run". You'll see the - // application has a blue toolbar. Then, without quitting the app, try - // changing the primarySwatch below to Colors.green and then invoke - // "hot reload" (press "r" in the console where you ran "flutter run", - // or simply save your changes to "hot reload" in a Flutter IDE). - // Notice that the counter didn't reset back to zero; the application - // is not restarted. - primarySwatch: Colors.blue, - // This makes the visual density adapt to the platform that you run - // the app on. For desktop platforms, the controls will be smaller and - // closer together (more dense) than on mobile platforms. - visualDensity: VisualDensity.adaptivePlatformDensity, - ), - home: MyHomePage(title: 'Flutter Demo Home Page'), - ); - } -} - -class MyHomePage extends StatefulWidget { - MyHomePage({Key key, this.title}) : super(key: key); - - // This widget is the home page of your application. It is stateful, meaning - // that it has a State object (defined below) that contains fields that affect - // how it looks. - - // This class is the configuration for the state. It holds the values (in this - // case the title) provided by the parent (in this case the App widget) and - // used by the build method of the State. Fields in a Widget subclass are - // always marked "final". - - final String title; - - @override - _MyHomePageState createState() => _MyHomePageState(); -} - -class _MyHomePageState extends State { - int _counter = 0; - - void _incrementCounter() { - setState(() { - // This call to setState tells the Flutter framework that something has - // changed in this State, which causes it to rerun the build method below - // so that the display can reflect the updated values. If we changed - // _counter without calling setState(), then the build method would not be - // called again, and so nothing would appear to happen. - _counter++; - }); - } - - @override - Widget build(BuildContext context) { - // This method is rerun every time setState is called, for instance as done - // by the _incrementCounter method above. - // - // The Flutter framework has been optimized to make rerunning build methods - // fast, so that you can just rebuild anything that needs updating rather - // than having to individually change instances of widgets. - return Scaffold( - appBar: AppBar( - // Here we take the value from the MyHomePage object that was created by - // the App.build method, and use it to set our appbar title. - title: Text(widget.title), - ), - body: Center( - // Center is a layout widget. It takes a single child and positions it - // in the middle of the parent. - child: Column( - // Column is also a layout widget. It takes a list of children and - // arranges them vertically. By default, it sizes itself to fit its - // children horizontally, and tries to be as tall as its parent. - // - // Invoke "debug painting" (press "p" in the console, choose the - // "Toggle Debug Paint" action from the Flutter Inspector in Android - // Studio, or the "Toggle Debug Paint" command in Visual Studio Code) - // to see the wireframe for each widget. - // - // Column has various properties to control how it sizes itself and - // how it positions its children. Here we use mainAxisAlignment to - // center the children vertically; the main axis here is the vertical - // axis because Columns are vertical (the cross axis would be - // horizontal). - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - 'You have pushed the button this many times:', - ), - Text( - '$_counter', - style: Theme.of(context).textTheme.headline4, - ), - ], - ), - ), - floatingActionButton: FloatingActionButton( - onPressed: _incrementCounter, - tooltip: 'Increment', - child: Icon(Icons.add), - ), // This trailing comma makes auto-formatting nicer for build methods. - ); - } -} diff --git a/help/pubspec.yaml b/help/pubspec.yaml deleted file mode 100644 index 66af3d9e..00000000 --- a/help/pubspec.yaml +++ /dev/null @@ -1,76 +0,0 @@ -name: help -description: A new Flutter project. - -# The following line prevents the package from being accidentally published to -# pub.dev using `pub publish`. This is preferred for private packages. -publish_to: 'none' # Remove this line if you wish to publish to pub.dev - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.7.0 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^1.0.0 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/help/test/widget_test.dart b/help/test/widget_test.dart deleted file mode 100644 index 9ca1523f..00000000 --- a/help/test/widget_test.dart +++ /dev/null @@ -1,32 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import '../lib/main.dart'; - - - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/hms-plugins/flutter-hms-location/.docs/images/homeScreen.jpg b/hms-plugins/flutter-hms-location/.docs/images/homeScreen.jpg deleted file mode 100644 index abfc5b99..00000000 Binary files a/hms-plugins/flutter-hms-location/.docs/images/homeScreen.jpg and /dev/null differ diff --git a/hms-plugins/flutter-hms-location/CHANGELOG.md b/hms-plugins/flutter-hms-location/CHANGELOG.md deleted file mode 100644 index 8c43b7b8..00000000 --- a/hms-plugins/flutter-hms-location/CHANGELOG.md +++ /dev/null @@ -1,12 +0,0 @@ -## 5.0.0+301 - -* Added the getNavigationContextState function. -* Added the enableLogger and disableLogger methods. - -## 4.0.4+1/4.0.4+300 - -* Fix minor issues. - -## 4.0.4 - -* Initial release. diff --git a/hms-plugins/flutter-hms-location/LICENSE b/hms-plugins/flutter-hms-location/LICENSE deleted file mode 100644 index 7783de53..00000000 --- a/hms-plugins/flutter-hms-location/LICENSE +++ /dev/null @@ -1,53 +0,0 @@ -Apache License - -Version 2.0, January 2004 - -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - -"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. - -"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. - -"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. - -"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. - -"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. - -"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: - -You must give any other recipients of the Work or Derivative Works a copy of this License; and -You must cause any modified files to carry prominent notices stating that You changed the files; and -You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and -If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. - -You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. -5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS diff --git a/hms-plugins/flutter-hms-location/README.md b/hms-plugins/flutter-hms-location/README.md deleted file mode 100644 index cb69c34a..00000000 --- a/hms-plugins/flutter-hms-location/README.md +++ /dev/null @@ -1,1737 +0,0 @@ -# Huawei Location Kit Flutter Plugin - -## Table of Contents -* [Introduction](#introduction) -* [Installation Guide](#installation-guide) - * [Creating Project in App Gallery Connect](#creating-project-in-app-gallery-connect) - * [Configuring the Signing Certificate Fingerprint](#configuring-the-signing-certificate-fingerprint) - * [Integrating the Flutter Location Plugin](#integrating-the-flutter-location-plugin) -* [API Reference](#api-reference) - * [Overview](#overview) - * [FusedLocationProviderClient](#fusedlocationproviderclient) - * [Location](#location) - * [HWLocation](#hwlocation) - * [LocationAvailability](#locationavailability) - * [LocationCallback](#locationcallback) - * [LocationRequest](#locationrequest) - * [LocationResult](#locationresult) - * [LocationSettingsRequest](#locationsettingsrequest) - * [LocationSettingsStates](#locationsettingsstates) - * [NavigationResult](#navigationresult) - * [NavigationRequest](#navigationrequest) - * [ActivityIdentificationService](#activityidentificationservice) - * [ActivityConversionData](#activityconversiondata) - * [ActivityConversionInfo](#activityconversioninfo) - * [ActivityConversionResponse](#activityconversionresponse) - * [ActivityIdentificationData](#activityidentificationdata) - * [ActivityIdentificationResponse](#activityidentificationresponse) - * [Geofence Service](#geofence-service) - * [GeofenceData](#geofencedata) - * [GeofenceRequest](#geofencerequest) - * [PermissionHandler](#permissionhandler) - * [HMSLogger](#hmslogger) - -* [Configuration Description](#configuration-description) -* [Sample Project](#sample-project) -* [Questions or Issues](#questions-or-issues) -* [Licensing and Terms](#licensing-and-terms) - -## Introduction - -This plugin enables communication between Huawei Location SDK and Flutter platform. Huawei Location Kit combines the GPS, Wi-Fi, and base station locations to help you quickly obtain precise user locations, build up global positioning capabilities, and reach a wide range of users around the globe.Currently, it provides the four main capabilities: fused location, location semantics, activity identification, and geofence. You can call relevant capabilities as needed. - -Huawei Location Kit provides the following core capabilities: -- **Fused location**: Provides a set of simple and easy-to-use APIs for you to quickly obtain the device location based on the GPS, Wi-Fi, and base station location data. -- **Activity identification**: Identifies user motion status through the acceleration sensor, cellular network information, and magnetometer, helping you adjust your app based on user behavior. -- **Geofence**: Allows you to set an interested area through an API so that your app can receive a notification when a specified action (such as leaving, entering, or lingering in the area) occurs. - -## Installation Guide - -- Before you get started, you must register as a HUAWEI developer and complete identity verification on the [HUAWEI Developer](https://developer.huawei.com/consumer/en/) website. For details, please refer to [Register a HUAWEI ID](https://developer.huawei.com/consumer/en/doc/10104). - -- Create an app in your project is required in AppGallery Connect in order to communicate with Huawei services. To create an app, perform the following steps: - -### Creating Project in App Gallery Connect - -**Step 1.** Sign in to [AppGallery Connect](https://developer.huawei.com/consumer/en) and select My projects. - -**Step 2.** Click your project from the project list. - -**Step 3.** Go to **Project Setting** > **General information**, and click **Add app**. -If an app exists in the project, and you need to add a new one, expand the app selection area on the top of the page and click **Add app**. - -**Step 4.** On the **Add app** page, enter app information, and click **OK**. - -- A signing certificate fingerprint is used to verify the authenticity of an app when it attempts to access an HMS Core service through the HMS Core SDK. Before using HMS Core (APK), you must locally generate a signing certificate fingerprint and configure it in AppGallery Connect. Ensure that the JDK has been installed on your computer. - -### Configuring the Signing Certificate Fingerprint -**Step 1:** Go to **Project Setting** > **General information**. In the **App information** field, click the icon next to SHA-256 certificate fingerprint, and enter the obtained **SHA256 certificate fingerprint**. - -**Step 2:** After completing the configuration, click **OK**. (Check mark icon) - -### Integrating Flutter Location Plugin - -**Step 1:** Sign in [AppGallery Connect](https://developer.huawei.com/consumer/en/service/josp/agc/index.html) to AppGallery Connect and select **My projects**. - -**Step 2:** Find your app project, and click the desired app name. - -**Step 3:** Go to **Project Setting > > General information**. In the **App information** field, click **agconnect-service.json** to download configuration file. - -**Step 4:** Create a Flutter project if you do not have one. - -**Step 5:** Copy the **agconnect-service.json** file to the **android/app** directory of your Flutter project. - -**Step 6:** Copy the signature file that is generated in **Generating a Signature File** to the android/app directory of your Flutter project. - -**Step 7:** Check whether the **agconnect-services.json** file and signature file are successfully added to the **android/app** directory of the Flutter project. - - - -**Step 8:** Open the **build.gradle** file in the **android** directory of your Flutter project. - - Go to **buildscript** then configure the Maven repository address and agconnect plugin for the HMS SDK. - - ```gradle - buildscript { - repositories { - google() - jcenter() - maven { url 'https://developer.huawei.com/repo/' } - } - - dependencies { - /* - * - */ - classpath 'com.huawei.agconnect:agcp:1.4.1.300' - } - } - ``` - - - Go to **allprojects** then configure the Maven repository address for the HMS SDK. - - ```gradle - allprojects { - repositories { - google() - jcenter() - maven { url 'https://developer.huawei.com/repo/' } - } - } - ``` - -**Step 9:** Open the **build.gradle** file in the **android/app** directory. -- Add `apply plugin: 'com.huawei.agconnect'` line after other `apply` entries. - - ```gradle - apply plugin: 'com.android.application' - apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" - apply plugin: 'com.huawei.agconnect' - ``` - - - Set your package name in **defaultConfig** > **applicationId** and set **minSdkVersion** to **19** or **higher**. - Package name must match with the **package_name** entry in **agconnect-services.json** file. - - ```gradle - defaultConfig { - applicationId "" - minSdkVersion 17 - /* - * - */ - } - ``` - - Copy the signature file that generated in [Generating a Signing Certificate](https://developer.huawei.com/consumer/en/codelab/HMSPreparation/index.html#3) to **android/app** directory. - - - Configure the signature in **android** according to the signature file information. - -```gradle -signingConfigs { - config { - keyAlias keystoreProperties['keyAlias'] - keyPassword keystoreProperties['keyPassword'] - storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null - storePassword keystoreProperties['storePassword'] - } -} -buildTypes { - debug { - signingConfig signingConfigs.config - } - release { - signingConfig signingConfigs.config - } -} -``` - -**Step 10:** On your Flutter project directory find and open your **pubspec.yaml** file and add library to dependencies. For more details please refer the [Using packages](https://flutter.dev/docs/development/packages-and-plugins/using-packages#dependencies-on-unpublished-packages) document. - - ```yaml - dependencies: - huawei_location: - # Replace {library path} with actual library path of Huawei Push Kit Location for Flutter. - path: {library path} - ``` - --**Step 11:** Run following command to update package info. - -``` -[project_path]> flutter pub get -``` - -**Step 12:** Run following command to start the app. - -``` -[project_path]> flutter run -``` - -## API Reference - -### Overview - -| Module | Description | -|----------------------------------|------------------------------------------------------------------------------------------------| -| FusedLocationProviderClient | With this module you can check the device location settings, get the last known location information once or continuously, set mock location and others. | -| ActivityIdentificationService | If your app needs to obtain the activity status of the user's device (for example, walking, running, or bicycling) or your app needs to detect activity status change of a user, you can use this module. | -| GeofenceService | If you are interested in a place, you can create a geofence based on the place. When the device enters the geofence or stays for a duration of time, a notification can be sent to your app. | - -### FusedLocationProviderClient - -#### Public Constructor Summary - -| Constructor | Description | -|----------------------------------|------------------------------------------------------------------------------------------------ -| FusedLocationProviderClient() | Default constructor. | - -#### Public Method Summary - -| Method | Return Type | Description | -|------------------------------------------------------------------------------------------------|-----------------------------------|-------------| -| checkLocationSettings(LocationSettingsRequest locationSettingsRequest) | Future\ | This API is used to check location settings of the device. | -| getLastLocation() | Future\ | This API is used to obtain the last requested available location. This API does not proactively request the location. Instead, it uses the location cached for the last request. | -| getLastLocationWithAddress(LocationRequest locationRequest) | Future\ | This API is used to obtain the available location of the last request, including the detailed address information. | -| getLocationAvailability() | Future\ | This API is used to check whether the location data is available. | -| setMockMode(bool mockMode) | Future\ | This API is used to specify whether the location provider uses the location mock mode. If yes, the GPS or network location is not used and the location set through setMockLocation (Location) is directly returned. | -| setMockLocation(Location location) | Future\ | This API is used to set the specific mock location. You must call the setMockMode(boolean) method and set the flag to true before calling this method. | -| requestLocationUpdates(LocationRequest locationRequest) | Future\ | This API is used to continuously request location updates. | -| requestLocationUpdatesCb(LocationRequest locationRequest, LocationCallback locationCallback) | Future\ | This API is used to request location updates using the callback. | -| requestLocationUpdatesExCb(LocationRequest locationRequest, LocationCallback locationCallback) | Future\ | This API is an extended location information service API. It supports high-precision location and is compatible with common location APIs. If the device does not support high-precision location or the app does not request the high-precision location permission, this API returns common location information similar to that returned by the requestLocationUpdates API. | -| removeLocationUpdates(int requestCode) | Future\ | This API is used to remove location updates from the specified requestCode. | -| removeLocationUpdatesCb(int callbackId) | Future\ | This API is used to remove location updates of the specified callbackId. | -| onLocationData | Future\Location\> | This API is used to listen location updates that comes from requestLocationUpdates API method. | -| getNavigationContextState(int type) | Future\ | Obtains the requested navigation type. | - -#### Public Constructors - -##### FusedLocationProviderClient() - -Constructor for *FusedLocationProviderClient* object. - -#### Public Methods - -##### Future\ checkLocationSettings(LocationSettingsRequest locationSettingsRequest) *async* - -Checks location settings of the device. - -| Parameter | Description | -|-------------------------|-------------| -| locationSettingsRequest | Location setting request object. | - -| Return Type | Description | -|----------------------------------|-------------| -| Future\ | LocationSettingsStates object if the operation is successful; PlatformException otherwise. | - -##### Future\ getLastLocation() *async* - -Obtains the available location of the last request. Instead of proactively requesting a location, this method uses the location cached during the last request. - -The value null may be returned in the following scenarios: -- The location function has never been used. -- The location function is disabled. -- The device is restored to factory settings. - -If real-time location is required, you are advised to proactively call requestLocationUpdates instead of this method. To receive a location once only, you can set numUpdates in LocationRequest to 1. - -| Return Type | Description | -|----------------------------------|-------------| -| Future\ | Location object if the operation is successful; PlatformException otherwise. | - -##### Future\ getLastLocationWithAddress(LocationRequest locationRequest) *async* - -Obtains the available location of the last request, including the detailed address information. If no location is available, null is returned. - -| Parameter | Description | -|-------------------------|-------------| -| locationRequest | Location request object. | - -| Return Type | Description | -|----------------------------------|-------------| -| Future\ | HWLocation object if the operation is successful; PlatformException otherwise. | - -##### Future\ getLocationAvailability() *async* - -Checks whether the location data is available. - -| Return Type | Description | -|----------------------------------|-------------| -| Future\ | LocationAvailability object if the operation is successful; PlatformException otherwise. | - -##### Future\ setMockMode(bool mockMode) *async* - -Sets whether the location provider uses the mock mode. If yes, the GPS or network location is not used and the location set through setMockLocation is directly returned. - -| Parameter | Description | -|-------------------------|-------------| -| mockMode | Indicates whether the location provider uses the mock mode. true: yes; false: no. | - -| Return Type | Description | -|----------------------------------|-------------| -| Future\ | No return value if the operation is successful; PlatformException otherwise. | - -##### Future\ setMockLocation(Location location) *async* - -Sets whether the location provider uses the mock mode. If yes, the GPS or network location is not used and the location set through setMockLocation is directly returned. - -| Parameter | Description | -|-------------------------|-------------| -| location | Mock location. | - -| Return Type | Description | -|----------------------------------|-------------| -| Future\ | No return value if the operation is successful; PlatformException otherwise. | - -##### Future\ requestLocationUpdates(LocationRequest locationRequest) *async* - -Continuously requests location updates. You can call the onLocationData API method to listen for location updates. - -| Parameter | Description | -|-------------------------|-------------| -| locationRequest | Location update request. | - -| Return Type | Description | -|----------------------------------|-------------| -| Future\ | Request code if the operation is successful; PlatformException otherwise. The request code can be used to call the removeLocationUpdates method. | - -##### Future\ requestLocationUpdatesCb(LocationRequest locationRequest, LocationCallback locationCallback) *async* - -Requests location updates using the callback. - -| Parameter | Description | -|-------------------------|-------------| -| locationRequest | Location update request. | -| locationCallback | Location update callback.| - -| Return Type | Description | -|----------------------------------|-------------| -| Future\ | Callback ID if the operation is successful; PlatformException otherwise. The callback ID can be used to call the removeLocationUpdatesCb method. | - -##### Future\ requestLocationUpdatesExCb(LocationRequest locationRequest, LocationCallback locationCallback) *async* - -Continuously requests location updates. This method is an extended location information service API. It supports high-precision location and is compatible with common location APIs. If the device does not support high-precision location or the app does not request the high-precision location, this method returns common location information similar to that returned by the requestLocationUpdatesCb method. - -| Parameter | Description | -|-------------------------|-------------| -| locationRequest | Location update request. | -| locationCallback | Location update callback.| - -| Return Type | Description | -|----------------------------------|-------------| -| Future\ | Callback ID if the operation is successful; PlatformException otherwise. The callback ID can be used to call the removeLocationUpdatesCb method. | - -##### Future\ removeLocationUpdates(int requestCode) *async* - -Removes location updates based on the specified request code. - -| Parameter | Description | -|-------------------------|-------------| -| requestCode | Request code returned by the requestLocationUpdates method. | - -| Return Type | Description | -|----------------------------------|-------------| -| Future\ | No return value if the operation is successful; PlatformException otherwise. | - -##### Future\ removeLocationUpdatesCb(int callbackId) *async* - -Removes location updates based on the specified callback ID. - -| Parameter | Description | -|-------------------------|-------------| -| callbackId | Callback ID returned by the requestLocationUpdatesCb or requestLocationUpdatesExCb method. | - -| Return Type | Description | -|----------------------------------|-------------| -| Future\ | No return value if the operation is successful; PlatformException otherwise. | - -##### Stream\ onLocationData - -Listens for location updates that come from the requestLocationUpdates method. - -| Return Type | Description | -|----------------------------------|-------------| -| Stream\ | Stream of Location object. You can call the .listen() method to subscribe to this stream and listen for updates. | - -##### Future\ getNavigationContextState(int type) *async* - -Removes location updates based on the specified callback ID. - -| Parameter | Description | -|-------------------------|-------------| -| type | Requested navigation type. | - -| Return Type | Description | -|----------------------------------|-------------| -| Future\ | NavigationResult object if the operation is successful; PlatformException otherwise. | - -### Location - -#### Public Properties - -| Properties | Type | Description | -|------------------------------|--------|-------------------------------------------------------------------------------------------------------------------------| -| provider | String | Location provider, such as network location, GPS, Wi-Fi, and Bluetooth. | -| latitude | double | Latitude of a location. If no latitude is available, 0.0 is returned. | -| longitude | double | Longitude of a location. If no longitude is available, 0.0 is returned. | -| altitude | double | Altitude of a location. If no altitude is available, 0.0 is returned. | -| speed | double | Speed of a device at the current location, in meters per second. If no speed is available, 0.0 is returned. | -| bearing | double | Bearing of a device at the current location, in degrees. If no bearing is available, 0.0 is returned. | -| horizontalAccuracyMeters | double | Horizontal error of a location, in meters. If no horizontal error is available, 0.0 is returned. | -| verticalAccuracyMeters | double | Vertical error of a location, in meters. If no vertical error is available, 0.0 is returned. | -| speedAccuracyMetersPerSecond | double | Speed error of a device at the current location, in meters per second. If no speed error is available, 0.0 is returned. | -| bearingAccuracyDegrees | double | Bearing error of the current location, in degrees. If no bearing error is available, 0.0 is returned. | -| time | int | Current timestamp, in milliseconds. | -| elapsedRealtimeNanos | int | Time elapsed since the system was started, in nanoseconds | - -#### Public Constructor Summary - -| Constructor | Description | -|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------| -| Location({String provider, double latitude, double longitude, double altitude, double speed, double bearing, double horizontalAccuracyMeters, double verticalAccuracyMeters, double speedAccuracyMetersPerSecond, double bearingAccuracyDegrees, int time, int elapsedRealtimeNanos}) | Default constructor. | -| Location.fromMap(Map\ map) | Creates a Location object from a map. | -| Location.fromJson(String source) | Creates a Location object from a JSON string. | - -#### Public Constructors - -##### Location({String provider, double latitude, double longitude, double altitude, double speed, double bearing, double horizontalAccuracyMeters, double verticalAccuracyMeters, double speedAccuracyMetersPerSecond, double bearingAccuracyDegrees, int time, int elapsedRealtimeNanos}) - -Constructor for Location object. - -| Parameter | Type | Description | -|------------------------------|--------|-------------------------------------------------------------------------------------------------------------------------| -| provider | String | Location provider, such as network location, GPS, Wi-Fi, and Bluetooth. | -| latitude | double | Latitude of a location. If no latitude is available, 0.0 is returned. | -| longitude | double | Longitude of a location. If no longitude is available, 0.0 is returned. | -| altitude | double | Altitude of a location. If no altitude is available, 0.0 is returned. | -| speed | double | Speed of a device at the current location, in meters per second. If no speed is available, 0.0 is returned. | -| bearing | double | Bearing of a device at the current location, in degrees. If no bearing is available, 0.0 is returned. | -| horizontalAccuracyMeters | double | Horizontal error of a location, in meters. If no horizontal error is available, 0.0 is returned. | -| verticalAccuracyMeters | double | Vertical error of a location, in meters. If no vertical error is available, 0.0 is returned. | -| speedAccuracyMetersPerSecond | double | Speed error of a device at the current location, in meters per second. If no speed error is available, 0.0 is returned. | -| bearingAccuracyDegrees | double | Bearing error of the current location, in degrees. If no bearing error is available, 0.0 is returned. | -| time | int | Current timestamp, in milliseconds. | -| elapsedRealtimeNanos | int | Time elapsed since the system was started, in nanoseconds | - -##### Location.fromMap(Map\ map) - -Creates a Location object from a map. - -| Parameter | Type | Description | -|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| -| map | Map\| Map as a source. | - -##### Location.fromJson(String source) - -Creates a Location object from a JSON string. - -| Parameter | Type | Description | -|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| -| source | String | JSON string as a source. | - - -### HWLocation - -#### Public Properties - -| Properties | Type | Description | -|------------------------------|------------------------|-------------------------------------------------------------------------------------------------------------------------| -| provider | String | Location provider, such as network location, GPS, Wi-Fi, and Bluetooth. | -| latitude | double | Latitude of a location. If no latitude is available, 0.0 is returned. | -| longitude | double | Longitude of a location. If no longitude is available, 0.0 is returned. | -| altitude | double | Altitude of a location. If no altitude is available, 0.0 is returned. | -| speed | double | Speed of a device at the current location, in meters per second. If no speed is available, 0.0 is returned. | -| bearing | double | Bearing of a device at the current location, in degrees. If no bearing is available, 0.0 is returned. | -| horizontalAccuracyMeters | double | Horizontal error of a location, in meters. If no horizontal error is available, 0.0 is returned. | -| verticalAccuracyMeters | double | Vertical error of a location, in meters. If no vertical error is available, 0.0 is returned. | -| speedAccuracyMetersPerSecond | double | Speed error of a device at the current location, in meters per second. If no speed error is available, 0.0 is returned. | -| bearingAccuracyDegrees | double | Bearing error of the current location, in degrees. If no bearing error is available, 0.0 is returned. | -| time | int | Current timestamp, in milliseconds. | -| elapsedRealtimeNanos | int | Time elapsed since the system was started, in nanoseconds | -| countryCode | String | Country code. The value is a two-letter code complying with the ISO 3166-1 standard. | -| countryName | String | Country name. | -| state | String | Administrative region. | -| city | String | City of the current location. | -| county | String | County of the current location. | -| street | String | Street of the current location. | -| featureName | String | Landmark building at the current location. | -| postalCode | String | Postal code of the current location. | -| phone | String | Phone number of the landmark building (such as a store or company) at the current location. | -| url | String | Website of the landmark building (such as a store or company) at the current location. | -| extraInfo | Map\ | Additional information, which is a key-value pair. | - - -#### Public Constructor Summary - -| Constructor | Description | -|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------| -| HWLocation({String provider, double latitude, double longitude, double altitude, double speed, double bearing, double horizontalAccuracyMeters, double verticalAccuracyMeters, double speedAccuracyMetersPerSecond, double bearingAccuracyDegrees, int time, int elapsedRealtimeNanos, String countryCode, String countryName, String state, String city, String county, String street, String featureName, String postalCode, String phone, String url, Map extraInfo}) | Default constructor. | -| HWLocation.fromMap(Map\ map) | Creates a HWLocation object from a map. | -| HWLocation.fromJson(String source) | Creates a HWLocation object from a JSON string. | - -#### Public Constructors - -##### HwLocation({String provider, double latitude, double longitude, double altitude, double speed, double bearing, double horizontalAccuracyMeters, double verticalAccuracyMeters, double speedAccuracyMetersPerSecond, double bearingAccuracyDegrees, int time, int elapsedRealtimeNanos}) - -Constructor for Location object. - -| Parameter | Type | Description | -|------------------------------|------------------------|-------------------------------------------------------------------------------------------------------------------------| -| provider | String | Location provider, such as network location, GPS, Wi-Fi, and Bluetooth. | -| latitude | double | Latitude of a location. If no latitude is available, 0.0 is returned. | -| longitude | double | Longitude of a location. If no longitude is available, 0.0 is returned. | -| altitude | double | Altitude of a location. If no altitude is available, 0.0 is returned. | -| speed | double | Speed of a device at the current location, in meters per second. If no speed is available, 0.0 is returned. | -| bearing | double | Bearing of a device at the current location, in degrees. If no bearing is available, 0.0 is returned. | -| horizontalAccuracyMeters | double | Horizontal error of a location, in meters. If no horizontal error is available, 0.0 is returned. | -| verticalAccuracyMeters | double | Vertical error of a location, in meters. If no vertical error is available, 0.0 is returned. | -| speedAccuracyMetersPerSecond | double | Speed error of a device at the current location, in meters per second. If no speed error is available, 0.0 is returned. | -| bearingAccuracyDegrees | double | Bearing error of the current location, in degrees. If no bearing error is available, 0.0 is returned. | -| time | int | Current timestamp, in milliseconds. | -| elapsedRealtimeNanos | int | Time elapsed since the system was started, in nanoseconds | -| countryCode | String | Country code. The value is a two-letter code complying with the ISO 3166-1 standard. | -| countryName | String | Country name. | -| state | String | Administrative region. | -| city | String | City of the current location. | -| county | String | County of the current location. | -| street | String | Street of the current location. | -| featureName | String | Landmark building at the current location. | -| postalCode | String | Postal code of the current location. | -| phone | String | Phone number of the landmark building (such as a store or company) at the current location. | -| url | String | Website of the landmark building (such as a store or company) at the current location. | -| extraInfo | Map\ | Additional information, which is a key-value pair. | - -##### HWLocation.fromMap(Map map) - -Creates a HWLocation object from a map. - -| Parameter | Type | Description | -|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| -| map | Map\| Map as a source. | - -##### HWLocation.fromJson(String source) - -Creates a HWLocation object from a JSON string. - -| Parameter | Type | Description | -|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| -| source | String | JSON string as a source. | - -### LocationAvailability - -Device location availability. - -#### Public Properties - -| Properties | Type | Description | -|-------------------|------|-----------------------------------------------------------------------------------------------------------| -| cellStatus | int | Availability status code of cell location. Currently not provided. Value is always **0**. | -| wifiStatus | int | Availability status code of wifi location. Currently not provided. Value is always **0**. | -| elapsedRealtimeNs | int | Time elapsed since the system was started, in nanoseconds. Currently not provided. Value is always **0**. | -| locationStatus | int | Location status code. If the value of smaller than 1000, then device location is available. | - -**NOTE:** - -Currently, cellStatus, wifiStatus and elapsedRealtimeNs are not provided and have a fixed value of 0. - -#### Public Constructor Summary - -| Constructor | Description | -|---------------------------------------------------------------------------------------------------|----------------------| -| LocationAvailability({int cellStatus, int wifiStatus, int elapsedRealtimeNs, int locationStatus}) | Default constructor. | -| LocationAvailability.fromMap(Map\ map) | Creates a LocationAvailability object from a map. | -| LocationAvailability.fromJson(String source) | Creates a LocationAvailability object from a JSON string. | - -#### Public Method Summary - -| Methods | Return Type | Description | -|---------------------|-------------|------------------------------------------------| -| isLocationAvailable | bool | Indicates if the location is available or not. | - -#### Public Constructors - -##### LocationAvailability({int cellStatus, int wifiStatus, int elapsedRealtimeNs, int locationStatus}) - -Constructor for LocationAvailability object. - -| Parameter | Type | Description | -|-------------------|------|-----------------------------------------------------------------------------------------------------------| -| cellStatus | int | Availability status code of cell location. Currently not provided. Value is always **0**. | -| wifiStatus | int | Availability status code of wifi location. Currently not provided. Value is always **0**. | -| elapsedRealtimeNs | int | Time elapsed since the system was started, in nanoseconds. Currently not provided. Value is always **0**. | -| locationStatus | int | Location status code. If the value of smaller than 1000, then device location is available. | - -##### LocationAvailability.fromMap(Map\ map) - -Creates a LocationAvailability object from a map. - -| Parameter | Type | Description | -|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| -| map | Map\| Map as a source. | - -##### LocationAvailability.fromJson(String source) - -Creates a LocationAvailability object from a JSON string. - -| Parameter | Type | Description | -|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| -| source | String | JSON string as a source. | - -#### Public Methods - -##### bool isLocationAvaible - -Checks whether the device location is available. If yes, the value true is returned. A number of causes may result in failure to determine the location, such as that the location function is disabled or sensor data cannot be obtained from the device. - -| Return Type | Description | -|------------------------------|----------------------| -| String | JSON string as a source. | - -### LocationCallback - -#### Public Properties - -| Properties | Type | Description | -|------------------------|----------------------------------------------------------|------------------------------------------------------------| -| onLocationAvailability | void Function(LocationAvailability locationAvailability) | Callback function to listen location availability changes. | -| onLocationResult | void Function(LocationResult locationResult) | Callback function to listen location updates. | - -#### Public Constructor Summary - -| Constructor | Description | -|------------------------------------------------------------------------------------------|----------------------| -| LocationCallback({void Function onLocationResult, void Function onLocationAvailability}) | Default constructor. | - -#### Public Constructors - -##### LocationCallback({void Function onLocationResult, void Function onLocationAvailability}) - -Constructor for LocationCallback object. - -| Parameter | Type | Description | -|------------------------------|---------------|-------------------------------------------------------------------------------------------------------------------------| -| onLocationResult | void Function | Callback function to trigger when the device location is available. | -| onLocationAvailability | void Function | Callback function to trigger when the device location availability changes. | - -### LocationRequest - -Location request class. - -#### Public Properties - -| Properties | Type | Description | -|----------------------|--------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| priority | int | Request priority. The default value is 100. | -| interval | int | Request interval, in milliseconds. The default value is 3600000. | -| fastestInterval | int | Shortest request interval, in milliseconds. The default value is 600000. If another app initiates a location request, the location is also reported to the app at the interval specified in fastestInterval. | -| expirationTime | int | Request expiration time, in milliseconds. | -| numUpdates | int | Number of requested location updates. | -| smallestDisplacement | double | Minimum displacement between location updates, in meters. | -| maxWaitTime | int | Maximum waiting timeIndicates whether to return the address information. The default value is false. | -| needAddress | bool | Indicates whether to return the address information. The default value is false. | -| language | String | Language. The value consists of two letters and complies with the ISO 639-1 international standard. By default, the value is empty. | -| countryCode | String | Country code. The value consists of two letters and complies with the ISO 3166-1 international standard. By default, the value is empty. | - -#### Public Constants - -| Constants | Type | Value | Description | -|----------------------------------|------|-------|----------------------------------------------------------------------------------------------------------------------------------------------| -| PRIORITY_HIGH_ACCURACY | int | 100 | Used to request the most accurate location. | -| PRIORITY_BALANCED_POWER_ACCURACY | int | 102 | Used to request the block-level location. | -| PRIORITY_LOW_POWER | int | 104 | Used to request the city-level location. | -| PRIORITY_NO_POWER | int | 105 | Used to request the location with the optimal accuracy without additional power consumption. | -| PRIORITY_HD_ACCURACY | int | 200 | Used to request the high-precision location information. Currently, this parameter is available only for the requestLocationUpdatesExCb API. | - -#### Public Constructor Summary - -| Constructor | Description | -|-------------------------------------------------------|----------------------| -| LocationRequest() | Default constructor. | -| LocationRequest.fromMap(Map\ map) | Creates a Location object from a map. | -| LocationRequest.fromJson(String source) | Creates a Location object from a JSON string. | - -#### Public Method Summary - -| Return Type | Method | Description | -|-----------------|--------------------------------|-------------| -| bool | isFastestIntervalExplicitlySet | Indicates whether the fastest interval explicitly set or default value is being used. | - - -#### Public Constructors - -##### LocationRequest() - -Constructor for Location object. - -##### LocationRequest.fromMap(Map\ map) - -Creates a Location object from a map. - -| Parameter | Type | Description | -|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| -| map | Map\| Map as a source. | - -##### LocationRequest.fromJson(String source) - -Creates a Location object from a JSON string. - -| Parameter | Type | Description | -|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| -| source | String | JSON string as a source. | - -#### Public Methods - -##### bool isFastestIntervalExplicitlySet - -Checks whether the shortest interval is used. - -| Methods | Return Type | Description | -|--------------------------------|-------------|---------------------------------------------------------------------------------------| -| isFastestIntervalExplicitlySet | bool | Indicates whether the fastest interval explicitly set or default value is being used. | - -### LocationResult - -Location data information class. - -#### Public Properties - -| Properties | Type | Description | -|----------------|--------------------|-------------------------------------------------------------------------------------------------------| -| locations | List\ | Available locations, which are ordered from oldest to newest. | -| hwLocations | List\ | List of available locations sorted from oldest to newest, including the detailed address information. | -| lastLocation | Location | Available location of the last request. | -| lastHWLocation | HWLocation | Available location of the last request, including the detailed address information. | - -#### Public Constructor Summary - -| Constructor | Description | -|----------------------------------------------------------------------------------------------------------------------------|----------------------| -| LocationResult({List locations, List hwLocations, Location lastLocation, HWLocation lastHWLocation}) | Default constructor. | -| LocationResult.fromMap(Map\ map) | Creates a Location object from a map. | -| LocationResult.fromJson(String source) | Creates a Location object from a JSON string. | - -#### Public Constructors - -##### LocationResult({List locations, List hwLocations, Location lastLocation, HWLocation lastHWLocation}) - -Constructor for LocationResult object. - -| Parameter | Type | Description | -|------------------------------|--------------------|-------------------------------------------------------------------------------------------------------------------------| -| locations | List\ | Available locations, which are sorted from oldest to newest. | -| hwLocations | List\ | List of available locations sorted from oldest to newest, including the detailed address. | -| lastLocation | Location | Available location of the last request. | -| lastHWLocation | HWLocation | Available location of the last request, including the detailed address. | - - -##### LocationResult.fromMap(Map\ map) - -Creates a LocationResult object from a map. - -| Parameter | Type | Description | -|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| -| map | Map\| Map as a source. | - -##### LocationResult.fromJson(String source) - -Creates a LocationResult object from a JSON string. - -| Parameter | Type | Description | -|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| -| source | String | JSON string as a source. | - - - - -### LocationSettingsRequest - -Class for specifying the location service types and checking the location settings to obtain optimal functionality of all requested services. - -#### Public Properties - -| Properties | Type | Description | -|------------|-------------------------|--------------------------------------------------------------------------------------------------------------| -| requests | List\ | Collection of LocationRequest object. | -| alwaysShow | bool | Indicates whether BLE scanning needs to be enabled. The options are true (yes) and false (no). | -| needBle | bool | Indicates whether a location is required for the app to continue. The options are true (yes) and false (no). | - -#### Public Constructor Summary - -| Constructor | Description | -|--------------------------------------------------------------------------------------------|----------------------| -| LocationSettingsRequest({List\ requests, bool alwaysShow, bool needBle}) | Default constructor. | -| LocationSettingsRequest.fromMap(Map\ map) | Creates a LocationSettingsRequest object from a map. | -| LocationSettingsRequest.fromJson(String source) | Creates a LocationSettingsRequest object from a JSON string. | - -#### Public Constructors - -##### LocationSettingsRequest({List\ requests, bool alwaysShow, bool needBle}) - -Constructor for LocationSettingsRequest object. - -| Parameter | Type | Description | -|-----------------------------|-------------------------|-------------------------------------------------------------------------------------------------------------------------| -| requests | List\ | Collection of LocationRequest objects. | -| alwaysShow | bool | Indicates whether BLE scanning needs to be enabled. The options are true (yes) and false (no). | -| needBle | bool | Indicates whether a location is required for the app to continue. The options are true (yes) and false (no). | - -##### LocationSettingsRequest.fromMap(Map\ map) - -Creates a LocationSettingsRequest object from a map. - -| Parameter | Type | Description | -|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| -| map | Map\| Map as a source. | - -##### LocationSettingsRequest.fromJson(String source) - -Creates a LocationSettingsRequest object from a JSON string. - -| Parameter | Type | Description | -|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| -| source | String | JSON string as a source. | - -### LocationSettingsStates - -Current location-related setting status. - -#### Public Properties - -| Properties | Type | Description | -|------------------------|------|----------------------------------------------------------------------------------------| -| blePresent | bool | Indicates whether the BLE exists on the device. | -| bleUsable | bool | Indicates whether the BLE is enabled and can be used by the app. | -| gpsPresent | bool | Indicates whether the GPS provider exists on the device. | -| gpsUsable | bool | Indicates whether the GPS provider is enabled and can be used by the app. | -| locationPresent | bool | Indicates whether the location provider exists on the device. | -| locationUsable | bool | Indicates whether the location provider is enabled and can be used by the app. | -| networkLocationPresent | bool | Indicates whether the network location provider exists on the device. | -| networkLocationUsable | bool | Indicates whether the network location provider is enabled and can be used by the app. | - -#### Public Constructor Summary - -| Constructor | Description | -|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------| -| LocationSettingsStates({bool blePresent, bool bleUsable, bool gpsPresent, bool gpsUsable, bool locationPresent, bool locationUsable, bool networkLocationPresent, bool networkLocationUsable}) | Default constructor. | -| LocationSettingsStates.fromMap(Map\ map) | Creates a LocationSettingsStates object from a map. | -| LocationSettingsStates.fromJson(String source) | Creates a LocationSettingsStates object from a JSON string. | - -#### Public Constructors - -##### LocationSettingsStates({bool blePresent, bool bleUsable, bool gpsPresent, bool gpsUsable, bool locationPresent, bool locationUsable, bool networkLocationPresent, bool networkLocationUsable}) - -Constructor for LocationSettingsStates object. - -| Parameter | Type | Description | -|------------------------|------|----------------------------------------------------------------------------------------| -| blePresent | bool | Indicates whether the BLE exists on the device. | -| bleUsable | bool | Indicates whether the BLE is enabled and can be used by the app. | -| gpsPresent | bool | Indicates whether the GPS provider exists on the device. | -| gpsUsable | bool | Indicates whether the GPS provider is enabled and can be used by the app. | -| locationPresent | bool | Indicates whether the location provider exists on the device. | -| locationUsable | bool | Indicates whether the location provider is enabled and can be used by the app. | -| networkLocationPresent | bool | Indicates whether the network location provider exists on the device. | -| networkLocationUsable | bool | Indicates whether the network location provider is enabled and can be used by the app. | - -##### LocationSettingsStates.fromMap(Map\ map) - -Creates a Location object from a map. - -| Parameter | Type | Description | -|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| -| map | Map\| Map as a source. | - -##### LocationSettingsStates.fromJson(String source) - -Creates a Location object from a JSON string. - -| Parameter | Type | Description | -|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| -| source | String | JSON string as a source. | - -### NavigationResult - -#### Public Properties - -| Methods | Return Type | Description | -|-------------------|-------------|----------------------------------------------------------------| -| possibility | int | Obtains the confidence of the status information. The value ranges from 0 to 100. A larger value indicates more reliable result authenticity. | -| state | int | Status information.If the navigation type is IS_SUPPORT_EX, the return values are described as follows: 11: The user device supports high-precision location.12: The user device does not support high-precision location. | - -#### Public Constructor Summary - -| Constructor | Description | -|-------------------------------------------------------|----------------------| -| NavigationResult({state, possibility}) | Default constructor. | -| NavigationResult.fromMap(Map\ map) | Creates a NavigationResult object from a map. | -| NavigationResult.fromJson(String source) | Creates a NavigationResult object from a JSON string. | - - -#### Public Constructors - -##### NavigationResult({state, possibility}) - -Constructor for NavigationResult object. - -| Parameter | Return Type | Description | -|-------------------|-------------|----------------------------------------------------------------| -| possibility | int | Obtains the confidence of the status information. The value ranges from 0 to 100. A larger value indicates more reliable result authenticity. | -| state | int | Status information.If the navigation type is IS_SUPPORT_EX, the return values are described as follows: 11: The user device supports high-precision location.12: The user device does not support high-precision location. | - - -##### NavigationResult.fromMap(Map\ map) - -Creates a NavigationResult object from a map. - -| Parameter | Type | Description | -|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| -| map | Map\| Map as a source. | - -##### NavigationResult.fromJson(String source) - -Creates a NavigationResult object from a JSON string. - -| Parameter | Type | Description | -|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| -| source | String | JSON string as a source. | - -### NavigationRequest - -#### Public Properties - -| Properties | Type | Description | -|--------------------------|----------------|--------------------------------------------| -| type | int | Requested navigation type. | - -#### Public Constants - -| Constants | Type | Value | Description | -|---------------------------|------|-------|----------------------------------------------------- | -| IS_SUPPORT_EX | int | 2 | Used to check whether the device supports high-precision location. | - -### ActivityIdentificationService - -Interaction access point of activity identification. - -#### Public Constructor Summary - -| Constructor | Description | -|------------------------------------------------|----------------------| -| ActivityIdentificationService() | Default constructor. | - -#### Public Method Summary - -| Return Type | Method | Description | -|------------------------------------------|-------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| Future\ | createActivityIdentificationUpdates(int detectionIntervalMillis) | This API is used to register for activity identification updates. | -| Future\ | createActivityConversionUpdates(List\ activityConversions) | This API is used to activity conversions (entering and exit), for example, detecting user status change from walking to bicycling.The Conversion API supports the following activity parameters. | -| Future\ | deleteActivityIdentificationUpdates(int requestCode) | This API is used to remove all activity identification updates from the specified **requestCode**. | -| Future\ | deleteActivityConversionUpdates(int requestCode) | This API is used to remove all activity conversion updates from the specified **requestCode**. | -| Stream\ | onActivityIdentification | This API is used to listen activity identification updates that comes from createActivityIdentificationUpdates API method. | -| Stream\ | onActivityConversion | This API is used to listen activity conversion updates that comes from createActivityConversionUpdates API method. | - - -#### Public Constructors - -##### ActivityIdentificationService() - -Constructor for ActivityIdentificationService object. - -#### Public Methods - -##### Future\ createActivityIdentificationUpdates(int detectionIntervalMillis) *async* - -Registers for activity identification updates. - -| Parameter | Description | -|-------------------------|-------------| -| detectionIntervalMillis | Interval for activity identification updates, in milliseconds. A larger value will result in a lower activity identification frequency, while a smaller value will result in a higher activity identification frequency. | - -| Return Type | Description | -|----------------------------------|-------------| -| Future\ | Request code if the operation is successful; PlatformException otherwise. The request code can be used to call the deleteActivityIdentificationUpdates method. | - -##### Future\ createActivityConversionUpdates(List\ activityConversions) *async* - -Registers for activity conversion updates (entering and exit), for example, detecting user status change from walking to bicycling. - -| Parameter | Description | -|---------------------|-------------| -| activityConversions | Activity conversion list. | - -| Return Type | Description | -|----------------------------------|-------------| -| Future\ | Request code if the operation is successful; PlatformException otherwise. The request code can be used to call the deleteActivityConversionUpdates method. | - -##### Future\ deleteActivityIdentificationUpdates(int requestCode) *async* - -Removes activity identification updates based on the specified request code. - -| Parameter | Description | -|-------------|-------------| -| requestCode | Request code returned by the createActivityIdentificationUpdates method. | - -| Return Type | Description | -|----------------------------------|-------------| -| Future\ | No return value if the operation is successful; PlatformException otherwise. | - -##### Future\ deleteActivityConversionUpdates(int requestCode) *async* - -Removes activity conversion updates based on the specified request code. - -| Parameter | Description | -|-------------|-------------| -| requestCode | Request code returned by the createActivityConversionUpdates method. | - -| Return Type | Description | -|----------------------------------|-------------| -| Future\ | No return value if the operation is successful; PlatformException otherwise. | - -##### Stream\ onActivityIdentification - -Listens for activity identification updates that come from the createActivityIdentificationUpdates method. - -| Return Type | Description | -|------------------------------------------|-------------| -| Stream\ | Stream of ActivityIdentificationResponse object. You can call the .listen() method to subscribe to this stream and listen for updates. | - -##### Stream\ onActivityConversion - -Listens for activity conversion updates that come from the createActivityConversionUpdates method. - -| Return Type | Description | -|--------------------------------------|-------------| -| Stream\ | Stream of ActivityConversionResponse object. You can call the .listen() method to subscribe to this stream and listen for updates. | - -### ActivityConversionData - -Activity conversion event. - -#### Public Properties - -| Properties | Type | Description | -|-----------------------|------|--------------------------------------------------------------------------------------------------------------------------------------------------------| -| activityType | int | Activity type of the conversion. The value is one of the activity types defined in ActivityIdentificationData. | -| conversionType | int | Activity conversion information. The options are ActivityConversionInfo.ENTER_ACTIVITY_CONVERSION and ActivityConversionInfo.EXIT_ACTIVITY_CONVERSION. | -| elapsedTimeFromReboot | int | Elapsed real time (in milliseconds) of this conversion since boot. | - -#### Public Constructor Summary - -| Constructor | Description | -|-------------------------------------------------------------------------------------------|----------------------| -| ActivityConversionData({int activityType, int conversionType, int elapsedTimeFromReboot}) | Default constructor. | -| ActivityConversionData.fromMap(Map\ map) | Creates a ActivityConversionData object from a map. | -| ActivityConversionData.fromJson(String source) | Creates a ActivityConversionData object from a JSON string. | - -#### Public Constructors - -##### ActivityConversionData({int activityType, int conversionType, int elapsedTimeFromReboot}) - -Constructor for ActivityConversionData object. - -| Parameter | Type | Description | -|-----------------------|------|--------------------------------------------------------------------------------------------------------------------------------------------------------| -| activityType | int | Activity type of the conversion. The value is one of the activity types defined in ActivityIdentificationData. | -| conversionType | int | Activity conversion information. The options are ActivityConversionInfo.ENTER_ACTIVITY_CONVERSION and ActivityConversionInfo.EXIT_ACTIVITY_CONVERSION. | -| elapsedTimeFromReboot | int | Elapsed real time (in milliseconds) of this conversion since boot. | - -##### ActivityConversionData.fromMap(Map\ map) - -Creates a ActivityConversionData object from a map. - -| Parameter | Type | Description | -|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| -| map | Map\| Map as a source. | - -##### ActivityConversionData.fromJson(String source) - -Creates a ActivityConversionData object from a JSON string. - -| Parameter | Type | Description | -|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| -| source | String | JSON string as a source. | - -### ActivityConversionInfo - -Activity conversion information. - -#### Public Properties - -| Properties | Type | Description | -|----------------|------|---------------------------------------------------------------------------------------------------------------------------------------------------------| -| activityType | int | Activity type of the conversion. The value is one of the activity types defined in ActivityIdentificationData. | -| conversionType | int | Activity conversion information. The options are ActivityConversionInfo.ENTER_ACTIVITY_CONVERSION and ActivityConversionInfo.EXIT_ACTIVITY_CONVERSION. | - -#### Public Constants - -| Constants | Type | Value | Description | -|---------------------------|------|-------|-----------------------------------| -| ENTER_ACTIVITY_CONVERSION | int | 0 | A user enters the given activity. | -| EXIT_ACTIVITY_CONVERSION | int | 1 | A user exits the given activity. | - -#### Public Constructor Summary - -| Constructor | Description | -|----------------------------------------------------------------|----------------------| -| ActivityConversionInfo({int activityType, int conversionType}) | Default constructor. | -| ActivityConversionInfo.fromMap(Map\ map) | Creates a ActivityConversionInfo object from a map. | -| ActivityConversionInfo.fromJson(String source) | Creates a ActivityConversionInfo object from a JSON string. | - -#### Public Constructors - -##### ActivityConversionInfo({int activityType, int conversionType}) - -Constructor for ActivityConversionInfo object. - -| Properties | Type | Description | -|----------------|------|---------------------------------------------------------------------------------------------------------------------------------------------------------| -| activityType | int | Activity type of the conversion. The value is one of the activity types defined in ActivityIdentificationData. | -| conversionType | int | Activity conversion information. The options are ActivityConversionInfo.ENTER_ACTIVITY_CONVERSION and ActivityConversionInfo.EXIT_ACTIVITY_CONVERSION. | - -##### ActivityConversionInfo.fromMap(Map\ map) - -Creates a ActivityConversionInfo object from a map. - -| Parameter | Type | Description | -|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| -| map | Map\| Map as a source. | - -##### ActivityConversionInfo.fromJson(String source) - -Creates a ActivityConversionInfo object from a JSON string. - -| Parameter | Type | Description | -|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| -| source | String | JSON string as a source. | - -### ActivityConversionResponse - -Activity conversion result. - -#### Public Properties - -| Properties | Type | Description | -|-------------------------|--------------------------------|-------------------------------------------------------------------------------------------------------------------| -| activityConversionDatas | List\ | All activity conversion events in the result. The obtained activity events are sorted by time in ascending order. | - -#### Public Constructor Summary - -| Constructor | Description | -|--------------------------------------------------------------------------------------|----------------------| -| ActivityConversionResponse({List\ activityConversionDatas}) | Default constructor. | -| ActivityConversionResponse.fromMap(Map\ map) | Creates a ActivityConversionResponse object from a map. | -| ActivityConversionResponse.fromJson(String source) | Creates a ActivityConversionResponse object from a JSON string. | - -#### Public Constructors - -##### ActivityConversionResponse({List\ activityConversionDatas}) - -Constructor for ActivityConversionResponse object. - -| Parameter | Type | Description | -|------------------------------|--------------------------------|-------------------------------------------------------------------------------------------------------------------------| -| activityConversionDatas | List\ | All activity conversion events in the result. The obtained activity events are sorted by time in ascending order. | - - -##### ActivityConversionResponse.fromMap(Map\ map) - -Creates a ActivityConversionResponse object from a map. - -| Parameter | Type | Description | -|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| -| map | Map\| Map as a source. | - -##### ActivityConversionResponse.fromJson(String source) - -Creates a ActivityConversionResponse object from a JSON string. - -| Parameter | Type | Description | -|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| -| source | String | JSON string as a source. | - -### ActivityIdentificationData - -Class for detecting the activity. - -#### Public Properties - -| Properties | Type | Description | -|------------------------|------|---------------------------------------------------------------------------------------------------------------------------------------------------------| -| identificationActivity | int | Type of the detected activity. | -| possibility | int | The confidence for the user to execute the activity. The confidence ranges from 0 to 100. A larger value indicates more reliable activity authenticity. | - -#### Public Constants - -| Constants | Type | Value | Description | -|-----------|------|-------|-----------------------------------------------------------------| -| VEHICLE | int | 100 | The device is in a vehicle, such as a car. | -| BIKE | int | 101 | The device is on a bicycle. | -| FOOT | int | 102 | The device user is walking or running. | -| STILL | int | 103 | The device is still. | -| OTHERS | int | 104 | The current activity cannot be detected. | -| TILTING | int | 105 | The device has an obvious tilt change. | -| WALKING | int | 107 | The user of the device is walking,it is a sub-activity of FOOT. | -| RUNNING | int | 108 | The user of the device is running,it is a sub-activity of FOOT. | - -#### Public Constructor Summary - -| Constructor | Description | -|-----------------------------------------------------------------|----------------------| -| ActivityIdentificationData({int identificationActivity, int possibility}) | Default constructor. | -| ActivityIdentificationData.fromMap(Map\ map) | Creates a ActivityIdentificationData object from a map. | -| ActivityIdentificationData.fromJson(String source) | Creates a ActivityIdentificationData object from a JSON string. | - -#### Public Method Summary - -| Methods | Return Type | Description | -|------------------------------|-------------|----------------------------------------------------------------| -| static isValidType(int type) | bool | Checks that given activity type is one of the valid constants. | - -#### Public Constructors - -##### ActivityIdentificationData({int identificationActivity, int possibility}) - -Constructor for ActivityIdentificationData object. - -| Parameter | Type | Description | -|------------------------|------|---------------------------------------------------------------------------------------------------------------------------------------------------------| -| identificationActivity | int | Type of the detected activity. | -| possibility | int | The confidence for the user to execute the activity. The confidence ranges from 0 to 100. A larger value indicates more reliable activity authenticity. | - -##### ActivityIdentificationData.fromMap(Map\ map) - -Creates a ActivityIdentificationData object from a map. - -| Parameter | Type | Description | -|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| -| map | Map\| Map as a source. | - -##### ActivityIdentificationData.fromJson(String source) - -Creates a ActivityIdentificationData object from a JSON string. - -| Parameter | Type | Description | -|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| -| source | String | JSON string as a source. | - -#### Public Methods - -##### bool isValidType - -Checks whether the specified activity type is a valid constant. - -| Return Type | Description | -|-----------------|-------------| -| bool | true if the specified activity type is a valid constant; false otherwise. | - -### ActivityIdentificationResponse - -Activity identification result. - -#### Public Properties - -| Properties | Type | Description | -|-----------------------------|------------------------------------|-----------------------------------------------------------------------------------------------------------------| -| time | int | Time of this identification, which is in milliseconds since January 1, 1970. | -| elapsedTimeFromReboot | int | Elapsed real time (in milliseconds) of this identification since boot. | -| activityIdentificationDatas | List\ | List of activitiy identification list. The activity identifications are sorted by most probable activity first. | - -#### Public Constructor Summary - -| Constructor | Description | -|---------------------------------------------------------------------------------------------------------------------------------------|----------------------| -| ActivityIdentificationResponse({int time, int elapsedTimeFromReboot, List\ activityIdentificationDatas}) | Default constructor. | -| ActivityIdentificationResponse.fromMap(Map\ map) | Creates a ActivityIdentificationResponse object from a map. | -| ActivityIdentificationResponse.fromJson(String source) | Creates a ActivityIdentificationResponse object from a JSON string. | - -#### Public Method Summary - -| Methods | Return Type | Description | -|------------------------------------------|----------------------------|-----------------------------------------------------------------------------------| -| mostActivityIdentification | ActivityIdentificationData | This API is used to obtain the most probable activity identification of the user. | -| getActivityPossibility(int activityType) | int | This API is used to obtain the confidence of an activity type. | - -#### Public Constructors - -##### ActivityIdentificationResponse({int time, int elapsedTimeFromReboot, List\ activityIdentificationDatas}) - -Constructor for ActivityIdentificationResponse object. - -| Parameter | Type | Description | -|-----------------------------|------------------------------------|-----------------------------------------------------------------------------------------------------------------| -| time | int | Time of this identification, which is in milliseconds since January 1, 1970. | -| elapsedTimeFromReboot | int | Elapsed real time (in milliseconds) of this identification since boot. | -| activityIdentificationDatas | List\ | List of activitiy identification list. The activity identifications are sorted by most probable activity first. | - -##### ActivityIdentificationResponse.fromMap(Map\ map) - -Creates a ActivityIdentificationResponse object from a map. - -| Parameter | Type | Description | -|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| -| map | Map\| Map as a source. | - -##### ActivityIdentificationResponse.fromJson(String source) - -Creates a Location object from a JSON string. - -| Parameter | Type | Description | -|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| -| source | String | JSON string as a source. | - -#### Public Methods - -##### ActivityIdentificationData mostActivityIdentification - -Obtains the most possible activity of a user. - -| Return Type | Description | -|----------------------------------|-------------| -| ActivityIdentificationData | Identified activity. | - -##### int getActivityPossibility - -Obtains the confidence of an activity type. - -| Parameter | Description | -|-------------------------|-------------| -| activityType | Activity type. | - -| Return Type | Description | -|----------------------------------|-------------| -| int | Confidence of the activity type. | - -### Geofence Service - -Interaction access point of geofence. - -#### Public Constructor Summary - -| Constructor | Description | -|----------------------------------------|----------------------| -| GeofenceService() | Default constructor. | - -#### Public Method Summary - -| Return Type | Method | Description | -|------------------------|-------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------| -| Future\ | createGeofenceList(GeofenceRequest geofenceRequest) | This API is used to add geofences. When a geofence is triggered, a notification can be listened through **onGeofenceData** API method. | -| Future\ | deleteGeofenceList(int requestCode) | This API is used to remove geofences associated with a **requestCode**. | -| Future\ | deleteGeofenceListWithIds(List\ geofenceIds) | This API is used to remove geofences by their unique IDs. | -| Stream\ | onGeofenceData | This API is used to listen geofence updates that comes from createGeofenceList API method. | - -#### Public Constructors - -##### GeofenceService() - -Constructor for GeofenceService object. - -#### Public Methods - -##### Future\ createGeofenceList(GeofenceRequest geofenceRequest) *async* - -Adds geofences. When a geofence is triggered, the onGeofenceData method can listen for a notification. - -| Parameter | Description | -|-------------------------|-------------| -| geofenceRequest | Geofence request object. | - -| Return Type | Description | -|----------------------------------|-------------| -| Future\ | Request code if the operation is successful; PlatformException otherwise. The request code can be used to call the deleteGeofenceList method. | - -##### Future\ deleteGeofenceList(int requestCode) *async* - -Removes geofences associated with a request code. - -| Parameter | Description | -|-------------------------|-------------| -| requestCode | Request code returned by the createGeofenceList method. | - -| Return Type | Description | -|----------------------------------|-------------| -| Future\ | No return value if the operation is successful; PlatformException otherwise. | - -##### Future\ deleteGeofenceListWithIds(List\ geofenceIds) *async* - -Removes geofences by their unique IDs. - -| Parameter | Description | -|-------------------------|-------------| -| geofenceIds | Unique IDs of geofences to be removed. | - -| Return Type | Description | -|----------------------------------|-------------| -| Future\ | No return value if the operation is successful; PlatformException otherwise. | - -##### Stream\ onGeofenceData - -Listens for geofence updates that come from the createGeofenceList method. - -| Parameter | Description | -|-------------------------|-------------| -| geofenceIds | Unique IDs of geofences to be removed. | - -| Return Type | Description | -|----------------------------------|-------------| -| Stream\ | Stream of GeofenceData object. You can call the .listen() method to subscribe to this stream and listen for updates. | - -### Geofence - -Class that contains information about geofences. - -#### Public Properties - -| Properties | Type | Description | -|----------------------|--------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| uniqueId | String | Unique ID. If the unique ID already exists, the new geofence will overwrite the old one. | -| conversions | int | Geofence conversions. The bitwise-OR operation is supported. | -| validDuration | int | Geofence timeout interval, in milliseconds. The geofence will be automatically deleted after this amount of time. | -| latitude | double | Latitude. The value range is [-90,90]. | -| longitude | double | Longitude. The value range is [-180,180]. | -| radius | double | Radius, in meters. | -| notificationInterval | int | Notification response capability. The default value is **0**. Setting it to a larger value can reduce power consumption accordingly. However, reporting of geofence events may be delayed. | -| dwellDelayTime | int | Lingering duration for converting a geofence event, in milliseconds. A geofence event is converted when a user lingers in a geofence for this amount of time. | - -#### Public Constants - -| Constants | Type | Value | Description | -|---------------------------|------|-------|-----------------------------------------------------| -| ENTER_GEOFENCE_CONVERSION | int | 1 | A user enters the geofence. | -| EXIT_GEOFENCE_CONVERSION | int | 2 | A user exits the geofence. | -| DWELL_GEOFENCE_CONVERSION | int | 4 | A user lingers in the geofence. | -| GEOFENCE_NEVER_EXPIRE | int | -1 | No timeout interval is configured for the geofence. | - -#### Public Constructor Summary - -| Constructor | Description | -|-----------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------| -| Geofence({String uniqueId, int conversions, int validDuration, double latitude, double longitude, double radius, int notificationInterval, int dwellDelayTime}) | Default constructor. | -| Geofence.fromMap(Map\ map) | Creates a Geofence object from a map. | -| Geofence.fromJson(String source) | Creates a Geofence object from a JSON string. | - -### Public Constructors - -##### Geofence({String uniqueId, int conversions, int validDuration, double latitude, double longitude, double radius, int notificationInterval, int dwellDelayTime}) - -Constructor for Geofence object. - -| Parameter | Type | Description | -|----------------------|--------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| uniqueId | String | Unique ID. If the unique ID already exists, the new geofence will overwrite the old one. | -| conversions | int | Geofence conversions. The bitwise-OR operation is supported. | -| validDuration | int | Geofence timeout interval, in milliseconds. The geofence will be automatically deleted after this amount of time. | -| latitude | double | Latitude. The value range is [-90,90]. | -| longitude | double | Longitude. The value range is [-180,180]. | -| radius | double | Radius, in meters. | -| notificationInterval | int | Notification response capability. The default value is **0**. Setting it to a larger value can reduce power consumption accordingly. However, reporting of geofence events may be delayed. | -| dwellDelayTime | int | Lingering duration for converting a geofence event, in milliseconds. A geofence event is converted when a user lingers in a geofence for this amount of time. | - -##### Geofence.fromMap(Map\ map) - -Creates a Geofence object from a map. - -| Parameter | Type | Description | -|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| -| map | Map\| Map as a source. | - -##### Geofence.fromJson(String source) - -Creates a Geofence object from a JSON string. - -| Parameter | Type | Description | -|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| -| source | String | JSON string as a source. | - -### GeofenceData - -Geofence event. - -#### Public Properties - -| Properties | Type | Description | -|--------------------------|----------------|--------------------------------------------| -| errorCode | int | Error code. | -| conversion | int | Geofence convert type. | -| convertingGeofenceIdList | List\ | List of converted geofence unique IDs. | -| convertingLocation | Location | The location when a geofence is converted. | - -#### Public Constructor Summary - -| Constructor | Description | -|-------------------------------------------------------------------------------------------------------------------|----------------------| -| GeofenceData({int errorCode, int conversion, List convertingGeofenceIdList, Location convertingLocation}) | Default constructor. | -| GeofenceData.fromMap(Map\ map) | Creates a GeofenceData object from a map. | -| GeofenceData.fromJson(String source) | Creates a GeofenceData object from a JSON string. | - -#### Public Constructors - -##### GeofenceData({int errorCode, int conversion, List convertingGeofenceIdList, Location convertingLocation}) - -Constructor for GeofenceData object. - -| Properties | Type | Description | -|--------------------------|----------------|--------------------------------------------| -| errorCode | int | Error code. | -| conversion | int | Geofence convert type. | -| convertingGeofenceIdList | List\ | List of converted geofence unique IDs. | -| convertingLocation | Location | The location when a geofence is converted. | - -##### GeofenceData.fromMap(Map\ map) - -Creates a GeofenceData object from a map. - -| Parameter | Type | Description | -|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| -| map | Map\| Map as a source. | - -##### GeofenceData.fromJson(String source) - -Creates a GeofenceData object from a JSON string. - -| Parameter | Type | Description | -|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| -| source | String | JSON string as a source. | - -### GeofenceRequest - -Geofence request class. - -#### Public Properties - -| Properties | Type | Description | -|-----------------|------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| geofenceList | List\ | List of geofences to be monitored. | -| initConversions | int | Initial conversion type. This parameter is invalid if it is set to 0. The default value is GeofenceRequest.ENTER_INIT_CONVERSION | GeofenceRequest.DWELL_INIT_CONVERSION. | -| coordinateType | int | Coordinate type of geofences. Defaults to GeofenceRequest.COORDINATE_TYPE_WGS_84. | - -#### Public Constants - -| Constants | Type | Value | Description | -|------------------------|------|-------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| ENTER_INIT_CONVERSION | int | 1 | ENTER_INIT_CONVERSION is converted immediately when a request is initiated to add the geofence where a user device has already entered. | -| EXIT_INIT_CONVERSION | int | 2 | EXIT_INIT_CONVERSION is converted immediately when a request is initiated to add the geofence where a user device has already exit. | -| DWELL_INIT_CONVERSION | int | 4 | DWELL_INIT_CONVERSION is converted immediately when a request is initiated to add the geofence where a user device has already entered and stayed for the specified duration. | -| COORDINATE_TYPE_WGS_84 | int | 1 | WGS_84 coordinate system. | -| COORDINATE_TYPE_GCJ_02 | int | 0 | GCJ-02 coordinate system. | - -#### Public Constructor Summary - -| Constructor | Description | -|-------------------------------------------------------------------------------------------|----------------------| -| GeofenceRequest({List\ geofenceList, int initConversions, int coordinateType}) | Default constructor. | -| GeofenceRequest.fromMap(Map\ map) | Creates a GeofenceRequest object from a map. | -| GeofenceRequest.fromJson(String source) | Creates a GeofenceRequest object from a JSON string. | - -#### Public Constructors - -##### GeofenceRequest({List\ geofenceList, int initConversions, int coordinateType}) - -Constructor for GeofenceRequest object. - -| Properties | Type | Description | -|-----------------|------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| geofenceList | List\ | List of geofences to be monitored. | -| initConversions | int | Initial conversion type. This parameter is invalid if it is set to 0. The default value is GeofenceRequest.ENTER_INIT_CONVERSION | GeofenceRequest.DWELL_INIT_CONVERSION. | -| coordinateType | int | Coordinate type of geofences. Defaults to GeofenceRequest.COORDINATE_TYPE_WGS_84. | - -##### GeofenceRequest.fromMap(Map\ map) - -Creates a GeofenceRequest object from a map. - -| Parameter | Type | Description | -|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| -| map | Map\| Map as a source. | - -##### GeofenceRequest.fromJson(String source) - -Creates a GeofenceRequest object from a JSON string. - -| Parameter | Type | Description | -|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| -| source | String | JSON string as a source. | - -### PermissionHandler - -Checks or requests required permissions. - -#### Public Constructor Summary - -| Constructor | Description | -|------------------------------------------------|----------------------| -| PermissionHandler() | Default constructor. | - -#### Public Method Summary - -| Return Type | Method | Description | -|----------------|----------------------------------------|-------------------------------------------------------------------------------------------------------------------------| -| Future\ | hasLocationPermission() | This API is used to check location permission is available or not. | -| Future\ | hasBackgroundLocationPermission() | This API is used to check background location permission is available or not. | -| Future\ | hasActivityRecognitionPermission() | This API is used to check activity permission is available or not. | -| Future\ | requestLocationPermission() | This API is used to request location permission. Returns true if permission is granted, else returns false. | -| Future\ | requestBackgroundLocationPermission() | This API is used to request background location permission. Returns true if permission is granted, else returns false. | -| Future\ | requestActivityRecognitionPermission() | This API is used to request activity recognition permission. Returns true if permission is granted, else returns false. | - -#### Public Constructors - -##### PermissionHandler() - -Constructor for PermissionHandler object. - -#### Public Methods - -##### Future\ hasLocationPermission() *async* - -Checks whether the location permission is available. - -| Return Type | Description | -|----------------------------------|-------------| -| Future\ | true or false if the operation is successful; PlatformException otherwise. | - -##### Future\ hasBackgroundLocationPermission() *async* - -Checks whether the background location permission is available. - -| Return Type | Description | -|----------------------------------|-------------| -| Future\ | true or false if the operation is successful; PlatformException otherwise. | - -##### Future\ hasActivityRecognitionPermission() *async* - -Checks whether the activity permission is available. - -| Return Type | Description | -|----------------------------------|-------------| -| Future\ | true or false if the operation is successful; PlatformException otherwise. | - -##### Future\ requestLocationPermission() *async* - -Requests the location permission. The value true is returned if the permission is granted. Otherwise, false is returned. - -| Return Type | Description | -|----------------------------------|-------------| -| Future\ | true or false if the operation is successful; PlatformException otherwise. | - -##### Future\ requestBackgroundLocationPermission() *async* - -Requests the background location permission. The value true is returned if the permission is granted. Otherwise, false is returned - -| Return Type | Description | -|----------------------------------|-------------| -| Future\ | true or false if the operation is successful; PlatformException otherwise. | - -##### Future\ requestActivityRecognitionPermission() *async* - -Requests the activity permission. The value true is returned if the permission is granted. Otherwise, false is returned. - -| Return Type | Description | -|----------------------------------|-------------| -| Future\ | true or false if the operation is successful; PlatformException otherwise. | - -### HMSLogger - -#### Public Method Summary - -| Return Type | Method | Description | -|----------------|----------------------------------------|-------------------------------------------------------------------------------------------------------------------------| -| Future\ | enableLogger() | This method enables the HMSLogger capability which is used for sending usage analytics of Location SDK's methods to improve the service quality.. | -| Future\ | disableLogger() | This method disables the HMSLogger capability which is used for sending usage analytics of Location SDK's methods to improve the service quality. | - -#### Public Methods - -##### Future\ enableLogger() *async* - -This method enables the HMSLogger capability which is used for sending usage analytics of Location SDK's methods to improve the service quality. HMSLogger is enabled by default, it can be disabled with the disableLogger method. - -| Return Type | Description | -|----------------------------------|-------------| -| Future\ | Future result of an execution that returns no value. | - -##### Future\ disableLogger() *async* - -This method disables the HMSLogger capability which is used for sending usage analytics of Location SDK's methods to improve the service quality. - -| Return Type | Description | -|----------------------------------|-------------| -| Future\ | Future result of an execution that returns no value. | - - -## Configuration Description - - -### Preparing for Release - -Before building a release version of your app you may need to customize the **proguard-rules.pro** obfuscation configuration file to prevent the HMS Core SDK from being obfuscated. Add the configurations below to exclude the HMS Core SDK from obfuscation. For more information on this topic refer to [this Android developer guide](https://developer.android.com/studio/build/shrink-code). - -**/android/app/proguard-rules. pro** - -``` --ignorewarnings --keepattributes *Annotation* --keepattributes Exceptions --keepattributes InnerClasses --keepattributes Signature --keepattributes SourceFile,LineNumberTable --keep class com.hianalytics.android.**{*;} --keep class com.huawei.updatesdk.**{*;} --keep class com.huawei.hms.**{*;} - -``` - -**/android/app/build.gradle** - -```gradle -buildTypes { - debug { - signingConfig signingConfigs.config - } - release { - - // Enables code shrinking, obfuscation and optimization for release builds - minifyEnabled true - // Unused resources will be removed, resources defined in the res/raw/keep.xml will be kept. - shrinkResources true - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - - signingConfig signingConfigs.config - } -} -``` - - -## Sample Project -This plugin includes a demo project in the **example** folder, there you can find more usage examples. - - - -## Questions or Issues - -If you have questions about how to use HMS samples, try the following options: - -- [Stack Overflow](https://stackoverflow.com/questions/tagged/huawei-mobile-services) is the best place for any programming questions. Be sure to tag your question with **huawei-mobile-services**. -- [Github](https://github.com/HMS-Core/hms-flutter-plugin) is the official repository for these plugins, You can open an issue or submit your ideas. -- [Huawei Developer Forum](https://forums.developer.huawei.com/forumPortal/en/home?fid=0101187876626530001) HMS Core Module is great for general questions, or seeking recommendations and opinions. -- [Huawei Developer Docs](https://developer.huawei.com/consumer/en/doc/overview/HMS-Core-Plugin) is place to official documentation for all HMS Core Kits, you can find detailed documentations in there. - -If you run into a bug in our samples, please submit an issue to the Github Repository. - - -## Licensing and Terms - -Huawei Location Kit Flutter Plugin uses the Apache 2.0 license. \ No newline at end of file diff --git a/hms-plugins/flutter-hms-location/android/build.gradle b/hms-plugins/flutter-hms-location/android/build.gradle deleted file mode 100644 index 228af211..00000000 --- a/hms-plugins/flutter-hms-location/android/build.gradle +++ /dev/null @@ -1,45 +0,0 @@ -group 'com.huawei.hms.flutter.location' -version '1.0' - -buildscript { - repositories { - google() - jcenter() - maven { url 'https://developer.huawei.com/repo/' } - } - - dependencies { - classpath 'com.android.tools.build:gradle:3.6.0' - } -} - -rootProject.allprojects { - repositories { - google() - jcenter() - maven { url 'https://developer.huawei.com/repo/' } - } -} - -apply plugin: 'com.android.library' - -android { - compileSdkVersion 29 - buildToolsVersion "29.0.3" - - defaultConfig { - minSdkVersion 19 - targetSdkVersion 29 - } - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - lintOptions { - disable 'InvalidPackage' - } -} - -dependencies { - implementation 'com.huawei.hms:location:5.0.0.301' -} diff --git a/hms-plugins/flutter-hms-location/android/gradle.properties b/hms-plugins/flutter-hms-location/android/gradle.properties deleted file mode 100644 index 38c8d454..00000000 --- a/hms-plugins/flutter-hms-location/android/gradle.properties +++ /dev/null @@ -1,4 +0,0 @@ -org.gradle.jvmargs=-Xmx1536M -android.enableR8=true -android.useAndroidX=true -android.enableJetifier=true diff --git a/hms-plugins/flutter-hms-location/android/gradle/wrapper/gradle-wrapper.properties b/hms-plugins/flutter-hms-location/android/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index a4b44297..00000000 --- a/hms-plugins/flutter-hms-location/android/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/hms-plugins/flutter-hms-location/android/gradlew b/hms-plugins/flutter-hms-location/android/gradlew deleted file mode 100644 index 2fe81a7d..00000000 --- a/hms-plugins/flutter-hms-location/android/gradlew +++ /dev/null @@ -1,183 +0,0 @@ -#!/usr/bin/env sh - -# -# Copyright 2015 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn () { - echo "$*" -} - -die () { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=`expr $i + 1` - done - case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=`save "$@"` - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" - -exec "$JAVACMD" "$@" diff --git a/hms-plugins/flutter-hms-location/android/gradlew.bat b/hms-plugins/flutter-hms-location/android/gradlew.bat deleted file mode 100644 index 62bd9b9c..00000000 --- a/hms-plugins/flutter-hms-location/android/gradlew.bat +++ /dev/null @@ -1,103 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/hms-plugins/flutter-hms-location/android/settings.gradle b/hms-plugins/flutter-hms-location/android/settings.gradle deleted file mode 100644 index 2a0347f0..00000000 --- a/hms-plugins/flutter-hms-location/android/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -rootProject.name = 'huawei_location' diff --git a/hms-plugins/flutter-hms-location/android/src/main/AndroidManifest.xml b/hms-plugins/flutter-hms-location/android/src/main/AndroidManifest.xml deleted file mode 100644 index d54dab86..00000000 --- a/hms-plugins/flutter-hms-location/android/src/main/AndroidManifest.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/LocationPlugin.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/LocationPlugin.java deleted file mode 100644 index 4e98a26d..00000000 --- a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/LocationPlugin.java +++ /dev/null @@ -1,201 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package com.huawei.hms.flutter.location; - -import android.app.Activity; -import android.content.Context; - -import androidx.annotation.NonNull; - -import com.huawei.hms.flutter.location.constants.Channel; -import com.huawei.hms.flutter.location.handlers.ActivityConversionStreamHandler; -import com.huawei.hms.flutter.location.handlers.ActivityIdentificationMethodHandler; -import com.huawei.hms.flutter.location.handlers.ActivityIdentificationStreamHandler; -import com.huawei.hms.flutter.location.handlers.FusedLocationMethodHandler; -import com.huawei.hms.flutter.location.handlers.FusedLocationStreamHandler; -import com.huawei.hms.flutter.location.handlers.GeofenceMethodHandler; -import com.huawei.hms.flutter.location.handlers.GeofenceStreamHandler; -import com.huawei.hms.flutter.location.handlers.HMSLoggerMethodHandler; -import com.huawei.hms.flutter.location.handlers.PermissionHandler; - -import io.flutter.embedding.engine.plugins.FlutterPlugin; -import io.flutter.embedding.engine.plugins.activity.ActivityAware; -import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding; -import io.flutter.plugin.common.BinaryMessenger; -import io.flutter.plugin.common.EventChannel; -import io.flutter.plugin.common.MethodChannel; -import io.flutter.plugin.common.PluginRegistry.Registrar; - -public class LocationPlugin implements FlutterPlugin, ActivityAware { - private MethodChannel permissionMethodChannel; - private MethodChannel fusedLocationMethodChannel; - private MethodChannel geofenceMethodChannel; - private MethodChannel activityIdentificationMethodChannel; - private MethodChannel locationEnhanceMethodChannel; - private MethodChannel hmsLoggerMethodChannel; - private EventChannel mFusedLocationEventChannel; - private EventChannel mGeofenceEventChannel; - private EventChannel mActivityIdentificationEventChannel; - private EventChannel mActivityConversionEventChannel; - private PermissionHandler permissionHandler; - private EventChannel.StreamHandler mFusedLocationStreamHandler; - private EventChannel.StreamHandler mGeofenceStreamHandler; - private EventChannel.StreamHandler mActivityIdentificationStreamHandler; - private EventChannel.StreamHandler mActivityConversionStreamHandler; - private FusedLocationMethodHandler fusedLocationMethodHandler; - private GeofenceMethodHandler geofenceMethodHandler; - private ActivityIdentificationMethodHandler activityIdentificationMethodHandler; - private HMSLoggerMethodHandler hmsLoggerMethodHandler; - - public static void registerWith(final Registrar registrar) { - final LocationPlugin instance = new LocationPlugin(); - final Activity activity = registrar.activity(); - final Context context = activity.getApplicationContext(); - final BinaryMessenger messenger = registrar.messenger(); - - instance.onAttachedToEngine(context, messenger); - instance.permissionHandler = new PermissionHandler(activity); - instance.permissionMethodChannel.setMethodCallHandler(instance.permissionHandler); - instance.fusedLocationMethodHandler = new FusedLocationMethodHandler(activity, - instance.fusedLocationMethodChannel); - instance.fusedLocationMethodChannel.setMethodCallHandler(instance.fusedLocationMethodHandler); - instance.geofenceMethodHandler = new GeofenceMethodHandler(activity); - instance.geofenceMethodChannel.setMethodCallHandler(instance.geofenceMethodHandler); - instance.activityIdentificationMethodHandler = new ActivityIdentificationMethodHandler(activity); - instance.activityIdentificationMethodChannel.setMethodCallHandler(instance.activityIdentificationMethodHandler); - instance.hmsLoggerMethodHandler = new HMSLoggerMethodHandler(context); - instance.hmsLoggerMethodChannel.setMethodCallHandler(instance.hmsLoggerMethodHandler); - registrar.addRequestPermissionsResultListener(instance.permissionHandler); - registrar.addActivityResultListener(instance.fusedLocationMethodHandler); - } - - private void initChannels(final BinaryMessenger messenger) { - permissionMethodChannel = new MethodChannel(messenger, Channel.PERMISSON_METHOD.id()); - fusedLocationMethodChannel = new MethodChannel(messenger, Channel.FUSED_LOCATION_METHOD.id()); - geofenceMethodChannel = new MethodChannel(messenger, Channel.GEOFENCE_METHOD.id()); - activityIdentificationMethodChannel = new MethodChannel(messenger, Channel.ACTIVITY_IDENTIFICATION_METHOD.id()); - locationEnhanceMethodChannel = new MethodChannel(messenger, Channel.LOCATION_ENHANCE_METHOD.id()); - hmsLoggerMethodChannel = new MethodChannel(messenger, Channel.HMSLOGGER_METHOD.id()); - mFusedLocationEventChannel = new EventChannel(messenger, Channel.FUSED_LOCATION_EVENT.id()); - mGeofenceEventChannel = new EventChannel(messenger, Channel.GEOFENCE_EVENT.id()); - mActivityIdentificationEventChannel = new EventChannel(messenger, Channel.ACTIVITY_IDENTIFICATION_EVENT.id()); - mActivityConversionEventChannel = new EventChannel(messenger, Channel.ACTIVITY_CONVERSION_EVENT.id()); - } - - private void initStreamHandlers(final Context context) { - mFusedLocationStreamHandler = new FusedLocationStreamHandler(context); - mGeofenceStreamHandler = new GeofenceStreamHandler(context); - mActivityIdentificationStreamHandler = new ActivityIdentificationStreamHandler(context); - mActivityConversionStreamHandler = new ActivityConversionStreamHandler(context); - } - - private void setStreamHandlers() { - mFusedLocationEventChannel.setStreamHandler(mFusedLocationStreamHandler); - mGeofenceEventChannel.setStreamHandler(mGeofenceStreamHandler); - mActivityIdentificationEventChannel.setStreamHandler(mActivityIdentificationStreamHandler); - mActivityConversionEventChannel.setStreamHandler(mActivityConversionStreamHandler); - } - - private void resetStreamHandlers() { - mFusedLocationEventChannel.setStreamHandler(null); - mGeofenceEventChannel.setStreamHandler(null); - mActivityIdentificationEventChannel.setStreamHandler(null); - mActivityConversionEventChannel.setStreamHandler(null); - } - - private void removeStreamHandlers() { - mFusedLocationStreamHandler = null; - mGeofenceStreamHandler = null; - mActivityIdentificationStreamHandler = null; - mActivityConversionStreamHandler = null; - } - - private void removeChannels() { - permissionMethodChannel = null; - fusedLocationMethodChannel = null; - geofenceMethodChannel = null; - activityIdentificationMethodChannel = null; - locationEnhanceMethodChannel = null; - hmsLoggerMethodChannel = null; - mFusedLocationEventChannel = null; - mGeofenceEventChannel = null; - mActivityIdentificationEventChannel = null; - mActivityConversionEventChannel = null; - } - - private void onAttachedToEngine(final Context context, final BinaryMessenger messenger) { - initChannels(messenger); - initStreamHandlers(context); - setStreamHandlers(); - } - - @Override - public void onAttachedToEngine(@NonNull final FlutterPluginBinding binding) { - onAttachedToEngine(binding.getApplicationContext(), binding.getBinaryMessenger()); - } - - @Override - public void onDetachedFromEngine(@NonNull final FlutterPluginBinding binding) { - resetStreamHandlers(); - removeStreamHandlers(); - removeChannels(); - } - - @Override - public void onAttachedToActivity(@NonNull final ActivityPluginBinding binding) { - final Activity activity = binding.getActivity(); - - permissionHandler = new PermissionHandler(activity); - fusedLocationMethodHandler = new FusedLocationMethodHandler(activity, fusedLocationMethodChannel); - geofenceMethodHandler = new GeofenceMethodHandler(activity); - activityIdentificationMethodHandler = new ActivityIdentificationMethodHandler(activity); - hmsLoggerMethodHandler = new HMSLoggerMethodHandler(activity.getApplicationContext()); - - binding.addRequestPermissionsResultListener(permissionHandler); - binding.addActivityResultListener(fusedLocationMethodHandler); - - permissionMethodChannel.setMethodCallHandler(permissionHandler); - fusedLocationMethodChannel.setMethodCallHandler(fusedLocationMethodHandler); - geofenceMethodChannel.setMethodCallHandler(geofenceMethodHandler); - activityIdentificationMethodChannel.setMethodCallHandler(activityIdentificationMethodHandler); - hmsLoggerMethodChannel.setMethodCallHandler(hmsLoggerMethodHandler); - } - - @Override - public void onDetachedFromActivityForConfigChanges() { - onDetachedFromActivity(); - } - - @Override - public void onReattachedToActivityForConfigChanges(@NonNull final ActivityPluginBinding binding) { - onAttachedToActivity(binding); - } - - @Override - public void onDetachedFromActivity() { - activityIdentificationMethodChannel.setMethodCallHandler(null); - geofenceMethodChannel.setMethodCallHandler(null); - fusedLocationMethodChannel.setMethodCallHandler(null); - locationEnhanceMethodChannel.setMethodCallHandler(null); - hmsLoggerMethodChannel.setMethodCallHandler(null); - activityIdentificationMethodHandler = null; - geofenceMethodHandler = null; - fusedLocationMethodHandler = null; - permissionHandler = null; - hmsLoggerMethodHandler = null; - } -} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/constants/Action.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/constants/Action.java deleted file mode 100644 index 9a83e743..00000000 --- a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/constants/Action.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package com.huawei.hms.flutter.location.constants; - -public interface Action { - String PROCESS_LOCATION = "com.huawei.hms.flutter.location.ACTION_PROCESS_LOCATION"; - String PROCESS_GEOFENCE = "com.huawei.hms.flutter.location.ACTION_PROCESS_GEOFENCE"; - String PROCESS_CONVERSION = "com.huawei.hms.flutter.location.ACTION_PROCESS_CONVERSION"; - String PROCESS_IDENTIFICATION = "com.huawei.hms.flutter.location.ACTION_PROCESS_IDENTIFICATION"; -} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/constants/Channel.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/constants/Channel.java deleted file mode 100644 index 3e21a60f..00000000 --- a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/constants/Channel.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package com.huawei.hms.flutter.location.constants; - -public enum Channel { - PERMISSON_METHOD("com.huawei.flutter.location/permission_methodchannel"), - FUSED_LOCATION_METHOD("com.huawei.flutter.location/fusedlocation_methodchannel"), - FUSED_LOCATION_EVENT("com.huawei.flutter.location/fusedlocation_eventchannel"), - GEOFENCE_METHOD("com.huawei.flutter.location/geofence_methodchannel"), - GEOFENCE_EVENT("com.huawei.flutter.location/geofence_eventchannel"), - ACTIVITY_IDENTIFICATION_METHOD("com.huawei.flutter.location/activityidentification_methodchannel"), - ACTIVITY_IDENTIFICATION_EVENT("com.huawei.flutter.location/activityidentification_eventchannel"), - ACTIVITY_CONVERSION_EVENT("com.huawei.flutter.location/activityconversion_eventchannel"), - LOCATION_ENHANCE_METHOD("com.huawei.flutter.location/locationenhance_methodchannel"), - HMSLOGGER_METHOD("com.huawei.flutter.location/hmslogger_methodchannel"); - - private final String id; - - Channel(final String id) { - this.id = id; - } - - public String id() { - return id; - } -} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/constants/Error.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/constants/Error.java deleted file mode 100644 index 35f42ea8..00000000 --- a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/constants/Error.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package com.huawei.hms.flutter.location.constants; - -public enum Error { - LOCATION_SETTINGS_NOT_AVAILABLE("Unable to get location settings"), - NON_EXISTING_REQUEST_ID("Request ID does not exists"), - SEND_INTENT_EXCEPTION("Unable to send intent"); - - private final String message; - - Error(final String message) { - this.message = message; - } - - public String message() { - return message; - } -} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/ActivityConversionStreamHandler.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/ActivityConversionStreamHandler.java deleted file mode 100644 index f761e0ca..00000000 --- a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/ActivityConversionStreamHandler.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package com.huawei.hms.flutter.location.handlers; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.IntentFilter; - -import com.huawei.hms.flutter.location.constants.Action; -import com.huawei.hms.flutter.location.logger.HMSLogger; -import com.huawei.hms.flutter.location.receivers.ActivityConversionBroadcastReceiver; - -import io.flutter.plugin.common.EventChannel.EventSink; -import io.flutter.plugin.common.EventChannel.StreamHandler; - -public class ActivityConversionStreamHandler implements StreamHandler { - private final Context context; - private BroadcastReceiver broadcastReceiver; - - public ActivityConversionStreamHandler(final Context context) { - this.context = context; - } - - @Override - public void onListen(final Object arguments, final EventSink events) { - broadcastReceiver = new ActivityConversionBroadcastReceiver(events); - context.registerReceiver(broadcastReceiver, new IntentFilter(Action.PROCESS_CONVERSION)); - - HMSLogger.getInstance(context).sendSingleEvent("ActivityConversionStreamHandler.onListen"); - } - - @Override - public void onCancel(final Object arguments) { - context.unregisterReceiver(broadcastReceiver); - broadcastReceiver = null; - - HMSLogger.getInstance(context).sendSingleEvent("ActivityConversionStreamHandler.onCancel"); - } -} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/ActivityIdentificationMethodHandler.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/ActivityIdentificationMethodHandler.java deleted file mode 100644 index ab502248..00000000 --- a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/ActivityIdentificationMethodHandler.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package com.huawei.hms.flutter.location.handlers; - -import android.app.Activity; -import android.app.PendingIntent; -import android.content.Intent; - -import androidx.annotation.NonNull; -import androidx.core.util.Pair; - -import com.huawei.hms.flutter.location.constants.Action; -import com.huawei.hms.flutter.location.constants.Error; -import com.huawei.hms.flutter.location.listeners.DefaultFailureListener; -import com.huawei.hms.flutter.location.listeners.RemoveUpdatesSuccessListener; -import com.huawei.hms.flutter.location.listeners.RequestUpdatesFailureListener; -import com.huawei.hms.flutter.location.listeners.RequestUpdatesSuccessListener; -import com.huawei.hms.flutter.location.logger.HMSLogger; -import com.huawei.hms.flutter.location.utils.ActivityUtils; -import com.huawei.hms.location.ActivityConversionRequest; -import com.huawei.hms.location.ActivityIdentification; -import com.huawei.hms.location.ActivityIdentificationService; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import io.flutter.plugin.common.MethodCall; -import io.flutter.plugin.common.MethodChannel.MethodCallHandler; -import io.flutter.plugin.common.MethodChannel.Result; - -public class ActivityIdentificationMethodHandler implements MethodCallHandler { - private final Activity activity; - private final Map requests; - private final ActivityIdentificationService service; - - private int requestCode = 0; - - public ActivityIdentificationMethodHandler(final Activity activity) { - this.activity = activity; - service = ActivityIdentification.getService(activity); - requests = new HashMap<>(); - } - - private void createActivityIdentificationUpdates(final MethodCall call, final Result result) { - final Pair intentData = buildPendingIntent(Action.PROCESS_IDENTIFICATION); - - service.createActivityIdentificationUpdates(call.arguments(), intentData.second) - .addOnSuccessListener(new RequestUpdatesSuccessListener(call.method, activity, result, intentData.first)) - .addOnFailureListener( - new RequestUpdatesFailureListener<>(call.method, activity, result, intentData.first, requests)); - } - - private void createActivityConversionUpdates(final MethodCall call, final Result result) { - final List> args = call.arguments(); - final Pair intentData = buildPendingIntent(Action.PROCESS_CONVERSION); - final ActivityConversionRequest request - = ActivityUtils.fromActivityConversionInfoListToActivityConversionRequest(args); - - service.createActivityConversionUpdates(request, intentData.second) - .addOnSuccessListener(new RequestUpdatesSuccessListener(call.method, activity, result, intentData.first)) - .addOnFailureListener( - new RequestUpdatesFailureListener<>(call.method, activity, result, intentData.first, requests)); - } - - private void deleteActivityIdentificationUpdates(final MethodCall call, final Result result) { - final int incomingRequestCode = call.arguments(); - - if (!requests.containsKey(incomingRequestCode)) { - result.error(Error.NON_EXISTING_REQUEST_ID.name(), Error.NON_EXISTING_REQUEST_ID.message(), null); - } else { - service.deleteActivityIdentificationUpdates(requests.get(incomingRequestCode)) - .addOnSuccessListener( - new RemoveUpdatesSuccessListener<>(call.method, activity, result, incomingRequestCode, requests)) - .addOnFailureListener(new DefaultFailureListener(call.method, activity, result)); - } - } - - private void deleteActivityConversionUpdates(final MethodCall call, final Result result) { - final int incomingRequestCode = call.arguments(); - - if (!requests.containsKey(incomingRequestCode)) { - result.error(Error.NON_EXISTING_REQUEST_ID.name(), Error.NON_EXISTING_REQUEST_ID.message(), null); - } else { - service.deleteActivityConversionUpdates(requests.get(incomingRequestCode)) - .addOnSuccessListener( - new RemoveUpdatesSuccessListener<>(call.method, activity, result, incomingRequestCode, requests)) - .addOnFailureListener(new DefaultFailureListener(call.method, activity, result)); - } - } - - private Pair buildPendingIntent(final String action) { - final Intent intent = new Intent(); - - intent.setPackage(activity.getPackageName()); - intent.setAction(action); - - final PendingIntent pendingIntent = PendingIntent.getBroadcast(activity.getApplicationContext(), ++requestCode, - intent, PendingIntent.FLAG_UPDATE_CURRENT); - - requests.put(requestCode, pendingIntent); - return Pair.create(requestCode, pendingIntent); - } - - @Override - public void onMethodCall(@NonNull final MethodCall call, @NonNull final Result result) { - HMSLogger.getInstance(activity).startMethodExecutionTimer(call.method); - - switch (call.method) { - case "createActivityIdentificationUpdates": - createActivityIdentificationUpdates(call, result); - break; - case "createActivityConversionUpdates": - createActivityConversionUpdates(call, result); - break; - case "deleteActivityIdentificationUpdates": - deleteActivityIdentificationUpdates(call, result); - break; - case "deleteActivityConversionUpdates": - deleteActivityConversionUpdates(call, result); - break; - default: - result.notImplemented(); - break; - } - } -} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/ActivityIdentificationStreamHandler.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/ActivityIdentificationStreamHandler.java deleted file mode 100644 index 8a2303d4..00000000 --- a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/ActivityIdentificationStreamHandler.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package com.huawei.hms.flutter.location.handlers; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.IntentFilter; - -import com.huawei.hms.flutter.location.constants.Action; -import com.huawei.hms.flutter.location.logger.HMSLogger; -import com.huawei.hms.flutter.location.receivers.ActivityIdentificationBroadcastReceiver; - -import io.flutter.plugin.common.EventChannel.EventSink; -import io.flutter.plugin.common.EventChannel.StreamHandler; - -public class ActivityIdentificationStreamHandler implements StreamHandler { - private final Context context; - private BroadcastReceiver broadcastReceiver; - - public ActivityIdentificationStreamHandler(final Context context) { - this.context = context; - } - - @Override - public void onListen(final Object arguments, final EventSink events) { - broadcastReceiver = new ActivityIdentificationBroadcastReceiver(events); - context.registerReceiver(broadcastReceiver, new IntentFilter(Action.PROCESS_IDENTIFICATION)); - - HMSLogger.getInstance(context).sendSingleEvent("ActivityIdentificationStreamHandler.onListen"); - } - - @Override - public void onCancel(final Object arguments) { - context.unregisterReceiver(broadcastReceiver); - broadcastReceiver = null; - - HMSLogger.getInstance(context).sendSingleEvent("ActivityIdentificationStreamHandler.onCancel"); - } -} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/FusedLocationMethodHandler.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/FusedLocationMethodHandler.java deleted file mode 100644 index d4ec83a0..00000000 --- a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/FusedLocationMethodHandler.java +++ /dev/null @@ -1,265 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package com.huawei.hms.flutter.location.handlers; - -import android.app.Activity; -import android.app.PendingIntent; -import android.content.Intent; -import android.os.Looper; -import android.util.Pair; - -import androidx.annotation.NonNull; - -import com.huawei.hms.flutter.location.constants.Action; -import com.huawei.hms.flutter.location.constants.Error; -import com.huawei.hms.flutter.location.listeners.DefaultFailureListener; -import com.huawei.hms.flutter.location.listeners.DefaultSuccessListener; -import com.huawei.hms.flutter.location.listeners.LocationSettingsFailureListener; -import com.huawei.hms.flutter.location.listeners.RemoveUpdatesSuccessListener; -import com.huawei.hms.flutter.location.listeners.RequestUpdatesFailureListener; -import com.huawei.hms.flutter.location.listeners.RequestUpdatesSuccessListener; -import com.huawei.hms.flutter.location.logger.HMSLogger; -import com.huawei.hms.flutter.location.utils.LocationUtils; -import com.huawei.hms.location.FusedLocationProviderClient; -import com.huawei.hms.location.LocationEnhanceService; -import com.huawei.hms.location.LocationRequest; -import com.huawei.hms.location.LocationServices; -import com.huawei.hms.location.LocationSettingsRequest; -import com.huawei.hms.location.LocationSettingsStates; -import com.huawei.hms.location.NavigationRequest; -import com.huawei.hms.location.SettingsClient; - -import java.util.HashMap; -import java.util.Map; - -import io.flutter.plugin.common.MethodCall; -import io.flutter.plugin.common.MethodChannel; -import io.flutter.plugin.common.PluginRegistry.ActivityResultListener; - -public class FusedLocationMethodHandler implements MethodChannel.MethodCallHandler, ActivityResultListener { - private final Activity activity; - private final MethodChannel channel; - private final Map callbacks; - private final Map requests; - private final SettingsClient settingsClient; - private final FusedLocationProviderClient service; - private final LocationEnhanceService enhanceService; - - private int requestCode = 0; - private MethodChannel.Result result; - - public FusedLocationMethodHandler(final Activity activity, final MethodChannel channel) { - this.activity = activity; - this.channel = channel; - callbacks = new HashMap<>(); - requests = new HashMap<>(); - settingsClient = LocationServices.getSettingsClient(activity); - service = LocationServices.getFusedLocationProviderClient(activity); - enhanceService = LocationServices.getLocationEnhanceService(activity); - } - - private void checkLocationSettings(final MethodCall call, final MethodChannel.Result result) { - final LocationSettingsRequest request = LocationUtils.fromMapToLocationSettingsRequest(call.arguments()); - this.result = result; - - settingsClient.checkLocationSettings(request) - .addOnSuccessListener(new DefaultSuccessListener<>(call.method, activity, result)) - .addOnFailureListener(new LocationSettingsFailureListener(result, activity)); - } - - private void getLastLocation(final MethodCall call, final MethodChannel.Result result) { - service.getLastLocation() - .addOnSuccessListener(new DefaultSuccessListener<>(call.method, activity, result)) - .addOnFailureListener(new DefaultFailureListener(call.method, activity, result)); - } - - private void getLastLocationWithAddress(final MethodCall call, final MethodChannel.Result result) { - service.getLastLocationWithAddress( - LocationUtils.fromMapToLocationRequest(call.>arguments())) - .addOnSuccessListener(new DefaultSuccessListener<>(call.method, activity, result)) - .addOnFailureListener(new DefaultFailureListener(call.method, activity, result)); - } - - private void getLocationAvailability(final MethodCall call, final MethodChannel.Result result) { - service.getLocationAvailability() - .addOnSuccessListener(new DefaultSuccessListener<>(call.method, activity, result)) - .addOnFailureListener(new DefaultFailureListener(call.method, activity, result)); - } - - private void setMockMode(final MethodCall call, final MethodChannel.Result result) { - service.setMockMode(call.arguments()) - .addOnSuccessListener(new DefaultSuccessListener<>(call.method, activity, result)) - .addOnFailureListener(new DefaultFailureListener(call.method, activity, result)); - } - - private void setMockLocation(final MethodCall call, final MethodChannel.Result result) { - service.setMockLocation(LocationUtils.fromMapToLocation(call.arguments())) - .addOnSuccessListener(new DefaultSuccessListener<>(call.method, activity, result)) - .addOnFailureListener(new DefaultFailureListener(call.method, activity, result)); - } - - private void requestLocationUpdates(final MethodCall call, final MethodChannel.Result result) { - final Pair intentData = buildLocationIntent(); - final LocationRequest request = LocationUtils.fromMapToLocationRequest(call.>arguments()); - - service.requestLocationUpdates(request, intentData.second) - .addOnSuccessListener(new RequestUpdatesSuccessListener(call.method, activity, result, intentData.first)) - .addOnFailureListener( - new RequestUpdatesFailureListener<>(call.method, activity, result, intentData.first, requests)); - } - - private void requestLocationUpdatesCb(final MethodCall call, final MethodChannel.Result result) { - final LocationRequest request = LocationUtils.fromMapToLocationRequest(call.>arguments()); - final Pair callbackData = buildCallback(call.method); - - service.requestLocationUpdates(request, callbackData.second, Looper.getMainLooper()) - .addOnSuccessListener(new RequestUpdatesSuccessListener(call.method, activity, result, callbackData.first)) - .addOnFailureListener( - new RequestUpdatesFailureListener<>(call.method, activity, result, callbackData.first, callbacks)); - } - - private void requestLocationUpdatesExCb(final MethodCall call, final MethodChannel.Result result) { - final LocationRequest request = LocationUtils.fromMapToLocationRequest(call.>arguments()); - final Pair callbackData = buildCallback(call.method); - - service.requestLocationUpdatesEx(request, callbackData.second, Looper.getMainLooper()) - .addOnSuccessListener(new RequestUpdatesSuccessListener(call.method, activity, result, callbackData.first)) - .addOnFailureListener( - new RequestUpdatesFailureListener<>(call.method, activity, result, callbackData.first, callbacks)); - } - - private void removeLocationUpdates(final MethodCall call, final MethodChannel.Result result) { - final int incomingRequestCode = call.arguments(); - - if (!requests.containsKey(incomingRequestCode)) { - result.error(Error.NON_EXISTING_REQUEST_ID.name(), Error.NON_EXISTING_REQUEST_ID.message(), null); - } else { - service.removeLocationUpdates(requests.get(incomingRequestCode)) - .addOnSuccessListener( - new RemoveUpdatesSuccessListener<>(call.method, activity, result, incomingRequestCode, requests)) - .addOnFailureListener(new DefaultFailureListener(call.method, activity, result)); - } - } - - private void removeLocationUpdatesCb(final MethodCall call, final MethodChannel.Result result) { - final int callbackId = call.arguments(); - - if (!callbacks.containsKey(callbackId)) { - result.error(Error.NON_EXISTING_REQUEST_ID.name(), Error.NON_EXISTING_REQUEST_ID.message(), null); - } else { - service.removeLocationUpdates(callbacks.get(callbackId)) - .addOnSuccessListener( - new RemoveUpdatesSuccessListener<>(call.method, activity, result, callbackId, callbacks)) - .addOnFailureListener(new DefaultFailureListener(call.method, activity, result)); - } - } - - private void getNavigationContextState(final MethodCall call, final MethodChannel.Result result) { - final NavigationRequest request = LocationUtils.fromMapToNavigationRequest(call.arguments()); - - enhanceService.getNavigationState(request) - .addOnSuccessListener(new DefaultSuccessListener<>(call.method, activity, result)) - .addOnFailureListener(new DefaultFailureListener(call.method, activity, result)); - } - - private Pair buildCallback(final String methodName) { - final LocationCallbackHandler callBack = new LocationCallbackHandler(activity.getApplicationContext(), - methodName, ++requestCode, channel); - callbacks.put(requestCode, callBack); - return Pair.create(requestCode, callBack); - } - - private Pair buildLocationIntent() { - final Intent intent = new Intent(); - intent.setPackage(activity.getPackageName()); - intent.setAction(Action.PROCESS_LOCATION); - - final PendingIntent pendingIntent = PendingIntent.getBroadcast(activity.getApplicationContext(), ++requestCode, - intent, PendingIntent.FLAG_UPDATE_CURRENT); - requests.put(requestCode, pendingIntent); - return Pair.create(requestCode, pendingIntent); - } - - @Override - public void onMethodCall(@NonNull final MethodCall call, @NonNull final MethodChannel.Result result) { - HMSLogger.getInstance(activity.getApplicationContext()).startMethodExecutionTimer(call.method); - - switch (call.method) { - case "checkLocationSettings": - checkLocationSettings(call, result); - break; - case "getLastLocation": - getLastLocation(call, result); - break; - case "getLastLocationWithAddress": - getLastLocationWithAddress(call, result); - break; - case "getLocationAvailability": - getLocationAvailability(call, result); - break; - case "setMockMode": - setMockMode(call, result); - break; - case "setMockLocation": - setMockLocation(call, result); - break; - case "requestLocationUpdates": - requestLocationUpdates(call, result); - break; - case "requestLocationUpdatesCb": - requestLocationUpdatesCb(call, result); - break; - case "requestLocationUpdatesExCb": - requestLocationUpdatesExCb(call, result); - break; - case "removeLocationUpdates": - removeLocationUpdates(call, result); - break; - case "removeLocationUpdatesCb": - removeLocationUpdatesCb(call, result); - break; - case "getNavigationContextState": - getNavigationContextState(call, result); - break; - default: - result.notImplemented(); - break; - } - } - - @Override - public boolean onActivityResult(final int requestCode, final int resultCode, final Intent intent) { - final MethodChannel.Result incomingResult = result; - result = null; - - if (incomingResult != null && requestCode == 0) { - if (resultCode == Activity.RESULT_OK) { - final LocationSettingsStates states = LocationSettingsStates.fromIntent(intent); - HMSLogger.getInstance(activity.getApplicationContext()) - .sendSingleEvent("checkLocationSettings.onActivityResult"); - incomingResult.success(LocationUtils.fromLocationSettingsStatesToMap(states)); - } else { - HMSLogger.getInstance(activity.getApplicationContext()) - .sendSingleEvent("checkLocationSettings" + ".onActivityResult", "-1"); - incomingResult.error(Error.LOCATION_SETTINGS_NOT_AVAILABLE.name(), - Error.LOCATION_SETTINGS_NOT_AVAILABLE.message(), null); - } - } - - return true; - } -} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/FusedLocationStreamHandler.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/FusedLocationStreamHandler.java deleted file mode 100644 index 03d732b0..00000000 --- a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/FusedLocationStreamHandler.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package com.huawei.hms.flutter.location.handlers; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.IntentFilter; - -import com.huawei.hms.flutter.location.constants.Action; -import com.huawei.hms.flutter.location.logger.HMSLogger; -import com.huawei.hms.flutter.location.receivers.FusedLocationBroadcastReceiver; - -import io.flutter.plugin.common.EventChannel.EventSink; -import io.flutter.plugin.common.EventChannel.StreamHandler; - -public class FusedLocationStreamHandler implements StreamHandler { - private final Context context; - private BroadcastReceiver broadcastReceiver; - - public FusedLocationStreamHandler(final Context context) { - this.context = context; - } - - @Override - public void onListen(final Object arguments, final EventSink events) { - broadcastReceiver = new FusedLocationBroadcastReceiver(events); - context.registerReceiver(broadcastReceiver, new IntentFilter(Action.PROCESS_LOCATION)); - HMSLogger.getInstance(context).sendSingleEvent("FusedLocationStreamHandler.onListen"); - } - - @Override - public void onCancel(final Object arguments) { - context.unregisterReceiver(broadcastReceiver); - broadcastReceiver = null; - HMSLogger.getInstance(context).sendSingleEvent("FusedLocationStreamHandler.onCancel"); - } -} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/GeofenceMethodHandler.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/GeofenceMethodHandler.java deleted file mode 100644 index 6c479b35..00000000 --- a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/GeofenceMethodHandler.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package com.huawei.hms.flutter.location.handlers; - -import android.app.Activity; -import android.app.PendingIntent; -import android.content.Intent; -import android.util.Pair; - -import androidx.annotation.NonNull; - -import com.huawei.hms.flutter.location.constants.Action; -import com.huawei.hms.flutter.location.constants.Error; -import com.huawei.hms.flutter.location.listeners.DefaultFailureListener; -import com.huawei.hms.flutter.location.listeners.DefaultSuccessListener; -import com.huawei.hms.flutter.location.listeners.RemoveUpdatesSuccessListener; -import com.huawei.hms.flutter.location.listeners.RequestUpdatesFailureListener; -import com.huawei.hms.flutter.location.listeners.RequestUpdatesSuccessListener; -import com.huawei.hms.flutter.location.logger.HMSLogger; -import com.huawei.hms.flutter.location.utils.GeofenceUtils; -import com.huawei.hms.location.GeofenceRequest; -import com.huawei.hms.location.GeofenceService; -import com.huawei.hms.location.LocationServices; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import io.flutter.plugin.common.MethodCall; -import io.flutter.plugin.common.MethodChannel.MethodCallHandler; -import io.flutter.plugin.common.MethodChannel.Result; - -public class GeofenceMethodHandler implements MethodCallHandler { - private final Activity activity; - private final GeofenceService service; - private final Map requests; - - private int requestCode = 0; - - public GeofenceMethodHandler(final Activity activity) { - this.activity = activity; - service = LocationServices.getGeofenceService(activity); - requests = new HashMap<>(); - } - - private void createGeofenceList(@NonNull final MethodCall call, @NonNull final Result result) { - final GeofenceRequest geofenceRequest = GeofenceUtils.fromMapToGeofenceRequest(call.arguments()); - final Pair intentData = buildGeofenceIntent(); - - service.createGeofenceList(geofenceRequest, intentData.second) - .addOnSuccessListener(new RequestUpdatesSuccessListener(call.method, activity, result, intentData.first)) - .addOnFailureListener( - new RequestUpdatesFailureListener<>(call.method, activity, result, intentData.first, requests)); - } - - private void deleteGeofenceList(@NonNull final MethodCall call, @NonNull final Result result) { - final int incomingRequestCode = call.arguments(); - - if (!requests.containsKey(incomingRequestCode)) { - result.error(Error.NON_EXISTING_REQUEST_ID.name(), Error.NON_EXISTING_REQUEST_ID.message(), null); - } else { - service.deleteGeofenceList(requests.get(incomingRequestCode)) - .addOnSuccessListener( - new RemoveUpdatesSuccessListener<>(call.method, activity, result, incomingRequestCode, requests)) - .addOnFailureListener(new DefaultFailureListener(call.method, activity, result)); - } - } - - private void deleteGeofenceListWithIds(@NonNull final MethodCall call, @NonNull final Result result) { - service.deleteGeofenceList(call.>arguments()) - .addOnSuccessListener(new DefaultSuccessListener<>(call.method, activity, result)) - .addOnFailureListener(new DefaultFailureListener(call.method, activity, result)); - } - - private Pair buildGeofenceIntent() { - final Intent intent = new Intent(); - intent.setPackage(activity.getPackageName()); - intent.setAction(Action.PROCESS_GEOFENCE); - - final PendingIntent pendingIntent = PendingIntent.getBroadcast(activity.getApplicationContext(), ++requestCode, - intent, PendingIntent.FLAG_UPDATE_CURRENT); - requests.put(requestCode, pendingIntent); - return Pair.create(requestCode, pendingIntent); - } - - @Override - public void onMethodCall(@NonNull final MethodCall call, @NonNull final Result result) { - HMSLogger.getInstance(activity.getApplicationContext()).startMethodExecutionTimer(call.method); - - switch (call.method) { - case "createGeofenceList": - createGeofenceList(call, result); - break; - case "deleteGeofenceList": - deleteGeofenceList(call, result); - break; - case "deleteGeofenceListWithIds": - deleteGeofenceListWithIds(call, result); - break; - default: - result.notImplemented(); - break; - } - } -} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/GeofenceStreamHandler.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/GeofenceStreamHandler.java deleted file mode 100644 index d2c24d69..00000000 --- a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/GeofenceStreamHandler.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package com.huawei.hms.flutter.location.handlers; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.IntentFilter; - -import com.huawei.hms.flutter.location.constants.Action; -import com.huawei.hms.flutter.location.logger.HMSLogger; -import com.huawei.hms.flutter.location.receivers.GeofenceBroadcastReceiver; - -import io.flutter.plugin.common.EventChannel.EventSink; -import io.flutter.plugin.common.EventChannel.StreamHandler; - -public class GeofenceStreamHandler implements StreamHandler { - private final Context context; - private BroadcastReceiver broadcastReceiver; - - public GeofenceStreamHandler(final Context context) { - this.context = context; - } - - @Override - public void onListen(final Object arguments, final EventSink events) { - broadcastReceiver = new GeofenceBroadcastReceiver(events); - context.registerReceiver(broadcastReceiver, new IntentFilter(Action.PROCESS_GEOFENCE)); - - HMSLogger.getInstance(context).sendSingleEvent("GeofenceStreamHandler.onListen"); - } - - @Override - public void onCancel(final Object arguments) { - context.unregisterReceiver(broadcastReceiver); - broadcastReceiver = null; - - HMSLogger.getInstance(context).sendSingleEvent("GeofenceStreamHandler.onCancel"); - } -} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/HMSLoggerMethodHandler.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/HMSLoggerMethodHandler.java deleted file mode 100644 index 57d4a65e..00000000 --- a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/HMSLoggerMethodHandler.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package com.huawei.hms.flutter.location.handlers; - -import android.content.Context; - -import androidx.annotation.NonNull; - -import com.huawei.hms.flutter.location.logger.HMSLogger; - -import io.flutter.plugin.common.MethodCall; -import io.flutter.plugin.common.MethodChannel.MethodCallHandler; -import io.flutter.plugin.common.MethodChannel.Result; - -public class HMSLoggerMethodHandler implements MethodCallHandler { - private final Context context; - - public HMSLoggerMethodHandler(final Context context) { - this.context = context; - } - - @Override - public void onMethodCall(final MethodCall call, @NonNull final Result result) { - switch (call.method) { - case "enableLogger": - HMSLogger.getInstance(context).enableLogger(); - result.success(null); - break; - case "disableLogger": - HMSLogger.getInstance(context).disableLogger(); - result.success(null); - break; - default: - break; - } - } -} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/LocationCallbackHandler.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/LocationCallbackHandler.java deleted file mode 100644 index d932988e..00000000 --- a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/LocationCallbackHandler.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package com.huawei.hms.flutter.location.handlers; - -import android.content.Context; - -import com.huawei.hms.flutter.location.logger.HMSLogger; -import com.huawei.hms.flutter.location.utils.LocationUtils; -import com.huawei.hms.location.LocationAvailability; -import com.huawei.hms.location.LocationCallback; -import com.huawei.hms.location.LocationResult; - -import java.util.HashMap; -import java.util.Map; - -import io.flutter.plugin.common.MethodChannel; - -public class LocationCallbackHandler extends LocationCallback { - private final Context context; - private final String methodName; - private final int callbackId; - private final MethodChannel channel; - - LocationCallbackHandler(final Context context, final String methodName, final int callbackId, - final MethodChannel channel) { - this.context = context; - this.methodName = methodName; - this.callbackId = callbackId; - this.channel = channel; - } - - @Override - public void onLocationResult(final LocationResult locationResult) { - if (locationResult != null) { - final Map map = new HashMap<>(); - - map.put("callbackId", callbackId); - map.put("locationResult", LocationUtils.fromLocationResultToMap(locationResult)); - - HMSLogger.getInstance(context).sendPeriodicEvent(methodName + ".onLocationResult"); - channel.invokeMethod("onLocationResult", map); - } - } - - @Override - public void onLocationAvailability(final LocationAvailability locationAvailability) { - if (locationAvailability != null) { - final Map map = new HashMap<>(); - - map.put("callbackId", callbackId); - map.put("locationAvailability", LocationUtils.fromLocationAvailabilityToMap(locationAvailability)); - - HMSLogger.getInstance(context).sendPeriodicEvent(methodName + ".onLocationAvailability"); - channel.invokeMethod("onLocationAvailability", map); - } - } -} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/PermissionHandler.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/PermissionHandler.java deleted file mode 100644 index 7db5a267..00000000 --- a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/PermissionHandler.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package com.huawei.hms.flutter.location.handlers; - -import static androidx.core.content.PermissionChecker.PERMISSION_GRANTED; -import static androidx.core.content.PermissionChecker.checkSelfPermission; - -import android.app.Activity; -import android.os.Build; - -import androidx.annotation.NonNull; - -import com.huawei.hms.flutter.location.logger.HMSLogger; - -import io.flutter.plugin.common.MethodCall; -import io.flutter.plugin.common.MethodChannel.MethodCallHandler; -import io.flutter.plugin.common.MethodChannel.Result; -import io.flutter.plugin.common.PluginRegistry.RequestPermissionsResultListener; - -public class PermissionHandler implements MethodCallHandler, RequestPermissionsResultListener { - private static final String HUAWEI_ACTIVITY_RECOGNITION_PERMISSION = "android.permission.ACTIVITY_RECOGNITION"; - private static final String[] BG_LOC_PERMISSION_OLD = { - android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION - }; - private final Activity activity; - private final HMSLogger hmsLogger; - - private Result result; - - public PermissionHandler(final Activity activity) { - this.activity = activity; - hmsLogger = HMSLogger.getInstance(activity.getApplicationContext()); - } - - private boolean hasLocationPermission() { - hmsLogger.sendSingleEvent("hasLocationPermission"); - return isCoarseLocGranted() && isFineLocGranted(); - } - - private boolean hasBackgroundLocationPermission() { - hmsLogger.sendSingleEvent("hasBackgroundLocationPermission"); - - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) { - return isFineLocGranted() && isBackgroundLocGranted(); - } - return isCoarseLocGranted() || isFineLocGranted(); - } - - private boolean hasActivityRecognitionPermission() { - hmsLogger.sendSingleEvent("hasActivityRecognitionPermission"); - - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) { - return PERMISSION_GRANTED == checkSelfPermission(activity.getApplicationContext(), - android.Manifest.permission.ACTIVITY_RECOGNITION); - } else { - return PERMISSION_GRANTED == checkSelfPermission(activity.getApplicationContext(), - HUAWEI_ACTIVITY_RECOGNITION_PERMISSION); - } - } - - private void requestLocationPermission() { - hmsLogger.sendSingleEvent("requestLocationPermission"); - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) { - final String[] permissions = { - android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION, - android.Manifest.permission.ACCESS_BACKGROUND_LOCATION - }; - activity.requestPermissions(permissions, 1); - } else { - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) { - activity.requestPermissions(BG_LOC_PERMISSION_OLD, 2); - } - } - } - - private void requestBackgroundLocationPermission() { - hmsLogger.sendSingleEvent("requestBackgroundLocationPermission"); - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) { - final String[] permissions = { - android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION, - android.Manifest.permission.ACCESS_BACKGROUND_LOCATION - }; - activity.requestPermissions(permissions, 3); - } else { - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) { - activity.requestPermissions(BG_LOC_PERMISSION_OLD, 4); - } - } - } - - private void requestActivityRecognitionPermission() { - hmsLogger.sendSingleEvent("requestActivityRecognitionPermission"); - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) { - final String[] permissions = {android.Manifest.permission.ACTIVITY_RECOGNITION}; - activity.requestPermissions(permissions, 5); - } else { - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) { - final String[] permissions = {HUAWEI_ACTIVITY_RECOGNITION_PERMISSION}; - activity.requestPermissions(permissions, 6); - } - } - } - - private boolean isCoarseLocGranted() { - final int coarseLoc = checkSelfPermission(activity, android.Manifest.permission.ACCESS_COARSE_LOCATION); - return coarseLoc == PERMISSION_GRANTED; - } - - private boolean isFineLocGranted() { - final int fineLoc = checkSelfPermission(activity, android.Manifest.permission.ACCESS_FINE_LOCATION); - return fineLoc == PERMISSION_GRANTED; - } - - private boolean isBackgroundLocGranted() { - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) { - final int backgroundLoc = checkSelfPermission(activity, - android.Manifest.permission.ACCESS_BACKGROUND_LOCATION); - return backgroundLoc == PERMISSION_GRANTED; - } - return true; - } - - private boolean checkGrantStatus(final int[] grantResults) { - for (final int i : grantResults) { - if (i != 0) { - return false; - } - } - return true; - } - - @Override - public void onMethodCall(final MethodCall call, @NonNull final Result result) { - this.result = result; - hmsLogger.startMethodExecutionTimer(call.method); - - switch (call.method) { - case "hasLocationPermission": - result.success(hasLocationPermission()); - break; - case "hasBackgroundLocationPermission": - result.success(hasBackgroundLocationPermission()); - break; - case "hasActivityRecognitionPermission": - result.success(hasActivityRecognitionPermission()); - break; - case "requestLocationPermission": - requestLocationPermission(); - break; - case "requestBackgroundLocationPermission": - requestBackgroundLocationPermission(); - break; - case "requestActivityRecognitionPermission": - requestActivityRecognitionPermission(); - break; - default: - break; - } - } - - @Override - public boolean onRequestPermissionsResult(final int requestCode, final String[] permissions, - final int[] grantResults) { - final Result incomingResult = result; - result = null; - - if (incomingResult != null) { - if (requestCode == 1) { - incomingResult.success(grantResults[0] == 0 || grantResults[1] == 0); - } else if (requestCode == 3) { - incomingResult.success((grantResults[0] == 0 || grantResults[1] == 0) && grantResults[2] == 0); - } else { - incomingResult.success(checkGrantStatus(grantResults)); - } - } - return true; - } -} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/listeners/DefaultFailureListener.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/listeners/DefaultFailureListener.java deleted file mode 100644 index c0a45044..00000000 --- a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/listeners/DefaultFailureListener.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package com.huawei.hms.flutter.location.listeners; - -import android.content.Context; - -import com.huawei.hmf.tasks.OnFailureListener; -import com.huawei.hms.common.ApiException; -import com.huawei.hms.flutter.location.logger.HMSLogger; -import com.huawei.hms.flutter.location.utils.ObjectUtils; - -import io.flutter.plugin.common.MethodChannel.Result; - -public class DefaultFailureListener implements OnFailureListener { - private final String methodName; - private final Context context; - private final Result result; - - public DefaultFailureListener(final String methodName, final Context context, final Result result) { - this.methodName = methodName; - this.context = context; - this.result = result; - } - - @Override - public void onFailure(final Exception e) { - final ApiException ex = ObjectUtils.cast(e, ApiException.class); - final String statusCodeString = Integer.toString(ex.getStatusCode()); - - HMSLogger.getInstance(context).sendSingleEvent(methodName, statusCodeString); - result.error(statusCodeString, ex.getMessage(), null); - } -} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/listeners/DefaultSuccessListener.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/listeners/DefaultSuccessListener.java deleted file mode 100644 index 3576ad59..00000000 --- a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/listeners/DefaultSuccessListener.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package com.huawei.hms.flutter.location.listeners; - -import android.content.Context; -import android.location.Location; - -import com.huawei.hmf.tasks.OnSuccessListener; -import com.huawei.hms.flutter.location.logger.HMSLogger; -import com.huawei.hms.flutter.location.utils.LocationUtils; -import com.huawei.hms.flutter.location.utils.ObjectUtils; -import com.huawei.hms.location.HWLocation; -import com.huawei.hms.location.LocationAvailability; -import com.huawei.hms.location.LocationSettingsResponse; -import com.huawei.hms.location.LocationSettingsStates; -import com.huawei.hms.location.NavigationResult; - -import io.flutter.plugin.common.MethodChannel.Result; - -public class DefaultSuccessListener implements OnSuccessListener { - private final String methodName; - private final Context context; - private final Result result; - - public DefaultSuccessListener(final String methodName, final Context context, final Result result) { - this.methodName = methodName; - this.context = context; - this.result = result; - } - - @Override - public void onSuccess(final T o) { - HMSLogger.getInstance(context).sendSingleEvent(methodName); - - if (o instanceof Void || o == null) { - result.success(null); - } - - if (o instanceof Location) { - final Location location = ObjectUtils.cast(o, Location.class); - result.success(LocationUtils.fromLocationToMap(location)); - } - - if (o instanceof HWLocation) { - final HWLocation hwLocation = ObjectUtils.cast(o, HWLocation.class); - result.success(LocationUtils.fromHWLocationToMap(hwLocation)); - } - - if (o instanceof LocationAvailability) { - final LocationAvailability locationAvailability = ObjectUtils.cast(o, LocationAvailability.class); - result.success(LocationUtils.fromLocationAvailabilityToMap(locationAvailability)); - } - - if (o instanceof LocationSettingsResponse) { - final LocationSettingsResponse response = ObjectUtils.cast(o, LocationSettingsResponse.class); - final LocationSettingsStates locationSettingsStates = response.getLocationSettingsStates(); - result.success(LocationUtils.fromLocationSettingsStatesToMap(locationSettingsStates)); - } - - if (o instanceof NavigationResult) { - final NavigationResult navigationResult = ObjectUtils.cast(o, NavigationResult.class); - result.success(LocationUtils.fromNavigationResultToMap(navigationResult)); - } - } -} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/listeners/LocationSettingsFailureListener.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/listeners/LocationSettingsFailureListener.java deleted file mode 100644 index 361e5c8e..00000000 --- a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/listeners/LocationSettingsFailureListener.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package com.huawei.hms.flutter.location.listeners; - -import static com.huawei.hms.location.LocationSettingsStatusCodes.RESOLUTION_REQUIRED; - -import android.app.Activity; -import android.content.IntentSender.SendIntentException; - -import com.huawei.hmf.tasks.OnFailureListener; -import com.huawei.hms.common.ApiException; -import com.huawei.hms.common.ResolvableApiException; -import com.huawei.hms.flutter.location.constants.Error; -import com.huawei.hms.flutter.location.logger.HMSLogger; -import com.huawei.hms.flutter.location.utils.ObjectUtils; - -import io.flutter.plugin.common.MethodChannel.Result; - -public class LocationSettingsFailureListener implements OnFailureListener { - private final Result result; - private final Activity activity; - - public LocationSettingsFailureListener(final Result result, final Activity activity) { - this.result = result; - this.activity = activity; - } - - @Override - public void onFailure(final Exception e) { - final ApiException apiException = ObjectUtils.cast(e, ApiException.class); - final int statusCode = apiException.getStatusCode(); - final String statusCodeString = Integer.toString(statusCode); - - if (statusCode == RESOLUTION_REQUIRED) { - try { - final ResolvableApiException resolvableApiException = ObjectUtils.cast(e, ResolvableApiException.class); - resolvableApiException.startResolutionForResult(activity, 0); - } catch (final SendIntentException ex) { - HMSLogger.getInstance(activity.getApplicationContext()).sendSingleEvent("checkLocationSettings", "-1"); - result.error(Error.SEND_INTENT_EXCEPTION.name(), ex.getMessage(), null); - } - } else { - HMSLogger.getInstance(activity.getApplicationContext()) - .sendSingleEvent("checkLocationSettings", statusCodeString); - result.error(statusCodeString, apiException.getMessage(), null); - } - } -} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/listeners/RemoveUpdatesSuccessListener.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/listeners/RemoveUpdatesSuccessListener.java deleted file mode 100644 index ff83dca9..00000000 --- a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/listeners/RemoveUpdatesSuccessListener.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package com.huawei.hms.flutter.location.listeners; - -import android.content.Context; - -import com.huawei.hmf.tasks.OnSuccessListener; -import com.huawei.hms.flutter.location.logger.HMSLogger; - -import java.util.Map; - -import io.flutter.plugin.common.MethodChannel.Result; - -public class RemoveUpdatesSuccessListener implements OnSuccessListener { - private final String methodName; - private final Context context; - private final Result result; - private final Integer id; - private final Map map; - - public RemoveUpdatesSuccessListener(final String methodName, final Context context, final Result result, - final Integer id, final Map map) { - this.methodName = methodName; - this.context = context; - this.result = result; - this.id = id; - this.map = map; - } - - @Override - public void onSuccess(final Void avoid) { - map.remove(id); - HMSLogger.getInstance(context).sendSingleEvent(methodName); - result.success(null); - } -} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/listeners/RequestUpdatesFailureListener.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/listeners/RequestUpdatesFailureListener.java deleted file mode 100644 index 6bc0131f..00000000 --- a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/listeners/RequestUpdatesFailureListener.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package com.huawei.hms.flutter.location.listeners; - -import android.content.Context; - -import com.huawei.hmf.tasks.OnFailureListener; -import com.huawei.hms.common.ApiException; -import com.huawei.hms.flutter.location.logger.HMSLogger; -import com.huawei.hms.flutter.location.utils.ObjectUtils; - -import java.util.Map; - -import io.flutter.plugin.common.MethodChannel.Result; - -public class RequestUpdatesFailureListener implements OnFailureListener { - private final String methodName; - private final Context context; - private final Result result; - private final Integer id; - private final Map map; - - public RequestUpdatesFailureListener(final String methodName, final Context context, final Result result, - final Integer id, final Map map) { - this.methodName = methodName; - this.context = context; - this.result = result; - this.id = id; - this.map = map; - } - - @Override - public void onFailure(final Exception e) { - final ApiException ex = ObjectUtils.cast(e, ApiException.class); - final String statusCodeString = Integer.toString(ex.getStatusCode()); - - map.remove(id); - HMSLogger.getInstance(context).sendSingleEvent(methodName, statusCodeString); - result.error(statusCodeString, ex.getMessage(), null); - } -} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/listeners/RequestUpdatesSuccessListener.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/listeners/RequestUpdatesSuccessListener.java deleted file mode 100644 index b90fbd2d..00000000 --- a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/listeners/RequestUpdatesSuccessListener.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package com.huawei.hms.flutter.location.listeners; - -import android.content.Context; - -import com.huawei.hmf.tasks.OnSuccessListener; -import com.huawei.hms.flutter.location.logger.HMSLogger; - -import io.flutter.plugin.common.MethodChannel.Result; - -public class RequestUpdatesSuccessListener implements OnSuccessListener { - private final Result result; - private final Integer requestCode; - private final Context context; - private final String methodName; - - public RequestUpdatesSuccessListener(final String methodName, final Context context, final Result result, - final Integer requestCode) { - this.methodName = methodName; - this.context = context; - this.result = result; - this.requestCode = requestCode; - } - - @Override - public void onSuccess(final Void avoid) { - HMSLogger.getInstance(context).sendSingleEvent(methodName); - result.success(requestCode); - } -} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/logger/HMSLogger.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/logger/HMSLogger.java deleted file mode 100644 index 80af0462..00000000 --- a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/logger/HMSLogger.java +++ /dev/null @@ -1,449 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package com.huawei.hms.flutter.location.logger; - -import static android.os.Build.DEVICE; - -import android.content.Context; -import android.content.pm.PackageManager; -import android.net.ConnectivityManager; -import android.net.NetworkCapabilities; -import android.util.Log; - -import com.huawei.agconnect.config.AGConnectServicesConfig; -import com.huawei.hms.support.hianalytics.HiAnalyticsUtils; -import com.huawei.hms.utils.HMSBIInitializer; - -import java.lang.ref.WeakReference; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; - -public final class HMSLogger { - private static final String TAG = "HMSLogger"; - - private static final String VERSION = "5.0.0.301"; - private static final String SERVICE = "FlutterLocation"; - - private static final String SUCCESS = "0"; - private static final String UNKNOWN = "UNKNOWN"; - private static final String NOT_AVAILABLE = "NOT_AVAILABLE"; - - private static final String SINGLE_EVENT_ID = "60000"; - private static final String PERIODIC_EVENT_ID = "60001"; - - private static final String NETWORK_TYPE_WIFI = "WIFI"; - - private static volatile HMSLogger instance; - - private final WeakReference weakContext; - private final HiAnalyticsUtils hiAnalyticsUtils; - - private final Map singleEventMap = new HashMap<>(); - private final Map periodicEventMap = new HashMap<>(); - private final Map allCountMap = new HashMap<>(); - private final Map failCountMap = new HashMap<>(); - private final Map startTimeMap = new HashMap<>(); - private final Map firstReceiveTimeMap = new HashMap<>(); - private final Map lastReceiveTimeMap = new HashMap<>(); - private final Map> resultCodeCountMap = new HashMap<>(); - private final Map networkTypeMap = createNetworkTypeMap(); - - private boolean isEnabled = true; - - /** - * Private constructor of this class - * - * @param context Application's context - */ - private HMSLogger(final Context context) { - weakContext = new WeakReference<>(context); - hiAnalyticsUtils = HiAnalyticsUtils.getInstance(); - - setupEventMap(singleEventMap); - setupEventMap(periodicEventMap); - initHMSBI(HMSBIInitializer.getInstance(context)); - - Log.d(TAG, "HMS Plugin Dotting is Enabled!"); - } - - /** - * Returns the instance of this class - * - * @param context Application's context - * @return HMSLogger instance - */ - public static synchronized HMSLogger getInstance(final Context context) { - if (instance == null) { - synchronized (HMSLogger.class) { - if (instance == null) { - instance = new HMSLogger(context); - } - } - } - return instance; - } - - /** - * Returns actual context reference - * - * @return Actual context reference - */ - private Context getContext() { - return weakContext.get(); - } - - /** - * Enables HMSLogger - */ - public synchronized void enableLogger() { - isEnabled = true; - Log.d(TAG, "HMS Plugin Dotting is Enabled!"); - } - - /** - * Disables HMSLogger - */ - public synchronized void disableLogger() { - isEnabled = false; - Log.d(TAG, "HMS Plugin Dotting is Disabled!"); - } - - /** - * Sets method start time for given method name - * - * @param methodName Name of the method that will be logged - */ - public synchronized void startMethodExecutionTimer(final String methodName) { - startTimeMap.put(methodName, System.currentTimeMillis()); - } - - /** - * Sends successful single event - * - * @param methodName The name of the method called - */ - public synchronized void sendSingleEvent(final String methodName) { - sendEvent(SINGLE_EVENT_ID, methodName, SUCCESS); - } - - /** - * Sends unsuccessful single event - * - * @param methodName The name of the method called - * @param errorCode API error code - */ - public synchronized void sendSingleEvent(final String methodName, final String errorCode) { - sendEvent(SINGLE_EVENT_ID, methodName, errorCode); - } - - /** - * Sends successful periodic event - * - * @param methodName The name of the method called - */ - public synchronized void sendPeriodicEvent(final String methodName) { - sendEvent(PERIODIC_EVENT_ID, methodName, SUCCESS); - } - - /** - * Sends unsuccessful periodic event - * - * @param methodName The name of the method called - * @param errorCode API error code - */ - public synchronized void sendPeriodicEvent(final String methodName, final String errorCode) { - sendEvent(PERIODIC_EVENT_ID, methodName, errorCode); - } - - /** - * Calls initBI() method from HMSBIInitializer - * - * @param initializer HMSBIInitializer object - */ - private void initHMSBI(final HMSBIInitializer initializer) { - if (!initializer.isInit()) { - initializer.initBI(); - } - } - - /** - * Sends the event based on eventId, methodName, and resultCode - * - * @param eventId Constant id of the event - * @param methodName The name of the method called - * @param resultCode Code of the method's result. "0" for success, others for error - */ - private synchronized void sendEvent(final String eventId, final String methodName, final String resultCode) { - if (isEnabled) { - final long currentTime = System.currentTimeMillis(); - - if (eventId.equals(SINGLE_EVENT_ID)) { - putToSingleEventMap(methodName, resultCode, currentTime); - hiAnalyticsUtils.onNewEvent(getContext(), SINGLE_EVENT_ID, singleEventMap); - - Log.d(TAG, "singleEventMap -> " + singleEventMap); - } else { - putToPeriodicEventMap(methodName, resultCode, currentTime); - hiAnalyticsUtils.onNewEvent(getContext(), PERIODIC_EVENT_ID, periodicEventMap); - - Log.d(TAG, "periodicEventMap -> " + periodicEventMap); - } - } - } - - /** - * Gets "client/app_id" value from agconnect-services.json file - * - * @return app_id value or NOT_AVAILABLE if not found - */ - private String getAppId() { - try { - return AGConnectServicesConfig.fromContext(getContext()).getString("client/app_id"); - } catch (final NullPointerException e) { - Log.d(TAG, "AgConnect is not found. Setting appId value to " + NOT_AVAILABLE); - } - return NOT_AVAILABLE; - } - - /** - * Gets app version name - * - * @param packageName Package name of the app - * @return App version name in String type - */ - private String getAppVersionName(final String packageName) { - try { - return getContext().getPackageManager().getPackageInfo(packageName, 0).versionName; - } catch (final PackageManager.NameNotFoundException e) { - Log.e(TAG, "getAppVersionName -> Could not get appVersionName!"); - return NOT_AVAILABLE; - } - } - - /** - * Detects current network type - * - * @return Human readable network type; such as WIFI, LTE - */ - private String getNetworkType() { - final ConnectivityManager cm = objectCast(getContext().getSystemService(Context.CONNECTIVITY_SERVICE), - ConnectivityManager.class); - if (cm != null) { - if (cm.getActiveNetworkInfo() == null || !cm.getActiveNetworkInfo().isConnected()) { - return NOT_AVAILABLE; - } - - final int networkSubtype = Objects.requireNonNull(cm.getActiveNetworkInfo()).getSubtype(); - final String networkSubtypeString = getOrDefault(networkTypeMap, networkSubtype, UNKNOWN); - - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { - final NetworkCapabilities capabilities = cm.getNetworkCapabilities(cm.getActiveNetwork()); - if (capabilities != null) { - if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) { - return networkSubtypeString; - } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) { - return NETWORK_TYPE_WIFI; - } else { - return UNKNOWN; - } - } else { - return NOT_AVAILABLE; - } - } else { - final int networkType = Objects.requireNonNull(cm.getActiveNetworkInfo()).getType(); - switch (networkType) { - case ConnectivityManager.TYPE_WIFI: - return NETWORK_TYPE_WIFI; - case ConnectivityManager.TYPE_MOBILE: - return networkSubtypeString; - default: - return UNKNOWN; - } - } - } - return NOT_AVAILABLE; - } - - /** - * Sets default values to given map - * - * @param map HashMap to put default values - */ - private void setupEventMap(final Map map) { - map.put("version", VERSION); - map.put("service", SERVICE); - map.put("appid", getAppId()); - map.put("package", getContext().getPackageName()); - map.put("cpAppVersion", getAppVersionName(getContext().getPackageName())); - map.put("model", DEVICE); - } - - /** - * Prepares sing-event map according to input parameters - * - * @param methodName The name of the method called - * @param resultCode Code of the method's result. "0" for success, others for error - * @param currentTime Current timestamp in millisecond - */ - private void putToSingleEventMap(final String methodName, final String resultCode, final long currentTime) { - final long startTime = getOrDefault(startTimeMap, methodName, currentTime); - final int costTime = (int) (currentTime - startTime); - singleEventMap.put("apiName", methodName); - singleEventMap.put("result", resultCode); - singleEventMap.put("callTime", currentTime); - singleEventMap.put("costTime", costTime); - singleEventMap.put("networkType", getNetworkType()); - } - - /** - * Prepares periodic-event map according to input parameters - * - * @param methodName The name of the method called - * @param resultCode Code of the method's result. "0" for success, others for error - * @param currentTime Current timestamp in millisecond - */ - private void putToPeriodicEventMap(final String methodName, final String resultCode, final long currentTime) { - increaseResultCodeCount(methodName, resultCode); - increaseMapValue(methodName, allCountMap); - - if (!resultCode.equals(SUCCESS)) { - increaseMapValue(methodName, failCountMap); - } - - final long firstReceiveTime = getOrDefault(firstReceiveTimeMap, methodName, currentTime); - periodicEventMap.put("callTime", firstReceiveTime); - - final long lastReceiveTime = getOrDefault(lastReceiveTimeMap, methodName, currentTime); - final int costTime = (int) (currentTime - lastReceiveTime); - periodicEventMap.put("costTime", costTime); - - periodicEventMap.put("apiName", methodName); - periodicEventMap.put("result", resultCodeCountMap.get(methodName)); - - final long allCount = getOrDefault(allCountMap, methodName, 0L); - periodicEventMap.put("allCnt", allCount); - - final long failCount = getOrDefault(failCountMap, methodName, 0L); - periodicEventMap.put("failCnt", failCount); - - periodicEventMap.put("lastCallTime", currentTime); - periodicEventMap.put("networkType", getNetworkType()); - - putIfAbsent(firstReceiveTimeMap, methodName, currentTime); - lastReceiveTimeMap.put(methodName, currentTime); - } - - /** - * Prepares HashMap of network type id and its human-readable string pairs - * - * @return HashMap of human readable network type names - */ - private Map createNetworkTypeMap() { - final Map map = new HashMap<>(); - - map.put(0, UNKNOWN); - map.put(1, "2.5G"); - map.put(2, "2.75G"); - map.put(3, "3G"); - map.put(4, "2G"); - map.put(5, "3G"); - map.put(6, "3G"); - map.put(7, "2G"); - map.put(8, "3G"); - map.put(9, "3G"); - map.put(10, "3G"); - map.put(11, "2G"); - map.put(12, "3G"); - map.put(13, "4G"); - map.put(14, "3G"); - map.put(15, "3G"); - map.put(16, "2G"); - map.put(17, "3G"); - map.put(18, "4G"); - map.put(19, "4G"); - map.put(20, "5G"); - - return Collections.unmodifiableMap(map); - } - - /** - * Increases count of the given result code - * - * @param methodName Name of the calling method - * @param resultCode Code of the method's result. "0" for success, others for error - */ - private void increaseResultCodeCount(final String methodName, final String resultCode) { - final Map map = getOrDefault(resultCodeCountMap, methodName, new HashMap<>()); - - increaseMapValue(resultCode, map); - resultCodeCountMap.put(methodName, map); - } - - /** - * Increases the value of the corresponding key which in the map - * - * @param key Key for map lookup - * @param map The Map that contains the key and its corresponding value - */ - private void increaseMapValue(final String key, final Map map) { - map.put(key, getOrDefault(map, key, 0L) + 1); - } - - /** - * Get the corresponding value of the key. If the key does not exist in the map then the default value is returned. - * - * @param map The Map - * @param key Lookup key - * @param defaultValue The default value will be returned if the key is absent - * @param Generic type of the key - * @param Generic type of the value - * @return Corresponding value or default value - */ - private V getOrDefault(final Map map, final K key, final V defaultValue) { - return map.containsKey(key) ? map.get(key) : defaultValue; - } - - /** - * Put key-value pair to map if the key is absent - * - * @param map The Map - * @param key Lookup key - * @param value The value will be put to the map if the key is absent - * @param Generic type of the key - * @param Generic type of the value - */ - private void putIfAbsent(final Map map, final K key, final V value) { - if (!map.containsKey(key)) { - map.put(key, value); - } - } - - /** - * Utility method that castes given object to given class type - * - * @param source Source object to be casted - * @param clazz Class that object will be casted to its type - * @param Source object's type - * @param Destination type - * @return Object that casted to D type - */ - private D objectCast(final S source, final Class clazz) { - return clazz.cast(source); - } -} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/receivers/ActivityConversionBroadcastReceiver.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/receivers/ActivityConversionBroadcastReceiver.java deleted file mode 100644 index 06d8e231..00000000 --- a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/receivers/ActivityConversionBroadcastReceiver.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package com.huawei.hms.flutter.location.receivers; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; - -import com.huawei.hms.flutter.location.logger.HMSLogger; -import com.huawei.hms.flutter.location.utils.ActivityUtils; -import com.huawei.hms.location.ActivityConversionResponse; - -import io.flutter.plugin.common.EventChannel.EventSink; - -public class ActivityConversionBroadcastReceiver extends BroadcastReceiver { - private final EventSink eventSink; - - public ActivityConversionBroadcastReceiver(final EventSink eventSink) { - this.eventSink = eventSink; - } - - @Override - public void onReceive(final Context context, final Intent intent) { - if (ActivityConversionResponse.containDataFromIntent(intent)) { - final ActivityConversionResponse response = ActivityConversionResponse.getDataFromIntent(intent); - - HMSLogger.getInstance(context).sendPeriodicEvent("ActivityConversionUpdates"); - eventSink.success(ActivityUtils.activityConversionResponseToMap(response)); - } - } -} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/receivers/ActivityIdentificationBroadcastReceiver.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/receivers/ActivityIdentificationBroadcastReceiver.java deleted file mode 100644 index bb2c9666..00000000 --- a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/receivers/ActivityIdentificationBroadcastReceiver.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package com.huawei.hms.flutter.location.receivers; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; - -import com.huawei.hms.flutter.location.logger.HMSLogger; -import com.huawei.hms.flutter.location.utils.ActivityUtils; -import com.huawei.hms.location.ActivityIdentificationResponse; - -import io.flutter.plugin.common.EventChannel.EventSink; - -public class ActivityIdentificationBroadcastReceiver extends BroadcastReceiver { - private final EventSink eventSink; - - public ActivityIdentificationBroadcastReceiver(final EventSink eventSink) { - this.eventSink = eventSink; - } - - @Override - public void onReceive(final Context context, final Intent intent) { - if (ActivityIdentificationResponse.containDataFromIntent(intent)) { - final ActivityIdentificationResponse response = ActivityIdentificationResponse.getDataFromIntent(intent); - - HMSLogger.getInstance(context).sendPeriodicEvent("ActivityIdentificationUpdates"); - eventSink.success(ActivityUtils.activityIdentificationResponseToMap(response)); - } - } -} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/receivers/FusedLocationBroadcastReceiver.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/receivers/FusedLocationBroadcastReceiver.java deleted file mode 100644 index dcdfbd49..00000000 --- a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/receivers/FusedLocationBroadcastReceiver.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package com.huawei.hms.flutter.location.receivers; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.location.Location; - -import com.huawei.hms.flutter.location.logger.HMSLogger; -import com.huawei.hms.flutter.location.utils.LocationUtils; -import com.huawei.hms.location.LocationResult; - -import io.flutter.plugin.common.EventChannel.EventSink; - -public class FusedLocationBroadcastReceiver extends BroadcastReceiver { - private final EventSink eventSink; - - public FusedLocationBroadcastReceiver(final EventSink eventSink) { - this.eventSink = eventSink; - } - - @Override - public void onReceive(final Context context, final Intent intent) { - if (LocationResult.hasResult(intent)) { - HMSLogger.getInstance(context).sendPeriodicEvent("LocationUpdates"); - for (final Location location : LocationResult.extractResult(intent).getLocations()) { - eventSink.success(LocationUtils.fromLocationToMap(location)); - } - } - } -} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/receivers/GeofenceBroadcastReceiver.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/receivers/GeofenceBroadcastReceiver.java deleted file mode 100644 index ae9f5451..00000000 --- a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/receivers/GeofenceBroadcastReceiver.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package com.huawei.hms.flutter.location.receivers; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; - -import com.huawei.hms.flutter.location.logger.HMSLogger; -import com.huawei.hms.flutter.location.utils.GeofenceUtils; -import com.huawei.hms.location.GeofenceData; - -import io.flutter.plugin.common.EventChannel.EventSink; - -public class GeofenceBroadcastReceiver extends BroadcastReceiver { - private final EventSink eventSink; - - public GeofenceBroadcastReceiver(final EventSink eventSink) { - this.eventSink = eventSink; - } - - @Override - public void onReceive(final Context context, final Intent intent) { - if (intent != null) { - final GeofenceData geofenceData = GeofenceData.getDataFromIntent(intent); - HMSLogger.getInstance(context).sendPeriodicEvent("GeofenceUpdates"); - eventSink.success(GeofenceUtils.fromGeofenceDataToMap(geofenceData)); - } - } -} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/utils/ActivityUtils.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/utils/ActivityUtils.java deleted file mode 100644 index 6600697a..00000000 --- a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/utils/ActivityUtils.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package com.huawei.hms.flutter.location.utils; - -import com.huawei.hms.location.ActivityConversionData; -import com.huawei.hms.location.ActivityConversionInfo; -import com.huawei.hms.location.ActivityConversionRequest; -import com.huawei.hms.location.ActivityConversionResponse; -import com.huawei.hms.location.ActivityIdentificationData; -import com.huawei.hms.location.ActivityIdentificationResponse; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public interface ActivityUtils { - /** - * Utility method - * @param list List of the ActivityConversionInfo - * @return ActivityConversionRequest object - */ - static ActivityConversionRequest fromActivityConversionInfoListToActivityConversionRequest( - final List> list) { - final List activityConversionInfos = new ArrayList<>(); - - for (final Map map : list) { - activityConversionInfos.add(fromMapToActivityConversionInfo(map)); - } - - return new ActivityConversionRequest(activityConversionInfos); - } - - /** - * Utility method - * @param map HashMap representation of the ActivityConversionInfo object - * @return ActivityConversionInfo object - */ - static ActivityConversionInfo fromMapToActivityConversionInfo(final Map map) { - return new ActivityConversionInfo(ValueGetter.getInt("activityType", map), - ValueGetter.getInt("conversionType", map)); - } - - /** - * Utility method - * @param data ActivityIdentificationData object - * @return HashMap representation of ActivityIdentificationData object - */ - static Map activityIdentificationDataToMap(final ActivityIdentificationData data) { - final Map map = new HashMap<>(); - - if (data == null) { - return map; - } - - map.put("identificationActivity", data.getIdentificationActivity()); - map.put("possibility", data.getPossibility()); - - return map; - } - - /** - * Utility method - * @param response ActivityIdentificationResponse object - * @return HashMap representation of ActivityIdentificationResponse object - */ - static Map activityIdentificationResponseToMap(final ActivityIdentificationResponse response) { - final Map map = new HashMap<>(); - - if (response == null) { - return map; - } - - map.put("time", response.getTime()); - map.put("elapsedTimeFromReboot", response.getElapsedTimeFromReboot()); - - final List> activityIdentificationDatas = new ArrayList<>(); - for (final ActivityIdentificationData data : response.getActivityIdentificationDatas()) { - activityIdentificationDatas.add(activityIdentificationDataToMap(data)); - } - map.put("activityIdentificationDatas", activityIdentificationDatas); - - return map; - } - - /** - * Utility method - * @param data ActivityConversionData object - * @return HashMap representation of the ActivityConversionData object - */ - static Map activityConversionDataToMap(final ActivityConversionData data) { - final Map map = new HashMap<>(); - - if (data == null) { - return map; - } - - map.put("activityType", data.getActivityType()); - map.put("conversionType", data.getConversionType()); - map.put("elapsedTimeFromReboot", data.getElapsedTimeFromReboot()); - - return map; - } - - /** - * Utility method - * @param response ActivityConversionResponse object - * @return HashMap representation of the ActivityConversionResponse object - */ - static Map activityConversionResponseToMap(final ActivityConversionResponse response) { - final Map map = new HashMap<>(); - - if (response == null) { - return map; - } - - final List> activityConversionDatas = new ArrayList<>(); - - for (final ActivityConversionData data : response.getActivityConversionDatas()) { - activityConversionDatas.add(ActivityUtils.activityConversionDataToMap(data)); - } - - map.put("activityConversionDatas", activityConversionDatas); - return map; - } -} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/utils/GeofenceUtils.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/utils/GeofenceUtils.java deleted file mode 100644 index d79cf75d..00000000 --- a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/utils/GeofenceUtils.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package com.huawei.hms.flutter.location.utils; - -import com.huawei.hms.location.Geofence; -import com.huawei.hms.location.GeofenceData; -import com.huawei.hms.location.GeofenceRequest; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public interface GeofenceUtils { - /** - * Utility method - * @param geofenceData GeofenceData object - * @return HashMap representation of the GeofenceData object - */ - static Map fromGeofenceDataToMap(final GeofenceData geofenceData) { - if (geofenceData == null) { - return Collections.emptyMap(); - } - - final Map map = new HashMap<>(); - final List convertingGeofenceIdList = new ArrayList<>(); - - for (final Geofence geofence : geofenceData.getConvertingGeofenceList()) { - convertingGeofenceIdList.add(geofence.getUniqueId()); - } - - map.put("errorCode", geofenceData.getErrorCode()); - map.put("conversion", geofenceData.getConversion()); - map.put("convertingGeofenceIdList", convertingGeofenceIdList); - map.put("convertingLocation", LocationUtils.fromLocationToMap(geofenceData.getConvertingLocation())); - - return map; - } - - /** - * Utility method - * @param map HashMap representation of the Geofence object - * @return Geofence object - */ - static Geofence fromMapToGeofence(final Map map) { - final Geofence.Builder builder = new Geofence.Builder(); - - final double lat = ValueGetter.getDouble("latitude", map); - final double lng = ValueGetter.getDouble("longitude", map); - final float rad = ValueGetter.getFloat("radius", map); - - builder.setRoundArea(lat, lng, rad); - builder.setUniqueId(ValueGetter.getString("uniqueId", map)); - builder.setConversions(ValueGetter.getInt("conversions", map)); - builder.setDwellDelayTime(ValueGetter.getInt("dwellDelayTime", map)); - builder.setValidContinueTime(ValueGetter.getLong("validDuration", map)); - builder.setNotificationInterval(ValueGetter.getInt("notificationInterval", map)); - - return builder.build(); - } - - /** - * Utility method - * @param map HashMap representation of the GeofenceRequest object - * @return GeofenceRequest object - */ - static GeofenceRequest fromMapToGeofenceRequest(final Map map) { - final GeofenceRequest.Builder builder = new GeofenceRequest.Builder(); - final List geofenceMapList = ObjectUtils.cast(map.get("geofenceList"), List.class); - - if (geofenceMapList != null) { - for (final Object geofence : geofenceMapList) { - final Map geofenceMap = ObjectUtils.cast(geofence, Map.class); - builder.createGeofence(fromMapToGeofence(geofenceMap)); - } - } - - builder.setCoordinateType(ValueGetter.getInt("coordinateType", map)); - builder.setInitConversions(ValueGetter.getInt("initConversions", map)); - - return builder.build(); - } -} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/utils/LocationUtils.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/utils/LocationUtils.java deleted file mode 100644 index 36931b67..00000000 --- a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/utils/LocationUtils.java +++ /dev/null @@ -1,309 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package com.huawei.hms.flutter.location.utils; - -import android.location.Location; -import android.os.Build.VERSION; -import android.os.Build.VERSION_CODES; - -import com.huawei.hms.location.HWLocation; -import com.huawei.hms.location.LocationAvailability; -import com.huawei.hms.location.LocationRequest; -import com.huawei.hms.location.LocationResult; -import com.huawei.hms.location.LocationSettingsRequest; -import com.huawei.hms.location.LocationSettingsStates; -import com.huawei.hms.location.NavigationRequest; -import com.huawei.hms.location.NavigationResult; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -public interface LocationUtils { - /** - * Utility method - * @param location ActivityIdentificationData object - * @return HashMap representation of Location object - */ - static Map fromLocationToMap(final Location location) { - if (location == null) { - return Collections.emptyMap(); - } - - final Map map = new HashMap<>(); - - map.put("provider", location.getProvider()); - map.put("latitude", location.getLatitude()); - map.put("longitude", location.getLongitude()); - map.put("altitude", location.getAltitude()); - map.put("speed", location.getSpeed()); - map.put("bearing", location.getBearing()); - map.put("horizontalAccuracyMeters", location.getAccuracy()); - map.put("time", location.getTime()); - map.put("elapsedRealtimeNanos", location.getElapsedRealtimeNanos()); - map.put("isFromMockProvider", location.isFromMockProvider()); - - if (VERSION.SDK_INT >= VERSION_CODES.O) { - map.put("verticalAccuracyMeters", location.getVerticalAccuracyMeters()); - map.put("speedAccuracyMetersPerSecond", location.getSpeedAccuracyMetersPerSecond()); - map.put("bearingAccuracyDegrees", location.getBearingAccuracyDegrees()); - } else { - map.put("verticalAccuracyMeters", 0.0); - map.put("speedAccuracyMetersPerSecond", 0.0); - map.put("bearingAccuracyDegrees", 0.0); - } - - return map; - } - - /** - * Utility method - * @param hwLocation HWLocation object - * @return HashMap representation of HWLocation object - */ - static Map fromHWLocationToMap(final HWLocation hwLocation) { - if (hwLocation == null) { - return Collections.emptyMap(); - } - - final Map map = new HashMap<>(); - - map.put("provider", hwLocation.getProvider()); - map.put("latitude", hwLocation.getLatitude()); - map.put("longitude", hwLocation.getLongitude()); - map.put("altitude", hwLocation.getAltitude()); - map.put("speed", hwLocation.getSpeed()); - map.put("bearing", hwLocation.getBearing()); - map.put("horizontalAccuracyMeters", hwLocation.getAccuracy()); - map.put("verticalAccuracyMeters", hwLocation.getVerticalAccuracyMeters()); - map.put("speedAccuracyMetersPerSecond", hwLocation.getSpeedAccuracyMetersPerSecond()); - map.put("bearingAccuracyDegrees", hwLocation.getBearingAccuracyDegrees()); - map.put("time", hwLocation.getTime()); - map.put("elapsedRealtimeNanos", hwLocation.getElapsedRealtimeNanos()); - map.put("countryCode", hwLocation.getCountryCode()); - map.put("countryName", hwLocation.getCountryName()); - map.put("state", hwLocation.getState()); - map.put("city", hwLocation.getCity()); - map.put("county", hwLocation.getCounty()); - map.put("street", hwLocation.getStreet()); - map.put("featureName", hwLocation.getFeatureName()); - map.put("postalCode", hwLocation.getPostalCode()); - map.put("phone", hwLocation.getPhone()); - map.put("url", hwLocation.getUrl()); - map.put("extraInfo", hwLocation.getExtraInfo()); - - return map; - } - - /** - * Utility method - * @param locationAvailability LocationAvailability object - * @return HashMap representation of LocationAvailability object - */ - static Map fromLocationAvailabilityToMap(final LocationAvailability locationAvailability) { - if (locationAvailability == null) { - return Collections.emptyMap(); - } - - final Map map = new HashMap<>(); - - map.put("cellStatus", locationAvailability.getCellStatus()); - map.put("wifiStatus", locationAvailability.getWifiStatus()); - map.put("elapsedRealtimeNs", locationAvailability.getElapsedRealtimeNs()); - map.put("locationStatus", locationAvailability.getLocationStatus()); - - return map; - } - - /** - * Utility method - * @param locationResult LocationResult object - * @return HashMap representation of LocationResult object - */ - static Map fromLocationResultToMap(final LocationResult locationResult) { - if (locationResult == null) { - return Collections.emptyMap(); - } - - final Map map = new HashMap<>(); - final List> locationMaps = new ArrayList<>(); - final List> hwLocationMaps = new ArrayList<>(); - - for (final Location location : locationResult.getLocations()) { - locationMaps.add(fromLocationToMap(location)); - } - - for (final HWLocation hwLocation : locationResult.getHWLocationList()) { - hwLocationMaps.add(fromHWLocationToMap(hwLocation)); - } - - map.put("locations", locationMaps); - map.put("hwLocations", hwLocationMaps); - map.put("lastLocation", fromLocationToMap(locationResult.getLastLocation())); - map.put("lastHWLocation", fromHWLocationToMap(locationResult.getLastHWLocation())); - - return map; - } - - /** - * Utility method - * @param states LocationSettingsStates object - * @return HashMap representation of LocationSettingsStates object - */ - static Map fromLocationSettingsStatesToMap(final LocationSettingsStates states) { - if (states == null) { - return Collections.emptyMap(); - } - - final Map map = new HashMap<>(); - - map.put("blePresent", states.isBlePresent()); - map.put("bleUsable", states.isBleUsable()); - map.put("gpsPresent", states.isGpsPresent()); - map.put("gpsUsable", states.isGpsUsable()); - map.put("locationPresent", states.isLocationPresent()); - map.put("locationUsable", states.isLocationUsable()); - map.put("networkLocationPresent", states.isNetworkLocationPresent()); - map.put("networkLocationUsable", states.isNetworkLocationUsable()); - - return map; - } - - /** - * Utility method - * @param result NavigationResult object - * @return HashMap representation of NavigationResult object - */ - static Map fromNavigationResultToMap(final NavigationResult result) { - if (result == null) { - return Collections.emptyMap(); - } - - final Map map = new HashMap<>(); - - map.put("state", result.getState()); - map.put("possibility", result.getPossibility()); - - return map; - } - - /** - * Utility method - * @param map HashMap representation of the LocationRequest object - * @return LocationRequest object - */ - static LocationRequest fromMapToLocationRequest(final Map map) { - final boolean isFastestIntervalExplicitlySet = ValueGetter.getBoolean("isFastestIntervalExplicitlySet", map); - - final LocationRequest result = LocationRequest.create(); - - if (isFastestIntervalExplicitlySet) { - result.setFastestInterval(ValueGetter.getLong("fastestInterval", map)); - } - - result.setPriority(ValueGetter.getInt("priority", map)); - result.setInterval(ValueGetter.getLong("interval", map)); - result.setExpirationTime(ValueGetter.getLong("expirationTime", map)); - result.setNumUpdates(ValueGetter.getInt("numUpdates", map)); - result.setSmallestDisplacement(ValueGetter.getFloat("smallestDisplacement", map)); - result.setMaxWaitTime(ValueGetter.getLong("maxWaitTime", map)); - result.setNeedAddress(ValueGetter.getBoolean("needAddress", map)); - result.setLanguage(ValueGetter.getString("language", map)); - result.setCountryCode(ValueGetter.getString("countryCode", map)); - - final Map extras = ObjectUtils.cast(map.get("extras"), Map.class); - - if (extras != null) { - final Set entries = extras.entrySet(); - for (final Object entry : entries) { - final Map.Entry mapEntry = ObjectUtils.cast(entry, Map.Entry.class); - final String key = ObjectUtils.cast(mapEntry.getKey(), String.class); - final String value = ObjectUtils.cast(mapEntry.getValue(), String.class); - result.putExtras(key, value); - } - } - - return result; - } - - /** - * Utility method - * @param map HashMap representation of the NavigationRequest object - * @return NavigationRequest object - */ - static NavigationRequest fromMapToNavigationRequest(final Map map) { - final int type = ValueGetter.getInt("type", map); - final Map extras = ObjectUtils.cast(map.get("extras"), Map.class); - - final NavigationRequest request = new NavigationRequest(type); - request.setExtras(extras); - - return request; - } - - /** - * Utility method - * @param map HashMap representation of the Location object - * @return Location object - */ - static Location fromMapToLocation(final Map map) { - final String provider = ValueGetter.getString("provider", map); - final Location location = new Location(provider); - - location.setLatitude(ValueGetter.getDouble("latitude", map)); - location.setLongitude(ValueGetter.getDouble("longitude", map)); - location.setAltitude(ValueGetter.getDouble("altitude", map)); - location.setSpeed(ValueGetter.getFloat("speed", map)); - location.setBearing(ValueGetter.getFloat("bearing", map)); - location.setAccuracy(ValueGetter.getFloat("horizontalAccuracyMeters", map)); - location.setTime(ValueGetter.getLong("time", map)); - location.setElapsedRealtimeNanos(ValueGetter.getLong("elapsedRealtimeNanos", map)); - - if (VERSION.SDK_INT >= VERSION_CODES.O) { - location.setVerticalAccuracyMeters(ValueGetter.getFloat("verticalAccuracyMeters", map)); - location.setSpeedAccuracyMetersPerSecond(ValueGetter.getFloat("speedAccuracyMetersPerSecond", map)); - location.setBearingAccuracyDegrees(ValueGetter.getFloat("bearingAccuracyDegrees", map)); - } - - return location; - } - - /** - * Utility method - * @param map HashMap representation of the LocationSettingsRequest object - * @return LocationSettingsRequest object - */ - static LocationSettingsRequest fromMapToLocationSettingsRequest(final Map map) { - final LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder(); - final List requests = ObjectUtils.cast(map.get("requests"), List.class); - - if (requests != null) { - for (final Object request : requests) { - final Map requestMap = ObjectUtils.cast(request, Map.class); - builder.addLocationRequest(fromMapToLocationRequest(requestMap)); - } - } - - builder.setAlwaysShow(ValueGetter.getBoolean("alwaysShow", map)); - builder.setNeedBle(ValueGetter.getBoolean("needBle", map)); - - return builder.build(); - } -} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/utils/ObjectUtils.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/utils/ObjectUtils.java deleted file mode 100644 index 395d14a8..00000000 --- a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/utils/ObjectUtils.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package com.huawei.hms.flutter.location.utils; - -public interface ObjectUtils { - /** - * Utility method that castes given object to given class type - * @param source Source object to be casted - * @param clazz Class that object will be casted to its type - * @param Source object's type - * @param Destination type - * @return Object that casted to D type - */ - static D cast(final S source, final Class clazz) { - return clazz.cast(source); - } -} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/utils/ValueGetter.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/utils/ValueGetter.java deleted file mode 100644 index f5d2ba38..00000000 --- a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/utils/ValueGetter.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package com.huawei.hms.flutter.location.utils; - -import java.util.Map; -import java.util.Objects; - -public interface ValueGetter { - /** - * Utility method - * @param key Lookup key for the map - * @param map Map that contains argument keys and values - * @return The "int" value for the corresponding key. - */ - static int getInt(final String key, final Map map) { - final Object value = Objects.requireNonNull(map.get(key)); - if (value instanceof Number) { - return ((Number) value).intValue(); - } else { - throw new IllegalArgumentException(); - } - } - - /** - * Utility method - * @param key Lookup key for the map - * @param map Map that contains argument keys and values - * @return The "long" value for the corresponding key. - */ - static long getLong(final String key, final Map map) { - final Object value = Objects.requireNonNull(map.get(key)); - if (value instanceof Number) { - return ((Number) value).longValue(); - } else { - throw new IllegalArgumentException(); - } - } - - /** - * Utility method - * @param key Lookup key for the map - * @param map Map that contains argument keys and values - * @return The "float" value for the corresponding key. - */ - static float getFloat(final String key, final Map map) { - final Object value = Objects.requireNonNull(map.get(key)); - if (value instanceof Number) { - return ((Number) value).floatValue(); - } else { - throw new IllegalArgumentException(); - } - } - - /** - * Utility method - * @param key Lookup key for the map - * @param map Map that contains argument keys and values - * @return The "double" value for the corresponding key. - */ - static double getDouble(final String key, final Map map) { - final Object value = Objects.requireNonNull(map.get(key)); - if (value instanceof Number) { - return ((Number) value).doubleValue(); - } else { - throw new IllegalArgumentException(); - } - } - - /** - * Utility method - * @param key Lookup key for the map - * @param map Map that contains argument keys and values - * @return The "boolean" value for the corresponding key. - */ - static boolean getBoolean(final String key, final Map map) { - final Object value = Objects.requireNonNull(map.get(key)); - if (value instanceof Boolean) { - return (boolean) value; - } else { - throw new IllegalArgumentException(); - } - } - - /** - * Utility method - * @param key Lookup key for the map - * @param map Map that contains argument keys and values - * @return The "String" value for the corresponding key. - */ - static String getString(final String key, final Map map) { - final Object value = Objects.requireNonNull(map.get(key)); - if (value instanceof String) { - return (String) value; - } else { - throw new IllegalArgumentException(); - } - } -} diff --git a/hms-plugins/flutter-hms-location/ios/Classes/LocationPlugin.h b/hms-plugins/flutter-hms-location/ios/Classes/LocationPlugin.h deleted file mode 100644 index 0676dadb..00000000 --- a/hms-plugins/flutter-hms-location/ios/Classes/LocationPlugin.h +++ /dev/null @@ -1,4 +0,0 @@ -#import - -@interface LocationPlugin : NSObject -@end diff --git a/hms-plugins/flutter-hms-location/ios/Classes/LocationPlugin.m b/hms-plugins/flutter-hms-location/ios/Classes/LocationPlugin.m deleted file mode 100644 index e71b90d2..00000000 --- a/hms-plugins/flutter-hms-location/ios/Classes/LocationPlugin.m +++ /dev/null @@ -1,20 +0,0 @@ -#import "LocationPlugin.h" - -@implementation LocationPlugin -+ (void)registerWithRegistrar:(NSObject*)registrar { - FlutterMethodChannel* channel = [FlutterMethodChannel - methodChannelWithName:@"location" - binaryMessenger:[registrar messenger]]; - LocationPlugin* instance = [[LocationPlugin alloc] init]; - [registrar addMethodCallDelegate:instance channel:channel]; -} - -- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { - if ([@"getPlatformVersion" isEqualToString:call.method]) { - result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]); - } else { - result(FlutterMethodNotImplemented); - } -} - -@end diff --git a/hms-plugins/flutter-hms-location/ios/huawei_location.podspec b/hms-plugins/flutter-hms-location/ios/huawei_location.podspec deleted file mode 100644 index cd8d7142..00000000 --- a/hms-plugins/flutter-hms-location/ios/huawei_location.podspec +++ /dev/null @@ -1,23 +0,0 @@ -# -# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. -# Run `pod lib lint location.podspec' to validate before publishing. -# -Pod::Spec.new do |s| - s.name = 'huawei_location' - s.version = '5.0.0+301' - s.summary = 'HUAWEI Flutter Location Kit plugin.' - s.description = <<-DESC - HUAWEI Flutter Location Kit plugin combines the GPS, Wi-Fi and base station locations to help you quickly obtain precise user locations & build up global positioning capabilities. - DESC - s.homepage = 'https://www.huawei.com' - s.license = { :type => 'Apache 2.0', :file => '../LICENSE' } - s.author = { 'Huawei Technologies' => 'huaweideveloper1@gmail.com' } - s.source = { :git => 'https://github.com/HMS-Core/hms-flutter-plugin/tree/master/flutter-hms-location' } - s.source_files = 'Classes/**/*' - s.public_header_files = 'Classes/**/*.h' - s.dependency 'Flutter' - s.platform = :ios, '8.0' - - # Flutter.framework does not contain a i386 slice. Only x86_64 simulators are supported. - s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' } -end diff --git a/hms-plugins/flutter-hms-location/lib/activity/activity_conversion_data.dart b/hms-plugins/flutter-hms-location/lib/activity/activity_conversion_data.dart deleted file mode 100644 index 8b5c6444..00000000 --- a/hms-plugins/flutter-hms-location/lib/activity/activity_conversion_data.dart +++ /dev/null @@ -1,76 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -import 'dart:convert'; -import 'dart:ui'; - -class ActivityConversionData { - int activityType; - int conversionType; - int elapsedTimeFromReboot; - - ActivityConversionData({ - this.activityType, - this.conversionType, - this.elapsedTimeFromReboot, - }); - - Map toMap() { - return { - 'activityType': activityType, - 'conversionType': conversionType, - 'elapsedTimeFromReboot': elapsedTimeFromReboot, - }; - } - - factory ActivityConversionData.fromMap(Map map) { - if (map == null) return null; - - return ActivityConversionData( - activityType: map['activityType'], - conversionType: map['conversionType'], - elapsedTimeFromReboot: map['elapsedTimeFromReboot'], - ); - } - - String toJson() => json.encode(toMap()); - - factory ActivityConversionData.fromJson(String source) => - ActivityConversionData.fromMap(json.decode(source)); - - @override - String toString() => - 'ActivityConversionData(activityType: $activityType, conversionType: $conversionType, elapsedTimeFromReboot: $elapsedTimeFromReboot)'; - - @override - bool operator ==(Object o) { - if (identical(this, o)) return true; - - return o is ActivityConversionData && - o.activityType == activityType && - o.conversionType == conversionType && - o.elapsedTimeFromReboot == elapsedTimeFromReboot; - } - - @override - int get hashCode { - return hashList([ - activityType, - conversionType, - elapsedTimeFromReboot, - ]); - } -} diff --git a/hms-plugins/flutter-hms-location/lib/activity/activity_conversion_info.dart b/hms-plugins/flutter-hms-location/lib/activity/activity_conversion_info.dart deleted file mode 100644 index 8eae9a55..00000000 --- a/hms-plugins/flutter-hms-location/lib/activity/activity_conversion_info.dart +++ /dev/null @@ -1,73 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -import 'dart:convert'; -import 'dart:ui'; - -class ActivityConversionInfo { - static const int ENTER_ACTIVITY_CONVERSION = 0; - static const int EXIT_ACTIVITY_CONVERSION = 1; - - int activityType; - int conversionType; - - ActivityConversionInfo({ - this.activityType, - this.conversionType, - }); - - Map toMap() { - return { - 'activityType': activityType, - 'conversionType': conversionType, - }; - } - - factory ActivityConversionInfo.fromMap(Map map) { - if (map == null) return null; - - return ActivityConversionInfo( - activityType: map['activityType'], - conversionType: map['conversionType'], - ); - } - - String toJson() => json.encode(toMap()); - - factory ActivityConversionInfo.fromJson(String source) => - ActivityConversionInfo.fromMap(json.decode(source)); - - @override - String toString() => - 'ActivityConversionInfo(activityType: $activityType, conversionType: $conversionType)'; - - @override - bool operator ==(Object o) { - if (identical(this, o)) return true; - - return o is ActivityConversionInfo && - o.activityType == activityType && - o.conversionType == conversionType; - } - - @override - int get hashCode { - return hashList([ - activityType, - conversionType, - ]); - } -} diff --git a/hms-plugins/flutter-hms-location/lib/activity/activity_conversion_response.dart b/hms-plugins/flutter-hms-location/lib/activity/activity_conversion_response.dart deleted file mode 100644 index 28c44158..00000000 --- a/hms-plugins/flutter-hms-location/lib/activity/activity_conversion_response.dart +++ /dev/null @@ -1,71 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -import 'dart:convert'; -import 'dart:ui'; - -import 'package:flutter/foundation.dart'; - -import 'activity_conversion_data.dart'; - -class ActivityConversionResponse { - List activityConversionDatas; - - ActivityConversionResponse({ - this.activityConversionDatas, - }); - - Map toMap() { - return { - 'activityConversionDatas': - activityConversionDatas?.map((x) => x?.toMap())?.toList(), - }; - } - - factory ActivityConversionResponse.fromMap(Map map) { - if (map == null) return null; - - return ActivityConversionResponse( - activityConversionDatas: List.from( - map['activityConversionDatas'] - ?.map((x) => ActivityConversionData.fromMap(x))), - ); - } - - String toJson() => json.encode(toMap()); - - factory ActivityConversionResponse.fromJson(String source) => - ActivityConversionResponse.fromMap(json.decode(source)); - - @override - String toString() => - 'ActivityConversionResponse(activityConversionDatas: $activityConversionDatas)'; - - @override - bool operator ==(Object o) { - if (identical(this, o)) return true; - - return o is ActivityConversionResponse && - listEquals(o.activityConversionDatas, activityConversionDatas); - } - - @override - int get hashCode { - return hashList([ - activityConversionDatas, - ]); - } -} diff --git a/hms-plugins/flutter-hms-location/lib/activity/activity_identification_data.dart b/hms-plugins/flutter-hms-location/lib/activity/activity_identification_data.dart deleted file mode 100644 index ed171175..00000000 --- a/hms-plugins/flutter-hms-location/lib/activity/activity_identification_data.dart +++ /dev/null @@ -1,94 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -import 'dart:convert'; -import 'dart:ui'; - -class ActivityIdentificationData { - static const int VEHICLE = 100; - static const int BIKE = 101; - static const int FOOT = 102; - static const int STILL = 103; - static const int OTHERS = 104; - static const int TILTING = 105; - static const int WALKING = 107; - static const int RUNNING = 108; - - static const List _validTypes = [ - VEHICLE, - BIKE, - FOOT, - STILL, - OTHERS, - TILTING, - WALKING, - RUNNING - ]; - - int identificationActivity; - int possibility; - - ActivityIdentificationData({ - this.identificationActivity, - this.possibility, - }); - - static bool isValidType(int type) { - return _validTypes.contains(type) ? true : false; - } - - Map toMap() { - return { - 'identificationActivity': identificationActivity, - 'possibility': possibility, - }; - } - - factory ActivityIdentificationData.fromMap(Map map) { - if (map == null) return null; - - return ActivityIdentificationData( - identificationActivity: map['identificationActivity'], - possibility: map['possibility'], - ); - } - - String toJson() => json.encode(toMap()); - - factory ActivityIdentificationData.fromJson(String source) => - ActivityIdentificationData.fromMap(json.decode(source)); - - @override - String toString() => - 'ActivityIdentificationData(identificationActivity: $identificationActivity, possibility: $possibility)'; - - @override - bool operator ==(Object o) { - if (identical(this, o)) return true; - - return o is ActivityIdentificationData && - o.identificationActivity == identificationActivity && - o.possibility == possibility; - } - - @override - int get hashCode { - return hashList([ - identificationActivity, - possibility, - ]); - } -} diff --git a/hms-plugins/flutter-hms-location/lib/activity/activity_identification_response.dart b/hms-plugins/flutter-hms-location/lib/activity/activity_identification_response.dart deleted file mode 100644 index c059ca50..00000000 --- a/hms-plugins/flutter-hms-location/lib/activity/activity_identification_response.dart +++ /dev/null @@ -1,106 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -import 'dart:convert'; -import 'dart:ui'; - -import 'package:flutter/foundation.dart'; - -import 'activity_identification_data.dart'; - -class ActivityIdentificationResponse { - int time; - int elapsedTimeFromReboot; - List activityIdentificationDatas; - - ActivityIdentificationResponse({ - this.activityIdentificationDatas, - this.time, - this.elapsedTimeFromReboot, - }); - - ActivityIdentificationData get mostActivityIdentification { - return activityIdentificationDatas != null && - activityIdentificationDatas.length > 0 - ? activityIdentificationDatas[0] - : null; - } - - int getActivityPossibility(int activityType) { - if (activityIdentificationDatas != null && - activityIdentificationDatas.length > 0) { - Iterator iterator = activityIdentificationDatas.iterator; - - while (iterator.moveNext()) { - ActivityIdentificationData currentData = iterator.current; - if (currentData.identificationActivity == activityType) { - return currentData.possibility; - } - } - } - - return 0; - } - - Map toMap() { - return { - 'time': time, - 'elapsedTimeFromReboot': elapsedTimeFromReboot, - 'activityIdentificationDatas': - activityIdentificationDatas?.map((x) => x?.toMap())?.toList(), - }; - } - - factory ActivityIdentificationResponse.fromMap(Map map) { - if (map == null) return null; - - return ActivityIdentificationResponse( - time: map['time'], - elapsedTimeFromReboot: map['elapsedTimeFromReboot'], - activityIdentificationDatas: List.from( - map['activityIdentificationDatas'] - ?.map((x) => ActivityIdentificationData.fromMap(x))), - ); - } - - String toJson() => json.encode(toMap()); - - factory ActivityIdentificationResponse.fromJson(String source) => - ActivityIdentificationResponse.fromMap(json.decode(source)); - - @override - String toString() => - 'ActivityIdentificationResponse(time: $time, elapsedTimeFromReboot: $elapsedTimeFromReboot, activityIdentificationDatas: $activityIdentificationDatas)'; - - @override - bool operator ==(Object o) { - if (identical(this, o)) return true; - - return o is ActivityIdentificationResponse && - o.time == time && - o.elapsedTimeFromReboot == elapsedTimeFromReboot && - listEquals(o.activityIdentificationDatas, activityIdentificationDatas); - } - - @override - int get hashCode { - return hashList([ - time, - elapsedTimeFromReboot, - activityIdentificationDatas, - ]); - } -} diff --git a/hms-plugins/flutter-hms-location/lib/activity/activity_identification_service.dart b/hms-plugins/flutter-hms-location/lib/activity/activity_identification_service.dart deleted file mode 100644 index c8598871..00000000 --- a/hms-plugins/flutter-hms-location/lib/activity/activity_identification_service.dart +++ /dev/null @@ -1,98 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -import 'package:flutter/services.dart'; - -import 'activity_conversion_info.dart'; -import 'activity_conversion_response.dart'; -import 'activity_identification_response.dart'; - -class ActivityIdentificationService { - static ActivityIdentificationService _instance; - - final MethodChannel _methodChannel; - final EventChannel _activityIdentificationEventChannel; - final EventChannel _activityConversionEventChannel; - - Stream _onActivityIdentification; - Stream _onActivityConversion; - - ActivityIdentificationService._create( - this._methodChannel, - this._activityIdentificationEventChannel, - this._activityConversionEventChannel, - ); - - factory ActivityIdentificationService() { - if (_instance == null) { - final MethodChannel methodChannel = const MethodChannel( - 'com.huawei.flutter.location/activityidentification_methodchannel'); - - final EventChannel activityIdentificationEventChannel = const EventChannel( - 'com.huawei.flutter.location/activityidentification_eventchannel'); - - final EventChannel activityConversionEventChannel = const EventChannel( - 'com.huawei.flutter.location/activityconversion_eventchannel'); - - _instance = ActivityIdentificationService._create( - methodChannel, - activityIdentificationEventChannel, - activityConversionEventChannel, - ); - } - return _instance; - } - - Future createActivityIdentificationUpdates( - int detectionIntervalMillis) async { - return _methodChannel.invokeMethod( - 'createActivityIdentificationUpdates', detectionIntervalMillis); - } - - Future createActivityConversionUpdates( - List activityConversions) async { - return _methodChannel.invokeMethod('createActivityConversionUpdates', - activityConversions?.map((x) => x?.toMap())?.toList()); - } - - Future deleteActivityIdentificationUpdates(int requestCode) async { - return _methodChannel.invokeMethod( - 'deleteActivityIdentificationUpdates', requestCode); - } - - Future deleteActivityConversionUpdates(int requestCode) async { - return _methodChannel.invokeMethod( - 'deleteActivityConversionUpdates', requestCode); - } - - Stream get onActivityIdentification { - if (_onActivityIdentification == null) { - _onActivityIdentification = _activityIdentificationEventChannel - .receiveBroadcastStream() - .map((event) => ActivityIdentificationResponse.fromMap(event)); - } - return _onActivityIdentification; - } - - Stream get onActivityConversion { - if (_onActivityConversion == null) { - _onActivityConversion = _activityConversionEventChannel - .receiveBroadcastStream() - .map((event) => ActivityConversionResponse.fromMap(event)); - } - return _onActivityConversion; - } -} diff --git a/hms-plugins/flutter-hms-location/lib/geofence/geofence.dart b/hms-plugins/flutter-hms-location/lib/geofence/geofence.dart deleted file mode 100644 index fc93cb7b..00000000 --- a/hms-plugins/flutter-hms-location/lib/geofence/geofence.dart +++ /dev/null @@ -1,113 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -import 'dart:convert'; -import 'dart:core'; -import 'dart:ui'; - -class Geofence { - static const int ENTER_GEOFENCE_CONVERSION = 1; - static const int EXIT_GEOFENCE_CONVERSION = 2; - static const int DWELL_GEOFENCE_CONVERSION = 4; - static const int GEOFENCE_NEVER_EXPIRE = -1; - - String uniqueId; - int conversions; - int validDuration; - double latitude; - double longitude; - double radius; - int notificationInterval; - int dwellDelayTime; - - Geofence({ - this.uniqueId, - this.conversions, - this.validDuration, - this.latitude, - this.longitude, - this.radius, - this.notificationInterval = 0, - this.dwellDelayTime = 0, - }); - - Map toMap() { - return { - 'uniqueId': uniqueId, - 'conversions': conversions, - 'validDuration': validDuration, - 'latitude': latitude, - 'longitude': longitude, - 'radius': radius, - 'notificationInterval': notificationInterval, - 'dwellDelayTime': dwellDelayTime, - }; - } - - factory Geofence.fromMap(Map map) { - if (map == null) return null; - - return Geofence( - uniqueId: map['uniqueId'], - conversions: map['conversions'], - validDuration: map['validDuration'], - latitude: map['latitude'], - longitude: map['longitude'], - radius: map['radius'], - notificationInterval: map['notificationInterval'], - dwellDelayTime: map['dwellDelayTime'], - ); - } - - String toJson() => json.encode(toMap()); - - factory Geofence.fromJson(String source) => - Geofence.fromMap(json.decode(source)); - - @override - String toString() { - return 'Geofence(uniqueId: $uniqueId, conversions: $conversions, validDuration: $validDuration, latitude: $latitude, longitude: $longitude, radius: $radius, notificationInterval: $notificationInterval, dwellDelayTime: $dwellDelayTime)'; - } - - @override - bool operator ==(Object o) { - if (identical(this, o)) return true; - - return o is Geofence && - o.uniqueId == uniqueId && - o.conversions == conversions && - o.validDuration == validDuration && - o.latitude == latitude && - o.longitude == longitude && - o.radius == radius && - o.notificationInterval == notificationInterval && - o.dwellDelayTime == dwellDelayTime; - } - - @override - int get hashCode { - return hashList([ - uniqueId, - conversions, - validDuration, - latitude, - longitude, - radius, - notificationInterval, - dwellDelayTime, - ]); - } -} diff --git a/hms-plugins/flutter-hms-location/lib/geofence/geofence_data.dart b/hms-plugins/flutter-hms-location/lib/geofence/geofence_data.dart deleted file mode 100644 index c2aca69e..00000000 --- a/hms-plugins/flutter-hms-location/lib/geofence/geofence_data.dart +++ /dev/null @@ -1,88 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -import 'dart:convert'; -import 'dart:ui'; - -import 'package:flutter/foundation.dart'; - -import '../location/location.dart'; - -class GeofenceData { - int errorCode; - int conversion; - List convertingGeofenceIdList; - Location convertingLocation; - - GeofenceData({ - this.errorCode, - this.conversion, - this.convertingGeofenceIdList, - this.convertingLocation, - }); - - Map toMap() { - return { - 'errorCode': errorCode, - 'conversion': conversion, - 'convertingGeofenceIdList': convertingGeofenceIdList, - 'convertingLocation': convertingLocation?.toMap(), - }; - } - - factory GeofenceData.fromMap(Map map) { - if (map == null) return null; - - return GeofenceData( - errorCode: map['errorCode'], - conversion: map['conversion'], - convertingGeofenceIdList: - List.from(map['convertingGeofenceIdList']), - convertingLocation: Location.fromMap(map['convertingLocation']), - ); - } - - String toJson() => json.encode(toMap()); - - factory GeofenceData.fromJson(String source) => - GeofenceData.fromMap(json.decode(source)); - - @override - String toString() { - return 'GeofenceData(errorCode: $errorCode, conversion: $conversion, convertingGeofenceIdList: $convertingGeofenceIdList, convertingLocation: $convertingLocation)'; - } - - @override - bool operator ==(Object o) { - if (identical(this, o)) return true; - - return o is GeofenceData && - o.errorCode == errorCode && - o.conversion == conversion && - listEquals(o.convertingGeofenceIdList, convertingGeofenceIdList) && - o.convertingLocation == convertingLocation; - } - - @override - int get hashCode { - return hashList([ - errorCode, - conversion, - convertingGeofenceIdList, - convertingLocation, - ]); - } -} diff --git a/hms-plugins/flutter-hms-location/lib/geofence/geofence_request.dart b/hms-plugins/flutter-hms-location/lib/geofence/geofence_request.dart deleted file mode 100644 index bbefb528..00000000 --- a/hms-plugins/flutter-hms-location/lib/geofence/geofence_request.dart +++ /dev/null @@ -1,91 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -import 'dart:convert'; -import 'dart:ui'; - -import 'package:flutter/foundation.dart'; - -import 'geofence.dart'; - -class GeofenceRequest { - static const int ENTER_INIT_CONVERSION = 1; - static const int EXIT_INIT_CONVERSION = 2; - static const int DWELL_INIT_CONVERSION = 4; - static const int COORDINATE_TYPE_WGS_84 = 1; - static const int COORDINATE_TYPE_GCJ_02 = 0; - - List geofenceList; - int initConversions; - int coordinateType; - - GeofenceRequest({ - this.geofenceList, - this.initConversions = ENTER_INIT_CONVERSION | DWELL_INIT_CONVERSION, - this.coordinateType = COORDINATE_TYPE_WGS_84, - }) { - if (this.geofenceList == null) { - this.geofenceList = []; - } - } - - Map toMap() { - return { - 'geofenceList': geofenceList?.map((x) => x?.toMap())?.toList(), - 'initConversions': initConversions, - 'coordinateType': coordinateType, - }; - } - - factory GeofenceRequest.fromMap(Map map) { - if (map == null) return null; - - return GeofenceRequest( - geofenceList: List.from( - map['geofenceList']?.map((x) => Geofence.fromMap(x))), - initConversions: map['initConversions'], - coordinateType: map['coordinateType'], - ); - } - - String toJson() => json.encode(toMap()); - - factory GeofenceRequest.fromJson(String source) => - GeofenceRequest.fromMap(json.decode(source)); - - @override - String toString() => - 'GeofenceRequest(geofenceList: $geofenceList, initConversions: $initConversions, coordinateType: $coordinateType)'; - - @override - bool operator ==(Object o) { - if (identical(this, o)) return true; - - return o is GeofenceRequest && - listEquals(o.geofenceList, geofenceList) && - o.initConversions == initConversions && - o.coordinateType == coordinateType; - } - - @override - int get hashCode { - return hashList([ - geofenceList, - initConversions, - coordinateType, - ]); - } -} diff --git a/hms-plugins/flutter-hms-location/lib/geofence/geofence_service.dart b/hms-plugins/flutter-hms-location/lib/geofence/geofence_service.dart deleted file mode 100644 index 87e9d0a8..00000000 --- a/hms-plugins/flutter-hms-location/lib/geofence/geofence_service.dart +++ /dev/null @@ -1,72 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -import 'package:flutter/services.dart'; - -import 'geofence_data.dart' show GeofenceData; -import 'geofence_request.dart' show GeofenceRequest; - -class GeofenceService { - static GeofenceService _instance; - - final MethodChannel _methodChannel; - final EventChannel _eventChannel; - - Stream _onGeofenceData; - - GeofenceService._create( - this._methodChannel, - this._eventChannel, - ); - - factory GeofenceService() { - if (_instance == null) { - final MethodChannel methodChannel = const MethodChannel( - 'com.huawei.flutter.location/geofence_methodchannel'); - final EventChannel eventChannel = const EventChannel( - 'com.huawei.flutter.location/geofence_eventchannel'); - - _instance = GeofenceService._create( - methodChannel, - eventChannel, - ); - } - return _instance; - } - - Future createGeofenceList(GeofenceRequest geofenceRequest) async { - return _methodChannel.invokeMethod( - 'createGeofenceList', geofenceRequest.toMap()); - } - - Future deleteGeofenceList(int requestCode) async { - return _methodChannel.invokeMethod('deleteGeofenceList', requestCode); - } - - Future deleteGeofenceListWithIds(List geofenceIds) async { - return _methodChannel.invokeMethod( - 'deleteGeofenceListWithIds', geofenceIds); - } - - Stream get onGeofenceData { - if (_onGeofenceData == null) { - _onGeofenceData = _eventChannel - .receiveBroadcastStream() - .map((event) => GeofenceData.fromMap(event)); - } - return _onGeofenceData; - } -} diff --git a/hms-plugins/flutter-hms-location/lib/location/fused_location_provider_client.dart b/hms-plugins/flutter-hms-location/lib/location/fused_location_provider_client.dart deleted file mode 100644 index b67c49af..00000000 --- a/hms-plugins/flutter-hms-location/lib/location/fused_location_provider_client.dart +++ /dev/null @@ -1,158 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -import 'package:flutter/services.dart'; - -import 'hwlocation.dart'; -import 'location.dart'; -import 'location_availability.dart'; -import 'location_callback.dart'; -import 'location_request.dart'; -import 'location_result.dart'; -import 'location_settings_request.dart'; -import 'location_settings_states.dart'; -import 'navigation_request.dart'; -import 'navigation_result.dart'; - -class FusedLocationProviderClient { - static FusedLocationProviderClient _instance; - - final MethodChannel _methodChannel; - final EventChannel _eventChannel; - final Map _callbacks; - - Stream _onLocationData; - - FusedLocationProviderClient._create( - this._methodChannel, - this._eventChannel, - this._callbacks, - ) { - _methodChannel.setMethodCallHandler(_methodCallHandler); - } - - factory FusedLocationProviderClient() { - if (_instance == null) { - _instance = FusedLocationProviderClient._create( - const MethodChannel( - 'com.huawei.flutter.location/fusedlocation_methodchannel'), - const EventChannel( - 'com.huawei.flutter.location/fusedlocation_eventchannel'), - {}, - ); - } - return _instance; - } - - Future _methodCallHandler(MethodCall methodCall) async { - switch (methodCall.method) { - case 'onLocationResult': - _callbacks[methodCall.arguments['callbackId']].onLocationResult( - LocationResult.fromMap(methodCall.arguments['locationResult'])); - break; - case 'onLocationAvailability': - _callbacks[methodCall.arguments['callbackId']].onLocationAvailability( - LocationAvailability.fromMap( - methodCall.arguments['locationAvailability'])); - break; - default: - break; - } - } - - Future checkLocationSettings( - LocationSettingsRequest locationSettingsRequest) async { - return LocationSettingsStates.fromMap( - await _methodChannel.invokeMapMethod( - 'checkLocationSettings', locationSettingsRequest.toMap())); - } - - Future getLastLocation() async { - return Location.fromMap(await _methodChannel - .invokeMapMethod('getLastLocation')); - } - - Future getLastLocationWithAddress( - LocationRequest locationRequest) async { - return HWLocation.fromMap( - await _methodChannel.invokeMapMethod( - 'getLastLocationWithAddress', locationRequest.toMap())); - } - - Future getLocationAvailability() async { - return LocationAvailability.fromMap(await _methodChannel - .invokeMapMethod('getLocationAvailability')); - } - - Future setMockMode(bool mockMode) async { - return _methodChannel.invokeMethod('setMockMode', mockMode); - } - - Future setMockLocation(Location location) async { - return _methodChannel.invokeMethod( - 'setMockLocation', location.toMap()); - } - - Future requestLocationUpdates(LocationRequest locationRequest) async { - return _methodChannel.invokeMethod( - 'requestLocationUpdates', locationRequest.toMap()); - } - - Future requestLocationUpdatesCb(LocationRequest locationRequest, - LocationCallback locationCallback) async { - int callbackId = await _methodChannel.invokeMethod( - 'requestLocationUpdatesCb', locationRequest.toMap()); - _callbacks.putIfAbsent(callbackId, () => locationCallback); - return callbackId; - } - - Future requestLocationUpdatesExCb(LocationRequest locationRequest, - LocationCallback locationCallback) async { - int callbackId = await _methodChannel.invokeMethod( - 'requestLocationUpdatesExCb', - (locationRequest..priority = LocationRequest.PRIORITY_HD_ACCURACY) - .toMap()); - _callbacks.putIfAbsent(callbackId, () => locationCallback); - return callbackId; - } - - Future removeLocationUpdates(int requestCode) async { - return _methodChannel.invokeMethod( - 'removeLocationUpdates', requestCode); - } - - Future removeLocationUpdatesCb(int callbackId) async { - await _methodChannel.invokeMethod( - 'removeLocationUpdatesCb', callbackId); - _callbacks.remove(callbackId); - } - - Future getNavigationContextState( - NavigationRequest navigationRequest) async { - return NavigationResult.fromMap( - await _methodChannel.invokeMapMethod( - 'getNavigationContextState', navigationRequest.toMap())); - } - - Stream get onLocationData { - if (_onLocationData == null) { - _onLocationData = _eventChannel - .receiveBroadcastStream() - .map((event) => Location.fromMap(event)); - } - return _onLocationData; - } -} diff --git a/hms-plugins/flutter-hms-location/lib/location/hwlocation.dart b/hms-plugins/flutter-hms-location/lib/location/hwlocation.dart deleted file mode 100644 index 97c92db5..00000000 --- a/hms-plugins/flutter-hms-location/lib/location/hwlocation.dart +++ /dev/null @@ -1,207 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -import 'dart:convert'; -import 'dart:ui'; - -import 'package:flutter/foundation.dart'; - -class HWLocation { - String provider; - double latitude; - double longitude; - double altitude; - double speed; - double bearing; - double horizontalAccuracyMeters; - double verticalAccuracyMeters; - double speedAccuracyMetersPerSecond; - double bearingAccuracyDegrees; - int time; - int elapsedRealtimeNanos; - String countryCode; - String countryName; - String state; - String city; - String county; - String street; - String featureName; - String postalCode; - String phone; - String url; - Map extraInfo; - - HWLocation({ - this.provider, - this.latitude, - this.longitude, - this.altitude, - this.speed, - this.bearing, - this.horizontalAccuracyMeters, - this.verticalAccuracyMeters, - this.speedAccuracyMetersPerSecond, - this.bearingAccuracyDegrees, - this.time, - this.elapsedRealtimeNanos, - this.countryCode, - this.countryName, - this.state, - this.city, - this.county, - this.street, - this.featureName, - this.postalCode, - this.phone, - this.url, - this.extraInfo, - }); - - Map toMap() { - return { - 'provider': provider, - 'latitude': latitude, - 'longitude': longitude, - 'altitude': altitude, - 'speed': speed, - 'bearing': bearing, - 'horizontalAccuracyMeters': horizontalAccuracyMeters, - 'verticalAccuracyMeters': verticalAccuracyMeters, - 'speedAccuracyMetersPerSecond': speedAccuracyMetersPerSecond, - 'bearingAccuracyDegrees': bearingAccuracyDegrees, - 'time': time, - 'elapsedRealtimeNanos': elapsedRealtimeNanos, - 'countryCode': countryCode, - 'countryName': countryName, - 'state': state, - 'city': city, - 'county': county, - 'street': street, - 'featureName': featureName, - 'postalCode': postalCode, - 'phone': phone, - 'url': url, - 'extraInfo': extraInfo, - }; - } - - factory HWLocation.fromMap(Map map) { - if (map == null) return null; - - return HWLocation( - provider: map["provider"] == null ? null : map["provider"], - latitude: map["latitude"] == null ? null : map["latitude"], - longitude: map["longitude"] == null ? null : map["longitude"], - altitude: map["altitude"] == null ? null : map["altitude"], - speed: map["speed"] == null ? null : map["speed"], - bearing: map["bearing"] == null ? null : map["bearing"], - horizontalAccuracyMeters: map["horizontalAccuracyMeters"], - verticalAccuracyMeters: map["verticalAccuracyMeters"] == null - ? null - : map["verticalAccuracyMeters"], - speedAccuracyMetersPerSecond: - map["speedAccuracyMetersPerSecond"] == null - ? null - : map["speedAccuracyMetersPerSecond"], - bearingAccuracyDegrees: map["bearingAccuracyDegrees"] == null - ? null - : map["bearingAccuracyDegrees"], - time: map["time"] == null ? null : map["time"], - elapsedRealtimeNanos: map["elapsedRealtimeNanos"] == null - ? null - : map["elapsedRealtimeNanos"], - countryCode: map["countryCode"] == null ? null : map["countryCode"], - countryName: map["countryName"] == null ? null : map["countryName"], - state: map["state"] == null ? null : map["state"], - city: map["city"] == null ? null : map["city"], - county: map["county"] == null ? null : map["county"], - street: map["street"] == null ? null : map["street"], - featureName: map["featureName"] == null ? null : map["featureName"], - postalCode: map["postalCode"] == null ? null : map["postalCode"], - phone: map["phone"] == null ? null : map["phone"], - url: map["url"] == null ? null : map["url"], - extraInfo: - map["extraInfo"] == null ? null : Map.from(map["extraInfo"])); - } - - String toJson() => json.encode(toMap()); - - factory HWLocation.fromJson(String source) => - HWLocation.fromMap(json.decode(source)); - - @override - String toString() { - return 'HWLocation(provider: $provider, latitude: $latitude, longitude: $longitude, altitude: $altitude, speed: $speed, bearing: $bearing, horizontalAccuracyMeters: $horizontalAccuracyMeters, verticalAccuracyMeters: $verticalAccuracyMeters, speedAccuracyMetersPerSecond: $speedAccuracyMetersPerSecond, bearingAccuracyDegrees: $bearingAccuracyDegrees, time: $time, elapsedRealtimeNanos: $elapsedRealtimeNanos, countryCode: $countryCode, countryName: $countryName, state: $state, city: $city, county: $county, street: $street, featureName: $featureName, postalCode: $postalCode, phone: $phone, url: $url, extraInfo: $extraInfo)'; - } - - @override - bool operator ==(Object o) { - if (identical(this, o)) return true; - return o is HWLocation && - o.provider == provider && - o.latitude == latitude && - o.longitude == longitude && - o.altitude == altitude && - o.speed == speed && - o.bearing == bearing && - o.horizontalAccuracyMeters == horizontalAccuracyMeters && - o.verticalAccuracyMeters == verticalAccuracyMeters && - o.speedAccuracyMetersPerSecond == speedAccuracyMetersPerSecond && - o.bearingAccuracyDegrees == bearingAccuracyDegrees && - o.time == time && - o.elapsedRealtimeNanos == elapsedRealtimeNanos && - o.countryCode == countryCode && - o.countryName == countryName && - o.state == state && - o.city == city && - o.county == county && - o.street == street && - o.featureName == featureName && - o.postalCode == postalCode && - o.phone == phone && - o.url == url && - mapEquals(o.extraInfo, extraInfo); - } - - @override - int get hashCode { - return hashList([ - provider, - latitude, - longitude, - altitude, - speed, - bearing, - horizontalAccuracyMeters, - verticalAccuracyMeters, - speedAccuracyMetersPerSecond, - bearingAccuracyDegrees, - time, - elapsedRealtimeNanos, - countryCode, - countryName, - state, - city, - county, - street, - featureName, - postalCode, - phone, - url, - extraInfo, - ]); - } -} diff --git a/hms-plugins/flutter-hms-location/lib/location/location.dart b/hms-plugins/flutter-hms-location/lib/location/location.dart deleted file mode 100644 index 5fa17b6a..00000000 --- a/hms-plugins/flutter-hms-location/lib/location/location.dart +++ /dev/null @@ -1,141 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -import 'dart:convert'; -import 'dart:ui'; - -class Location { - String provider; - double latitude; - double longitude; - double altitude; - double speed; - double bearing; - double horizontalAccuracyMeters; - double verticalAccuracyMeters; - double speedAccuracyMetersPerSecond; - double bearingAccuracyDegrees; - int time; - int elapsedRealtimeNanos; - - Location({ - this.provider = 'HMS Mock Location', - this.latitude = 0.0, - this.longitude = 0.0, - this.altitude = 0.0, - this.speed = 0.0, - this.bearing = 0.0, - this.horizontalAccuracyMeters = 0.0, - this.verticalAccuracyMeters = 0.0, - this.speedAccuracyMetersPerSecond = 0.0, - this.bearingAccuracyDegrees = 0.0, - this.time = 0, - this.elapsedRealtimeNanos = 0, - }); - - Map toMap() { - return { - 'provider': provider, - 'latitude': latitude, - 'longitude': longitude, - 'altitude': altitude, - 'speed': speed, - 'bearing': bearing, - 'horizontalAccuracyMeters': horizontalAccuracyMeters, - 'verticalAccuracyMeters': verticalAccuracyMeters, - 'speedAccuracyMetersPerSecond': speedAccuracyMetersPerSecond, - 'bearingAccuracyDegrees': bearingAccuracyDegrees, - 'time': time, - 'elapsedRealtimeNanos': elapsedRealtimeNanos, - }; - } - - factory Location.fromMap(Map map) { - if (map == null) return null; - - return Location( - provider: map["provider"] == null ? null : map["provider"], - latitude: map["latitude"] == null ? null : map["latitude"], - longitude: map["longitude"] == null ? null : map["longitude"], - altitude: map["altitude"] == null ? null : map["altitude"], - speed: map["speed"] == null ? null : map["speed"], - bearing: map["bearing"] == null ? null : map["bearing"], - horizontalAccuracyMeters: map["horizontalAccuracyMeters"] == null - ? null - : map["horizontalAccuracyMeters"], - verticalAccuracyMeters: map["verticalAccuracyMeters"] == null - ? null - : map["verticalAccuracyMeters"], - speedAccuracyMetersPerSecond: map["speedAccuracyMetersPerSecond"] == null - ? null - : map["speedAccuracyMetersPerSecond"], - bearingAccuracyDegrees: map["bearingAccuracyDegrees"] == null - ? null - : map["bearingAccuracyDegrees"], - time: map["time"] == null ? null : map["time"], - elapsedRealtimeNanos: map["elapsedRealtimeNanos"] == null - ? null - : map["elapsedRealtimeNanos"], - ); - } - - String toJson() => json.encode(toMap()); - - factory Location.fromJson(String source) => - Location.fromMap(json.decode(source)); - - @override - String toString() { - return 'Location(provider: $provider, latitude: $latitude, longitude: $longitude, altitude: $altitude, speed: $speed, bearing: $bearing, horizontalAccuracyMeters: $horizontalAccuracyMeters, verticalAccuracyMeters: $verticalAccuracyMeters, speedAccuracyMetersPerSecond: $speedAccuracyMetersPerSecond, bearingAccuracyDegrees: $bearingAccuracyDegrees, time: $time, elapsedRealtimeNanos: $elapsedRealtimeNanos)'; - } - - @override - bool operator ==(Object o) { - if (identical(this, o)) return true; - - return o is Location && - o.provider == provider && - o.latitude == latitude && - o.longitude == longitude && - o.altitude == altitude && - o.speed == speed && - o.bearing == bearing && - o.horizontalAccuracyMeters == horizontalAccuracyMeters && - o.verticalAccuracyMeters == verticalAccuracyMeters && - o.speedAccuracyMetersPerSecond == speedAccuracyMetersPerSecond && - o.bearingAccuracyDegrees == bearingAccuracyDegrees && - o.time == time && - o.elapsedRealtimeNanos == elapsedRealtimeNanos; - } - - @override - int get hashCode { - return hashList([ - provider, - latitude, - longitude, - altitude, - speed, - bearing, - horizontalAccuracyMeters, - verticalAccuracyMeters, - speedAccuracyMetersPerSecond, - bearingAccuracyDegrees, - time, - elapsedRealtimeNanos, - ]); - } -} diff --git a/hms-plugins/flutter-hms-location/lib/location/location_availability.dart b/hms-plugins/flutter-hms-location/lib/location/location_availability.dart deleted file mode 100644 index a93a1061..00000000 --- a/hms-plugins/flutter-hms-location/lib/location/location_availability.dart +++ /dev/null @@ -1,85 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -import 'dart:convert'; -import 'dart:ui'; - -class LocationAvailability { - int cellStatus; - int wifiStatus; - int elapsedRealtimeNs; - int locationStatus; - - LocationAvailability({ - this.cellStatus, - this.wifiStatus, - this.elapsedRealtimeNs, - this.locationStatus, - }); - - bool get isLocationAvailable => locationStatus < 1000; - - Map toMap() { - return { - 'cellStatus': cellStatus, - 'wifiStatus': wifiStatus, - 'elapsedRealtimeNs': elapsedRealtimeNs, - 'locationStatus': locationStatus, - }; - } - - factory LocationAvailability.fromMap(Map map) { - if (map == null) return null; - - return LocationAvailability( - cellStatus: map['cellStatus'], - wifiStatus: map['wifiStatus'], - elapsedRealtimeNs: map['elapsedRealtimeNs'], - locationStatus: map['locationStatus'], - ); - } - - String toJson() => json.encode(toMap()); - - factory LocationAvailability.fromJson(String source) => - LocationAvailability.fromMap(json.decode(source)); - - @override - String toString() { - return 'LocationAvailability(cellStatus: $cellStatus, wifiStatus: $wifiStatus, elapsedRealtimeNs: $elapsedRealtimeNs, locationStatus: $locationStatus)'; - } - - @override - bool operator ==(Object o) { - if (identical(this, o)) return true; - - return o is LocationAvailability && - o.cellStatus == cellStatus && - o.wifiStatus == wifiStatus && - o.elapsedRealtimeNs == elapsedRealtimeNs && - o.locationStatus == locationStatus; - } - - @override - int get hashCode { - return hashList([ - cellStatus, - wifiStatus, - elapsedRealtimeNs, - locationStatus, - ]); - } -} diff --git a/hms-plugins/flutter-hms-location/lib/location/location_callback.dart b/hms-plugins/flutter-hms-location/lib/location/location_callback.dart deleted file mode 100644 index b67068ae..00000000 --- a/hms-plugins/flutter-hms-location/lib/location/location_callback.dart +++ /dev/null @@ -1,31 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -import 'location_availability.dart'; -import 'location_result.dart'; - -typedef void OnLocationResult(LocationResult locationResult); -typedef void OnLocationAvailability(LocationAvailability locationAvailability); - -class LocationCallback { - OnLocationResult onLocationResult; - OnLocationAvailability onLocationAvailability; - - LocationCallback({ - this.onLocationResult, - this.onLocationAvailability, - }); -} diff --git a/hms-plugins/flutter-hms-location/lib/location/location_request.dart b/hms-plugins/flutter-hms-location/lib/location/location_request.dart deleted file mode 100644 index af4ee2ea..00000000 --- a/hms-plugins/flutter-hms-location/lib/location/location_request.dart +++ /dev/null @@ -1,231 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -import 'dart:convert'; -import 'dart:ui'; - -import 'package:flutter/foundation.dart'; - -class LocationRequest { - static const int PRIORITY_HIGH_ACCURACY = 100; - static const int PRIORITY_BALANCED_POWER_ACCURACY = 102; - static const int PRIORITY_LOW_POWER = 104; - static const int PRIORITY_NO_POWER = 105; - static const int PRIORITY_HD_ACCURACY = 200; - static const double _FASTEST_INTERVAL_FACTOR = 6.0; - - int _priority; - int _interval; - int _fastestInterval; - bool _isFastestIntervalExplicitlySet; - int _expirationTime; - int _numUpdates; - double _smallestDisplacement; - int _maxWaitTime; - bool needAddress; - String language; - String countryCode; - Map extras; - - LocationRequest._create( - this._priority, - this._interval, - this._fastestInterval, - this._isFastestIntervalExplicitlySet, - this._expirationTime, - this._numUpdates, - this._smallestDisplacement, - this._maxWaitTime, - this.needAddress, - this.language, - this.countryCode, - this.extras, - ); - - LocationRequest() { - _priority = PRIORITY_BALANCED_POWER_ACCURACY; - _interval = 3600000; - _fastestInterval = (_interval ~/ _FASTEST_INTERVAL_FACTOR); - _isFastestIntervalExplicitlySet = false; - _expirationTime = 9223372036854775807; - _numUpdates = 2147483647; - _smallestDisplacement = 0.0; - _maxWaitTime = 0; - needAddress = false; - language = ''; - countryCode = ''; - } - - int get priority => _priority; - - set priority(int value) { - if (value == PRIORITY_HIGH_ACCURACY || - value == PRIORITY_BALANCED_POWER_ACCURACY || - value == PRIORITY_LOW_POWER || - value == PRIORITY_NO_POWER || - value == PRIORITY_HD_ACCURACY) { - _priority = value; - } else { - throw ArgumentError('Priority is not a known constant'); - } - } - - int get interval => _interval; - - set interval(int value) { - if (value.isNegative) { - throw ArgumentError('Interval is invalid'); - } else { - _interval = value; - _fastestInterval = _isFastestIntervalExplicitlySet - ? _fastestInterval - : (_interval ~/ _FASTEST_INTERVAL_FACTOR); - } - } - - int get fastestInterval => _fastestInterval; - - set fastestInterval(int value) { - if (value.isNegative) { - throw ArgumentError('FastestInterval is invalid'); - } else { - _isFastestIntervalExplicitlySet = true; - _fastestInterval = value; - } - } - - bool get isFastestIntervalExplicitlySet => _isFastestIntervalExplicitlySet; - - int get expirationTime => _expirationTime; - - set expirationTime(int value) { - _expirationTime = value.isNegative ? 0 : value; - } - - int get numUpdates => _numUpdates; - - set numUpdates(int value) { - if (value <= 0) { - throw ArgumentError('numUpdates is invalid'); - } else { - _numUpdates = value; - } - } - - double get smallestDisplacement => _smallestDisplacement; - - set smallestDisplacement(double value) { - if (value.isNegative) { - throw ArgumentError('smallestDisplacement param invalid'); - } else { - _smallestDisplacement = value; - } - } - - int get maxWaitTime => _maxWaitTime < _interval ? _interval : _maxWaitTime; - - set maxWaitTime(int value) => _maxWaitTime = value; - - void putExtras(String key, String value) { - if (extras == null) { - extras = Map(); - } - extras.putIfAbsent(key, () => value); - } - - Map toMap() { - return { - 'priority': _priority, - 'interval': _interval, - 'fastestInterval': _fastestInterval, - 'isFastestIntervalExplicitlySet': _isFastestIntervalExplicitlySet, - 'expirationTime': _expirationTime, - 'numUpdates': _numUpdates, - 'smallestDisplacement': _smallestDisplacement, - 'maxWaitTime': _maxWaitTime, - 'needAddress': needAddress, - 'language': language, - 'countryCode': countryCode, - 'extras': extras, - }; - } - - factory LocationRequest.fromMap(Map map) { - if (map == null) return null; - - return LocationRequest._create( - map['priority'], - map['interval'], - map['fastestInterval'], - map['isFastestIntervalExplicitlySet'], - map['expirationTime'], - map['numUpdates'], - map['smallestDisplacement'], - map['maxWaitTime'], - map['needAddress'], - map['language'], - map['countryCode'], - Map.from(map['extras']), - ); - } - - String toJson() => json.encode(toMap()); - - factory LocationRequest.fromJson(String source) => - LocationRequest.fromMap(json.decode(source)); - - @override - String toString() { - return 'LocationRequest(_priority: $_priority, _interval: $_interval, _fastestInterval: $_fastestInterval, _isFastestIntervalExplicitlySet: $_isFastestIntervalExplicitlySet, _expirationTime: $_expirationTime, _numUpdates: $_numUpdates, _smallestDisplacement: $_smallestDisplacement, _maxWaitTime: $_maxWaitTime, _needAddress: $needAddress, _language: $language, _countryCode: $countryCode, _extras: $extras)'; - } - - @override - bool operator ==(Object o) { - if (identical(this, o)) return true; - - return o is LocationRequest && - o._priority == _priority && - o._interval == _interval && - o._fastestInterval == _fastestInterval && - o._isFastestIntervalExplicitlySet == _isFastestIntervalExplicitlySet && - o._expirationTime == _expirationTime && - o._numUpdates == _numUpdates && - o._smallestDisplacement == _smallestDisplacement && - o._maxWaitTime == _maxWaitTime && - o.needAddress == needAddress && - o.language == language && - o.countryCode == countryCode && - mapEquals(o.extras, extras); - } - - @override - int get hashCode { - return hashList([ - _priority, - _interval, - _fastestInterval, - _isFastestIntervalExplicitlySet, - _expirationTime, - _numUpdates, - _smallestDisplacement, - _maxWaitTime, - needAddress, - language, - countryCode, - extras, - ]); - } -} diff --git a/hms-plugins/flutter-hms-location/lib/location/location_result.dart b/hms-plugins/flutter-hms-location/lib/location/location_result.dart deleted file mode 100644 index 04cac6d5..00000000 --- a/hms-plugins/flutter-hms-location/lib/location/location_result.dart +++ /dev/null @@ -1,98 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -import 'dart:convert'; -import 'dart:ui'; - -import 'package:flutter/foundation.dart'; - -import 'hwlocation.dart' show HWLocation; -import 'location.dart' show Location; - -class LocationResult { - List locations; - List hwLocations; - Location lastLocation; - HWLocation lastHWLocation; - - LocationResult({ - this.locations, - this.hwLocations, - this.lastLocation, - this.lastHWLocation, - }); - - Map toMap() { - return { - 'locations': locations?.map((x) => x?.toMap())?.toList(), - 'hwLocations': hwLocations?.map((x) => x?.toMap())?.toList(), - 'lastLocation': lastLocation?.toMap(), - 'lastHWLocation': lastHWLocation?.toMap(), - }; - } - - factory LocationResult.fromMap(Map map) { - if (map == null) return null; - - return LocationResult( - locations: map["locations"] == null - ? null - : List.from( - map["locations"].map((x) => Location.fromMap(x))), - hwLocations: map["hwLocations"] == null - ? null - : List.from( - map["hwLocations"].map((x) => HWLocation.fromMap(x))), - lastLocation: map["lastLocation"] == null - ? null - : Location.fromMap(map["lastLocation"]), - lastHWLocation: map["lastHWLocation"] == null - ? null - : HWLocation.fromMap(map["lastHWLocation"]), - ); - } - - String toJson() => json.encode(toMap()); - - factory LocationResult.fromJson(String source) => - LocationResult.fromMap(json.decode(source)); - - @override - String toString() { - return 'LocationResult(locations: $locations, hwLocations: $hwLocations, lastLocation: $lastLocation, lastHWLocation: $lastHWLocation)'; - } - - @override - bool operator ==(Object o) { - if (identical(this, o)) return true; - - return o is LocationResult && - listEquals(o.locations, locations) && - listEquals(o.hwLocations, hwLocations) && - o.lastLocation == lastLocation && - o.lastHWLocation == lastHWLocation; - } - - @override - int get hashCode { - return hashList([ - locations, - hwLocations, - lastLocation, - lastHWLocation, - ]); - } -} diff --git a/hms-plugins/flutter-hms-location/lib/location/location_settings_request.dart b/hms-plugins/flutter-hms-location/lib/location/location_settings_request.dart deleted file mode 100644 index f03d7224..00000000 --- a/hms-plugins/flutter-hms-location/lib/location/location_settings_request.dart +++ /dev/null @@ -1,81 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -import 'dart:convert'; -import 'dart:ui'; - -import 'package:flutter/foundation.dart'; - -import 'location_request.dart'; - -class LocationSettingsRequest { - List requests; - bool alwaysShow; - bool needBle; - - LocationSettingsRequest({ - this.requests = const [], - this.alwaysShow = false, - this.needBle = false, - }); - - Map toMap() { - return { - 'requests': requests?.map((x) => x?.toMap())?.toList(), - 'alwaysShow': alwaysShow, - 'needBle': needBle, - }; - } - - factory LocationSettingsRequest.fromMap(Map map) { - if (map == null) return null; - - return LocationSettingsRequest( - requests: List.from( - map['requests']?.map((x) => LocationRequest.fromMap(x))), - alwaysShow: map['alwaysShow'], - needBle: map['needBle'], - ); - } - - String toJson() => json.encode(toMap()); - - factory LocationSettingsRequest.fromJson(String source) => - LocationSettingsRequest.fromMap(json.decode(source)); - - @override - String toString() => - 'LocationSettingsRequest(requests: $requests, alwaysShow: $alwaysShow, needBle: $needBle)'; - - @override - bool operator ==(Object o) { - if (identical(this, o)) return true; - - return o is LocationSettingsRequest && - listEquals(o.requests, requests) && - o.alwaysShow == alwaysShow && - o.needBle == needBle; - } - - @override - int get hashCode { - return hashList([ - requests, - alwaysShow, - needBle, - ]); - } -} diff --git a/hms-plugins/flutter-hms-location/lib/location/location_settings_states.dart b/hms-plugins/flutter-hms-location/lib/location/location_settings_states.dart deleted file mode 100644 index 096374c6..00000000 --- a/hms-plugins/flutter-hms-location/lib/location/location_settings_states.dart +++ /dev/null @@ -1,107 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -import 'dart:convert'; -import 'dart:ui'; - -class LocationSettingsStates { - bool blePresent; - bool bleUsable; - bool gpsPresent; - bool gpsUsable; - bool locationPresent; - bool locationUsable; - bool networkLocationPresent; - bool networkLocationUsable; - - LocationSettingsStates({ - this.blePresent, - this.bleUsable, - this.gpsPresent, - this.gpsUsable, - this.locationPresent, - this.locationUsable, - this.networkLocationPresent, - this.networkLocationUsable, - }); - - Map toMap() { - return { - 'blePresent': blePresent, - 'bleUsable': bleUsable, - 'gpsPresent': gpsPresent, - 'gpsUsable': gpsUsable, - 'locationPresent': locationPresent, - 'locationUsable': locationUsable, - 'networkLocationPresent': networkLocationPresent, - 'networkLocationUsable': networkLocationUsable, - }; - } - - factory LocationSettingsStates.fromMap(Map map) { - if (map == null) return null; - - return LocationSettingsStates( - blePresent: map['blePresent'], - bleUsable: map['bleUsable'], - gpsPresent: map['gpsPresent'], - gpsUsable: map['gpsUsable'], - locationPresent: map['locationPresent'], - locationUsable: map['locationUsable'], - networkLocationPresent: map['networkLocationPresent'], - networkLocationUsable: map['networkLocationUsable'], - ); - } - - String toJson() => json.encode(toMap()); - - factory LocationSettingsStates.fromJson(String source) => - LocationSettingsStates.fromMap(json.decode(source)); - - @override - String toString() { - return 'LocationSettingsStates(blePresent: $blePresent, bleUsable: $bleUsable, gpsPresent: $gpsPresent, gpsUsable: $gpsUsable, locationPresent: $locationPresent, locationUsable: $locationUsable, networkLocationPresent: $networkLocationPresent, networkLocationUsable: $networkLocationUsable)'; - } - - @override - bool operator ==(Object o) { - if (identical(this, o)) return true; - - return o is LocationSettingsStates && - o.blePresent == blePresent && - o.bleUsable == bleUsable && - o.gpsPresent == gpsPresent && - o.gpsUsable == gpsUsable && - o.locationPresent == locationPresent && - o.locationUsable == locationUsable && - o.networkLocationPresent == networkLocationPresent && - o.networkLocationUsable == networkLocationUsable; - } - - @override - int get hashCode { - return hashList([ - blePresent, - bleUsable, - gpsPresent, - gpsUsable, - locationPresent, - locationUsable, - networkLocationPresent, - networkLocationUsable, - ]); - } -} diff --git a/hms-plugins/flutter-hms-location/lib/location/navigation_request.dart b/hms-plugins/flutter-hms-location/lib/location/navigation_request.dart deleted file mode 100644 index d929ec2b..00000000 --- a/hms-plugins/flutter-hms-location/lib/location/navigation_request.dart +++ /dev/null @@ -1,82 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -import 'dart:convert'; -import 'dart:ui'; - -import 'package:flutter/foundation.dart'; - -class NavigationRequest { - static const int OVERPASS = 1; - static const int IS_SUPPORT_EX = 2; - - int type; - Map extras; - - NavigationRequest({ - this.type, - this.extras, - }); - - void putExtras(String key, String value) { - if (extras == null) { - extras = Map(); - } - extras.putIfAbsent(key, () => value); - } - - Map toMap() { - return { - 'type': type, - 'extras': extras, - }; - } - - factory NavigationRequest.fromMap(Map map) { - if (map == null) return null; - - return NavigationRequest( - type: map['type'], - extras: Map.from(map['extras']), - ); - } - - String toJson() => json.encode(toMap()); - - factory NavigationRequest.fromJson(String source) => - NavigationRequest.fromMap(json.decode(source)); - - @override - String toString() { - return 'NavigationRequest(type: $type, extras: $extras)'; - } - - @override - bool operator ==(Object o) { - if (identical(this, o)) return true; - return o is NavigationRequest && - o.type == type && - mapEquals(o.extras, extras); - } - - @override - int get hashCode { - return hashList([ - type, - extras, - ]); - } -} diff --git a/hms-plugins/flutter-hms-location/lib/location/navigation_result.dart b/hms-plugins/flutter-hms-location/lib/location/navigation_result.dart deleted file mode 100644 index 71d3a177..00000000 --- a/hms-plugins/flutter-hms-location/lib/location/navigation_result.dart +++ /dev/null @@ -1,53 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -import 'dart:convert'; - -class NavigationResult { - int possibility; - int state; - - NavigationResult({ - this.possibility, - this.state, - }); - - Map toMap() { - return { - 'state': state, - 'possibility': possibility, - }; - } - - factory NavigationResult.fromMap(Map map) { - if (map == null) return null; - - return NavigationResult( - state: map["state"] == null ? null : map["state"], - possibility: map["possibility"] == null ? null : map["possibility"], - ); - } - - String toJson() => json.encode(toMap()); - - factory NavigationResult.fromJson(String source) => - NavigationResult.fromMap(json.decode(source)); - - @override - String toString() { - return 'State: $state, Possibility: $possibility'; - } -} diff --git a/hms-plugins/flutter-hms-location/lib/logger/hmslogger.dart b/hms-plugins/flutter-hms-location/lib/logger/hmslogger.dart deleted file mode 100644 index f35113e6..00000000 --- a/hms-plugins/flutter-hms-location/lib/logger/hmslogger.dart +++ /dev/null @@ -1,30 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -import 'package:flutter/services.dart'; - -class HMSLogger { - static const MethodChannel _methodChannel = - MethodChannel("com.huawei.flutter.location/hmslogger_methodchannel"); - - static Future enableLogger() async { - return _methodChannel.invokeMethod('enableLogger'); - } - - static Future disableLogger() async { - return _methodChannel.invokeMethod('disableLogger'); - } -} diff --git a/hms-plugins/flutter-hms-location/lib/permission/permission_handler.dart b/hms-plugins/flutter-hms-location/lib/permission/permission_handler.dart deleted file mode 100644 index 865234fb..00000000 --- a/hms-plugins/flutter-hms-location/lib/permission/permission_handler.dart +++ /dev/null @@ -1,63 +0,0 @@ -/* - Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -import 'package:flutter/services.dart'; - -class PermissionHandler { - static PermissionHandler _instance; - - final MethodChannel _methodChannel; - - PermissionHandler._create( - this._methodChannel, - ); - - factory PermissionHandler() { - if (_instance == null) { - final MethodChannel methodChannel = const MethodChannel( - 'com.huawei.flutter.location/permission_methodchannel'); - _instance = PermissionHandler._create(methodChannel); - } - return _instance; - } - - Future hasLocationPermission() async { - return _methodChannel.invokeMethod('hasLocationPermission'); - } - - Future hasBackgroundLocationPermission() async { - return _methodChannel.invokeMethod('hasBackgroundLocationPermission'); - } - - Future hasActivityRecognitionPermission() async { - return _methodChannel - .invokeMethod('hasActivityRecognitionPermission'); - } - - Future requestLocationPermission() async { - return _methodChannel.invokeMethod('requestLocationPermission'); - } - - Future requestBackgroundLocationPermission() async { - return _methodChannel - .invokeMethod('requestBackgroundLocationPermission'); - } - - Future requestActivityRecognitionPermission() async { - return _methodChannel - .invokeMethod('requestActivityRecognitionPermission'); - } -} diff --git a/hms-plugins/flutter-hms-location/pubspec.yaml b/hms-plugins/flutter-hms-location/pubspec.yaml deleted file mode 100644 index 74c68492..00000000 --- a/hms-plugins/flutter-hms-location/pubspec.yaml +++ /dev/null @@ -1,24 +0,0 @@ -name: huawei_location -description: HUAWEI Flutter Location Kit plugin combines the GPS, Wi-Fi and base station locations to help you quickly obtain precise user locations & build up global positioning capabilities. -version: 5.0.0+301 -homepage: https://www.huawei.com -repository: https://github.com/HMS-Core/hms-flutter-plugin/tree/master/flutter-hms-location - -environment: - sdk: ">=2.1.0 <3.0.0" - flutter: ">=1.12.13+hotfix.6 <2.0.0" - -dependencies: - flutter: - sdk: flutter - -dev_dependencies: - flutter_test: - sdk: flutter - -flutter: - plugin: - platforms: - android: - package: com.huawei.hms.flutter.location - pluginClass: LocationPlugin diff --git a/ios/Flutter/.last_build_id b/ios/Flutter/.last_build_id index 3b4ea73f..b95e82c3 100644 --- a/ios/Flutter/.last_build_id +++ b/ios/Flutter/.last_build_id @@ -1 +1 @@ -45a7d43b55124e1b314759554f9a14d3 \ No newline at end of file +84018bae6147d7170a2e3bd8d9e051aa \ No newline at end of file diff --git a/ios/Flutter/AppFrameworkInfo.plist b/ios/Flutter/AppFrameworkInfo.plist index 6b4c0f78..c5ff5d37 100644 --- a/ios/Flutter/AppFrameworkInfo.plist +++ b/ios/Flutter/AppFrameworkInfo.plist @@ -2,25 +2,25 @@ - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - App - CFBundleIdentifier - io.flutter.flutter.app - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - App - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1.0 - MinimumOSVersion - 8.0 + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 13.0 diff --git a/ios/Podfile b/ios/Podfile index d68afba2..87d62e9b 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -1,94 +1,102 @@ # Uncomment this line to define a global platform for your project -# platform :ios, '11.0' +platform :ios, '14.0' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' - +use_frameworks! :linkage => :static project 'Runner', { 'Debug' => :debug, 'Profile' => :release, 'Release' => :release, } -# pod 'FBSDKCoreKit' -# pod 'FBSDKLoginKit' - -def parse_KV_file(file, separator='=') - file_abs_path = File.expand_path(file) - if !File.exists? file_abs_path - return []; +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" end - generated_key_values = {} - skip_line_start_symbols = ["#", "/"] - File.foreach(file_abs_path) do |line| - next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } - plugin = line.split(pattern=separator) - if plugin.length == 2 - podname = plugin[0].strip() - path = plugin[1].strip() - podpath = File.expand_path("#{path}", file_abs_path) - generated_key_values[podname] = podpath - else - puts "Invalid plugin specification: #{line}" - end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches end - generated_key_values + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" end +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + target 'Runner' do use_frameworks! use_modular_headers! - - # Native Pods - pod 'NVActivityIndicatorView' - - # Flutter Pod - copied_flutter_dir = File.join(__dir__, 'Flutter') - copied_framework_path = File.join(copied_flutter_dir, 'Flutter.framework') - copied_podspec_path = File.join(copied_flutter_dir, 'Flutter.podspec') - unless File.exist?(copied_framework_path) && File.exist?(copied_podspec_path) - # Copy Flutter.framework and Flutter.podspec to Flutter/ to have something to link against if the xcode backend script has not run yet. - # That script will copy the correct debug/profile/release version of the framework based on the currently selected Xcode configuration. - # CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist. + pod 'OpenTok', '~> 2.22.0' + pod 'VTO2Lib' + pod 'MapboxMaps', '10.19.0' + pod 'MapboxNavigation', '2.19.0' + pod 'FLAnimatedImage' - generated_xcode_build_settings_path = File.join(copied_flutter_dir, 'Generated.xcconfig') - unless File.exist?(generated_xcode_build_settings_path) - raise "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first" - end - generated_xcode_build_settings = parse_KV_file(generated_xcode_build_settings_path) - cached_framework_dir = generated_xcode_build_settings['FLUTTER_FRAMEWORK_DIR']; + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) +end - unless File.exist?(copied_framework_path) - FileUtils.cp_r(File.join(cached_framework_dir, 'Flutter.framework'), copied_flutter_dir) - end - unless File.exist?(copied_podspec_path) - FileUtils.cp(File.join(cached_framework_dir, 'Flutter.podspec'), copied_flutter_dir) - end - end +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + target.build_configurations.each do |build_configuration| + build_configuration.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [ + '$(inherited)', + ## dart: [PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse] + 'PERMISSION_LOCATION=1', + 'PERMISSION_CAMERA=1', + 'PERMISSION_MICROPHONE=1', + ## dart: PermissionGroup.calendar + 'PERMISSION_EVENTS_FULL_ACCESS=1', + ## dart: PermissionGroup.reminders + 'PERMISSION_REMINDERS=1', + ] + build_configuration.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'arm64 i386' + build_configuration.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.0' + build_configuration.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES' + xcconfig_path = build_configuration.base_configuration_reference.real_path + xcconfig = File.read(xcconfig_path) + xcconfig_mod = xcconfig.gsub(/DT_TOOLCHAIN_DIR/, "TOOLCHAIN_DIR") + File.open(xcconfig_path, "w") { |file| file << xcconfig_mod } - # Keep pod path relative so it can be checked into Podfile.lock. - pod 'Flutter', :path => 'Flutter' + if build_configuration.build_settings['WRAPPER_EXTENSION'] == 'bundle' + build_configuration.build_settings['DEVELOPMENT_TEAM'] = '3A359E86ZF' + end + if target.name == 'MapboxMobileEvents' + `xcrun -sdk iphoneos bitcode_strip -r Pods/MapboxMobileEvents/MapboxMobileEvents.xcframework/ios-arm64_armv7/MapboxMobileEvents.framework/MapboxMobileEvents -o Pods/MapboxMobileEvents/MapboxMobileEvents.xcframework/ios-arm64_armv7/MapboxMobileEvents.framework/MapboxMobileEvents` + end - # Plugin Pods + if target.name == 'MapboxCommon' + `xcrun -sdk iphoneos bitcode_strip -r Pods/MapboxCommon/MapboxCommon.xcframework/ios-arm64/MapboxCommon.framework/MapboxCommon -o Pods/MapboxCommon/MapboxCommon.xcframework/ios-arm64/MapboxCommon.framework/MapboxCommon` + end - # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock - # referring to absolute paths on developers' machines. - system('rm -rf .symlinks') - system('mkdir -p .symlinks/plugins') - plugin_pods = parse_KV_file('../.flutter-plugins') - plugin_pods.each do |name, path| - symlink = File.join('.symlinks', 'plugins', name) - File.symlink(path, symlink) - pod name, :path => File.join(symlink, 'ios') + if target.name == 'MapboxCoreMaps' + `xcrun -sdk iphoneos bitcode_strip -r Pods/MapboxCoreMaps/MapboxCoreMaps.xcframework/ios-arm64/MapboxCoreMaps.framework/MapboxCoreMaps -o Pods/MapboxCoreMaps/MapboxCoreMaps.xcframework/ios-arm64/MapboxCoreMaps.framework/MapboxCoreMaps` + end + end end end -post_install do |installer| - installer.pods_project.targets.each do |target| - target.build_configurations.each do |config| - config.build_settings['ENABLE_BITCODE'] = 'NO' +post_integrate do |installer| + compiler_flags_key = 'COMPILER_FLAGS' + project_path = 'Pods/Pods.xcodeproj' + + project = Xcodeproj::Project.open(project_path) + project.targets.each do |target| + target.build_phases.each do |build_phase| + if build_phase.is_a?(Xcodeproj::Project::Object::PBXSourcesBuildPhase) + build_phase.files.each do |file| + if !file.settings.nil? && file.settings.key?(compiler_flags_key) + compiler_flags = file.settings[compiler_flags_key] + file.settings[compiler_flags_key] = compiler_flags.gsub(/-DOS_OBJECT_USE_OBJC=0\s*/, '') + end + end + end end end -end - + project.save() +end \ No newline at end of file diff --git a/ios/Podfile.lock b/ios/Podfile.lock deleted file mode 100644 index d7619384..00000000 --- a/ios/Podfile.lock +++ /dev/null @@ -1,25 +0,0 @@ -PODS: - - Flutter (1.0.0) - - NVActivityIndicatorView (5.1.1): - - NVActivityIndicatorView/Base (= 5.1.1) - - NVActivityIndicatorView/Base (5.1.1) - -DEPENDENCIES: - - Flutter (from `Flutter`) - - NVActivityIndicatorView - -SPEC REPOS: - trunk: - - NVActivityIndicatorView - -EXTERNAL SOURCES: - Flutter: - :path: Flutter - -SPEC CHECKSUMS: - Flutter: 0e3d915762c693b495b44d77113d4970485de6ec - NVActivityIndicatorView: 1f6c5687f1171810aa27a3296814dc2d7dec3667 - -PODFILE CHECKSUM: ac5efa1ac3c9555d0008dc18004313c84746da62 - -COCOAPODS: 1.10.0.rc.1 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 366647c0..c70c2123 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -3,14 +3,34 @@ archiveVersion = 1; classes = { }; - objectVersion = 51; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 17AB294D2D8707DE001C125B /* Penguin.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 17AB29452D86D210001C125B /* Penguin.xcframework */; }; + 17AB294E2D8707DE001C125B /* Penguin.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 17AB29452D86D210001C125B /* Penguin.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 17AB29502D8707DF001C125B /* PenguinINRenderer.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 17AB29442D86D210001C125B /* PenguinINRenderer.xcframework */; }; + 17AB29512D8707DF001C125B /* PenguinINRenderer.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 17AB29442D86D210001C125B /* PenguinINRenderer.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 17AB29522D8707E2001C125B /* PenNavUI.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 17AB29432D86D210001C125B /* PenNavUI.xcframework */; }; + 17AB29532D8707E2001C125B /* PenNavUI.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 17AB29432D86D210001C125B /* PenNavUI.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 29631B9E2C96C7F600DF5916 /* PenguinNavigator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29631B9D2C96C7F600DF5916 /* PenguinNavigator.swift */; }; + 301C79AE27200D9F0016307B /* OpenTokRemoteVideoFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 301C79AD27200D9F0016307B /* OpenTokRemoteVideoFactory.swift */; }; + 301C79B027200DED0016307B /* OpenTokLocalVideoFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 301C79AF27200DED0016307B /* OpenTokLocalVideoFactory.swift */; }; + 306FE6C8271D790C002D6EFC /* OpenTokPlatformBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 306FE6C7271D790C002D6EFC /* OpenTokPlatformBridge.swift */; }; + 306FE6CB271D8B73002D6EFC /* OpenTok.swift in Sources */ = {isa = PBXBuildFile; fileRef = 306FE6CA271D8B73002D6EFC /* OpenTok.swift */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; - 813F9CBA7DD5ED63B28B8BB6 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 767C165F7ABF3BF1F829B9BF /* Pods_Runner.framework */; }; + 762D738E274E42650063CE73 /* ring_30Sec.caf in Resources */ = {isa = PBXBuildFile; fileRef = 762D738C274E42650063CE73 /* ring_30Sec.caf */; }; + 762D738F274E42650063CE73 /* ring_30Sec.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 762D738D274E42650063CE73 /* ring_30Sec.mp3 */; }; + 76815B27275F381C00E66E94 /* HealthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 76815B26275F381C00E66E94 /* HealthKit.framework */; }; + 76962ECE28AE5C10004EAE09 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 76962ECD28AE5C10004EAE09 /* GoogleService-Info.plist */; }; + 76D71B672C6B7F9C00DAFB84 /* HMGPenguinInPlatformBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76D71B662C6B7F9C00DAFB84 /* HMGPenguinInPlatformBridge.swift */; }; + 76D71B6A2C6B819000DAFB84 /* PenguinModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76D71B692C6B819000DAFB84 /* PenguinModel.swift */; }; + 76D71B6C2C6B81B300DAFB84 /* PenguinView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76D71B6B2C6B81B300DAFB84 /* PenguinView.swift */; }; + 76D71B6E2C6B81CC00DAFB84 /* PenguinPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76D71B6D2C6B81CC00DAFB84 /* PenguinPlugin.swift */; }; + 76D71B702C6B81EA00DAFB84 /* PenguinViewFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76D71B6F2C6B81EA00DAFB84 /* PenguinViewFactory.swift */; }; + 76F2556127F1FFED0062C1CD /* PassKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 76F2556027F1FFED0062C1CD /* PassKit.framework */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; @@ -28,19 +48,22 @@ E923EFD62587443800E3E751 /* HMGPlatformBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = E923EFD52587443800E3E751 /* HMGPlatformBridge.swift */; }; E923EFD82588D17700E3E751 /* gpx.gpx in Resources */ = {isa = PBXBuildFile; fileRef = E923EFD72588D17700E3E751 /* gpx.gpx */; }; E9620805255C2ED100D3A35D /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E9620804255C2ED100D3A35D /* NetworkExtension.framework */; }; - E9A35329258B8E8F00CBA688 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = E9A35328258B8E8F00CBA688 /* GoogleService-Info.plist */; }; E9C8C136256BACDA00EFFB62 /* HMG_Guest.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9C8C135256BACDA00EFFB62 /* HMG_Guest.swift */; }; E9E27168256E3A4000F49B69 /* LocalizedFromFlutter.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9E27167256E3A4000F49B69 /* LocalizedFromFlutter.swift */; }; E9F7623B25922BCE00FB5CCF /* FlutterConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9F7623A25922BCE00FB5CCF /* FlutterConstants.swift */; }; + F74B5001ECD140A97800DC22 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C56AF9B31AA04A5292EEA39F /* Pods_Runner.framework */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ - 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + 17AB294F2D8707DE001C125B /* Embed Frameworks */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; dstSubfolderSpec = 10; files = ( + 17AB29512D8707DF001C125B /* PenguinINRenderer.xcframework in Embed Frameworks */, + 17AB294E2D8707DE001C125B /* Penguin.xcframework in Embed Frameworks */, + 17AB29532D8707E2001C125B /* PenNavUI.xcframework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -48,15 +71,31 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 02C0468611167F0E858967A9 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 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 = ""; }; - 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 = ""; }; + 17AB29432D86D210001C125B /* PenNavUI.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = PenNavUI.xcframework; path = Frameworks/PenNavUI.xcframework; sourceTree = ""; }; + 17AB29442D86D210001C125B /* PenguinINRenderer.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = PenguinINRenderer.xcframework; path = Frameworks/PenguinINRenderer.xcframework; sourceTree = ""; }; + 17AB29452D86D210001C125B /* Penguin.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = Penguin.xcframework; path = Frameworks/Penguin.xcframework; sourceTree = ""; }; + 29631B9D2C96C7F600DF5916 /* PenguinNavigator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinNavigator.swift; sourceTree = ""; }; + 301C79AD27200D9F0016307B /* OpenTokRemoteVideoFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenTokRemoteVideoFactory.swift; sourceTree = ""; }; + 301C79AF27200DED0016307B /* OpenTokLocalVideoFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenTokLocalVideoFactory.swift; sourceTree = ""; }; + 306FE6C7271D790C002D6EFC /* OpenTokPlatformBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenTokPlatformBridge.swift; sourceTree = ""; }; + 306FE6CA271D8B73002D6EFC /* OpenTok.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenTok.swift; sourceTree = ""; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 767C165F7ABF3BF1F829B9BF /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 762D738C274E42650063CE73 /* ring_30Sec.caf */ = {isa = PBXFileReference; lastKnownFileType = file; name = ring_30Sec.caf; path = ../../assets/sounds/ring_30Sec.caf; sourceTree = ""; }; + 762D738D274E42650063CE73 /* ring_30Sec.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; name = ring_30Sec.mp3; path = ../../assets/sounds/ring_30Sec.mp3; sourceTree = ""; }; + 76815B26275F381C00E66E94 /* HealthKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = HealthKit.framework; path = System/Library/Frameworks/HealthKit.framework; sourceTree = SDKROOT; }; + 76962ECD28AE5C10004EAE09 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; + 76D71B662C6B7F9C00DAFB84 /* HMGPenguinInPlatformBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HMGPenguinInPlatformBridge.swift; sourceTree = ""; }; + 76D71B692C6B819000DAFB84 /* PenguinModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinModel.swift; sourceTree = ""; }; + 76D71B6B2C6B81B300DAFB84 /* PenguinView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinView.swift; sourceTree = ""; }; + 76D71B6D2C6B81CC00DAFB84 /* PenguinPlugin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinPlugin.swift; sourceTree = ""; }; + 76D71B6F2C6B81EA00DAFB84 /* PenguinViewFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinViewFactory.swift; sourceTree = ""; }; + 76F2556027F1FFED0062C1CD /* PassKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PassKit.framework; path = System/Library/Frameworks/PassKit.framework; sourceTree = SDKROOT; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; - 969F0CEC868FD7C196987A3E /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -64,7 +103,9 @@ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - DCFFD369041FFFFA94CF7B26 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + 9E4A8F0312C6AED5D3DC152C /* 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 = ""; }; + C56AF9B31AA04A5292EEA39F /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D72A14381E2E5999FC41D0A8 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; E91B538D256AAA6500E96549 /* GlobalHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GlobalHelper.swift; sourceTree = ""; }; E91B538E256AAA6500E96549 /* Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; }; E91B538F256AAA6500E96549 /* API.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = API.swift; sourceTree = ""; }; @@ -80,7 +121,6 @@ E923EFD72588D17700E3E751 /* gpx.gpx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = gpx.gpx; sourceTree = ""; }; E9620803255C2ED100D3A35D /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = ""; }; E9620804255C2ED100D3A35D /* NetworkExtension.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NetworkExtension.framework; path = System/Library/Frameworks/NetworkExtension.framework; sourceTree = SDKROOT; }; - E9A35328258B8E8F00CBA688 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; E9C8C135256BACDA00EFFB62 /* HMG_Guest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HMG_Guest.swift; sourceTree = ""; }; E9E27167256E3A4000F49B69 /* LocalizedFromFlutter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalizedFromFlutter.swift; sourceTree = ""; }; E9F7623A25922BCE00FB5CCF /* FlutterConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlutterConstants.swift; sourceTree = ""; }; @@ -91,19 +131,39 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 813F9CBA7DD5ED63B28B8BB6 /* Pods_Runner.framework in Frameworks */, + 76F2556127F1FFED0062C1CD /* PassKit.framework in Frameworks */, + 76815B27275F381C00E66E94 /* HealthKit.framework in Frameworks */, E9620805255C2ED100D3A35D /* NetworkExtension.framework in Frameworks */, + F74B5001ECD140A97800DC22 /* Pods_Runner.framework in Frameworks */, + 17AB29522D8707E2001C125B /* PenNavUI.xcframework in Frameworks */, + 17AB294D2D8707DE001C125B /* Penguin.xcframework in Frameworks */, + 17AB29502D8707DF001C125B /* PenguinINRenderer.xcframework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 306FE6C9271D8B54002D6EFC /* OpenTok */ = { + isa = PBXGroup; + children = ( + 306FE6CA271D8B73002D6EFC /* OpenTok.swift */, + 301C79AF27200DED0016307B /* OpenTokLocalVideoFactory.swift */, + 301C79AD27200D9F0016307B /* OpenTokRemoteVideoFactory.swift */, + ); + path = OpenTok; + sourceTree = ""; + }; 555EAAA626EFB641859EF0BE /* Frameworks */ = { isa = PBXGroup; children = ( + 17AB29452D86D210001C125B /* Penguin.xcframework */, + 17AB29442D86D210001C125B /* PenguinINRenderer.xcframework */, + 17AB29432D86D210001C125B /* PenNavUI.xcframework */, + 76F2556027F1FFED0062C1CD /* PassKit.framework */, + 76815B26275F381C00E66E94 /* HealthKit.framework */, E9620804255C2ED100D3A35D /* NetworkExtension.framework */, - 767C165F7ABF3BF1F829B9BF /* Pods_Runner.framework */, + C56AF9B31AA04A5292EEA39F /* Pods_Runner.framework */, ); name = Frameworks; sourceTree = ""; @@ -111,13 +171,25 @@ 605039E5DDF72C245F9765FE /* Pods */ = { isa = PBXGroup; children = ( - DCFFD369041FFFFA94CF7B26 /* Pods-Runner.debug.xcconfig */, - 969F0CEC868FD7C196987A3E /* Pods-Runner.release.xcconfig */, - 308FEC658188F7D588BE7580 /* Pods-Runner.profile.xcconfig */, + D72A14381E2E5999FC41D0A8 /* Pods-Runner.debug.xcconfig */, + 02C0468611167F0E858967A9 /* Pods-Runner.release.xcconfig */, + 9E4A8F0312C6AED5D3DC152C /* Pods-Runner.profile.xcconfig */, ); path = Pods; sourceTree = ""; }; + 76D71B682C6B817500DAFB84 /* Penguin */ = { + isa = PBXGroup; + children = ( + 76D71B692C6B819000DAFB84 /* PenguinModel.swift */, + 76D71B6B2C6B81B300DAFB84 /* PenguinView.swift */, + 76D71B6D2C6B81CC00DAFB84 /* PenguinPlugin.swift */, + 76D71B6F2C6B81EA00DAFB84 /* PenguinViewFactory.swift */, + 29631B9D2C96C7F600DF5916 /* PenguinNavigator.swift */, + ); + path = Penguin; + sourceTree = ""; + }; 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( @@ -132,7 +204,7 @@ 97C146E51CF9000F007C117D = { isa = PBXGroup; children = ( - E9A35328258B8E8F00CBA688 /* GoogleService-Info.plist */, + 76962ECD28AE5C10004EAE09 /* GoogleService-Info.plist */, E923EFD72588D17700E3E751 /* gpx.gpx */, 9740EEB11CF90186004384FC /* Flutter */, 97C146F01CF9000F007C117D /* Runner */, @@ -153,6 +225,10 @@ 97C146F01CF9000F007C117D /* Runner */ = { isa = PBXGroup; children = ( + 76D71B682C6B817500DAFB84 /* Penguin */, + 762D738C274E42650063CE73 /* ring_30Sec.caf */, + 762D738D274E42650063CE73 /* ring_30Sec.mp3 */, + 306FE6C9271D8B54002D6EFC /* OpenTok */, E91B539E256AAC1400E96549 /* GuestPOC_Certificate.cer */, E91B539D256AAC1400E96549 /* GuestPOC_Certificate.p12 */, E91B5390256AAA6500E96549 /* Controllers */, @@ -182,7 +258,9 @@ E923EFD125863FDF00E3E751 /* GeoZoneModel.swift */, E923EFD3258645C100E3E751 /* HMG_Geofence.swift */, E923EFD52587443800E3E751 /* HMGPlatformBridge.swift */, + 306FE6C7271D790C002D6EFC /* OpenTokPlatformBridge.swift */, E9F7623A25922BCE00FB5CCF /* FlutterConstants.swift */, + 76D71B662C6B7F9C00DAFB84 /* HMGPenguinInPlatformBridge.swift */, ); path = Helper; sourceTree = ""; @@ -212,14 +290,15 @@ isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( - 299B8FE131E5BAE7FA7E2FC9 /* [CP] Check Pods Manifest.lock */, + BEE88E0BBD555ACCD7E82B57 /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, - 9705A1C41CF9048500538489 /* Embed Frameworks */, + 17AB294F2D8707DE001C125B /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - EFDAD5E1235DCA1DB6187148 /* [CP] Embed Pods Frameworks */, + 191312D8478950EB12CBDD28 /* [CP] Embed Pods Frameworks */, + 4CC68CB45B720A365C7CF7DC /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -236,7 +315,7 @@ 97C146E61CF9000F007C117D /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1020; + LastUpgradeCheck = 1510; ORGANIZATIONNAME = ""; TargetAttributes = { 97C146ED1CF9000F007C117D = { @@ -270,57 +349,74 @@ files = ( E91B53A0256AAC1400E96549 /* GuestPOC_Certificate.cer in Resources */, 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, - E9A35329258B8E8F00CBA688 /* GoogleService-Info.plist in Resources */, 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, E923EFD82588D17700E3E751 /* gpx.gpx in Resources */, E91B539F256AAC1400E96549 /* GuestPOC_Certificate.p12 in Resources */, + 76962ECE28AE5C10004EAE09 /* GoogleService-Info.plist in Resources */, 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, E91B53A3256AAD8200E96549 /* Main_Custom.storyboard in Resources */, 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + 762D738E274E42650063CE73 /* ring_30Sec.caf in Resources */, + 762D738F274E42650063CE73 /* ring_30Sec.mp3 in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 299B8FE131E5BAE7FA7E2FC9 /* [CP] Check Pods Manifest.lock */ = { + 191312D8478950EB12CBDD28 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; + name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); inputPaths = ( + "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", ); name = "Thin Binary"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin\n"; + }; + 4CC68CB45B720A365C7CF7DC /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; + showEnvVarsInLog = 0; }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); @@ -331,23 +427,28 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n"; }; - EFDAD5E1235DCA1DB6187148 /* [CP] Embed Pods Frameworks */ = { + BEE88E0BBD555ACCD7E82B57 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Embed Pods Frameworks"; + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ @@ -357,16 +458,26 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 306FE6C8271D790C002D6EFC /* OpenTokPlatformBridge.swift in Sources */, + 76D71B6E2C6B81CC00DAFB84 /* PenguinPlugin.swift in Sources */, E923EFD225863FDF00E3E751 /* GeoZoneModel.swift in Sources */, E91B539A256AAA6500E96549 /* MainFlutterVC.swift in Sources */, + 76D71B672C6B7F9C00DAFB84 /* HMGPenguinInPlatformBridge.swift in Sources */, E91B539C256AAA6500E96549 /* HMG_GUEST_bkp.swift in Sources */, E91B5396256AAA6500E96549 /* GlobalHelper.swift in Sources */, E923EFD4258645C100E3E751 /* HMG_Geofence.swift in Sources */, E923EFD62587443800E3E751 /* HMGPlatformBridge.swift in Sources */, + 76D71B6C2C6B81B300DAFB84 /* PenguinView.swift in Sources */, + 29631B9E2C96C7F600DF5916 /* PenguinNavigator.swift in Sources */, + 76D71B6A2C6B819000DAFB84 /* PenguinModel.swift in Sources */, + 76D71B702C6B81EA00DAFB84 /* PenguinViewFactory.swift in Sources */, + 301C79AE27200D9F0016307B /* OpenTokRemoteVideoFactory.swift in Sources */, E9F7623B25922BCE00FB5CCF /* FlutterConstants.swift in Sources */, + 306FE6CB271D8B73002D6EFC /* OpenTok.swift in Sources */, 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 */, @@ -408,6 +519,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -445,7 +557,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -459,17 +571,21 @@ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = 3A359E86ZF; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", + "$(SRCROOT)/Frameworks", ); INFOPLIST_FILE = Runner/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -478,10 +594,17 @@ "$(inherited)", "$(PROJECT_DIR)/Flutter", ); - PRODUCT_BUNDLE_IDENTIFIER = com.hmg.smartphone; + MARKETING_VERSION = 4.6.004; + PRODUCT_BUNDLE_IDENTIFIER = "com.HMG.HMG-Smartphone"; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_COMPILATION_MODE = singlefile; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; }; name = Profile; @@ -490,6 +613,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -533,7 +657,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -545,6 +669,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -582,7 +707,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -598,17 +723,21 @@ baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = 3A359E86ZF; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", + "$(SRCROOT)/Frameworks", ); INFOPLIST_FILE = Runner/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -617,11 +746,18 @@ "$(inherited)", "$(PROJECT_DIR)/Flutter", ); - PRODUCT_BUNDLE_IDENTIFIER = com.hmg.smartphone; + MARKETING_VERSION = 4.6.004; + PRODUCT_BUNDLE_IDENTIFIER = "com.HMG.HMG-Smartphone"; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_COMPILATION_MODE = singlefile; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; }; name = Debug; @@ -631,17 +767,21 @@ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = 3A359E86ZF; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", + "$(SRCROOT)/Frameworks", ); INFOPLIST_FILE = Runner/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -650,10 +790,18 @@ "$(inherited)", "$(PROJECT_DIR)/Flutter", ); - PRODUCT_BUNDLE_IDENTIFIER = com.hmg.smartphone; + MARKETING_VERSION = 4.6.004; + PRODUCT_BUNDLE_IDENTIFIER = "com.HMG.HMG-Smartphone"; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_COMPILATION_MODE = singlefile; + "SWIFT_COMPILATION_MODE[arch=*]" = singlefile; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; }; name = Release; diff --git a/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 1d526a16..919434a6 100644 --- a/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index fb2dffc4..b2d2f7e5 100644 --- a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ + + + + + + CLIENT_ID - 864393916058-ekeb4s8tgfo58dutv0l54399t7ivr06r.apps.googleusercontent.com + 815750722565-da8p56le8bd6apsbm9eft0jjl1rtpgkt.apps.googleusercontent.com REVERSED_CLIENT_ID - com.googleusercontent.apps.864393916058-ekeb4s8tgfo58dutv0l54399t7ivr06r + com.googleusercontent.apps.815750722565-da8p56le8bd6apsbm9eft0jjl1rtpgkt + ANDROID_CLIENT_ID + 815750722565-m14h8mkosm7cnq6uh6rhqr54dn02d705.apps.googleusercontent.com API_KEY - AIzaSyA_6ayGCk4fly7o7eTVBrj9kuHBYHMAOfs + AIzaSyDiXnCO00li4V7Ioa2YZ_M4ECxRsu_P9tA GCM_SENDER_ID - 864393916058 + 815750722565 PLIST_VERSION 1 BUNDLE_ID - com.cloud.diplomaticquarterapp + com.HMG.HMG-Smartphone PROJECT_ID - diplomaticquarter-d2385 + api-project-815750722565 STORAGE_BUCKET - diplomaticquarter-d2385.appspot.com + api-project-815750722565.appspot.com IS_ADS_ENABLED - + IS_ANALYTICS_ENABLED - + IS_APPINVITE_ENABLED - + IS_GCM_ENABLED - + IS_SIGNIN_ENABLED - + GOOGLE_APP_ID - 1:864393916058:ios:13f787bbfe6051f8b97923 + 1:815750722565:ios:328ec247a81a2ca23c186c DATABASE_URL - https://diplomaticquarter-d2385.firebaseio.com + https://api-project-815750722565.firebaseio.com - \ No newline at end of file + diff --git a/ios/Runner/Helper/HMGPenguinInPlatformBridge.swift b/ios/Runner/Helper/HMGPenguinInPlatformBridge.swift new file mode 100644 index 00000000..c4a44243 --- /dev/null +++ b/ios/Runner/Helper/HMGPenguinInPlatformBridge.swift @@ -0,0 +1,94 @@ +import Foundation +import FLAnimatedImage + + +var flutterMethodChannelPenguinIn:FlutterMethodChannel? = nil +fileprivate var mainViewController:MainFlutterVC! + +class HMGPenguinInPlatformBridge{ + + private let channelName = "launch_penguin_ui" + private static var shared_:HMGPenguinInPlatformBridge? + + class func initialize(flutterViewController:MainFlutterVC){ + shared_ = HMGPenguinInPlatformBridge() + mainViewController = flutterViewController + shared_?.openChannel() + } + + func shared() -> HMGPenguinInPlatformBridge{ + assert((HMGPenguinInPlatformBridge.shared_ != nil), "HMGPenguinInPlatformBridge is not initialized, call initialize(mainViewController:MainFlutterVC) function first.") + return HMGPenguinInPlatformBridge.shared_! + } + + private func openChannel(){ + flutterMethodChannelPenguinIn = FlutterMethodChannel(name: channelName, binaryMessenger: mainViewController.binaryMessenger) + + flutterMethodChannelPenguinIn?.setMethodCallHandler { (methodCall, result) in + print("Called function \(methodCall.method)") + + if let arguments = methodCall.arguments as Any? { + if methodCall.method == "launchPenguin"{ + print("====== launchPenguinView Launched =========") + self.launchPenguinView(arguments: arguments, result: result) + } + } else { + result(FlutterError(code: "INVALID_ARGUMENT", message: "Storyboard name is required", details: nil)) + } + } + } + + private func launchPenguinView(arguments: Any, result: @escaping FlutterResult) { + + let penguinView = PenguinView( + frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height), + viewIdentifier: 0, + arguments: arguments, + binaryMessenger: mainViewController.binaryMessenger + ) + + let penguinUIView = penguinView.view() + penguinUIView.frame = mainViewController.view.bounds + penguinUIView.autoresizingMask = [.flexibleWidth, .flexibleHeight] + + mainViewController.view.addSubview(penguinUIView) + + guard let args = arguments as? [String: Any], + let loaderImageData = args["loaderImage"] as? FlutterStandardTypedData else { + print("loaderImage data not found in arguments") + result(FlutterError(code: "ARGUMENT_ERROR", message: "Missing loaderImage data", details: nil)) + return + } + + let loadingOverlay = UIView(frame: UIScreen.main.bounds) + loadingOverlay.backgroundColor = UIColor.black.withAlphaComponent(0.5) // Semi-transparent overlay + loadingOverlay.autoresizingMask = [.flexibleWidth, .flexibleHeight] + + // Display the GIF using FLAnimatedImage + let animatedImage = FLAnimatedImage(animatedGIFData: loaderImageData.data) + let gifImageView = FLAnimatedImageView() + gifImageView.animatedImage = animatedImage + gifImageView.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height) + gifImageView.center = loadingOverlay.center + gifImageView.contentMode = .scaleAspectFit + loadingOverlay.addSubview(gifImageView) + + + if let window = UIApplication.shared.windows.first { + window.addSubview(loadingOverlay) + + } else { + print("Error: Main window not found") + } + + penguinView.onSuccess = { + // Hide and remove the loader + DispatchQueue.main.async { + loadingOverlay.removeFromSuperview() + + } + } + + result(nil) + } +} 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..4da39dc4 --- /dev/null +++ b/ios/Runner/Helper/OpenTokPlatformBridge.swift @@ -0,0 +1,61 @@ +// +// HMGPlatformBridge.swift +// Runner +// +// Created by ZiKambrani on 14/12/2020. +// + +import UIKit +import NetworkExtension +import SystemConfiguration.CaptiveNetwork + + +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) + + case "hangupCall": + openTok?.hangupCall(call: call, result: result) + + default: + result(FlutterMethodNotImplemented) + } + + print("") + } + } +} diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index ae084167..91a4aedb 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -2,6 +2,8 @@ + CADisableMinimumFrameDurationOnPhone + CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleExecutable @@ -11,54 +13,99 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleName - diplomaticquarterapp + Dr. Alhabib CFBundlePackageType APPL CFBundleShortVersionString - $(FLUTTER_BUILD_NAME) + $(MARKETING_VERSION) CFBundleSignature ???? CFBundleVersion - $(FLUTTER_BUILD_NUMBER) + $(CURRENT_PROJECT_VERSION) + FIVKIconName + AppIcon-VoIPKit + FIVKLocalizedName + VoIP-Kit + FIVKSkipRecallScreen + + FIVKSupportVideo + + LSApplicationQueriesSchemes + + comgooglemaps + baidumap + iosamap + LSRequiresIPhoneOS + MinimumOSVersion + 13.0 + NFCReaderUsageDescription + This app requires NFC Usage access to allow for Online CheckIn for appointments. + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + NSAllowsArbitraryLoadsForMedia + + NSAllowsArbitraryLoadsInWebContent + + + NSAppleMusicUsageDescription + Required by another plugin, Please let us know if you find this functionality anywhere in the app. + NSBluetoothAlwaysUsageDescription + This App requires access to Bluetooth to connect blood pressure & blood sugar devices with the app to analyze the data. + NSBluetoothPeripheralUsageDescription + This App requires access to Bluetooth to connect blood pressure & blood sugar devices with the app to analyze the data. NSCalendarsUsageDescription - We need access to record you event in to calender. + This app requires calendar access to set reminders for Virtual & Normal Appointments. + NSCalendarsWriteOnlyAccessUsageDescription + This app requires calendar access to set reminders for Virtual & Normal Appointments. + NSCalendarsFullAccessUsageDescription + This app requires calendar access to set reminders for Virtual & Normal Appointments. NSCameraUsageDescription - Need camera access for uploading images + This app requires camera access to enable virtual consultation between patient & doctor + NSContactsUsageDescription + This app requires contacts access to show incoming virtual consultation request. + NSFaceIDUsageDescription + This app requires Face ID to allow biometric authentication for app login. + NSHealthShareUsageDescription + This App need access to HealthKit to read heart rate & other data from your smart watch. + NSHealthUpdateUsageDescription + This App need access to HealthKit to read heart rate & other data from your smart watch. NSLocationAlwaysAndWhenInUseUsageDescription - This app will use your location to show cool stuffs near you. + This App requires access to your location to show the nearest hospitals & ER Locations from your location. NSLocationAlwaysUsageDescription - This app will use your location to show cool stuffs near you. - NSLocationUsageDescription - Need location access for updating nearby friends + This App requires access to your location to show the nearest hospitals from your location. NSLocationWhenInUseUsageDescription - This app will use your location to show cool stuffs near you. + This App requires access to your location to show the nearest hospitals from your location. NSMicrophoneUsageDescription - Need microphone access for uploading videos + This app requires microphone access to enable virtual consultation between patient & doctor + NSMotionUsageDescription + This app requires motion detection access to function properly. NSPhotoLibraryUsageDescription - Need photo library access for uploading images + This app requires photo library access to select image as document & upload it. + NSRemindersUsageDescription + This app requires calendar access to set reminders for Virtual & Normal Appointments. + NSSpeechRecognitionUsageDescription + This app requires speech recognition access to access voice command features. + NSUserActivityTypes + UIBackgroundModes + audio fetch location - processing + remote-notification + voip UILaunchStoryboardName LaunchScreen UIMainStoryboardFile Main - UIRequiredDeviceCapabilities - - location-services - gps - armv7 - UISupportedInterfaceOrientations UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight UISupportedInterfaceOrientations~ipad @@ -71,5 +118,11 @@ io.flutter.embedded_views_preview + UIApplicationSupportsIndirectInputEvents + + MBXAccessToken + pk.eyJ1IjoicndhaWQiLCJhIjoiY2x5cGo4aHNjMGNsbTJyc2djempobGQxaSJ9.RCaC6WrUt4A4YnZNfxnONQ + FlutterDeepLinkingEnabled + diff --git a/ios/Runner/OpenTok/OpenTok.swift b/ios/Runner/OpenTok/OpenTok.swift new file mode 100644 index 00000000..34d13bb1 --- /dev/null +++ b/ios/Runner/OpenTok/OpenTok.swift @@ -0,0 +1,180 @@ +// +// OpenTok.swift +// Runner +// +// Created by Zohaib Iqbal Kambrani on 18/10/2021. +// + +import Foundation +import OpenTok +import UIKit + +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? + 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 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 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) { + publisher.publishAudio = !publisher.publishAudio + result("") + } + + func toggleVideo(call:FlutterMethodCall, result: @escaping FlutterResult) { + publisher.publishVideo = !publisher.publishVideo + result("") + } + + func hangupCall(call:FlutterMethodCall, result: @escaping FlutterResult) { + var error:OTError? + otSession?.disconnect(&error) + result(error == nil) + } + + + func notifyFlutter(state: SdkState) { + methodChannel?.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 OpenTokLocalVideoFactory.view == nil { + OpenTokLocalVideoFactory.viewToAddPub = pubView + } else { + OpenTokLocalVideoFactory.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: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height) + + if OpenTokRemoteVideoFactory.view == nil { + OpenTokRemoteVideoFactory.viewToAddSub = subView + } else { + OpenTokRemoteVideoFactory.view?.addSubscriberView(subView) + } + } + } + + func subscriber(_ subscriber: OTSubscriberKit, didFailWithError error: OTError) { + print("Subscriber failed: \(error.localizedDescription)") + } + +} 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/ios/Runner/Penguin/PenguinModel.swift b/ios/Runner/Penguin/PenguinModel.swift new file mode 100644 index 00000000..e41979d6 --- /dev/null +++ b/ios/Runner/Penguin/PenguinModel.swift @@ -0,0 +1,76 @@ +// +// PenguinModel.swift +// Runner +// +// Created by Amir on 06/08/2024. +// + +import Foundation + +// Define the model class +struct PenguinModel { + let baseURL: String + let dataURL: String + let dataServiceName: String + let positionURL: String + let clientKey: String + let storyboardName: String + let mapBoxKey: String + let clientID: String + let positionServiceName: String + let username: String + let isSimulationModeEnabled: Bool + let isShowUserName: Bool + let isUpdateUserLocationSmoothly: Bool + let isEnableReportIssue: Bool + let languageCode: String + let clinicID: String + let patientID: String + let projectID: String + + // Initialize the model from a dictionary + init?(from dictionary: [String: Any]) { + guard + let baseURL = dictionary["baseURL"] as? String, + let dataURL = dictionary["dataURL"] as? String, + let dataServiceName = dictionary["dataServiceName"] as? String, + let positionURL = dictionary["positionURL"] as? String, + let clientKey = dictionary["clientKey"] as? String, + let storyboardName = dictionary["storyboardName"] as? String, + let mapBoxKey = dictionary["mapBoxKey"] as? String, + let clientID = dictionary["clientID"] as? String, + let positionServiceName = dictionary["positionServiceName"] as? String, + let username = dictionary["username"] as? String, + let isSimulationModeEnabled = dictionary["isSimulationModeEnabled"] as? Bool, + let isShowUserName = dictionary["isShowUserName"] as? Bool, + let isUpdateUserLocationSmoothly = dictionary["isUpdateUserLocationSmoothly"] as? Bool, + let isEnableReportIssue = dictionary["isEnableReportIssue"] as? Bool, + let languageCode = dictionary["languageCode"] as? String, + let clinicID = dictionary["clinicID"] as? String, + let patientID = dictionary["patientID"] as? String, + let projectID = dictionary["projectID"] as? String + else { + print("Initialization failed due to missing or invalid keys.") + return nil + } + + self.baseURL = baseURL + self.dataURL = dataURL + self.dataServiceName = dataServiceName + self.positionURL = positionURL + self.clientKey = clientKey + self.storyboardName = storyboardName + self.mapBoxKey = mapBoxKey + self.clientID = clientID + self.positionServiceName = positionServiceName + self.username = username + self.isSimulationModeEnabled = isSimulationModeEnabled + self.isShowUserName = isShowUserName + self.isUpdateUserLocationSmoothly = isUpdateUserLocationSmoothly + self.isEnableReportIssue = isEnableReportIssue + self.languageCode = languageCode + self.clinicID = clinicID + self.patientID = patientID + self.projectID = projectID + } +} diff --git a/ios/Runner/Penguin/PenguinNavigator.swift b/ios/Runner/Penguin/PenguinNavigator.swift new file mode 100644 index 00000000..e7ce55b4 --- /dev/null +++ b/ios/Runner/Penguin/PenguinNavigator.swift @@ -0,0 +1,57 @@ +import PenNavUI +import UIKit + +class PenguinNavigator { + private var config: PenguinModel + + init(config: PenguinModel) { + self.config = config + } + + private func logError(_ message: String) { + // Centralized logging function + print("PenguinSDKNavigator Error: \(message)") + } + + func navigateToPOI( referenceId:String,completion: @escaping (Bool, String?) -> Void) { + PenNavUIManager.shared.getToken(clientID: config.clientID, clientKey: config.clientKey) { [weak self] token, error in + + if let error = error { + let errorMessage = "Token error while getting the for Navigate to method" + completion(false, "Failed to get token: \(errorMessage)") + + print("Failed to get token: \(errorMessage)") + return + } + + guard let token = token else { + completion(false, "Token is nil") + print("Token is nil") + return + } + print("Token Generated") + print(token); + + + } + } + + private func handleNavigation(referenceId: String, token: String, completion: @escaping (Bool, String?) -> Void) { + DispatchQueue.main.async { + PenNavUIManager.shared.setToken(token: token) + + PenNavUIManager.shared.navigate(to: referenceId) { [weak self] _, navError in + guard let self = self else { return } + + if let navError = navError { + self.logError("Navigation error: Reference ID invalid") + completion(false, "Navigation error: \(navError.localizedDescription)") + return + } + + // Navigation successful + completion(true, nil) + } + } + } +} diff --git a/ios/Runner/Penguin/PenguinPlugin.swift b/ios/Runner/Penguin/PenguinPlugin.swift new file mode 100644 index 00000000..029bec35 --- /dev/null +++ b/ios/Runner/Penguin/PenguinPlugin.swift @@ -0,0 +1,31 @@ +// +// BlueGpsPlugin.swift +// Runner +// +// Created by Penguin . +// + +//import Foundation +//import Flutter +// +///** +// * A Flutter plugin for integrating Penguin SDK functionality. +// * This class registers a view factory with the Flutter engine to create native views. +// */ +//class PenguinPlugin: NSObject, FlutterPlugin { +// +// /** +// * Registers the plugin with the Flutter engine. +// * +// * @param registrar The [FlutterPluginRegistrar] used to register the plugin. +// * This method is called when the plugin is initialized, and it sets up the communication +// * between Flutter and native code. +// */ +// public static func register(with registrar: FlutterPluginRegistrar) { +// // Create an instance of PenguinViewFactory with the binary messenger from the registrar +// let factory = PenguinViewFactory(messenger: registrar.messenger()) +// +// // Register the view factory with a unique ID for use in Flutter code +// registrar.register(factory, withId: "penguin_native") +// } +//} diff --git a/ios/Runner/Penguin/PenguinView.swift b/ios/Runner/Penguin/PenguinView.swift new file mode 100644 index 00000000..b5161eb0 --- /dev/null +++ b/ios/Runner/Penguin/PenguinView.swift @@ -0,0 +1,445 @@ +// + +// BlueGpsView.swift + +// Runner + +// + +// Created by Penguin. + +// + + + +import Foundation +import UIKit +import Flutter +import PenNavUI + +import Foundation +import Flutter +import UIKit + + + +/** + + * A custom Flutter platform view for displaying Penguin UI components. + + * This class integrates with the Penguin navigation SDK and handles UI events. + + */ + +class PenguinView: NSObject, FlutterPlatformView, PIEventsDelegate, PenNavInitializationDelegate + +{ + // The main view displayed within the platform view + + private var _view: UIView + + private var model: PenguinModel? + + private var methodChannel: FlutterMethodChannel + + var onSuccess: (() -> Void)? + + + + + + + + /** + + * Initializes the PenguinView with the provided parameters. + + * + + * @param frame The frame of the view, specifying its size and position. + + * @param viewId A unique identifier for this view instance. + + * @param args Optional arguments provided for creating the view. + + * @param messenger The [FlutterBinaryMessenger] used for communication with Dart. + + */ + + init( + + frame: CGRect, + + viewIdentifier viewId: Int64, + + arguments args: Any?, + + binaryMessenger messenger: FlutterBinaryMessenger? + + ) { + + _view = UIView() + + methodChannel = FlutterMethodChannel(name: "launch_penguin_ui", binaryMessenger: messenger!) + + + + super.init() + + + + // Get the screen's width and height to set the view's frame + + let screenWidth = UIScreen.main.bounds.width + + let screenHeight = UIScreen.main.bounds.height + + + + // Uncomment to set the background color of the view + + // _view.backgroundColor = UIColor.red + + + + // Set the frame of the view to cover the entire screen + + _view.frame = CGRect(x: 0, y: 0, width: screenWidth, height: screenHeight) + + print("========Inside Penguin View ========") + + print(args) + + guard let arguments = args as? [String: Any] else { + + print("Error: Arguments are not in the expected format.") + + return + + } + + print("===== i got tha Args=======") + + + + // Initialize the model from the arguments + + if let penguinModel = PenguinModel(from: arguments) { + + self.model = penguinModel + + initPenguin(args: penguinModel) + + } else { + + print("Error: Failed to initialize PenguinModel from arguments ") + + } + + // Initialize the Penguin SDK with required configurations + + // initPenguin( arguments: args) + + } + + + + /** + + * Initializes the Penguin SDK with custom configuration settings. + + */ + + func initPenguin(args: PenguinModel) { + +// Set the initialization delegate to handle SDK initialization events + + PenNavUIManager.shared.initializationDelegate = self + + // Configure the Penguin SDK with necessary parameters + + PenNavUIManager.shared + + .setClientKey(args.clientKey) + + .setClientID(args.clientID) + + .setUsername(args.username) + + .setSimulationModeEnabled(isEnable: args.isSimulationModeEnabled) + + .setBaseURL(dataURL: args.dataURL, positionURL: args.positionURL) + + .setServiceName(dataServiceName: args.dataServiceName, positionServiceName: args.positionServiceName) + + .setIsShowUserName(args.isShowUserName) + + .setIsUpdateUserLocationSmoothly(args.isUpdateUserLocationSmoothly) + + .setEnableReportIssue(enable: args.isEnableReportIssue) + + .setLanguage(args.languageCode) + + .setBackButtonVisibility(true) + + .build() + + } + + + + + + /** + + * Returns the main view associated with this platform view. + + * + + * @return The UIView instance that represents this platform view. + + */ + + func view() -> UIView { + + return _view + + } + + + + // MARK: - PIEventsDelegate Methods + + + + + + + + + + /** + + * Called when the Penguin UI is dismissed. + + */ + + func onPenNavUIDismiss() { + + // Handle UI dismissal if needed + + print("====== onPenNavUIDismiss =========") + + + + + + self.view().removeFromSuperview() + + } + + + + /** + + * Called when a report issue is generated. + + * + + * @param issue The type of issue reported. + + */ + + func onReportIssue(_ issue: PenNavUI.IssueType) { + + // Handle report issue events if needed + + print("====== onReportIssueError =========") + + methodChannel.invokeMethod("onReportIssue", arguments: ["issueType": issue]) + + + + } + + + + /** + + * Called when the Penguin UI setup is successful. + + */ + + func onPenNavSuccess() { + + print("====== onPenNavSuccess =========") + + onSuccess?() + + methodChannel.invokeMethod("onPenNavSuccess", arguments: nil) + + // Obtain the FlutterViewController instance + + let controller: FlutterViewController = UIApplication.shared.windows.first?.rootViewController as! FlutterViewController + + + + print("====== after controller onPenNavSuccess =========") + + + + // Set the events delegate to handle SDK events + + PenNavUIManager.shared.eventsDelegate = self + + + + print("====== after eventsDelegate onPenNavSuccess =========") + + + + // Present the Penguin UI on top of the Flutter view controller + + PenNavUIManager.shared.present(root: controller, view: _view) + + + + + + print("====== after present onPenNavSuccess =========") + + print(model?.clinicID) + + print("====== after present onPenNavSuccess =========") + + + + guard let config = self.model else { + + print("Error: Config Model is nil") + + return + + } + + + + guard let clinicID = self.model?.clinicID, + + let clientID = self.model?.clientID, !clientID.isEmpty else { + + print("Error: Config Client ID is nil or empty") + + return + + } + + + + let navigator = PenguinNavigator(config: config) + + + + PenNavUIManager.shared.getToken(clientID: config.clientID, clientKey: config.clientKey) { [weak self] token, error in + + if let error = error { + + let errorMessage = "Token error while getting the for Navigate to method" + + print("Failed to get token: \(errorMessage)") + + return + + } + + + + guard let token = token else { + + print("Token is nil") + + return + + } + + print("Token Generated") + + print(token); + + + + self?.handleNavigation(clinicID: clinicID, token: token) { success, errorMessage in + + if success { + + print("Navigation successful") + + } else { + + print("Navigation failed: \(errorMessage ?? "Unknown error")") + + } + + + + } + + + + print("====== after Token onPenNavSuccess =========") + + } + + + + } + + + + + + + + private func handleNavigation(clinicID: String, token: String, completion: @escaping (Bool, String?) -> Void) { + + DispatchQueue.main.async { + + PenNavUIManager.shared.setToken(token: token) + + PenNavUIManager.shared.navigate(to: clinicID) + + completion(true,nil) + + } + + } + + + + + + + + + + /** + + * Called when there is an initialization error with the Penguin UI. + + * + + * @param errorType The type of initialization error. + + * @param errorDescription A description of the error. + + */ + + func onPenNavInitializationError(errorType: PenNavUI.PenNavUIError, errorDescription: String) { + + // Handle initialization errors if needed + + print("onPenNavInitializationErrorType: \(errorType.rawValue)") + + print("onPenNavInitializationError: \(errorDescription)") + } +} diff --git a/ios/Runner/Penguin/PenguinViewFactory.swift b/ios/Runner/Penguin/PenguinViewFactory.swift new file mode 100644 index 00000000..a88bb5d0 --- /dev/null +++ b/ios/Runner/Penguin/PenguinViewFactory.swift @@ -0,0 +1,59 @@ +// +// BlueGpsViewFactory.swift +// Runner +// +// Created by Penguin . +// + +import Foundation +import Flutter + +/** + * A factory class for creating instances of [PenguinView]. + * This class implements `FlutterPlatformViewFactory` to create and manage native views. + */ +class PenguinViewFactory: NSObject, FlutterPlatformViewFactory { + + // The binary messenger used for communication with the Flutter engine + private var messenger: FlutterBinaryMessenger + + /** + * Initializes the PenguinViewFactory with the given messenger. + * + * @param messenger The [FlutterBinaryMessenger] used to communicate with Dart code. + */ + init(messenger: FlutterBinaryMessenger) { + self.messenger = messenger + super.init() + } + + /** + * Creates a new instance of [PenguinView]. + * + * @param frame The frame of the view, specifying its size and position. + * @param viewId A unique identifier for this view instance. + * @param args Optional arguments provided for creating the view. + * @return An instance of [PenguinView] configured with the provided parameters. + */ + func create( + withFrame frame: CGRect, + viewIdentifier viewId: Int64, + arguments args: Any? + ) -> FlutterPlatformView { + return PenguinView( + frame: frame, + viewIdentifier: viewId, + arguments: args, + binaryMessenger: messenger) + } + + /** + * Returns the codec used for encoding and decoding method channel arguments. + * This method is required when `arguments` in `create` is not `nil`. + * + * @return A [FlutterMessageCodec] instance used for serialization. + */ + public func createArgsCodec() -> FlutterMessageCodec & NSObjectProtocol { + return FlutterStandardMessageCodec.sharedInstance() + } +} diff --git a/ios/Runner/Runner.entitlements b/ios/Runner/Runner.entitlements index be2e0283..244f5e17 100644 --- a/ios/Runner/Runner.entitlements +++ b/ios/Runner/Runner.entitlements @@ -2,13 +2,38 @@ - - aps-environment development + com.apple.developer.associated-domains + + applinks:www.hmg.com + webcredentials:example.com + + com.apple.developer.healthkit + + com.apple.developer.healthkit.access + + com.apple.developer.in-app-payments + + merchant.com.hmgwebsersives + merchant.com.hmgwebservices.uat + merchant.com.hmgwebservices + com.apple.developer.networking.HotspotConfiguration com.apple.developer.networking.wifi-info + com.apple.developer.nfc.readersession.formats + + TAG + + com.apple.developer.pass-type-identifiers + + $(TeamIdentifierPrefix)* + + com.apple.developer.associated-domains + + applinks:hmg.com + diff --git a/lib/Constants.dart b/lib/Constants.dart index 5b8fd9da..3cb69afd 100644 --- a/lib/Constants.dart +++ b/lib/Constants.dart @@ -1,3 +1,5 @@ import 'package:flutter/material.dart'; -final Color secondaryColor = Colors.red[800]; \ No newline at end of file +final Color? secondaryColor = Colors.red[800]; + +final Color? dividerColor = Colors.grey[600]; \ No newline at end of file diff --git a/lib/analytics/analytic-events.dart b/lib/analytics/analytic-events.dart new file mode 100644 index 00000000..8f524173 --- /dev/null +++ b/lib/analytics/analytic-events.dart @@ -0,0 +1,72 @@ +import 'package:diplomaticquarterapp/uitl/utils.dart'; + +class _Event { + String? name; + String? description; + bool? active; + _Event(dynamic map) { + if (map != null) { + name = map['name']; + description = map['description']; + active = map['active']; + } + } + + flutterName() => 'f: $name'; +} + +class AnalyticEvents { + static _Event get(String key) { + var e = _Event(mapping[key]); + if (e == null) { + var label = labelFrom( + className: + key); // Convert Class Name in to Label (HomeCare -> Home Care) + e = _Event({"name": label, "active": true, "description": key}); + } + return e; + } + + static var mapping = const { + "HomeHealthCarePage": { + "active": true, + "name": "Home Health Care Page", + "description": "", + }, + "SplashScreen": { + "active": true, + "name": "Splash Screen", + "description": "", + }, + "LandingPage": { + "active": true, + "name": "Landing Page", + "description": "", + }, + "WelcomeLogin": { + "active": true, + "name": "Welcome Login", + "description": "", + }, + "LoginType": { + "active": true, + "name": "Login Type", + "description": "", + }, + "Login": { + "active": true, + "name": "Login", + "description": "", + }, + "ForgotPassword": { + "active": true, + "name": "Forgot Password", + "description": "", + }, + "": { + "active": true, + "name": "", + "description": "", + }, + }; +} diff --git a/lib/analytics/flows/advance_payments.dart b/lib/analytics/flows/advance_payments.dart new file mode 100644 index 00000000..5d946766 --- /dev/null +++ b/lib/analytics/flows/advance_payments.dart @@ -0,0 +1,92 @@ +import 'package:flutter/cupertino.dart'; + +import '../google-analytics.dart'; + +class AdvancePayments{ + + final GALogger logger; + AdvancePayments(this.logger); + + // R038 + payment_services({required String service_type}){ + logger('payment_services', parameters: { + 'service_type' : service_type + }); + } + + // R039 + wallet_recharge({required String service_type}){ + logger('wallet_recharge', parameters: { + 'service_type' : service_type + }); + } + + // R040 + wallet_payment_details(){ + logger('wallet_payment_details'); + } + + // R041 + payment_method({required String method,type}){ + logger('payment_method', parameters: { + 'payment_method' : method, + 'payment_type' : type + }); + } + + // R042 + payment_confirm({required String method,type}){ + logger('payment_confirm', parameters: { + 'payment_method' : method, + 'payment_type' : type + }); + } + + // R043 + payment_otp_confirmation({required String method,type}){ + logger('payment_otp_confirmation', parameters: { + 'payment_method' : method, + 'payment_type' : type + }); + } + + // R044 + payment_confirm_card_details({required String method,type}){ + logger('payment_confirm_card_details', parameters: { + 'payment_method' : method, + 'payment_type' : type + }); + } + + // R045 + payment_pay({required String method,type}){ + logger('payment_pay', parameters: { + 'payment_method' : method, + 'payment_type' : type + }); + } + + // R046 + payment_success({required String hospital, payment_method, payment_type, txn_number, txn_amount, txn_currency}){ + logger('payment_success', parameters: { + 'payment_method' : payment_method, + 'payment_type' : payment_type, + 'hospital_name' : hospital, + 'transaction_number' : txn_number, + 'transaction_amount' : txn_amount, + 'transaction_currency' : txn_currency + }); + } + + payment_fail({required String hospital, payment_method, payment_type, txn_amount, txn_currency, error_type}){ + logger('payment_fail', parameters: { + 'payment_method' : payment_method, + 'payment_type' : payment_type, + 'hospital_name' : hospital, + 'transaction_amount' : txn_amount, + 'transaction_currency' : txn_currency, + 'error_type' : error_type + }); + } + +} \ No newline at end of file diff --git a/lib/analytics/flows/app_nav.dart b/lib/analytics/flows/app_nav.dart new file mode 100644 index 00000000..cc1d8f98 --- /dev/null +++ b/lib/analytics/flows/app_nav.dart @@ -0,0 +1,30 @@ +import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; + +class AppNav{ + final name = 'app_nav'; + final GALogger logger; + AppNav(this.logger); + + logNavName(String value){ + logger(name, parameters: { + 'nav_name' : value + }); + } + + log({int? tabIndex, bool? isLoggedIn}){ + var nav_name = ""; + if(tabIndex == 1) + nav_name = "medical file"; + if(tabIndex == 3) + nav_name = "my family"; + if(tabIndex == 4) + nav_name = "todo list"; + if(tabIndex == 5) + nav_name = "help"; + + if(nav_name.isNotEmpty) + logger(name, parameters: { + 'nav_name' : nav_name + }); + } +} \ No newline at end of file diff --git a/lib/analytics/flows/appointments.dart b/lib/analytics/flows/appointments.dart new file mode 100644 index 00000000..594c9179 --- /dev/null +++ b/lib/analytics/flows/appointments.dart @@ -0,0 +1,273 @@ +import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; +import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DentalChiefComplaintsModel.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; +import 'package:diplomaticquarterapp/models/Clinics/ClinicListResponse.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; + +import '../google-analytics.dart'; + +class Appointment { + final GALogger logger; + + Appointment(this.logger); + + // R015 + book_appointment() { + logger('book_appointment'); + } + + // R016.1, R017.2 + book_appointment_by_clinic() { + logger('book_appointment_by_clinic'); + } + + // R016.2, R018.2 + book_appointment_by_doctor() { + logger('book_appointment_by_doctor'); + } + + // R017.1 + book_appointment_doctor_search({required String query}) { + // doctor_search_query : value + logger('book_appointment_doctor_search', parameters: {'doctor_search_query': query}); + } + + // R018.1 + book_appointment_select_clinic({required String appointment_type, clinic}) { + // appointment_type: regular | livecare + // clinic_type : $clinic_type + logger('book_appointment_select_clinic', parameters: {'appointment_type': appointment_type, 'clinic_type': clinic}); + } + + // R019.1 + book_appointment_livecare_accept() { + logger('book_appointment_livecare_accept'); + } + + // R019.2 + book_appointment_livecare_decline() { + logger('book_appointment_livecare_decline'); + } + + // R020 + book_appointment_chief_complaints({ + required String appointment_type, + ListClinicCentralized? clinic, + HospitalsModel? hospital, + ListDentalChiefComplain? treatment, + }) { + GAnalytics.TREATMENT_TYPE = treatment!.name; + logger('book_appointment_chief_complaints', parameters: { + 'appointment_type': appointment_type, + 'clinic_type': clinic!.clinicDescription, + 'hospital_name':hospital!=null ? hospital!.name :"", + 'treatment_type': treatment.name, + }); + } + + // R021 + book_appointment_select_doctor({required String appointment_type, required DoctorList doctor}) { + // appointment_type, clinic_type, hospital_name, treatment_type, doctor_name, doctor_nationality, doctor_gender + logger('book_appointment_select_doctor', parameters: { + 'appointment_type': appointment_type, + 'clinic_type': doctor.clinicName, + 'hospital_name': doctor.projectName, + 'treatment_type': GAnalytics.TREATMENT_TYPE ?? '', + 'doctor_name': doctor.name, + 'doctor_nationality': doctor.nationalityName, + 'doctor_gender': doctor.genderDescription, + }); + } + + // R022 + book_appointment_schedule({required String appointment_type, required DoctorList doctor}) { + // appointment_type, clinic_type, hospital_name, treatment_type, doctor_name, doctor_nationality, doctor_gender + logger('book_appointment_schedule', parameters: { + 'appointment_type': appointment_type, + 'clinic_type': doctor.clinicName, + 'hospital_name': doctor.projectName, + 'treatment_type': GAnalytics.TREATMENT_TYPE ?? '', + 'doctor_name': doctor.name, + 'doctor_nationality': doctor.nationalityName, + 'doctor_gender': doctor.genderDescription, + }); + } + + // R023 + book_appointment_date_selection({required String appointment_type, required day, required DoctorList doctor}) { + logger('book_appointment_date_selection', parameters: { + 'appointment_type': appointment_type, + 'clinic_type': doctor.clinicName, + 'hospital_name': doctor.projectName, + 'treatment_type': GAnalytics.TREATMENT_TYPE ?? '', + 'doctor_name': doctor.name, + 'doctor_nationality': doctor.nationalityName, + 'doctor_gender': doctor.genderDescription, + 'appointment_day': day + }); + } + + // R024.1 + book_appointment_time_selection({required String appointment_type, required DateTime? dateTime, required DoctorList doctor}) { + final day = DateUtil.getWeekDay(dateTime!.weekday); + final hour = DateFormat('HH').format(dateTime); + logger('book_appointment_time_selection', parameters: { + 'appointment_type': appointment_type, + 'clinic_type': doctor.clinicName, + 'hospital_name': doctor.projectName, + 'treatment_type': GAnalytics.TREATMENT_TYPE ?? '', + 'doctor_name': doctor.name, + 'doctor_nationality': doctor.nationalityName, + 'doctor_gender': doctor.genderDescription, + 'appointment_day': day, + 'appointment_hour': hour + }); + } + + // R024.2 + book_appointment_review({required String appointment_type, required DateTime dateTime, required DoctorList doctor}) { + final day = DateUtil.getWeekDay(dateTime.weekday); + final hour = DateFormat('HH').format(dateTime); + logger('book_appointment_review', parameters: { + 'appointment_type': appointment_type, + 'clinic_type': doctor.clinicName, + 'hospital_name': doctor.projectName, + 'treatment_type': GAnalytics.TREATMENT_TYPE ?? '', + 'doctor_name': doctor.name, + 'doctor_nationality': doctor.nationalityName, + 'doctor_gender': doctor.genderDescription, + 'appointment_day': day, + 'appointment_hour': hour + }); + } + + // R025 + book_appointment_click_confirm({required String appointment_type, required DateTime dateTime, required DoctorList doctor}) { + final day = DateUtil.getWeekDay(dateTime.weekday); + final hour = DateFormat('HH').format(dateTime); + logger('book_appointment_click_confirm', parameters: { + 'appointment_type': appointment_type, + 'clinic_type': doctor.clinicName, + 'hospital_name': doctor.projectName, + 'treatment_type': GAnalytics.TREATMENT_TYPE ?? '', + 'doctor_name': doctor.name, + 'doctor_nationality': doctor.nationalityName, + 'doctor_gender': doctor.genderDescription, + 'appointment_day': day, + 'appointment_hour': hour // '5-6' + }); + } + + // R026 + book_appointment_confirmation_success({required String appointment_type, required DateTime dateTime, required DoctorList doctor}) { + final day = DateUtil.getWeekDay(dateTime.weekday); + final hour = DateFormat('HH').format(dateTime); + logger('book_appointment_confirmation_success', parameters: { + 'appointment_type': appointment_type, + 'clinic_type': doctor.clinicName, + 'hospital_name': doctor.projectName, + 'treatment_type': GAnalytics.TREATMENT_TYPE ?? '', + 'doctor_name': doctor.name, + 'doctor_nationality': doctor.nationalityName, + 'doctor_gender': doctor.genderDescription, + 'appointment_day': day, + 'appointment_hour': hour + }); + } + + // R049.1 // should be for appointment flow + appointment_actions(AppoitmentAllHistoryResultList appointment, String action) { + logger('appointment_actions', parameters: { + 'action_type': action, + 'flow_type': GAnalytics.APPOINTMENT_DETAIL_FLOW_TYPE, + 'appointment_type': appointment.appointmentType, + 'clinic_type_online': appointment.clinicName, + 'hospital_name': appointment.projectName, + 'doctor_name': (appointment.doctorName == null || appointment.doctorName == '') ? appointment.doctorNameObj : appointment.doctorName, + 'payment_type': 'appointment', + }); + } + + // R027 + appointment_reminder(bool value) { + logger('appointment_reminder', parameters: {'reminder': value ? 'yes' : 'no'}); + } + + // R028 + appointment_reminder_time({required String reminde_before}) { + logger('appointment_reminder_time', parameters: {'reminder_before': reminde_before}); + } + + // R053 + // Note : - Payment flow beyond this step are same as listed under ‘Advance Payment’ section of this document + pay_now_for_appointment({required String appointment_type, required DoctorList doctorDetail, bool payNow = true}) { + logger('pay_now_for_appointment', parameters: { + 'appointment_type': appointment_type, + 'clinic_type': doctorDetail.clinicName, + 'hospital_name': doctorDetail.projectName, + 'doctor_name': doctorDetail.name, + 'payment_type': 'appointment' + }); + } + + // R033 + payment_method({required String appointment_type, clinic, payment_method, payment_type}) { + logger('payment_method', parameters: {'appointment_type': appointment_type, 'clinic_type': clinic, 'payment_method': payment_method, 'payment_type': payment_type}); + } + + // R036 + payment_success({required String appointment_type, clinic, hospital, payment_method, payment_type, txn_number, txn_amount, txn_currency}) { + logger('payment_success', parameters: { + 'appointment_type': appointment_type, + 'payment_method': payment_method, + 'payment_type': payment_type, + 'hospital_name': hospital, + 'clinic_type_online': clinic, + 'transaction_number': txn_number, + 'transaction_amount': txn_amount, + 'transaction_currency': txn_currency, + }); + } + + payment_fail({required String appointment_type, clinic, hospital, payment_method, payment_type, txn_amount, txn_currency, error_type}) { + logger('payment_fail', parameters: { + 'appointment_type': appointment_type, + 'payment_method': payment_method, + 'payment_type': payment_type, + 'hospital_name': hospital, + 'clinic_type_online': clinic, + 'transaction_amount': txn_amount, + 'transaction_currency': txn_currency, + 'error_type': error_type + }); + } + + // Note : - Payment flow beyond this step are same as listed under ‘Advance Payment’ section of this document + appointment_detail_action({required AppoitmentAllHistoryResultList appointment, required String action}) { + logger('appointment_detail_action', parameters: { + 'action_type': action, + 'flow_type': GAnalytics.APPOINTMENT_DETAIL_FLOW_TYPE, + }); + } + + // Note : - Payment flow beyond this step are same as listed under ‘Advance Payment’ section of this document + appointment_details_confirm({required AppoitmentAllHistoryResultList appointment}) { + logger('appointment_details_confirm', parameters: {}); + } + + // R053 + // Note : - Payment flow beyond this step are same as listed under ‘Advance Payment’ section of this document + appointment_details_cancel({required AppoitmentAllHistoryResultList appointment, appointment_type}) { + logger('cancel_appointment', parameters: { + 'flow_type': GAnalytics.APPOINTMENT_DETAIL_FLOW_TYPE, + 'appointment_type': appointment_type, + 'clinic_type_online': appointment.clinicName, + 'hospital_name': appointment.projectName, + 'doctor_name': (appointment.doctorName == null || appointment.doctorName == '') ? appointment.doctorNameObj : appointment.doctorName + }); + } +} diff --git a/lib/analytics/flows/error_tracking.dart b/lib/analytics/flows/error_tracking.dart new file mode 100644 index 00000000..17258b39 --- /dev/null +++ b/lib/analytics/flows/error_tracking.dart @@ -0,0 +1,15 @@ +import '../google-analytics.dart'; + +class ErrorTracking{ + + final GALogger logger; + ErrorTracking(this.logger); + + log(String type, {String? error}){ + logger('errors', parameters: { + 'error_type' : type ?? 'unknown', + 'error' : error ?? 'unknown', + }); + } + +} \ No newline at end of file diff --git a/lib/analytics/flows/hamburger_menu.dart b/lib/analytics/flows/hamburger_menu.dart new file mode 100644 index 00000000..404cdbcf --- /dev/null +++ b/lib/analytics/flows/hamburger_menu.dart @@ -0,0 +1,15 @@ +import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; + +class HamburgerMenu{ + final hamburger_menu = 'hamburger_menu'; + + final GALogger logger; + HamburgerMenu(this.logger); + + logMenuItemClick(String value){ + logger(hamburger_menu, parameters: { + 'menu_item' : value + }); + } + +} \ No newline at end of file diff --git a/lib/analytics/flows/hmg_services.dart b/lib/analytics/flows/hmg_services.dart new file mode 100644 index 00000000..cd771c1f --- /dev/null +++ b/lib/analytics/flows/hmg_services.dart @@ -0,0 +1,18 @@ +import '../google-analytics.dart'; + +class HMGServices{ + final hmg_services = 'hmg_services'; + + final GALogger logger; + HMGServices(this.logger); + logServiceName(String value){ + logger('hmg_services', parameters: { + 'services_name' : value + }); + } + viewAll(){ + logger('hmg_services', parameters: { + 'services_name' : 'view all services' + }); + } +} \ No newline at end of file diff --git a/lib/analytics/flows/live_care.dart b/lib/analytics/flows/live_care.dart new file mode 100644 index 00000000..ca496e53 --- /dev/null +++ b/lib/analytics/flows/live_care.dart @@ -0,0 +1,103 @@ +import 'package:flutter/cupertino.dart'; + +import '../google-analytics.dart'; + +class LiveCare{ + + final GALogger logger; + LiveCare(this.logger); + + // R030.1 + livecare_immediate_consultation(){ + logger('livecare_immediate_consultation'); + } + + // R030.2 + livecare_schedule_video_call(){ + logger('livecare_schedule_video_call'); + } + + // R031.1 + livecare_clinic_schedule({required String clinic}){ + logger('livecare_clinic_schedule', parameters: { + 'clinic_type_online' : clinic + }); + } + + // R031.2 + livecare_immediate_consultation_clinic({required String clinic}){ + logger('livecare_immediate_consultation_clinic', parameters: { + 'clinic_type_online' : clinic + }); + } + + // R031.2 + livecare_schedule_video_call_clinic({required String clinic}){ + logger('livecare_schedule_video_call_clinic', parameters: { + 'clinic_type_online' : clinic + }); + } + + // R032 + livecare_immediate_consultation_TnC({required String clinic}){ + logger('livecare_immediate_consultation_tandc', parameters: { + 'clinic_type_online' : clinic + }); + } + + // R033 + payment_method({required String appointment_type, clinic, payment_method, payment_type}){ + logger('payment_method', parameters: { + 'appointment_type' : appointment_type, + 'clinic_type_online' : clinic, + 'payment_method' : payment_method, + 'payment_type' : payment_type + }); + } + + // R034 + payment_confirm({required String appointment_type, clinic, payment_method, payment_type}){ + logger('payment_confirm', parameters: { + 'appointment_type' : appointment_type, + 'clinic_type_online' : clinic, + 'payment_method' : payment_method, + 'payment_type' : payment_type + }); + } + + // R035 + payment_pay({required String appointment_type, clinic, hospital, payment_method, payment_type}){ + // logger('payment_pay', parameters: { + // 'appointment_type' : appointment_type, + // 'clinic_type_online' : clinic, + // 'payment_method' : payment_method, + // 'payment_type' : payment_type, + // 'hospital_name' : hospital + // }); + } + + // R036 + payment_success({required String appointment_type, clinic, hospital, payment_method, payment_type, txn_number, txn_amount, txn_currency}){ + // appointment_type + // clinic_type_online + // payment_method + // payment_type + // hospital_name + // transaction_number + // transaction_amount + // transaction_currency + } + + // R037 + livecare_immediate_consultation_payment_failed({required String appointment_type, clinic, payment_method, payment_type, txn_amount, txn_currency, error_message}){ + logger('livecare_immediate_consult_payment_fail', parameters: { + 'payment_method' : payment_method, + 'appointment_type' : appointment_type, + 'payment_type' : payment_type, + 'clinic_type_online' : clinic, + 'transaction_amount' : txn_amount, + 'transaction_currency' : txn_currency, + 'error_type' : error_message + }); + } +} \ No newline at end of file diff --git a/lib/analytics/flows/login_registration.dart b/lib/analytics/flows/login_registration.dart new file mode 100644 index 00000000..eb02d253 --- /dev/null +++ b/lib/analytics/flows/login_registration.dart @@ -0,0 +1,157 @@ +import 'package:flutter/cupertino.dart'; + +import '../google-analytics.dart'; + +class LoginRegistration{ + static int loginMethod = 0; + static int verificationMethod = 0; + + final GALogger logger; + LoginRegistration(this.logger); + // R004.1 + login_register_initiate(){ + logger('login_register_initiate'); + } + + // R005.1 + visited_alhabib_group(bool value){ + // selection_type: yes/no + logger('visited_alhabib_group', parameters: { + 'selection_type' : value ? 'yes' : 'no' + }); + } + + // R006.1, R007.1, R008.1, R009.1 + registration_cancel({required String step}){ + // registration_step : enter details + // registration_step : personal info + // registration_step : patient info + // fourth (verification) + logger('registration_cancel', parameters: { + 'registration_step' : step + }); + } + + // R006.2 + registration_enter_details(){ + logger('registration_enter_details'); + } + + // R007.2 + registration_personal_info(){ + logger('registration_personal_info'); + } + + // R008.2 + registration_patient_info(){ + logger('registration_patient_info'); + } + + // R009.2 + registration_verification_option(){ + logger('registration_verification_option'); + } + + // R010:registration_confirmation + registration_confirmation(){ + // verification_method: by + logger('registration_confirmation'); + } + + registration_fail({required String errorType}){ + // verification_method: by + logger('registration_fail', parameters: { + 'error_type' : errorType + }); + } + + // R011.1 + login_start({required String method}){ + logger('login_start', parameters: { + 'login_method' : method + }); + } + + // R011:login_verify_otp | R009:registration_verification_option + verify_otp_method({bool forRegistration = false}){ + if(forRegistration == false) + logger("login_verify_otp", parameters: { + 'login_method' : _getLoginMethod(), + 'verification_method' : _getVerificationMethod(), + }); + else + logger("registration_verification_option", parameters: { + 'verification_method' : _getVerificationMethod() + }); + } + + // R011:login_verify_otp | R009:registration_verification_option + login_verfication({bool forRegistration = false}){ + if(forRegistration == false) + logger("login_verfication", parameters: { + 'login_method' : _getLoginMethod(), + 'verification_method' : _getVerificationMethod(), + }); + else + logger("login_varification_register", parameters: { + 'login_method' : _getLoginMethod(), + 'verification_method' : _getVerificationMethod(), + }); + } + + // R011.2 + forget_file_number(){ + logger('forget_file_number'); + } + + // R011.3 + register_now(){ + logger('register_now'); + } + + // R012.1, R014.1 + login_successful(){ + logger('login_successful', parameters: { + 'login_method' : _getVerificationMethod() + }); + } + + // R012.4 + login_unsuccessful({required String method, error}){ + logger('login_unsuccessful', parameters: { + 'login_method' : method + }); + } + + login_fail({error}){ + logger('login_unsuccessful', parameters: { + 'login_method' : loginMethod, + 'error': error + }); + } + + // R013 + recover_file_number(){ + logger('recover_file_number'); + } + + // R014.2 + login_with_other_account(){ + logger('login_with_other_account'); + } + + + _getLoginMethod(){ + if(loginMethod == 1) return 'national id'; + if(loginMethod == 2) return 'file number'; + return 'otp'; + } + + String _getVerificationMethod(){ + if(verificationMethod == 1) return 'sms'; + if(verificationMethod == 2) return 'fingerprint'; + if(verificationMethod == 3) return 'face id'; + if(verificationMethod == 4) return 'whatsapp'; + return "unknown"; + } +} \ No newline at end of file diff --git a/lib/analytics/flows/offers_promotions.dart b/lib/analytics/flows/offers_promotions.dart new file mode 100644 index 00000000..17a6232c --- /dev/null +++ b/lib/analytics/flows/offers_promotions.dart @@ -0,0 +1,16 @@ +import '../google-analytics.dart'; + +class OfferAndPromotion{ + + final GALogger logger; + OfferAndPromotion(this.logger); + + final offers_and_promotion = 'offers_&_promotion'; + + log(){ + logger('offers_and_promotion', parameters: { + 'promotion_name' : "offer" + }); + } + +} \ No newline at end of file diff --git a/lib/analytics/flows/todo_list.dart b/lib/analytics/flows/todo_list.dart new file mode 100644 index 00000000..a3ff21f2 --- /dev/null +++ b/lib/analytics/flows/todo_list.dart @@ -0,0 +1,111 @@ +import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; + +import '../google-analytics.dart'; + +class TodoList{ + + final GALogger logger; + TodoList(this.logger); + + // R047.1 + to_do_list_pay_now(AppoitmentAllHistoryResultList appointment){ + logger('to_do_list_pay_now', parameters: { + 'appointment_type' : appointment.isLiveCareAppointment! ? 'livecare' : 'regular', + 'clinic_type_online' : appointment.clinicName, + 'hospital_name' : appointment.projectName, + 'doctor_name' : (appointment.doctorName == null || appointment.doctorName == '') ? appointment.doctorNameObj : appointment.doctorName, + 'payment_type' : 'appointment', + }); + } + + // R047.2 + to_do_list_more_details(AppoitmentAllHistoryResultList appointment){ + logger('to_do_list_more_details', parameters: { + 'appointment_type' : appointment.isLiveCareAppointment! ? 'livecare' : 'regular', + 'clinic_type_online' : appointment.clinicName, + 'hospital_name' : appointment.projectName, + 'doctor_name' : (appointment.doctorName == null || appointment.doctorName == '') ? appointment.doctorNameObj : appointment.doctorName, + 'payment_type' : 'appointment', + }); + } + + // R048 + to_do_list_confirm_payment_details(AppoitmentAllHistoryResultList appointment){ + logger('to_do_list_confirm_payment_details', parameters: { + 'appointment_type' : appointment.isLiveCareAppointment! ? 'livecare' : 'regular', + 'clinic_type_online' : appointment.clinicName, + 'hospital_name' : appointment.projectName, + 'doctor_name' : (appointment.doctorName == null || appointment.doctorName == '') ? appointment.doctorNameObj : appointment.doctorName, + 'payment_type' : 'appointment', + }); + } + + // R048 + to_do_list_cancel_payment_details(AppoitmentAllHistoryResultList appointment){ + logger('to_do_list_cancel_payment_details', parameters: { + 'appointment_type' : appointment.isLiveCareAppointment! ? 'livecare' : 'regular', + 'clinic_type_online' : appointment.clinicName, + 'hospital_name' : appointment.projectName, + 'doctor_name' : (appointment.doctorName == null || appointment.doctorName == '') ? appointment.doctorNameObj : appointment.doctorName, + 'payment_type' : 'appointment', + }); + } + + + + // R049.2 + to_do_list_cancel_appointment(AppoitmentAllHistoryResultList appointment){ + logger('to_do_list_cancel_appointment', parameters: { + 'appointment_type' : appointment.isLiveCareAppointment! ? 'livecare' : 'regular', + 'clinic_type_online' : appointment.clinicName, + 'hospital_name' : appointment.projectName, + 'doctor_name' : (appointment.doctorName == null || appointment.doctorName == '') ? appointment.doctorNameObj : appointment.doctorName, + 'payment_type' : 'appointment', + }); + } + + // R049.3 + to_do_list_confirm_appointment(AppoitmentAllHistoryResultList appointment){ + logger('confirm_appointment', parameters: { + 'appointment_type' : appointment.isLiveCareAppointment! ? 'livecare' : 'regular', + 'flow_type' : 'todo list', + 'clinic_type_online' : appointment.clinicName, + 'hospital_name' : appointment.projectName, + 'doctor_name' : (appointment.doctorName == null || appointment.doctorName == '') ? appointment.doctorNameObj : appointment.doctorName, + 'payment_type' : 'appointment', + }); + } + + // R050 + to_do_list_check_in(AppoitmentAllHistoryResultList appointment){ + logger('to_do_list_check_in', parameters: { + 'appointment_type' : appointment.isLiveCareAppointment! ? 'livecare' : 'regular', + 'clinic_type_online' : appointment.clinicName, + 'hospital_name' : appointment.projectName, + 'doctor_name' : (appointment.doctorName == null || appointment.doctorName == '') ? appointment.doctorNameObj : appointment.doctorName, + 'payment_type' : 'appointment', + }); + } + + // R051 + to_do_list_nfc(AppoitmentAllHistoryResultList appointment){ + logger('to_do_list_nfc', parameters: { + 'appointment_type' : appointment.isLiveCareAppointment! ? 'livecare' : 'regular', + 'clinic_type_online' : appointment.clinicName, + 'hospital_name' : appointment.projectName, + 'doctor_name' : (appointment.doctorName == null || appointment.doctorName == '') ? appointment.doctorNameObj : appointment.doctorName, + 'payment_type' : 'appointment', + }); + } + + // R052 + to_do_list_nfc_cancel(AppoitmentAllHistoryResultList appointment){ + logger('to_do_list_nfc_cancel', parameters: { + 'appointment_type' : appointment.isLiveCareAppointment != null ? appointment.isLiveCareAppointment! ? 'livecare' : 'regular' : 'regular', + 'clinic_type_online' : appointment.clinicName, + 'hospital_name' : appointment.projectName, + 'doctor_name' : (appointment.doctorName == null || appointment.doctorName == '') ? appointment.doctorNameObj : appointment.doctorName, + 'payment_type' : 'appointment', + }); + } +} \ No newline at end of file diff --git a/lib/analytics/google-analytics.dart b/lib/analytics/google-analytics.dart new file mode 100644 index 00000000..46ae7f80 --- /dev/null +++ b/lib/analytics/google-analytics.dart @@ -0,0 +1,145 @@ +import 'package:diplomaticquarterapp/analytics/analytic-events.dart'; +import 'package:diplomaticquarterapp/analytics/flows/advance_payments.dart'; +import 'package:diplomaticquarterapp/analytics/flows/appointments.dart'; +import 'package:diplomaticquarterapp/analytics/flows/error_tracking.dart'; +import 'package:diplomaticquarterapp/analytics/flows/hamburger_menu.dart'; +import 'package:diplomaticquarterapp/analytics/flows/live_care.dart'; +import 'package:diplomaticquarterapp/analytics/flows/login_registration.dart'; +import 'package:diplomaticquarterapp/analytics/flows/offers_promotions.dart'; +import 'package:diplomaticquarterapp/analytics/flows/todo_list.dart'; +import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; +import 'package:diplomaticquarterapp/routes.dart'; +import 'package:diplomaticquarterapp/services/permission/permission_service.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +import 'package:firebase_analytics/firebase_analytics.dart'; +import 'package:firebase_analytics/observer.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:geocoding/geocoding.dart'; +import 'package:geolocator/geolocator.dart'; + +import 'flows/app_nav.dart'; +import 'flows/hmg_services.dart'; + +typedef GALogger = Function(String name, {Map parameters}); + +var _analytics = FirebaseAnalytics.instance; + +_logger(String name, {Map? parameters}) async { + // return; + if (name != null && name.isNotEmpty) { + if (name.contains(' ')) name = name.replaceAll(' ', '_'); + + // To LowerCase + if (parameters != null && parameters.isNotEmpty) + parameters = parameters.map((key, value) { + final key_ = key.toLowerCase(); + var value_ = value; + if (value is String) value_ = value.toLowerCase(); + return MapEntry(key_, value_); + }); + + try { + _analytics.logEvent(name: name.trim().toLowerCase(), parameters: parameters).then((value) { + // debugPrint('SUCCESS: Google analytics event "$name" sent with parameters $parameters'); + }).catchError((error) { + // debugPrint('ERROR: Google analytics event "$name" sent failed'); + }); + } catch (e) { + print(e); + } + } +} + +class GAnalytics { + static String? TREATMENT_TYPE; + static String? APPOINTMENT_DETAIL_FLOW_TYPE; + static String? PAYMENT_TYPE; + + setUser(AuthenticatedUser user) async { + try { + _analytics.setUserProperty(name: 'user_language', value: user.preferredLanguage == '1' ? 'arabic' : 'english'); + _analytics.setUserProperty(name: 'userid', value: Utils.generateMd5Hash(user.emailAddress!)); + _analytics.setUserProperty(name: 'login_status', value: user == null ? 'guest' : 'loggedin'); + if (await PermissionService.isLocationEnabled()) { + final location = await Geolocator.getCurrentPosition(); + if (location != null && !location.isMocked) { + final places = await placemarkFromCoordinates(location.latitude, location.longitude,); + final countryCode = places.first.isoCountryCode; + _analytics.setUserProperty(name: 'user_country', value: countryCode); + } + } else { + _analytics.setUserProperty(name: 'user_country', value: "N/A"); + } + } catch (e) {} + } + + NavObserver navObserver() => NavObserver(); + final hamburgerMenu = HamburgerMenu(_logger); + final bottomTabNavigation = AppNav(_logger); + final hmgServices = HMGServices(_logger); + final loginRegistration = LoginRegistration(_logger); + final appointment = Appointment(_logger); + final liveCare = LiveCare(_logger); + final todoList = TodoList(_logger); + final advancePayments = AdvancePayments(_logger); + final offerPackages = OfferAndPromotion(_logger); + final errorTracking = ErrorTracking(_logger); +} + +// adb shell setprop debug.firebase.analytics.app com.ejada.hmg -> Android +class NavObserver extends RouteObserver> { + _sendScreenView(PageRoute route) async { + log(String className) { + var event = AnalyticEvents.get(className); + if (event.active != null) { + _analytics.setCurrentScreen(screenName: event.flutterName(), screenClassOverride: className).catchError( + (Object error) { + print('$FirebaseAnalyticsObserver: $error'); + }, + test: (Object error) { + return error is PlatformException; + }, + ); + } + } + + if (route.settings.name != null && route.settings.name!.isNotEmpty && route.settings.name != "null") { + var class_ = routes[route.settings.name]!(0); + if (class_ != null) log(class_.toStringShort()); + } else if (route is FadePage) { + var class_ = route.page; + if (class_ != null) log(class_.toStringShort()); + } else if (route is MaterialPageRoute) { + var class_ = route.builder(route.subtreeContext!); + if (class_ != null) log(class_.toStringShort()); + } else { + print(""); + } + } + + @override + void didPush(Route route, Route? previousRoute) { + super.didPush(route, previousRoute); + if (route is PageRoute) { + _sendScreenView(route); + } + } + + @override + void didReplace({Route? newRoute, Route? oldRoute}) { + super.didReplace(newRoute: newRoute, oldRoute: oldRoute); + if (newRoute is PageRoute) { + _sendScreenView(newRoute); + } + } + + @override + void didPop(Route route, Route? previousRoute) { + super.didPop(route, previousRoute); + // if (previousRoute is PageRoute && route is PageRoute) { + // _sendScreenView(previousRoute); + // } + } +} diff --git a/lib/app_state/app_state.dart b/lib/app_state/app_state.dart new file mode 100644 index 00000000..0fd54e74 --- /dev/null +++ b/lib/app_state/app_state.dart @@ -0,0 +1,13 @@ +class AppState { + static final AppState _instance = AppState._internal(); + + AppState._internal(); + + factory AppState() => _instance; + + bool isLogged = false; + + set setLogged(v) => isLogged = v; + + bool get getIsLogged => isLogged; +} diff --git a/lib/config/config.dart b/lib/config/config.dart index 1ea16a37..8d75daae 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -1,596 +1,720 @@ import 'dart:io'; +import 'package:amazon_payfort/amazon_payfort.dart'; import 'package:diplomaticquarterapp/models/Request.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; -const MAX_SMALL_SCREEN = 660; +var MAX_SMALL_SCREEN = 660; +final OPENTOK_API_KEY = '46209962'; +// final OPENTOK_API_KEY = '47464241'; // PACKAGES and OFFERS -const EXA_CART_API_BASE_URL = 'http://10.200.101.75:9000'; -const PACKAGES_CATEGORIES = '/api/categories'; -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/'; +var EXA_CART_API_BASE_URL = 'https://mdlaboratories.com/offersdiscounts'; +// var EXA_CART_API_BASE_URL = 'http://10.200.101.75:9000'; +var PACKAGES_CATEGORIES = '/api/categories'; +var PACKAGES_STORES = '/api/stores'; +var PACKAGES_TOKEN = '/api/token'; +var PACKAGES_PRODUCTS = '/api/products'; +var PACKAGES_CUSTOMER = '/api/customers'; +var PACKAGES_SHOPPING_CART = '/api/shopping_cart_items'; +var PACKAGES_ORDERS = '/api/orders'; +var PACKAGES_ORDER_HISTORY = '/api/orders/items'; +var PACKAGES_TAMARA_OPT = '/api/orders/paymentoptions/tamara'; + // var BASE_URL = 'http://10.50.100.198:2018/'; + // var BASE_URL = 'https://uat.hmgwebservices.com/'; +var BASE_URL = 'https://hmgwebservices.com/'; +// var BASE_URL = 'http://10.201.204.103/'; +// var BASE_URL = 'https://orash.cloudsolutions.com.sa/'; +// var BASE_URL = 'https://vidauat.cloudsolutions.com.sa/'; +// var BASE_URL = 'https://vidamergeuat.cloudsolutions.com.sa/'; + +// var BASE_URL = 'https://webservices.hmg.com/'; + +// var BASE_URL = 'http://10.50.100.198:4422/'; // Pharmacy UAT URLs -const BASE_PHARMACY_URL = 'https://uat.hmgwebservices.com/epharmacy/api/'; -const PHARMACY_BASE_URL = 'https://uat.hmgwebservices.com/epharmacy/api/'; +// var BASE_PHARMACY_URL = 'https://uat.hmgwebservices.com/epharmacy/api/'; +// var PHARMACY_BASE_URL = 'https://uat.hmgwebservices.com/epharmacy/api/'; + +// // Pharmacy Production URLs +var BASE_PHARMACY_URL = 'https://mdlaboratories.com/exacartapi/api/'; +var PHARMACY_BASE_URL = 'https://mdlaboratories.com/exacartapi/api/'; + +var PHARMACY_REDIRECT_URL = 'https://bit.ly/AlhabibPharmacy'; + +// Pharmacy VidaPlus URLs +// var BASE_PHARMACY_URL = 'https://mdlaboratories.com/exacartapitest/api/'; +// var PHARMACY_BASE_URL = 'https://mdlaboratories.com/exacartapitest/api/'; + +// // Pharmacy Pre-Production URLs +// var BASE_PHARMACY_URL = 'https://mdlaboratories.com/exacartapitest/api/'; +// var PHARMACY_BASE_URL = 'https://mdlaboratories.com/exacartapitest/api/'; + +// RC API URL +var RC_BASE_URL = 'https://rc.hmg.com/'; + +// var RC_BASE_URL = 'https://rc.hmg.com/test/'; -// Pharmacy Production URLs -// const BASE_PHARMACY_URL = 'https://mdlaboratories.com/exacartapi/api/'; -// const PHARMACY_BASE_URL = 'https://mdlaboratories.com/exacartapi/api/'; +// var RC_BASE_URL = 'https://ms.hmg.com/rc/'; -const PING_SERVICE = 'Services/Weather.svc/REST/CheckConnectivity'; +var PING_SERVICE = 'Services/Weather.svc/REST/CheckConnectivity'; -const GET_PROJECT = 'Services/Lists.svc/REST/GetProject'; +var GET_PROJECT = 'Services/Lists.svc/REST/GetProject'; ///Geofencing -const GET_GEO_ZONES = 'Services/Patients.svc/REST/GeoF_GetAllPoints'; -const LOG_GEO_ZONES = 'Services/Patients.svc/REST/GeoF_InsertPatientFileInfo'; +var GET_GEO_ZONES = 'Services/Patients.svc/REST/GeoF_GetAllPoints'; +var LOG_GEO_ZONES = 'Services/Patients.svc/REST/GeoF_InsertPatientFileInfo'; // Delivery Driver -const DRIVER_LOCATION = 'Services/Patients.svc/REST/PatientER_GetDriverLocation'; +var DRIVER_LOCATION = 'Services/Patients.svc/REST/PatientER_GetDriverLocation'; //weather -const WEATHER_INDICATOR = 'Services/Weather.svc/REST/GetCityInfo'; +var WEATHER_INDICATOR = 'Services/Weather.svc/REST/GetCityInfo'; -const GET_PRIVILEGE = 'Services/Patients.svc/REST/Service_Privilege'; +var GET_PRIVILEGE = 'Services/Patients.svc/REST/Service_Privilege'; // Wifi Credentials -const WIFI_CREDENTIALS = - "Services/Patients.svc/Hmg_SMS_Get_By_ProjectID_And_PatientID"; +var WIFI_CREDENTIALS = "Services/Patients.svc/Hmg_SMS_Get_By_ProjectID_And_PatientID"; ///Doctor -const GET_MY_DOCTOR = - 'Services/Doctors.svc/REST/GetPatientDoctorAppointmentResult'; -const GET_DOCTOR_PROFILE = 'Services/Doctors.svc/REST/GetDocProfiles'; -const GET_DOCTOR_RATING_NOTES = - 'Services/Doctors.svc/REST/dr_GetNotesDoctorRating'; -const GET_DOCTOR_RATING_DETAILS = - 'Services/Doctors.svc/REST/dr_GetDoctorRatingDetails'; -const GET_DOCTOR_RATING = 'Services/Doctors.svc/REST/dr_GetAvgDoctorRating'; +var GET_MY_DOCTOR = 'Services/Doctors.svc/REST/GetPatientDoctorAppointmentResult'; +var GET_DOCTOR_PROFILE = 'Services/Doctors.svc/REST/GetDocProfiles'; +var GET_DOCTOR_PRE_POST_IMAGES = 'Services/Doctors.svc/REST/GetDoctorPrePostImages'; +var GET_DOCTOR_RATING_NOTES = 'Services/Doctors.svc/REST/dr_GetNotesDoctorRating'; +var GET_DOCTOR_RATING_DETAILS = 'Services/Doctors.svc/REST/dr_GetDoctorRatingDetails'; + +var GET_DOCTOR_RATING = 'Services/Doctors.svc/REST/dr_GetAvgDoctorRating'; ///Prescriptions -const PRESCRIPTIONS = 'Services/Patients.svc/REST/GetPrescriptionApptList'; -const GET_PRESCRIPTIONS_ALL_ORDERS = - 'Services/Patients.svc/REST/PatientER_GetPatientAllPresOrders'; -const GET_PRESCRIPTION_REPORT = - 'Services/Patients.svc/REST/INP_GetPrescriptionReport'; -const SEND_PRESCRIPTION_EMAIL = - 'Services/Notifications.svc/REST/SendPrescriptionEmail'; -const GET_PRESCRIPTION_REPORT_ENH = - 'Services/Patients.svc/REST/GetPrescriptionReport_enh'; +// var PRESCRIPTIONS = 'Services/Patients.svc/REST/GetPrescriptionApptList'; +var PRESCRIPTIONS = 'Services/Patients.svc/REST/GetPrescriptionApptList_Async'; + +var GET_PRESCRIPTIONS_ALL_ORDERS = 'Services/Patients.svc/REST/PatientER_GetPatientAllPresOrders'; +var GET_PRESCRIPTION_REPORT = 'Services/Patients.svc/REST/INP_GetPrescriptionReport'; +var SEND_PRESCRIPTION_EMAIL = 'Services/Notifications.svc/REST/SendPrescriptionEmail'; +var GET_PRESCRIPTION_REPORT_ENH = 'Services/Patients.svc/REST/GetPrescriptionReport_enh'; ///Lab Order -const GET_Patient_LAB_ORDERS = 'Services/Patients.svc/REST/GetPatientLabOrders'; -const GET_Patient_LAB_SPECIAL_RESULT = - 'Services/Patients.svc/REST/GetPatientLabSpecialResults'; -const SEND_LAB_RESULT_EMAIL = - 'Services/Notifications.svc/REST/SendLabReportEmail'; -const GET_Patient_LAB_RESULT = - 'Services/Patients.svc/REST/GetPatientLabResults'; -const GET_Patient_LAB_ORDERS_RESULT = - 'Services/Patients.svc/REST/GetPatientLabOrdersResults'; +var GET_Patient_LAB_ORDERS = 'Services/Patients.svc/REST/GetPatientLabOrders'; +var GET_Patient_LAB_SPECIAL_RESULT = 'Services/Patients.svc/REST/GetPatientLabSpecialResults'; +var SEND_LAB_RESULT_EMAIL = 'Services/Notifications.svc/REST/SendLabReportEmail'; +var GET_Patient_LAB_RESULT = 'Services/Patients.svc/REST/GetPatientLabResults'; +var GET_Patient_LAB_ORDERS_RESULT = 'Services/Patients.svc/REST/GetPatientLabOrdersResults'; +var SEND_COVID_LAB_RESULT_EMAIL = 'Services/Notifications.svc/REST/GenerateCOVIDReport'; +var COVID_PASSPORT_UPDATE = 'Services/Patients.svc/REST/Covid19_Certificate_PassportUpdate'; +var GET_PATIENT_PASSPORT_NUMBER = 'Services/Patients.svc/REST/Covid19_Certificate_GetPassport'; +var SEND_LAB_RESULT_EMAIL_NEW = 'ReportsAPI/api/reports/labReport'; + +var UPDATE_WORKPLACE_NAME = 'Services/Patients.svc/REST/ActivateSickLeave_FromVida'; +var GET_SICKLEAVE_STATUS_ADMISSION_NO = 'Services/ChatBot_Service.svc/REST/GetSickLeaveStatusByAdmissionNo'; /// -const GET_PATIENT_ORDERS = 'Services/Patients.svc/REST/GetPatientRadOrders'; -const GET_PATIENT_LAB_ORDERS_BY_APPOINTMENT = - 'Services/Patients.svc/REST/GetPatientLabResultsByAppointmentNo'; +var GET_PATIENT_ORDERS = 'Services/Patients.svc/REST/GetPatientRadOrders'; +var GET_PATIENT_LAB_ORDERS_BY_APPOINTMENT = 'Services/Patients.svc/REST/GetPatientLabResultsByAppointmentNo'; -const GET_PATIENT_ORDERS_DETAILS = - 'Services/Patients.svc/REST/Rad_UpdatePatientRadOrdersToRead'; -const GET_RAD_IMAGE_URL = 'Services/Patients.svc/Rest/GetRadImageURL'; -const SEND_RAD_REPORT_EMAIL = - 'Services/Notifications.svc/REST/SendRadReportEmail'; +var GET_PATIENT_ORDERS_DETAILS = 'Services/Patients.svc/REST/Rad_UpdatePatientRadOrdersToRead'; +var GET_RAD_IMAGE_URL = 'Services/Patients.svc/Rest/GetRadImageURL'; +var SEND_RAD_REPORT_EMAIL = 'Services/Notifications.svc/REST/SendRadReportEmail'; ///Feedback -const SEND_FEEDBACK = 'Services/COCWS.svc/REST/InsertCOCItemInSPList'; -const GET_STATUS_FOR_COCO = 'Services/COCWS.svc/REST/GetStatusforCOC'; -const GET_PATIENT_AppointmentHistory = 'Services' - '/Doctors.svc/REST/PateintHasAppoimentHistory'; +var SEND_FEEDBACK = 'Services/COCWS.svc/REST/InsertCOCItemInSPList'; +var GET_STATUS_FOR_COCO = 'Services/COCWS.svc/REST/GetStatusforCOC'; +// var GET_PATIENT_AppointmentHistory = 'Services' +// '/Doctors.svc/REST/PateintHasAppoimentHistory'; + +var GET_PATIENT_AppointmentHistory = 'Services' + '/Doctors.svc/REST/PateintHasAppoimentHistory_Async'; ///VITAL SIGN -const GET_PATIENT_VITAL_SIGN = - 'Services/Doctors.svc/REST/Doctor_GetPatientVitalSign'; +var GET_PATIENT_VITAL_SIGN = 'Services/Doctors.svc/REST/Doctor_GetPatientVitalSign'; ///Er Nearest -const GET_NEAREST_HOSPITAL = - 'Services/Patients.svc/REST/Patient_GetProjectAvgERWaitingTime'; +var GET_NEAREST_HOSPITAL = 'Services/Patients.svc/REST/Patient_GetProjectAvgERWaitingTime'; ///ED Online -const ER_GET_VISUAL_TRIAGE_QUESTIONS = - "services/Doctors.svc/REST/ER_GetVisualTriageQuestions"; -const ER_SAVE_TRIAGE_INFORMATION = - "services/Doctors.svc/REST/ER_SaveTriageInformation"; -const ER_GetPatientPaymentInformationForERClinic = - "services/Doctors.svc/REST/ER_GetPatientPaymentInformationForERClinic"; +var ER_GET_VISUAL_TRIAGE_QUESTIONS = "services/Doctors.svc/REST/ER_GetVisualTriageQuestions"; +var ER_SAVE_TRIAGE_INFORMATION = "services/Doctors.svc/REST/ER_SaveTriageInformation"; +var ER_GetPatientPaymentInformationForERClinic = "services/Doctors.svc/REST/ER_GetPatientPaymentInformationForERClinic"; ///Er Nearest -const GET_AMBULANCE_REQUEST = - 'Services/Patients.svc/REST/PatientER_RRT_GetAllTransportationMethod'; -const GET_PATIENT_ALL_PRES_ORDERS = - 'Services/Patients.svc/REST/PatientER_GetPatientAllPresOrders'; -const GET_PICK_UP_REQUEST_BY_PRES_ORDER_ID = - 'Services/Patients.svc/REST/PatientER_RRT_GetPickUpRequestByPresOrderID'; -const UPDATE_PRESS_ORDER = - 'Services/Patients.svc/REST/PatientER_UpdatePresOrder'; -const INSERT_ER_INERT_PRES_ORDER = - 'Services/Patients.svc/REST/PatientER_InsertPresOrder'; +var GET_AMBULANCE_REQUEST = 'Services/Patients.svc/REST/PatientER_RRT_GetAllTransportationMethod'; +var GET_PATIENT_ALL_PRES_ORDERS = 'Services/Patients.svc/REST/PatientER_GetPatientAllPresOrders'; +var GET_PICK_UP_REQUEST_BY_PRES_ORDER_ID = 'Services/Patients.svc/REST/PatientER_RRT_GetPickUpRequestByPresOrderID'; +var UPDATE_PRESS_ORDER = 'Services/Patients.svc/REST/PatientER_UpdatePresOrder'; +var INSERT_ER_INERT_PRES_ORDER = 'Services/Patients.svc/REST/PatientER_InsertPresOrder'; + +/// ER RRT +var GET_ALL_RC_TRANSPORTATION = 'api/Transportation/getalltransportation'; +var GET_ALL_TRANSPORTATIONS_RC = 'api/Transportation/getalltransportation'; +var GET_ALL_RRT_QUESTIONS = 'Services/Patients.svc/REST/PatientER_RRT_GetAllQuestions'; +var GET_RRT_SERVICE_PRICE = 'Services/Patients.svc/REST/PatientE_RealRRT_GetServicePrice'; + +var GET_ALL_TRANSPORTATIONS_ORDERS = 'api/Transportation/get'; + +var CANCEL_AMBULANCE_REQUEST = "api/Transportation/update"; + +var INSERT_TRANSPORTATION_ORDER_RC = "api/Transportation/add"; ///FindUs -const GET_FINDUS_REQUEST = 'Services/Lists.svc/REST/Get_HMG_Locations'; +var GET_FINDUS_REQUEST = 'Services/Lists.svc/REST/Get_HMG_Locations'; ///LiveChat -const GET_LIVECHAT_REQUEST = 'Services/Patients.svc/REST/GetPatientICProjects'; +var GET_LIVECHAT_REQUEST = 'Services/Patients.svc/REST/GetPatientICProjects'; ///babyInformation -const GET_BABYINFORMATION_REQUEST = - 'Services/Community.svc/REST/GetBabyByUserID'; +var GET_BABYINFORMATION_REQUEST = 'Services/Community.svc/REST/GetBabyByUserID'; ///Get Baby By User ID -const GET_BABY_BY_USER_ID = 'Services/Community.svc/REST/GetBabyByUserID'; +var GET_BABY_BY_USER_ID = 'Services/Community.svc/REST/GetBabyByUserID'; ///userInformation -const GET_USERINFORMATION_REQUEST = - 'Services/Community.svc/REST/GetUserInformation_New'; +var GET_USERINFORMATION_REQUEST = 'Services/Community.svc/REST/GetUserInformation_New'; ///Update email -const UPDATE_PATENT_EMAIL = 'Services/Patients.svc/REST/UpdatePateintEmail'; -const UPDATE_PATENT_INFO = 'Services/Community.svc/REST/UpdateUserInfo_New'; +var UPDATE_PATENT_EMAIL = 'Services/Patients.svc/REST/UpdatePateintEmail'; +var UPDATE_PATENT_INFO = 'Services/Community.svc/REST/UpdateUserInfo_New'; ///addNewChild -const GET_NEWCHILD_REQUEST = 'Services/Community.svc/REST/CreateNewBaby'; +var GET_NEWCHILD_REQUEST = 'Services/Community.svc/REST/CreateNewBaby'; ///newUserId -const GET_NEW_USER_REQUEST = 'Services/Community.svc/REST/CreateNewUser_New'; +var GET_NEW_USER_REQUEST = 'Services/Community.svc/REST/CreateNewUser_New'; ///delete Child -const DELETE_CHILD_REQUEST = 'Services/Community.svc/REST/DeleteBaby'; +var DELETE_CHILD_REQUEST = 'Services/Community.svc/REST/DeleteBaby'; ///addNewTABLE -const GET_TABLE_REQUEST = 'Services/Community.svc/REST/CreateVaccinationTable'; +var GET_TABLE_REQUEST = 'Services/Community.svc/REST/CreateVaccinationTable'; ///BloodDenote -const GET_CITIES_REQUEST = 'Services/Lists.svc/REST/GetAllCities'; +var GET_CITIES_REQUEST = 'Services/Lists.svc/REST/GetAllCities'; ///BloodDetails -const GET_BLOOD_REQUEST = - 'services/PatientVarification.svc/REST/BloodDonation_GetBloodGroupDetails'; +var GET_BLOOD_REQUEST = 'services/PatientVarification.svc/REST/BloodDonation_GetBloodGroupDetails'; -const SAVE_BLOOD_REQUEST = - 'Services/PatientVarification.svc/REST/BloodDonation_RegisterBloodType'; +var SAVE_BLOOD_REQUEST = 'Services/PatientVarification.svc/REST/BloodDonation_RegisterBloodType'; -const GET_BLOOD_AGREEMENT = - 'Services/PatientVarification.svc/REST/CheckUserAgreementForBloodDonation'; -const SAVE_BLOOD_AGREEMENT = - 'Services/PatientVarification.svc/REST/AddUserAgreementForBloodDonation'; +var GET_BLOOD_AGREEMENT = 'Services/PatientVarification.svc/REST/CheckUserAgreementForBloodDonation'; +var SAVE_BLOOD_AGREEMENT = 'Services/PatientVarification.svc/REST/AddUserAgreementForBloodDonation'; ///Reports -const REPORTS = 'Services/Doctors.svc/REST/GetPatientMedicalReportStatusInfo'; -const INSERT_REQUEST_FOR_MEDICAL_REPORT = - 'Services/Doctors.svc/REST/InsertRequestForMedicalReport'; -const SEND_MEDICAL_REPORT_EMAIL = - 'Services/Notifications.svc/REST/SendMedicalReportEmail'; +var REPORTS = 'Services/Doctors.svc/REST/GetPatientMedicalReportStatusInfo'; +var INSERT_REQUEST_FOR_MEDICAL_REPORT = 'Services/Doctors.svc/REST/InsertRequestForMedicalReport'; +var SEND_MEDICAL_REPORT_EMAIL = 'Services/Notifications.svc/REST/SendMedicalReportEmail'; +var GET_INPATIENT_ADMISSIONS = 'Services/inps.svc/REST/getAdmissionForMedicalReport'; +var GET_MEDICAL_REPORT_PDF = 'Services/inps.svc/REST/getMedicalReportPDF'; ///Rate -const IS_LAST_APPOITMENT_RATED = - 'Services/Doctors.svc/REST/IsLastAppoitmentRated'; -const GET_APPOINTMENT_DETAILS_BY_NO = - 'Services/MobileNotifications.svc/REST/GetAppointmentDetailsByApptNo'; - -const GET_QR_PARKING = 'Services/SWP.svc/REST/GetQRParkingByID'; +// var IS_LAST_APPOITMENT_RATED = 'Services/Doctors.svc/REST/IsLastAppoitmentRated'; +var IS_LAST_APPOITMENT_RATED = 'Services/Doctors.svc/REST/IsLastAppoitmentRated_Async'; +var GET_APPOINTMENT_DETAILS_BY_NO = 'Services/MobileNotifications.svc/REST/GetAppointmentDetailsByApptNo'; +var NEW_RATE_APPOINTMENT_URL = "Services/Doctors.svc/REST/AppointmentsRating_InsertAppointmentRate"; +var NEW_RATE_DOCTOR_URL = "Services/Doctors.svc/REST/DoctorsRating_InsertDoctorRate"; -//const BASE_URL = 'https://hmgwebservices.com/'; // Production Environment -//const BASE_URL = 'https://hmgwebservices.com/Services'; // Production Environment -//const BASE_URL = 'https://uat.hmgwebservices.com/Services'; // UAT Environment +var GET_QR_PARKING = 'Services/SWP.svc/REST/GetQRParkingByID'; //URL to get clinic list -const GET_CLINICS_LIST_URL = "Services/lists.svc/REST/GetClinicCentralized"; +var GET_CLINICS_LIST_URL = "Services/lists.svc/REST/GetClinicCentralized"; +var GET_CLINICS_LIST_WRT_HOSPITAL_URL = "Services/Lists.svc/REST/GetClinicFromDoctorSchedule"; //URL to get active appointment list -const GET_ACTIVE_APPOINTMENTS_LIST_URL = - "Services/Doctors.svc/Rest/Dr_GetAppointmentActiveNumber"; +var GET_ACTIVE_APPOINTMENTS_LIST_URL = "Services/Doctors.svc/Rest/Dr_GetAppointmentActiveNumber"; //URL to get projects list -const GET_PROJECTS_LIST = 'Services/Lists.svc/REST/GetProject'; +var GET_PROJECTS_LIST = 'Services/Lists.svc/REST/GetProject'; //URL to get doctors list -const GET_DOCTORS_LIST_URL = "Services/Doctors.svc/REST/SearchDoctorsByTime"; +var GET_DOCTORS_LIST_URL = "Services/Doctors.svc/REST/SearchDoctorsByTime"; //URL to dental doctors list -const GET_DENTAL_DOCTORS_LIST_URL = - "Services/Doctors.svc/REST/Dental_DoctorChiefComplaintMapping"; +var GET_DENTAL_DOCTORS_LIST_URL = "Services/Doctors.svc/REST/Dental_DoctorChiefComplaintMapping"; //URL to get doctor free slots -const GET_DOCTOR_FREE_SLOTS = "Services/Doctors.svc/REST/GetDoctorFreeSlots"; +var GET_DOCTOR_FREE_SLOTS = "Services/Doctors.svc/REST/GetDoctorFreeSlots"; //URL to insert appointment -const INSERT_SPECIFIC_APPOINTMENT = - "Services/Doctors.svc/REST/InsertSpecificAppointment"; +var INSERT_SPECIFIC_APPOINTMENT = "Services/Doctors.svc/REST/InsertSpecificAppointment"; //URL to get patient share -const GET_PATIENT_SHARE = - "Services/Doctors.svc/REST/GetCheckinScreenAppointmentDetailsByAppointmentNO"; +var GET_PATIENT_SHARE = "Services/Doctors.svc/REST/GetCheckinScreenAppointmentDetailsByAppointmentNO"; //URL to get patient appointment history -const GET_PATIENT_APPOINTMENT_HISTORY = - "Services/Doctors.svc/REST/PateintHasAppoimentHistory"; +var GET_PATIENT_APPOINTMENT_HISTORY = "Services/Doctors.svc/REST/PateintHasAppoimentHistory"; + +var GET_OBGYNE_ORDERS_LIST = "services/Patients.svc/REST/HIS_OBGYNEProcedureGet"; + +var GET_OBGYNE_DOCTORS_LIST = "services/Doctors.svc/REST/HIS_ObgyneUltrasoundDoctors"; + +var OBGYNE_PROCEDURE_UPDATE = "services/Patients.svc/REST/HIS_OBGYNEProcedure_Update"; + +var GET_RRT_PROCEDURE_LIST = "Services/Patients.svc/REST/GetRRTProcedureDetailsListFromVida"; + +var DOCTOR_SCHEDULE_URL = 'Services/Doctors.svc/REST/GetDoctorWorkingHoursTable'; -const SEND_REPORT_EYE_EMAIL = "Services/Notifications.svc/REST/SendGlassesPrescriptionEmail"; +var SEND_REPORT_EYE_EMAIL = "Services/Notifications.svc/REST/SendGlassesPrescriptionEmail"; -const SEND_CONTACT_LENS_PRESCRIPTION_EMAIL = "Services/Notifications.svc/REST/SendContactLensPrescriptionEmail"; +var SEND_CONTACT_LENS_PRESCRIPTION_EMAIL = "Services/Notifications.svc/REST/SendContactLensPrescriptionEmail"; //URL to get patient appointment curfew history -const GET_PATIENT_APPOINTMENT_CURFEW_HISTORY = - "Services/Doctors.svc/REST/AppoimentHistoryForCurfew"; +// var GET_PATIENT_APPOINTMENT_CURFEW_HISTORY = "Services/Doctors.svc/REST/AppoimentHistoryForCurfew"; +var GET_PATIENT_APPOINTMENT_CURFEW_HISTORY = "Services/Doctors.svc/REST/AppoimentHistoryForCurfew_Async"; //URL to confirm appointment -const CONFIRM_APPOINTMENT = - "Services/MobileNotifications.svc/REST/ConfirmAppointment"; +var CONFIRM_APPOINTMENT = "Services/MobileNotifications.svc/REST/ConfirmAppointment"; -const INSERT_VIDA_REQUEST = - "Services/ER_VirtualCall.svc/REST/PatientER_VidaRequestInseart"; +var INSERT_VIDA_REQUEST = "Services/ER_VirtualCall.svc/REST/PatientER_VidaRequestInseart"; //URL to cancel appointment -const CANCEL_APPOINTMENT = "Services/Doctors.svc/REST/CancelAppointment"; +var CANCEL_APPOINTMENT = "Services/Doctors.svc/REST/CancelAppointment"; //URL get appointment QR -const GENERATE_QR_APPOINTMENT = - "Services/Doctors.svc/REST/GenerateQRAppointmentNo"; +var GENERATE_QR_APPOINTMENT = "Services/Doctors.svc/REST/GenerateQRAppointmentNo"; //URL send email appointment QR -const EMAIL_QR_APPOINTMENT = - "Services/Notifications.svc/REST/sendEmailForOnLineCheckin"; +var EMAIL_QR_APPOINTMENT = "Services/Notifications.svc/REST/sendEmailForOnLineCheckin"; //URL check payment status -const CHECK_PAYMENT_STATUS = - "Services/PayFort_Serv.svc/REST/GetRequestStatusByRequestID"; +var CHECK_PAYMENT_STATUS = "Services/PayFort_Serv.svc/REST/GetRequestStatusByRequestID"; //URL create advance payment -const CREATE_ADVANCE_PAYMENT = "Services/Doctors.svc/REST/CreateAdvancePayment"; +var CREATE_ADVANCE_PAYMENT = "Services/Doctors.svc/REST/CreateAdvancePayment"; + +var HIS_CREATE_ADVANCE_PAYMENT = "Services/Patients.svc/REST/HIS_CreateAdvancePayment"; + +var ER_CREATE_ADVANCE_PAYMENT = "services/Doctors.svc/REST/ER_CreateAdvancePaymentForClinic"; + +var ER_INSERT_ADVANCE_PAYMENT = "services/Doctors.svc/REST/ER_InsertEROnlinePaymentDetails"; + +var ADD_ADVANCE_NUMBER_REQUEST = 'Services/PayFort_Serv.svc/REST/AddAdvancedNumberRequest'; + +var GENERATE_ANCILLARY_ORDERS_INVOICE = 'Services/Doctors.svc/REST/AutoGenerateAncillaryOrderInvoice'; + +var IS_ALLOW_ASK_DOCTOR = 'Services/Doctors.svc/REST/GetPatientDoctorAppointmentResult'; +var GET_CALL_REQUEST_TYPE = 'Services/Doctors.svc/REST/GetCallRequestType_LOV'; +var ADD_VIDA_REQUEST = 'Services/ER_VirtualCall.svc/REST/PatientER_VidaRequestInseart'; -const HIS_CREATE_ADVANCE_PAYMENT = - "Services/Patients.svc/REST/HIS_CreateAdvancePayment"; +var SEND_CALL_REQUEST = 'Services/Doctors.svc/REST/InsertCallInfo'; -const ADD_ADVANCE_NUMBER_REQUEST = - 'Services/PayFort_Serv.svc/REST/AddAdvancedNumberRequest'; +var GET_LIVECARE_CLINICS = 'Services/ER_VirtualCall.svc/REST/PatientER_GetClinics'; -const IS_ALLOW_ASK_DOCTOR = - 'Services/Doctors.svc/REST/GetPatientDoctorAppointmentResult'; -const GET_CALL_REQUEST_TYPE = - 'Services/Doctors.svc/REST/GetCallRequestType_LOV'; -const ADD_VIDA_REQUEST = - 'Services/ER_VirtualCall.svc/REST/PatientER_VidaRequestInseart'; +var GET_LIVECARE_SCHEDULE_CLINICS = 'Services/Doctors.svc/REST/PatientER_GetClinicsHaveSchedule'; -const SEND_CALL_REQUEST = 'Services/Doctors.svc/REST/InsertCallInfo'; +var GET_LIVECARE_SCHEDULE_CLINIC_DOCTOR_LIST = 'Services/Doctors.svc/REST/PatientER_GetDoctorByClinicID'; -const GET_LIVECARE_CLINICS = - 'Services/ER_VirtualCall.svc/REST/PatientER_GetClinics'; +var GET_LIVECARE_SCHEDULE_DOCTOR_TIME_SLOTS = 'Services/Doctors.svc/REST/PatientER_GetDoctorFreeSlots'; -const GET_LIVECARE_SCHEDULE_CLINICS = - 'Services/Doctors.svc/REST/PatientER_GetClinicsHaveSchedule'; +var INSERT_LIVECARE_SCHEDULE_APPOINTMENT = 'Services/Doctors.svc/REST/InsertSpecificAppoitmentForSchedule'; -const GET_LIVECARE_SCHEDULE_CLINIC_DOCTOR_LIST = - 'Services/Doctors.svc/REST/PatientER_GetDoctorByClinicID'; +var GET_PATIENT_SHARE_LIVECARE = "Services/Doctors.svc/REST/GetCheckinScreenAppointmentDetailsByAppointmentNOForLiveCare"; -const GET_LIVECARE_SCHEDULE_DOCTOR_TIME_SLOTS = - 'Services/Doctors.svc/REST/PatientER_GetDoctorFreeSlots'; +var SET_ONLINE_CHECKIN_FOR_APPOINTMENT = "Services/Patients.svc/REST/SetOnlineCheckInForAppointment"; -const INSERT_LIVECARE_SCHEDULE_APPOINTMENT = - 'Services/Doctors.svc/REST/InsertSpecificAppoitmentForSchedule'; +var GET_LIVECARE_CLINIC_TIMING = 'Services/ER_VirtualCall.svc/REST/PatientER_GetClinicsServiceTimingsSchedule'; -const GET_PATIENT_SHARE_LIVECARE = - "Services/Doctors.svc/REST/GetCheckinScreenAppointmentDetailsByAppointmentNOForLiveCare"; +var GET_ER_APPOINTMENT_FEES = 'Services/DoctorApplication.svc/REST/GetERAppointmentFees'; +var GET_ER_APPOINTMENT_TIME = 'Services/ER_VirtualCall.svc/REST/GetRestTime'; -const GET_LIVECARE_CLINIC_TIMING = - 'Services/ER_VirtualCall.svc/REST/PatientER_GetClinicsServiceTimingsSchedule'; +var CHECK_PATIENT_DERMA_PACKAGE = 'Services/OUTPs.svc/REST/getPatientPackageComponentsForOnlineCheckIn'; -const GET_ER_APPOINTMENT_FEES = - 'Services/DoctorApplication.svc/REST/GetERAppointmentFees'; -const GET_ER_APPOINTMENT_TIME = 'Services/ER_VirtualCall.svc/REST/GetRestTime'; +var ADD_NEW_CALL_FOR_PATIENT_ER = 'Services/DoctorApplication.svc/REST/NewCallForPatientER'; -const ADD_NEW_CALL_FOR_PATIENT_ER = - 'Services/DoctorApplication.svc/REST/NewCallForPatientER'; +var GET_LIVECARE_HISTORY = 'Services/ER_VirtualCall.svc/REST/GetPatientErVirtualHistory'; +var CANCEL_LIVECARE_REQUEST = 'Services/ER_VirtualCall.svc/REST/DeleteErRequest'; +var SEND_LIVECARE_INVOICE_EMAIL = 'Services/Notifications.svc/REST/SendInvoiceForLiveCare'; -const GET_LIVECARE_HISTORY = - 'Services/ER_VirtualCall.svc/REST/GetPatientErVirtualHistory'; -const CANCEL_LIVECARE_REQUEST = - 'Services/ER_VirtualCall.svc/REST/DeleteErRequest'; -const SEND_LIVECARE_INVOICE_EMAIL = - 'Services/Notifications.svc/REST/SendInvoiceForLiveCare'; +var CHANGE_PATIENT_ER_SESSION = 'Services/DoctorApplication.svc/REST/ChangePatientERSession'; -const GET_USER_TERMS = 'Services/Patients.svc/REST/GetUserTermsAndConditions'; -const UPDATE_HEALTH_TERMS = - 'services/Patients.svc/REST/UpdatePateintHealthSummaryReport'; +var APPLE_PAY_INSERT_REQUEST = 'Services/PayFort_Serv.svc/REST/PayFort_ApplePayRequestData_Insert'; -const GET_PATIENT_HEALTH_STATS = - 'Services/Patients.svc/REST/Med_GetTransactionsSts'; +var GET_USER_TERMS = 'Services/Patients.svc/REST/GetUserTermsAndConditions'; + +var TAMARA_REQUEST_INSERT = 'Services/PayFort_Serv.svc/REST/AddTamaraRequest'; + +var UPDATE_HEALTH_TERMS = 'services/Patients.svc/REST/UpdatePateintHealthSummaryReport'; + +var GET_PATIENT_HEALTH_STATS = 'Services/Patients.svc/REST/Med_GetTransactionsSts'; + +var SEND_CHECK_IN_NFC_REQUEST = 'Services/Patients.svc/REST/Patient_CheckAppointmentValidation_ForNFC'; + +var CHECK_SCANNED_NFC_QR_CODE = 'Services/Patients.svc/REST/Patient_ValidationMachine_ForNFC'; + +var HAS_DENTAL_PLAN = 'Services/Doctors.svc/REST/Dental_IsPatientHasOnGoingEstimation'; + +var LASER_BODY_PARTS = 'Services/Patients.svc/REST/Laser_GetBodyPartsByCategory'; + +var INSERT_COVID_QUESTIONNAIRE = 'Services/Doctors.svc/REST/COVID19_Questionnarie_Insert'; + +var UPDATE_COVID_QUESTIONNAIRE = 'Services/Doctors.svc/REST/COVID19_Questionnarie_Update'; + +var GET_PATIENT_SHARE_FOR_WALKIN_APPOINTMENT = 'Services/Doctors.svc/REST/GetCheckinScreenAppointmentDetailsByAppointmentNOForWalkIn'; + +var CAN_PAY_FOR_FOR_WALKIN_APPOINTMENT = 'Services/Doctors.svc/REST/CanPayForWalkinAppointment'; //URL to get medicine and pharmacies list -const CHANNEL = 3; -const GENERAL_ID = 'Cs2020@2016\$2958'; -const IP_ADDRESS = '10.20.10.20'; -const VERSION_ID = 8.8; -const SETUP_ID = '91877'; -const LANGUAGE = 2; -const PATIENT_OUT_SA = 0; -const SESSION_ID = 'TMRhVmkGhOsvamErw'; -const IS_DENTAL_ALLOWED_BACKEND = false; -const PATIENT_TYPE = 1; -const PATIENT_TYPE_ID = 1; +var CHANNEL = 3; +var GENERAL_ID = 'Cs2020@2016\$2958'; +var IP_ADDRESS = '10.20.10.20'; +var VERSION_ID = 18.7; +var SETUP_ID = '91877'; +var LANGUAGE = 2; +// var PATIENT_OUT_SA = 0; +var SESSION_ID = 'TMRhVmkGhOsvamErw'; +var IS_DENTAL_ALLOWED_BACKEND = false; +var PATIENT_TYPE = 1; +var PATIENT_TYPE_ID = 1; var DEVICE_TOKEN = ""; -var IS_VOICE_COMMAND_CLOSED = false; +var IS_VOICE_COMMAND_CLOSED = true; var IS_TEXT_COMPLETED = false; -var DeviceTypeID = Platform.isIOS ? 1 : 2; -const LANGUAGE_ID = 2; -const GET_PHARMCY_ITEMS = "Services/Lists.svc/REST/GetPharmcyItems_Region"; -const GET_PHARMACY_LIST = "Services/Patients.svc/REST/GetPharmcyList"; -const GET_PAtIENTS_INSURANCE = - "Services/Patients.svc/REST/Get_PatientInsuranceDetails"; -const GET_PAtIENTS_INSURANCE_UPDATED = - "Services/Patients.svc/REST/PatientER_GetPatientInsuranceCardUpdateHistory"; - -const INSURANCE_DETAILS = "Services/Patients.svc/REST/Get_InsuranceCheckList"; -const GET_PATIENT_INSURANCE_DETAILS = - "Services/Patients.svc/REST/PatientER_GetPatientInsuranceDetails"; -const UPLOAD_INSURANCE_CARD = - 'Services/Patients.svc/REST/PatientER_PatientInfoForInsuranceCardUpdate'; - -const GET_VACCINES = "Services/Patients.svc/REST/GetDoneVaccinesByPatientID"; -const GET_VACCINES_EMAIL = "Services/Notifications.svc/REST/SendVaccinesEmail"; -const GET_PAtIENTS_INSURANCE_APPROVALS = - "Services/Patients.svc/REST/GetApprovalStatus"; -const SEARCH_BOT = 'HabibiChatBotApi/BotInterface/GetVoiceCommandResponse'; - -const GET_VACCINATIONS_ITEMS = "/Services/ERP.svc/REST/GET_VACCINATIONS_ITEMS"; -const GET_VACCINATION_ONHAND = "/Services/ERP.svc/REST/GET_VACCINATION_ONHAND"; - -const GET_PATIENT_SICK_LEAVE = 'Services/Patients.svc/REST/GetPatientSickLeave'; - -const SendSickLeaveEmail = 'Services/Notifications.svc/REST/SendSickLeaveEmail'; - -const GET_PATIENT_AdVANCE_BALANCE_AMOUNT = - 'Services/Patients.svc/REST/GetPatientAdvanceBalanceAmount'; -const GET_PATIENT_INFO_BY_ID = - 'Services/Doctors.svc/REST/GetPatientInfoByPatientID'; -const GET_PATIENT_INFO_BY_ID_AND_MOBILE_NUMBER = - 'Services/Patients.svc/REST/AP_GetPatientInfoByPatientIDandMobileNumber'; -const SEND_ACTIVATION_CODE_FOR_ADVANCE_PAYMENT = - 'Services/Authentication.svc/REST/SendActivationCodeForAdvancePayment'; -const CHECK_ACTIVATION_CODE_FOR_ADVANCE_PAYMENT = - 'Services/Authentication.svc/REST/CheckActivationCodeForAdvancePayment'; - -const GET_COVID_DRIVETHRU_PROJECT_LIST = - 'Services/Doctors.svc/REST/COVID19_ProjectDriveThroughTestingCenter'; - -const GET_COVID_DRIVETHRU_PAYMENT_INFO = - 'Services/Doctors.svc/REST/COVID19_GetPatientPaymentInormation'; - -const GET_COVID_DRIVETHRU_FREE_SLOTS = - 'Services/Doctors.svc/REST/COVID19_GetFreeSlots'; +// var DeviceTypeID = Platform.isIOS ? 1 : 2; +// var LANGUAGE_ID = 2; + +var GET_PHARMCY_ITEMS = "Services/Lists.svc/REST/GetPharmcyItems_Region"; +var GET_PHARMACY_LIST = "Services/Patients.svc/REST/GetPharmcyList"; +var GET_PAtIENTS_INSURANCE = "Services/Patients.svc/REST/Get_PatientInsuranceDetails"; +var GET_PAtIENTS_INSURANCE_UPDATED = "Services/Patients.svc/REST/PatientER_GetPatientInsuranceCardUpdateHistory"; + +var INSURANCE_DETAILS = "Services/Patients.svc/REST/Get_InsuranceCheckList"; +var INSURANCE_SCHEMES = "Services/Patients.svc/REST/PatientER_SchemesOfAactiveCompaniesGet"; +var UPDATE_MANUAL_INSURANCE = "Services/Patients.svc/REST/PatientER_PatientInfoForInsuranceCardUpdate"; +var INSURANCE_COMPANIES = "Services/Patients.svc/REST/PatientER_InsuranceCompanyGet"; +var GET_PATIENT_INSURANCE_DETAILS = "Services/Patients.svc/REST/PatientER_GetPatientInsuranceDetails"; +var UPLOAD_INSURANCE_CARD = 'Services/Patients.svc/REST/PatientER_PatientInfoForInsuranceCardUpdate'; + +var GET_VACCINES = "Services/Patients.svc/REST/GetDoneVaccinesByPatientID"; +var GET_VACCINES_EMAIL = "Services/Notifications.svc/REST/SendVaccinesEmail"; +var GET_PAtIENTS_INSURANCE_APPROVALS = "Services/Patients.svc/REST/GetApprovalStatus_Async"; +// var GET_PAtIENTS_INSURANCE_APPROVALS = "Services/Patients.svc/REST/GetApprovalStatus"; +var SEARCH_BOT = 'HabibiChatBotApi/BotInterface/GetVoiceCommandResponse'; + +var GET_VACCINATIONS_ITEMS = "/Services/ERP.svc/REST/GET_VACCINATIONS_ITEMS"; +var GET_VACCINATION_ONHAND = "/Services/ERP.svc/REST/GET_VACCINATION_ONHAND"; + +var GET_PATIENT_SICK_LEAVE = 'Services/Patients.svc/REST/GetPatientSickLeave'; + +var GET_PATIENT_SICK_LEAVE_STATUS = 'Services/Patients.svc/REST/GetPatientSickLeave_Status'; + +var SendSickLeaveEmail = 'Services/Notifications.svc/REST/SendSickLeaveEmail'; + +var GET_PATIENT_AdVANCE_BALANCE_AMOUNT = 'Services/Patients.svc/REST/GetPatientAdvanceBalanceAmount'; +var GET_PATIENT_INFO_BY_ID = 'Services/Doctors.svc/REST/GetPatientInfoByPatientID'; +var GET_PATIENT_INFO_BY_ID_AND_MOBILE_NUMBER = 'Services/Patients.svc/REST/AP_GetPatientInfoByPatientIDandMobileNumber'; +var SEND_ACTIVATION_CODE_FOR_ADVANCE_PAYMENT = 'Services/Authentication.svc/REST/SendActivationCodeForAdvancePayment'; +var CHECK_ACTIVATION_CODE_FOR_ADVANCE_PAYMENT = 'Services/Authentication.svc/REST/CheckActivationCodeForAdvancePayment'; + +var GET_COVID_DRIVETHRU_PROJECT_LIST = 'Services/Doctors.svc/REST/COVID19_ProjectDriveThroughTestingCenter'; + +var GET_COVID_DRIVETHRU_PAYMENT_INFO = 'Services/Doctors.svc/REST/COVID19_GetPatientPaymentInormation'; + +var GET_COVID_DRIVETHRU_FREE_SLOTS = 'Services/Doctors.svc/REST/COVID19_GetFreeSlots'; + +var GET_COVID_DRIVETHRU_PROCEDURES_LIST = 'Services/Doctors.svc/REST/COVID19_GetTestProcedures'; ///Smartwatch Integration Services -const GET_PATIENT_LAST_RECORD = - 'Services/Patients.svc/REST/Med_GetPatientLastRecord'; +var GET_PATIENT_LAST_RECORD = 'Services/Patients.svc/REST/Med_GetPatientLastRecord'; +var INSERT_PATIENT_HEALTH_DATA = 'Services/Patients.svc/REST/Med_InsertTransactions'; ///My Trackers -const GET_DIABETIC_RESULT_AVERAGE = - 'Services/Patients.svc/REST/Patient_GetDiabeticResultAverage'; -const GET_DIABTEC_RESULT = - 'Services/Patients.svc/REST/Patient_GetDiabtecResults'; -const ADD_DIABTEC_RESULT = - 'Services/Patients.svc/REST/Patient_AddDiabtecResult'; - -const GET_BLOOD_PRESSURE_RESULT_AVERAGE = - 'Services/Patients.svc/REST/Patient_GetBloodPressureResultAverage'; -const GET_BLOOD_PRESSURE_RESULT = - 'Services/Patients.svc/REST/Patient_GetBloodPressureResult'; -const ADD_BLOOD_PRESSURE_RESULT = - 'Services/Patients.svc/REST/Patient_AddBloodPressureResult'; - -const GET_WEIGHT_PRESSURE_RESULT_AVERAGE = - 'Services/Patients.svc/REST/Patient_GetWeightMeasurementResultAverage'; -const GET_WEIGHT_PRESSURE_RESULT = - 'Services/Patients.svc/REST/Patient_GetWeightMeasurementResult'; -const ADD_WEIGHT_PRESSURE_RESULT = - 'Services/Patients.svc/REST/Patient_AddWeightMeasurementResult'; - -const ADD_ACTIVE_PRESCRIPTIONS_REPORT_BY_PATIENT_ID = - 'Services/Patients.svc/Rest/GetActivePrescriptionReportByPatientID'; - -const GET_CALL_INFO_HOURS_RESULT = - 'Services/Doctors.svc/REST/GetCallInfoHoursResult'; -const GET_CALL_REQUEST_TYPE_LOV = - 'Services/Doctors.svc/REST/GetCallRequestType_LOV'; - -const UPDATE_DIABETIC_RESULT = - 'Services/Patients.svc/REST/Patient_UpdateDiabeticResult'; - -const SEND_AVERAGE_BLOOD_SUGAR_REPORT = - 'Services/Notifications.svc/REST/SendAverageBloodSugarReport'; -const DEACTIVATE_DIABETIC_STATUS = - 'services/Patients.svc/REST/Patient_DeactivateDiabeticStatus'; -const DEACTIVATE_BLOOD_PRESSURES_STATUS = - 'services/Patients.svc/REST/Patient_DeactivateBloodPressureStatus'; - -const UPDATE_BLOOD_PRESSURE_RESULT = - 'Services/Patients.svc/REST/Patient_UpdateBloodPressureResult'; -const SEND_AVERAGE_BLOOD_WEIGHT_REPORT = - 'Services/Notifications.svc/REST/SendAverageBodyWeightReport'; -const SEND_AVERAGE_BLOOD_PRESSURE_REPORT = - 'Services/Notifications.svc/REST/SendAverageBloodPressureReport'; - -const UPDATE_WEIGHT_PRESSURE_RESULT = - 'Services/Patients.svc/REST/Patient_UpdateWeightMeasurementResult'; -const DEACTIVATE_WEIGHT_PRESSURE_RESULT = - 'services/Patients.svc/REST/Patient_DeactivateWeightMeasurementStatus'; -const GET_DOCTOR_RESPONSE = 'Services/Patients.svc/REST/GetDoctorResponse'; -const UPDATE_READ_STATUS = 'Services/Patients.svc/REST/UpdateReadStatus'; -const INSERT_CALL_INFO = 'Services/Doctors.svc/REST/InsertCallInfo'; - -const GET_PATIENT_ALLERGIES = 'Services/Patients.svc/REST/GetPatientAllergies'; +var GET_DIABETIC_RESULT_AVERAGE = 'Services/Patients.svc/REST/Patient_GetDiabeticResultAverage'; +var GET_DIABTEC_RESULT = 'Services/Patients.svc/REST/Patient_GetDiabtecResults'; +var ADD_DIABTEC_RESULT = 'Services/Patients.svc/REST/Patient_AddDiabtecResult'; + +var GET_BLOOD_PRESSURE_RESULT_AVERAGE = 'Services/Patients.svc/REST/Patient_GetBloodPressureResultAverage'; +var GET_BLOOD_PRESSURE_RESULT = 'Services/Patients.svc/REST/Patient_GetBloodPressureResult'; +var ADD_BLOOD_PRESSURE_RESULT = 'Services/Patients.svc/REST/Patient_AddBloodPressureResult'; + +var GET_WEIGHT_PRESSURE_RESULT_AVERAGE = 'Services/Patients.svc/REST/Patient_GetWeightMeasurementResultAverage'; +var GET_WEIGHT_PRESSURE_RESULT = 'Services/Patients.svc/REST/Patient_GetWeightMeasurementResult'; +var ADD_WEIGHT_PRESSURE_RESULT = 'Services/Patients.svc/REST/Patient_AddWeightMeasurementResult'; + +var ADD_ACTIVE_PRESCRIPTIONS_REPORT_BY_PATIENT_ID = 'Services/Patients.svc/Rest/GetActivePrescriptionReportByPatientID'; + +var GET_CALL_INFO_HOURS_RESULT = 'Services/Doctors.svc/REST/GetCallInfoHoursResult'; +var GET_CALL_REQUEST_TYPE_LOV = 'Services/Doctors.svc/REST/GetCallRequestType_LOV'; + +var GET_QUESTION_TYPES = 'Services/OUTPs.svc/REST/getQuestionsTypes'; + +var UPDATE_DIABETIC_RESULT = 'Services/Patients.svc/REST/Patient_UpdateDiabeticResult'; + +var SEND_AVERAGE_BLOOD_SUGAR_REPORT = 'Services/Notifications.svc/REST/SendAverageBloodSugarReport'; +var DEACTIVATE_DIABETIC_STATUS = 'services/Patients.svc/REST/Patient_DeactivateDiabeticStatus'; +var DEACTIVATE_BLOOD_PRESSURES_STATUS = 'services/Patients.svc/REST/Patient_DeactivateBloodPressureStatus'; + +var UPDATE_BLOOD_PRESSURE_RESULT = 'Services/Patients.svc/REST/Patient_UpdateBloodPressureResult'; +var SEND_AVERAGE_BLOOD_WEIGHT_REPORT = 'Services/Notifications.svc/REST/SendAverageBodyWeightReport'; +var SEND_AVERAGE_BLOOD_PRESSURE_REPORT = 'Services/Notifications.svc/REST/SendAverageBloodPressureReport'; + +var UPDATE_WEIGHT_PRESSURE_RESULT = 'Services/Patients.svc/REST/Patient_UpdateWeightMeasurementResult'; +var DEACTIVATE_WEIGHT_PRESSURE_RESULT = 'services/Patients.svc/REST/Patient_DeactivateWeightMeasurementStatus'; +var GET_DOCTOR_RESPONSE = 'Services/Patients.svc/REST/GetDoctorResponse'; +var UPDATE_READ_STATUS = 'Services/Patients.svc/REST/UpdateReadStatus'; + +var INSERT_CALL_INFO = 'Services/Doctors.svc/REST/InsertCallInfo'; +var INSERT_APPOINTMENT_QUESTION = 'Services/OUTPs.svc/REST/insertAppointmentQuestion'; +var RATE_DOCTOR_RESPONSE = 'Services/OUTPs.svc/REST/insertAppointmentQuestionRating'; + +var GET_PATIENT_ALLERGIES = 'Services/Patients.svc/REST/GetPatientAllergies'; // H2O -const H2O_GET_USER_PROGRESS = - "Services/H2ORemainder.svc/REST/H2O_GetUserProgress"; -const H2O_INSERT_USER_ACTIVITY = - "Services/H2ORemainder.svc/REST/H2O_InsertUserActivity"; -const H2O_GET_USER_DETAIL = - "Services/H2ORemainder.svc/REST/H2O_GetUserDetails_New"; -const H2O_UPDATE_USER_DETAIL = - "Services/H2ORemainder.svc/REST/H2O_UpdateUserDetails_New"; -const H2O_UNDO_USER_ACTIVITY = - "Services/H2ORemainder.svc/REST/H2o_UndoUserActivity"; +var H2O_GET_USER_PROGRESS = "Services/H2ORemainder.svc/REST/H2O_GetUserProgress"; +var H2O_INSERT_USER_ACTIVITY = "Services/H2ORemainder.svc/REST/H2O_InsertUserActivity"; +var H2O_GET_USER_DETAIL = "Services/H2ORemainder.svc/REST/H2O_GetUserDetails_New"; +var H2O_UPDATE_USER_DETAIL = "Services/H2ORemainder.svc/REST/H2O_UpdateUserDetails_New"; +var H2O_UNDO_USER_ACTIVITY = "Services/H2ORemainder.svc/REST/H2o_UndoUserActivity"; //E_Referral Services -const GET_ALL_RELATIONSHIP_TYPES = - "Services/Patients.svc/REST/GetAllRelationshipTypes"; -const SEND_ACTIVATION_CODE_FOR_E_REFERRAL = - 'Services/Authentication.svc/REST/SendActivationCodeForEReferral'; -const CHECK_ACTIVATION_CODE_FOR_E_REFERRAL = - 'Services/Authentication.svc/REST/CheckActivationCodeForEReferral'; -const GET_ALL_CITIES = 'services/Lists.svc/rest/GetAllCities'; -const CREATE_E_REFERRAL = "Services/Patients.svc/REST/CreateEReferral"; -const GET_E_REFERRALS = "Services/Patients.svc/REST/GetEReferrals"; +var GET_ALL_RELATIONSHIP_TYPES = "Services/Patients.svc/REST/GetAllRelationshipTypes"; +var SEND_ACTIVATION_CODE_FOR_E_REFERRAL = 'Services/Authentication.svc/REST/SendActivationCodeForEReferral'; +var CHECK_ACTIVATION_CODE_FOR_E_REFERRAL = 'Services/Authentication.svc/REST/CheckActivationCodeForEReferral'; +var GET_ALL_CITIES = 'services/Lists.svc/rest/GetAllCities'; +var CREATE_E_REFERRAL = "Services/Patients.svc/REST/CreateEReferral"; +var GET_E_REFERRALS = "Services/Patients.svc/REST/GetEReferrals"; // Encillary Orders -const GET_ANCILLARY_ORDERS = - 'Services/Doctors.svc/REST/GetOnlineAncillaryOrderList'; +var GET_ANCILLARY_ORDERS = 'Services/Doctors.svc/REST/GetOnlineAncillaryOrderList'; -const GET_ANCILLARY_ORDERS_DETAILS = - 'Services/Doctors.svc/REST/GetOnlineAncillaryOrderProcList'; +var GET_ANCILLARY_ORDERS_DETAILS = 'Services/Doctors.svc/REST/GetOnlineAncillaryOrderProcList'; //Pharmacy wishlist -// const GET_WISHLIST = "http://swd-pharapp-01:7200/api/shopping_cart_items/"; +// var GET_WISHLIST = "http://swd-pharapp-01:7200/api/shopping_cart_items/"; + +var GET_DOCTOR_LIST_BY_TIME = "Services/Doctors.svc/REST/SearchDoctorsByTime"; // pharmacy -const PHARMACY_AUTORZIE_CUSTOMER = "AutorizeCustomer"; -const PHARMACY_VERIFY_CUSTOMER = "VerifyCustomer"; -const PHARMACY_GET_COUNTRY = "countries"; -const PHARMACY_CREATE_CUSTOMER = "epharmacy/api/CreateCustomer"; -const GET_PHARMACY_BANNER = "promotionbanners"; -const GET_PHARMACY_TOP_MANUFACTURER = "topmanufacturer"; -const GET_PHARMACY_BEST_SELLER_PRODUCT = "bestsellerproducts"; -const GET_PHARMACY_PRODUCTs_BY_IDS = "productsbyids/"; -const GET_PHARMACY_PRODUCTs_BY_SKU = "productbysku/"; -const GET_CUSTOMERS_ADDRESSES = "Customers/"; -const SUBSCRIBE_PRODUCT = "subscribe?"; -const GET_ORDER = "orders?"; -const GET_ORDER_DETAILS = "orders/"; -const ADD_CUSTOMER_ADDRESS = "epharmacy/api/addcustomeraddress"; -const EDIT_CUSTOMER_ADDRESS = "epharmacy/api/editcustomeraddress"; -const DELETE_CUSTOMER_ADDRESS = "epharmacy/api/deletecustomeraddress"; -const GET_ADDRESS = "Customers/"; -const GET_Cancel_ORDER = "cancelorder/"; -const WRITE_REVIEW = "Content-Type" + "text/plain; charset=utf-8"; -const GET_SHOPPING_CART = "shopping_cart_items/"; -const GET_SHIPPING_OPTIONS = "get_shipping_option/"; -const DELETE_SHOPPING_CART = "delete_shopping_cart_items/"; -const DELETE_SHOPPING_CART_ALL = "delete_shopping_cart_item_by_customer/"; -const ORDER_SHOPPING_CART = "orders"; -const GET_LACUM_ACCOUNT_INFORMATION = - "Services/Patients.svc/REST/GetLakumAccountInformation"; -const GET_LACUM_GROUP_INFORMATION = - "Services/Patients.svc/REST/GetlakumInQueryInfoGrouping"; -const LACUM_ACCOUNT_ACTIVATE = - "Services/Patients.svc/REST/LakumAccountActivation"; -const LACUM_ACCOUNT_DEACTIVATE = - "Services/Patients.svc/REST/LakumAccountDeactivation"; -const CREATE_LAKUM_ACCOUNT = - "Services/Patients.svc/REST/PHR_CreateLakumAccount"; -const TRANSFER_YAHALA_LOYALITY_POINTS = - "Services/Patients.svc/REST/TransferYaHalaLoyaltyPoints"; -const LAKUM_GET_USER_TERMS_AND_CONDITIONS = - "Services/ERP.svc/REST/GetUserTermsAndConditionsForEPharmcy"; -const PRESCRIPTION = 'Services/Patients.svc/REST/GetPrescriptionApptList'; -const GET_RECOMMENDED_PRODUCT = 'alsoProduct/'; -const GET_MOST_VIEWED_PRODUCTS ="mostview?"; -const GET_NEW_PRODUCTS = "newproducts?"; +var PHARMACY_AUTORZIE_CUSTOMER = "AutorizeCustomer"; +var PHARMACY_VERIFY_CUSTOMER = "VerifyCustomer"; +var PHARMACY_GET_COUNTRY = "countries"; +// var PHARMACY_CREATE_CUSTOMER = "epharmacy/api/CreateCustomer"; +var PHARMACY_CREATE_CUSTOMER = "getorcreateCustomer"; +var GET_PHARMACY_BANNER = "promotionbanners"; +var GET_PHARMACY_TOP_MANUFACTURER = "topmanufacturer"; +var GET_PHARMACY_BEST_SELLER_PRODUCT = "bestsellerproducts"; +var GET_PHARMACY_PRODUCTs_BY_IDS = "productsbyids/"; +var GET_PHARMACY_PRODUCTs_BY_SKU = "productbysku/"; +var GET_CUSTOMERS_ADDRESSES = "Customers/"; +var SUBSCRIBE_PRODUCT = "subscribe?"; +var GET_ORDER = "orders?"; +var GET_ORDER_DETAILS = "orders/"; +var ADD_CUSTOMER_ADDRESS = "addcustomeraddress"; +var EDIT_CUSTOMER_ADDRESS = "editcustomeraddress"; +var DELETE_CUSTOMER_ADDRESS = "deletecustomeraddress"; +var GET_ADDRESS = "Customers/"; +var GET_Cancel_ORDER = "cancelorder/"; +var WRITE_REVIEW = "Content-Type" + "text/plain; charset=utf-8"; +var GET_SHOPPING_CART = "shopping_cart_items/"; +var GET_SHIPPING_OPTIONS = "get_shipping_option/"; +var DELETE_SHOPPING_CART = "delete_shopping_cart_items/"; +var DELETE_SHOPPING_CART_ALL = "delete_shopping_cart_item_by_customer/"; +var ORDER_SHOPPING_CART = "orders"; +var GET_LACUM_ACCOUNT_INFORMATION = "Services/Patients.svc/REST/GetLakumAccountInformation"; +var GET_LACUM_GROUP_INFORMATION = "Services/Patients.svc/REST/GetlakumInQueryInfoGrouping"; +var LACUM_ACCOUNT_ACTIVATE = "Services/Patients.svc/REST/LakumAccountActivation"; +var LACUM_ACCOUNT_DEACTIVATE = "Services/Patients.svc/REST/LakumAccountDeactivation"; +var CREATE_LAKUM_ACCOUNT = "Services/Patients.svc/REST/PHR_CreateLakumAccount"; +var TRANSFER_YAHALA_LOYALITY_POINTS = "Services/Patients.svc/REST/TransferYaHalaLoyaltyPoints"; +var LAKUM_GET_USER_TERMS_AND_CONDITIONS = "Services/ERP.svc/REST/GetUserTermsAndConditionsForEPharmcy"; + +// var PRESCRIPTION = 'Services/Patients.svc/REST/GetPrescriptionApptList'; +var PRESCRIPTION = 'Services/Patients.svc/REST/GetPrescriptionApptList_Async'; + +var GET_RECOMMENDED_PRODUCT = 'alsoProduct/'; +var GET_MOST_VIEWED_PRODUCTS = "mostview"; +var GET_NEW_PRODUCTS = "newproducts"; // Home Health Care -const HHC_GET_ALL_SERVICES = - "Services/Patients.svc/REST/PatientER_HHC_GetAllServices"; -const HHC_GET_ALL_CMC_SERVICES = - "Services/Patients.svc/REST/PatientER_CMC_GetAllServices"; -const PATIENT_ER_UPDATE_PRES_ORDER = - "Services/Patients.svc/REST/PatientER_UpdatePresOrder"; -const GET_ORDER_DETAIL_BY_ID = - "Services/Patients.svc/REST/PatientER_HHC_GetTransactionsForOrder"; -const GET_CMC_ORDER_DETAIL_BY_ID = - "Services/Patients.svc/REST/PatientER_CMC_GetTransactionsForOrder"; -const GET_CHECK_UP_ITEMS = "Services/Patients.svc/REST/GetCheckUpItems"; -const PUSH_NOTIFICATION_GET_ALL_NOTIFICATIONS = - 'Services/MobileNotifications.svc/REST/PushNotification_GetAllNotifications'; -const PUSH_NOTIFICATION_SET_MESSAGES_FROM_POOL_AS_READ = - 'Services/MobileNotifications.svc/REST/PushNotification_SetMessagesFromPoolAsRead'; -const GET_PATIENT_ALL_PRES_ORD = - 'Services/Patients.svc/REST/PatientER_GetPatientAllPresOrders'; -const PATIENT_ER_INSERT_PRES_ORDER = - 'Services/Patients.svc/REST/PatientER_InsertPresOrder'; -const PHARMACY_MAKE_REVIEW = 'epharmacy/api/insertreviews'; -const BLOOD_DONATION_REGISTER_BLOOD_TYPE = - 'Services/PatientVarification.svc/REST/BloodDonation_RegisterBloodType'; -const ADD_USER_AGREEMENT_FOR_BLOOD_DONATION = - 'Services/PatientVarification.svc/REST/AddUserAgreementForBloodDonation'; +var HHC_GET_ALL_SERVICES = "Services/Patients.svc/REST/PatientER_HHC_GetAllServices"; +var HHC_GET_ALL_CMC_SERVICES = "Services/Patients.svc/REST/PatientER_CMC_GetAllServices"; +var PATIENT_ER_UPDATE_PRES_ORDER = "Services/Patients.svc/REST/PatientER_UpdatePresOrder"; +var GET_ORDER_DETAIL_BY_ID = "Services/Patients.svc/REST/PatientER_HHC_GetTransactionsForOrder"; +var GET_CMC_ORDER_DETAIL_BY_ID = "Services/Patients.svc/REST/PatientER_CMC_GetTransactionsForOrder"; +var GET_CHECK_UP_ITEMS = "Services/Patients.svc/REST/GetCheckUpItems"; +var PUSH_NOTIFICATION_GET_ALL_NOTIFICATIONS = 'Services/MobileNotifications.svc/REST/PushNotification_GetAllNotifications'; +var PUSH_NOTIFICATION_SET_MESSAGES_FROM_POOL_AS_READ = 'Services/MobileNotifications.svc/REST/PushNotification_SetMessagesFromPoolAsRead'; +var GET_PATIENT_ALL_PRES_ORD = 'Services/Patients.svc/REST/PatientER_GetPatientAllPresOrders'; +var PATIENT_ER_INSERT_PRES_ORDER = 'Services/Patients.svc/REST/PatientER_InsertPresOrder'; +var BLOOD_DONATION_REGISTER_BLOOD_TYPE = 'Services/PatientVarification.svc/REST/BloodDonation_RegisterBloodType'; +var ADD_USER_AGREEMENT_FOR_BLOOD_DONATION = 'Services/PatientVarification.svc/REST/AddUserAgreementForBloodDonation'; + +// HHC RC SERVICES +var HHC_GET_ALL_SERVICES_RC = "api/HHC/getallhhc"; +var ADD_HHC_ORDER_RC = "api/HHC/add"; +var GET_ALL_HHC_ORDERS_RC = 'api/hhc/list'; +var UPDATE_HHC_ORDER_RC = 'api/hhc/update'; + +// CMC RC SERVICES +var GET_ALL_CMC_SERVICES_RC = 'api/cmc/getallcmc'; +var ADD_CMC_ORDER_RC = 'api/cmc/add'; +var GET_ALL_CMC_ORDERS_RC = 'api/cmc/list'; +var UPDATE_CMC_ORDER_RC = 'api/cmc/update'; + +// RRT RC SERVICES +var ADD_RRT_ORDER_RC = "api/rrt/add"; +var GET_ALL_RRT_ORDERS_RC = "api/rrt/list"; +var UPDATE_RRT_ORDER_RC = 'api/rrt/update'; + +// PRESCRIPTION RC SERVICES +var ADD_PRESCRIPTION_ORDER_RC = "api/prescription/add"; +var GET_ALL_PRESCRIPTION_ORDERS_RC = "api/prescription/list"; +var GET_ALL_PRESCRIPTION_INFO_RC = "api/Prescription/info"; +var UPDATE_PRESCRIPTION_ORDER_RC = 'api/prescription/update'; //Pharmacy wishlist -const GET_WISHLIST = "shopping_cart_items/"; -const DELETE_WISHLIST = "delete_shopping_cart_item_by_product?customer_id="; -const GET_REVIEW = "customerreviews/"; -const GET_BRANDS = "manufacturer"; -const GET_TOP_BRANDS = "topmanufacturer?page=1&limit=8"; -const GET_PRODUCT_DETAIL = "products/"; -const GET_LOCATION = "Services/Patients.svc/REST/GetPharmcyListBySKU"; -const GET_SPECIFICATION = "productspecification/"; -const GET_BRAND_ITEMS = "products"; +var GET_WISHLIST = "shopping_cart_items/"; +var DELETE_WISHLIST = "delete_shopping_cart_item_by_product?customer_id="; +var GET_REVIEW = "customerreviews/"; +var GET_BRANDS = "manufacturer"; +var GET_TOP_BRANDS = "topmanufacturer?page=1&limit=8"; +var GET_PRODUCT_DETAIL = "products/"; +var GET_LOCATION = "Services/Patients.svc/REST/GetPharmcyListBySKU"; +var GET_SPECIFICATION = "productspecification/"; +var GET_BRAND_ITEMS = "products"; +var PHARMACY_MAKE_REVIEW = 'insertreviews'; // External API -const ADD_ADDRESS_INFO = "addcustomeraddress"; -const GET_CUSTOMER_ADDRESSES = "Customers/"; -const GET_CUSTOMER_INFO = "VerifyCustomer"; +var ADD_ADDRESS_INFO = "addcustomeraddress"; +var GET_CUSTOMER_ADDRESSES = "Customers/"; +var GET_CUSTOMER_INFO = "VerifyCustomer"; //Pharmacy -const GET_PHARMACY_CATEGORISE = - 'categories?fields=id,name,namen,description,image,localized_names,display_order,parent_category_id,is_leaf&parent_id=0'; -const GET_OFFERS_CATEGORISE = 'discountcategories'; -const GET_OFFERS_PRODUCTS = 'offerproducts/'; -const GET_CATEGORISE_PARENT = - 'categories?fields=id,name,namen,description,image,localized_names,display_order,parent_category_id,is_leaf&parent_id='; -const GET_PARENT_PRODUCTS = 'products?categoryid='; -const GET_SUB_CATEGORISE = - 'categories?fields=id,name,namen,description,image,localized_names,display_order,parent_category_id,is_leaf&parent_id='; -const GET_SUB_PRODUCTS = 'products?categoryid='; -const GET_FINAL_PRODUCTS = +var GET_PHARMACY_CATEGORISE = 'categories?fields=id,name,namen,description,image,localized_names,display_order,parent_category_id,is_leaf&parent_id=0'; +var GET_OFFERS_CATEGORISE = 'discountcategories'; +var GET_OFFERS_PRODUCTS = 'offerproducts/'; +var GET_CATEGORISE_PARENT = 'categories?fields=id,name,namen,description,image,localized_names,display_order,parent_category_id,is_leaf&parent_id='; +var GET_PARENT_PRODUCTS = 'products?categoryid='; +var GET_SUB_CATEGORISE = 'categories?fields=id,name,namen,description,image,localized_names,display_order,parent_category_id,is_leaf&parent_id='; +var GET_SUB_PRODUCTS = 'products?categoryid='; +var GET_FINAL_PRODUCTS = 'products?fields=id,reviews,discount_ids,name,namen,localized_names,display_order,short_description,full_description,full_descriptionn,sku,order_minimum_quantity,order_maximum_quantity,price,old_price,images,is_rx,rx_message,rx_messagen,discount_name,discount_namen,approved_rating_sum,approved_total_reviews,allow_back_in_stock_subscriptions,stock_quantity,stock_availability,stock_availabilityn,discount_percentage&CategoryId='; -const GET_CLINIC_CATEGORY = 'Services/Doctors.svc/REST/DP_GetClinicCategory'; -const GET_DISEASE_BY_CLINIC_ID = - 'Services/Doctors.svc/REST/DP_GetDiseasesByClinicID'; -const SEARCH_DOCTOR_BY_TIME = 'Services/Doctors.svc/REST/SearchDoctorsByTime'; +var GET_CLINIC_CATEGORY = 'Services/Doctors.svc/REST/DP_GetClinicCategory'; +var GET_DISEASE_BY_CLINIC_ID = 'Services/Doctors.svc/REST/DP_GetDiseasesByClinicID'; +var SEARCH_DOCTOR_BY_TIME = 'Services/Doctors.svc/REST/SearchDoctorsByTime'; -const TIMER_MIN = 10; +var TIMER_MIN = 10; -const GOOGLE_API_KEY = "AIzaSyCmevVlr2Bh-c8W1VUzo8gt8JRY7n5PANw"; +var GOOGLE_API_KEY = "AIzaSyCmevVlr2Bh-c8W1VUzo8gt8JRY7n5PANw"; -const GET_BRANDS_LIST = 'categoryManufacturer?categoryids='; +var GET_BRANDS_LIST = 'categoryManufacturer?categoryids='; -const GET_SEARCH_PRODUCTS = +var GET_SEARCH_PRODUCTS = 'searchproducts?fields=id,discount_ids,reviews,name,namen,localized_names,display_order,short_description,full_description,full_descriptionn,sku,order_minimum_quantity,order_maximum_quantity,price,old_price,images,is_rx,rx_message,rx_messagen,discount_name,discount_namen,approved_rating_sum,approved_total_reviews,allow_back_in_stock_subscriptions,stock_quantity,stock_availability,stock_availabilityn,discount_percentage&search_key='; -const SCAN_QR_CODE = 'productbysku/'; +var SCAN_QR_CODE = 'productbysku/'; + +var FILTERED_PRODUCTS = 'products?categoryids='; + +var GET_DOCTOR_LIST_CALCULATION = "Services/Doctors.svc/REST/GetCallculationDoctors"; + +var GET_ALL_APPOINTMENTS_FOR_DENTAL_CLINIC = "Services/Patients.svc/REST/GetDentalAppointments"; + +var GET_DENTAL_APPOINTMENT_INVOICE = "Services/Patients.svc/REST/HIS_eInvoiceForDentalByAppointmentNo"; + +var SEND_DENTAL_APPOINTMENT_INVOICE_EMAIL = "Services/Notifications.svc/REST/SendInvoiceForDental"; + +var GET_TAMARA_PLAN = 'https://mdlaboratories.com/tamaralive/Home/GetInstallments'; + +var GET_TAMARA_PAYMENT_STATUS = 'https://mdlaboratories.com/tamaralive/api/OnlineTamara/order_status?orderid='; + +var UPDATE_TAMARA_STATUS = 'Services/PayFort_Serv.svc/REST/Tamara_UpdateRequestStatus'; + +var MARK_APPOINTMENT_TAMARA_STATUS = 'Services/Patients.svc/REST/MarkAppointmentForTamaraPayment_FromVida'; + +var AUTO_GENERATE_INVOICE_TAMARA = 'Services/PayFort_Serv.svc/REST/Tamara_GetinfoByAppointmentNo_AutoGenerateInvoice'; + +var GET_ONESIGNAL_VOIP_TOKEN = 'https://onesignal.com/api/v1/players'; + +var CANCEL_PHARMA_LIVECARE_REQUEST = 'https://vcallapi.hmg.com/api/PharmaLiveCare/SendPaymentStatus'; + +var INSERT_FREE_SLOTS_LOGS = 'Services/Doctors.svc/Rest/InsertDoctorFreeSlotsLogs'; + +var GET_NATIONALITY = 'Services/Lists.svc/REST/GetNationality'; + +var PAYFORT_TEST_URL = 'https://sbpaymentservices.payfort.com/FortAPI/paymentApi'; +var PAYFORT_PROD_URL = 'https://paymentservices.payfort.com/FortAPI/paymentApi'; + +// Check If InPatient API +var CHECK_IF_INPATIENT = 'Services/Patients.svc/REST/GetInPatientAdmissionInfo'; + +var CHECK_IF_PATIENT_ADMITTED = 'Services/Inps.svc/REST/checkIsPatientAdmittedOrAdmissionRequest'; -const FILTERED_PRODUCTS = 'products?categoryids='; +// Get General Instructions API +var GET_GENERAL_INSTRUCTIONS = 'Services/INPs.svc/REST/getGeneralInstructions'; + +// Get Medical Instructions API +var GET_MEDICAL_INSTRUCTIONS = 'Services/INPs.svc/REST/getPatientAdmissionRequest'; + +var GET_INPATIENT_ADVANCE_PAYMENT_REQUESTS = 'Services/INPs.svc/REST/getInpatientAdvancePendingPayment'; + +var GET_INPATIENT_PAID_ADVANCE_PAYMENT = 'Services/INPs.svc/REST/getInpatientAdvanceHistory'; + +var GET_INPATIENT_ADVANCE_PAYMENT_LINK = 'Services/PayFort_Serv.svc/REST/InsertInPatientAdvanceDetails'; + +var INSERT_INPATIENT_ORDER = 'Services/INPs.svc/REST/Inpcp_insertOrder'; + +var INPATIENT_DISCHARGE_MEDICATIONS = 'Services/INPs.svc/REST/chekPatientHasDischargeMedicine'; + +var GET_BIRTH_NOTIFICATION = 'Services/INPs.svc/REST/getBirthNotification_bymothermrn'; + +var SAVE_BIRTH_NOTIFICATION = 'Services/INPs.svc/REST/SaveBirthNotification'; + +var INSERT_GENERAL_ADMISSION_CONSENT = 'Services/INPs.svc/REST/Inp_insertAAForGeneralAdmissionConsent'; + +//Meal Plan APIs +var GET_ADMITTED_PATIENTS = 'Services/MOP.svc/REST/GetAdmittedPatients'; +var GET_CURRENT_WEEKID_WEEKDAY = 'Services/MOP.svc/REST/GetCurrentWeekAndDayHMGMP'; +var GET_MEALS_OF_SCHEDULE_ID = 'Services/MOP.svc/REST/GetMealsOfScheduleID_Mobile'; +var GET_MEAL_ITEMS_OF_SCHEDULE_ID = 'Services/MOP.svc/REST/GetDefaultItemsOfScheduleID'; +var PLACE_MEAL_PLAN_ORDER = 'Services/MOP.svc/REST/UpdateOrMakeNewOrder'; + +var CHECK_PATIENT_NPHIES_ELIGIBILITY = 'Services/Doctors.svc/REST/checkPatientInsuranceCompanyValidity'; +var CONVERT_PATIENT_TO_CASH = 'Services/Doctors.svc/REST/deActivateInsuranceCompany'; + +var GET_BLOOD_DONATION_PROJECTS_LIST = 'Services/OUTPs.svc/REST/BD_getProjectsHaveBDClinics'; + +var GET_BLOOD_DONATION_FREE_SLOTS = 'Services/OUTPs.svc/REST/BD_GetFreeSlots'; + +var GET_WE_CARE_TOUR_URL = 'Services/Consent.svc/Rest/Consent_VirtualJurny_Url_GetByProjectID'; + +var GET_DENTAL_INSTRUCTIONS = 'Services/OUTPs.svc/Rest/getProcedureNotification'; + +var INSERT_WALKIN_APPOINTMENT = "Services/Doctors.svc/REST/InsertWalkinAppointment"; + +//Usage Agreement APIs +var CHECK_USAGE_AGREEMENT = "Services/Patients.svc/REST/CheckForUsageAgreement"; +var GET_USAGE_AGREEMENT = "Services/Patients.svc/REST/GetUsageAgreementText"; +var ADD_USAGE_AGREEMENT = "Services/Patients.svc/REST/AddUsageAgreement"; + +var GET_ER_ONLINE_PAYMENT_DETAILS = 'Services/OUTPs.svc/Rest/Outp_GetPatientPaymentInformationForERClinic'; + +var AUTO_GENERATE_INVOICE_ER = 'Services/OUTPs.svc/Rest/Outp_AutoGenerateInvoiceForER'; + +var CHECK_IF_PATIENT_ARRIVED_ER_ONLINE_CHECKIN = 'Services/OUTPs.svc/Rest/IsPatientArrived'; + +var CHECK_PATIENT_ER_ADVANCE_BALANCE = 'Services/OUTPs.svc/Rest/getPatientAdvanceBalanceAmountByClinic'; + +var GET_PROJECT_FROM_NFC = 'Services/OUTPs.svc/Rest/GetProjectByNFC'; + +var GET_PATIENT_OCCUPATION_LIST = 'Services/Authentication.svc/REST/GetPatientOccupation'; + +var IS_DOCTOR_AVAILABLE_BY_CALENDAR_SCHEDULE = 'Services/OUTPs.svc/REST/HIS_IsDoctorAvailableByCalendarSchedule'; + +//PAYFORT +var getPayFortProjectDetails = "Services/PayFort_Serv.svc/REST/GetPayFortProjectDetails"; +var addPayFortApplePayResponse = "Services/PayFort_Serv.svc/REST/AddResponse"; +var payFortEnvironment = FortEnvironment.production; +var applePayMerchantId = "merchant.com.hmgwebservices"; +// var payFortEnvironment = FortEnvironment.test; +// var applePayMerchantId = "merchant.com.hmgwebservices.uat"; class AppGlobal { static var context; + static var projectViewModelContext; AppSharedPreferences sharedPref = AppSharedPreferences(); + static bool isNetworkDebugEnabled = false; + static String appLanguage = ""; + Request getPublicRequest() { Request request = new Request(); request.Channel = 3; @@ -602,7 +726,6 @@ class AppGlobal { request.generalid = GENERAL_ID; //'Cs2020@2016\$2958'; request.PatientOutSA = 0; request.SessionID = "wEVNbagIkaNhGECWZjHaA"; - request.TokenID = "@dm!n"; request.isDentalAllowedBackend = false; request.DeviceTypeID = Platform.isIOS ? 1 : 2; request.DeviceType = Platform.isIOS ? "iOS" : "Android"; diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 2987e621a..786baadc 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -2,49 +2,28 @@ // Used for Native through Platform Method Channel // --------- - -- - - - - - - - - ---------------- const Map platformLocalizedValues = { - "errorConnectingHmgNetwork": { - "en": "Sorry you are not connecting to HMG network", - "ar": "نعتذر لست متصل في شكبة مستشفى د.سليمان الحبيب" - }, - "successConnectingHmgNetwork": { - "en": "You connected to HMG network successfully, you can access the app", - "ar": - "تم التصال بشبكة د.سليمان الحبيب بنجاح, تستطيع الان استخدام تطبيق الحبيب" - }, + "errorConnectingHmgNetwork": {"en": "Sorry you are not connecting to HMG network", "ar": "نعتذر لست متصل في شكبة مستشفى د.سليمان الحبيب"}, + "successConnectingHmgNetwork": {"en": "You connected to HMG network successfully, you can access the app", "ar": "تم التصال بشبكة د.سليمان الحبيب بنجاح, تستطيع الان استخدام تطبيق الحبيب"}, "failedConnectingHmgNetwork": { - "en": - "Sorry the connection to HMG network had been failed, make sure you are in range of HMG network", - "ar": - "نعتذر لقد فشل الاتصال بشبكة د.سليمان الحبيب, تاكد من وجودك داخل نطاق الشبكة" - }, - "alreadyConnectedHmgNetwork": { - "en": " You already connected to HMG network to access Alhabib app", - "ar": "انت متصل مسبقاً بالشبكة تستطيع استخدام تطبيق الحبيب" - }, - "somethingWentWrong": { - "en": "Sorry something went wrong please try again later", - "ar": "نعتذر لخدمتكم يرجى المحاولة لاحقا" + "en": "Sorry the connection to HMG network had been failed, make sure you are in range of HMG network", + "ar": "نعتذر لقد فشل الاتصال بشبكة د.سليمان الحبيب, تاكد من وجودك داخل نطاق الشبكة" }, + "alreadyConnectedHmgNetwork": {"en": " You already connected to HMG network to access Alhabib app", "ar": "انت متصل مسبقاً بالشبكة تستطيع استخدام تطبيق الحبيب"}, + "somethingWentWrong": {"en": "Sorry something went wrong please try again later", "ar": "نعتذر لخدمتكم يرجى المحاولة لاحقا"}, "enablingWifi": {"en": "Enabling wifi...", "ar": "Enabling wifi..."}, - "connectedHmgNetworkWithInternet": { - "en": "Successfully connected to the HMG network to access internet", - "ar": "Successfully connected to the HMG network to access internet" - }, + "connectedHmgNetworkWithInternet": {"en": "Successfully connected to the HMG network to access internet", "ar": "Successfully connected to the HMG network to access internet"}, "connectedToHmgNetworkWithNoInternet": { - "en": - "Successfully connected to the HMG network but it have no internet access", - "ar": - "Successfully connected to the HMG network but it have no internet access" + "en": "Successfully connected to the HMG network but it have no internet access", + "ar": "Successfully connected to the HMG network but it have no internet access" }, "notConnectedToHmgNetworkSecurityIssue": { - "en": - "We are not able to connect you to HMG network due to security reasons", - "ar": - "We are not able to connect you to HMG network due to security reasons" + "en": "We are not able to connect you to HMG network due to security reasons", + "ar": "We are not able to connect you to HMG network due to security reasons" } }; const Map localizedValues = { + 'kilometerUnit': {'en': 'KM', 'ar': 'كيلومتر'}, 'dashboardScreenToolbarTitle': {'ar': 'الرئيسة', 'en': 'Home'}, 'settings': {'en': 'Settings', 'ar': 'الاعدادات'}, 'language': {'en': 'App Language', 'ar': 'لغة التطبيق'}, @@ -61,42 +40,47 @@ const Map localizedValues = { 'bookAppo': {'en': 'Book Appointment', 'ar': 'حجز موعد'}, 'searchBy': {'en': 'Search By:', 'ar': 'البحث عن طريق:'}, 'clinic': {'en': 'Clinic', 'ar': 'العيادة'}, + 'by-clinic': {'en': 'By Clinic', 'ar': 'العيادة'}, 'hospital': {'en': 'Hospital', 'ar': 'المستشفى'}, + 'by-hospital': {'en': 'By Hospital', 'ar': 'المستشفى'}, 'name': {'en': 'Name', 'ar': 'الإسم'}, 'doctor': {'en': 'Doctor', 'ar': 'الطبيب'}, 'clinicName': {'en': 'Clinic Name', 'ar': 'اسم العيادة'}, + 'hospitalName': {'en': 'Hospital Name', 'ar': 'اسم المستشفى'}, + 'NoClinicFound': {'en': 'No Clinic Found', 'ar': 'لم يتم العثور على عيادة'}, 'doctorName': {'en': 'Doctor Name', 'ar': 'إسم الطبيب'}, - 'nearestAppo': {'en': 'Nearest appointment', 'ar': 'أقرب موعد'}, - 'searchByDocText': { - 'en': 'Type the name of the doctor to help you find him', - 'ar': 'اكتب اسم الطبيب لمساعدتك في العثور عليه' - }, + 'nearestAppo': {'en': 'Nearest Appointment', 'ar': 'أقرب موعد'}, + 'searchByDocText': {'en': 'Type the name of the doctor to help you find him', 'ar': 'اكتب اسم الطبيب لمساعدتك في العثور عليه'}, 'enterDocName': {'en': 'Enter Doctor name', 'ar': 'أدخل إسم الطبيب'}, 'search': {'en': 'Search', 'ar': 'بحث'}, - 'bookNow': {'en': 'BOOK NOW', 'ar': 'احجز الآن'}, + 'noResultFound': {'en': 'No Result Found', 'ar': 'لم يتم العثور على نتائج '}, + 'noSearchResultFound': {'en': 'No Result Found', 'ar': 'لم يتم العثور على نتائج الرجاء تغيير لغة البحث'}, + 'pleaseEnterProductName': {'en': 'Please Enter Product Name', 'ar': 'ادخل اسم المنتج'}, + 'bookNow': {'en': 'Book Now', 'ar': 'احجز الآن'}, 'docInfo': {'en': 'Doctor Information', 'ar': 'معلومات الطبيب'}, 'appoInfo': {'en': 'Appointment Information', 'ar': 'معلومات الموعد'}, 'availableAppo': {'en': 'Available Appointments', 'ar': 'المواعيد المتاحة'}, 'gender': {'en': 'Gender', 'ar': 'الجنس'}, 'nationality': {'en': 'Nationality', 'ar': 'الجنسية'}, + 'neverWait': {'en': 'Never wait in queue', 'ar': 'لا تنتظر في قائمة الانتظار'}, + 'reminderTitle': {'en': 'You have appointment with Dr. ', 'ar': 'لديك موعد مع د'}, + 'appointmentCalendar': {'en': 'Would you like to set a reminder for this appointment in your calendar?', 'ar': 'هل ترغب في إضافة تذكير لهذا الموعد في التقويم الخاص بك؟'}, + 'appointmentSuccess': {'en': 'Appointment is successfully booked', 'ar': 'تم حجز الموعد بنجاح'}, 'docQualifications': {'en': 'Doctor Qualifications', 'ar': 'مؤهلات الطبيب'}, - 'confirmAppoHeading': { - 'en': 'Kindly confirm your Appointment', - 'ar': 'يرجى تأكيد موعدك' - }, - 'patientInfo': {'en': 'Patient Information', 'ar': 'معلومات المريض'}, + 'pressAgain': {'en': 'Press again to exit the app', 'ar': 'اضغط مرة أخرى للخروج من التطبيق'}, + 'laserMaxLimitReach': {'en': "Maximum limit is 90 minutes", 'ar': "الحد الأقصى هو 90 دقيقة"}, + 'confirmAppoHeading': {'en': 'Kindly review your Appointment', 'ar': 'يرجى تأكيد موعدك'}, + 'patientInfo': {'en': 'Patient Information', 'ar': 'معلومات المراجع'}, + 'doctorFilter': {'en': 'Doctors will be filtered based on your gender and age', 'ar': 'سيتم تصفية الأطباء بناءً على جنسك وعمرك'}, 'bookSuccess': {'en': 'Book Success', 'ar': 'تم حجز الموعد بنجاح'}, - 'patientShare': {'en': 'Patient Share', 'ar': 'المبلغ المستحق'}, - 'patientShareWithTax': { - 'en': 'Patient Share with Tax', - 'ar': 'المبلغ الإجمالي المستحق' - }, + 'patientShare': {'en': 'Patient Share', 'ar': 'نسبة العميل'}, + 'patientShareWithTax': {'en': 'Patient Share with Tax', 'ar': 'المبلغ الإجمالي المستحق مع الضريبة'}, 'confirmAppo': {'en': 'Confirm Appointment', 'ar': 'تأكيد الموعد'}, 'confirm': {'en': 'Confirm', 'ar': 'تأكيد'}, 'confirmLiveCare': {'en': 'Confirm LiveCare', 'ar': 'تأكيد لايف كير'}, 'waitingForDoctor': {'en': 'Waiting for doctor', 'ar': 'في انتظار الطبيب'}, 'appointment': {'en': 'Appointment', 'ar': 'الموعد'}, - 'confirmLater': {'en': 'Confirm Later', 'ar': 'تأكيد لاحقا'}, + 'confirmLater': {'en': 'Confirm Later', 'ar': 'التاكيد لاحقا'}, 'todoList': {'en': 'Todo List', 'ar': 'مهامي'}, 'appoActions': {'en': 'Appointment Actions', 'ar': 'إجراءات الموعد'}, 'date': {'en': 'Date', 'ar': 'التاريخ'}, @@ -107,46 +91,18 @@ const Map localizedValues = { 'instruction': {'en': 'Instructions', 'ar': 'تعليمات'}, 'livecare': {'en': 'LiveCare', 'ar': 'لايف كير'}, 'livecareAppo': {'en': 'LiveCare Appointment', 'ar': 'الموعد لايف كير'}, - 'cancelAppoMsg': { - 'en': 'Are you sure you want to cancel this appointment?', - 'ar': 'هل أنت متأكد أنك تريد إلغاء هذا الموعد؟' - }, - - 'upcoming-noAction': { - 'en': 'No Action Required', - 'ar': 'لا يوجد إجراء مطلوب' - }, - 'upcoming-confirm': { - 'en': 'Please confirm the appointment to avoid cancellation', - 'ar': 'يرجى تأكيد الموعد لتفادي الإلغاء' - }, - "book-success-confirm-more-24-1-2": { - "en": - "The online payment process will be available 24 hours before the appointment.", - "ar": "- عملية الدفع الالكتروني ستكون متاحة قبل الموعد ب 24 ساعة." - }, - 'upcoming-payment-pending': { - 'en': - 'Online Payment will be Activated before 24 Hours of Appointment Time', - 'ar': 'سيتم تفعيل خدمة الدفع الالكتروني قبل 24 ساعة من موعد الحجز' - }, - 'upcoming-payment-now': { - 'en': 'Pay Online now to avoid long waiting queue', - 'ar': 'ادفع الآن لتفادي الانتظار' - }, - 'upcoming-QR': { - 'en': 'Use the QR Code to Check-In in hospital', - 'ar': 'استخدم الرمز لتسجيل الحضور في المستشفى' - }, - 'upcoming-virtual': { - 'en': - 'This is a virtual appointment, Please adhere to the instructions for a seamless experience.', - 'ar': 'هذا موعد اتصال مرئي عن بعد ، يرجى اتباع تعليمات الخدمة.' - }, - 'upcoming-livecare': { - 'en': 'This is a LiveCare appointment', - 'ar': 'هذا موعد لايف كير' - }, + 'agreeTo': {'en': 'I agree to the', 'ar': 'أوافق على'}, + 'termsConditoins': {'en': 'Terms and Conditions', 'ar': 'الأحكام والشروط'}, + 'cancelAppoMsg': {'en': 'Are you sure you want to cancel this appointment?', 'ar': 'هل أنت متأكد أنك تريد إلغاء هذا الموعد؟'}, + 'changePayment': {'en': 'Change Payment Method', 'ar': 'تغيير آلية الدفع'}, + 'upcoming-noAction': {'en': 'No Action Required', 'ar': 'لا يلزم اتخاذ أي إجراء'}, + 'upcoming-confirm': {'en': 'Please confirm the appointment to avoid cancellation', 'ar': 'يرجى تأكيد الموعد لتفادي الإلغاء'}, + "book-success-confirm-more-24-1-2": {"en": "The online payment process will be available 24 hours before the appointment.", "ar": "عملية الدفع الالكتروني ستكون متاحة قبل الموعد ب 24 ساعة."}, + 'upcoming-payment-pending': {'en': 'Online Payment will be Activated before 24 Hours of Appointment Time', 'ar': 'سيتم تفعيل خدمة الدفع الالكتروني قبل 24 ساعة من موعد الحجز'}, + 'upcoming-payment-now': {'en': 'Pay Online now to avoid long waiting queue', 'ar': 'ادفع الآن لتفادي طابور الانتظار'}, + 'upcoming-QR': {'en': 'Use the QR Code to Check-In in hospital', 'ar': 'استخدم الرمز لتسجيل الحضور بشكل آلي في المستشفى'}, + 'upcoming-virtual': {'en': 'This is a virtual appointment, Please adhere to the instructions for a seamless experience.', 'ar': 'هذا موعد اتصال مرئي عن بعد ، يرجى اتباع تعليمات الخدمة.'}, + 'upcoming-livecare': {'en': 'This is a LiveCare appointment', 'ar': 'هذا موعد لايف كير'}, 'upcoming-details': {'en': 'More Details', 'ar': 'المزيد'}, 'reschedule': {'en': 'Reschedule', 'ar': 'إعادة جدولة'}, 'raise': {'en': 'Raise', 'ar': 'رفع'}, @@ -154,98 +110,63 @@ const Map localizedValues = { 'add': {'en': 'Add', 'ar': 'إضافة'}, 'reminder': {'en': 'Reminder', 'ar': 'تذكير'}, 'location': {'en': 'Locations', 'ar': 'مواقعنا'}, - 'online': {'en': 'Online', 'ar': 'الالكترونية'}, - 'payment': {'en': 'Payment', 'ar': 'الدفع'}, + 'online': {'en': 'Online', 'ar': 'الدفع'}, + 'payment': {'en': 'Payment', 'ar': 'الالكتروني'}, + 'onlinePayment': {'en': 'Online', 'ar': 'الدفع'}, + 'onlinePaymentSubtitle': {'en': 'Payment', 'ar': 'الالكتروني'}, 'cancel-nocaps': {'en': 'Cancel', 'ar': 'الغاء'}, - 'set-reminder': {'en': 'Set Reminder', 'ar': 'تعيين تذكير'}, - - 'login': {'en': 'Login', 'ar': 'تسجيل الدخول'}, - 'loginregister': {'en': 'Login / Register', 'ar': 'تسجيل الدخول'}, - 'poweredBy': {'en': 'Powered By', 'ar': 'مشغل بواسطة'}, - "welcome": {"en": "Welcome", "ar": "مرحبا"}, - "welcome_text": { - "en": "Dr. Sulaiman Al Habib Mobile Application", - "ar": "الدكتور سليمان الحبيب لتطبيقات الهاتف المتحرك" - }, - 'welcome_text2': { - 'en': 'Have you visited AlHabib Medical Group before? ', - 'ar': 'هل قمت بزيارة مجموعة الحبيب الطبية من قبل؟' - }, + 'set-reminder': {'en': 'Set Reminder', 'ar': 'إضافة تذكير'}, + "national-id-number": {"en": "National ID Number", "ar": "رقم الهوية الوطنية / الاقامة"}, + "medical-file-number": {"en": "Medical File Number", "ar": "رقم الملف الطبي"}, + 'login': {'en': 'Login', 'ar': 'دخول'}, + 'loginregister': {'en': 'Login / Register', 'ar': 'دخول/ تسجيل'}, + 'poweredBy': {'en': 'Powered by', 'ar': 'مشغل بواسطة'}, + "welcome": {"en": "Welcome", "ar": "مرحبا بكم"}, + "welcome-to": {"en": "Welcome to", "ar": "مرحبا بك في"}, + "patient-app": {"en": "Patient App", "ar": "تطبيق المراجعين"}, + "welcome_text": {"en": "Dr. Sulaiman Al Habib Mobile Application", "ar": "الدكتور سليمان الحبيب لتطبيقات الهاتف"}, + "dr-sulaiman-text": {"en": "Dr. Sulaiman Al Habib", "ar": "د. سليمان الحبيب"}, + 'welcome_text2': {'en': 'Have you previously visited the hospitals or medical centers of Dr. Sulaiman Al Habib?', 'ar': 'هل قمت مسبقا بزيارة مستشفيات او مراكز الدكتور سليمان الحبيب الطبية ؟'}, 'yes': {'en': 'Yes', 'ar': 'نعم'}, 'no': {'en': 'No', 'ar': 'لا'}, - "logintyperadio": { - "en": "Choose from below options to login to your medical file.", - "ar": "اختر من الخيارات أدناه لتسجيل الدخول إلى ملفك الطبي." - }, - "registernow": {"en": "Register Now", "ar": "تسجيل الان"}, - "nationalID": { - "en": "Enter the Identification Number", - "ar": "أدخل رقم الهوية الوطنية او الاقامة" - }, + "logintyperadio": {"en": " Choose from the below options to login to your medical file.", "ar": " اختر احدى الخيارات أدناه لتسجيل الدخول إلى ملفك الطبي "}, + "registernow": {"en": "Register Now", "ar": "سجل الان"}, + "nationalID": {"en": "Enter the Identification Number", "ar": "أدخل رقم الهوية الوطنية او الاقامة"}, "national-id": {"en": "National ID", "ar": "رقم الهوية"}, "fileNo": {"en": "File Number", "ar": "رقم الملف"}, "fileno": {"en": "File No", "ar": "رقم الملف"}, "forgotFileNo": {"en": "Forgot file Number?", "ar": "نسيت رقم الملف الطبي؟"}, - "forgotFileNoTitle": { - "en": "Forgot medical file Number", - "ar": "نسيت رقم الملف" - }, - - "enter-national-id": { - "en": "Please enter mobile number and identification number", - "ar": "الرجاء إدخال رقم الجوال ورقم الهوية" - }, - "profile-info": { - "en": "Please enter profile information", - "ar": "الرجاء إدخال معلومات الملف الشخصي" - }, + "forgotFileNoTitle": {"en": "Forgot medical file", "ar": "نسيت رقم الملف الطبي"}, + "enter-national-id": {"en": "Please enter mobile number and identification number", "ar": "الرجاء إدخال رقم الجوال ورقم الهوية"}, + "profile-info": {"en": "Please enter profile information", "ar": "الرجاء إدخال معلومات الملف الشخصي"}, "submit": {"en": "Submit", "ar": "ارسال"}, - "forgot-desc": { - "en": "Enter the mobile number to receive the Medical file Number via SMS", - "ar": "أدخل رقم الجوال المسجل لاستلام رقم الملف عن طريق الرسائل النصية" - }, + "forgot-desc": {"en": "Enter the mobile number to receive the Medical File Number via SMS", "ar": "أدخل رقم الجوال المسجل لاستلام رقم الملف عن طريق الرسائل النصية"}, "dob": {"en": "Birth Date:", "ar": "تاريخ الميلاد"}, "hijri-date": {"en": "Hijri Date", "ar": "التاريخ الهجري"}, "gregorian-date": {"en": "Gregorian Date", "ar": "التاريخ الميلادي"}, - "verify-login-with": { - "en": "Please choose one of the following options to verify", - "ar": "الرجاء اختيار احدى الخيارات التالية للتحقق من البيانات" - }, + "verify-login-with": {"en": "Please choose one of the following options to verify", "ar": "الرجاء اختيار احدى الخيارات التالية للتحقق من البيانات"}, "register-user": {"en": "Register", "ar": "تسجيل"}, "verify-with-fingerprint": {"en": "Fingerprint", "ar": "بصمة"}, "verify-with-faceid": {"en": "Face ID", "ar": "معرف الوجه"}, "verify-with-sms": {"en": "SMS", "ar": "الرسائل القصيرة"}, "verify-with-whatsapp": {"en": "Whatsapp", "ar": " الواتس اب"}, + "verify-through": {"en": "Verify Through", "ar": " تحقق من خلال"}, "last-login": {"en": "LAST LOGIN AT:", "ar": "آخر تسجيل دخول"}, - "last-login-with": {"en": "VERIFICATION TYPE:", "ar": "نوع التحقق:"}, + "last-login-with": {"en": "VERIFICATION TYPE:", "ar": "طريقة التحقق:"}, "verify-fingerprint": { - "en": - "To activate the fingerprint login service, please verify data by using one of the following options.", - "ar": - "لتفعيل خدمة الدخول بالبصمة، يرجى اختيار احدى القنوات التالية للتحقق من البيانات" + "en": "To activate the fingerprint login service, please verify data by using one of the following options.", + "ar": "لتفعيل خدمة الدخول بالبصمة، يرجى اختيار احدى القنوات التالية للتحقق من البيانات" }, 'searchMedicine': {'en': 'Search Medicine', 'ar': 'البحث عن الدواء'}, - 'pharmaciesList': {'en': 'Pharmacies List', 'ar': 'قائمة الصيدلايات'}, - 'searchMedicineHere': { - 'en': 'Search Medicine Here', - 'ar': 'ابحث عن الدواء هنا' - }, + 'pharmaciesList': {'en': 'Pharmacies List', 'ar': 'قائمة الصيدليات'}, + 'searchMedicineHere': {'en': 'Search Medicine Here', 'ar': 'ابحث عن الدواء هنا'}, 'description': {'en': 'Description', 'ar': 'الوصف'}, 'howToUse': {'en': 'How to Use', 'ar': 'طريقة الأستخدام'}, 'price': {'en': 'Price', 'ar': 'السعر'}, - 'youCanFindItIn': {'en': 'You can find it in', 'ar': 'يمكنكة ان تجده في'}, - 'pleaseEnterMedicineName': { - 'en': 'Please Enter Medicine Name', - 'ar': 'الرجائ ادخال اسم الدواء' - }, - "verification_message": { - "en": "Please enter the Verification Code sent to", - "ar": "الرجاء ادخال رمز التحقق الذي تم إرساله إلى" - }, - "validation_message": { - "en": "The verification code expires in", - "ar": "تنتهي صلاحية رمز التحقق خلال" - }, + 'youCanFindItIn': {'en': 'You can find it in', 'ar': 'يمكنك ان تجده في'}, + 'pleaseEnterMedicineName': {'en': 'Please Enter Medicine Name', 'ar': 'الرجاء ادخال اسم الدواء'}, + "verification_message": {"en": "Please enter the Verification Code sent to", "ar": "الرجاء ادخال رمز التحقق الذي تم إرساله إلى"}, + "validation_message": {"en": "The verification code expires in", "ar": "تنتهي صلاحية رمز التحقق خلال"}, "arabic-change": {"en": "عربي", "ar": "English"}, "notification": {"en": "Notifications", "ar": "إشعارات"}, "app-settings": {"en": "App Settings", "ar": "إعدادات التطبيق"}, @@ -253,85 +174,39 @@ const Map localizedValues = { "before": {"en": "Before", "ar": "قبل"}, "minute": {"en": "Minutes", "ar": "دقيقة"}, "hour": {"en": "Hour", "ar": "ساعة"}, - "reminderSuccess": { - "en": "The reminder has been added successfully", - "ar": "يضاف التذكير بنجاح" - }, - "patientShareToDo": { - "en": "Amount before tax: ", - "ar": "المبلغ قبل الضريبة:" - }, + "reminderSuccess": {"en": "The reminder has been added successfully", "ar": "تمت إضافة التذكير بنجاح"}, + "reminderCancelSuccess": {"en": "The reminder has been cancelled successfully", "ar": "تم إلغاء التذكير بنجاح"}, + "patientShareToDo": {"en": "Amount before tax: ", "ar": "المبلغ قبل الضريبة:"}, "patientTaxToDo": {"en": "Tax amount: ", "ar": "قيمة الضريبة:"}, - "patientShareTotalToDo": { - "en": "Total amount Due: ", - "ar": "المبلغ الإجمالي المستحق:" - }, + "patientShareTotalToDo": {"en": "Total amount due: ", "ar": "المبلغ الإجمالي المستحق:"}, 'paymentMethod': {'en': 'Payment Method', 'ar': 'طريقة الدفع او السداد'}, - 'noNeedToWaitInLine': { - 'en': 'No need to stand in line.', - 'ar': 'لا داعي للوقوف في الطابور.' - }, - 'useQRAppoAttend': { - 'en': 'Use the QR code to register the appointment attendance.', - 'ar': 'استخدم الكود لتسجيل الحضور في المستشفى.' - }, - 'passQRAppoAttend': { - 'en': - 'Pass the QR code through the attendance devices available in the Hospital.', - 'ar': 'تمرير الكود من خلال اجهزة تسجيل الحضور المتوفرة في الفرع.' - }, - 'sitWaitingQR': { - 'en': 'Sit in the waiting rooms until called by the nurse.', - 'ar': 'الجلوس في غرف الانتظار لحين منادتك من قبل الممرضة.' - }, - 'attendRegisterCode': { - 'en': 'Attendance registration code', - 'ar': 'رمز تسجيل الحضور' - }, + 'noNeedToWaitInLine': {'en': 'No need to stand in line.', 'ar': 'لا داعي للوقوف في الطابور.'}, + 'useQRAppoAttend': {'en': 'Use the QR code to register the appointment attendance.', 'ar': 'استخدم الكود لتسجيل الحضور في المستشفى.'}, + 'passQRAppoAttend': {'en': 'Pass the QR code through the attendance devices available in the Hospital.', 'ar': 'تمرير الكود من خلال اجهزة تسجيل الحضور المتوفرة في الفرع.'}, + 'sitWaitingQR': {'en': 'Sit in the waiting rooms until called by the nurse.', 'ar': 'الجلوس في غرف الانتظار لحين منادتك من قبل الممرضة.'}, + 'attendRegisterCode': {'en': 'Attendance registration code', 'ar': 'رمز تسجيل الحضور'}, 'scanQRHospital': { - 'en': 'Scan above QR Code to Check-In on the Machine in Hospital', - 'ar': 'مسح فوق رمز الاستجابة السريعة للتحقق في الجهاز في المستشفى' + 'en': 'Approach the Online Check-In board in the hospital & scan via NFC or QR Code to Check-In', + 'ar': 'اقترب من لوحة تسجيل الوصول عبر الإنترنت في المستشفى وقم بالمسح الضوئي عبر NFC أو رمز الاستجابة السريعة لتسجيل الوصول' }, + 'scanNFC': {'en': 'Scan NFC to Check-In', 'ar': 'مسح NFC لتسجيل الوصول'}, "sendEmail": {"en": "Send Email", "ar": "ارسال نسخة"}, "success": {"en": "Done successfully", "ar": "تم تنفذ الطلب بنجاح"}, - "EmailSentSuccessfully": { - "en": "Email Sent Successfully", - "ar": "تم إرسال البريد الإلكتروني بنجاح" - }, - "EmailSentError": { - "en": "Error Sending Email", - "ar": "خطأ في إرسال البريد الإلكتروني" - }, + "EmailSentSuccessfully": {"en": "Email Sent Successfully", "ar": "تم إرسال البريد الإلكتروني بنجاح"}, + "EmailSentError": {"en": "Error Sending Email", "ar": "خطأ في إرسال البريد الإلكتروني"}, "close": {"en": "Close", "ar": "مغلق"}, + "closeIt": {"en": "Close", "ar": "اغلاق"}, "booked": {"en": "Booked", "ar": "محجوز"}, "confirmed": {"en": "Confirmed", "ar": "مؤكد"}, "arrived": {"en": "Arrived", "ar": "تم الحضور"}, - "payNowBookSuccess": { - "en": "Pay now via Al Habib App", - "ar": "ادفع الآن عبر تطبيق الحبيب" - }, - "payNowBookSuccesstext1": { - "en": "Pay Now using online payment service From secure payment gateways", - "ar": "ادفع الآن باستخدام خدمة الدفع عبر الإنترنت من بوابات الدفع الآمنة" - }, - "payNowBookSuccesstext2": { - "en": "You can also Pay Later via online payment Or in Hospital", - "ar": "يمكنك أيضًا الدفع لاحقًا عبر الدفع عبر الإنترنت أو في المستشفى" - }, + "payNowBookSuccess": {"en": "Pay now via Al Habib App", "ar": "ادفع الآن عبر تطبيق الحبيب"}, + "payNowBookSuccesstext1": {"en": "Pay Now using online payment service from secure payment gateways", "ar": " ادفع الآن من خلال خدمة الدفع الالكتروني الآمنة"}, + "payNowBookSuccesstext2": {"en": "You can also Pay Later via online payment or in Hospital", "ar": "يمكنك أيضًا الدفع لاحقًا عبر الدفع الالكتروني أو في المستشفى"}, 'payLater': {'en': 'Pay Later', 'ar': 'ادفع لاحقا'}, - 'askDocNotAllowed': { - 'en': 'This service will be available for last 15 days doctor Visit only', - 'ar': 'هذه الخدمة متاحة للزيارات خلال اخر 15 يوم فقط' - }, - "more-verify": { - "en": "More Verification Options", - "ar": "المزيد من خيارات التحقق" - }, + 'askDocNotAllowed': {'en': 'This service will be available for last 15 days’ doctor Visit only', 'ar': 'هذه الخدمة متاحة للزيارات خلال اخر 15 يوم فقط'}, + "more-verify": {"en": "More Verification Options", "ar": "المزيد من خيارات التحقق"}, "welcome-back": {"en": "Welcome back!", "ar": "مرحبا بعودتك!"}, - "account-info": { - "en": "Would you like to login with current username?", - "ar": "هل ترغب في تسجيل الدخول باسم المستخدم الحالي؟" - }, + "account-info": {"en": "Would you like to login with current username?", "ar": "هل ترغب في تسجيل الدخول باسم المستخدم الحالي؟"}, "another-acc": {"en": "Use Another Account", "ar": "استخدم حسابا آخر"}, "next": {"en": "Next", "ar": 'التالى'}, "first-name": {"en": "First Name", "ar": "الاسم الأول"}, @@ -339,13 +214,10 @@ const Map localizedValues = { "last-name": {"en": "Last Name", "ar": "إسم العائلة"}, "female": {"en": "Female", "ar": "أنثى"}, "male": {"en": "Male", "ar": "ذكر"}, - "preferred-language": {"en": "Preferred Language", "ar": "اللغة المفضلة"}, + "preferred-language": {"en": "Preferred Language *", "ar": "اللغة المفضلة *"}, "english": {"en": "English", "ar": "الإنجليزية"}, "arabic": {"en": "Arabic", "ar": "العربية"}, - "locations-register": { - "en": "Where do you want to create this file?", - "ar": "أين تريد فتح هذا الملف؟" - }, + "locations-register": {"en": "Where do you want to create this file?", "ar": "أين تريد فتح هذا الملف؟"}, "ksa": {"en": "KSA", "ar": "السعودية"}, "dubai": {"en": "Dubai", "ar": "دبي"}, "enter-email": {"en": "Please Enter Email", "ar": "ادخل البريد الالكتروني"}, @@ -368,180 +240,152 @@ const Map localizedValues = { 'heart': {'en': 'Heart Rate', 'ar': 'معدل النبض'}, "heightUnit": {"en": "height unit", "ar": "وحدة الطول"}, "weightUnit": {"en": "Weight Unit", "ar": "وحدة الوزن"}, + "unit": {"en": "Unit", "ar": "وحدة"}, "request": {"en": "Request", "ar": "طلبات الاضافة"}, "member-name": {"en": "Member Name", "ar": "اسم العضو"}, - "switch-login": {"en": "Switch User", "ar": "تغير المستخدم"}, + "switch-login": {"en": "Switch", "ar": "تغير "}, "remove-member": {"en": "Remove", "ar": "حذف"}, "allow-view": {"en": "Allow", "ar": "قبول"}, "reject-view": {"en": "Reject", "ar": "رفض"}, "delete-view": {"en": "Delete", "ar": "حذف"}, - // "my-family": {"en": "MY FAMILY", "ar": "عائلتي"}, + "my-family": {"en": "MY FAMILY", "ar": "عائلتي"}, "approvals": {"en": "Approvals", "ar": "موافقات التأمين"}, - "approvalNo": {"en": "Approval No.: ", "ar": "رقم الموافقة: "}, - "companyName": {"en": "Company Name ", "ar": "اسم الشركة: "}, - "receiptOn": {"en": "Receipt on: ", "ar": "تاريخ الفاتورة: "}, - "expiryDate": {"en": "Expiry Date: ", "ar": "تاريخ الانتهاء: "}, - "procedureName": {"en": "Procedure Name", "ar": "اسم الاجراء"}, + "approvalNo": {"en": "Approval No:", "ar": "رقم الموافقة: "}, + "companyName": {"en": "Company Name:", "ar": "اسم الشركة: "}, + "receiptOn": {"en": "Receipt on:", "ar": "تاريخ الفاتورة: "}, + "expiryDate": {"en": "Expiry Date:", "ar": "تاريخ الانتهاء: "}, + "expiryPoints": {"en": "Expired", "ar": " منتهية الصلاحية"}, + "expiryOn": {"en": "Expiry on:", "ar": "تاريخ الانتهاء: "}, + "procedureName": {"en": "Procedure Name:", "ar": "اسم الاجراء:"}, + "procedure": {"en": "Procedure", "ar": "اسم الاجراء:"}, "procedureStatus": {"en": "Procedure Status: ", "ar": "حالة الاجراء"}, - "usageStatus": {"en": "Usage Status", "ar": "جالة الاستخدام"}, - "unusedCount": {"en": "Unused Count: ", "ar": "غير مستخدم: "}, - "totalApproval": { - "en": "Total approval unused", - "ar": "اجمالي الموافقات الغير مستخدمة" - }, + "usageStatus": {"en": "Usage Status", "ar": "حالة الاستخدام"}, + "unusedCount": {"en": "Unused Count:", "ar": "غير مستخدم:"}, + "totalApproval": {"en": "Total approval unused", "ar": "اجمالي الموافقات الغير مستخدمة"}, "category": {"en": "Category: ", "ar": "الفئة"}, "expirationDate": {"en": "Expiration Date: ", "ar": "تاريخ الانتهاء"}, "patientCard": {"en": "Patient Card ID: ", "ar": "رقم الاشتراك"}, - "policyNumber": {"en": "Policy Number: ", "ar": "رقم بوليصة التاميت:"}, + "policyNumber": {"en": "Policy Number: ", "ar": "رقم بوليصة التامين:"}, "seeDetails": {"en": "SEE DETAILS", "ar": "منافعك التامينية"}, "insuranceCards": {"en": "Insurance Cards", "ar": "بطاقات التأمين"}, "requestType": {"en": "Request Type", "ar": "نوع الاستفسار"}, - "register-info-family": { - "en": "How would like to add the new member?", - "ar": "كيف ترغب باضافة العضو الجديد؟" - }, - "remove-family-member": { - "en": "Remove this member?", - "ar": "إزالة ملف العضو؟" - }, - "MyMedicalFile": {"en": "My Medical File", 'ar': 'ملف الطبي الالكتروني'}, - "myMedicalFileSubTitle": { - "en": "All your medical records", - 'ar': 'جميع سجلاتك الطبية' - }, - + "register-info-family": {"en": "How would like to add the new member?", "ar": "كيف ترغب باضافة العضو الجديد؟"}, + "remove-family-member": {"en": "Remove this member?", "ar": "إزالة ملف العضو؟"}, + "MyMedicalFile": {"en": "My Medical File", 'ar': 'الملف الطبي الالكتروني'}, + "myMedicalFileSubTitle": {"en": "All your medical records", 'ar': 'جميع سجلاتك الطبية'}, "viewMore": {"en": "View More", 'ar': 'عرض المزيد'}, - "homeHealthCareService": { - "en": "Home Health Care Service", - 'ar': 'الرعاية الصحية المنزلية' - }, - "OnlinePharmacy": {"en": "Online Pharmacy", 'ar': 'صيدليات الحبيب'}, + "homeHealthCareService": {"en": "Home Health Care Service", 'ar': 'الرعاية الصحية المنزلية'}, + "OnlinePharmacy": {"en": "Online Pharmacy", 'ar': 'الصيدلية الإلكترونية'}, "EmergencyService": {"en": "Emergency Service", 'ar': 'الفحص الطبي الشامل'}, - "OnlinePaymentService": { - "en": "Online Payment Service", - 'ar': 'خدمة الدفع الإلكتدوني' - }, - "OffersAndPackages": { - "en": "Online transfer request", - 'ar': 'طلب التحويل الالكتروني' - }, - "ComprehensiveMedicalCheckup": { - "en": "Comprehensive Medical Check up", - 'ar': 'فحص طبي شامل' - }, - "HMGService": {"en": "HMG Service", 'ar': 'جميع خدمات الحبيب'}, - "ViewAllHabibMedicalService": { - "en": "View All Habib Medical Service", - 'ar': 'عرض خدمات الحبيب الطبية' - }, + "OnlinePaymentService": {"en": "Online Payment Service", 'ar': 'خدمة الدفع الإلكتروني'}, + "OffersAndPackages": {"en": "Online transfer request", 'ar': 'طلب التحويل الالكتروني'}, + "ComprehensiveMedicalCheckup": {"en": "Comprehensive Medical Check-up", 'ar': 'فحص طبي شامل'}, + "HMGService": {"en": "HMG Service", 'ar': 'الخدمات الإلكترونية'}, + "ViewAllHabibMedicalService": {"en": "View All Habib Medical Service", 'ar': 'عرض خدمات الحبيب الطبية'}, "viewAll": {"en": "View All", 'ar': 'عرض الكل'}, "view": {"en": "View", 'ar': 'عرض'}, "ContactUs": {"en": "Contact Us", 'ar': 'الوصول إلينا'}, - "ViewAllWaysReachUs": { - "en": "View All Ways Reach Us", - 'ar': 'جميع طرق الاتصال بنا' + "contactUsLocation": { + "en": "P.O.Box: 91877 - Riyadh 11643, King Fahad Road - Olaya - Kingdom of Saudi Arabia", + 'ar': 'صندوق بريد: 91877 - الرياض 11643 ، طريق الملك فهد - العليا - المملكة العربية السعودية' + }, + "contactUsTime": { + "en": "Saturday - Wednesday 8:00 AM - 10 PM, Thursday 8:00 AM- 8:00 PM, Friday 2:00 PM - 8:00 PM", + 'ar': " السبت – الأربعاء 08:00 ص – 10:00 م , الخميس 08:00 ص – 08:00 م, الجمعة 02:00 م - 08:00 م" }, + "ViewAllWaysReachUs": {"en": "View All Ways Reach Us", 'ar': 'جميع طرق الاتصال بنا'}, "medicalProfile": {"en": "Medical Profile", 'ar': 'الملف الطبي'}, "consultation": {"en": "Consultation", "ar": "استشارة"}, "logs": {"en": "Logs", "ar": "السجلات"}, "textToSpeech": {"en": "How May I Help You?", "ar": "كيف يمكنني مساعدتك؟"}, "locationDialogMessage": { - "en": - "Allow the HMG app to access your location will assist you in showing the hospitals according to the nearest to you.", - "ar": - "السماح لتطبيق مجموعة الحبيب الطبية بالوصول إلى موقعك سيساعدك في إظهار المستشفيات وفقًا للأقرب إليك." - }, - - "user-view-requester": { - "en": "User Wants To View Your Medical File", - "ar": "أشخاص يرغبون الاطلاع على ملفك الطبي" + "en": "Allow the HMG app to access your location will assist you in showing the hospitals according to the nearest to you.", + "ar": "السماح لتطبيق مجموعة الحبيب الطبية بالوصول إلى موقعك سيساعدك في إظهار المستشفيات وفقًا للأقرب إليك." }, - "user-view": { - "en": "User Can View Your Medical File", - "ar": "أشخاص يمكنهم الاطلاع على ملفك الطبي" - }, - + "user-view-requester": {"en": "User Wants to View Your Medical File", "ar": "أشخاص يرغبون في الاطلاع على ملفك الطبي"}, + "user-view": {"en": "User Can View Your Medical File", "ar": "أشخاص مصرح لهم الاطلاع على ملفك الطبي"}, "parking": {"en": "Parking", "ar": "مواقف"}, "alhabiServices": {"en": "HMG Service", "ar": "خدمات الحبيب"}, "parkingTitle": { "en": "Car service, car service, service to save parking information, return to it later, 1- By clicking on (Read the code), save the parking data. 2- By clicking on the button (view my car park), it shows you the car’s location in Google Maps. 3- Read another position by pressing the Clear Position Data button.", "ar": - " خدمة المواقف، تتيح هذه الخدمة للمستخدم معلومات عن موقف السيارة ليسهل عليه العودة لها لاحقاً ، 1- بالضغط على زر(قراءة الكود) تستطيع حفظ البيانات الخاصة بالموقف. 2-بالضغط على زر(عرض موقف سيارتي) يعرض لك موقع السيارة في خرائط قوقل. 3- لإعادة قراءة موقف آخرعن طريق الضغط على زر(مسح بيانات الموقف). " + " خدمة المواقف، تتيح هذه الخدمة للمستخدم معلومات عن موقف السيارة ليسهل عليه العودة لها لاحقاً ، 1- بالضغط على زر (قراءة الكود) تستطيع حفظ البيانات الخاصة بالموقف. 2-بالضغط على زر(عرض موقف سيارتي) يعرض لك موقع السيارة في خرائط قوقل. 3- لإعادة قراءة موقف آخرعن طريق الضغط على زر(مسح بيانات الموقف). " + }, + "parkingDescription": { + "en": + "Parking service is for you to scan the car location so you can find it easy on you way out. click on (scan parking) button to save the parking location, then (show my park) button will appear to show you the way for the parking. if you want to rescan parking QR just click on (Clear My Data).", + "ar": + "خدمة المواقف، تتيح هذه الخدمة للمستخدم معلومات عن موقف السيارة ليسهل عليه العودة لها لاحقاً ، 1- بالضغط على زر (قراءة الكود) تستطيع حفظ البيانات الخاصة بالموقف. 2-بالضغط على زر(عرض موقف سيارتي) يعرض لك موقع السيارة في خرائط قوقل. 3- لإعادة قراءة موقف آخرعن طريق الضغط على زر(مسح بيانات الموقف)." }, + "appointments": {"en": "Appointments", "ar": "مواعيد"}, + "all2": {"en": "All", "ar": "الكل"}, + "checkinOption": {"en": "Check-In", "ar": "لتسجيل الحضور"}, "readBarcode": {"en": "Read Barcode", "ar": "قراءة الكود"}, - "showMyPark": {"en": "Show My Park", "ar": "عرض بارك"}, - "clearMyData": {"en": "clear My Data", "ar": "امسح البيانات"}, + "showMyPark": {"en": "Show My Park", "ar": "عرض الموقف"}, + "clearMyData": {"en": "Clear My Data", "ar": "امسح البيانات"}, "floor": {"en": "Floor:", "ar": "الطابق"}, "gate": {"en": "Gate:", "ar": "بوابة"}, "building": {"en": "Building:", "ar": "المبنى"}, "branch": {"en": "Branch:", "ar": "الفرع"}, - "emergencyServices": {"en": "Emergency Services:", "ar": "خدمات الطوارئ"}, - "nearester": {"en": "Nearest ER:", "ar": "أقرب طوارى"}, - "locationa": {"en": "location:", "ar": "الموقع"}, - "ambulancerequest": {"en": "Ambulance :", "ar": "طلب نقل "}, - "requestA": {"en": "Request:", "ar": "اسعاف"}, - "MyAppointments": {"en": "Appointments", "ar": "مواعيدي"}, - "NoBookedAppointments": { - "en": "No Booked Appointments", - "ar": "لا توجد مواعيد محجوزة" - }, - "NoConfirmedAppointments": { - "en": "No Confirmed Appointments", - "ar": "لا توجد مواعيد مؤكدة" - }, - "noArrivedAppointments": { - "en": "No Arrived Appointments", - "ar": "لم تصل المواعيد" - }, - "MyAppointmentsList": {"en": "List", "ar": "قائمة بمواعدي"}, + "emergencyServices": {"en": "Emergency Services", "ar": "خدمات الطوارئ"}, + "nearester": {"en": "Nearest ER", "ar": "أقرب طوارى"}, + "locationa": {"en": "Location", "ar": "الموقع"}, + "call_now": {"en": "Call now", "ar": "اتصل الان"}, + "ambulancerequest": {"en": "Ambulance", "ar": "طلب النقل "}, + "requestA": {"en": "Request", "ar": "الاسعافي"}, + "NoBookedAppointments": {"en": "No Booked Appointments", "ar": "لا توجد مواعيد محجوزة"}, + "NoConfirmedAppointments": {"en": "No Confirmed Appointments", "ar": "لا توجد مواعيد مؤكدة"}, + "noArrivedAppointments": {"en": "No Arrived Appointments", "ar": "لم يتم حضورها"}, + "MyAppointmentsList": {"en": "Appointments", "ar": "بمواعيدي"}, + "MyAppointments": {"en": "My", "ar": "قائمة"}, "Radiology": {"en": "Radiology", "ar": "الأشعة"}, "RadiologySubtitle": {"en": "Result", "ar": "صور وتقارير"}, - "Lab": {"en": "Lab", "ar": "تحليل المختبر"}, - "LabSubtitle": {"en": "Result", "ar": "نتائج"}, + "Lab": {"en": "Lab", "ar": "نتائج"}, + "LabSubtitle": {"en": "Results", "ar": "تحليل المختبر"}, "Medicines": {"en": "Medicines", "ar": "الوصفات"}, - "MedicinesSubtitle": {"en": "Prescriptions", "ar": "الوصفات الطبية"}, - "VitalSigns": {"en": "Vital Signs", "ar": "المؤشرات الحيوية"}, - "VitalSignsSubTitle": {"en": "Reports", "ar": "قراءات"}, - "MyMedical": {"en": "Active", "ar": "قراءات"}, + "MedicinesSubtitle": {"en": "Prescriptions", "ar": "الطبية"}, + "VitalSigns": {"en": "Vital Signs", "ar": "المؤشرات"}, + "VitalSignsSubTitle": {"en": "Reports", "ar": "الحيوية"}, + "MyMedical": {"en": "Active", "ar": "الأدوية"}, "MyMedicalSubtitle": {"en": "Medications", "ar": "النشطة"}, "MyDoctor": {"en": "My Doctor", "ar": "اطبائي"}, "MyDoctorSubtitle": {"en": "List", "ar": "قمت بزيارتهم"}, "Eye": {"en": "Eye", "ar": "قياسات"}, "EyeSubtitle": {"en": "Measurement", "ar": "النظر"}, - "Insurance": {"en": "Insurance", "ar": "بطاقة"}, + "Insurance": {"en": "Insurance", "ar": "بطاقات"}, "InsuranceSubtitle": {"en": "Card", "ar": "التأمين"}, - "UpdateInsurance": {"en": "Update Insurance", "ar": "تحديث التأمين"}, - "UpdateInsuranceSubtitle": {"en": "Card", "ar": "التأمين"}, - "InsuranceApproval": {"en": "Insurance Approval", "ar": "موافقات"}, - "InsuranceApprovalSubtitle": {"en": "Approvals", "ar": "موافقات التأمين"}, - "Allergies": {"en": "Allergies", "ar": "الحساسية"}, - "AllergiesSubtitle": {"en": "Diagnosed", "ar": "مسجلة"}, - "MyVaccines": {"en": "My Vaccines", "ar": "تطعيماتي"}, - "MyVaccinesSubtitle": {"en": "List", "ar": "قائمة"}, + "UpdateInsurance": {"en": "Update", "ar": "تحديث"}, + "UpdateInsuranceSubtitle": {"en": "Insurance", "ar": "التأمين"}, + "InsuranceApproval": {"en": "Insurance", "ar": "موافقات"}, + "InsuranceApprovalSubtitle": {"en": "Approvals", "ar": "التأمين"}, + "Allergies": {"en": "Allergies", "ar": "قائمة"}, + "AllergiesSubtitle": {"en": "List", "ar": "الحساسية"}, + "MyVaccines": {"en": "My Vaccines", "ar": "قائمة"}, + "MyVaccinesSubtitle": {"en": "List", "ar": "تطعيماتي"}, "Medical": {"en": "Medical", "ar": "التقارير"}, "MedicalSubtitle": {"en": "Report", "ar": "الطبية"}, - "Monthly": {"en": "Monthly", "ar": "تقارير"}, + "Monthly": {"en": "Monthly", "ar": "التقارير"}, "MonthlySubtitle": {"en": "Report", "ar": "الشهرية"}, "Sick": {"en": "Sick", "ar": "الإجازات"}, "SickSubtitle": {"en": "Leaves", "ar": "المرضية"}, - "MyBalance": {"en": "My Balance", "ar": "ارصدتي"}, - "MyBalanceSubtitle": {"en": "Credit", "ar": "المبالغ"}, + "MyBalance": {"en": "My Balance", "ar": "رصيد"}, + "MyBalanceSubtitle": {"en": "Credit", "ar": "محفظتي"}, "PatientCall": {"en": "Patient Call", "ar": "النداء للموعد"}, "PatientCallSubtitle": {"en": "Service", "ar": "خدمة"}, - "SmartWatches": {"en": "Smart Watches", "ar": "الساعة الذكية"}, - "SmartWatchesSubtitle": {"en": "Pairing", "ar": "ربط البيانات"}, + "SmartWatches": {"en": "Smart Watches", "ar": "الساعات الذكية"}, + "SmartWatchesSubtitle": {"en": "Pairing", "ar": "ربط بيانات"}, "MyTrackers": {"en": "My Trackers", "ar": "تتبع قراءاتي"}, "MyTrackersSubtitle": {"en": "Service", "ar": "الطبية"}, - "AskYour": {"en": "Ask Your", "ar": "إرسل طبيبك"}, + "AskYour": {"en": "Ask Your", "ar": "إسال طبيبك"}, "AskYourSubtitle": {"en": "Doctor", "ar": "خدمة"}, "Internet": {"en": "Internet", "ar": "الاتصال"}, "InternetSubtitle": {"en": "Pairing", "ar": "بالإنترنت"}, - "Chatbot": {"en": "Chatbot", "ar": "تاشت بوت"}, + "Chatbot": {"en": "Chatbot", "ar": "شات بوت"}, "ChatbotSubtitle": {"en": "", "ar": ""}, - "TimeLine": {"en": "Time Line", "ar": "الجدول الزمني"}, + "TimeLine": {"en": "Timeline", "ar": "الجدول الزمني"}, "LabOrders": {"en": "Lab Orders", "ar": "تحاليل المختبر"}, - "BillNo": {"en": "Bill No :", "ar": "رقم الفاتورة"}, + "BillNo": {"en": "Bill No:", "ar": "رقم الفاتورة"}, "Prescriptions": {"en": "Prescriptions", "ar": "الوصفات الطبية"}, "History": {"en": "History", "ar": "السجلات"}, "OrderNo": {"en": "Order No", "ar": "رقم الطلب"}, @@ -552,208 +396,190 @@ const Map localizedValues = { "VitalSign": {"en": "Vital Sign", "ar": "العلامة حيوية"}, "MonthlyReports": {"en": "Monthly Reports", "ar": "تقارير شهرية"}, "km": {"en": "KMs:", "ar": "كم"}, - "PatientHealthSummaryReport": { - "en": "Patient Health Summary Report", - "ar": " ملخص التقارير الشهرية" - }, - "ToViewTheTermsAndConditions": { - "en": "To View The Terms And Conditions Report", - "ar": " عرض الشروط والأحكام " - }, + "km_": {"en": "KM", "ar": "كم"}, + "PatientHealthSummaryReport": {"en": "Patient Health Summary Report", "ar": " ملخص التقارير الشهرية"}, + "ToViewTheTermsAndConditions": {"en": "To View the Terms and Conditions Report", "ar": " عرض الشروط والأحكام "}, "ClickHere": {"en": "Click here", "ar": "أنقر هنا"}, - "IAgreeToTheTermsAndConditions": { - "en": "I agree to the terms and conditions ", - "ar": "أوافق على الشروط والاحكام " - }, + "IAgreeToTheTermsAndConditions": {"en": "I agree to the terms and conditions ", "ar": "موافق على الشروط والاحكام "}, "IAgreeToTheTermsAndConditionsSubtitle": { "en": "I agree to the terms and conditions ", "ar": - "هذا ملخص التقرير الصحي الشهري و الذي يسرد المؤشرات الصحية و نتائج التحاليل لأخر الزيارات. يرجى ملاحظة أن هذا التقرير هو تقرير يتم ارساله بشكل آلي من النظام و لا يعتبر رسمي و لا تؤخذ عليه أي قرارات طبية" + "هذا ملخص التقرير الصحي الشهري و الذي يسرد المؤشرات الصحية و نتائج التحاليل لأخر الزيارات. يرجى ملاحظة أن هذا التقرير يتم ارساله بشكل آلي من النظام و لا يعتبر رسمي و لا تؤخذ عليه أي قرارات طبية" }, "Save": {"en": "Save", "ar": "حفظ "}, "UserAgreement": {"en": "User Agreement", "ar": "اتفاقية الخصوصية "}, "UpdateSuccessfully": {"en": "Update Successfully", "ar": "تم التحديث بنجاح"}, - "CHECK_VACCINE_AVAILABILITY": { - "en": "CHECK VACCINE AVAILABILITY", - "ar": "تحقق من توافر اللقاح" - }, - "MyVaccinesAvailability": { - "en": "MyVaccinesAvailability", - "ar": "توفر لقاحي" - }, + "CHECK_VACCINE_AVAILABILITY": {"en": "CHECK VACCINE AVAILABILITY", "ar": "التحقق من توفر اللقاح"}, + "MyVaccinesAvailability": {"en": "MyVaccinesAvailability", "ar": "توفر لقاحي"}, "PaymentService": {"en": "Payment Service", "ar": "خدمة المدفوعات"}, "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": "المبلغ الإجمالي"}, - "CreateAdvancedPayment": {"en": "Recharge Wallet", "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 you account or other accounts.", - "ar": "يمكنك تحويل مبلغ لحسابك لدى المجموعة أو لحساب احد المراجعين" - }, + "AdvancePaymentLabel": {"en": "You can create and add an Advanced Payment for your account or other accounts.", "ar": "يمكنك تحويل مبلغ لحسابك لدى المجموعة أو لحساب احد المراجعين"}, "FileNumber": {"en": "File Number", "ar": "رقم الملف"}, "Amount": {"en": "Amount *", "ar": "المبلغ *"}, - "DepositorEmail": { - "en": "Depositor Email *", - "ar": "البريد الإلكتروني للمودع *" - }, + "DepositorEmail": {"en": "Depositor Email *", "ar": "البريد الإلكتروني للمودع *"}, "Notes": {"en": "Notes", "ar": "ملاحظات"}, - "SelectPatientName": {"en": "Select Patient Name", "ar": "اختر اسم المريض"}, + "SelectPatientName": {"en": "Select Patient Name", "ar": "اختر اسم المراجع"}, "SelectFamilyPatientName": {"en": "Family Members", "ar": "أفراد الأسرة"}, "SelectHospital": {"en": "Select Hospital", "ar": "اختر المستشفى"}, "selectCity": {"en": "Select City", "ar": "اختر المدينة"}, + "city": {"en": "City", "ar": "مدينة"}, + "distance": {"en": "Distance", "ar": "مسافه"}, "MyAccount": {"en": "My Account", "ar": "حسابي"}, "OtherAccount": {"en": "Other Account", "ar": "حساب آخر"}, "SelectBeneficiary": {"en": "Select Beneficiary", "ar": "حدد المستفيد"}, "ConfirmThePayment": {"en": "Confirm The Payment", "ar": "تأكيد عملية الدفع"}, "DepositorName": {"en": "Depositor Name", "ar": "اسم المودع *"}, "MobileNumber": {"en": "Mobile Number", "ar": "رقم الجوال"}, - "Ok": {"en": "Ok", "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": "تنتهي صلاحية رمز التحقق في" - }, - "PleaseEnterTheVerificationCode": { - "en": "Please enter the verification code send to", - "ar": "الرجاء إدخال رمز التحقق المرسل إلى" - }, + "phone-number": {"en": "Phone Number", "ar": "رقم الجوال"}, + "country": {"en": "Country", "ar": "دولة"}, + "Ok": {"en": "Ok", "ar": "موافق"}, + "averageWaitingTime": {"en": "Average 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": "تنتهي صلاحية رمز التحقق في"}, + "PleaseEnterTheVerificationCode": {"en": "Please enter the verification code send to", "ar": "الرجاء إدخال رمز التحقق المرسل إلى"}, "EyeMeasurements": {"en": "Eye Measurements", "ar": "قياسات النظر"}, "Measurements": {"en": "Measurements", "ar": "قياسات"}, - "Classes": {"en": "Classes", "ar": "نظارات"}, + "Classes": {"en": "Glasses", "ar": "نظارات"}, "ContactLens": {"en": "Contact Lens", "ar": "العدسات اللاصقة"}, "RightEye": {"en": "Right Eye", "ar": "العين اليمين"}, "Sphere": {"en": "Sphere", "ar": "القوة"}, "Cylinder": {"en": "Cylinder", "ar": "الدائرية"}, "Axis": {"en": "Axis", "ar": "المحاور"}, "Prism": {"en": "Prism", "ar": "موشور"}, - "VA": {"en": "Prism", "ar": "المحاور"}, + "VA": {"en": "VA", "ar": "فرجينيا"}, "LeftEye": {"en": "Left Eye", "ar": "العين اليسرى"}, "Brand": {"en": "Brand", "ar": "النوع"}, "Power": {"en": "Power", "ar": "القوة"}, "Diameter": {"en": "Diameter", "ar": "القطر"}, - "Remarks": {"en": "Remarks", "ar": "ملاحضات"}, + "Remarks": {"en": "Remarks", "ar": "ملاحظات"}, "ActiveMedications": {"en": "Active Medications", "ar": "ادويتي النشطة"}, "ExpDate": {"en": "Active Exp Date :", "VA": "تاريخ الإنتهاء"}, "Route": {"en": "Route", "ar": "الطريقة"}, "Frequency": {"en": "Frequency", "ar": "المعدل"}, "DailyQuantity": {"en": "Daily Quantity :", "ar": "جرعات يومية"}, "AddReminder": {"en": "Add Reminder", "ar": "إضافة تذكير"}, + "CancelReminder": {"en": "Cancel Reminder", "ar": "إلغاء تذكير"}, "reminderDes": { - "en": - "Please select treatment start day and time to be notified when it\'s time to take the medicine", - "ar": - " يرجى تحديد يوم بدء العلاج والوقت ليتم ارسال تنبيه عندما يحين الوقت لتناول الدواء" + "en": "Please select treatment start day and time to be notified when it\'s time to take the medicine", + "ar": "يرجى تحديد يوم بدء العلاج والوقت ليتم ارسال تنبيه عندما يحين الوقت لتناول الدواء" }, + "pleaseSelectAllQuestionToContinue": {"en": "Please answer all questions to continue...", "ar": "يرجى الإجابة على جميع الأسئلة للمتابعة..."}, "StartDay": {"en": "Start Day", "ar": "يوم البداية"}, "EndDay": {"en": "End Day", "ar": "يوم الانتهاء"}, "Days": {"en": "Days ", "ar": "أيام"}, + "please-verify": {"en": "Please Verify ", "ar": "ارجوك تحقق"}, "ScheduleTime": {"en": "Schedule time", "ar": "الجدول الزمني"}, "AskDoctor": {"en": "Ask Doctor", "ar": "اسأل طبيبك"}, "DoctorResponses": {"en": "Doctor Responses", "ar": "ردود الأطباء"}, "New": {"en": "New", "ar": "جديد"}, "All": {"en": "All", "ar": "الكل"}, - "QuestionHere": { - "en": "Enter the question here...", - "ar": "اضف الاستفسار هنا" - }, - "ViewDoctorResponses": { - "en": "View Doctor Responses", - "ar": "الاطلاع على ردود الأطباء" - }, + "dailyWater": {"en": "Daily Water Check", "ar": "فحص المياه اليومي"}, + "QuestionHere": {"en": "Enter the question here...", "ar": "اضف الاستفسار هنا"}, + "ViewDoctorResponses": {"en": "View Doctor Responses", "ar": "الاطلاع على ردود الأطباء"}, "ServiceInformationButton": {"en": "LOGIN / REGISTER", "ar": "دخول / تسجيل"}, - "ServiceInformationTitle": { - "en": "Service Information", - "ar": "معلومات الخدمة" - }, + "ServiceInformationTitle": {"en": "Service Information", "ar": "معلومات الخدمة"}, "ServiceInformation": {"en": "Service Information", "ar": "معلومات الخدمة"}, - "HomeHealthCare": { - "en": "Home Health Care", - "ar": " الرعاية الصحية المنزلية " - }, + "HomeHealthCare": {"en": "Home Health Care", "ar": " الرعاية الصحية المنزلية "}, + "noAppointmentAvailable": {"en": "No Available Appointments", "ar": "لا توجد مواعيد متاحة"}, "HomeHealthCareText": { "en": "This service provides a set of home health care services, continuous and comprehensive follow-up in their places of residence for those who cannot access health facilities, such as (laboratory analyzes - radiology - vaccinations - physical therapy), etc.", "ar": - "توفر هذه الخدمة مجموعه من خدمات الرعايه الصحيه المنزلية و متابعه مستمره وشامله للذين لا يستطيعون الوصول للمنشات الصحيه في اماكن اقامتهم (التحاليل المخبرية – الاشعة – التطعيمات – العلاج الطبيعي)... " + "توفر هذه الخدمة مجموعه من خدمات الرعايه الصحيه المنزلية و متابعه مستمره وشامله للذين لا يستطيعون الوصول للمنشات الصحيه في اماكن اقامتهم (التحاليل المخبرية – الاشعة – التطعيمات – العلاج الطبيعي) ... " }, "LoginRegister": {"en": "Login/Register", "ar": "دخول / تسجيل"}, "OrderLog": {"en": "Order Log", "ar": " سجل الطلبات"}, "info-lab": { - "en": - "This service allows you to view the results of all laboratory tests performed in Al Habib Medical Group as well as sending the report via e-mail.", - "ar": - "خدمة نتائج المختبر: هذه الخدمة تمكنك من الاطلاع على نتائج جميع الفحوصات المخبرية التي تمت في مجموعة الحبيب الطبية." + "en": "This service allows you to view the results of all laboratory tests performed in Al Habib Medical Group as well as sending the report via e-mail.", + "ar": "خدمة نتائج المختبر: هذه الخدمة تمكنك من الاطلاع على نتائج جميع الفحوصات المخبرية التي تمت في مجموعة الحبيب الطبية." }, "info-radiology": { - "en": - "This service allows you to view the reports and photos of radiology in Al Habib Medical Group as well as send the report by e-mail.", - "ar": - "خدمة الاشعة: هذه الخدمة تمكنك من الاطلاع على تقارير وصور الاشعة التي تمت في مجموعة الحبيب الطبية وكذلك ارسال التقرير عن طريق الايميل." + "en": "This service allows you to view the reports and photos of radiology in Al Habib Medical Group as well as send the report by e-mail.", + "ar": "خدمة الاشعة: هذه الخدمة تمكنك من الاطلاع على تقارير وصور الاشعة التي تمت في مجموعة الحبيب الطبية وكذلك ارسال التقرير عن طريق الايميل." }, + "noReviewsAvailable": {"en": "No Reviews Available", "ar": "لا يوجد تقييمات"}, + "noLocationAvailable": {"en": "No Location Available", "ar": "لا يوجد موقع"}, "orders": {"en": "Orders", "ar": "الطلبات"}, - "lakum": {"en": "Lakum", "ar": "لكم"}, - "wishlist": {"en": "Wishlist", "ar": "الرغبات"}, - "reviews": {"en": "Reviews", "ar": "التقيمات"}, - // "myPrescriptions": {"en": "My Prescriptions", "ar": "وصفاتي"}, - // "medicationRefill": {"en": "Medication Refill", "ar": "تعبئة الأدوية"}, + "lakum": {"en": "Lakum", "ar": "برنامج لكم"}, + "lakumMsg": {"en": "No Details of Points Are There", "ar": " لاتوجد تفاصيل عن النقاط"}, + "lakumPoint": {"en": "Point", "ar": "نقطه"}, + "wishlist": {"en": "Wishlist", "ar": "المفضلة"}, + "products": {"en": "Products", "ar": "المنتجات"}, + "reviews": {"en": "Reviews", "ar": "التقييمات"}, + "brands": {"en": "Brands", "ar": "العلامات التجارية"}, + "productDetails": {"en": "Product Details", "ar": "تفاصيل المنتج"}, + "medicationRefill": {"en": "Medication Refill", "ar": "تعبئة الأدوية"}, "pillReminder": {"en": "Pill Reminder", "ar": "تذكير الأدويه"}, "shippingAddresses": {"en": "Shipping Addresses", "ar": "عناوين الشحن"}, "reachUs": {"en": "Reach Us", "ar": "الوصول لنا"}, "ourLocations": {"en": "Our Locations", "ar": "مواقعنا"}, "edit": {"en": "Edit", "ar": "تعديل"}, + "whatsApp": {"en": "Whats App", "ar": " واتس اب"}, + "phone": {"en": "Phone", "ar": " هاتف"}, "delete": {"en": "Delete", "ar": " حذف"}, + "deleteAddress": {"en": "Are you sure want to delete", "ar": " هل انت متأكد تريد حذف هذا العنوان"}, + "deletedAddres": {"en": "Address has been deleted", "ar": " تم حذف العنوان"}, "addAddress": {"en": "ADD A NEW ADDRESS", "ar": " اضافة عنوان جديد"}, "addNewAddress": {"en": "Add New Address", "ar": " اضافة عنوان جديد"}, "order": {"en": "My Order", "ar": " طلباتي"}, "delivered": {"en": "Delivered", "ar": " تم التوصيل"}, "pending": {"en": "Pending", "ar": " معلقة "}, - "enterNameHere": {"en": "Enter the name here", "ar": " أدخل الاسم هنا "}, + "enterNameHere": {"en": "Enter Your Name", "ar": "أدخل أسمك"}, "processing": {"en": "Processing", "ar": " تحت المعالجة"}, "cancelled": {"en": "Cancelled", "ar": " ملغي"}, "writeReview": {"en": "Write Review", "ar": " اكتب تقييمك"}, "shareReview": {"en": "SHARE REVIEW", "ar": " اكتب تقييمك"}, - "review": {"en": " reviews", "ar": " تقييمات"}, + "review": {"en": " reviews", "ar": "تقييمات"}, + "viewMedicalFile": {"en": "View Details", "ar": "عرض الملف الطبي"}, + "viewAllServices": {"en": "View All Services", "ar": "عرض جميع الخدمات"}, + "medicalFile": {"en": "Medical File", "ar": "ملفي الطبي"}, + "verified": {"en": "Verified", "ar": "تم التحقق"}, + "checkup": {"en": "Checkup", "ar": "فحص"}, + "hhcHome": {"en": "Home", "ar": "الرعاية"}, + "refferal": {"en": "E-Refferal", "ar": "الإحالة الإلكترونية"}, + "refferalTitle": {"en": "E-Refferal", "ar": "خدمات"}, + "refferalSubTitle": {"en": "Service", "ar": "الإحالة الإلكترونية"}, + "healthCare": {"en": "Health Care", "ar": "الصحية المنزلية"}, + "emergency": {"en": "Emergency", "ar": "الطوارئ"}, + "erservices": {"en": "Emergency", "ar": "الطوارئ"}, + "services2": {"en": "Services", "ar": "خدمات"}, + "cantSeeProfile": {"en": "To view your medical profile, please log in or register now", "ar": "لتصفح ملفك الطبي الرجاء تسجيل الدخول أو التسجيل الآن"}, + "loginRegisterNow": {"en": "Login or Register Now", "ar": "تسجيل الدخول أو التسجيل الآن"}, + "HMGPharmacy": {"en": "HMG Pharmacy", "ar": "صيدلية HMG"}, + "ecommerceSolution": {"en": "Ecommerce Solution", "ar": "حل التجارة الإلكترونية"}, + "comprehensive": {"en": "Comprehensive", "ar": "شامل"}, + "onlineConsulting": {"en": "Online Consulting", "ar": "استشارات فورية عن بعد"}, "pendingOrder": {"en": " PENDING", "ar": " معلقة"}, - "deliveredOrder": {"en": " DELIVERED", "ar": " تم التوصيل"}, + "deliveredOrder": {"en": " DELIVERED", "ar": "تم التوصيل"}, "processingOrder": {"en": " PROCESSING", "ar": "قيد التنفيذ"}, "cancelledOrder": {"en": " CANCELLED", "ar": "ملغي"}, "compare": {"en": " Compare", "ar": "مقارنه"}, "medicationsRefill": {"en": " Medication Refill", "ar": "طلب أعادة صرف"}, - "recommended": {"en": " Recommended For You", "ar": "موصى لك"}, + "recommended": {"en": " Recommended for You", "ar": "موصى لك"}, "myPrescription": {"en": " My Prescriptions", "ar": "وصفاتي"}, "quantity": {"en": " QTY ", "ar": "الكمية"}, - "backMyAccount": { - "en": "BACK TO MY ACCOUNT ", - "ar": " الرجوع لحسابي الشخصي" - }, + "reviewAppointment": {"en": " Review Appointment ", "ar": "مراجعة الموعد"}, + "backMyAccount": {"en": "BACK TO MY ACCOUNT ", "ar": "الرجوع لحسابي الشخصي"}, "reviewSuccessful": {"en": "Review Successful", "ar": " تقييم ناجح"}, - "reviewShared": { - "en": "Your review has been shared on product review section", - "ar": " تمت مشاركة تقييمك في قسم تقييم المنتج" - }, - "reviewComment": { - "en": "Your reviews help other to choose better product", - "ar": " تقييمك سوف يساعد الأخرين في اختيار المنتج الأفضل" - }, + "reviewShared": {"en": "Your review has been shared on product review section", "ar": " تمت مشاركة تقييمك في قسم تقييم المنتج"}, + "reviewComment": {"en": "Your reviews help other to choose better product", "ar": " تقييمك سوف يساعد الأخرين في اختيار المنتج الأفضل"}, "shippedMethod": {"en": "SHIP BY:", "ar": " الشحن بواسطة:"}, "orderDetail": {"en": "Order Details", "ar": " تفاصيل الطلب"}, "orderSummary": {"en": "Order Summary", "ar": " تفاصيل المنتج"}, "subtotal": {"en": "Subtotal", "ar": " المجموع الفرعي"}, "shipping": {"en": "Shipping", "ar": " الشحن"}, "shipBy": {"en": "SHIP BY:", "ar": "الشحن عن طريق:"}, - "lakumPoints": {"en": "Lakum Points", "ar": "نقاط لكم"}, + "lakumPoints": {"en": "Lakum Points", "ar": "نقاط برنامج لكم"}, + "useLakumPoints": {"en": "Use Lakum points", "ar": "استخدم برنامج لكم"}, "use": {"en": "USE", "ar": "استخدم"}, "proceedPay": {"en": "PROCEED TO PAY", "ar": "المتابعة للدفع"}, "vat": {"en": "VAT (15%)", "ar": "(15%) القيمة المضافة"}, @@ -761,131 +587,111 @@ const Map localizedValues = { "items": {"en": "item(s)", "ar": "عنصر"}, "checkOut": {"en": "CHECK OUT", "ar": "الدفع"}, "sar": {"en": "SAR", "ar": " ر.س "}, + // "sar": {"en": "", "ar": " "}, + "aed": {"en": "AED", "ar": "درهم"}, "payOnline": {"en": "PAY ONLINE", "ar": "اتمام عملية الدفع "}, "cancelOrder": {"en": "CANCEL ORDER", "ar": "الغاء الطلب "}, "confirmAddress": {"en": "CONFIRM ADDRESS ", "ar": " تأكيد العنوان "}, "confirmLocation": {"en": "CONFIRM LOCATION ", "ar": " تأكيد الموقع "}, "conditionsHMG": {"en": "Terms & Conditions ", "ar": "الشروط و الأحكام "}, - "conditions": {"en": "Terms & Conditions of Lakum", "ar": "شروط و احكام لكم"}, - "confirmDeleteMsg": { - "en": "Are you sure! want to delete ", - "ar": "هل انت متأكد تريد الحذف " - }, + "conditions": {"en": "Terms & Conditions of Lakum", "ar": "شروط واحكام برنامج لكم"}, + "confirmDeleteMsg": {"en": "Are you sure! want to delete ", "ar": "هل انت متأكد من الحذف "}, "confirmDelete": {"en": "DELETE", "ar": "حذف"}, - "confirmCancellation": { - "en": "Are you sure! want to cancel this order ", - "ar": "هل انت متأكد تريد حذف هذا المنتج " - }, + "confirmCancellation": {"en": "Are you sure! want to cancel this order ", "ar": "هل انت متأكد من حذف هذا المنتج "}, "orderNumber": {"en": "Order#: ", "ar": "الطلب: "}, "orderDate": {"en": "Date", "ar": "التاريخ:"}, "itemsNo": {"en": "items(s)", "ar": "عناصر"}, "noOrder": {"en": "You Don't have any orders.", "ar": "ليس لديك طلبات"}, - + "noResult": {"en": "No Result.", "ar": "لا يوجد نتائج"}, + "nonRecommended": {"en": "No Recommended Products.", "ar": "لا يوجد منتجات"}, "TermsService": {"en": "Terms of Service", "ar": "شروط الخدمه"}, - "Beforeusing": { - "en": "Before using the checkup, please read Terms of Service.", - "ar": "قبل استخدام الفحص ، يرجى قراءة شروط الخدمة" - }, - "accept": { - "en": "I read and accept Terms of Service and Privacy Policy", - "ar": "قرأت ووافقت على شروط الخدمة وسياسة الخصوصية" - }, - "data-safe-info": { - "en": - "Information that you provide is anonymous and not shared with anyone.", - "ar": "المعلومات التي تقدمها لا تتم مشاركتها مع أي شخص" - }, + "Beforeusing": {"en": "Before using the checkup, please read Terms of Service.", "ar": "قبل استخدام الفحص ، يرجى قراءة شروط الخدمة"}, + "accept": {"en": "I read and accept Terms of Service and Privacy Policy", "ar": "قرأت ووافقت على شروط الخدمة وسياسة الخصوصية"}, + "data-safe-info": {"en": "Information that you provide is anonymous and not shared with anyone.", "ar": "المعلومات التي تقدمها لا تتم مشاركتها مع أي شخص"}, "data-safe": {"en": " Your data is safe.", "ar": "بياناتك آمنة"}, - "informational": { - "en": - "Checkup is for informational purposes and is not a qualified medical opinion", - "ar": "الفحص هو لأغراض معلوماتية وليس رأي طبي مؤهل" - }, - "not-use-in-emerbency": { - "en": "Do not use in emergencies.", - "ar": "لا تستخدم في حالات الطوارئ" - }, - "not-use-in-emerbency-details": { - "en": "In case of health emergency, ", - "ar": "في حالة الطوارئ اتصل بأقرب رقم للطوارئ على الفور" - }, - "not-use-in-emerbency-details-call": { - "en": "call the nearest emergency number immediately", - "ar": " اتصل بأقرب رقم للطوارئ على الفور" - }, - "check-diagnosis": { - "en": "Checkup is not a diagnosis.", - "ar": "الفحص ليس تشخيص." - }, + "informational": {"en": "Checkup is for informational purposes and is not a qualified medical opinion", "ar": "الفحص هو لأغراض معلوماتية وليس رأي طبي مؤهل"}, + "not-use-in-emerbency": {"en": "Do not use in emergencies.", "ar": "لا تستخدم في حالات الطوارئ"}, + "not-use-in-emerbency-details": {"en": "In case of health emergency, ", "ar": "في حالة الطوارئ اتصل بأقرب رقم للطوارئ على الفور"}, + "not-use-in-emerbency-details-call": {"en": "call the nearest emergency number immediately", "ar": " اتصل بأقرب رقم للطوارئ على الفور"}, + "check-diagnosis": {"en": "Checkup is not a diagnosis.", "ar": "الفحص ليس تشخيص."}, "remeberthat": {"en": "Remember that", "ar": "تذكر ذلك:"}, - "loginToUseService": { - "en": "You need to login to use this service", - "ar": "هذة الخدمة تتطلب تسجيل الدخول" - }, - - // pharmacy module - "medicationRefill": {"en": "MEDICATION REFILL", "ar": "إعادة تعبئة الدواء"}, - "offersAndPromotions": { - "en": "OFFERS & SPECIAL PROMOTIONS", - "ar": "العروض والترقيات الخاصة" - }, + "loginToUseService": {"en": "You need to login to use this service", "ar": "هذة الخدمة تتطلب تسجيل الدخول"}, + "offersAndPromotions": {"en": "OFFERS & SPECIAL PROMOTIONS", "ar": "العروض والترقيات الخاصة"}, + "offers": {"en": "OFFERS", "ar": "العروض"}, "myPrescriptions": {"en": "MY PRESCRIPTIONS", "ar": "وصفاتي"}, - "searchAndScanMedication": { - "en": "SEARCH & SCAN FOR MEDICATION", - "ar": "البحث والمسح للأدوية" - }, - "shopByBrands": {"en": "Shop By Brands", "ar": "تسوق حسب الماركات"}, + "searchAndScanMedication": {"en": "SEARCH & SCAN FOR MEDICATION", "ar": "البحث والمسح للأدوية"}, + "shopByBrands": {"en": "Shop by Brands", "ar": "تسوق حسب الماركات"}, "recentlyViewed": {"en": "Recently Viewed", "ar": "شوهدت مؤخرا"}, - "bestSellers": {"en": "Best Sellers", "ar": "أفضل البائعين"}, + "bestSellers": {"en": "Best Seller", "ar": "الأكثر مبيعأ"}, "deleteAllItems": {"en": "Delete All Items", "ar": "حذف كافة العناصر"}, "total": {"en": "Total", "ar": "المجموع"}, - "totalWithColonRight": {"en": "Total:", "ar": ":المجموع"}, + "totalWithColonRight": {"en": "Total:", "ar": "المجموع"}, "selectAddress": {"en": "Select Address", "ar": "حدد العنوان"}, "shippingAddress": {"en": "SHIPPING ADDRESS", "ar": "عنوان الشحن"}, "changeAddress": {"en": "Change Address", "ar": "تغيير العنوان"}, - "selectPaymentOption": { - "en": "Select Payment Option", - "ar": "حدد خيار الدفع" - }, - "changeMethod": {"en": "Change Method", "ar": "تغيير خيار الدفع"}, + "selectPaymentOption": {"en": "Select Payment Option", "ar": "حدد طريقة الدفع"}, + "selectTamaraPlan": {"en": "Select Tamara Payment Plan", "ar": "حدد خطة الدفع تمارا"}, + "changeMethod": {"en": "Change Method", "ar": "تغيير طريقة الدفع"}, "reviewOrder": {"en": "Review Order", "ar": "مراجعة الطلب"}, "active": {"en": "ACTIVE", "ar": "فعال"}, "inactive": {"en": "INACTIVE", "ar": "غير فعال"}, "balance": {"en": "BALANCE", "ar": "الحالي"}, "gained": {"en": "GAINED", "ar": "المكتسب"}, - "consumed": {"en": "CONSUMED", "ar": "المستهلك"}, + "consumed": {"en": "Consumed", "ar": "المستهلك"}, "transferred": {"en": "TRANSFERRED", "ar": "المحول"}, + "RIYAL": {"en": "RIYAL", "ar": "ريال"}, + "MEMBERSINCE": {"en": "MEMBER SINCE", "ar": "تاريخ العضوية"}, + "IDENTIFICATION": {"en": "IDENTIFICATION", "ar": "رقم الهوية"}, + "lakumMobile": {"en": "lakum Mobile", "ar": "رقم الجوال"}, + "Waitinggained": {"en": "Waiting gained", "ar": " بأنتظار التفعيل"}, + "Expired": {"en": "Expired", "ar": "منتهية الصلاحيه"}, + "WillBeExpired": {"en": "Will Be Expired", "ar": "ستنتهي صلاحيتها"}, + "LakumPoint": {"en": "Lakum Points", "ar": "نقاط لكم"}, + "ActivateLAKUMAccount": {"en": "Activate LAKUM Account", "ar": "تفعيل لكم"}, "checkBeneficiary": {"en": "CHECK BENEFICIARY", "ar": "تحقق من المستفيد"}, "beneficiaryName": {"en": "Beneficiary Name", "ar": "اسم المستفيد"}, "accountActivation": {"en": "Account Activation", "ar": "تفعيل الحساب"}, - "lakumTransfer": {"en": "Lakum Transfer", "ar": "تفعيل الحساب"}, - "acceptLbl": {"en": "Accept", "ar": "موافقة"}, + "lakumTransfer": {"en": "Lakum Transfer", "ar": "تحويل نقاط لكم"}, + "acceptLbl": {"en": "Accept", "ar": "موافق"}, + "declineLbl": {"en": "Decline", "ar": "رفض"}, "select-gender": {"en": "Select Gender", "ar": "اختر الجنس"}, "i-am-a": {"en": "I am a ...", "ar": "أنا ..."}, "select-age": {"en": "Select Your Age", "ar": "حدد العمر"}, + "select": {"en": "Select", "ar": "اختر"}, "i-am": {"en": "I am", "ar": "أنا"}, "years-old": {"en": "years old", "ar": "سنة"}, - "drag-point": { - "en": "Drag point to change your age", - "ar": "اسحب لتغيير عمرك" - }, - - "categorise": {"en": "Categories", "ar": "التطبيقات"}, - "wishList": {"en": "WishList", "ar": "الرغبات"}, + "drag-point": {"en": "Drag point to change your age", "ar": "اسحب لتغيير عمرك"}, + "refine": {"en": "Refine", "ar": "تصفية"}, + "subGroup": {"en": "Subgroup", "ar": "مجموعة فرعيه"}, + "max": {"en": "Max", "ar": "اعلى"}, + "compeleteOrderMsg": {"en": "Order has been placed successfully!!", "ar": "تم اتمام الطلب بنجاح"}, + "addToCompareMsg": {"en": "You have added a product to the Compare list", "ar": "تمت الاضافه لقائمة المقارنه"}, + "itInListMsg": {"en": "Item is already in the list", "ar": "المنتج موجود في القائمه"}, + "compareListFull": {"en": "Your compare list is full", "ar": "قائمة المقارنة ممتلئه"}, + "addQuantity": {"en": "You should add quantity", "ar": "اختر الكمية"}, + "addToCartMsg": {"en": "You have added a product to the cart", "ar": "تمت اضافة المنتج بنجاح"}, + "addToWishlistMsg": {"en": "You have added a product to the Wishlist", "ar": "تمت الاضافة لقائمة المفضله"}, + "notifyMeMsg": {"en": "You will be notified when product available", "ar": "سيتم اخبارك في حال توفر المنتج"}, + "removeFromWishlistMsg": {"en": "You have removed a product from the Wishlist", "ar": "تمت ازالة المنتج بنجاح"}, + "min": {"en": "Min", "ar": "اقل"}, + "reset": {"en": "Reset", "ar": "اعادة تعيين"}, + "apply": {"en": "Apply", "ar": "تطبيق"}, + "viewCategorise": {"en": "View All Categories", "ar": "عرض جميع الفئات"}, + "viewSubCategorise": {"en": "View All Sub Categories", "ar": "عرض جميع الفئات الفرعيه"}, + "categorise": {"en": "Categories", "ar": "الفئات"}, + "wishList": {"en": "WishList", "ar": "المفضلة"}, "myAccount": {"en": "My Account", "ar": "حسابي"}, "cart": {"en": "Cart", "ar": "التسوق"}, - "searchProductHere": { - "en": "Search Product here", - "ar": "ابحث في الطلب الخاص بك" - }, + "Alhabibapp": {"en": "Al Habib app", "ar": "تطبيق الحبيب"}, + "searchProductHere": {"en": "Search Product here", "ar": "البحث عن منتج"}, "HHCNotAuthMsg": { "en": "This service provides a set of home health care services, continuous and comprehensive follow-up in their places of residence for those who cannot access health facilities, such as (laboratory analyzes - radiology - vaccinations - physical therapy), etc.", "ar": - "توفر هذه الخدمة مجموعه من خدمات الرعايه الصحيه المنزلية و متابعه مستمره وشامله للذين لا يستطيعون الوصول للمنشات الصحيه في اماكن اقامتهم (التحاليل المخبرية – الاشعة – التطعيمات – العلاج الطبيعي)..." + "توفر هذه الخدمة مجموعه من خدمات الرعايه الصحيه المنزلية و متابعه مستمره وشامله للذين لا يستطيعون الوصول للمنشات الصحيه في اماكن اقامتهم (التحاليل المخبرية – الاشعة – التطعيمات – العلاج الطبيعي) ..." }, - "email": {"en": "Email", "ar": "البريد الالكتروني"}, - "Book": {"en": "Book", "ar": "احجز"}, + "email": {"en": "Email *", "ar": "البريد الالكتروني *"}, + "Book": {"en": "Book", "ar": "حجز"}, "AppointmentLabel": {"en": "Appointment", "ar": "موعد"}, "BloodType": {"en": "Blood Type", "ar": "فصيلة الدم"}, "marital-status": {"en": "Marital status", "ar": "الحالة الإجتماعية"}, @@ -893,11 +699,7 @@ const Map localizedValues = { "profile": {"en": "Profile", "ar": "ملفي"}, "notifications": {"en": "Notifications", "ar": "إشعارات"}, "notificationDetails": {"en": "Notification Details", "ar": "تفاصيل الاشعار"}, - "notificationDetailsa": { - "en": "Notification Details", - "ar": "تفاصيل الاشعار" - }, - + "notificationDetailsa": {"en": "Notification Details", "ar": "تفاصيل الاشعار"}, "info-my-doctor-points": { "en": [ "View the doctor's profile and qualifications.", @@ -905,24 +707,15 @@ const Map localizedValues = { "View details of your appointments with the selected doctor.", "Book appointment with the doctor. ", ], - "ar": [ - "الاطلاع على معلومات الطبيب ومؤهلاته.", - "الاطلاع على جدول الطبيب.", - "الاطلاع على تفاصيل المواعيد التي تمت مع الطبيب.", - "حجز موعد مع الطبيب." - ] + "ar": ["الاطلاع على معلومات الطبيب ومؤهلاته.", "الاطلاع على جدول الطبيب.", "الاطلاع على تفاصيل المواعيد التي تمت مع الطبيب.", "حجز موعد مع الطبيب."] }, "info-my-doctor": { - "en": - "This service allows you to see all the doctors you have visited in Al Habib Medical Group, and through this service:", - "ar": - "خدمة اطبائي: هذه الخدمة تمكنك من الاطلاع على جميع الاطباء الذين قمت بزيارتهم في مجموعة الحبيب الطبية, كما تستطيع من خلال هذه الخدمة:" + "en": "This service allows you to see all the doctors you have visited in Al Habib Medical Group, and through this service:", + "ar": "خدمة اطبائي: هذه الخدمة تمكنك من الاطلاع على جميع الاطباء الذين قمت بزيارتهم في مجموعة الحبيب الطبية, كما تستطيع من خلال هذه الخدمة:" }, "info-prescriptions": { - "en": - "This service allows you to view all the medical prescriptions issued by Al Habib Medical Group, and through this service, you can:", - "ar": - "خدمة الوصفات الطبية: هذه الخدمة تمكنك من الاطلاع على جميع الوصفات الطبية التي تم اصدارها في مجموعة الحبيب الطبية، كما تستطيع من خلال هذه الخدمة:" + "en": "This service allows you to view all the medical prescriptions issued by Al Habib Medical Group, and through this service, you can:", + "ar": "خدمة الوصفات الطبية: هذه الخدمة تمكنك من الاطلاع على جميع الوصفات الطبية التي تم اصدارها في مجموعة الحبيب الطبية، كما تستطيع من خلال هذه الخدمة:" }, "info-my-prescription-points": { "en": [ @@ -944,14 +737,10 @@ const Map localizedValues = { "الاطلاع على اسعار الادوية المصروفة." ] }, - "info-insurance-cards": { - "en": - "This service allows you to view all the insurance cards that recorded during your visits to Al Habib Medical Group in addition to:", - "ar": - "خدمة بطاقات التامين: هذه الخدمة تمكنك من الاطلاع على جميع بطاقات التامين والتي تم تسجيلها اثناء زياراتك لمجموعة الحبيب الطبية بالاضافة الى:" + "en": "This service allows you to view all the insurance cards that recorded during your visits to Al Habib Medical Group in addition to:", + "ar": "خدمة بطاقات التامين: هذه الخدمة تمكنك من الاطلاع على جميع بطاقات التامين والتي تم تسجيلها اثناء زياراتك لمجموعة الحبيب الطبية بالاضافة الى:" }, - "info-insurance-cards-points": { "en": [ "Name of the insurance company.", @@ -970,21 +759,14 @@ const Map localizedValues = { "تفاصيل التامين، مثلاً: مستوى الغرفة التي يغطيها التامين وكذلك الحالات التي يغطيها التامين.", ] }, - "info-allergies": { - "en": - "This service allows you to view all types of allergies recorded during your visits to Al Habib Medical Group.", - "ar": - "خدمة الحساسية: هذه الخدمة تمكنك من الاطلاع على جميع انواع الحساسية التي تم تسجيلها خلال زياراتك في مجموعة الحبيب الطبية." + "en": "This service allows you to view all types of allergies recorded during your visits to Al Habib Medical Group.", + "ar": "خدمة الحساسية: هذه الخدمة تمكنك من الاطلاع على جميع انواع الحساسية التي تم تسجيلها خلال زياراتك في مجموعة الحبيب الطبية." }, - "sick-leaves": {"en": "Sick Leaves", "ar": "الاجازات المرضية"}, - "info-sick-leaves": { - "en": - "This service allows you to view all sick leaves that were taken in Al Habib Medical Group in addition to:", - "ar": - "الاجازات المرضية: هذه الخدمة تمكنك من الاطلاع على جميع الاجازات المرضية والتي تم اصدارها في مجموعة الحبيب الطبية بالاضافة الى:" + "en": "This service allows you to view all sick leaves that were taken in Al Habib Medical Group in addition to:", + "ar": "الاجازات المرضية: هذه الخدمة تمكنك من الاطلاع على جميع الاجازات المرضية والتي تم اصدارها في مجموعة الحبيب الطبية بالاضافة الى:" }, "info-sick-leave-points": { "en": [ @@ -994,22 +776,12 @@ const Map localizedValues = { "Branch that patient take the vaccination form.", "Sending a report of vaccinations to the email. ", ], - "ar": [ - "اسم الطبيب", - "تاريخ الاجازة.", - "عدد ايام الاجازة.", - "الفرع الذي تم اصدار الاجازة منه.", - "ارسال نسخة مختومة من الاجازة الى البريد الالكتروني." - ] + "ar": ["اسم الطبيب", "تاريخ الاجازة.", "عدد ايام الاجازة.", "الفرع الذي تم اصدار الاجازة منه.", "ارسال نسخة مختومة من الاجازة الى البريد الالكتروني."] }, - "info-approvals": { - "en": - "This service allows you to view all approvals requests that have been sent to the insurance companies in addition to:", - "ar": - "خدمة الموافقات: هذه الخدمة تمكنك من الاطلاع على جميع طلبات الموافقات والتي تم ارسالها الى شركات التامين بالاضافة الى:" + "en": "This service allows you to view all approvals requests that have been sent to the insurance companies in addition to:", + "ar": "خدمة الموافقات: هذه الخدمة تمكنك من الاطلاع على جميع طلبات الموافقات والتي تم ارسالها الى شركات التامين بالاضافة الى:" }, - "info-approval-points": { "en": [ "View the total unused approvals.", @@ -1020,42 +792,22 @@ const Map localizedValues = { "تتبع حالة الموافقة.", ] }, - "month-report": {"en": "Monthly Reports", "ar": "تقاريري الشهرية"}, "info-month-report": { "en": "Upon activation of this service, the system will send a monthly report automatically to the registered email which lists the vital signs and the results for the last visits made in AlHabib Medical Group.", - "ar": - "خدمة التقارير الشهرية: عند تفعيل هذه الخدمة سيقوم النظام بارسال تقرير شهري بشكل آلي على الايميل المسجل والذي يسرد المؤشرات الحيوية ونتائج التحاليل لآخر زيارات تمت بمجموعة الحبيب الطبية." - }, - "language-setting": { - "en": "SMS and Confirmation Calls Language", - "ar": "لغة الرسائل القصيرة و الاتصال الآلي" + "ar": "خدمة التقارير الشهرية: عند تفعيل هذه الخدمة سيقوم النظام بارسال تقرير شهري بشكل آلي على الايميل المسجل والذي يسرد المؤشرات الحيوية ونتائج التحاليل لآخر زيارات تمت بمجموعة الحبيب الطبية." }, + "language-setting": {"en": "SMS, WhatsApp and Confirmation Calls Language", "ar": "لغة الرسائل القصيرة والواتس اب وتأكيد المكالمات"}, "alert": {"en": "Alerts", "ar": "التنبيهات"}, - "email-alert": { - "en": "Alert By Email", - "ar": "استلام التنبيهات بالبريد الالكتروني" - }, - "sms-alert": { - "en": "Alert By SMS", - "ar": "استلام التنبيهات بالرسائل القصيرة" - }, + "email-alert": {"en": "Alert by Email", "ar": "استلام التنبيهات بالبريد الالكتروني"}, + "sms-alert": {"en": "Alert by SMS", "ar": "استلام التنبيهات بالرسائل القصيرة"}, "contact-info": {"en": "Contact Information", "ar": "معلومات التواصل"}, - "emrg-name": { - "en": "Emergency Contact Name", - "ar": "اسم للتواصل في حالة الطوارئ" - }, - "emrg-no": { - "en": "Emergency Contact Number", - "ar": "رقم للتواصل في حالة الطوارئ" - }, + "emrg-name": {"en": "Emergency Contact Name", "ar": "اسم للتواصل في حالة الطوارئ"}, + "emrg-no": {"en": "Emergency Contact Number", "ar": "رقم للتواصل في حالة الطوارئ"}, "modes": {"en": "Modes", "ar": "الاوضاع"}, "vibration": {"en": "Vibration Touch Feedback", "ar": "الاهتزاز عند اللمس"}, - "blind-modes": { - "en": "Modes for Partially Blind", - "ar": "تأثيرات لدعم ضعاف البصر" - }, + "blind-modes": {"en": "Modes for Partially Blind", "ar": "تأثيرات لدعم ضعاف البصر"}, "invert-theme": {"en": "Invert", "ar": "ألوان سلبية"}, "off-theme": {"en": "Off", "ar": "إيقاف"}, "dim-theme": {"en": "Dim", "ar": "ضوء خافت"}, @@ -1063,7 +815,10 @@ const Map localizedValues = { "permissions": {"en": "Permission", "ar": "الصلاحيات"}, "camera-permission": {"en": "Camera", "ar": "الكاميرا"}, "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": "الغاء الطلب"}, @@ -1072,20 +827,14 @@ const Map localizedValues = { "LiveChat": {"en": "Live Chat", "ar": "محادثة مباشرة"}, "Service": {"en": "Service", "ar": "خدمة"}, "HMGServiceLabel": {"en": "HMG Service", 'ar': 'خدمات الحبيب'}, - "HealthWeatherIndicators": { - "en": "Health Weather Indicators", - 'ar': ' مؤشرات الطقس الصحية ' - }, - "HealthTipsBasedOnCurrentWeather": { - "en": "Health Tips Based On Current Weather", - 'ar': ' نصائح صحية على أساس الطقس الحالي ' - }, + "HealthWeatherIndicators": {"en": "Health Weather Indicators", 'ar': ' مؤشرات الطقس الصحية '}, + "HealthTipsBasedOnCurrentWeather": {"en": "Health Tips Based On Current Weather", 'ar': ' نصائح صحية بناءاً على الطقس الحالي '}, "MoreDetails": {"en": "More details", "ar": " المزيد من التفاصيل "}, "SendCopy": {"en": "Send Copy", "ar": "ارسال نسخة"}, - "ResendOrder": {"en": "Resend order & deliver", "ar": "إعادة طلب و توصيل"}, + "ResendOrder": {"en": "Refill & Delivery", "ar": "إعادة صرف وتوصيل"}, "Ports": {"en": "Ports", "ar": "المنافذ"}, - "Way": {"en": "Way", "ar": "الطزيقة"}, - "Average": {"en": "Average", "ar": "المعدل"}, + "Way": {"en": "Way", "ar": "الطريقة"}, + "Average": {"en": "Average", "ar": "متوسط"}, "DailyDoses": {"en": "Daily Doses", "ar": "جرعات يومية"}, "Period": {"en": "Period", "ar": "الفترة"}, "duration": {"en": "Duration", "ar": "المدة"}, @@ -1094,81 +843,66 @@ const Map localizedValues = { "kg": {"en": "kg", "ar": "كجم"}, "lb": {"en": "lb", "ar": "رطل"}, "birth_date": {"en": "Birth Date", "ar": "تاريخ الميلاد"}, + "date_of_birth": {"en": "Date of Birth", "ar": "تاريخ الولادة"}, "mass": {"en": "Mass", "ar": "كتلة"}, "temp-c": {"en": "°C", "ar": "°س"}, "bpm": {"en": "bpm", "ar": "نبضة"}, "respiration-signs": {"en": "Respiration", "ar": "تنفس"}, "sys-dias": {"en": "SBP/DBP", "ar": "إنقباض/إنبساط"}, - "body": {"en": "Body \n Mass", "ar": "كتلة\nالجسم"}, + "body": {"en": "Body Mass", "ar": "كتلة\nالجسم"}, + "body_string": {"en": "Body", "ar": "الجسم"}, + "face": {"en": "Face", "ar": "وجه"}, + "retouch": {"en": "Retouch", "ar": "روتوش"}, + "bikini": {"en": "Bikini", "ar": "بيكيني"}, + "totalMinutes": {"en": "Total Minutes", "ar": "إجمالي الدقائق"}, "feedback": {"en": "Feedback", "ar": "رأيك يهمنا"}, "send": {"en": "Send", "ar": "أرسل"}, "status": {"en": "Status", "ar": "الحالة"}, "like-to-hear": { - "en": - "We would love to hear the feedback, concerns on healthcare services and eServices experience. Please use the below form", - "ar": - "يسعدنا سماع ملاحظاتك حول خدمات الرعاية الصحية والخدمات الإلكترونية. يرجى تعبئة الحقول المطلوبة" + "en": "We would love to hear the feedback, concerns on healthcare services and eServices experience. Please use the below form", + "ar": "يسعدنا سماع ملاحظاتك حول خدمات الرعاية الصحية والخدمات الإلكترونية. يرجى تعبئة الحقول المطلوبة" }, "subject": {"en": "Subject", "ar": "الموضوع"}, "message": {"en": "Message", "ar": "رسالة"}, - "empty-subject": { - "en": "Please enter the subject", - "ar": "يرجى ادخال الموضوع" - }, + "empty-subject": {"en": "Please enter the subject", "ar": "يرجى ادخال الموضوع"}, "empty-message": {"en": "Please enter message", "ar": "يرجى ادخال الرسالة"}, "select-attachment": {"en": "Select Attachment", "ar": "إختر المرفق"}, "complain-appo": {"en": "Complaint for appointment", "ar": "شكوى على موعد"}, - "complain-without-appo": { - "en": "Complaint without appointment", - "ar": "شكوى بدون موعد" - }, + "complain-without-appo": {"en": "Complaint without appointment", "ar": "شكوى بدون موعد"}, "question": {"en": "Question", "ar": "سؤال"}, "message-type": {"en": "Message Type", "ar": "نوع الرسالة"}, - "compliment": {"en": "compliment", "ar": "ثناء"}, + "feedback-type": {"en": "Feedback Type", "ar": "نوع الرسالة"}, + "compliment": {"en": "Appreciation", "ar": "تقدير"}, "suggestion": {"en": "Suggestion", "ar": "إقتراح"}, - "your-feedback": { - "en": "Your feedback was sent", - "ar": "لقد تم ارسال اقراحك شكرا لك" - }, - "select-part": { - "en": "Please select the part that complain about", - "ar": "يرجى تحديد الجزء الذي تشكو منه" - }, + "your-feedback": {"en": "Your feedback was sent", "ar": "لقد تم ارسال اقتراحك شكرا لك"}, + "select-part": {"en": "Please select the part that complain about", "ar": "يرجى تحديد الجزء الذي تشكو منه"}, "number": {"en": "Number", "ar": "الرقم"}, "not-classified": {"en": "Not classified", "ar": "غير محدد"}, - "selectClinic": {"en": "Select Clinic", "ar": " بحث بالعيادة"}, - "searchItemError": { - "en": "Item name should be more than 3 character ", - "ar": "يجب أن يكون اسم العنصر أكثر من 3 أحرف" - }, + "selectClinic": {"en": "Select Clinic", "ar": "اختر بالعيادة"}, + "selectProject": {"en": "Select Hospital", "ar": " بحث المستشفى"}, + "searchItemError": {"en": "Item name should be more than 3 character ", "ar": "يجب أن يكون الاسم المدخل أكثر من 3 أحرف"}, "YouCanFind": {"en": "You Can Find ", "ar": "باستطاعتك العثور على "}, - "ItemInSearch": {"en": " Item In Search", "ar": " عنصر في البحث "}, + "ItemInSearch": {"en": " Item in Search", "ar": " عنصر في البحث "}, "blood-donation": {"en": "Blood Donation", "ar": "التبرع بالدم"}, - "blood-instruction": { - "en": - "Enter the required information, In order to register for Blood Donation Service", - "ar": "ادخل المعلومات المطلوبة للتسجيل بخدمة التبرع بالدم" - }, - "view-terms": { - "en": "To view the terms and conditions", - "ar": "عرض الشروط والأحكام" + "blood-donation-info": { + "en": "Through this service, you can register your name as a blood donor where the blood bank in the Habib Medical Group will communicate you in case of need for blood type.", + "ar": "عن طريق هذه الخدمة تستطيع تسجيل اسمك كمتبرع بالدم حيث سيتم التواصل معك عن طريق بنك الدم في مجموعة الحبيب الطبية في حال الحاجة الى فصيلة الدم." }, + "blood-instruction": {"en": "Enter the required information, in order to register for Blood Donation Service", "ar": "ادخل المعلومات المطلوبة للتسجيل بخدمة التبرع بالدم"}, + "view-terms": {"en": "To view the terms and conditions", "ar": "عرض الشروط والأحكام"}, "wantConnectHmgNetwork": { - "en": - "Dear customer there is no internet access, Do you want to connect with HMG network to use our app, make sure you are in range of HMG network", - "ar": - "عزيز العميل لا يوجد اتصال بالإنترنت, هل تريد الاتصال بشبكة مستشفى د. سليمان الحبيب لاستخدام التطبيق. يجب عليك ان تكون في نطاق شبكة المستشفى" - }, - "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" + "en": "Dear customer there is no internet access, do you want to connect with HMG network to use our app, make sure you are in range of HMG network", + "ar": "عزيز العميل لا يوجد اتصال بالإنترنت, هل تريد الاتصال بشبكة مستشفى د. سليمان الحبيب لاستخدام التطبيق. يجب عليك ان تكون في نطاق شبكة المستشفى" }, - "offerAndPackages": {"en": "Offers And Packages", "ar": "العروض والباقات"}, + "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": "نتيجة خاصة"}, "GeneralResult": {"en": "General Result", "ar": "نتيجة عامة"}, "show-more-btn": {"en": "Flow Chart", "ar": "النتائج التراكمية"}, - + "view_flow_chart": {"en": "View Flowchart", "ar": "النتائج التراكمية"}, "value": {"en": "Value", "ar": "القيمة"}, "range": {"en": "Range", "ar": "المدى"}, "out-patient": {"en": "Out Patient", "ar": "عيادات خارجية"}, @@ -1176,9 +910,9 @@ const Map localizedValues = { "report": {"en": "Radiology Report", "ar": "تقرير الاشعة"}, "open-rad": {"en": "Open Image", "ar": "فتح صور الاشعة"}, "send-copy": {"en": "Email the Report", "ar": "أرسل التقرير"}, - "appoSurvey": {"en": "Survey", "ar": "إستبيان"}, - "appoSurveySubtitle": {"en": "Survey", "ar": "إستبيان"}, - "labResults": {"en": "Lab Result", "ar": "نتيجة المختبر"}, + "appoSurvey": {"en": "Survey", "ar": "الاستبيان"}, + "appoSurveySubtitle": {"en": "Survey", "ar": "الاستبيان"}, + "labResults": {"en": "Lab Results", "ar": "نتيجة المختبر"}, "doctorRating": {"en": "Doctor Rating", "ar": "تقييم الطبيب"}, "good": {"en": "Good", "ar": "جيد"}, "v-good": {"en": "Very Good", "ar": "جيد جدا"}, @@ -1186,40 +920,28 @@ const Map localizedValues = { "average": {"en": "Average", "ar": "متوسط"}, "below-average": {"en": "Below Average", "ar": "أقل من المتوسط"}, "info-signs": { - "en": - "This service allows you to view all vital signs were performed in the Habib Medical Group, e.x (height, weight, body mass index, heart rate, etc.) as well shows some statistics charts.", + "en": "This service allows you to view all vital signs were performed in the Habib Medical Group, e.x (height, weight, body mass index, heart rate, etc.) as well shows some statistics charts.", "ar": - "خدمة المؤشرات الحيوية: هذه الخدمة تمكنك من الاطلاع على جميع المؤشرات الحيوية على سبيل المثال (الطول، الوزن، مؤشر كتلة الجسم، معدل نبضات القلب الخ..) التي تمت في مجموعة الحبيب الطبية وكذلك رسوم بيانية على مستوى المؤشر." + "خدمة المؤشرات الحيوية: هذه الخدمة تمكنك من الاطلاع على جميع المؤشرات الحيوية على سبيل المثال (الطول، الوزن، مؤشر كتلة الجسم، معدل نبضات القلب الخ.) التي تمت في مجموعة الحبيب الطبية وكذلك رسوم بيانية على مستوى المؤشر." }, "info-advance-payment": { - "en": - "This service designed so that you can deposit an amount in advance either in your account or in someone else's account with Al Habib Medical Group.", - "ar": - "تم تصميم هذه الخدمة حتى تتمكن من دفع مبلغ مقدما او تحت الحساب سواء في حسابك او في حساب شخص اخر لدى مجموعة الحبيب الطبية." - }, - "info-my-balance": { - "en": "This service allows you to check your balance in all branchs", - "ar": "هذه الخدمه تتيح لك الاطلاع رصيدك في كل الفروع" + "en": "This service designed so that you can deposit an amount in advance either in your account or in someone else's account with Al Habib Medical Group.", + "ar": "تم تصميم هذه الخدمة حتى تتمكن من دفع مبلغ مقدما او تحت الحساب سواء في حسابك او في حساب شخص اخر لدى مجموعة الحبيب الطبية." }, + "info-my-balance": {"en": "This service allows you to check your balance in all branchs", "ar": "هذه الخدمه تتيح لك الاطلاع رصيدك في كل الفروع"}, "er-contant": { - "en": - "This service displays nearest branch among all the branches of Al Habib Medical Group based on your current location.", - "ar": - "تعرض هذه الخدمة أقرب فرع من بين جميع فروع مجموعة الحبيب الطبية بناءً على موقعك الحالي." + "en": "This service displays nearest branch among all the branches of Al Habib Medical Group based on your current location.", + "ar": "تعرض هذه الخدمة أقرب فرع من بين جميع فروع مجموعة الحبيب الطبية بناءً على موقعك الحالي." }, "er": {"en": "ER", "ar": "الطوارىء"}, - "transportation-Service": {"en": "Ambulance Request", "ar": "طلب نقل اسعاف"}, + "transportation-Service": {"en": "Ambulance Request", "ar": "خدمات النقل الاسعافي"}, "info-ambulance": { - "en": - "Through this service, you can request evacuation by ambulance, whether from home or to home, in addition to a set of other services", - "ar": - "عن طريق هذه الخدمة يمكنك طلب اخلاء بواسطة سيارة اسعاف سواء من المزل او الى المنزل بالاضافة الى مجموعة من الخدمات الاخرى" - }, - "RRT-transport-heading": { - "en": "Select Transportation Method", - "ar": "حدد طريقة النقل" + "en": "Through this service, you can request evacuation by ambulance, whether from home or to home, in addition to a set of other services", + "ar": "عن طريق هذه الخدمة يمكنك طلب اخلاء بواسطة سيارة اسعاف سواء من المزل او الى المنزل بالاضافة الى مجموعة من الخدمات الاخرى" }, + "RRT-transport-heading": {"en": "Select Transportation Method", "ar": "حدد طريقة النقل"}, "RRT-direction-heading": {"en": "Select Direction", "ar": "حدد الاتجاه"}, + "RRT-way-heading": {"en": "Select Way", "ar": "حدد الطريق"}, "to-hospital": {"en": "To Hospital", "ar": "الى المستشفى"}, "from-hospital": {"en": "From Hospital", "ar": "من المستشفى"}, "one-direc": {"en": "One Way", "ar": "ذهاب"}, @@ -1227,84 +949,59 @@ const Map localizedValues = { "pickup-location": {"en": "Pickup Location", "ar": "نقطة الانطلاق"}, "pickup-spot": {"en": "Pickup Spot", "ar": "نقطة اللقاء"}, "inside-home": {"en": "Inside Home", "ar": "داخل المنزل"}, - "have-appo": {"en": "Do you have an appointment ?", "ar": "هل لديك موعد ؟"}, + "have-appo": {"en": "Do you have an appointment?", "ar": "هل لديك موعد ؟"}, "dropoff-location": {"en": "Dropoff Location", "ar": "نقطة الوصول"}, - "select-all": { - "en": "Please select all fields", - "ar": "يرجى تحديد جميع الحقول" - }, - "select-map": {"en": "Select From Map", "ar": "حدد من الخريطة"}, - "no-appointment": { - "en": "You don't have any appointments yet", - "ar": "ليس لديك أي مواعيد حتى الآن" - }, + "select-all": {"en": "Please select all fields", "ar": "يرجى تحديد جميع الحقول"}, + "select-map": {"en": "Select from Map", "ar": "حدد من الخريطة"}, + "no-appointment": {"en": "You don't have any appointments yet", "ar": "ليس لديك أي مواعيد حتى الآن"}, "patient-share": {"en": "Amount before tax: ", "ar": "المبلغ قبل الضريبة:"}, "patient-share-tax": {"en": "Tax amount: ", "ar": "قيمة الضريبة:"}, - "patient-share-total": { - "en": "Total amount payable: ", - "ar": "المبلغ الإجمالي المستحق:" - }, + "patient-share-total": {"en": "Total amount payable: ", "ar": "المبلغ الإجمالي المستحق:"}, "select-ambulate": {"en": "Select Ambulate", "ar": "بحاجة للتنقل بواسطة"}, "wheelchair": {"en": "Wheelchair", "ar": "كرسي متحرك"}, "walker": {"en": "Walker", "ar": "مشاية"}, "stretcher": {"en": "Stretcher", "ar": "نقالة"}, "none": {"en": "None", "ar": "لا شيء"}, "RRT-Summary": {"en": "Summary", "ar": "ملخص الطلب"}, + "Rapid-Response-Team": {"en": "Rapid Response Team", "ar": "فريق الاستجابة السريع"}, + "AmountBeforeTax": {"en": "Amount Before Tax:", "ar": "المبلغ قبل الضريبة:"}, + "ApproximateServiceFee": {"en": "Service fee starting from", "ar": "تبدأ رسوم الخدمة من"}, + "TaxAmount": {"en": "Tax Amount:", "ar": "مبلغ الضريبة:"}, + "somethingWentWrongTryLater": {"en": "Sorry something went wrong please try again later", "ar": "نعتذر عن خدمتك يرجى المحاولة لاحقا"}, + "TotalAmountPayable": {"en": "Total Amount Payable:", "ar": " إجمالي المبلغ المستحق:"}, + "iAcceptTermsConditions": {"en": "I Accept the Terms and Conditions", "ar": "أوافق على الشروط والأحكام"}, + "YouCanPayByTheFollowingOptions": {"en": "You can pay by the following options:", "ar": "يمكنك الدفع عن طريق الخيارات التالية:"}, + "RRTDDetails": { + "en": + "The Rapid response team provides a comprehensive medical service for all sorts of urgent and stable cases of all ages, including adult and paediatric patients, the service is covered by a fully equipped and highly trained medical team capable of providing the best medical care at the patient’s home.", + "ar": + "فريق الاستجابة السريعة يقوم بتقديم رعاية صحية متكاملة لجميع الحالات الطارئة و المستقرة، الخدمة تشمل جميع الأعمار بما في ذلك حالات الأطفال، تشمل الخدمة إرسال فريق طبي كامل الجاهزية و على مستوى عالي من التدريب قادر على تقديم أفضل رعاية صحية من داخل المنزل." + }, + "rrtService": {"en": "RRT Service", "ar": "خدمة RRT"}, "bill-amount": {"en": "Bill Amount", "ar": "مبلغ الفاتورة"}, "transport-method": {"en": "Transportation Method", "ar": "طريقة النقل"}, "directions": {"en": "Directions", "ar": "الاتجاهات"}, "info-my-appointments": { - "en": - "This service allows you to see all the appointment you have visited in Al Habib Medical Group, and through this service:", - "ar": - "خدمة مواعيدي: هذه الخدمة تمكنك من الاطلاع على جميع المواعيد التي قمت بزيارتهم في مجموعة الحبيب الطبية, كما تستطيع من خلال هذه الخدمة:" + "en": "This service allows you to see all the appointment you have visited in Al Habib Medical Group, and through this service:", + "ar": "خدمة مواعيدي: هذه الخدمة تمكنك من الاطلاع على جميع المواعيد التي قمت بزيارتهم في مجموعة الحبيب الطبية, كما تستطيع من خلال هذه الخدمة:" }, "info-todo": { - "en": - "This service is designed to enable you to have a quick link to the list of tasks that need to be done", - "ar": - "هذه الخدمة تم تصميمها لتمكنك من الوصول الى رابط سريع لقائمة المهام التي يجب القيام بها" + "en": "This service is designed to enable you to have a quick link to the list of tasks that need to be done", + "ar": "هذه الخدمة تم تصميمها لتمكنك من الوصول الى رابط سريع لقائمة المهام التي يجب القيام بها" }, "family-info": { - "en": - "Through this service, you will be able to link your family medical files to your medical file so that you can manage their records by login to your medical file.", - "ar": - "هذه الخدمة تم تصميمها لتتمكن من ربط الملفات الطبية للعائلة بملفك الطبي حتى تتمكن من إدارة سجلاتهم عن طريق تسجيل الدخول إلى ملفك الطبي." - }, - "update-succ": { - "en": "Successfully updated profile", - "ar": "تم تحديث البيانات بنجاح" + "en": "Through this service, you will be able to link your family medical files to your medical file so that you can manage their records by login to your medical file.", + "ar": "هذه الخدمة تم تصميمها لتتمكن من ربط الملفات الطبية للعائلة بملفك الطبي حتى تتمكن من إدارة سجلاتهم عن طريق تسجيل الدخول إلى ملفك الطبي." }, + "update-succ": {"en": "Successfully updated profile", "ar": "تم تحديث البيانات بنجاح"}, "dental-complains": {"en": "Symptoms", "ar": "الأعراض"}, - "empty-result": { - "en": "There is no search results found", - "ar": "لايوجد نتائج" - }, - - "no-booked-appointment": { - "en": "No booked appointments", - "ar": "لا يوجد مواعيد محجوزة" - }, - "no-confirmed-appointment": { - "en": "No confirmed appointments", - "ar": "لا توجد مواعيد مؤكدة" - }, - "no-arrived-appointment": { - "en": "No arrived appointments", - "ar": "لا يوجد مواعيد" - }, - "upcoming-empty": { - "en": "You do not have any Todo actions yet.", - "ar": "ليس لديك أي إجراءات الآن." - }, - "upcoming-timeLeft": { - "en": "time left for appointment", - "ar": "الوقت المتبقي للموعد" - }, - "covid-test-all-services": { - "en": "Covid-19 Drive-Thru Test", - "ar": "فحص كورونا من داخل السيارة" - }, + "empty-result": {"en": "There is no search results found", "ar": "لايوجد نتائج"}, + "no-booked-appointment": {"en": "No booked appointments", "ar": "لا يوجد مواعيد محجوزة"}, + "no-confirmed-appointment": {"en": "No confirmed appointments", "ar": "لا توجد مواعيد مؤكدة"}, + "no-arrived-appointment": {"en": "No arrived appointments", "ar": "لا يوجد مواعيد"}, + "upcoming-empty": {"en": "You do not have any Todo actions yet.", "ar": "ليس لديك أي إجراءات الآن."}, + "upcoming-timeLeft": {"en": "time left for appointment", "ar": "الوقت المتبقي للموعد"}, + "covid-test-all-services": {"en": "Covid-19 Drive-Thru Test", "ar": "فحص كورونا من داخل السيارة"}, "pharmacy": {"en": "Pharmacy", "ar": "الصيدلية"}, "ereferral": {"en": "E-Referral", "ar": "طلب التحويل"}, "child-vaccine": {"en": "Child Vaccines", "ar": "تطعيمات الأطفال"}, @@ -1317,99 +1014,53 @@ const Map localizedValues = { "blood-d": {"en": "Blood Donation", "ar": "تبرع بالدم"}, "symptomCheckerTitle": {"en": "Symptom Checker", "ar": "مدقق الأعراض"}, "latest-news": {"en": "Latest News", "ar": "أحدث الأخبار"}, - "our-location": {"en": "Our Locations", "ar": "موقعنا"}, + "our-location": {"en": "Our Locations", "ar": "مواقعنا"}, "pharmacies": {"en": "Pharmacies", "ar": "الصيدليات"}, "hospitals": {"en": "Hospitals", "ar": "المستشفيات"}, "wallet": {"en": "Wallet", "ar": "محفظة نقود"}, "hmg": {"en": "Al Habib", "ar": "الحبيب"}, - "requested": {"en": "Requested", "ar": "مطلوب"}, "ready": {"en": "Ready", "ar": "جاهز"}, "completed": {"en": "Completed", "ar": "مكتمل"}, - - "request-medical-report": { - "en": "Request medical report", - "ar": "طلب تقرير طبي" - }, + "request-medical-report": {"en": "Request medical report", "ar": "طلب تقرير طبي"}, "insur-cards": {"en": "Insurance Cards", "ar": "بطاقات التأمين"}, 'labResult': {"en": "Lab results", "ar": "نتائج التحاليل المخبرية"}, 'details': {'en': 'Details', 'ar': 'التفاصيل'}, + 'graph-details': {'en': 'Graph Details', 'ar': 'التفاصيل الرسم البياني'}, "age": {"en": "Age", "ar": "العمر"}, "active-insurence": {"en": "Active", "ar": "نشطة"}, "not-active": {"en": "Not Active", "ar": "غير نشط"}, "card-detail": {"en": "Insurance Details", "ar": "منافعك التامينية"}, "Dr": {"en": "Dr. ", "ar": "الدكتور."}, "empty": {"en": "You do not have any records.", "ar": "ليس لديك أي سجلات"}, - "last-visit": { - "en": "How was your last visit with doctor?", - "ar": "كيف تقيم زيارتك الأخيرة للطبيب؟" - }, + "last-visit": {"en": "How was your last visit with doctor?", "ar": "كيف تقيم زيارتك الأخيرة للطبيب؟"}, "tap-title": {"en": "Please rate the doctor", "ar": "يرجى تقييم الطبيب"}, "later": {"en": "Later", "ar": "لاحقاً"}, - "sendSuc": { - "en": "A copy has been sent to the email", - "ar": "تم إرسال نسخة إلى البريد الإلكتروني" - }, + "sendSuc": {"en": "A copy has been sent to the email", "ar": "تم إرسال نسخة إلى البريد الإلكتروني"}, "instructions": { - "en": - "You can now talk directly to the appointments department by chat or request a call back", - "ar": - "يمكنك الان التحدث مباشرة مع قسم المواعيد عن طريق خدمة المحادثة النصية أو طلب معاودة الاتصال" - }, - "instructions-pharmacies": { - "en": - "You can now talk directly to the pharmacist by chat or request a call back", - "ar": - "يمكنك الآن التحدث مباشرة إلى الصيدلي عن طريق الدردشة أو طلب معاودة الاتصال" + "en": "You can now talk directly to the appointments department by chat or request a call back", + "ar": "يمكنك الان التحدث مباشرة مع قسم المواعيد عن طريق خدمة المحادثة النصية أو طلب معاودة الاتصال" }, - "select-hospital": {"en": "Choose Hospital", "ar": "اختر المستشفى"}, + "instructions-pharmacies": {"en": "You can now talk directly to the pharmacist by chat or request a call back", "ar": "يمكنك الآن التحدث مباشرة إلى الصيدلي عن طريق الدردشة أو طلب معاودة الاتصال"}, + "select-hospital": {"en": "Choose Hospital", "ar": "اختر المستشفىالمستشفى"}, "start": {"en": "Start", "ar": "ابدأ"}, "info-chat": { - "en": - "This service allows you to chat with customer service directly without the need to call.", - "ar": - "المحادثة المباشرة: هذه الخدمة تمكنك التحدث كتابياً مع خدمة العملاء مباشرة دون الحاجة الى الاتصال هاتفياً." - }, - "last-appointment": { - "en": "How was your appointment?", - "ar": "كيف كان موعدك الطبي ؟" + "en": "This service allows you to chat with customer service directly without the need to call.", + "ar": "المحادثة المباشرة: هذه الخدمة تمكنك التحدث كتابياً مع خدمة العملاء مباشرة دون الحاجة الى الاتصال هاتفياً." }, + "last-appointment": {"en": "How was your appointment?", "ar": "كيف كان موعدك الطبي ؟"}, "rate-clinic": {"en": "Please rate the clinic", "ar": "يرجى تقييم العيادة"}, "fetch-data": {"en": "Fetch Data", "ar": "تحديث الان"}, "rate": {"en": "Rate", "ar": "تقييم"}, - "send-email": { - "en": "Send a copy of this report to the email", - "ar": "أرسل نسخة من هذا التقرير إلى البريد الإلكتروني" - }, - "update-email-msg": { - "en": "Email updated", - "ar": "تم تحديث البريد الالكتروني" - }, + "send-email": {"en": "Send a copy of this report to the email", "ar": "أرسل نسخة من هذا التقرير إلى البريد الإلكتروني"}, + "update-email-msg": {"en": "Email updated", "ar": "تم تحديث البريد الالكتروني"}, "update-email": {"en": "Update Email", "ar": "تحديث البريد الالكتروني"}, - "booked-success": { - "en": "The appointment has been successfully booked.", - "ar": "لقد تم حجز الموعد بنجاح" - }, - "appo-reminder-select-option-30": { - "en": "Before 30 Mins", - "ar": "قبل 30 دقيقة" - }, - "appo-reminder-select-option-60": { - "en": "Before 1 Hour", - "ar": "قبل ساعة واحدة" - }, - "appo-reminder-select-option-90": { - "en": "Before 1 Hour and 30 mins", - "ar": "قبل ساعة و 30 دقيقة" - }, - "appo-reminder-select-option-120": { - "en": "Before 2 Hours", - "ar": "قبل ساعتين" - }, - "noDataAvailable": { - "en": "No data available", - "ar": " لا يوجد بيانات متاحة " - }, + "booked-success": {"en": "The appointment has been successfully booked.", "ar": "لقد تم حجز الموعد بنجاح"}, + "appo-reminder-select-option-30": {"en": "Before 30 Mins", "ar": "قبل 30 دقيقة"}, + "appo-reminder-select-option-60": {"en": "Before 1 Hour", "ar": "قبل ساعة واحدة"}, + "appo-reminder-select-option-90": {"en": "Before 1 Hour and 30 mins", "ar": "قبل ساعة و 30 دقيقة"}, + "appo-reminder-select-option-120": {"en": "Before 2 Hours", "ar": "قبل ساعتين"}, + "noDataAvailable": {"en": "No data available", "ar": " لا يوجد بيانات متاحة "}, "thename": {"en": "The Name", "ar": "الاسم"}, "noSearchResult": {"en": "No Search Result", "ar": "لا توجد نتيجة بحث"}, "selectFileSouse": {"en": "Select file souse", "ar": "حدد الملف"}, @@ -1417,193 +1068,108 @@ const Map localizedValues = { "camera": {"en": "Camera", "ar": "كاميرا"}, "med-report": {"en": "Medical Reports", "ar": "التقارير الطبية"}, "new-med-report": {"en": "Requests", "ar": "الطلبات"}, - "requestReport": {"en": "Request a report", "ar": " طلب تقرير"}, - "confirm-msg-report": { - "en": "Request for medical report?", - "ar": "طلب تقرير طبي؟" - }, - "successSendReport": { - "en": "The request has been submitted successfully", - "ar": "تم تنفيذ طلبك بنجاح" - }, + "requestReport": {"en": "Request a report", "ar": "طلب تقرير"}, + "confirm-msg-report": {"en": "Request for medical report?", "ar": "طلب تقرير طبي؟"}, + "successSendReport": {"en": "The request has been submitted successfully", "ar": "تم تنفيذ طلبك بنجاح"}, "pulseTitle": {"en": "Heart rate", "ar": "معدل النبض بالدقيقة"}, "systolic-lng": {"en": "Systolic", "ar": "الإنقباض"}, "diastolic-lng": {"en": "Diastolic", "ar": "الإنبساط"}, "policy-holder": {"en": "Policy Holder", "ar": "حامل بطاقة التأمين"}, - "policy-no": {"en": "Policy Number", "ar": "رقم سياسات"}, - "agree": { - "en": "I agree, this is the correct information", - "ar": "موافق، هذه المعلومات صحيحة" - }, - "disagree": { - "en": "No, this is not the correct information", - "ar": "غير موافق، هذه المعلومات غير الصحيحة" - }, + "policy-no": {"en": "Policy Number", "ar": "رقم السياسة"}, + "agree": {"en": "I agree, this is the correct information", "ar": "موافق، هذه المعلومات صحيحة"}, + "disagree": {"en": "No, this is not the correct information", "ar": "غير موافق، هذه المعلومات غير الصحيحة"}, "expiry-date": {"en": "Expiry Date", "ar": "تاريخ انتهاء الصلاحية"}, "class": {"en": "Class", "ar": "فئة"}, + "offersdiscount": {"en": "Offers", "ar": "العروض"}, + "explore": {"en": "Explore Now", "ar": "استكشف الآن"}, "approval": {"en": "Approval", "ar": "موافقة"}, "no-data": {"en": "No data found", "ar": "لاتوجد بيانات"}, "insurance-details": {"en": "Insurance Details", "ar": "تفاصيل التأمين"}, "nearest-hospital": {"en": "Nearest Hospital", "ar": "أقرب مستشفى"}, - "request-sent": { - "en": "Request sent successfully", - "ar": "تم إرسال الطلب بنجاح" - }, - "message-sent": { - "en": "Message sent successfully", - "ar": "تم إرسال الرسالة بنجاح" - }, + "submitReview": {"en": "Your review has been Submitted successfully", "ar": "تم إرسال التقييم بنجاح"}, + "request-sent": {"en": "Request sent successfully", "ar": "تم إرسال الطلب بنجاح"}, + "message-sent": {"en": "Message sent successfully", "ar": "تم إرسال الرسالة بنجاح"}, "sent-on": {"en": "Sent on", "ar": "أرسلت في"}, - "attach-insurace-image": { - "en": "Attach insurance card image", - "ar": "إرفاق صورة بطاقة التأمين" - }, - "upload-without-image": { - "en": "You can still submit, if you don't have Insurance Image", - "ar": "لا يزال بإمكانك الإرسال ، إذا لم يكن لديك صورة تأمين" - }, + "attach-insurace-image": {"en": "Attach insurance card image", "ar": "إرفاق صورة بطاقة التأمين"}, + "upload-without-image": {"en": "You can still submit, if you don't have Insurance Image", "ar": "لا يزال بإمكانك الإرسال ، إذا لم يكن لديك صورة تأمين"}, "info-insur-cards": { - "en": - "This service allows you to view all the insurance cards that recorded during your visits to Al Habib Medical Group in addition to:", - "ar": - "خدمة بطاقات التامين: هذه الخدمة تمكنك من الاطلاع على جميع بطاقات التامين والتي تم تسجيلها اثناء زياراتك لمجموعة الحبيب الطبية بالاضافة الى:" - }, - "scan-now": { - "en": "If you have a card / Document Scan now", - "ar": "إذا كانت لديك بطاقة / مستند ارفقها الان" + "en": "This service allows you to view all the insurance cards that recorded during your visits to Al Habib Medical Group in addition to:", + "ar": "خدمة بطاقات التامين: هذه الخدمة تمكنك من الاطلاع على جميع بطاقات التامين والتي تم تسجيلها اثناء زياراتك لمجموعة الحبيب الطبية بالاضافة الى:" }, + "scan-now": {"en": "If you have a card/Document Scan now", "ar": "إذا كانت لديك بطاقة / مستند ارفقها الان"}, "liveCare": {"en": "Live Care", "ar": "لايف كير"}, "topBrands": {"en": "Top Brands", "ar": "اعلى العلامات التجارية"}, - "notifyMe": {"en": "notify me", "ar": "اعلمني"}, "specification": {"en": "Specification", "ar": "تخصيص"}, - - "availability": {"en": "Availability", "ar": "التوفر"}, - + "availability": {"en": "Availability", "ar": "متوفر في"}, "vaccination": {"en": "Vaccination", "ar": "جدول التطعيمات"}, "welcomeBack": {"en": "Welcome back", "ar": "مرحبا مرة أخرى"}, "quantitySize": {"en": "Quantity", "ar": "كميه"}, - "addToCart": {"en": "add to cart", "ar": "إضفة للسلة"}, - "buyNow": {"en": "buy now", "ar": "إشتري الان"}, + "addToCart": {"en": "Add to Cart", "ar": "إضف للسلة"}, + "addToWishlist": {"en": "Add to Wishlist", "ar": "اضف للمفضلة"}, + "removeFromWishlist": {"en": "Remove From Wishlist", "ar": "احذف للمفضلة"}, + "noData": {"en": "There is no data", "ar": "لايوجد بيانات"}, + "no_data": {"en": "No data", "ar": "لايوجد بيانات"}, + "buyNow": {"en": "Buy Now", "ar": "إشتري الان"}, "quantityShortcut": {"en": "QTY", "ar": "كمية"}, - - "pharmacyServiceTermsCondition": { - "en": - "I agree with the terms of service and I adhere to them unconditionally", - "ar": " أوافق على شروط الخدمة وألتزم بها دون قيد أو شرط" - }, + "pharmacyServiceTermsCondition": {"en": "I agree with the terms of service and I adhere to them unconditionally", "ar": " موافق على شروط الخدمة وألتزم بها دون قيد أو شرط"}, "Year": {"en": "YEAR", "ar": "السنة"}, "Month": {"en": "MONTH", "ar": "الشهر"}, "point": {"en": "POINT", "ar": "النقاط"}, "riyal": {"en": "RIYAL", "ar": "الريال"}, "termOfService": {"en": "Terms of service", "ar": "شروط الخدمة"}, "shoppingCart": {"en": "Shopping Cart", "ar": "عربة التسوق"}, - "add-child": {"en": "Add New Child", "ar": "اضافة طفل"}, "child-name": {"en": "Child Name", "ar": "اسم الطفل"}, "childDob": {"en": "Birth Date", "ar": "تاريخ الولادة"}, - "deleted-child-mes": { - "en": - "The request was successful. The children have removed from the vaccination schedule subscription service.", - "ar": "تم حذف الطفل بنجاح" - }, + "deleted-child-mes": {"en": "The request was successful. The children have removed from the vaccination schedule subscription service.", "ar": "تم حذف الطفل بنجاح"}, "deleted-child": {"en": "Delete child", "ar": "إالغاء الطفل"}, "visit": {"en": "Visit", "ar": "زيارة"}, "referralStatus": {"en": "Referral Status", "ar": "حالة الإحالة"}, "referralDate": {"en": "Referral Date", "ar": "تاريخ الإحالة"}, - "patientName": {"en": "Patient Name", "ar": "اسم المريض"}, + "patientName": {"en": "Patient Name", "ar": "اسم المراجع"}, "referralNumber": {"en": "Referral Number", "ar": "رقم الإحالة"}, - "requestID": {"en": "Request ID", "ar": " رقم الطلب"}, + "requestID": {"en": "Req ID", "ar": " رقم الطلب"}, "OrderStatus": {"en": "Status", "ar": "الحاله"}, "pickupDate": {"en": "Pickup Date", "ar": "التاريخ"}, "serviceName": {"en": "Service Name", "ar": " اسم الخدمة"}, "orderLocation": {"en": "Location", "ar": "الموقع"}, "selectService": {"en": "Select Service", "ar": "حدد الخدمة"}, - "coveredService": {"en": "Covered Service : ", "ar": " الخدمات المغطاة : "}, - "selectedService": { - "en": "Selected Service : ", - "ar": " الخدمات المختارة : " - }, - "cancelOrderMsg": { - "en": "Are you sure!! want to cancel this order", - "ar": "هل أنت واثق!! تريد إلغاء هذا الطلب" - }, - "processDoneSuccessfully": { - "en": "Process Done Successfully", - "ar": "تمت العملية بنجاح" - }, - "selectHomeHealthCareServices": { - "en": "Select Home Health Care Services", - "ar": " حدد خدمات الرعاية الصحية المنزلية" - }, + "coveredService": {"en": "Covered Services: ", "ar": " الخدمات المغطاة: "}, + "selectedService": {"en": "Selected Services: ", "ar": " الخدمات المختارة: "}, + "cancelOrderMsg": {"en": "Are you sure!! want to cancel this order", "ar": "هل ترغب في إلغاء هذا الطلب"}, + "processDoneSuccessfully": {"en": "Process Done Successfully", "ar": "تمت العملية بنجاح"}, + "selectHomeHealthCareServices": {"en": "Select Home Health Care Services", "ar": " حدد خدمات الرعاية الصحية المنزلية"}, "description-vaccination": {"en": "Description", "ar": "وصف"}, "due-date": {"en": "Due date", "ar": "تاريخ الاستحقاق"}, - "valid-email": { - "en": "Please enter valid email", - "ar": "الرجاء إدخال عنوان بريد صحيح" - }, - "confirm-send": { - "en": "Send the child's schedule to the email?", - "ar": "ارسال جدول التطعيمات الى بريدك الالكتروني؟" - }, - "email-success": { - "en": - " The request was successful. You will receive the Schedule in moments.", - "ar": "تم ارسال جدول التطعيمات " - }, - "add-instructions": { - "en": - "Add the child's information below to recieve the schedule of vaccinations.", - "ar": "أضف معلومات الطفل لاستلام جدول التطعيمات" - }, - "added-child": { - "en": - "The request was successful. You have added a child to the vaccination schedule subscription service.", - "ar": "تمت الاضافة بنجاح." - }, + "valid-email": {"en": "Please enter valid email", "ar": "الرجاء إدخال بريد الكتروني صحيح"}, + "confirm-send": {"en": "Send the child's schedule to the email?", "ar": "ارسال جدول التطعيمات الى بريدك الالكتروني؟"}, + "email-success": {"en": " The request was successful. You will receive the Schedule in moments.", "ar": "تم ارسال جدول التطعيمات "}, + "add-instructions": {"en": "Add the child's information below to recieve the schedule of vaccinations.", "ar": "أضف معلومات الطفل لاستلام جدول التطعيمات"}, + "added-child": {"en": "The request was successful. You have added a child to the vaccination schedule subscription service.", "ar": "تمت الاضافة بنجاح."}, "appUpdate": {"en": "UPDATE THE APP", "ar": "تحديث التطبيق"}, "ereferralSaveSuccess": { - "en": - "The referral request has been submitted successfully, you will be contacted ASAP to complete the process. Referral request no is ", - "ar": - " تم إرسال طلب الإحالة بنجاح ، وسيتم الاتصال بك في أسرع وقت ممكن لإكمال العملية. رقم طلب الإحالة" + "en": "The referral request has been submitted successfully, you will be contacted ASAP to complete the process.", + "ar": " تم إرسال طلب الإحالة بنجاح ، وسيتم الاتصال بك في أسرع وقت ممكن لإكمال العملية." }, - "help": {"en": "Help", "ar": "مساعدة"}, - "habibRobotText": { - "en": - "Hi, This is HABIB, your personal assistant. I'm here to assist you by voice commands. How can I help?", + "en": "Hi, this is HABIB, your personal assistant. I'm here to assist you by voice commands. How can I help?", "ar": "مرحباً ، معك حبيب مساعدك الشخصي. أنا هنا لمساعدتك بالأوامر الصوتية." }, - "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": "من السيارة"}, - "trackDeliveryDriver": { - "en": "Track Delivery Driver", - "ar": "trackDeliveryDriver" - }, - + "updated-email": {"en": "Updated email successfully", "ar": "تم تحديث البريد الالكتروني"}, + "view-list-children": {"en": "View List of Children", "ar": "عرض قائمة الأطفال"}, + "covidTest": {"en": "COVID-19", "ar": "فحص"}, + "driveThru": {"en": "Test", "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": "أقرب ER"}, + "NearestEr": {"en": "Nearest ER", "ar": "اقرب طوارئ"}, "infoCMC": { - "en": - "Through this service, you can request a set of tests that help you and your doctor to understand the current health condition and then identify potential risks.", - "ar": - "من خلال هذه الخدمة يمكنك طلب مجموعة من الفحوصات التي تساعدك وتساعد طبيبك في فهم حالتك الصحية الحالية ومن ثم تحديد المخاطر المحتملة" + "en": "Through this service, you can request a set of tests that help you and your doctor to understand the current health condition and then identify potential risks.", + "ar": "من خلال هذه الخدمة يمكنك طلب مجموعة من الفحوصات التي تساعدك وتساعد طبيبك في فهم حالتك الصحية الحالية ومن ثم تحديد المخاطر المحتملة" }, "instructionAgree": { "en": @@ -1614,68 +1180,41 @@ const Map localizedValues = { "reqId": {"en": "Request ID:", "ar": " رقم الطلب"}, "RRT-orders-log": {"en": "Orders Log", "ar": "سجل الطلبات"}, "blood-sugar": {"en": "Blood Sugar", "ar": "سكر الدم"}, - - "covid19_driveThrueTest": { - "en": "'Covid-19- Drive-Thru Test'", - "ar": "Covid-19- الفحص من خلال القيادة" - }, + "covid19_driveThrueTest": {"en": "'Covid-19- Drive-Thru Test'", "ar": " الفحص من داخل السيارة"}, "E-Referral": {"en": "'E-Referral'", "ar": "الإحالة الإلكترونية"}, "childName": {"en": "'CHILD NAME'", "ar": "إسم الطفل"}, "recordDeleted": {"en": "'Record Deleted'", "ar": "تم حذف السجل"}, "msg_email_address_up_to_date": { - "en": - "Please ensure that the email address is up-to-date and process to view the schedule", - "ar": - "يرجى التأكد من أن عنوان البريد الإلكتروني محدث وأن العملية لعرض الجدول الزمني" + "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": "إضافة طفل جديد"}, - - "send-child-email-msg": { - "en": "Send the child's schedule to the email", - "ar": "أرسل جدول الطفل إلى البريد الإلكتروني" - }, - - "vaccination-add-child-msg": { - "en": - "Add the child's information below to receive the schedule of vaccinations.", - "ar": "أضف معلومات الطفل أدناه للحصول على جدول التطعيمات." - }, - "child_added_successfully": { - "en": "Child added successfully", - "ar": "تمت إضافة الطفل بنجاح" - }, + "send-child-email-msg": {"en": "Send the child's schedule to the email", "ar": "أرسل جدول التطعيمات إلى البريد الإلكتروني"}, + "vaccination-add-child-msg": {"en": "Add the child's information below to receive the schedule of vaccinations.", "ar": "أضف معلومات الطفل أدناه للحصول على جدول التطعيمات."}, + "child_added_successfully": {"en": "Child added successfully", "ar": "تمت إضافة الطفل بنجاح"}, "bloodSugar": {"en": "Blood", "ar": "السكر في الدم"}, - "sugar": {"en": "Sugar", "ar": ""}, + "sugar": {"en": "Sugar", "ar": "السكر"}, "bloodCholesterol": {"en": "Blood", "ar": " الكولسترول في الدم"}, - - "cholesterol": {"en": "Cholesterol", "ar": ""}, + "cholesterol": {"en": "Cholesterol", "ar": " الكولسترول"}, "triglycerides": {"en": "Triglycerides", "ar": "الدهون الثلاثية"}, - - "fatInBlood": {"en": "Fat In Blood", "ar": ""}, - "convertFrom": {"en": "Convert From", "ar": "تحويل من"}, - "calculate": {"en": "calculate", "ar": "حساب"}, + "fatInBlood": {"en": "Fat in Blood", "ar": ""}, + "convertFrom": {"en": "Convert from", "ar": "تحويل من"}, + "calculate": {"en": "Calculate", "ar": "احسب"}, "enterReadingValue": {"en": "Enter the reading value", "ar": "ادخل القيمة"}, "result": {"en": "Result", "ar": "النتيجة"}, "sort": {"en": "Sort", "ar": "فرز"}, - "bloodSugarConversion": { - "en": "Blood Sugar Conversion", - "ar": "السكر في الدم" - }, + "bloodSugarConversion": {"en": "Blood Sugar Conversion", "ar": "السكر في الدم"}, "convertBloodSugarStatement": { - "en": - "Convert blood sugar/glucose from mmol/l (UK standard) to mg/dlt (US standard) and vice versa.", - "ar": - "تحويل مستوى السكر في الدم من مليمول/ لتر (مقياس المملكة المتحدة) الى ملغ/ ديسيلتر (مقياس الولايات المتحدة) والعكس" + "en": "Convert blood sugar/glucose from mmol/l (UK standard) to mg/dlt (US standard) and vice versa.", + "ar": "تحويل مستوى السكر في الدم من مليمول/ لتر (مقياس المملكة المتحدة) الى ملغ/ ديسيلتر (مقياس الولايات المتحدة) والعكس" }, "convertCholesterolStatement": { - "en": "Convert blood cholesterol from\n mmol/l to mg/dlt and vice versa.", - "ar": - "تحويل مستوى الكولسترول في الدم من مليمول/ لتر (مقياس المملكة المتحدة) الى ملغ/ ديسيلتر (مقياس الولايات المتحدة) والعكس" + "en": "Convert blood cholesterol from mmol/l to mg/dlt and vice versa.", + "ar": "تحويل مستوى الكولسترول في الدم من مليمول/ لتر (مقياس المملكة المتحدة) الى ملغ/ ديسيلتر (مقياس الولايات المتحدة) والعكس" }, "triglyceridesConvertStatement": { "en": "Convert Triglycerides from mmol/l to mg/dlt and vice versa.", - "ar": - "تحويل مستوى الدهون الثلاثية في الدم من مليمول/ لتر (مقياس المملكة المتحدة) الى ملغ/ ديسيلتر (مقياس الولايات المتحدة) والعكس" + "ar": "تحويل مستوى الدهون الثلاثية في الدم من مليمول/ لتر (مقياس المملكة المتحدة) الى ملغ/ ديسيلتر (مقياس الولايات المتحدة) والعكس" }, "my-tracker": {"en": "My Tracker", "ar": "قراءاتي"}, "weekly": {"en": "Weekly", "ar": "أسبوعي"}, @@ -1686,26 +1225,15 @@ const Map localizedValues = { "other": {"en": "Other", "ar": "آخر"}, "measure-unit": {"en": "Measure unit", "ar": "وحدة القياس"}, "measure-time": {"en": "Measure time", "ar": "وقت القياس"}, - "update": {"en": "Update", "ar": "تعديل"}, - "bloodD-enter-desc": { - "en": - "Enter the required information, In order to register for Blood Donation Service", - "ar": "أدخل المعلومات المطلوبة ، للتسجيل في خدمة التبرع بالدم" - }, - "viewTermsConditions": { - "en": "To view the terms and conditions", - "ar": "لعرض الشروط والأحكام" - }, - "WalkinAppo": { - "en": "Hospital Visit Appointment", - "ar": "موعد زيارة للمستشفى" - }, - + "update": {"en": "Update", "ar": "تحديث"}, + "bloodD-enter-desc": {"en": "Enter the required information, in order to register for Blood Donation Service", "ar": "أدخل المعلومات المطلوبة ، للتسجيل في خدمة التبرع بالدم"}, + "viewTermsConditions": {"en": "To view the terms and conditions", "ar": "لعرض الشروط والأحكام"}, + "WalkinAppo": {"en": "Hospital Visit Appointment", "ar": "موعد زيارة للمستشفى"}, "videoAppo": {"en": "Video Call Appointment", "ar": "موعد اتصال فيديو"}, - "generalHealth": {"en": "General Health", "ar": "صحة عامة"}, "womanHealth": {"en": "Women's Health", "ar": "صحة المرأة"}, "bmi": {"en": "BMI", "ar": "الكتلة"}, + "bloodType": {"en": "Blood Type:", "ar": "فصيلة الدم"}, "calc-health": {"en": "Calculators", "ar": "الصحية"}, "calories": {"en": "Calories", "ar": "سعرات"}, "bmr": {"en": "BMR", "ar": "معدل الأيض القاعدي"}, @@ -1717,19 +1245,17 @@ const Map localizedValues = { "ovulation": {"en": "Ovulation", "ar": "الإباضة"}, "delivery": {"en": "Delivery", "ar": "الولادة"}, "bmiCalcDesc": { - "en": - "'Calculate the BMI value and weight\n status to identify the healthy weight .\n Not appropriate for children and women\n who are pregnant or breastfeeding'", - "ar": - "حساب قيمة مؤشر كتلة الجسم وحالة الوزن لتحديد الوزن الصحي. \n وغير مناسب للأطفال والنساء الحوامل أو المرضعات" + "en": "Calculate the BMI value and weight status to identify the healthy weight. Not appropriate for children and women who are pregnant or breastfeeding", + "ar": "احسب قيمة مؤشر كتلة الجسم وحالة الوزن لتحديد الوزن الصحي. غير مناسب للأطفال والنساء الحوامل أو المرضعات" }, "selectUnit": {"en": "Select Unit", "ar": "اختر الوحدة"}, "feet": {"en": "Feet", "ar": "قدم"}, "pound": {"en": "Pound", "ar": "رطل"}, - "seeListOfDoctor": {"en": "See List Of Doctors", "ar": "انظر قائمة الأطباء"}, + "seeListOfDoctor": {"en": "See List of Doctors", "ar": "انظر قائمة الأطباء"}, "obese": {"en": "Obese", "ar": "سمين"}, "overWeight": {"en": "OverWeight", "ar": "وزن زائد"}, "healthy": {"en": "Healthy", "ar": "صحي"}, - "underWeight": {"en": "UnderWeight", "ar": "نقص الوزن"}, + "underWeight": {"en": "UnderWeight", "ar": "وزن ناقص"}, "bmiCalcMsgObese": { "en": "A BMI of over 30 indicates that are heavily overweight. Health may be at risk if not lose weight. Recommended talking to a doctor or a dietician for advice. To book an appointment, click below to get started.", @@ -1745,8 +1271,7 @@ const Map localizedValues = { "bmiCalcMsgHealthy": { "en": "A BMI of 18.5 - 25 indicates that are at a healthy weight for the height. By maintaining a healthy weight, lower the risk of developing severe health problems. To book an appointment, click below to get started.", - "ar": - "يشير مؤشر كتلة الجسم من 18.5 - 25 إلى وزن صحي بالنسبة للطول. بالحفاظ على وزن صحي ، قلل من خطر الإصابة بمشاكل صحية خطيرة. لحجز موعد ، انقر أدناه للبدء." + "ar": "يشير مؤشر كتلة الجسم من 18.5 - 25 إلى وزن صحي بالنسبة للطول. بالحفاظ على وزن صحي ، قلل من خطر الإصابة بمشاكل صحية خطيرة. لحجز موعد ، انقر أدناه للبدء." }, "bmiCalcMsgUnderWeight": { "en": @@ -1754,25 +1279,18 @@ const Map localizedValues = { "ar": "يشير مؤشر كتلة الجسم الذي يقل عن 18.5 إلى أنك تعاني من نقص الوزن ، لذلك قد تحتاج إلى زيادة الوزن. يوصى بالتحدث إلى الطبيب أو أخصائي التغذية للحصول على المشورة. لحجز موعد ، انقر أدناه للبدء." }, - "bariatrics": {"en": "Bariatrics", "ar": "طب السمنة"}, + "bariatrics": {"en": "Bariatrics", "ar": " أمراض السمنة"}, "bariatricsHeaderMsg": { - "en": - "Choose one of the following symptoms to show the right doctors or choose a consultation to show all", - "ar": - "اختر أحد الأعراض التالية لتظهر للأطباء المناسبين أو اختر استشارة لإظهار الكل" + "en": "Choose one of the following symptoms to show the right doctors or choose a consultation to show all", + "ar": "اختر أحد الأعراض التالية لتظهر للأطباء المناسبين أو اختر استشارة لإظهار الكل" }, - "continue": {"en": "CONTINUE", "ar": "إستمرار"}, + "continue": {"en": "Continue", "ar": "إستمرار"}, "skip": {"en": "SKIP", "ar": "تخطى"}, "calorieCalcDesc": { - "en": - "Calculates daily calorie intake based on several factors, like height, weight, age, gender and daily physical activity ", - "ar": - "يحسب السعرات الحرارية اليومية بناءً على عدة عوامل ، مثل الطول والوزن والعمر والجنس والنشاط البدني اليومي" - }, - "age11_120_years": { - "en": "The Age ( 11 - 120 ) yrs", - "ar": "العمر (11 - 120) سنة" + "en": "Calculates daily calorie intake based on several factors, like height, weight, age, gender and daily physical activity ", + "ar": "يحسب السعرات الحرارية اليومية بناءً على عدة عوامل ، مثل الطول والوزن والعمر والجنس والنشاط البدني اليومي" }, + "age11_120_years": {"en": "The Age (11 - 120) yrs", "ar": "العمر (11 - 120) سنة"}, "weight-add": {"en": "Enter Weight Value", "ar": "أدخل الوزن "}, "systolic-add": {"en": "Enter Systolic Value", "ar": "أدخل قيمة الإنقباض "}, "diastolic-add": {"en": "Enter Diastolic Value", "ar": "أدخل قيمة الإنبساط "}, @@ -1780,220 +1298,1033 @@ const Map localizedValues = { "today": {"en": "Today", "ar": "اليوم"}, "week": {"en": "Week", "ar": "أسبوع"}, "month": {"en": "Month", "ar": "شهر"}, - "h2o-amount-of-water": { - "en": "Enter the amount of water:", - "ar": "ادخل كمية الماء:" - }, + "enter_detail_below": {"en": "Enter the details below", "ar": "أدخل التفاصيل أدناه"}, + "h2o-amount-of-water": {"en": "Enter the amount of water:", "ar": "ادخل كمية الماء:"}, "update-user": {"en": "Update Information", "ar": "تحديث بيانات"}, "editname": {"en": "Enter the name here", "ar": "أدخل الاسم هنا"}, "activity-level": {"en": "Activity Level", "ar": "مستوى النشاط"}, "light-active": {"en": "Lightly Active", "ar": " قليل النشاط"}, "mod-active": {"en": "Moderately Active", "ar": "متوسط النشاط"}, - "reminder-label": { - "en": "Activate the reminder of drink water?", - "ar": "تفعيل خاصية تذكير شرب الماء؟" - }, - "reminder-times-label": { - "en": "How many times do you want to be reminded?", - "ar": "عدد مرات التذكير" - }, + "reminder-label": {"en": "Activate the reminder of drink water?", "ar": "تفعيل خاصية تذكير شرب الماء؟"}, + "reminder-times-label": {"en": "How many times do you want to be reminded?", "ar": "عدد مرات التذكير"}, "times": {"en": "Times", "ar": "مرات"}, "WaterCalculate": {"en": "Save", "ar": "حفظ"}, "notif-title": {"en": "Water Reminder", "ar": "تذكير"}, - "notif-text": { - "en": " Don't forget to drink water.", - "ar": "لا تنسى شرب الماء" - }, - "custom": {"en": "Custom", "ar": "خاص"}, + "notif-text": {"en": " Don't forget to drink water.", "ar": "لا تنسى شرب الماء"}, + "custom": {"en": "Custom", "ar": "مخصص"}, "undo": {"en": "Undo", "ar": "تراجع"}, "drinking": {"en": "Drinkning", "ar": "الشرب"}, "remaining": {"en": "Remaining", "ar": "المتبقي"}, + "addCustomAmount": {"en": "Add Custom Amount", "ar": "إضافة كمية محددة"}, + "left": {"en": "Left", "ar": "المتبقي"}, "taken": {"en": "Taken", "ar": " مأخوذ"}, - "ml": {"en": "ml", "ar": "مل"}, + "ml": {"en": "ML", "ar": "مل"}, + "mililitre": {"en": "Mililitre (ml)", "ar": "مليلتر (مل)"}, "l": {"en": "L", "ar": "لتر"}, + "litre": {"en": "Litre (l)", "ar": "لتر (لتر)"}, "custom-label": {"en": "Enter amount", "ar": "أدخل كمية الماء"}, - "custom-label-in-litres": { - "en": "Enter amount in liters", - "ar": "أدخل الكمية باللتر" - }, - "custom-label-in-mililitres": { - "en": "Enter amount in millilitres", - "ar": "أدخل الكمية بالملليتر" - }, + "custom-label-in-litres": {"en": "Enter amount in liters", "ar": "أدخل الكمية باللتر"}, + "custom-label-in-mililitres": {"en": "Enter amount in millilitres", "ar": "أدخل الكمية بالملليتر"}, "amount": {"en": "Amount", "ar": "الكمية"}, - "target-reach": { - "en": "You have reached the target for the day!", - "ar": "لقد حققت هدفك اليومي! مبروك" - }, - "week-header": { - "en": "Water consumed in a week", - "ar": "معدل شرب الماء خلال الاسبوع" - }, - "month-header": { - "en": "Water consumed in a month", - "ar": "معدل شرب الماء خلال الشهر" - }, - "notif-permission-title": { - "en": "Could not set the water reminders", - "ar": "لا يمكن ضبط اشعار شرب الماء" - }, - "notif-permission-msg": { - "en": - "To recieve water reminders, please turn on notifications in the system settings", - "ar": "الرجاء تفعيل الاشعارات في الاعدادات" - }, - "verification_message_code": { - "en": "Please enter verification code", - "ar": "الرجاء إدخال رمز التحقق" - }, - "select-location": {"en": "Select Location", "ar": "اختر موقعا"}, - "result-header": { - "en": "Get The Result During 8 Hours", - "ar": "احصل على النتيجة خلال 8 ساعة" - }, + "target-reach": {"en": "You have reached the target for the day!", "ar": "لقد حققت هدفك اليومي! مبروك"}, + "week-header": {"en": "Water consumed in a week", "ar": "معدل شرب الماء خلال الاسبوع"}, + "month-header": {"en": "Water consumed in a month", "ar": "معدل شرب الماء خلال الشهر"}, + "notif-permission-title": {"en": "Could not set the water reminders", "ar": "لا يمكن ضبط اشعار شرب الماء"}, + "notif-permission-msg": {"en": "To recieve water reminders, please turn on notifications in the system settings", "ar": "الرجاء تفعيل الاشعارات في الاعدادات"}, + "verification_message_code": {"en": "Please enter verification code", "ar": "الرجاء إدخال رمز التحقق"}, + "select-location": {"en": "Select Location *", "ar": "اختر الموقع *"}, + "result-header": {"en": "Get the result in Few Hours", "ar": "احصل على النتيجة خلال عدة ساعات"}, + "please_select_gender": {"en": "Please select gender", "ar": "يرجى تحديد الجنس"}, "covid-info": { "en": - "We are using the advance technology to test COVID-19, The sample for examination is taking between the nose and mouth (nasopharyngeal swab), the examination is done by ELITE In Genius of the company ELITECH GROUP MOLECULAR DIAGNOSTICS, Note that the device belongs to an Italian company and is manufactured in Japan with RC- PCR​", + "Dr. Sulaiman Al Habib hospitals are conducting a test for the emerging corona virus and issuing travel certificates 24/7 in a short time and with high accuracy. Those wishing to benefit from this service can visit one of Dr. Sulaiman Al Habib branches to conduct a corona test within few minutes, and obtain the result within several hours. Corona Virus Covid 19 testing service with PCR technology to detect the virus according to the highest international standards and with the latest high-precision RT-PCR devices (American GeneXpert and others), That is approved by the Food and Drug Authority as well as by the Saudi Center for Infectious Diseases Prevention.", "ar": - "يتوفر لدينا أحدث جهاز خاص بفحص مرض الكورونا (COVID-19) طريقة الفحص تؤخذ مسحة من البلعوم الأنفي ( عن طريف الأنف) ويتم الفحص بواسطة جهاز ELITE In Genius التابع لشركة ELITECH GROUP MOLECULAR DIAGNOSTICS علما بأن الجهاز تابع لشركة إيطالية ومصنع في اليابان بتقينة RC-PCR" - }, - "select-appo": { - "en": "Kindly select one of the available appointments from below:", - "ar": "يرجى اختيار أحد المواعيد المتاحة من أدناه:" - }, - "covid-alert-header": { - "en": "Pay With-in 15 mins to confirm the appointment", - "ar": "الرجاء اتمام عملية الدفع خلال 15 دقيقه لتاكيد الموعد" + "تجري مستشفيات د. سليمان الحبيب فحص فيروس كورونا المستجد وتصدر شهادات السفر على مدار الساعة، طوال أيام الأسبوع، وبسرعة ودقة عالية. يمكن للراغبين في الاستفادة من هذه الخدمة زيارة أحد فروع مستشفيات د. سليمان الحبيب وإجراء فحص كورونا خلال بضع دقائق والحصول على النتائج خلال عدة ساعات خدمة فحص فيروس كورونا Covid 19 بتقنية PCR للكشف عن الفيروس وفقاً لأعلى المعايير العالمية وبأحدث أجهزة RT-PCR عالية الدقة (GeneXpert الأمريكي وغيره)، وهي طرق معتمدة من قبل هيئة الغذاء والدواء وكذلك من قبل المركز السعودي للوقاية من الأمراض المُعدية" }, + "select-appo": {"en": "Kindly select one of the available appointments from below:", "ar": " يرجى اختيار أحد المواعيد المتاحة مما يلي:"}, + "covid-alert-header": {"en": "Pay With-in 15 mins to confirm the appointment", "ar": "الرجاء اتمام عملية الدفع خلال 15 دقيقه لتاكيد الموعد"}, "covid-alert-info": { - "en": - "Payment for Covid-19 Test should Be made with-in 15 mins otherwise The system will Cancel the Scheduled appointment automatically​", - "ar": - "سيتم الغاء الموعد عن طريق النظام بشكل الي في حال عدم اتمام عمليه الدفع خلال 15 دقيقة​" + "en": "Payment for Covid-19 Test should Be made with-in 15 mins otherwise The system will Cancel the Scheduled appointment automatically​", + "ar": "سيتم الغاء الموعد عن طريق النظام بشكل الي في حال عدم اتمام عمليه الدفع خلال 15 دقيقة" }, "covid-alert-mins": {"en": "Pay With-in 15 mins", "ar": "ادفع خلال 15 دقيقة"}, "back": {"en": "Back", "ar": "رجوع"}, "get-directions": {"en": "Get Directions", "ar": "احصل على الاتجاهات"}, "selected-location": {"en": "Selected Location:", "ar": "الموقع المحدد:"}, - "test-fee": {"en": "Test Fee", "ar": "رسوم الاختبار"}, - "pay-options": { - "en": "You can pay by the following Options:", - "ar": "يمكنك الدفع عن طريق الخيارات التالية:" - }, + "test-fee": {"en": "Test Fee", "ar": "الرسوم"}, + "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": "لماذا خدمة اللايف كير"}, - "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": "خدمة توصيل الادوية مجانا" - }, + "livecare-service-desc": {"en": "is to obtain medical advice with a specialist doctor Via a video call", "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": "خدمة توصيل الادوية مجانا"}, "livecare-summary": { - "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": "الحصول على الاستشارة فورا" + "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 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": "اتصال فيديو مجدول"}, "sms_code": {"en": "Enter SMS Code here", "ar": "أدخل رمز التحقق هنا"}, - "code_failure": { - "en": "Didn’t received the code", - "ar": "لم أستلم رمز التحقق" - }, + "code_failure": {"en": "Didn’t received the code", "ar": "لم أستلم رمز التحقق"}, "resend": {"en": "Resend", "ar": "إعادة إرسال"}, "submitncontinue": {"en": "Submit and continue", "ar": "إرسال ومتابعة"}, - "areyousure": { - "en": "Are you sure you want to Add", - "ar": "هل أنت متأكد أنك تريد إضافة" - }, - "preferredunit": { - "en": "Select the preferred unit", - "ar": "اختر الوحدة المفضلة" - }, + "areyousure": {"en": "Are you sure you want to Add", "ar": "هل أنت متأكد أنك تريد إضافة"}, + "preferredunit": {"en": "Select the preferred unit", "ar": "اختر الوحدة المفضلة"}, "select-unit": {"en": "Select unit", "ar": "اختر وحدة القياس"}, "try-saying": {"en": "Try saying something", "ar": 'حاول قول شيء ما'}, - "app-update": {"en": "UPDATE THE APP", "ar": "تحديث التطبيق"}, "covid-alert": {"en": "Alert", "ar": "تنبيه"}, - "enterIdentificationNumber": { - "en": "Enter Identification Number", - "ar": "أدخل رقم التعريف" - }, + "enterIdentificationNumber": {"en": "Enter Identification Number", "ar": "أدخل رقم الهوية"}, + "identificationNumber": {"en": "Identification Number", "ar": "رقم الهوية"}, + "complaintNumber": {"en": "Complaint Number", "ar": "رقم الشكوى"}, "accountActivationDesc": { + "en": " This service allows you to activate your LAKUM account after registering completed.", + "ar": " تتيح لك هذه الخدمة تفعيل حساب برنامج الولاء لكم بعد اكتمال التسجيل. " + }, + "pointsToTransfer": {"en": "Points to Transfer:", "ar": "النقاط المراد تحويلها:"}, + "enterBeneficiaryAccountNo": {"en": "Enter Beneficiary Account No.", "ar": "أدخل رقم حساب المستفيد"}, + "confirm-prescription": {"en": "Are you sure !! you want to send this request", "ar": "تاكيد ارسال الطلب؟"}, + "you-already-have-order": {"en": "You already have this order! do you want to view it?", "ar": "لديك هذا الطلب بالفعل! هل تريد مشاهدته؟"}, + "order-overview": {"en": "Order Overview", "ar": "ملخص الطلب"}, + "shipping-address": {"en": "Delivery Address", "ar": "عنوان التوصيل"}, + "pharmacy-relogin": {"en": "Your session has timed out, please try again", "ar": "انتهت مهلة جلسة الخاص بها. يرجى المحاولة مرة أخرى"}, + "ancillary-orders": {"en": "Ancillary Orders", "ar": "الطلبات الاضافية"}, + "onlineCheckInAgreement": { "en": - "This service allows you to activate your LAKUM account after registering through the Vida system.", + "The online check-in is for non-life threatening situation. Call the red crescent (997) or go to the nearest emergency department if there are: \n\nsigns of stroke or heart attack \nhistory of seizure or syncope \nthere is limb or life threatening injury \npicture of severe injuries", "ar": - "تتيح لك هذه الخدمة تفعيل حساب LAKUM الخاص بك بعد التسجيل من خلال نظام Vida." + "تسجيل الذهاب الى الطوارئ عبر الإنترنت هو فقط للحالات التي لا تهدد الحياة يجب الاتصال بالهلال الأحمر (997) أو الذهاب إلى أقرب قسم طوارئ إذا كان هناك علامات السكتة الدماغية أو النوبة القلبية او هناك نوبة تشنج او حالة فقدان الوعي او وجود إصابة تهدد أحد الأطراف او تهدد الحياة او وجود إصابات خطيرة" }, - "pointsToTransfer": { - "en": "Point's to Transfer :", - "ar": "النقاط المراد تحويلها:" + "MRN": {"en": "MRN", "ar": "رقم الملف الطبي"}, + "appointment-date": {"en": "Appointment Date", "ar": "تاريخ الموعد"}, + "appointment-no": {"en": "Appointment No", "ar": "رقم الموعد"}, + "insurance-id": {"en": "Insurance ID", "ar": "رقم العضويه"}, + "chiefComplaints": {"en": "Chief Complaints", "ar": "الشكوى الرئيسة"}, + "errorChiefComplaints": {"en": "Please Chief Complaints", "ar": "يرجى ادخال الشكوى الرئيسة"}, + "errorExpectedArrivalTimes": {"en": "Please Expected arrival time", "ar": "يرجى ادخال الوقت المتوقع للوصول"}, + "expectedArrivalTime": {"en": "Expected arrival time", "ar": "الوقت المتوقع للوصول"}, + "add-address": {"en": "Add new address", "ar": "اضف عنوان جديد"}, + "enter-file": {"en": "Please Enter Mobile Number and Medical File Number", "ar": "الرجاء إدخال رقم الجوال ورقم الملف الطبي"}, + "allow": {"en": "Allow", "ar": "السماح"}, + "reject": {"en": "Reject", "ar": "رفض"}, + "referralRequesterInformation": {"en": "Referral requester information", "ar": "معلومات طالب الإحالة"}, + "enterReferralRequesterName": {"en": "Enter Referral Requester Name*", "ar": "أدخل اسم مقدم طلب الإحالة *"}, + "selectRelationship": {"en": "Select Relationship", "ar": "حدد العلاقة"}, + "requesterRelationship": {"en": "Requester Relationship", "ar": "علاقة الطالب"}, + "newReferral": {"en": "New Referral", "ar": "إحالة جديدة"}, + "searchForReferrals": {"en": "Search for Referrals", "ar": "ابحث عن الإحالات"}, + "covid-select-procedure": {"en": "Please select the procedure:", "ar": "الرجاء تحديد الإجراء:"}, + "online-consultation": {"en": "Online Consultation", "ar": "استشارة مباشرة"}, + "expected-weiting": {"en": "Waiting time to start LiveCare consultation ", "ar": "وقت الانتظار المتوقع لبدء استشارة لايف كير"}, + "er-consult-fee": {"en": "Consultation Fee", "ar": "رسوم الاستشارة"}, + "insured-patient": {"en": "If you're Insurance patient, you have only have to pay the co-payment", "ar": "إذا كنت مراجع في مجال التأمين ، فليس عليك سوى دفع المبلغ المشترك"}, + "i-accept-terms": {"en": "I Accept the Terms and Conditions", "ar": "موافق على الشروط والأحكام"}, + "upcoming-pay-options": {"en": "You can pay by the following Options:", "ar": "يمكنك الدفع عن طريق الخيارات التالية:"}, + "please-accept-terms": {"en": "Please accept terms & conditions to continue", "ar": "يرجى قبول الشروط والأحكام للمتابعة"}, + "type": {"en": "Type", "ar": "اكتب"}, + "info-ereferral": { + "en": + "This service allows you to submit a Referral request from any health care providers either inside or outside the kingdom of Saudi Arabia to any of HMG Hospitals, by filling some of the patient's data and attaching the medical reports, moreover you can track the request status (Under process, Accepted or Rejected)", + "ar": + "تتيح لك هذه الخدمة إرسال طلب إحالة من أي من مقدمي الرعاية الصحية سواء داخل المملكة العربية السعودية أو خارجها إلى أي من مستشفيات HMG ، عن طريق ملء بعض بيانات المراجع وإرفاق التقارير الطبية ، علاوة على ذلك يمكنك تتبع حالة الطلب (قيد المعالجة ، مقبول أو مرفوض)" + }, + "er-consultation": { + "en": "This service allows you to make an online virtual consultation via video call directly with the doctor from anywhere at any time.", + "ar": "تتيح لك هذه الخدمة إجراء استشارة عبر مكالمة فيديو مباشرة مع الطبيب من أي مكان وفي أي وقت" + }, + "my-invoice": {"en": "List", "ar": "فواتيري"}, + "invoice-list": {"en": "My Invoice", "ar": "قائمة"}, + "thisItemIsNotAvailable": {"en": "This item is not available", "ar": "هذا العنصر غير متوفر"}, + "beforeAfterImages": {"en": "Before & After Images", "ar": "الصور قبل وبعد"}, + "clinic-accept-livecare": { + "en": "No need to wait or visit You can now get medical consultation via Video call (LiveCare service) in The name of the clinic clinic and the doctor will contact you immediately", + "ar": "لا داعي للانتظار او الحضور يمكنك الان الحصول على الاستشارة عن طريق مكالمة الفيديو (خدمة لايف كير) في العيادة وسوف يقوم الطبيب بالتواصل معك فورا" + }, + "livecareModal-top": {"en": "This Clinic is Accepting livecare services", "ar": "هذه العيادة تقدم خدمة لايف كير"}, + "schedule": {"en": "Schedule", "ar": "جدول الحضور"}, + "livecare-point-2": {"en": "A Specialized doctor will contact you", "ar": "سوف يقوم بخدمتك طبيب متخصص"}, + "livecare-point-3": {"en": "A Doctor will be able to see your full medical file history", "ar": "سوف يتمكن الطبيب من الاطلاع على ملفك الطبي كاملا"}, + "livecare-point-4": {"en": "Free Medicine Delivery Available", "ar": "خدمة توصيل الادوية مجانية"}, + "livecare-point-5": {"en": "No need to visit the service is in your place", "ar": "لا داعي للحضور سوف تحصل على الخدمة في مكانك"}, + "book-immediate-livecare": {"en": "I accept to get the service immediately", "ar": "موافق اريد الحصول على الخدمة فورا"}, + "book-video-livecare-2": {"en": "I don't need to visit the clinic", "ar": "اتصال فيديو لا احتاج الحضور الى العيادة"}, + "no-thankyou": {"en": "No Thanks", "ar": "لا شكرا"}, + "visit-clinic": {"en": "Schedule appointment with the doctor", "ar": "ارغب في حجز موعد مجدول مع الطبيب"}, + "generate-covid-certificate": {"en": "Generate Covid-19 Certificate", "ar": "إنشاء شهادة كورونا"}, + "is-report-outside-ksa": {"en": "Is the certificate needed for outside KSA?", "ar": "هل الشهادة مطلوبة من خارج المملكة؟"}, + "passport-number": {"en": "Passport Number", "ar": "رقم جواز السفر"}, + "enter-passport-number": {"en": "Please confirm or update your passport number:", "ar": "الرجاء تأكيد أو تحديث رقم جواز السفر الخاص بك:"}, + "valid-passport-number": {"en": "Please enter valid passport number", "ar": "الرجاء إدخال رقم جواز سفر صحيح"}, + "continue-plan": {"en": "Continue with the treatment plan?", "ar": "إكمال الخطة العلاجية؟"}, + "about-app": {"en": "About the app", "ar": "عن التطبيق"}, + "about-points": { + "length": {"en": "16", "ar": "16"}, + "1": {"en": "Online Appointment Booking & rescheduling", "ar": "حجز المواعيد إلكترونياً و إعادة جدولتها"}, + "2": {"en": "Insurance approval status", "ar": "موافقات شركات التأمين الطبية"}, + "3": {"en": "Find A doctor", "ar": "معلومات الأطباء والبحث عنهم وسؤالهم"}, + "4": {"en": "Ask your doctor", "ar": "اسأل طبيبك"}, + "5": {"en": "Medical prescriptions", "ar": "الوصفات الطبية"}, + "6": {"en": "Lab results", "ar": "نتائج التحاليل المخبرية"}, + "7": {"en": "Hospitals contact numbers", "ar": "أرقام هواتف جميع المستشفيات"}, + "8": {"en": "Doctor profiles", "ar": "ملف الطبيب"}, + "9": {"en": "Hospitals locations", "ar": "مواقع المستشفيات على الخريطة"}, + "10": {"en": "Pharmacies Locations", "ar": "مواقع الصيدليات على الخريطة"}, + "11": {"en": "Hospital's Virtual Tour", "ar": "جولة افتراضية داخل المستشفيات"}, + "12": {"en": "Official Social Media", "ar": "مواقع التواصل الاجتماعي الخاصة بالمجموعة"}, + "13": {"en": "Vaccines Schedule", "ar": "جدول التطعيمات"}, + "14": {"en": "Health Calculators", "ar": "حاسبات صحية"}, + "15": {"en": "Other Services", "ar": "خدمات أخرى"} + }, + "dental-procedure-list": {"en": "Dental Procedures for this Appointment: ", "ar": "إجراءات الأسنان لهذا الموعد:"}, + "time-needed": {"en": "Time Needed:", "ar": "الوقت اللازم:"}, + "total-time-needed": {"en": "Total Appointment Time:", "ar": "وقت المواعيد الكلي:"}, + "info-eye": { + "en": "This service allows you to view all the eye measurements, lenses, and eyeglasses that have been made in the Habib Medical Group.", + "ar": " خدمة قياسات النظر: هذه الخدمة تمكنك من الاطلاع على جميع قياسات النظر والعدسات والنظارات التي تمت في مجموعة الحبيب الطبية." + }, + "info-vaccines": { + "en": "This service allows you to view all the vaccinations that were taken in Al Habib Medical Group.", + "ar": "خدمة تطعيماتي: هذه الخدمة تمكنك من الاطلاع على جميع التطعيمات التي تمت في مجموعة الحبيب الطبية." + }, + "info-trackers": { + "en": "This service allows you to record the readings of the measurement of sugar, pressure, and weight and then refer to them as a reference in addition to view the statistics charts.", + "ar": "متابعة قراءاتي: هذه الخدمة تمكنك من تسجيل قراءات قياس السكر والضغط والوزن بشكل دوري ومن ثم الاطلاع عليها كمرجع وكذلك الاطلاع على الرسوم البيانية لمتابعة تطور الحالة." + }, + "info-health-data": { + "en": + "This service is designed to allows you to synchronize the health data from your smart watches into your health record system in Habib Medical Group so that the doctors you are visiting can analyze your health & activity level.", + "ar": "تم تصميم هذه الخدمة للسماح لك بمزامنة البيانات الصحية من ساعاتك الذكية الى نظام السجلات الصحية الخاص بك في مجموعة حبيب الطبية حتى يتمكن الأطباء الذين تزورهم من تحليل مستوى صحتك ونشاطك." + }, + "info-ask-doc": { + "en": + "This service allows you to ask the doctor you have visited during the last 14 days. When you receive a response from the doctor, you will be notified via the system to view the doctor's reply.", + "ar": "اسال طبيبك: هذه الخدمة تمكنك من توجيه استفسارات الى الطبيب الذي قمت بزيارته خلال اخر 14 يوم وكذلك عند تلقى الرد من الطبيب سوف يتم ابلاغك عن طريق النظام للاطلاع على رد الطبيب." + }, + "info-auto-wifi": { + "en": "This service allows you to connect to the Internet directly without the need for entering a user name or password.", + "ar": "الاتصال بالانترنت: هذه الخدمة تمكنك من الاتصال بالانترنت مباشرة دون الحاجة الى اسم مستخدم او كلمة مرور." + }, + "auto-wifi": {"en": "Connect To Internet", "ar": "الإتصال بالإنترنت"}, + "child-vaccine-info": { + "en": + "This service to remind you of the deadlines of the necessary vaccinations for your child’s against diseases targeted by immunization according to the MOH vaccinations schedule by sending a reminding message and notifications of the vaccination date to the registered mobile phone.", + "ar": + "هذه الخدمة تم تصميمها لتذكيرك بالمواعيد النهائية للتحصينات اللازمة لطفلك ضد الأمراض المستهدفة بالتحصين وفقًا لجدول تطعيمات وزارة الصحة عن طريق إرسال رسالة تذكير وإشعارات عن مواعيد التطعيم على الجوال المسجل." }, - "enterBeneficiaryAccountNo": { - "en": "Enter Beneficiary Account No.", - "ar": "أدخل رقم حساب المستفيد" + "h2o-info": { + "en": + "This service is designed to help you to set drinking water goals and track the volume of water you are drinking on a daily basis. This service allows for schedule reminders and offers a basic statistical analysis of the amount of what you have consumed over the course of a day, week or month.", + "ar": + "تم تصميم هذه الخدمة لمساعدتك في تحديد وتتبع كميات المياه التي يتوجب شربها بشكل يومي. كما توفر هذه الخدمة تذكيرات الجدول الزمني وتقدم تحليلًا إحصائيًا لمقدار ما استهلكته خلال اليوم أو الأسبوع أو الشهر." + }, + "sys/dias": {"en": "SBP/DBP", "ar": "إنقباض/إنبساط"}, + "arm": {"en": "Arm", "ar": "الذراع"}, + "remove-measure": {"en": "Remove this measure", "ar": "إزالة هذا القياس؟"}, + "select-arm": {"en": "Select the Arm", "ar": "إختر الذراع"}, + "ask-doc-empty": {"en": "This service is available to doctors visited during the past 15 days", "ar": "هذه الخدمة متاحة للاطباء الذين تمت زيارتهم خلال ال 15 يوم الماضية"}, + "online-clinics": {"en": "Online Clinics: ", "ar": "​العيادات المفتوحة: "}, + "offline-clinics": {"en": "Offline Clinics: ", "ar": "العيادات المغلقة: "}, + "clinic-schedule": {"en": "Clinic Schedule", "ar": "جدول العيادة"}, + "discount": {"en": "Discount:", "ar": "الخصم:"}, + "total-VAT": {"en": "VAT", "ar": "القيمة المضافة"}, + "paid": {"en": "Paid", "ar": "المدفوع"}, + "dental-insurance": {"en": "Insurance", "ar": "التأمين"}, + "drivethru-appo": {"en": "Drive Thru Appointment", "ar": "موعد من داخل السيارة"}, + "upcoming-QR-NFC": {"en": "Use the NFC or QR Code to Check-In", "ar": "استخدم NFC أو رمزQR لتسجيل الوصول"}, + "ovulation-desc": {"en": "Calculates Ovulation Period", "ar": "حساب افضل فترة للحمل بناءاً على تاريخ اخر دورة شهرية"}, + "cycle-label": {"en": "Average Cycle Length (usually 28 days):", "ar": "متوسط الدورة الشهرية 28 يوم: "}, + "luteal-label": {"en": "Average Luteal Phase Length (usually 14 days):", "ar": "متوسط الأيام ما بعد الاباضة عادة 14 يوما: "}, + "pregnancy-title": {"en": "Delivery Due Date", "ar": "تاريخ الولادة"}, + "pregnancy-desc": { + "en": "Congratulations, you are pregnant! Now when will the new baby arrive? To estimate the due date, enter the date when the last menstrual period began (the first day), then click calculate.", + "ar": "مبروك, أنت حامل! الآن متى سيصل الطفل؟ لتقدير موعد الولادة, ادخل تاريخ بداية آخر دورة شهرية (اليوم الأول), ثم اضغط على الحساب" + }, + "pregnancy-date-label": {"en": "What was the date of the first day of the last period?", "ar": "ما هو تاريخ أول يوم من أخر دورة شهرية ؟"}, + "ovulation-period": {"en": "The next ovulation period is estimated to be: ", "ar": "تقدر فترة الاباضة القادمة "}, + "from": {"en": "From: ", "ar": "من:"}, + "to": {"en": "To: ", "ar": "الى:"}, + "conceive": {"en": "You have conceived on: ", "ar": " تاريخ بداية الحمل"}, + "firstTri": {"en": "First Trimester Ends (12 weeks):", "ar": "تاريخ انتهاء الثلث الأول 12 اسبوع: "}, + "secondTri": {"en": "Second Trimester Ends (27 weeks):", "ar": "تاريخ انتهاء الثلث الثاني 27 اسبوع: "}, + "thirdTri": {"en": "Third Trimester, Estimated Due Date (40 weeks):", "ar": "تاريخ احتمال الولادة 40 اسبوع:"}, + "seeDoctorsList": {"en": "See List of Doctors", "ar": "اعرض قائمة الأطباء"}, + "covidQuestionnaire": {"en": "Please answer below questionnaire:", "ar": "الرجاء الإجابة على الاستبيان أدناه:"}, + "covidBookAppo": {"en": "Booking Appointment for: ", "ar": "موعد الحجز لـ: "}, + "emptySchedule": {"en": "Doctor has no schedule.", "ar": "لا يوجد جدول حضور مسجل للطبيب"}, + "serviceNotAvailable": {"en": "Dear, this service is not available now, please try again later", "ar": "عزيزي المراجع, هذه الخدمة غير متوفرة الان يرجى المحاوله لاحقا"}, + "doctorScheduleNot": {"en": "Doctor schedule not available", "ar": "جدول الطبيب غير متوفر"}, + "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": "Req Date", "ar": "التاريخ "}, + "requestedDateLiveCare": {"en": "Requested Date: ", "ar": "التاريخ: "}, + "callDuration": {"en": "Call Duration", "ar": "مدة الاتصال"}, + "alreadyRated": {"en": "This appointment has been previously evaluated.", "ar": "تم تقييم هذا الموعد مسبقاً"}, + "insuranceCompany": {"en": "Insurance Company", "ar": "شركة تأمين"}, + "preferredBranch": {"en": "Preferred Branch", "ar": "الفرع المفضل"}, + "selectPreferredBranch": {"en": "Select Preferred Branch", "ar": "اختر الفرع المفضل"}, + "patientLocated": {"en": "Where the patient located", "ar": "اين موقع المراجع"}, + "otherInfo": {"en": "Other details", "ar": "تفاصيل أخرى"}, + "medicalReport": {"en": "Medical Report", "ar": "تقرير طبي"}, + "insuredPatient": {"en": "Insured Patient", "ar": "هل لدى المراجع تامين؟"}, + "rateDoctor": {"en": "Rate Doctor", "ar": "تقييم الطبيب"}, + "rateAppointment": {"en": "Rate Appointment", "ar": "تقييم الموعد"}, + "noInsuranceCardAttached": {"en": "Please attach your insurance card image to continue", "ar": "يرجى إرفاق صورة بطاقة التأمين الخاصة بك للمتابعة"}, + "bodyMassIndex": {"en": "Body Mass Index is: ", "ar": "مؤشر كتلة الجسم هو:"}, + "noSlotsError": {"en": "No appointments available for selected date", "ar": "لا توجد مواعيد متاحة للتاريخ المحدد"}, + "selectSlot": {"en": "Please select Time Slot to continue", "ar": "الرجاء تحديد فترة زمنية للمتابعة"}, + "years": {"en": "Years", "ar": "سنوات"}, + "respirationBPM": {"en": "bpm", "ar": "نفس"}, + "extremeObese": {"en": "Extreme Obese", "ar": "سمنة مفرطة"}, + "invoiceDetails": {"en": "Invoice Details", "ar": "تفاصيل الفاتورة"}, + "appoDetails": {"en": "Appointment Details", "ar": "تفاصيل الموعد"}, + "appoPaymentConfirm": {"en": "Are you sure you Want to make payment for this appointment?", "ar": "هل أنت متأكد من أنك تريد سداد هذا الموعد؟"}, + "selectSearchCriteria": {"en": "Select the search criteria", "ar": "حدد معايير البحث"}, + "enterComplainNumber": {"en": "Enter the Complain Number", "ar": "أدخل رقم الشكوى"}, + "enterfileNumber": {"en": "Enter File Number", "ar": "أدخل رقم الملف"}, + "please_select_from_below_options": {"en": "Please select from below options:", "ar": "الرجاء التحديد من الخيارات أدناه:"}, + "selectLanguage": {"en": "Please select any language:", "ar": ":الرجاء تحديد أي لغة"}, + "recAlert": {"en": "How do you want to receive alerts?", "ar": "كيف تريد تلقي التنبيهات؟"}, + "modesBelow": {"en": "Please select the modes below:", "ar": ":الرجاء تحديد الأوضاع أدناه"}, + "prefferedMode": {"en": "Please select the preferred mode below:", "ar": ":الرجاء تحديد الوضع المفضل أدناه"}, + "permissionsBellow": {"en": "Please allow the permissions below:", "ar": ":الرجاء السماح الأذونات أدناه"}, + "appointmentReminder": {"en": "Would you like to set a reminder for this in your calendar?", "ar": "هل ترغب في اضافة تذكير لهذا في التقويم؟"}, + "cancelAppointment": {"en": "Cancel Appt.", "ar": "الغاء الموعد"}, + "updateInsurCards": {"en": "Update Insurance Card", "ar": "تحديث بطاقات التأمين"}, + "patientAge": {"en": "y", "ar": "سنة"}, + "searchCriteria": {"en": "Select Search Criteria", "ar": "حدد معايير البحث"}, + "RequesterInfo": {"en": "Requester Info", "ar": "معلومات مقدم الطلب"}, + "PatientInfo": {"en": "Patient Info", "ar": "معلومات المراجع"}, + "OtherInfo": {"en": "Other Info", "ar": "معلومات اخرى"}, + "inPrgress": {"en": "Active", "ar": "نشط"}, + "locked": {"en": "Inactive", "ar": "غير نشط"}, + "personalInfo": {"en": "Personal Information", "ar": "معلومات شخصية"}, + "cmcTitle": {"en": "Comprehensive", "ar": "خدمة"}, + "cmcSubtitle": {"en": "Medical Checkup", "ar": "الفحص الشامل"}, + "emergencyTitle": {"en": "Emergency", "ar": "خدمات"}, + "emergencySubtitle": {"en": "Services", "ar": "الطوارئ"}, + "ereferralTitle": {"en": "E-Referral", "ar": "خدمة"}, + "ereferralSubtitle": {"en": "Service", "ar": "الإحالة الإلكترونية"}, + "medicalFileTitle": {"en": "Medical File", 'ar': 'الملف الطبي'}, + "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": "بالدم"}, + "Health": {"en": "Health", "ar": "الصحة"}, + "Calculator": {"en": "Calculator", "ar": "آلة حاسبة"}, + "Converter": {"en": "Converter", "ar": "محول"}, + "Smart": {"en": "Smart", "ar": "ذكي"}, + "Watches": {"en": "Watches", "ar": "ساعات"}, + "parkingTitle2": {"en": "Car parking", "ar": "خدمة"}, + "ParkingSubtitle": {"en": "service", "ar": "مواقف السيارات"}, + "Details": {"en": "Details", "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": "Online", "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": "القياسات"}, + "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": "متوسط معدل ضربات القلب"}, + "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": "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." + }, + "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 وكلاهما في حالة مزامنة." + }, + "tamaraInstPlan": {"en": "Select the tamara installment plan", "ar": "حدد خطة تقسيط تمارة"}, + "onlineTag": {"en": "Online", "ar": "مفتوح"}, + "offlineTag": {"en": "Offline", "ar": "مغلق"}, + "viewDocList": {"en": "View List of Doctors", "ar": "عرض قائمة الأطباء"}, + "bodyFatTitle": {"en": "Body Fat", "ar": " الدهون في الجسم"}, + "cholesTitle": {"en": "Blood Cholesterol", "ar": " الكولسترول في الدم"}, + "laserClinic": {"en": "Laser Clinic", "ar": "عيادة الليزر"}, + "noImage": {"en": "No Image", "ar": "لا توجد صورة"}, + "signoutMessage": {"en": "Are you sure you want to logout?", "ar": "هل أنت متأكد أنك تريد تسجيل الخروج؟"}, + "RRTTitle": {"en": "RRT", "ar": "خدمة فريق"}, + "RRTSubTitle": {"en": "Service", "ar": "الاستجابة السريع"}, + "transportation": {"en": "Transportation", "ar": "النقل"}, + "installments": {"en": "Installments", "ar": "أقساط"}, + "neck": {"en": "Neck", "ar": "رقبه"}, + "waist": {"en": "Waist", "ar": "وسط"}, + "hip": {"en": "Hip", "ar": "ورك او نتوء"}, + "carbsProtin": {"en": "Carbs, Protein and Fat", "ar": "الكربوهيدرات والبروتينات والدهون"}, + "usefulInfo": {"en": "Useful Information", "ar": "معلومات مفيدة"}, + "babyAge": {"en": "Baby Age", "ar": "عمر الطفل الآن:"}, + "babyAgeAvail": {"en": "baby age is not available", "ar": "عمر الطفل غير متوفر"}, + "deliveryDue": {"en": "The delivery due date is estimated to be on the", "ar": "من المقدر أن يكون تاريخ استحقاق التسليم في"}, + "almostInactive": {"en": "Almost Inactive(Little or no exercises)", "ar": "شبه غير نشط (تمارين قليلة أو معدومة)"}, + "lightActive1": {"en": "Lighty Active (1-3) days per week", "ar": "Lighty Active (1-3) أيام في الأسبوع"}, + "veryActive": {"en": "very Active(6-7) days per week", "ar": "نشط جدا (6-7) أيام في الأسبوع"}, + "superActive": {"en": "Super Active(very hard exercises)", "ar": "سوبر نشط (تمارين صعبة للغاية)"}, + "dailyIntake": {"en": "Daily intake is", "ar": "المدخول اليومي"}, + "calculateAmount": {"en": "Calculates the amount of energy that the person’s body expends in a day", "ar": "تحسب كمية الطاقة التي يبذلها جسم الشخص في اليوم"}, + "bodyWillBurn": {"en": "This means the body will burn", "ar": "هذا يعني أن الجسم سوف يحترق"}, + "caloriesEachDay": { + "en": "calories each day, if engaged in no activity for the entire day.. Note: Daily calorie requirement is", + "ar": "السعرات الحرارية في كل يوم ، إذا لم تمارس أي نشاط طوال اليوم .. ملاحظة: متطلبات السعرات الحرارية اليومية هي" + }, + "maintainWeight": {"en": "calories, to maintain the current weight.", "ar": "السعرات الحرارية للحفاظ على الوزن الحالي."}, + "mediumFinger": {"en": "Medium(fingers touch)", "ar": "متوسطة (لمسة الأصابع)"}, + "smallFinger": {"en": "Small(fingers overlap)", "ar": "صغير (أصابع متداخلة)"}, + "largeFinger": {"en": "Large(fingers don\'n touch)", "ar": "كبير (لا تلمس الأصابع)"}, + "idealBodyWeight": {"en": "Calculates the ideal body weight based on height, Weight, and Body Size", "ar": "يحسب وزن الجسم المثالي بناءً على الطول والوزن وحجم الجسم"}, + "bodyFrameSize": {"en": "Body Frame Size", "ar": "حجم إطار الجسم"}, + "idealWeightRange": {"en": "Ideal weight range is", "ar": "نطاق الوزن المثالي هو"}, + "currentWeightPerfect": {"en": "Congratulations! The current weight is perfect and considered healthy", "ar": "تهانينا! الوزن الحالي مثالي ويعتبر صحي"}, + "littleBitWeightMore": {"en": "This means that the weight is a little bit more than ideal weight by", "ar": "هذا يعني أن الوزن أكثر قليلاً من الوزن المثالي به"}, + "consultWithDoctor": { + "en": "May wish to consult with the doctor for medical help. Click to view our list of Doctors", + "ar": "قد ترغب في استشارة الطبيب للحصول على مساعدة طبية. انقر لعرض قائمة الأطباء لدينا" + }, + "excessiveObesity": {"en": "Means that you suffer from excessive obesity by", "ar": "يعني أنك تعاني من السمنة المفرطة بها"}, + "mayWish": { + "en": "May wish to consult with the doctor for medical help. Click to view our list of\n Doctors", + "ar": "قد ترغب في استشارة الطبيب للحصول على مساعدة طبية. انقر لعرض قائمة الأطباء \ n الخاصة بنا" + }, + "essential": {"en": "The category falls under essential", "ar": "الفئة تندرج تحت الأساسية"}, + "athlete": {"en": "The category falls under athlete", "ar": "فئة تندرج تحت رياضي"}, + "fitness": {"en": "The category falls under fitness", "ar": "الفئة تندرج تحت اللياقة البدنية"}, + "acceptable": {"en": "The category falls under acceptable", "ar": "الفئة تندرج تحت مقبول"}, + "underObese": {"en": "The category falls under obese", "ar": "تندرج الفئة تحت السمنة"}, + "crossedLimits": { + "en": "Please check the value you have entered, since the body fat percentage has crosed the limits.", + "ar": "يرجى التحقق من القيمة التي أدخلتها ، لأن نسبة الدهون في الجسم تجاوزت الحدود." + }, + "lowLimits": { + "en": "Please check the value you have entered, since the body fat percentage cannot be this low.", + "ar": "يرجى التحقق من القيمة التي أدخلتها ، حيث لا يمكن أن تكون نسبة الدهون في الجسم منخفضة." + }, + "estimates": {"en": "Estimates the total body fat based on\nthe size", "ar": "تقدير إجمالي الدهون في الجسم بناءً على \ n الحجم"}, + "myCart": {"en": "My Cart", "ar": "عربة التسوق"}, + "browseOffers": {"en": "Browse offers by clinic", "ar": "تصفح العروض حسب العيادة"}, + "browseOffersByProject": {"en": "Browse offers by hospital", "ar": "تصفح العروض حسب المستشفى"}, + "inactiveAct": {"en": "Almost inactive (little or no exercise)", "ar": "غير نشط تقريبا (ممارسة الرياضة قليلة أو منعدمة)"}, + "light": {"en": "Lightly active (1-3) days per week", "ar": "خفيف النشاط (1-3 أيام في الأسبوع)"}, + "moderate": {"en": "Moderately active (3-5) days per week)", "ar": "معتدل النشاط (3-5 أيام في الأسبوع)"}, + "very": {"en": "Very active (6-7) days per week)", "ar": "نشط جداُ (6-7 أيام في الأسبوع)"}, + "super": {"en": "Super active (very hard exercise)", "ar": "عالي النشاط (ممارسة الرياضة الصعبة)"}, + "resultCalories": {"en": "Daily intake is (#) calories", "ar": "الإحتياج اليومي (#) سعرة حرارية"}, + "bmrDesc": {"en": "Calculates the amount of energy that the person’s body expends in a day", "ar": "معدل الأيض القاعدي: هو حساب كمية الطاقة التي يحتاجها الجسم في اليوم الواحد"}, + "idealWeightDesc": {"en": "Calculates the ideal body weight based on height, Weight, and Body Size", "ar": "حساب الوزن المثالي والوزن الصحي للجسم على أساس الطول، والوزن ،والجسم"}, + "bodyFrame": {"en": "Body Frame Size", "ar": "مقاس هيكل الجسم"}, + "bodyFrameSmall": {"en": "Small (fingers overlap)", "ar": "رفيع (الأصابع تتداخل)"}, + "bodyFrameMedium": {"en": "Medium (fingers touch)", "ar": "متوسط (الأصابع تتلامس)"}, + "bodyFrameLarge": {"en": "Large (fingers don't touch)", "ar": "عريض (الأصابع لا تتلامس)"}, + "bodyFatDesc": {"en": "Estimates the total body fat based on the size", "ar": "حساب الدهون في الجسم بناءاً على الحجم"}, + "obeseBodyFat": {"en": "The category falls under Obese.", "ar": "تندرج تحت فئة دهون جسم سمين"}, + "invalid": {"en": "Invalid input for calculation.", "ar": "البيانات المدخلة غير صالحة للحساب"}, + "more": { + "en": "Please check the value you have entered, since the body fat percentage has crossed the limits.", + "ar": "يرجى التحقق من القيمة التي أدخلتها ، نظرًا لأن نسبة الدهون في الجسم قد تجاوزت الحدود" + }, + "less": { + "en": "Please check the value you have entered, since the body fat percentage cannot be this low.", + "ar": "يرجى التحقق من القيمة التي أدخلتها ، نظرًا لأن نسبة الدهون في الجسم لا يمكن أن تكون منخفضة" + }, + "carbProteinDesc": { + "en": "Calculates carbohydrate protein and fat ratio in calories and grams according to a pre-set ratio", + "ar": "حساب نسب الكربوهيدرات و البروتينات و الدهون بالسعرات الحرارية والغرامات وفقا لنسب محددة مسبقا" + }, + "calDay": {"en": "Calories Per Day", "ar": "السعرات الحرارية في اليوم الواحد"}, + "notSure": {"en": "Not sure? click here", "ar": "غير متأكد؟ اضغط هنا"}, + "selectDiet": {"en": "Select Diet Type", "ar": "حدد نوع النظام الغذائي"}, + "dietVeryLow": {"en": "Very Low Carb", "ar": "حمية منخفضة جدا في الكربوهيدرات"}, + "dietLow": {"en": "Low Carb", "ar": "حمية منخفضة الكربوهيدرات"}, + "dietModerate": {"en": "Moderate Carb", "ar": "حمية معتدلة الكربوهيدرات"}, + "dietUSDA": {"en": "USDA Guidelines", "ar": "ارشادات وزارة الزراعة الأمريكية"}, + "dietZone": {"en": "Zone Diet", "ar": "حمية زون"}, + "Protein": {"en": "Protein", "ar": "بروتين"}, + "Cals": {"en": "Cals", "ar": "كالس"}, + "gramsPerDay": {"en": "Grams Per Day", "ar": "غرام في اليوم"}, + "gr": {"en": "gr", "ar": "غرام"}, + "gramsPerMeal": {"en": "Grams Per Meal", "ar": "عدد الجرامات لكل وجبة"}, + "syncSuccess": {"en": "Data Synced Successfully", "ar": "تمت مزامنة البيانات بنجاح"}, + "points": {"en": "Points", "ar": "نقاط"}, + "availableBalance": {"en": "Available Balance", "ar": "الرصيد المتوفر"}, + "ordersDashboard": {"en": "My Orders", "ar": "طلباتي"}, + "productOutOfStock": {"en": "Out Of Stock", "ar": "إنتهى من المخزن"}, + "productQuantity": {"en": "Quantity", "ar": "كمية"}, + "yourTurn": {"en": "your turn is after", "ar": "دورك بعد"}, + "patients": {"en": "patients", "ar": "مريض"}, + "group": {"en": "Group", "ar": "مجموعة"}, + "covidTestTodo": {"en": "Covid-19 Test", "ar": "فحص كورونا"}, + "ancillaryOrdersPaymentConfirm": {"en": "Are you sure you want to make payment for selected orders?", "ar": "هل أنت متأكد أنك تريد سداد قيمة الطلبات المختارة؟"}, + "successRegister": {"en": "Your account has been created.", "ar": "لقد تم إنشاء حسابك."}, + "pharmacyLiveCare": {"en": "Pharmacy LiveCare", "ar": "لايف كير صيدلية"}, + "ancillaryOrderPaymentSuccess": {"en": "Your payment for selected orders has been made successfully.", "ar": "تم سداد دفعتك للطلبات المحددة بنجاح."}, + "connectTitle": {"en": "Connect", "ar": "تواصل"}, + "connectSubtitle": {"en": "With us", "ar": "معنا"}, + "covidConsent": { + "en": + "Covid-19 Test feature allows you to book an appointment for the Covid-19 Lab test within HMG branches, where a swab sample will be collected & processed. Once the result has been processed, we shall notify you via SMS on your registered mobile number & the test result will also be available in the Lab Results section of this app. Please note that this result is only available to you & not publicly available to anyone else.", + "ar": + "تتيح لك ميزة اختبار كوفيد19 حجز موعد في احد فروع مجموعة الحبيب الطبية ، حيث سيتم اخذ عينة المسحة ومعالجتها. بمجرد معالجة النتيجة ، سنخطرك عبر رسالة نصية قصيرة على رقم هاتفك المحمول المسجل وستكون نتيجة الاختبار متاحة أيضًا على التطبيق في قسم نتائج المختبر. يرجى ملاحظة أن هذه النتيجة متاحة لك فقط وليست متاحة للجمهور او اي شخص آخر. الرجاء الموافقة للتأكيد والمتابعة." + }, + "covidConsentHeader": {"en": "User Consent", "ar": "موافقة المستخدم"}, + "drawOverAppsPermission": { + "en": "Please allow the Al-Habib Medical Group application to appear on the top of the screen when receiving the call from the doctor for LiveCare service.", + "ar": "الرجاء السماح لتطبيق مجموعة الحبيب الطبية للظهورعلى سطح الشاشة عند استلام الاتصال من الطبيب لخدمة اللايف كير" + }, + "cameraPermissionDialog": { + "en": "Dr. Al Habib app needs to access Camera to enable virtual consultation between patient & doctor, attach images and scan QR for parking service.", + "ar": "يحتاج تطبيق دكتور الحبيب الى صلاحية الوصول إلى الكاميرا لخدمة الاستشارة الافتراضية بين المراجع والطبيب وإرفاق الصور ومسح رمز الاستجابة السريع لخدمة مواقف السيارات." + }, + "galleryPermission": { + "en": "Dr. Al Habib app needs to access Read & write external storage to upload images & documents in the E-Referral module and renew and update the insurance cards.", + "ar": "يحتاج تطبيق دكتور الحبيب إلى صلاحية الوصول إلى معرض الصور وذلك لتحميل الصور والمستندات لخدمة الإحالة الإلكترونية وكذلك لخدمة تجديد بطاقات التأمين وتحديثها." + }, + "locationPermissionDialog": { + "en": + "Dr. Al Habib app collects location data to show the nearest HMG hospitals and ER Locations and provides health care services to your location and Health weather indicators service and the medication delivery.", + "ar": "يحتاج تطبيق دكتور الحبيب إلى صلاحية الوصول الى الموقع لإظهار أقرب مستشفيات المجموعة، مواقع الطوارئ، تقديم خدمات الرعاية الصحية إلى موقعك، خدمة مؤشرات الطقس الصحية وكذلك خدمة توصيل الأدوية." + }, + "calendarPermission": { + "en": "Dr. Al Habib app collects calendar data to modify and set reminders for Appointments", + "ar": "يحتاج تطبيق دكتور الحبيب إلى صلاحية الوصول الى التقويم وذلك لاضافة تذكيرات بالمواعيد في التقويم." + }, + "recordAudioPermission": { + "en": "Dr. Al Habib app needs audio permission to enable voice command features.", + "ar": "يحتاج تطبيق دكتور الحبيب إلى صلاحية الوصول الى الصوت لتفعيل خدمة الأوامر الصوتية." + }, + "wifiPermission": { + "en": "Dr. Al Habib app needs to access WiFi state permission to connect to the HMG WiFi network from within the app when you visit the hospital.", + "ar": "يحتاج تطبيق دكتور الحبيب إلى الوصول إلى الواي فاي للاتصال بشبكة الواي فاي في المجموعة عند زيارة المستشفى." + }, + "physicalActivityPermission": { + "en": "Dr. Al Habib app collects physical activity data to read heart rate, steps & distance from your smartwatch & send it to your doctor.", + "ar": "يحتاج تطبيق دكتور الحبيب إلى الوصول إلى بيانات النشاط البدني لقراءة معدل ضربات القلب والخطوات والمسافة من ساعتك الذكية وتحميلها على ملفك الطبي حتى يتمكن الطبيب من الاطلاع عليها." + }, + "bluetoothPermission": { + "en": "Dr. Al Habib app needs to access Bluetooth permission to connect blood pressure & blood sugar devices with the app to analyze the data", + "ar": "يحتاج تطبيق دكتور الحبيب إلى الوصول إلى البلوتوث لربط أجهزة ضغط الدم وسكر الدم بالتطبيق لتحليل البيانات وتحميلها على ملفك الطبي حتى يتمكن الطبيب من الاطلاع عليها." + }, + "privacyPolicy": {"en": "Privacy Policy", "ar": "سياسة الخصوصية"}, + "termsConditions": {"en": "Terms & Conditions", "ar": "الأحكام والشروط"}, + "prescriptionDeliveryError": {"en": "This clinic does not support refill & delivery.", "ar": "هذه العيادة لا تدعم إعادة التعبئة والتسليم."}, + "liveCarePermissions": { + "en": "LiveCare requires Camera, Microphone & Location permissions to enable virtual consultation between patient & doctor, Please allow these to proceed.", + "ar": "يتطلب لايف كير أذونات الكاميرا والميكروفون والموقع، يرجى السماح لها بالمتابعة." + }, + "lakumUnhold": {"en": "The account has already been activated", "ar": "لقد تم تفعيل الحساب من قبل"}, + "lakumDiscontinue": {"en": "The account is closed", "ar": "الحساب مغلق"}, + "lakumSuccess": {"en": "The account has been activated successfully", "ar": "تم تفعيل الحساب بنجاح"}, + "deleteAccount": {"en": "Deactivate Account", "ar": "ايقاف الحساب مؤقتاً"}, + "deactivateAccount": {"en": "Are you sure you want to deactivate your account?", "ar": "هل أنت متأكد أنك تريد ايقاف الحساب مؤقتاً حسابك؟"}, + "accountDeactivated": {"en": "Your account has been deactivated successfully", "ar": "تم ايقاف الحساب مؤقتاً بنجاح."}, + "accountDeactivatedMsg": {"en": "Your account has been deactivated. Would you like to reactivate it?", "ar": "حسابك معطل. هل ترغب في إعادة تنشيطه مرة أخرى؟"}, + "updateInsuranceManually": {"en": "Update Insurance Manually", "ar": "تحديث التأمين يدويا"}, + "or": {"en": "Update Insurance Manually", "ar": "تحديث التأمين يدويا"}, + "enterInsuranceDetails": {"en": "Please enter your insurance card details below:", "ar": "الرجاء إدخال تفاصيل بطاقة التأمين الخاصة بك أدناه:"}, + "cardHolderName": {"en": "Card Holder Name", "ar": "إسم صاحب البطاقة"}, + "membershipNo": {"en": "Membership No.", "ar": "رقم العضوية"}, + "policyNo": {"en": "Policy No.", "ar": "رقم وثيقة التأمين"}, + "paymentOnly": {"en": "Payment", "ar": "معلقة"}, + "pendingOnly": {"en": "Pending", "ar": "مدفوعات"}, + "insuranceClassName": {"en": "Insurance Class", "ar": "فئة التأمين"}, + "insuranceRequestSubmit": {"en": "Your insurance update request has been submitted successfully.", "ar": "تم تقديم طلب تحديث التأمين الخاص بك بنجاح."}, + "NFCNotSupported": {"en": "Your device does not support NFC. Please visit reception to Check-In", "ar": "جهازك لا يدعم NFC. يرجى زيارة مكتب الاستقبال لتسجيل الوصول"}, + "enter-workplace-name": {"en": "Please enter your workplace details:", "ar": "الرجاء إدخال تفاصيل مكان عملك:"}, + + // "workplaceName": {"en": "Workplace name:", "ar": "مكان العمل:"}, + "workplaceName": {"en": "Workplace name English", "ar": "مكان العمل انجليزي:"}, + "workplaceNameAr": {"en": "Workplace name Arabic *", "ar": "مكان العمل عربي:"}, + "occupationNameEn": {"en": "Occupation name English", "ar": "مكان العمل انجليزي:"}, + "occupationNameAr": {"en": "Occupation name Arabic *", "ar": "مكان العمل عربي:"}, + + "callLiveCareSupport": {"en": "Call LiveCare Support", "ar": "اتصل بدعم اللايف كير"}, + "needApproval": { + "en": "Your sick leave is under process in medical administration, you will be notified once approved.", + "ar": "جازتك المرضية تحت الإجراء في الإدارة الطبية ، سوف يتم إشعارك فور الموافقه عليها." + }, + "pendingActivation": {"en": "Pending Activation", "ar": "في انتظار التنشيط"}, + "awaitingApproval": {"en": "Awaiting Approval", "ar": "انتظر القبول"}, + "liveCareSupportContact": {"en": "LiveCare Support Contact: ", "ar": "اتصل لايف كير: "}, + "pharmaLiveCare": {"en": "Pharma LiveCare", "ar": "لايف كير الصيدلية"}, + "pharmaLiveCare1": {"en": "What is Pharma LiveCare?", "ar": "ما هولايف كير الصيدلية؟"}, + "pharmaLiveCareDesc1": { + "en": "Pharma LiveCare allows you to get consultation from your doctor virtually being in HMG Pharmacy booth.", + "ar": "تتيح لك خدمة لايف كير الصيدلية الحصول على استشارة من طبيبك المتواجد فعليًا في كشك صيدلية د.سليمان الحبيب." + }, + "wherePharmaLiveCare": {"en": "Where can i find Pharma LiveCare?", "ar": "أين يمكنني أن أجد لايف كير الصيدلية؟"}, + "pharmaLiveCareDesc2": {"en": "You can find the booth in HMG Pharmacies.", "ar": "يمكنك العثور على الكشك في صيدليات مستشفى د.سليمان الحبيب."}, + "howPharmaLiveCare": {"en": "How can i use Pharma LiveCare?", "ar": "كيف يمكنني استخدام لايف كير الصيدلية؟"}, + "pharmaLiveCareDesc3": { + "en": "Following the below steps you can easily benefit from the virtual consultation service:", + "ar": "باتباع الخطوات التالية يمكنك الاستفادة بسهولة من خدمة الاستشارة الافتراضية:" + }, + "pharmaLiveCareScanQR": {"en": "Scan QR Code", "ar": "مسح رمز الاستجابة السريعة"}, + "pharmaLiveCareScanQR1": {"en": "Scan the QR Code in the booth to make the connection", "ar": "امسح رمز الاستجابة السريعة في المقصورة لإجراء الاتصال"}, + "pharmaLiveCareMakePayment": {"en": "Make Payment Online", "ar": "قم بالدفع عبر الإنترنت"}, + "pharmaLiveCareMakePayment1": {"en": "Make the payment through the mobile app", "ar": "قم بالدفع من خلال تطبيق الهاتف المحمول"}, + "pharmaLiveCareJoinConsultation": {"en": "Join the virtual consultation from booth", "ar": "انضم إلى الاستشارة الافتراضية من الكبينة"}, + "pharmaLiveCareJoinConsultation1": {"en": "Wait for the doctor in the pharma booth to join you", "ar": "انتظر حتى ينضم إليك الطبيب في كبينة لايف كير الصيدلية"}, + "emergencyServicesSubtitle": {"en": "Always at your service", "ar": "في خدمتكم دائما"}, + "rateDoctorResponse": {"en": "Rate Doctor Response", "ar": "تقييم استجابة الطبيب"}, + "comments": {"en": "Comments", "ar": "تعليقات"}, + "rateDoctorResponseHeading": {"en": "Please rate the doctor response:", "ar": "يرجى تقييم استجابة الطبيب:"}, + "updateInsuranceManuallyDialog": {"en": "Would you like to update your insurance manually?", "ar": "هل ترغب في تحديث التأمين الخاص بك يدويًا؟"}, + "viewReport": {"en": "View Report", "ar": "عرض التقرير"}, + "sickLeaveAdmittedPatient": {"en": "You cannot activate this sick leave since you're an admitted patient.", "ar": "لا يمكنك تفعيل هذه الإجازة المرضية لأنك مريض مقبل."}, + "InPatient": {"en": "InPatient", "ar": "خدمات"}, + "InPatientServices": {"en": "Services", "ar": "تنويم"}, + "InPatientServicesHeader": {"en": "InPatient Services", "ar": "خدمات التنويم"}, + "admissionGeneral": {"en": "Admission General", "ar": "اقرار"}, + "consent": {"en": "Consent", "ar": "التنويم"}, + "generalInstructionsTitle": {"en": "General", "ar": "تعليمات"}, + "generalInstructionsSubTitle": {"en": "Instructions", "ar": "التنويم العامة"}, + "generalConsentTitle": {"en": "General", "ar": "الموافقة"}, + "generalConsentSubTitle": {"en": "Consent", "ar": "العامة"}, + "medicalInstructionsTitle": {"en": "Medical", "ar": "التعليمات الطبية"}, + "medicalInstructionsSubTitle": {"en": "Instructions", "ar": "قبل التنويم"}, + "mealPlanTitle": {"en": "Meal Plan", "ar": "خدمات"}, + "mealPlanSubTitle": {"en": "Services", "ar": "الوجبات"}, + "birthNotificationTitle": {"en": "Birth", "ar": "خدمات"}, + "birthNotificationSubTitle": {"en": "Notification", "ar": "تبليغ الولادة"}, + "admissionNoticeTitle": {"en": "Admission", "ar": "إشعار"}, + "admissionNoticeSubTitle": {"en": "Notice", "ar": "تنويم"}, + "mothersMRN": {"en": "Mother's MRN *", "ar": "رقم ملف الأم"}, + "mothersName": {"en": "Mother's name *", "ar": "اسم الأم"}, + "fathersNameEN": {"en": "Father's name english *", "ar": "اسم الاب انجليزي"}, + "fathersNameAR": {"en": "Father's name arabic *", "ar": "اسم الاب عربي"}, + "babysNameEN": {"en": "Baby's name english *", "ar": "اسم المولود انجليزي"}, + "babysNameAR": {"en": "Baby's name arabic *", "ar": "اسم المولود عربي"}, + "contactNumber": {"en": "Contact number *", "ar": "رقم الاتصال"}, + "scanID": {"en": "Scan ID", "ar": "معرف المسح"}, + "birthNotificationNotes1": { + "en": "For Saudis: Provide copy of the identification card for both couples. If the wife doesn't have identification card, The family card must be provided.", + "ar": "للسعوديين : إرفاق صورة من بطاقة الأحوال لكلا الزوجين وفي حال عدم توفر بطاقة الزوجة ترفق عنها بطاقة العائلة" + }, + "birthNotificationNotes2": {"en": "Non Saudis: Provide copy of iqama or copy of the passport.", "ar": "لغير السعوديين : إرفاق صورة الإقامة آأو جواز السفر"}, + "birthNotificationNotes3": {"en": "For Residents without identification card: Provide marriage contract.", "ar": "للمواطنين الغير حاملين لبطاقة الأحوال : إرفاق صورة من عقد الزواج برقم الحاسب"}, + "placeOrder": {"en": "Place Order", "ar": "مكان الامر"}, + "isFasting": {"en": "Are you fasting?", "ar": "هل أنت صائم؟"}, + "noGeneralInstructions": {"en": "You do not have any general instructions right now.", "ar": "ليس لديك أي تعليمات عامة في الوقت الحالي."}, + "noMedicalInstructions": {"en": "You do not have any medical instructions right now.", "ar": "ليس لديك أي تعليمات طبية في الوقت الحالي."}, + "medicalInstructions": {"en": "Medical Instructions:", "ar": "تعليمات طبية:"}, + "generalInstructions": {"en": "General Instructions:", "ar": "تعليمات عامة:"}, + "copyLink": {"en": "COPY LINK", "ar": "نسخ الوصلة:"}, + "paymentLinkCopied": {"en": "Payment link copied to your clipboard!'", "ar": "تم نسخ رابط الدفع إلى الحافظة الخاصة بك!"}, + "copyLinkTxt": { + "en": "Or you can copy the payment link from below & send it to someone who can pay on your behalf: ", + "ar": "أو يمكنك نسخ رابط الدفع من الأسفل وإرساله إلى شخص يمكنه الدفع نيابة عنك:" + }, + "proErrorMessage": { + "en": + "Dear patient, Our staff is currently out of office, please note that our working hours are from 7:00 AM to 10:00 PM, and we'd love to help you during that time, or you can call ", + "ar": "عزيزي المريض ، طاقم العمل لدينا خارج المكتب حاليًا ، يرجى ملاحظة أن ساعات العمل لدينا من 7:00 صباحًا إلى 10:00 مساءً ، ويسعدنا مساعدتك خلال هذا الوقت ، أو يمكنك الاتصال بـ <أدخل الرقم هنا>" + }, + "admissionNo": {"en": "Admission No", "ar": "رقم القبول:"}, + "admissionReqNo": {"en": "Admission Request No", "ar": "رقم طلب القبول:"}, + "dischargeDate": {"en": "Discharge Date", "ar": "تاريخ التفريغ"}, + "selectAdmissionText": {"en": "Please select one of the admissions from below to view medical reports:", "ar": "يرجى تحديد أحد حالات القبول من الأسفل لعرض التقارير الطبية:"}, + "onlyAdmitted": {"en": "This service is only available for admitted patients", "ar": "هذه الخدمة متاحة فقط للمرضى المقبولين"}, + "assistYou": {"en": "How we may assist you?", "ar": "كيف يمكننا مساعدتك؟"}, + "receive": {"en": "Receive", "ar": "تجهيز"}, + "PRO": {"en": "PRO", "ar": "علاقات المرضى"}, + "patientRelationOffice": {"en": "Patient Relation Office", "ar": "علاقات المرضى"}, + "roomNo": {"en": "Room No.", "ar": "رقم الغرفة"}, + "invalidEligibility": { + "en": "You cannot make online payment because you are not eligible to use the provided service.", + "ar": "لا يمكنك إجراء الدفع عبر الإنترنت لأنك غير مؤهل لاستخدام الخدمة المقدمة." + }, + "invalidInsurance": {"en": "You cannot make online payment because you do not have a valid insurance.", "ar": "لا يمكنك إجراء الدفع عبر الإنترنت لأنه ليس لديك تأمين صالح."}, + "continueCash": {"en": "Continue as cash", "ar": "تواصل نقدا"}, + "updateInsurance": {"en": "Update insurance", "ar": "تحديث التأمين"}, + "downloadReport": {"en": "Download Report", "ar": "تحميل تقرير المختبر"}, + "habibCallCenter": {"en": "Please contact AlHabib call center to update your insurance manually.", "ar": "يرجى الاتصال بمركز اتصال الحبيب لتحديث التأمين الخاص بك يدوياً."}, + "cashAmountUpdateInsurance": { + "en": "Please note that this is the cash amount, If you want to update your insurance, Please tap below:", + "ar": "يرجى ملاحظة أن هذا هو المبلغ النقدي، إذا كنت ترغب في تحديث التأمين الخاص بك، يرجى النقر أدناه:" + }, + "validInsurance": {"en": "Do you have a valid insurance?", "ar": "هل لديك تأمين صالح؟"}, + "resultStatus": {"en": "Result Status: ", "ar": "حالة النتيجة: "}, + "contactRRT": {"en": "Contact RRT", "ar": "تواصل مع فريق الاستجابة السريعة"}, + "checkInViaLocation": {"en": "Check-In Via Location", "ar": "تسجيل الوصول عبر الموقع"}, + "locationCheckInError": {"en": "Please ensure you're within the hospital location to perform online check-in.", "ar": "يرجى التأكد من تواجدك داخل موقع المستشفى لإجراء تسجيل الوصول عبر الإنترنت."}, + "upcoming": {"en": "Upcoming", "ar": "المواعيد القادمة"}, + "noUpcomingAppointment": {"en": "No upcoming appointments", "ar": "لا توجد مواعيد القادمة"}, + "locationTimeoutError": {"en": "Unable to fetch your location, Please try again.", "ar": "غير قادر على جلب موقعك، يرجى المحاولة مرة أخرى."}, + "loadMore": {"en": "Load More", "ar": "تحميل المزيد"}, + "selectHospitalBloodDonation": {"en": "Please select the hospital you want to book an appointment with: ", "ar": "يرجى اختيار المستشفى الذي تريد حجز موعد معه:"}, + "wecare": {"en": "We Care", "ar": "نحن نهتم"}, + "myinstructions": {"en": "My Instructions", "ar": "تعليماتي"}, + "existingPackage": {"en": "This patient has a package under this clinic,", "ar": "هذا المريض لديه حزمة تحت هذه العيادة،"}, + "continueOrbookNew": {"en": "do you want to continue with that package? or book new appointment?", "ar": "هل تريد الاستمرار في هذه الباقة؟ أو حجز موعد جديد؟"}, + "newAppointment": {"en": "New Appointment", "ar": "موعد جديد"}, + "proceedPackage": {"en": "Proceed with package", "ar": "المضي قدما في الحزمة"}, + + "clinicLocation": {"en": "Clinic Location", "ar": "موقع العيادة"}, + "waitingAppointment": {"en": "Waiting appointment", "ar": "انتظار الموعد"}, + "whatWaitingAppointment": {"en": "What is Waiting appointment?", "ar": "ما هو انتظار الموعد؟"}, + "waitingAppointmentText1": { + "en": "The waiting appointments feature allows you to book an appointment while you are inside the hospital building, and in case there is no available slot in the doctor’s schedule.", + "ar": "تتيح لك خاصية انتظار المواعيد حجز موعد أثناء تواجدك داخل مبنى المستشفى، وفي حالة عدم وجود وقت متاح في جدول الطبيب." + }, + "waitingAppointmentText2": {"en": "The appointment with the doctor is confirmed, but the time of entry is uncertain", "ar": "دخول الموعد مؤكد, التوقيت غير محدد."}, + "waitingAppointmentText3": { + "en": "Note: You must have to pay within 10 minutes of booking, otherwise your appointment will be cancelled automatically", + "ar": "ملحوظة: يجب عليك الدفع خلال 10 دقائق من الحجز، وإلا سيتم إلغاء موعدك تلقائيًا" + }, + "waitingAppointmentVerificationMethod": {"en": "Please select verification method", "ar": "الرجاء تحديد طريقة التحقق"}, + "howToUseVerificationMethod": {"en": "How to use verification methods?", "ar": "كيفية استخدام طرق التحقق؟"}, + "addToWaitingList": {"en": "Add to waiting list", "ar": "اضافه الى قائمة الانتظار"}, + "searchClinic": {"en": "Search Clinic", "ar": "بحث العيادة"}, + "enterMobileNumber": {"en": "Enter Mobile Number", "ar": "أدخل رقم الجوال"}, + "videoCall": {"en": "Video Call", "ar": "اتصال فيديو"}, + "audioCall": {"en": "Audio Call", "ar": "اتصال صوتية"}, + "phoneCall": {"en": "Phone Call", "ar": "اتصال هاتفية"}, + "selectCallType": {"en": "Select Call Type", "ar": "حدد نوع المكالمة"}, + "selectedCallType": {"en": "Selected Call Type", "ar": "نوع المكالمة المحدد"}, + "selectBranch": {"en": "Select Branch", "ar": "اختر الفرع"}, + "searchByBranch": {"en": "Search By Branch Name", "ar": "البحث عن طريق اسم الفرع"}, + "hospitalNavigationTitle": {"en": "Hospital", "ar": "الملاحة"}, + "hospitalNavigationSubtitle": {"en": "Navigation", "ar": "المستشفى"}, + "continueAgreeTerms": {"en": "By continuing, You agree to the above Terms and Conditions.", "ar": "من خلال المتابعة، فإنك توافق على الشروط والأحكام المذكورة أعلاه."}, + "agreeText": {"en": "Agree", "ar": "أوافق"}, + "ERCheckInSuccess": {"en": "Your ER Online Check-In has been successfully done. Please proceed to the waiting area.", "ar": "لقد تم تسجيل دخولك عبر الإنترنت بنجاح. يرجى التوجه إلى منطقة الانتظار."}, + "generalConsent": {"en": "General Consent: ", "ar": "موافقة عامة:"}, + + "generalConsent1": { + "en": + "I authorize the Hospital and their staff to conduct any diagnostic examinations, test (including, but not limited to, HIV, HBsAg and any other as the clinician may deem fit), procedures and to provide any medications, treatments or therapy necessary to effectively assess and maintain my health, and to assess, diagnose and treat my illness or injuries. I understand that it is the responsibility of my health care providers to explain the patient's condition and thereby reasons for any particular diagnostic examination, test or procedure, the available treatment options, the common risks, anticipated benefits associated with these options, alternative courses of treatment and possible outcomes of non-treatment.", + "ar": + "أفوض المستشفى وموظفيه بإجراء أية فحوصات واختبارات وإجراءات تشخيصية (بما في ذلك مثالاً وليس حصراً فحوصات أمراض الكبد الوبائية أو نقص المناعة المكتسبة أو أي فحوصات أخرى يرى الطبيب المعالج (مناسبتها وتقديم أية أدوية أو علاج ضروري لتقييم . صحتي والمحافظة عليها بفاعلية والتقييم وتشخيص ومعالجة مرضي او الإصابات اللاحقة بي، وأدرك بأنه من مسؤولية مقدمي الرعاية الصحية بيان أسباب أي فحص أو إختبار أو إجراء تشخيصي محدد وخيارات العلاج المتوفرة والمخاطرة الشائعة والمنافع المتوقعة المرتبطة بهذه الخيارات والعلاج البديل والنتائج المحتملة لرفض العلاج." }, - "confirm-prescription": { - "en": "Are you sure !! you want to send this request", - "ar": "تاكيد ارسال الطلب؟" + "hospitalRules": {"en": "HOSPITAL RULES: ", "ar": "أنظمة المستشفى: "}, + "generalConsent2": { + "en": + "Agree to be obliged to adhere to the Hospital rules, and to ensure compliance by all visitors. In the event of any severe violations of the rules, the hospital reserves the right to take the necessary measures according to the applicable Laws.", + "ar": + "أوافق على التقيد بقواعد وأنظمة المستشفى، وأضمن التزام جميع الزوار بذلك ، في حالة حدوث أي إنتهاكات جسيمة لقواعد وأنظمة المستشفى، يحتفظ المستشفى بالحق في إتخاذ جميع الاجراءات النظامية المكفولة." }, - "you-already-have-order": { - "en": "You already have this order! do you want to view it?", - "ar": "لديك هذا الطلب بالفعل! هل تريد مشاهدته؟" + "communicationConsent": {"en": "COMMUNICATION VIA EMAIL, TEXT MESSAGES AND PHONE CALLS: ", "ar": "الاتصال عبر البريد الإلكتروني والرسائل النصية والمكالمات الهاتفية: "}, + "generalConsent3": { + "en": + "I understand that the contact number or Email that I have provided on registration will be used for communication by the Hospital. I hereby agree to be notified by the Hospital through SMS, Email, phone calls or any other method, for appointments notifications, special promotions, new features or products, current HMG's medical services, and of any services introduced by the Hospital or any third party in the future or any modifications made to the services offered by the Hospital. And these messages may be submitted as evidence where the Hospital has the right to use at any time whatsoever and as it sees fit. I understand the risks of communicating by email and text messages, in particular the privacy risks. I understand that the Hospital cannot guarantee the security and confidentiality of email or text communication. The Hospital will not be responsible for messages that are not received or delivered due to technical failure, or for disclosure of confidential information unless caused by intentional misconduct.", + "ar": + "المستشفى أدرك بأن رقم الجوال الهاتف أو البريد الإلكتروني الذي قدمته في نموذج التسجيل سيستخدم كوسيلة اتصال بيني وبين | وأقر بموافقتي على قيام المستشفى بإخطاري عن طريق رسائل البريد أو الرسائل القصيرة أو البريد الإلكتروني أو المكالمات الهاتفية أو أي طريقة أخرى بالمواعيد والعروض الترويجية أو المميزات والمنتجات الخاصة بالمستشفى أو) خاصة بأي طرف خارجي) وبأي خدمات طبية تقدمها المجموعة أو قد يطرحها المستشفى في المستقبل أو أي تعديلات قد تطرأ على الخدمات المقدمة من قبل المستشفى. وتعتبر هذه الرسائل دليل إثبات يحق للمستشفى استخدامه في اي وقت يشاء. أفهم مخاطر التواصل عبر البريد الإلكتروني والرسائل النصية خاصة مخاطر الخصوصية وأدرك أن المستشفى لا يمكنه ضمان أمن وسرية البريد الإلكتروني أو الرسائل النصية ولن يكون المستشفى مسؤول عن الرسائل التي لم يتم استلامها أو تسليمها بسبب الفشل التقني أو الكشف عن المعلومات السرية ما لم يكن سببها سوء سلوك متعمد." }, - "order-overview": {"en": "Order Overview", "ar": "ملخص الطلب"}, - "shipping-address": {"en": "Delivery Address", "ar": "عنوان التوصيل"}, - "pharmacy-relogin": { - "en": "Your session has timed out, Please try again", - "ar": "انتهت مهلة جلسة الخاص بها. يرجى المحاولة مرة أخرى" + "releaseConsent": {"en": "RELEASE OF PERSONAL AND MEDICAL INFORMATION: ", "ar": "الإفصاح عن المعلومات الشخصية والطبية: "}, + "generalConsent4": { + "en": + "On completion of this consent I hereby authorize the hospital to provide any information of whatever nature concerning my treatment, including but not limited to, current conditions/co-morbidities to my insurance carrier or third party payer, for the purpose of determining benefit entitlement and to process payment, therefore taking responsibility for the financial settlement of my medical bills.", + "ar": + "عند تعبئة هذا النموذج ، أصرح بموجبه للمستشفي بتقديم أية معلومات أياً كانت طبيعتها بخصوص حالتي الصحية وعلاجي لشركة التأمين أو لأي طرف آخر مسؤول عن الدفع لأغراض تحديد حق الاستفادة والقيام بالدفع وبالتالي تحمل المسؤولية عن التسوية المالية للفواتير الطبية الخاصة بي." }, - "ancillary-orders": {"en": "Ancillary Orders", "ar": "الأوامر التبعية"}, - - "onlineCheckInAgreement": { + "generalConsent5": { "en": - "The online check-in is for non-life threatening situationCall the red crescent (number) or go to the nearest emergency department if there are:signs of stroke or heart attack history of seizure or syncope there is limb or life threatening injury picture of severe injuries​", + "The Hospital is obliged by local and government regulations to submit certain patient information and I hereby give consent for the disclosure or use of my information as per statutory requirement. I also acknowledge that this consent is subject to the laws and jurisdiction of the country in which the Hospital is located.", "ar": - "تسجيل الذهاب الى الطوارئ عبر الإنترنت هو فقط للحالات  التي لا تهدد الحياة يجب الاتصل بالهلال الأحمر (رقم) أو الذهاب إلى أقرب قسم طوارئ إذا كان هناك علامات السكتة الدماغية أو النوبة القلبية او هناك نوبة تشنج او حالة فقدان الوعي او وجود إصابة تهدد أحد الأطراف او تهدد الحياة او وجود إصابات خطيرة" + " إن المستشفى ملزم بموجب الأنظمة المحلية وأنظمة الدولة بتقديم بعض المعلومات المتعلقة بالمريض وأوافق بموجبه على إفصاح أو استخدام المستشفى للمعلومات الخاصة بي حسبما هو مطلوب نظاماً، وأن هذا الإقرار خاضع للأنظمة والقوانين والاختصاص القضائي للدولة حيث يقع المستشفى." }, - "MRN": {"en": "MRN", "ar": "ایم آر این"}, - "appointment-date": {"en": "Appointment Date", "ar": "تقرری کی تاریخ"}, - "appointment-no": {"en": "Appointment No", "ar": "تقرری نمبر"}, - "insurance-id": {"en": "Insurance ID", "ar": "انشورنس ID"}, - "chiefComplaints": {"en": "Chief Complaints", "ar": "الشكوى الرئيسة"}, - "errorChiefComplaints": { - "en": "Please Chief Complaints", - "ar": "يرجى ادخال الشكوى الرئيسة" + "valuables": {"en": "VALUABLES: ", "ar": "الممتلكات الثمينة: "}, + "generalConsent6": { + "en": "The Hospital is not liable for the loss or damage of any money, jewelry, documents or other personal articles of value.", + "ar": "المستشفى غير مسؤول عن ضياع أو تلف أي أموال أو مجوهرات أو مستندات أو أي أشياء أخري ذات قيمة." }, - "errorExpectedArrivalTimes": { - "en": "Please Expected arrival time", - "ar": "يرجى ادخال الوقت المتوقع للوصول" + "financialConsent": {"en": "FINANCIAL AGREEMENT: ", "ar": "الموافقة المالية: "}, + "generalConsent7": { + "en": + "Within the expected time frame during their hospital visit or stay, patients/relatives are required to take personal responsibility and meet any financial obligation towards the Hospital regardless of the mode and source of payment (i.e. self-paying, insurance company, sponsoring company & others). I understand that for credit cases (Insurance covered or corporate patients) approval letter is essential at the time of admission. In case the approval letter is not available, I, the undersigned, agree to be treated as cash patient and advance deposit shall be made. Once approval is obtained the amount paid as advance shall be refunded to me / patient and if there is no approval till discharge the bill shall be settled in full by me/patient.", + "ar": + "يتوجب علي ضمن الاطار الزمني المتوقع أثناء زيارة المستشفى أو الإقامة فيها تحمل المسؤولية الشخصية والوفاء بأي التزام مالي تجاه المستشفى بغض النظر عن طريقة ومصدر الدفع (أي: الدفع الذاتي أو شركة التأمين أو صاحب العمل أو غيره، وأن الموافقة المسبقة ضرورية قبل دخول المستشفى في حالة التغطية المالية من قبل شركة التأمين أو شركة الكفالة في الحالات التي يتم فيها تأخر الموافقة أتعهد أنا الموقع أدناه بالموافقة على العلاج كمريض دفع ذاتي ويجب إيداع مبلغ تحت الحساب يتم استرداده بعد الحصول على موافقة التأمين، ويجب دفع الحساب بالكامل في حالة عدم الحصول على موافقة التأمين حتى موعد الخروج." }, - "expectedArrivalTime": { - "en": "Expected arrival time", - "ar": "الوقت المتوقع للوصول" + "dataSharingConsent": {"en": "DATA SHARING AND INQUIRY: ", "ar": "تبادل المعلومات والاستفسارات: "}, + "generalConsent8": { + "en": + "Hereby, I, the undersigned, agree to provide the Hospital with any information that it requires for the establishing and/or auditing and/or administering my accounts and facilities therewith and I authorize it to obtain and collect any information as it deems necessary or in need for regarding me, my accounts and facilities therewith, from the Saudi Credit Bureau (SIMAH) or to any other agency approved by Saudi Arabian Monetary Agency (SAMA) and to disclose and share (inclusive of Data Pooling) that information to the said company (SIMAH) or to any other agency approved by Saudi Arabian Monetary Agency (SAMA) in accordance with the Membership Agreement and Code of Conduct approved. I agree and acknowledge that the delay in payment or non-payment of Hospital dues is a failure and as a result, SIMAH and/or any other agency approved by will be provided with my name and information to be added to the lists at SIMAH. These lists are accessed by other parties, and I will not be removed from these lists until I pay all of the outstanding amounts.", + "ar": + "بهذا أنا الموقع أدناه أوافق على تزويد المستشفى بأي معلومات أو بيانات يطلبها مني لتأسيس ملفي لدى المستشفى و/أو لمراجعته و/ أو لإدارته وأفوض المستشفى بأن يحصل على ما يلزم أو يحتاج إليه من معلومات تخصني من الشركة السعودية للمعلومات الائتمانية (سمة) واو اي جهة أخرى معتمدة من مؤسسة النقد العربي السعودي (ساما). كما أوافق على أن يفصح المستشفى عن المعلومات الخاصة بي لدى المستشفى للشركة السعودية للمعلومات الائتمانية (سمة) واو اي جهة أخرى معتمدة من مؤسسة النقد العربي السعودي (ساما) من خلال إتفاقية العضوية المبرمة وقواعد العمل المقرة والخاصة بتبادل المعلومات. كما أوافق وأقر بان التأخير في السداد أو عدم السداد لمستحقات المستشفى يعتبر تقصيراً وإخلالاً مني ونتيجة لذلك سيتم تزويد الشركة السعودية للمعلومات الائتمانية (سمه) و/أو أي جهة أخرى توافق عليها مؤسسة النقد العربي السعودي (ساما) بإسمي ومعلوماتي الإضافتها على القوائم لديها هذه القوائم يتم الوصول اليها والإطلاع عليها من قبل جهات أخرى، ولن يتم رفع اسمي من تلك القوائم إلا بعد أداء كافة ما علي من مبالغ مستحقة." }, - "add-address": {"en": "Add new address", "ar": "اضف عنوان جديد"}, - "enter-file": { - "en": "Please enter the mobile number and the medical file number", - "ar": "الرجاء إدخال رقم الجوال ورقم الملف الطبي" - } + "permissionLeaveConsent": {"en": "PERMISSION TO LEAVE THE HOSPITAL: ", "ar": "قواعد المستشفى: "}, + "generalConsent9": { + "en": + "Fully understand that, at no time, patient can leave the Hospital without prior consent and approval of treating doctor. In case I insist on leaving the Hospital, I must sign an undertaking of my responsibility on leaving the Hospital against the medical advice.", + "ar": "اتفهم انه ليس بإمكاني مغادرة المستشفى في أي وقت شئت دون أخذ إذن طبيبي المعالج. وفي حالة إصراري على مغادرة المستشفى يتعين علي توقيع اقرار مغادرتي ضد النصيحة الطبية وعلى مسؤوليتي." + }, + "observeConsent": {"en": "CONSENT TO OBSERVE: ", "ar": "قواعد المستشفى: "}, + "generalConsent10": { + "en": + "Observers will be allowed according to the Hospital policy as will the taking of pictures of medical or surgical procedures and the use of same for internal staff education or process improvement purposes. Observation and photography or medical or surgical procedures may be done with the approval of the Hospital and in accordance with the Hospital's policy and related laws. I, the undersigned, fully understand that electronically-transmitted information may be used and/or shared by the Hospital with other hospitals for my diagnosis, therapy, follow-up and/or patient education, and may include patient medical records, medical images, interactive audio, video, and/or data communications, output data from medical devices, sound and video files etc. for betterment of patient care.", + "ar": + "وفقاً لسياسة المستشفى، سيتم السماح للمراقبين بمتابعة الإجراءات الطبية والجراحية وسيتم استخدامها لتعليم الموظفين الداخليين أو لأغراض التحسين والتطوير ويمكن إجراء المراقبة والتصوير الفوتوغرافي أو الإجراءات الطبية أو الجراحية بموافقة المستشفى ووفقاً لسياسة المستشفى والانظمة ذات العلاقة. أنا الموقع ادناه أتفهم انه قد يتم الكترونياً إرسال معلومات متعلقة بالتشخيص الطبي لي، العلاج المتابعة وتثقيف المريض، والتي قد تتضمن ملف المريض الطبي النتائج الإشعاعية، التسجيلات الصوتية والمرئية، وذلك بين المستشفى ومستشفيات أخرى بهدف تقديم رعاية صحية أفضل." + }, + "noGuaranteeConsent": {"en": "NO GUARENTEE OF THE RESULTS OF TREATMENT OR EXAMINATION: ", "ar": "لا ضمان لنتائج العلاج أو الفحوصات: "}, + "generalConsent11": { + "en": "I fully understand that no guarantee can be made to me as to the results of treatment or examinations done in the hospital during my hospitalization.", + "ar": "أنا الموقع أدناه أتفهم أنه لا يمكن ضمان نتائج العلاج أو الفحوصات أو الإجراءات التي قد تجرى لي خلال فترة وجودي بالمستشفى." + }, + "disputeConsent": {"en": "GOVERNING LAWS AND DISPUTE RESOLUTION: ", "ar": "النظام الحاكم وحل النزاعات: "}, + "generalConsent12": { + "en": + "This General Consent and Conditions of Admissions is governed by and shall be construed in accordance with the laws of the Kingdom of Saudi Arabia. Any dispute which arises during the execution of it, in which the parties have failed to resolve amicably, will be referred to the concerned judicial authorities in the city of Riyadh, Kingdom of Saudi Arabia.", + "ar": + "تخضع وتفسر هذه الموافقة العامة وشروط القبول للأنظمة المعمول بها في المملكة العربية السعودية. كل خلاف ينشأ عن تنفيذها ولا يتوصل إلى تسويته بين الطرفين وديا يحال إلى الجهة القضائية المختصة بالفصل في النزاع في مدينة الرياض، المملكة العربية السعودية." + }, + "patientsRightsConsent": {"en": "ACKNOWLEDGEMENT OF NOTICE OF PATIENT RIGHTS AND RESPONSIBILITIES: ", "ar": "الإقرار بحقوق ومسؤوليات المرضى: "}, + "generalConsent13": { + "en": + "I, the undersigned, acknowledge that I have been provided with a copy of the Patients' Bill of Right and Responsibilities and the admission staff has explained to me Patients' Bill of Right and Responsibilities.", + "ar": "أنا الموقع أدناه أقر بانه تم تزويدي بـ وثيقة حقوق ومسؤوليات المرضى وقام الموظف المختص بشرح وثيقة حقوق ومسؤوليات المرضى لي." + }, + "acknowledgementConsent": {"en": "ACKNOWLEDGEMENTS: ", "ar": "الإقرارات: "}, + "generalConsent14": { + "en": + "I, the undersigned, acknowledge that I have been provided with a copy of the Patients' Bill of Right and Responsibilities and the admission staff has explained to me Patients' Bill of Right and Responsibilities.", + "ar": + "لقد قرأت وفهمت وأوافق على الشروط والأحكام المبينة أعلاه وأوافق على الإلتزام بالمتطلبات المذكورة تجاه المستشفى ، لقد قرأت التفاصيل المبينة في نموذج التسجيل الخاص بي وأقر بأنها صحيحة. أنا الموقع ادناه أقر بأنه أتيحت لي الفرصة لطرح الأسئلة والتحفظات بشأن هذه الموافقة، وتلقيت إجابات مرضية على جميع إستفساراتي." + }, + "incorrectNationalId": {"en": "Incorrect National ID", "ar": "رقم الهوية غير صحيحة"}, + "labResultFlag": {"en": "Flag", "ar": "Flag"}, + "selectOccupation": {"en": "Select Occupation", "ar": "اختر المهنة"}, + "selectOccupationError": {"en": "Please select your occupation.", "ar": "الرجاء تحديد مهنتك."}, + + "whatIsOnlineCheckIn": {"en": "What is Online Check-In?", "ar": "ما هو تسجيل الوصول عبر الإنترنت؟"}, + "EROnlineCheckInDesc1": {"en": "Online check-in lets patients fill out forms, share insurance details, and book appointments online, making their visit smoother and quicker.", "ar": "يتيح تسجيل الوصول عبر الإنترنت للمرضى ملء النماذج ومشاركة تفاصيل التأمين وحجز المواعيد عبر الإنترنت، مما يجعل زيارتهم أكثر سلاسة وسرعة."}, + "EROnlineCheckInHow": {"en": "How can i use Online Check-In?", "ar": "كيف يمكنني استخدام تسجيل الوصول عبر الإنترنت؟"}, + "EROnlineCheckInTapOn": {"en": "Tap On", "ar": "اضغط على"}, + "EROnlineCheckInHoldPhone": {"en": "Hold your phone", "ar": "أمسك هاتفك"}, + "EROnlineCheckInWaitTurn": {"en": "Wait your turn", "ar": "انتظر دورك"}, + "EROnlineCheckInWaitTurnInstruction": {"en": "Please wait in the waiting area until called by the nurse.", "ar": "يرجى الانتظار في منطقة الانتظار حتى يتم استدعاؤك من قبل الممرضة."}, + "EROnlineCheckInHoldPhoneInstruction": {"en": "Hold the phone 1 to 2 cm from the NFC sign displayed on the board", "ar": "امسك الهاتف على مسافة 1 إلى 2 سم من علامة NFC المعروضة على اللوحة"}, + "EROnlineCheckInTapOnCheckIn": {"en": "Tap on the check-in button within the app", "ar": "اضغط على زر تسجيل الدخول داخل التطبيق"}, + "download": {"en": "Download", "ar": "تحميل"}, + "share": {"en": "Share", "ar": "يشارك"}, + "nearest": {"en": "Nearest", "ar": "الأقرب"}, + "selectRegion": {"en": "Select Region", "ar": "اختر المنطقة"}, + "selectFacitlity": {"en": "Select Facility", "ar": "اختر المنشأة"}, + "selectDoctor": {"en": "Select Doctor", "ar": "اختر الطبيب"}, + "hmgHospital": {"en": "Hospital", "ar": "المستشفيات "}, + "hmcHospital": {"en": "Medical Center", "ar": "المراكز الطبية"}, + "hmcHospitalCountSingle": { + "en": "@ Medical Center", + "ar": "المراكز الطبية @" + }, + "hmgHospitalCountSingle": {"en": "@ Hospital", "ar": "المستشفيات @"}, + "hmcHospitalCountPlural": { + "en": "@ Medical Centers", + "ar": "المراكز الطبية @" + }, + "hmgHospitalCountPlural": {"en": "@ Hospitals", "ar": "المستشفيات @"}, + + "termsHeading": {"en": "ONLINE SERVICES TERMS OF USE", "ar": "شروط استخدام الخدمات الالكترونية"}, + "termsConditions1": {"en": "These Online Services Terms of Use (Service Terms) govern certain online services provided by Dr Sulaiman Al Habib Medical Services Group Company (HMG, we, us, our) to the visitors and users of our websites and mobile app (you, your).", "ar": "تخضع الخدمات الالكترونية المحددة التي تقدمها شركة مجموعة الدكتور سليمان الحبيب للخدمات الطبية (المجموعة، نحن، والضمائر التي تشير إلينا) إلى زوار ومستخدمي مواقع الويب الخاصة بنا وتطبيقاتنا المحمولة (أنت، والضمائر التي تشير إليك) لشروط استخدام الخدمات الالكترونية (شروط الخدمة) هذه."}, + "termsConditions2": {"en": "By accessing our websites and/or mobile app, you agree to our Website Terms of Use and App User Agreement, as applicable (General Terms), which creates an agreement between you and us. When you accept these Service Terms they are incorporated into and become part of that same agreement. ", "ar": "بمجرد دخولك إلى مواقع الويب و/أو تطبيق الجوال الخاص بنا، فإنك توافق على شروط استخدام الموقع الإلكتروني الخاص بنا واتفاقية مستخدم التطبيق، حسب الاقتضاء (الشروط العامة)، والتي اتفاقاً بينك وبيننا. عندما تقبل شروط الخدمة هذه، فإنها تصبح مشمولة في وتشكل جزءا من نفس الاتفاقية."}, + "termsConditions3": {"en": "Please ensure you have read our Privacy Policy. Use of our online services may require you to provide us with personal information to create an account and may also require you to provide us with personal information, including information related to your health and wellbeing, to access specific services. If you purchase items from us and wish to bill charges to your insurance provider, we will need to provide personal information relating to you and your purchase to your insurance provider. By using our online services, you agree and consent to our use of your personal information in accordance with the Privacy Policy.", "ar": "يرجى التأكد من أنك قد قرأت سياسة الخصوصيةالخاصة بنا. قد يتطلب منك استخدام خدماتنا عبر الإنترنت أن تزودنا بالمعلومات الشخصية لإنشاء حساب قد تتطلب منك أيضاً تزويدنا بالمعلومات الشخصية بما في ذلك المعلومات المتعلقة بصحتك ورفاهيتك، للوصول إلى خدمات محددة. إذا قمت بشراء سلع منا وترغب منا في تقاضي قيمة الفاتورة من مزود التأمين الخاص بك، فسوف نحتاج إلى تقديم معلومات شخصية تتعلق بك وبمشترياتك لمزود التأمين الخاص بك. بمجرد استخدامك لخدماتنا الالكترونية، فإنك توافق على استخدامنا لمعلوماتك الشخصية وفقاً لسياسة الخصوصية."}, + "termsConditions4": {"en": "The Service Terms apply when you access services on our Sites, which require you to create a user account or log-in to your existing user account. You are required to indicate your acceptance of these Service Terms when creating your user account. If the Service Terms are updated by us, you will be required to confirm your agreement again, on your next log-in.", "ar": "تنطبق شروط الخدمة عند دخولك إلى الخدمات على مواقعنا التي تتطلب منك إنشاء حساب مستخدم أو تسجيل الدخول إلى حساب المستخدم الحالي. يتعين عليك الإشارة إلى قبولك لشروط الخدمة هذه عند إنشاء حساب المستخدم الخاص بك. إذا تم تحديث شروط الخدمة من قبلنا، فسيُطلب منك تأكيد موافقتك عليها مرة أخرى، عند تسجيل الدخول التالي الخاص بك."}, + "termsConditions5": {"en": "Telehealth and Online Pharmacy - Additional terms apply to our telehealth and online pharmacy services, and you will be required to agree to such terms before using those particular services.", "ar": "الرعاية الصحية عن بعد والصيدلية الإلكترونية – تنطبق شروط إضافية على خدماتنا المتعلقة بالرعاية الصحية عن بُعد والصيدلية الإلكترونية، ويتعين عليك الموافقة على هذه الشروط قبل استخدام هذه الخدمات."}, + "termsHeading2": {"en": "1. GENERAL TERMS", "ar": "1. أحكام عامة"}, + "termsConditions6": {"en": "The General Terms form part of this agreement, and all provisions of the General Terms apply to our online services.", "ar": "تشكل الشروط العامة جزءاً من هذه الاتفاقية وتُطبق جميع أحكام الشروط العامة على خدماتنا الإلكترونية عبر الإنترنت."}, + "termsHeading3": {"en": "2. APPOINTMENT BOOKING CONDITIONS", "ar": "2. شروط حجز الموعد"}, + "termsConditions7": {"en": "2.1 The Sites (all the websites defined in the General Terms, along with the mobile app) must not be used for speculative, false, or fraudulent appointment bookings. You warrant, represent and undertake that all information you provide about yourself and about anyone else is true and accurate when you are providing information to make an appointment.", "ar": "2-1 يتعين عليك ألا تستخدم المواقع (جميع مواقع الويب المحددة في الشروط العامة، إلى جانب تطبيق الجوال) لإجراء حجوزات غير مؤكدة أو خاطئة أو احتيالية. أنت تضمن وتقر وتتعهد بأن جميع المعلومات التي تقدمها عن نفسك وحول أي شخص آخر هي معلومات صحيحة ودقيقة عند تقديمك لمعلومات لحجز موعد."}, + "termsConditions8": {"en": "2.2 Appointment bookings can only be made through the Sites for selected HMG hospitals and clinics, to be determined at our sole discretion. ", "ar": "2-2 لا يمكن إجراء حجوزات المواعيد إلا من خلال مواقع مستشفيات وعيادات المجموعة المحددة، والتي نقوم بتحديدها وفقاً لتقديرنا الخاص."}, + "termsConditions9": {"en": "2.3 Once the appointment booking has been made through the Site, you will be required to confirm your appointment through the Sites, by phone, or in person at least twenty-four (24) hours prior to the appointment.", "ar": "2-3 بمجرد إجراء حجز المواعيد من خلال الموقع، سيُطلب منك تأكيد موعدك من خلال المواقع أو عن طريق الهاتف أو شخصياً قبل ما لا يقل عن أربعة وعشرين (24) ساعة من الموعد."}, + "termsConditions10": {"en": "2.4 For those HMG hospitals and clinics for which appointment bookings through the Sites are not permitted, you shall be required to book an appointment by phone or in person.", "ar": "2-4 بالنسبة لمستشفيات وعيادات المجموعة التي لا يسمح بحجز مواعيد فيها من خلال المواقع، يتعين عليك حجز موعد عبر الهاتف أو شخصياً. "}, + "termsConditions11": {"en": "2.5 You must register in accordance with the terms outlined in clause 7 to be able to make appointment bookings through the Sites.", "ar": "2-5 يتعين عليك التسجيل وفقاً للشروط المبينة في البند 7 لكي تتمكن من إجراء حجوزات المواعيد من خلال المواقع."}, + "termsConditions12": {"en": "2.6 In using the Sites, you will be entitled to:", "ar": "2-6 عند استخدامك للمواقع، فإنه يحق لك:"}, + "termsConditions12a": {"en": "a) book an appointment at an HMG hospital or clinic ", "ar": "(1) حجز موعد في إحدى مستشفيات أو عيادات المجوعة"}, + "termsConditions12b": {"en": "b) book one appointment at given time", "ar": "(2) حجز موعد في وقت معين"}, + "termsConditions12c": {"en": "c) book one appointment at given clinic. ", "ar": "(3) حجز موعد في عيادة معينة."}, + "termsConditions13": {"en": "To ensure there is no misunderstanding, In case that you won’t attend your confirmed appointment, you shall be required to cancel or reschedule appointment by phone or in person or through the Sites.", "ar": " تفادياً للشك، في حال عدم الرغبة في الحضور للموعد المؤكد، يتعين عليك إلغاء أو إعادة جدولة أي موعد مؤكد إما عن طريق الهاتف أو شخصياً أو من خلال المواقع."}, + "termsConditions14": {"en": "2.7 We reserve the right to disable your ability to book appointments through the Sites for a period, the duration of which is at sole discretion in the following circumstances: ", "ar": "2-7 نحن نحتفظ بالحق في تعطيل قدرتك على حجز المواعيد من خلال المواقع لفترة يتم تحديد مدتها وفقًا لتقديرنا الخاص، وذلك في الحالات التالية:"}, + "termsConditions14a": {"en": "a) you fail to attend appointments booked and confirmed through the Sites ", "ar": "(1) في حال أخفقت في حضور مواعيد تم حجزها وتأكيدها من خلال المواقع"}, + "termsConditions14b": {"en": "b) we determine at our sole discretion to do so for whatever reason. ", "ar": "(1) في حال أخفقت في حضور مواعيد تم حجزها وتأكيدها من خلال المواقع"}, + "termsHeading4": {"en": "3. ONLINE ENQUIRY CONDITIONS", "ar": "3. شروط الاستفسار عبر الإنترنت"}, + "termsConditions15": {"en": "3.1 You shall be entitled to communicate your enquiries to doctors through the Sites should you have visited an HMG hospital or clinic within the last 14 days. The enquiry must be submitted to the doctor with whom you had your appointment. For enquiries that are not directed towards doctors, you can submit them through the Sites without any time limitation.", "ar": "3-1 يحق لك إيصال استفساراتك إلى الأطباء من خلال المواقع في حال كان قد سبق لك أن قمت بزيارة أي مستشفى أو عيادة في المجموعة خلال الـ 14 يوما الماضية. يجب تقديم الاستفسار إلى الطبيب الذي كان لديك موعد معه. بالنسبة للاستفسارات التي لا يتم توجيهها إلى الأطباء، يمكنك إرسالها عبر المواقع دون أي قيود زمنية."}, + "termsConditions16": {"en": "3.2 In using the Sites, you shall only be entitled to:", "ar": "3-2 عند استخدامك للمواقع، فإنه لا يحق لك سوى:"}, + "termsConditions16a": {"en": "a) submit the enquiry to the doctor with whom you had your appointment within the last 14 days.", "ar": "(1) إرسال الاستفسار للطبيب الذي كان لديك موعد معه خلال الـ 14 يوما الماضية."}, + "termsConditions16b": {"en": "b) only make one doctor enquiry in any twenty-four (24) hour period.", "ar": "(2) إرسال استفسار واحد فقط للطبيب في أي فترة أربع وعشرين (24) ساعة."}, + "termsConditions17": {"en": "3.3 A response to enquiries made through the Sites is not guaranteed and is subject to doctor availability. Responses to enquiries will be subject to the doctor's sole discretion.", "ar": "3-3 عدم ضمان استجابة الاستفسارات المقدمة من خلال المواقع وهي عرضة لتوافر الطبيب. الردود على الاستفسارات سوف تخضع لتقدير الطبيب وحده ."}, + "termsConditions18": {"en": "3.4 Any response to enquiries made through the Sites which include details concerning, amongst other things, prescriptions, lab results, and radiology reports should not be considered as final and should be verified and stamped by the relevant medical office.", "ar": "3-4 أي رد على الاستفسارات المقدمة من خلال المواقع التي تشمل تفاصيل تتعلق، من بين الأشياء الأخرى، بالوصفات الطبية، نتائج المختبرات وتقارير الأشعة ينبغي عدم اعتبارها نهائية وينبغي التحقق منها وختمها من قبل المكتب الطبي المختص."}, + "termsConditions19": {"en": "3.5 We reserve the right to disable your ability to make enquiries through the Sites for a period, the duration of which is at sole discretion in the following circumstances:", "ar": "3-5 نحن نحتفظ بالحق في تعطيل قدرتك على إرسال الاستفسارات من خلال المواقع لأي فترة يتم تحديد مدتها وفقًا لتقديرنا الخاص في الحالات التالية:"}, + "termsConditions19a": {"en": "a) you fail to attend three (3) appointments booked and confirmed through the Sites. ", "ar": "(1) في حال أخفقت في حضور ثلاثة (3) مواعيد تم حجزها وتأكيدها من خلال المواقع. "}, + "termsConditions19b": {"en": "b) we determine at our sole discretion to do so for whatever reason.", "ar": "(2) في حال ارتأينا القيام بذلك وفقاً لتقديرنا المنفرد لأي سبب كان."}, + "termsHeading5": {"en": "4. PURCHASE CONDITIONS", "ar": "4. شروط الشراء"}, + "termsConditions20": {"en": "4.1 The Sites must not be used for speculative, false, or fraudulent purchases. You warrant, represent and undertake that all information you provide about yourself and about anyone else is true and accurate when you are making payments to the Sites. ", "ar": "4-1 يتعين عدم استخدام المواقع لإجراء مشتريات مضاربة أو خاطئة أو احتيالية. أنت تضمن وتقر وتتعهد بأن جميع المعلومات التي تقدمها عن نفسك وحول أي شخص آخر هي معلومات صحيحة ودقيقة عند سدادك لمدفوعات عبر المواقع."}, + "termsConditions21": {"en": "4.2 Services purchased through the Sites as a result of visits to the Sites made by you will be subject to the policy that applies to the particular services purchased by you (Policy). In the event of any discrepancy between these Terms of Use and the relevant Policy, the terms of the Policy will prevail, but only to the extent of the inconsistency. If there is a Policy for any particular service, it will be made clear to you before you access the service.", "ar": "4-2 الخدمات التي تم شراؤها من خلال المواقع نتيجة لزياراتك إلى المواقع، ستكون خاضعة للسياسة التي تنطبق على الخدمات المعينة التي تم شراؤها من جانبك (السياسة). في حالة وجود أي تباين بين شروط الاستخدام هذه والسياسة ذات الصلة، فإنه يُعتد بشروط السياسة، ولكن فقط في حدود ذلك التعارض . إذا كانت هناك سياسة محددة لأي خدمة معينة، فسيتم توضيحها لك قبل دخولك إلى الخدمة."}, + "termsHeading6": {"en": "5. PRICING AND AVAILABILITY", "ar": "5. التسعير والتوافر"}, + "termsConditions22": {"en": "5.1 Unless otherwise expressly stated, all prices on the Sites are exclusive of all applicable taxes and surcharges. All prices are expressed to be in Saudi riyals, as indicated on the Sites. We may also accept payment in US dollars, if indicated.", "ar": "5-1 ما لم يرد نص على خلاف ذلك صراحةً، فإن جميع الأسعار على المواقع لا تشمل أياً من الضرائب والرسوم الإضافية المعمول بها. جميع الأسعار معبر عنها بالريال السعودي، كما هو موضح في المواقع. قد نقبل أيضاً الدفع بالدولار الأمريكي، إذا تم بيان ذلك."}, + "termsConditions23": {"en": "5.2 Prices and availability stated on the Sites are subject to change at any time until your online purchase has been confirmed and your payment has been processed. While we will endeavour to ensure that the information on the Sites is as accurate and as up to date as possible, we do not provide a warranty to that effect. You acknowledge that we have no responsibility for the accuracy, completeness, currency or timeliness of price and availability information that is made available on the Sites.", "ar": "5-2 الأسعار ومدى التوافر الموضح على المواقع عرضة للتغيير في أي وقت حتى يتم تأكيد الشراء عبر الإنترنت ومعالجة مدفوعاتك بنجاح. رغم أننا سنسعى للتأكد من أن المعلومات الموجودة على المواقع دقيقة ومحدثة قدر الإمكان، إلا أننا لا نقدم أي ضمان بهذا الخصوص. أنت تقر بأننا لا نتحمل أي مسؤولية عن دقة معلومات السعر ومدى التوافر المبين على المواقع أو مدى اكتمالها أو حداثتها أو إتاحتها في الوقت المناسب."}, + "termsConditions24": {"en": "5.3 Special offers may be advertised on the Sites at any time. Special offers are not applicable to any transactions that have already been confirmed.", "ar": "5-3 قد يتم الإعلان عن عروض خاصة على المواقع في أي وقت. لا تنطبق العروض الخاصة على أي معاملات سبق أن تم تأكيدها بالفعل."}, + "termsHeading7": {"en": "6. PAYMENTS", "ar": "6. سداد المدفوعات"}, + "termsConditions25": {"en": "6.1 We may accept the following methods of payment: ", "ar": "6-1 يجوز لنا قبول طرق السداد التالية:"}, + "termsConditions25a": {"en": "a) direct debit bank transfers in accordance with the provisions of clause 6.2 below: ", "ar": "(1) تحويلات بنكية بالخصم المباشر وفقاً لأحكام البند 6-2 أدناه: "}, + "termsConditions25b": {"en": "b) credit card payments in accordance with the provisions of clauses 6.3, 6.4 and 6.5 below: ", "ar": "(2) مدفوعات بطاقات الائتمان وفقاً لبنود 6-3 و 6-4 و 6-5 أدناه: "}, + "termsConditions25c": {"en": "c) direct billing to medical insurance providers in accordance with the provisions of clause 6.6 below. ", "ar": "(3) الفواتير المباشرة لمزودي خدمات التأمين الطبي وفقاً لأحكام البند 6-6 أدناه."}, + "termsConditions26": {"en": "6.2 All payments made by direct debit bank transfer should be made to respective bank account that will be shown along with your purchasing activity.", "ar": "6-2 يجب أن يتم سداد جميع المدفوعات التي تتم عن طريق التحويل المصرفي بالخصم المباشر إلى الحساب المصرفي المعني الذي سيتم بيانه جنباً إلى جنب مع عملية الشراء التي تخصك."}, + "termsConditions27": {"en": "6.3 We accept all major international credit and debit cards (each a Card). Your Card will be debited when you click the 'confirm payment' button. ", "ar": "6-3 نقبل جميع بطاقات الائتمان والخصم الدولية الرئيسية (ويُشار إلى كل منها بلفظ بطاقة). سيتم الخصم من بطاقتك عندما تنقر على زر 'تأكيد الدفع'."}, + "termsConditions28": {"en": "6.3 We accept all major international credit and debit cards (each a Card). Your Card will be debited when you click the 'confirm payment' button. ", "ar": "6-3 نقبل جميع بطاقات الائتمان والخصم الدولية الرئيسية (ويُشار إلى كل منها بلفظ بطاقة). سيتم الخصم من بطاقتك عندما تنقر على زر 'تأكيد الدفع'."}, + "termsConditions29": {"en": "6.4 Please supply us with the correct c card billing and cardholder information (Payment Information). If you do not supply the correct Payment Information, purchases made through the Sites may be delayed. We reserve the right to cancel purchases made through the Sites if payment is declined or if you have supplied incorrect Payment Information.", "ar": "6-4 يرجى تزويدنا بفاتورة البطاقة الصحيحة ومعلومات حامل البطاقة (معلومات الدفع). إذا لم تقدم معلومات الدفع الصحيحة، فقد تتأخر عمليات الشراء التي تتم عبر المواقع. نحتفظ بالحق في إلغاء المشتريات التي تتم عبر المواقع إذا تم رفض الدفع أو إذا قدمت معلومات دفع غير صحيحة."}, + "termsConditions30": {"en": "6.5 We may incur charges when a booking is made through the Sites using a Card. We reserve the right to pass on to you, in full, any changes incurred by us in connection with any purchase made through the Sites by you using a Card. We will let you know of any applicable charges prior to you clicking the 'confirm payment' button.", "ar": "6-5 قد نتحمل رسوماً عند إجراء الحجز عبر المواقع باستخدام البطاقة. نحتفظ بالحق في أن نتقاضى منك، بالكامل، أي تغييرات نُطالب بدفعها فيما يتعلق بأي عملية شراء يتم إجراؤها عبر المواقع بواسطتك باستخدام البطاقة. سنخبرك بأي رسوم مطبقة قبل النقر فوق زر 'تأكيد الدفع'."}, + "termsConditions31": {"en": "6.6 If our Site provides the option for you to submit insurance provider details for the purposes of direct billing then you may do so. We may provide the ability for you to store insurance details on your account profile. You are responsible for ensuring all insurance details provided are valid and up to date. You represent and warrant to us that any insurance details you provide will relate to a valid medical insurance policy which covers treatment in the country from which you are making your purchase. You acknowledge that we will need to provide details to your insurer of your purchase, and you hereby consent to us doing so. Before we confirm an order, we will need to verify that your insurer accepts payment for the order. If the insurer declines payment or you are required to pay part or all of the order price, we will contact you and the order will not progress until you have paid the remainder of the total amount due. Aside from seeking approval of costs in accordance with the information you provide with your order, we cannot act as an intermediary for communications between you and your insurer and we accept no liability whatsoever for any delay, act or omission of your insurer. If you are unhappy with your insurer’s treatment of your claim you must contact your insurer or the appropriate supervisory authority directly. ", "ar": "6-6 إذا كان موقعنا يوفر لك خيار إرسال تفاصيل مزود التأمين لأغراض الفوترة المباشرة، فيمكنك القيام بذلك. قد نوفر لك القدرة على تخزين تفاصيل التأمين في ملف تعريف حسابك. أنت مسؤول عن التأكد من أن جميع تفاصيل التأمين المقدمة صحيحة ومحدثة. أنت تقر وتضمن لنا أن أي تفاصيل تأمين تقدمها سوف تتعلق بوثيقة تأمين طبي سارية المفعول تغطي العلاج في البلد الذي تقوم بالشراء منه. أنت تقر بأننا سنحتاج إلى تقديم تفاصيل إلى شركة التأمين الخاصة بك عن مشترياتك وأنت توافق بموجبه على قيامنا بذلك. قبل تأكيد طلب الشراء، سنحتاج إلى التحقق من أن شركة التأمين توافق على سداد قيمة طلب الشراء. إذا رفضت شركة التأمين سداد ذلك أو طُلب منك سداد جزء من قيمة الطلبية أو جميعها، فسنقوم بالاتصال بك ولن يتم تنفيذ طلب الشراء حتى تقوم بسداد باقي المبلغ الإجمالي المستحق. بصرف النظر عن السعي للحصول على الموافقة على التكاليف وفقاً للمعلومات التي تقدمها مع طلبك، لا يمكننا العمل كوسيط للاتصالات بينك وبين شركة التأمين الخاصة بك ولا نتحمل أي مسؤولية من أي نوع عن أي تأخير أو فعل أو إغفال من جانب شركة التأمين الخاصة بك. إذا لم تكن راضيًا عن كيفية معاملة شركة التأمين الخاصة بك لطلبك، فيجب عليك الاتصال بشركة التأمين أو السلطة الإشرافية المناسبة بشكل مباشر."}, + "termsConditions32": {"en": "6.7 We may outsource payment processing to a third party provider. We will not be liable to you or anyone else for any loss resulting from an act or omission of a third party payment provider.", "ar": "6-7 يجوز لنا تعهيد مسألة معالجة المدفوعات لمزود خارجي. لن نتحمل أي مسؤولية تجاهك أو تجاه أي شخص آخر عن أي خسارة ناتجة عن أي فعل أو إغفال من قبل مزود خارجي لخدمات المدفوعات."}, + "termsHeading8": {"en": "7. ACCOUNT RULES ", "ar": "7. قواعد الحساب"}, + "termsConditions33": {"en": "7.1 In order to access certain services, you will need to: ", "ar": "7-1 من أجل الدخول إلى خدمات معينة، سوف تحتاج إلى:"}, + "termsConditions33a": {"en": "(a) enter your credentials (registered National ID and mobile number). ", "ar": "(1) إدخال بيانات الاعتماد الخاصة بك (رقم الهوية الوطنية المسجل ورقم الجوال )"}, + "termsConditions33b": {"en": "(b) enter the onetime secure-access code that you will receive to your registered mobile number. ", "ar": "(2) إدخال رمز الدخول الآمن لمرة واحدة الذي ستتلقاه على رقم هاتفك الجوال المسجل."}, + "termsConditions34": {"en": "7.2 In order to create an account to obtain full access to the services on the Sites, you must: ", "ar": "7-2 لإنشاء حساب والحصول على حق الوصول الكامل إلى الخدمات على المواقع، يتعين عليك:"}, + "termsConditions34a": {"en": "(a) satisfy the minimum age requirement of 18 years (measured according to the Gregorian calendar); ", "ar": "(1) استيفاء شرط الحد الأدنى للسن وهو 18 سنة (يُقاس بالتقويم الميلادي)؛"}, + "termsConditions34b": {"en": "(b) provide us with complete and accurate registration information in accordance with requested information fields on the Site;", "ar": "(2) تزويدنا بمعلومات تسجيل كاملة ودقيقة وفقاً لحقول المعلومات المطلوبة على الموقع؛"}, + "termsConditions34c": {"en": "(c) ensure your use of the Sites is in accordance with these Online Services Terms of Use and any applicable laws;", "ar": "(3) التأكد من أن استخدامك للمواقع يتوافق مع شروط استخدام الخدمات الالكترونية هذه وأي أنظمة معمول بها؛"}, + "termsConditions34d": {"en": "(d) enter your national ID card number; ", "ar": "(4)إدخال رقم بطاقة الهوية الوطنية الخاصة بك؛ و"}, + "termsConditions34e": {"en": "(e) enter your mobile telephone number to receive a confidential secure-access code via SMS. ", "ar": "(5) إدخال رقم هاتفك الجوال لتلقي رمز دخول آمن سري عبر رسالة نصية قصيرة."}, + "termsConditions35": {"en": "7.3 When you create an account, and any time you attempt to access our on-line services, you warrant, represent and undertake that: ", "ar": "7-3 عندما تنشئ حساباً، وفي أي وقت تحاول فيه الدخول إلى خدماتنا الالكترونية عبر الإنترنت، فإنك تضمن وتقر وتتعهد بما يلي:"}, + "termsConditions35a": {"en": "(a) you meet the minimum age requirement ", "ar": "(1)أنك تستوفي الحد الأدنى من متطلبات العمر"}, + "termsConditions35b": {"en": "(b) you have given complete and accurate registration information, and will keep that information updated; ", "ar": "(2) أنك قدمت معلومات تسجيل كاملة ودقيقة، وأنك ستقوم بتحديث هذه المعلومات "}, + "termsConditions35c": {"en": "(c) you are resident in the Kingdom of Saudi Arabia. ", "ar": "(3) أنك مقيم في المملكة العربية السعودية؛"}, + "termsConditions35d": {"en": "(d) you have authorised us to execute all instructions and transactions on your behalf in relation to your use of the Sites; ", "ar": "(4) أنك قد فوضتنا بتنفيذ جميع التعليمات والمعاملات نيابة عنك فيما يتعلق باستخدامك للمواقع"}, + "termsConditions35e": {"en": "(e) your use of the Sites will not violate these Online Services Terms of Use or breach any applicable laws. ", "ar": "(5) أن استخدامك للمواقع لا ينتهك شروط استخدام الخدمات الالكترونية هذه ولا ينتهك أي أنظمة معمول بها. "}, + "termsConditions36": {"en": "7.4 We reserve the right to reject or revoke, for whatever reason and at our sole discretion, your request to access the Sites or to freeze access to the Sites.", "ar": "7-4 نحتفظ بالحق في رفض أو إلغاء طلبك للدخول إلى المواقع أو تجميد إمكانية الوصول إلى إلى المواقع، لأي سبب من الأسباب ووفقاً لتقديرنا الخاص ."}, + "termsConditions37": {"en": "7.5 In order to use the Sites, you will require access to the Internet. You are responsible for any connection, service and other fees associated with such access and for providing all equipment necessary to enable you to connect to the Internet (including a computer and modem or other access device).", "ar": "7-5 من أجل استخدام المواقع، سوف تحتاج إلى الاتصال بالإنترنت. أنت مسؤول عن أي رسوم اتصال أو رسوم خدمة أو أي رسوم أخرى مرتبطة بهذا الدخول وعن توفير جميع المعدات اللازمة لتمكينك من الاتصال بالإنترنت (بما في ذلك الكمبيوتر والمودم أو أي جهاز اتصال آخر)."}, + "termsConditions38": {"en": "7.6 We may use information from your profile for aggregated analysis purposes (such as your age, gender, nationality etc.) to enable us to gain insights into who is using our online services and how we may improve the reach and quality of the services. We will not use any information which can personally identify you, including any information which links you to any medical procedure or health status, for any such purpose. Please see our Privacy Policy for more information about how we use your information.", "ar": "7-6 قد نستخدم معلومات من ملفك الشخصي لأغراض التحليل المجمع (مثل عمرك وجنسك وجنسيتك وما إلى ذلك) لتمكيننا من اكتساب نظرة عامة بشأن من يستخدم خدماتنا الإلكترونية عبر الإنترنت وكيف يمكننا تحسين الدخول إلى الخدمات وجودتها. لن نستخدم أي معلومات يمكن أن تحدد هويتك، بما في ذلك أي معلومات تربطك بأي إجراء طبي أو حالة صحية لأي غرض من هذا القبيل. يرجى الاطلاع على سياسة الخصوصية الخاصة بنا للحصول على مزيد من المعلومات حول كيفية استخدامنا لمعلوماتك."}, + "termsConditions39": {"en": "7.7 You may create an account on behalf of a child for whom you have legal responsibility. If you create an account on behalf of a child you warrant, represent and undertake that:", "ar": "7-7 يمكنك إنشاء حساب نيابة عن طفل ما تكون مسؤولاً عنه بموجب النظام. إذا أنشأت حساباً نيابةً عن أي طفل، فإنك تضمن وتقر وتتعهد بما يلي:"}, + "termsConditions39a": {"en": "(a) you are a parent or legal guardian of that child and are lawfully authorised to direct the medical care of the child and to provide us will all necessary information in connection with the child (such as identification documents, medical history etc.)", "ar": "(1)أنك أحد الوالدين أو الوصي الشرعي لذلك الطفل ومصرح لك نظاماً بتوجيه الرعاية الطبية للطفل وتزويدنا بجميع المعلومات اللازمة فيما يتعلق بالطفل (مثل وثائق الهوية والتاريخ الطبي وما إلى ذلك)"}, + "termsConditions39b": {"en": "(b) you have authorised us to execute all instructions and transactions on behalf of the child in relation to your use of the Sites;", "ar": "(2) أنك قد فوضتنا بتنفيذ جميع التعليمات والمعاملات نيابة عن الطفل فيما يتعلق باستخدامك للمواقع"}, + "termsConditions39c": {"en": "(c) without prejudice to any patient/doctor confidentiality obligations that may occur if the child independently seeks medical advice, you will supervise and direct all use of the child’s account on the Site and will not permit the child to use the account without supervision;", "ar": "(3) دون الإخلال بأي التزامات سرية بين المريض / الطبيب قد تحدث إذا طلب الطفل مشورة طبية بشكل مستقل، فسوف تشرف وتوجه كافة استخدامات حساب الطفل على الموقع ولن تسمح للطفل باستخدام الحساب دون إشراف؛ و"}, + "termsConditions39d": {"en": "(d) you will remain responsible for all charges incurred in connection with the account.", "ar": "(4) ستظل مسؤولاً عن جميع الرسوم المستحقة فيما يتعلق بالحساب."}, + "termsHeading9": {"en": "8.PASSWORD SECURITY AND NOTIFICATION", "ar": "8. أمن كلمة المرور والإشعار"}, + "termsConditions40": {"en": "8.1 You are solely responsible for all activities that occur in connection with your log-in details in respect of the Sites. You must take steps to protect the confidentiality of your log-in details and you must not allow any other person to use your account.", "ar": "8-1 أنت وحدك المسؤول عن جميع الأنشطة التي تحدث فيما يتعلق بتفاصيل تسجيل الدخول الخاصة بك بخصوص المواقع. يتعين عليك اتخاذ خطوات لحماية سرية بيانات تسجيل الدخول الخاصة بك ويجب ألا تسمح لأي شخص آخر باستخدام حسابك."}, + "termsConditions41": {"en": "8.2 You must notify us immediately if you become aware of any disclosure, loss, theft or unauthorised use of your log-In details.", "ar": "8-2 يتعين عليك إخطارنا على الفور إذا علمت بأي إفشاء أو ضياع أو سرقة أو استخدام غير مصرح به لبيانات تسجيل الدخول الخاصة بك."}, + "termsHeading10": {"en": "9.TERMINATION", "ar": "9. الإنهاء"}, + "termsConditions42": {"en": "9.1 We may discontinue any service at any time or terminate your access to one or more services at any time for any reason, with or without notice to you and without incurring any liability to you, however that liability may arise.", "ar": "9-1 يجوز لنا التوقف عن توفير أي خدمة أو أنهاء حقك في الدخول إلى أي خدمة أو أكثر في أي وقت ولأي سبب سواء بموجب إخطار نرسله لك أو بدونه ودون أنت نتحمل أي مسؤولية تجاهك، بغض النظر عن كيفية نشوء تلك المسؤولية."}, + "termsConditions43": {"en": "9.2 All restrictions and all disclaimers and exclusions and limitations of our liability will survive any termination. Upon termination, you must not directly or indirectly access or use the services.", "ar": "9-2 ستظل جميع القيود وجميع إخلاءات الطرف من المسؤولية والاستثناءات والقيود الخاصة بمسؤوليتنا سارية بعد أي إنهاء. عند الإنهاء، يتعين عليك عدم الدخول إلى الخدمات سواء بشكل مباشر أو غير مباشر."}, + "termsHeading11": {"en": "10. INDEMNITY", "ar": "10. ضمان التعويض"}, + "termsConditions44": {"en": "You indemnify us in full in respect of any liability incurred by us or suffered by us for any loss, cost, damage or expense, as a result of your breach of these Online Services Terms of Use. Where you use our services inappropriately or maliciously, you agree that you will indemnify us against any losses suffered by us or any third parties as a result of or in connection with such use.", "ar": "أنت تلتزم بضمان تعويضنا بشكل الكامل فيما يتعلق بأي مسؤولية تترتب علينا أو نتحملها عن أي خسارة أو تكلفة أو ضرر أو مصاريف، نتيجة لإخلالك بشروط استخدام الخدمات الالكترونية هذه. عندما تستخدم خدماتنا بشكل غير مناسب أو ضار، فإنك توافق على أنك ستعوضنا عن أي خسائر نتكبدها نحن أو أي طرف ثالث نتيجة هذا الاستخدام أو فيما يتعلق به."}, + "termsHeading12": {"en": "11. GENERAL", "ar": "11. أحكام عامة"}, + "termsConditions45": {"en": "As noted above, these Online Services Terms of Use are subject to the General Terms and form part of the same agreement. You should ensure you have read the General Terms. In particular, please note the following sections, as they relate to the online services, Website Terms of Use: 2) No Warranties; 3) Submission of Content; 12) Limitation of Liability; 13) Indemnity; 14) Availability of the Site; 15) Privacy; 18) General. App User Agreement: 1.4) use of location data.", "ar": "11-1 كما هو مذكور أعلاه، تخضع شروط استخدام الخدمات الالكترونية هذه للشروط العامة وتشكل جزءاً من نفس الاتفاقية. يتعين عليك الحرص على قراءة الشروط العامة بتمعن. على وجه الخصوص، يرجى التمعن في الأقسام التالية، من حيث صلتها بالخدمات الالكترونية, شروط استخدام الموقع الإلكتروني: 2) انعدام الضمانات؛ 3) تقديم المحتوى؛ 12) حدود المسؤولية؛ 13) ضمان التعويض؛ 14) توافر الموقع؛ 15) الخصوصية؛ 18) أحكام عامة. اتفاقية مستخدم التطبيق: 1-4) استخدام بيانات تحديد المواقع."}, + "termsConditionsRead": {"en": "I have read these Online Services Terms of Use and all other terms and conditions referred to in them. I understand that by ticking this box and proceeding to use the services I will be bound by these Terms & Conditions and that they govern the services to be provided to me. I consent to the receipt of the online services and the use of my personal information, including sensitive personal information, for the purposes set out above and in accordance with the Privacy Policy.", "ar": "لقد قرأت شروط وأحكام الخدمات الالكترونية عبر الانترنت هذه وجميع البنود والشروط الأخرى المشار إليها فيها. أدرك أنه بمجرد وضع إشارة صح في هذا المربع والاستمرار في استخدام الخدمات، سأكون ملزماً بهذه الشروط والأحكام وأنها تحكم الخدمات التي سيتم تقديمها لي. أوافق على تلقي الخدمات الالكترونية عبر الانترنت واستخدام معلوماتي الشخصية، بما في ذلك المعلومات الشخصية الحساسة، للأغراض الموضحة أعلاه ووفقاً لسياسة الخصوصية."}, + "liveCareTermsHeading": {"en": "TELEHEALTH SERVICES TERMS OF USE", "ar": "شروط خدمات الرعاية الصحية عن بُعد"}, + "liveCareTermsIntroHeading": {"en": "INTRODUCTION", "ar": "مقدمة"}, + "liveCareTermsConditions1": {"en": "Dr. Sulaiman Al Habib Medical Services Group Company (the “Group”) is one of the leaders in the healthcare sector in the Kingdom of Saudi Arabia with an aim to always improve its services in the region, and as a step to take our services to another level and to facilitate the process of receiving healthcare services we have adopted the approach of providing some of our services remotely to patients. These terms apply to our Telehealth Services, which enable consultations to occur between a doctor and a patient over the internet, using audio or and video conferencing technology (often referred to as “Telehealth Services”).", "ar": "تعتبر شركة مجموعة الدكتور سليمان الحبيب للخدمات الطبية ('المجموعة') واحدة من الشركات الرائدة في قطاع الرعاية الصحية في المملكة العربية السعودية والتي تسعى دائمًا لتحسين خدماتها في المنطقة، وكخطوة لنقل خدماتنا إلى مستوى آخر ولتسهيل عملية تلقي خدمات الرعاية الصحية، فقد اعتمدنا نهج تقديم بعض خدماتنا عن بُعد للمرضى. تنطبق هذه الشروط على خدمات الرعاية الصحية عن بُعد التي نقدمها، والتي تتيح إجراء الاستشارات بين الطبيب والمريض عبر الإنترنت، باستخدام تقنية الاتصالات الصوتية أو المرئية (يشار إليها غالباً باسم 'خدمات الرعاية الصحية عن بُعد')."}, + "liveCareTermsConditions2": {"en": "The purpose of the Telehealth Services is to facilitate communication between healthcare practitioners and patients to provide healthcare services through advanced electronic communication means, which allows healthcare professionals to evaluate, diagnose, treat and follow-up with patients remotely without the need for patients to attend in person.).", "ar": "الغرض من خدمات الرعاية الصحية عن بعد هو تسهيل الاتصالات بين الممارسين الصحيين والمرضى لتقديم خدمات الرعاية الصحية من خلال وسائل الاتصال الإلكترونية المتقدمة، والتي تتيح للممارسين الصحيين تقييم وتشخيص وعلاج ومتابعة المرضى عن بُعد دون الحاجة إلى حضور المرضى شخصياً."}, + "liveCareTermsHeading2": {"en": "AGREEMENT", "ar": "الاتفاقية"}, + "liveCareTermsConditions3": {"en": "Telehealth Services is delivered over the Group’s mobile application or and Website. The following terms apply to the Telehealth Services: ", "ar": "يتم تقديم خدمات الرعاية الصحية عن بُعد عبر تطبيق الهاتف المحمول أو الموقع الإلكتروني للمجموعة. تنطبق الشروط التالية على خدمات الرعاية الصحية عن بُعد: "}, + "liveCareTermsConditions3a": {"en": " - Website Terms of Use", "ar": "شروط استخدام الموقع الالكتروني - "}, + "liveCareTermsConditions3b": {"en": " - App User Agreement", "ar": "تفاقية مستخدم التطبيق - "}, + "liveCareTermsConditions3c": {"en": " - Online Services Terms of Use", "ar": "روط استخدام الخدمات الإلكترونية - "}, + "liveCareTermsConditions3d": {"en": " - These Telehealth Services User Terms of Use", "ar": "شروط خدمات الرعاية الصحية عن بُعد هذه - "}, + "liveCareTermsConditions4": {"en": "By agreeing to proceed with the Telehealth Services and accepting these terms, you enter into an agreement with The Group incorporating all the above terms (Telehealth Services Agreement).", "ar": "بالموافقة على الاستمرار في خدمات الرعاية الصحية عن بُعد وقبول هذه الشروط، فإنك تدخل في اتفاقية مع المجموعة تتضمن جميع الشروط المذكورة أعلاه (اتفاقية خدمات الرعاية الصحية عن بُعد)."}, + "liveCareTermsConditions5": {"en": "Our Privacy Policy should also be read. It contains details about how we use your personal information and your rights. By proceeding with the Telehealth Services, you agree to our use of your personal information in accordance with our Privacy Policy and you expressly consent to our use of your personal information for the performance of the Telehealth Services and the discharge of our professional duties as a medical care provider.", "ar": "يتعين عليك أيضاً قراءة سياسة الخصوصية الخاصة بنا حيث تحتوي سياسة الخصوصية على تفاصيل حول كيفية استخدامنا لمعلوماتك الشخصية وحقوقك بشأنها. من خلال متابعة استخدام خدمات الرعاية الصحية عن بُعد، فإنك توافق على استخدامنا لمعلوماتك الشخصية وفقاً لسياسة الخصوصية الخاصة بنا وتوافق صراحةً على استخدامنا لمعلوماتك الشخصية لأداء خدمات الرعاية الصحية عن بُعد وأداء واجباتنا المهنية كمقدم لخدمات الرعاية الطبية."}, + "liveCareTermsConditions6": {"en": "Our Privacy Policy should also be read. It contains details about how we use your personal information and your rights. By proceeding with the Telehealth Services, you agree to our use of your personal information in accordance with our Privacy Policy and you expressly consent to our use of your personal information for the performance of the Telehealth Services and the discharge of our professional duties as a medical care provider.", "ar": "يتعين عليك أيضاً قراءة سياسة الخصوصية الخاصة بنا حيث تحتوي سياسة الخصوصية على تفاصيل حول كيفية استخدامنا لمعلوماتك الشخصية وحقوقك بشأنها. من خلال متابعة استخدام خدمات الرعاية الصحية عن بُعد، فإنك توافق على استخدامنا لمعلوماتك الشخصية وفقاً لسياسة الخصوصية الخاصة بنا وتوافق صراحةً على استخدامنا لمعلوماتك الشخصية لأداء خدمات الرعاية الصحية عن بُعد وأداء واجباتنا المهنية كمقدم لخدمات الرعاية الطبية."}, + "liveCareTermsHeading3": {"en": "1. DEFINITIONS", "ar": "1. التعاريف"}, + "liveCareTermsConditions7": {"en": "Group means Dr. Sulaiman Al Habib Medical Services Group Company and its subsidiaries. ", "ar": "المجموعة تعني شركة مجموعة الدكتور سليمان الحبيب للخدمات الطبية والشركات التابعة لها."}, + "liveCareTermsConditions8": {"en": "Telehealth Services means the Group’s telehealth service, enabling remote consultation, diagnosis and follow-up between the patient and doctor, using the Application and or the Website.", "ar": "خدمات الرعاية الصحية عن بُعد تعني خدمة الرعاية الصحية عن بُعد التي تقدمها المجموعة، والتي تتيح الاستشارة والتشخيص والمتابعة عن بُعد بين المريض والطبيب، باستخدام التطبيق و/أو موقع الويب."}, + "liveCareTermsConditions9": {"en": "Our Services means certain services provided by the Group which covers viewing patients’ medical records and medical test results, providing medical diagnostics in addition to the availability of voice and video Telehealth Service between healthcare practitioners and patients.", "ar": "خدماتنا تعني بعض الخدمات التي تقدمها المجموعة والتي تغطي استعراض السجلات الطبية للمرضى ونتائج الفحوصات الطبية، وتوفير التشخيصات الطبية بالإضافة إلى توفر خدمة الرعاية الصحية عن بعد بالصوت والفيديو بين ممارسي الرعاية الصحية والمرضى."}, + "liveCareTermsConditions10": {"en": "Application means Dr. ALHABIB Application which is a platform where Our Services are provided through and accessible by users. ", "ar": "التطبيق يعني تطبيق (Dr. ALHABIB) وهو عبارة عن منصة يتم من خلالها تقديم خدماتنا ويمكن للمستخدمين الولوج إليها."}, + "liveCareTermsConditions11": {"en": "Website means the Group internet website which is a platform where Our Services are provided through and accessible by users. ", "ar": "موقع الويب يعني موقع الويب الخاص بالمجموعة وهو عبارة عن منصة يتم من خلالها تقديم خدماتنا ويمكن للمستخدمين الدخول إليها."}, + "liveCareTermsConditions12": {"en": "Terms & Conditions means these Telehealth Services Terms of Use. ", "ar": "الشروط والأحكام تعني شروط خدمات الرعاية الصحية عن بُعد هذه."}, + "liveCareTermsConditions13": {"en": "Content means any message, data, information, text, sound, photos, video, graphics, code or any other material contained on the Application and or the Website or transmitted via the Application and or the Website. ", "ar": "المحتوى يعني أي رسالة أو بيانات أو معلومات أو نص أو صوت أو صور أو فيديو أو رسومات أو رمز أو أي مادة أخرى واردة في التطبيق أو موقع الويب أو يتم نقلها عبر التطبيق أو موقع الويب."}, + "liveCareTermsHeading4": {"en": "2. USER UNDERTAKINGS", "ar": "2. تعهدات المستخدم"}, + "liveCareTermsConditions14": {"en": "2.1 By accessing and using Telehealth Services, you agree to these Terms & Conditions, and you should not attempt to access Our Services if you do not agree. ", "ar": "2-1 من خلال دخولك إلى خدمات الرعاية الصحية عن بُعد واستخدامها، فإنك توافق على هذه الشروط والأحكام ويتعين عليك ألا تحاول الدخول إلى خدماتنا إذا كنت لا توافق عليها."}, + "liveCareTermsConditions15": {"en": "2.2 You warrant, represent and undertake that all information you provide about yourself and about anyone else is true and accurate. ", "ar": "2-2 أنت تضمن وتقر وتتعهد بأن جميع المعلومات التي تقدمها عن نفسك وعن أي شخص آخر صحيحة ودقيقة."}, + "liveCareTermsConditions16": {"en": "2.3 Telehealth Services is intended for use by patients physically located in the Kingdom Saudi Arabia (Permitted Territory) and should not be used by patients outside the Permitted Territory. By agreeing to these Terms & Conditions and accessing Telehealth Services via the Application and or the Website, you represent and warrant to us that you are physically located in one of the Permitted Territory. ", "ar": "2-3 خدمات الرعاية الصحية عن بعد مخصصة للاستخدام من قبل المرضى الموجودين فعلياً في المملكة العربية السعودية (المنطقة المسموح بها) ولا ينبغي استخدامها من قبل المرضى خارج المنطقة المسموح بها. بالموافقة على هذه الشروط والأحكام والدخول إلى خدمات الرعاية الصحية عن بُعد عبر التطبيق أو موقع الويب، فإنك تقر وتضمن لنا أنك موجود فعلياً في إحدى المناطق المسموح بها."}, + "liveCareTermsHeading5": {"en": "3. LIMITATIONS OF TELEHEALTH SERVICES AND ASSOCIATED RISKS", "ar": "3. القيود على خدمات الرعاية الصحية عن بعد والمخاطر المرتبطة بها"}, + "liveCareTermsConditions17": {"en": "3.1 Do not use the Application and or the Website or the Telehealth Services to communicate or treat medical emergencies. Neither the Application nor the Website nor Telehealth Services are intended for the provision of care in an emergency. IF THERE IS AN URGENT MEDICAL EMERGENCY OR A RESPONSE IS NEEDED QUICKLY REGARDING YOUR HEALTH, GO TO A NEARBY EMERGENCY CENTER/HOSPITAL OR CALL IMMEDIATELY ANY EMERGENCY PHONE NUMBER. ", "ar": "3-1 لا تستخدم التطبيق أو موقع الويب أو خدمات الرعاية الصحية عن بُعد للتواصل بشأن الحالات الطبية الطارئة أو علاجها. لا التطبيق ولا موقع الويب ولا خدمات الرعاية الصحية عن بُعد توفر الرعاية في الحالات الطبية الطارئة. إذا كانت هناك حالة طبية طارئة عاجلة أو كانت هناك حاجة إلى استجابة سريعة فيما يتعلق بصحتك، فانتقل إلى أقرب مركز/مستشفى طوارئ أو اتصل على الفور بأي رقم هاتف للطوارئ."}, + "liveCareTermsConditions18": {"en": "3.2 Telehealth Services is not appropriate for emergency conditions and there may be some treatments or medicines which cannot be provided without follow-up physical consultation. If you believe you have a serious medical condition, you should seek an in-person consultation with a licensed medical professional.", "ar": "3-2 خدمات الرعاية الصحية عن بعد ليست مناسبة للحالات الطبية الطارئة وقد تكون هناك بعض العلاجات أو الأدوية التي لا يمكن تقديمها دون استشارة متابعة في حضور المريض شخصياً. إذا كنت تعتقد أن لديك حالة طبية خطيرة، فعليك طلب استشارة شخصية مع أخصائي طبي مرخص."}, + "liveCareTermsConditions19": {"en": "3.3 Telehealth Services is intended to provide benefits including patient convenience. As such, it is most suitable as an alternative to in-person consultation for routine medical matters. However, there are potential risks associated with the use of any telehealth service, including Telehealth Services, and these risks may include but not be limited to the following: ", "ar": "3-3 تهدف خدمات الرعاية الصحية عن بُعد إلى توفير مزايا تشمل راحة المريض. لذلك، فهو قد يكون الأنسب كبديل للاستشارة الشخصية للأمور الطبية الروتينية. ومع ذلك، هناك مخاطر محتملة مرتبطة باستخدام أي خدمة للرعاية الصحية عن بُعد، بما في ذلك خدمات الرعاية الصحية عن بُعد، وقد تشمل هذه المخاطر على سبيل المثال لا الحصر ما يلي:"}, + "liveCareTermsConditions19a": {"en": "(a) information transmitted may not be sufficient (e.g. poor resolution of images) to allow for appropriate medical decision making by healthcare practitioners.", "ar": "(1) المعلومات المنقولة قد لا تكون كافية (مثل ضعف دقة الصور) للسماح باتخاذ القرار الطبي المناسب من قبل الممارسين الصحيين"}, + "liveCareTermsConditions19b": {"en": "(b) healthcare practitioners may determine that the transmitted information is of inadequate quality, thus necessitating a face-to-face meeting with the patient, or at least a rescheduled voice and video medical consult. ", "ar": "(2) قد يقرر الممارسين الصحيين أن المعلومات المنقولة ليست ذات جودة كافية، مما يستلزم مقابلة المريض وجهاً لوجه، أو على الأقل إعادة جدولة استشارة طبية صوتية ومرئية في وقت لاحق"}, + "liveCareTermsConditions19c": {"en": "(c) delays in medical care could occur due to deficiencies or failures of the electronic devices. ", "ar": "(3) يمكن أن يحدث تأخير في تقديم الرعاية الطبية بسبب أوجه القصور أو الأعطال في الأجهزة الإلكترونية"}, + "liveCareTermsConditions19d": {"en": "(d) the practitioner is dependent on the patient to provide all relevant information orally and via the appropriate use of the patient’s own camera device. It is possible that information may not be provided to the practitioner or may not be apparent which would have been apparent to the practitioner during an in-person physical examination. ", "ar": "(4) يعتمد الممارس الصحي على المريض لتقديم جميع المعلومات ذات الصلة شفوياً وعبر الاستخدام المناسب لجهاز الكاميرا الخاص بالمريض. من الممكن ألا يتم تقديم المعلومات إلى الممارس أو قد لا تكون واضحة بقدر الوضوح الذي يتوفر للممارس الصحي أثناء إجراء الفحص البدني الشخصي"}, + "liveCareTermsConditions19e": {"en": "(e) security protocols could fail, causing a breach of privacy of personal medical information. Whilst we take reasonable measures to protect the security of the information transmitted over the Application and or the Website, such transmissions can never be guaranteed to be completely secure and information transmitted over public telecommunications networks is outside our control and cannot be secured by us.", "ar": "(5) قد تفشل البروتوكولات الأمنية، مما يتسبب في انتهاك خصوصية المعلومات الطبية الشخصية. على الرغم من أننا نتخذ تدابير معقولة لحماية أمن المعلومات المنقولة عبر التطبيق و/أو الموقع الإلكتروني، إلا أنه لا يمكن أبدًا ضمان أن تكون عمليات الإرسال هذه آمنة تماماً، والمعلومات المنقولة عبر شبكات الاتصالات العامة خارجة عن سيطرتنا ولا يمكننا تأمينها."}, + "liveCareTermsConditions20": {"en": "3.4 If you use Telehealth Services but are experiencing any ongoing condition or concerns, we recommend you schedule an in-person consultation. ", "ar": "3-4 في حال كنت تستخدم خدمات الرعاية الصحية عن بُعد ولكنك تواجه أي حالة أو مخاوف مستمرة، فإننا نوصيك بحجز استشارة شخصية."}, + "liveCareTermsHeading6": {"en": "4. DISCLAIMER OF WARRANTY ", "ar": "4. إخلاء المسؤولية عن الضمان"}, + "liveCareTermsConditions21": {"en": "4.1 We do not warrant, represent or undertake that Telehealth Services will meet your needs, or that it will be uninterrupted, timely, secure, error-free or free from viruses. We shall have no liability to you if a Telehealth Services session cannot occur or is interrupted or abandoned due to any unavailability of our online platform, however, where the Telehealth Services session cannot be delivered fully due to the downtime of our own platform, we will not charge you for a replacement consultation.", "ar": "4-1 نحن لا نضمن ولا نقر أو نتعهد بأن خدمات الرعاية الصحية عن بُعد ستلبي احتياجاتك، أو أنها ستكون مستمرة دون انقطاع أو سيتم توفيرها في الوقت المناسب أو أنها آمنة أو خالية من الأخطاء أو خالية من الفيروسات. لن نتحمل أي مسؤولية تجاهك في حالة تعذر حدوث جلسة خدمات الرعاية الصحية عن بُعد أو تمت مقاطعتها أو التخلي عنها بسبب عدم توفر منصتنا عبر الإنترنت ومع ذلك، في حالة تعذر علينا إجراء جلسة خدمات الرعاية الصحية عن بُعد بالكامل بسبب تعطل منصتنا، فلن نتقاضى منك أي أجور عن جلسة الاستشارة البديلة."}, + "liveCareTermsConditions22": {"en": "4.2 All warranties expressed or implied by law, except those that cannot be lawfully excluded, are excluded. ", "ar": "4-2 تُستثنى جميع الضمانات الصريحة أو الضمنية بموجب النظام، باستثناء تلك التي لا يمكن استثناؤها بشكل قانوني."}, + "liveCareTermsConditions23": {"en": "4.3 Nothing in this section 4 is intended to exclude or limit our liability for any medical negligence claim, to the extent the applicable law in the relevant Permitted Territory does not permit us to do so.", "ar": "4-3 لا يوجد في هذا القسم 4 أي نص يُقصد منه استبعاد أو تقييد مسؤوليتنا عن أي مطالبة تتعلق بالإهمال الطبي، إلى الحد الذي لا يسمح لنا فيه النظام المعمول به في المنطقة المسموح بها ذات الصلة بالقيام بذلك."}, + "liveCareTermsHeading7": {"en": "5. ELIGIBILITY, REGISTRATION AND USE", "ar": "5. الأهلية والتسجيل والاستخدام"}, + "liveCareTermsConditions24": {"en": "5.1 To access Telehealth Services, you must satisfy the minimum age requirement of 18 years (measured according to the Gregorian calendar) and have full legal capacity. ", "ar": "5-1 من أجل الدخول إلى خدمات الرعاية الصحية عن بُعد، يتعين عليك أن تفي بمتطلبات الحد الأدنى للسن وهو 18 عاماً (يتم احتسابها وفقاً للتقويم الميلادي) وأن تتمتع بالأهلية القانونية الكاملة."}, + "liveCareTermsConditions25": {"en": "5.2 Any person under the age of 18 years (measured according to the Gregorian calendar) accessing Telehealth Services must have permission from their parent or guardian to do so.", "ar": "5-2 يجب أن يحصل أي شخص يقل عمره عن 18 عاماً (يتم احتسابها وفقاً للتقويم الميلادي) يقوم بالدخول إلى خدمات الرعاية الصحية عن بُعد على إذن من أحد الوالدين أو الوصي للقيام بذلك."}, + "liveCareTermsConditions26": {"en": "5.3 You warrant, represent and undertake that you possess the legal right and ability to access the Application and or the Website in accordance with these Terms & Conditions and, where relevant, to make bookings and payments through the Application and or the Website.", "ar": "5-3 أنت تضمن وتقر وتتعهد بأن لديك الحق القانوني والقدرة على الدخول إلى التطبيق و/أو موقع الويب وفقاً لهذه الشروط والأحكام و، عند الاقتضاء، إجراء الحجوزات والمدفوعات من خلال التطبيق أو موقع الويب."}, + "liveCareTermsConditions27": {"en": "5.4 The registration process is as provided in the Online Services Terms of Use.", "ar": "5-4 تتم عملية التسجيل وفق ما ورد في شروط استخدام الخدمات الإلكترونية"}, + "liveCareTermsConditions28": {"en": "5.5 Telehealth Services is intended only for your own personal use and the use of your children under your supervision. You must not share your user access details (log-in name, password etc.) with any other person and must take reasonable steps to maintain the security of such details. Our services are delivered on the basis that we have certain information about the user, which may be connected to or obtained from your account details (age, gender, medical history etc.). We accept no responsibility whatsoever to you or any other person if our services are delivered via a user account to a person other than the registered user. This is particularly important for telehealth services, where the practitioner will need to assess the information, the patient provides during the consultation in the context of the patient’s medical file and history.", "ar": "5-5 خدمات الرعاية الصحية عن بُعد مخصصة فقط لاستخدامك الشخصي واستخدام أطفالك تحت إشرافك. يتعين عليك ألا تشارك بيانات تسجيل الدخول الخاصة بك (اسم المستخدم وكلمة المرور وما إلى ذلك) مع أي شخص آخر ويجب أن تتخذ خطوات معقولة للحفاظ على أمان هذه البيانات. يتم تقديم خدماتنا على أساس أن لدينا معلومات معينة حول المستخدم، والتي قد تكون مرتبطة أو تم الحصول عليها من تفاصيل حسابك (العمر والجنس والتاريخ الطبي وما إلى ذلك). نحن لا نتحمل أي مسؤولية من أي نوع تجاهك أو تجاه أي شخص آخر إذا تم تقديم خدماتنا عبر حساب مستخدم إلى شخص آخر غير المستخدم المسجل. هذا مهم بشكل خاص لخدمات الرعاية الصحية عن بعد، حيث سيحتاج الممارس الصحي إلى تقييم المعلومات التي يقدمها المريض أثناء الاستشارة في سياق الملف الطبي للمريض وتاريخه."}, + "liveCareTermsConditions29": {"en": "5.6 You are responsible for ensuring you have a device connected to the internet and capable of transmitting and receiving video and sound. We are not responsible for any failure of a Telehealth Services session caused by your device or your internet connection. You are responsible for all costs associated with your own internet connection and use.", "ar": "5-6 أنت مسؤول عن التأكد من أن لديك جهازاً متصلاً بالإنترنت وقادراً على إرسال واستقبال الفيديو والصوت. نحن لسنا مسؤولين عن أي انقطاع في جلسة خدمات الرعاية الصحية عن بعد بسبب ناجم عن جهازك أو اتصالك بالإنترنت. أنت مسؤول عن جميع التكاليف المرتبطة باتصالك بالإنترنت واستخدامك لها."}, + "liveCareTermsConditions30": {"en": "5.7 From time to time we may release updates to our Application and or the Website. You should ensure that you are running the latest version of the Application. Use of old versions of the Application may lead to technical errors in your use of the Telehealth Services and may expose you to additional security risks.", "ar": "5-7 قد نقوم من وقت لآخر بإصدار تحديثات لتطبيقنا و/أو موقع الويب الخاص بنا. يجب عليك التأكد من أنك تقوم بتشغيل أحدث إصدار من التطبيق. قد يؤدي استخدام الإصدارات القديمة من التطبيق إلى حدوث أخطاء فنية أثناء استخدامك لخدمات الرعاية الصحية عن بُعد وقد يعرضك ذلك لمخاطر أمنية إضافية."}, + + "liveCareTermsHeading8": {"en": "6. TELEHEALTH SERVICES", "ar": "6. خدمات الرعاية الصحية عن بُعد"}, + "liveCareTermsConditions31": {"en": "Our Telehealth Services will be for specific medical specialties or follow-up or medication refill appointments.", "ar": "خدمات الرعاية الصحية عن بُعد الخاصة بنا سوف تكون لتخصصات طبية محددة أو لمواعيد المتابعة أو إعادة صرف الدواء. "}, + "liveCareTermsHeading9": {"en": "7. CHARGES AND PAYMENT", "ar": "7. الأجور والسداد"}, + "liveCareTermsConditions32": {"en": "Our Telehealth Services will be for specific medical specialties or follow-up or medication refill appointments.", "ar": "خدمات الرعاية الصحية عن بُعد الخاصة بنا سوف تكون لتخصصات طبية محددة أو لمواعيد المتابعة أو إعادة صرف الدواء. "}, + "liveCareTermsConditions33": {"en": "7.1 The charges for a Telehealth Services consultation will be indicated before you choose to proceed. By proceeding, you agree to pay the charges. Any subsequent charges, such as prescription charges, lab tests, follow-up consultations etc. are excluded from the initial charge and will be communicated to you following the initial consultation. ", "ar": "7-1 ستتم الإشارة إلى أجور استشارة خدمات الرعاية الصحية عن بُعد قبل أن تختار المتابعة. بمجرد المتابعة، فإنك توافق على سداد الأجور. لا تشمل تلك الأجور الأولية أي أجور لاحقة مثل أجور الوصفات الطبية والاختبارات المعملية واستشارات المتابعة وما إلى ذلك من أجور وسيتم إبلاغك بها بعد الاستشارة الأولية."}, + "liveCareTermsConditions34": {"en": "7.2 The applicable payment terms and methods are set out in our Online Services Terms of Use. ", "ar": "7-2 يتم تحديد شروط وطرق السداد المعمول بها في شروط استخدام الخدمات عبر الإنترنت الخاصة بنا."}, + "liveCareTermsConditions35": {"en": "7.3 It may be possible to charge Telehealth Services directly to a provider of medical insurance, although we give no undertaking or warranty that this shall be possible at any given time. Further details are set out in our Online Services Terms of Use. If such facility is made available and you choose to use it, you will need to provide us with details of your medical insurer and policy coverage, unless you have already done so and linked them to your account. You hereby authorise us to contact any such insurer with the details you provide at the time of purchase, or which are linked to your account to seek approval of the cost of your services. You acknowledge that we may be required to provide specific details of the medical services sought by you to do so and you expressly consent to such disclosure.", "ar": "7-3 قد يكون من الممكن فرض أجور خدمات الرعاية الصحية عن بُعد مباشرة على مزود التأمين الطبي، على الرغم من أننا لا نقدم أي تعهد أو ضمان بأن هذا سيكون ممكناً في أي وقت. تضمنت شروط استخدام الخدمات عبر الإنترنت الخاصة بنا مزيد من التفاصيل حول ذلك. إذا كان هذا التسهيل الخدمي متاحاً واخترت استخدامه، فستحتاج إلى تزويدنا بتفاصيل شركة التأمين الطبي وتغطية وثيقة التأمين، ما لم تكن قد قمت بذلك مسبقاً وربطتها بحسابك. أنت تفوضنا بموجب هذا بالتواصل مع أي شركة تأمين وفق التفاصيل التي تقدمها لنا في وقت الشراء أو المرتبطة بحسابك من أجل الحصول على الموافقة على تكلفة الخدمات المقدمة لك. أنت تقر بأنه قد يُطلب منا تقديم تفاصيل محددة عن الخدمات الطبية التي تطلبها من أجل القيام بذلك وتوافق صراحة على هذا الإفصاح."}, + "liveCareTermsHeading10": {"en": "8. COMMUNICATION AND/OR INQUIRIES", "ar": "8. الاتصالات و/أو الاستفسارات"}, + "liveCareTermsConditions36": {"en": "In case there are any questions and/or inquiries regarding the use of Telehealth Services please contact: EServices.HMG@drsulaimanalhabib.com or call 011 525 9553", "ar": "في حال وجود أي أسئلة و/أو استفسارات بخصوص استخدام خدمات الرعاية الصحية عن بُعد، يرجى التواصل معنا على: EServices.HMG@drsulaimanalhabib.com أو الاتصال على الرقم: 9553 525 011"}, + "liveCareTermsHeading11": {"en": "9. LIMITATION OF LIABILITY ", "ar": "9. حدود المسؤولية"}, + "liveCareTermsConditions37": {"en": "9.1 Subject to any responsibilities implied by law and which cannot be excluded, neither the Group nor any of our directors, employees, agents or contractors, are liable to you for any losses, damages, liabilities, claims and expenses (including without limitation but not limited to legal costs and defense or settlement costs) whatsoever, whether direct, indirect or consequential, arising out of or referable to your use of Telehealth Services , however caused, whether in contract, tort (including negligence), statute or otherwise. ", "ar": "9-1 مع مراعاة أي مسؤوليات ينص عليها النظام والتي لا يمكن استبعادها بموجبه، لا تتحمل المجموعة أو أي من مديرينا أو موظفينا أو وكلائنا أو مقاولينا المسؤولية تجاهك عن أي خسائر وأضرار ومسؤوليات ومطالبات ونفقات (بما في ذلك على سبيل المثال لا الحصر الأتعاب القانونية وتكاليف الدفاع أو التسوية) أيا كانت، سواء كانت مباشرة أو غير مباشرة أو تبعية، ناشئة عن أو متعلقة باستخدامك لخدمات الرعاية الصحية عن بُعد، أياً كان سبب نشوئها، سواء كان ذلك بموجب عقد أو المسؤولية التقصيرية (بما في ذلك الإهمال) أو النظام أو غير ذلك."}, + "liveCareTermsConditions38": {"en": "9.2 We will not be liable to you or anyone else for any loss resulting from a cause over which we do not have control. This includes failure of electronic or mechanical equipment or communications lines (including telephone, cable and Internet), unauthorized access, acts or omissions of third parties, viruses, theft, operator errors, severe or extraordinary weather (including flood, earthquake, or other act of God), fire, war, insurrection, terrorist act, riot, labor dispute or other labor problems, accident, emergency, delay, overbooking, cancellation, Royal demise or action of government", "ar": "9-2 لن نكون مسؤولين تجاهك أو تجاه أي شخص آخر عن أي خسارة ناتجة عن سبب خارج عن سيطرتنا. يتضمن ذلك تعطل المعدات الإلكترونية أو الميكانيكية أو خطوط الاتصالات (بما في ذلك الهاتف والكابل والإنترنت)، أو الدخول غير المصرح به، أو أفعال أو إغفالات الأطراف الثالثة، أو الفيروسات، أو السرقة، أو أخطاء المشغل، أو الطقس القاسي أو غير العادي (بما في ذلك الفيضانات، أو الزلازل، أو أي من أفعال القضاء والقدر الأخرى)، أو الحرائق والحروب والتمرد والأعمال الإرهابية وأعمال شغب والنزاع العمالي أو المشاكل العمالية الأخرى أو الحوادث أو الطوارئ أو التأخير أو الحجز الزائد أو الإلغاء، أو الزوال الملكي أو أي إجراء حكومي."}, + "liveCareTermsHeading12": {"en": "10. TERMINATION OF USE", "ar": "10. إنهاء الاستخدام"}, + "liveCareTermsConditions39": {"en": "10.1 We may discontinue the provision of Telehealth Services at any time and for any reason. We shall have no liability for any discontinuation, including where you are part-way through a series of consultations or courses of treatment using Telehealth Services. We will assist in enabling you to book in-person consultations instead or in transferring relevant information to an alternative medical provider to enable you to continue treatment (subject to data protection, confidentiality and medical practice laws and to prevailing medical good practice).", "ar": "10-1 يجوز لنا التوقف عن توفير خدمات الرعاية الصحية عن بُعد في أي وقت ولأي سبب. لن نتحمل أي مسؤولية عن أي توقف، بما في ذلك عندما تكون خلال الاستشارات أو دورات العلاج باستخدام خدمات الرعاية الصحية عن بُعد. سنساعدك للتمكن من حجز الاستشارات الشخصية بدلاً من ذلك أو في نقل المعلومات ذات الصلة إلى مزود طبي بديل لتمكينك من مواصلة العلاج (مع مراعاة أنظمة حماية البيانات والسرية والممارسات الطبية والممارسات الطبية الجيدة السائدة)."}, + "liveCareTermsConditions40": {"en": "10.2 We may terminate your use and access to Telehealth Services for any or no reason, at any time, with or without notice to you and without incurring any liability to you, however that liability may arise (although we will consider our medical duties to you, if doing so). ", "ar": "10-2 يجوز لنا إنهاء استخدامك ودخولك إلى خدمات الرعاية الصحية عن بُعد لأي سبب أو بدون سبب، في أي وقت، سواء بإشعارك أو بدونه ودون تحمل أي مسؤولية تجاهك، ومع ذلك قد تنشأ هذه المسؤولية (على الرغم من أننا سنأخذ واجباتنا الطبية تجاهك بعين الاعتبار في حالة القيام بذلك)."}, + "liveCareTermsConditions41": {"en": "10.3 All restrictions and all disclaimers and exclusions and limitations of our liability will survive any termination. Upon termination, you must not directly or indirectly access or use the Application and or the Website.", "ar": "10-3 ستظل جميع القيود وجميع إخلاءات الطرف من المسؤولية والاستثناءات والقيود الخاصة بمسؤوليتنا سارية بعد أي إنهاء. عند الإنهاء، يتعين عليك عدم الدخول إلى أو استخدام التطبيق و/أو موقع الويب بشكل مباشر أو غير مباشر."}, + "liveCareTermsHeading13": {"en": "11. GOVERNING LAW AND JURISDICTION ", "ar": "11. القانون الحاكم والاختصاص القضائي"}, + "liveCareTermsConditions42": {"en": "The law applicable to the Application and or the Website User Terms and Conditions and to disputes arising out of or in connection with them are the laws of The Kingdom of Saudi Arabia. You irrevocably submit to the exclusive jurisdiction of the courts of the Kingdom of Saudi Arabia. ", "ar": "النظام المعمول به على التطبيق و/أو شروط وأحكام مستخدم موقع الويب والنزاعات الناشئة عنها أو المتعلقة بها هي أنظمة المملكة العربية السعودية. وأنت تخضع بشكل لا رجوع فيه للاختصاص القضائي الحصري لمحاكم المملكة العربية السعودية."}, + "liveCareTermsHeading14": {"en": "12. ACKNOWLEDGEMENTS", "ar": "12. الإقرارات"}, + "liveCareTermsConditions43": {"en": "12.1 Except as expressly set out in these Terms & Conditions or as permitted by any applicable law, you agree on the following: ", "ar": "12-1 باستثناء ما هو منصوص عليه صراحةً في هذه الشروط والأحكام أو ما يسمح به أي نظام معمول به، فإنك توافق على ما يلي:"}, + "liveCareTermsConditions43a": {"en": "(a) you have read and understand these Terms & Conditions and the other terms forming part of your Agreement with us; ", "ar": "(1) أنك قد قرأت وفهمت هذه الشروط والأحكام والبنود الأخرى التي تشكل جزءاً من اتفاقيتك معنا"}, + "liveCareTermsConditions43b": {"en": "(b) you have read our Privacy Policy and hereby expressly consent to our use of your personal information as described. In addition, you understand that the contact number or email address that you have provided on registration will be used for communications by the Group through SMS, email or any other method in connection with the Telehealth Services, including for appointment notifications and current medical services;", "ar": "(2) أنك قد قرأت سياسة الخصوصية الخاصة بنا وتوافق بموجبه صراحة على استخدامنا لمعلوماتك الشخصية كما هو موضح فيها. بالإضافة إلى ذلك، أنت تدرك أن رقم الاتصال أو عنوان البريد الإلكتروني الذي زودتنا به عند التسجيل سيتم استخدامه للاتصالات من قبل المجموعة من خلال الرسائل القصيرة أو البريد الإلكتروني أو أي طريقة أخرى فيما يتعلق بخدمات الرعاية الصحية عن بُعد، بما في ذلك إشعارات المواعيد والخدمات الطبية الحالية."}, + "liveCareTermsConditions43c": {"en": "(c) you understand that you have the right to withhold or withdraw your consent to the use of the Application and or the Website in the course of your care at any time, without affecting your right to future care or treatment; ", "ar": "(3) أنت تدرك أن لديك الحق في حجب أو سحب موافقتك بشأن استخدام التطبيق و/أو موقع الويب في سياق رعايتك في أي وقت، دون التأثير على حقك في تلقي الرعاية أو العلاج في المستقبل؛"}, + "liveCareTermsConditions43d": {"en": "(d) you understand that you may expect to receive benefits from the use of Application and or the Website concerning your healthcare, but that no results can be guaranteed or assured; ", "ar": "(4) أنت تدرك أنك قد تتوقع الحصول على مزايا من استخدام التطبيق و/أو موقع الويب فيما يتعلق برعايتك الصحية، ولكن لا يمكن ضمان أي نتائج أو تأكيدها؛"}, + "liveCareTermsConditions43e": {"en": "(e) you understand that your healthcare information may be shared with other employees in the Group for scheduling and billing purposes;", "ar": "(5) أنت تدرك أنه قد تتم مشاركة معلومات الرعاية الصحية الخاصة بك مع موظفين آخرين في المجموعة لأغراض جدولة المواعيد والفواتير؛"}, + "liveCareTermsConditions43f": {"en": "(f) you understand that video images and audio recordings of you may be captured and stored electronically. You understand that these recordings may be later used in connection with legal proceedings if necessary but will not otherwise be used for any purpose other than providing Telehealth Services and follow-up medical services to you. You acknowledge and consent to the use of these images and audio recordings by us for the purposes described; ", "ar": "(6) أنت تدرك أن صور الفيديو والتسجيلات الصوتية الخاصة بك قد يتم التقاطها وتخزينها إلكترونياً. وأنت تدرك كذلك أنه يمكن استخدام هذه التسجيلات لاحقاً فيما يتعلق بالإجراءات النظامية إذا لزم الأمر ولكن لن يتم استخدامها لأي غرض بخلاف توفير خدمات الرعاية الصحية عن بُعد وخدمات المتابعة الطبية لك. أنت تقر وتوافق على استخدام هذه الصور والتسجيلات الصوتية من قبلنا للأغراض الموضحة؛"}, + "liveCareTermsConditions43g": {"en": "(g) you understand the risks of communicating by email and text messages, particularly the privacy risks. You understand that the Group cannot guarantee the security and confidentiality of email or text communication. The Group will not be responsible for messages that are not received or delivered due to technical failure, or for disclosure of confidential information unless caused by intentional misconduct.", "ar": "(7) أنك تدرك مخاطر الاتصال عبر البريد الإلكتروني والرسائل النصية، ولا سيما مخاطر الخصوصية. أنت تدرك أن المجموعة لا يمكنها ضمان أمان وسرية البريد الإلكتروني أو الاتصالات النصية. لن تكون المجموعة مسؤولة عن الرسائل التي لم يتم استلامها أو تسليمها بسبب عطل فني أو الكشف عن معلومات سرية ما لم يكن ذلك بسبب سوء سلوك متعمد."}, + "liveCareTermsHeading15": {"en": "13. GENERAL TERMS AND CONDITIONS ", "ar": "13. شروط وأحكام عامة"}, + "liveCareTermsConditions44": {"en": "13.1 We may at any time vary these Terms & Conditions for security, legal or regulatory reasons, or to reflect updates or changes to the services or functionality of Telehealth Services or the Application, by publishing the varied Terms & Conditions on the Application. We will notify you on the Application that these Terms & Conditions have changed before your next use of the Telehealth Services and you will have the opportunity to agree to the revised terms before using the service again. ", "ar": "13-1 يجوز لنا في أي وقت تغيير هذه الشروط والأحكام لأسباب أمنية أو نظامية أو تنظيمية ، أو لتعكس التحديثات أو التغييرات التي تطرأ على خدمات أو وظائف خدمات الرعاية الصحية عن بُعد أو التطبيق، عن طريق نشر الشروط والأحكام المتنوعة على التطبيق. سنخطرك في التطبيق بأن هذه الشروط والأحكام قد تغيرت قبل استخدامك التالي لخدمات الرعاية الصحية عن بُعد وستتاح لك الفرصة للموافقة على الشروط المعدلة قبل استخدام الخدمة مرة أخرى."}, + "liveCareTermsConditions45": {"en": "13.2 We may perform any of our obligations, and exercise any of the rights granted to us under these Terms & Conditions, through a third party. We may assign any or all our rights and obligations under these Terms & Conditions to any third party.", "ar": "13-2 يجوز لنا أداء أي من التزاماتنا، وممارسة أي من الحقوق الممنوحة لنا بموجب هذه الشروط والأحكام، من خلال طرف ثالث. يجوز لنا التنازل عن أي من حقوقنا والتزاماتنا أو جميعها بموجب هذه الشروط والأحكام إلى أي طرف ثالث."}, + "liveCareTermsConditions46": {"en": "13.3 If any clause or part of any clause of these Terms & Conditions is found to be void, unenforceable or invalid, then it will be severed from these Terms & Conditions, leaving the remainder in full force and effect, provided that the severance has not altered the basic nature of these Terms & Conditions. ", "ar": "13-3 إذا تبين أن أي بند أو جزء من أي بند من هذه الشروط والأحكام باطل أو غير قابل للإنفاذ أو غير صالح، فسيتم فصله عن هذه الشروط والأحكام، تاركاً باقي الشروط سارية المفعول بكامل الأثر والنفاذ، بشرط ألا يغير فصل ذلك البند من الطبيعة الأساسية لهذه الشروط والأحكام."}, + "liveCareTermsHeading16": {"en": "14. COMPLAINTS", "ar": "14. الشكاوى"}, + "liveCareTermsConditions47": {"en": "Our Telehealth Services will be for specific medical specialties or follow-up or medication refill appointments.", "ar": "خدمات الرعاية الصحية عن بُعد الخاصة بنا سوف تكون لتخصصات طبية محددة أو لمواعيد المتابعة أو إعادة صرف الدواء. "}, + "liveCareTermsConditions48": {"en": "If you have any complaints or concerns about the Application and or the Website, Our Services, or how we handle your personal information please contact us on: EServices.HMG@drsulaimanalhabib.com or call 011 525 9553", "ar": "إذا كانت لديك أي شكاوى أو مخاوف بشأن التطبيق و/أو موقع الويب أو خدماتنا أو كيفية تعاملنا مع معلوماتك الشخصية، فيرجى التواصل معنا على: EServices.HMG@drsulaimanalhabib.com أو الاتصال على الرقم: 9553 525 011"}, + "clickPrivacyPolicy": {"en": "Please click here to view the privacy policy", "ar": "الرجاء الضغط هنا لعرض سياسة الخصوصية"}, }; diff --git a/lib/config/shared_pref_kay.dart b/lib/config/shared_pref_kay.dart index caada21f..07295d75 100644 --- a/lib/config/shared_pref_kay.dart +++ b/lib/config/shared_pref_kay.dart @@ -2,10 +2,13 @@ const TOKEN = 'token'; const APP_LANGUAGE = 'language'; const USER_PROFILE = 'user-profile'; const PUSH_TOKEN = 'push-token'; +const APNS_TOKEN = 'apns-token'; +const ONESIGNAL_APNS_TOKEN = 'onesignal-apns-token'; const REGISTER_DATA_FOR_REGISTER = 'register-data-for-register'; const LOGIN_TOKEN_ID = 'register-data-for-register'; const REGISTER_DATA_FOR_LOGIIN = 'register-data-for-login'; const LAST_LOGIN = 'last-login'; +const ER_CHECKIN_RISK_SCORE = 'er-checkin-risk-score'; const ONLY_SMS = 'only-sms'; const AUTH_DATA = 'auth-data'; const IMEI_USER_DATA = 'imei-user-data'; @@ -21,6 +24,8 @@ const THEME_VALUE = 'is_vibration'; const MAIN_USER = 'main-user'; const PHARMACY_LAST_VISITED_PRODUCTS = 'last-visited'; const PHARMACY_CUSTOMER_ID = 'costumer-id'; +const PHARMACY_CUSTOMER_GUID = 'customer-guid'; +const PHARMACY_CUSTOMER_OBJECT = 'pharmacy-customer-object'; const IS_ROBOT_VISIBLE = 'robot-visible'; const IS_ROBOT_INIT = 'robot-init'; const HMG_GEOFENCES = 'hmg-geo-fences'; @@ -29,3 +34,14 @@ const BLOOD_TYPE = 'blood-type'; const NOTIFICATION_COUNT = 'notification-count'; const PHARMACY_SELECTED_ADDRESS = 'selected-address'; const PHARMACY_AUTORZIE_TOKEN = 'PHARMACY_AUTORZIE_TOKEN'; +const H2O_UNIT = 'H2O_UNIT'; +const H2O_REMINDER = 'H2O_REMINDER'; +const LIVECARE_CLINIC_DATA = 'LIVECARE_CLINIC_DATA'; +const DOCTOR_SCHEDULE_DATE_SEL = 'DOCTOR_SCHEDULE_DATE_SEL'; +const APPOINTMENT_HISTORY_MEDICAL = 'APPOINTMENT_HISTORY_MEDICAL'; +const CLINICS_LIST = 'CLINICS_LIST'; +const COVID_QA_LIST = 'COVID_QA_LIST'; +const IS_COVID_CONSENT_SHOWN = 'IS_COVID_CONSENT_SHOWN'; +const REGISTER_INFO_DUBAI ='register-info-dubai'; +const IS_LAST_APPOINTMENT_RATE_SHOWN ='is-last-appointment-rate-shown'; +const PATIENT_OCCUPATION_LIST ='patient-occupation-list'; diff --git a/lib/config/size_config.dart b/lib/config/size_config.dart index e7e1b41b..8a9a92f2 100644 --- a/lib/config/size_config.dart +++ b/lib/config/size_config.dart @@ -6,14 +6,14 @@ class SizeConfig { static double _blockWidth = 0; static double _blockHeight = 0; - static double realScreenWidth; - static double realScreenHeight; - static double screenWidth; - static double screenHeight; - static double textMultiplier; - static double imageSizeMultiplier; - static double heightMultiplier; - static double widthMultiplier; + static double? realScreenWidth; + static double? realScreenHeight; + static double? screenWidth; + static double? screenHeight; + static double? textMultiplier; + static double? imageSizeMultiplier; + static double? heightMultiplier; + static double? widthMultiplier; static bool isPortrait = true; static bool isMobilePortrait = false; @@ -28,7 +28,7 @@ class SizeConfig { } if (orientation == Orientation.portrait) { isPortrait = true; - if (realScreenWidth < 450) { + if (realScreenWidth! < 450) { isMobilePortrait = true; } screenHeight = realScreenHeight; @@ -39,8 +39,8 @@ class SizeConfig { screenHeight = realScreenWidth; screenWidth = realScreenHeight; } - _blockWidth = screenWidth / 100; - _blockHeight = screenHeight / 100; + _blockWidth = screenWidth! / 100; + _blockHeight = screenHeight! / 100; textMultiplier = _blockHeight; imageSizeMultiplier = _blockWidth; diff --git a/lib/core/enum/PayfortEnums.dart b/lib/core/enum/PayfortEnums.dart new file mode 100644 index 00000000..2951eed8 --- /dev/null +++ b/lib/core/enum/PayfortEnums.dart @@ -0,0 +1,44 @@ +enum ServiceTypeEnum { + advancePayment, //3 + ancillaryOrder, //3 + appointmentPayment, //2 + covidPayment, //2 + erOnlineCheckIn, //3 + liveCareAppointment //4 +} + +extension ServiceTypeEnumExt on ServiceTypeEnum { + String value() { + switch (this) { + case ServiceTypeEnum.advancePayment: + return "Advance Payment"; + case ServiceTypeEnum.ancillaryOrder: + return "Ancillary Order"; + case ServiceTypeEnum.appointmentPayment: + return "Appointment Payment"; + case ServiceTypeEnum.covidPayment: + return "Covid Payment"; + case ServiceTypeEnum.erOnlineCheckIn: + return "ER Online Check In"; + case ServiceTypeEnum.liveCareAppointment: + return "LiveCare Appointment"; + } + } + + int getIdFromServiceEnum() { + switch (this) { + case ServiceTypeEnum.advancePayment: + return 3; + case ServiceTypeEnum.ancillaryOrder: + return 3; + case ServiceTypeEnum.appointmentPayment: + return 2; + case ServiceTypeEnum.covidPayment: + return 2; + case ServiceTypeEnum.erOnlineCheckIn: + return 3; + case ServiceTypeEnum.liveCareAppointment: + return 4; + } + } +} diff --git a/lib/core/enum/PaymentOptions.dart b/lib/core/enum/PaymentOptions.dart index bbf43cb2..1e2bab4e 100644 --- a/lib/core/enum/PaymentOptions.dart +++ b/lib/core/enum/PaymentOptions.dart @@ -28,7 +28,5 @@ extension PaymentOptions_ on PaymentOptions{ return "APPLEPAY"; break; } - - return null; } } diff --git a/lib/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/GetCMCAllOrdersResponseModel.dart b/lib/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/GetCMCAllOrdersResponseModel.dart new file mode 100644 index 00000000..8364a240 --- /dev/null +++ b/lib/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/GetCMCAllOrdersResponseModel.dart @@ -0,0 +1,345 @@ +class GetCMCAllOrdersResponseModel { + int? iD; + int? patientId; + int? patientOutSa; + bool? isOutPatient; + int? projectId; + int? nearestProjectId; + dynamic longitude; + dynamic latitude; + dynamic appointmentNo; + dynamic dischargeId; + int? statusId; + int? serviceId; + int? channel; + Orderpayment? orderpayment; + dynamic orderselectedservice; + dynamic wforder; + dynamic orderapprovalobj; + String? created; + dynamic createdBy; + dynamic modified; + dynamic modifiedBy; + bool? isDeleted; + String? statusText; + int? paymentStatus; + dynamic clientRequestid; + dynamic paymentStatusText; + String? projectName; + String? nearestProjectName; + dynamic paymentAmount; + WFOrder? wFOrder; + String? serviceText; + bool? isSentForApproval; + int? exaCartOrderId; + bool? isTimer; + int? timeSeconds; + int? totalPendingSeconds; + int? timeMinute; + int? timeHour; + int? timeTotalSeconds; + int? timeTotalMinute; + int? timeTotalHour; + dynamic approvalStatus; + bool? isActive; + int? clickButton; + List? procedures; + dynamic pickupLocation; + dynamic dropOffLocation; + dynamic clinicName; + dynamic doctorName; + dynamic branch; + dynamic time; + dynamic notes; + + GetCMCAllOrdersResponseModel( + {this.iD, + this.patientId, + this.patientOutSa, + this.isOutPatient, + this.projectId, + this.nearestProjectId, + this.longitude, + this.latitude, + this.appointmentNo, + this.dischargeId, + this.statusId, + this.serviceId, + this.channel, + this.orderpayment, + this.orderselectedservice, + this.wforder, + this.orderapprovalobj, + this.created, + this.createdBy, + this.modified, + this.modifiedBy, + this.isDeleted, + this.statusText, + this.paymentStatus, + this.clientRequestid, + this.paymentStatusText, + this.projectName, + this.nearestProjectName, + this.paymentAmount, + this.wFOrder, + this.serviceText, + this.isSentForApproval, + this.exaCartOrderId, + this.isTimer, + this.timeSeconds, + this.totalPendingSeconds, + this.timeMinute, + this.timeHour, + this.timeTotalSeconds, + this.timeTotalMinute, + this.timeTotalHour, + this.approvalStatus, + this.isActive, + this.clickButton, + this.procedures, + this.pickupLocation, + this.dropOffLocation, + this.clinicName, + this.doctorName, + this.branch, + this.time, + this.notes}); + + GetCMCAllOrdersResponseModel.fromJson(Map json) { + iD = json['ID']; + patientId = json['PatientId']; + patientOutSa = json['PatientOutSa']; + isOutPatient = json['IsOutPatient']; + projectId = json['ProjectId']; + nearestProjectId = json['NearestProjectId']; + longitude = json['Longitude']; + latitude = json['Latitude']; + appointmentNo = json['AppointmentNo']; + dischargeId = json['DischargeId']; + statusId = json['StatusId']; + serviceId = json['ServiceId']; + channel = json['Channel']; + orderpayment = json['orderpayment'] != null + ? new Orderpayment.fromJson(json['orderpayment']) + : null; + orderselectedservice = json['orderselectedservice']; + wforder = json['wforder']; + orderapprovalobj = json['orderapprovalobj']; + created = json['Created']; + createdBy = json['CreatedBy']; + modified = json['Modified']; + modifiedBy = json['ModifiedBy']; + isDeleted = json['IsDeleted']; + statusText = json['StatusText']; + paymentStatus = json['PaymentStatus']; + clientRequestid = json['ClientRequestid']; + paymentStatusText = json['PaymentStatusText']; + projectName = json['ProjectName']; + nearestProjectName = json['NearestProjectName']; + paymentAmount = json['PaymentAmount']; + wFOrder = json['WF_order'] != null + ? new WFOrder.fromJson(json['WF_order']) + : null; + serviceText = json['ServiceText']; + isSentForApproval = json['isSentForApproval']; + exaCartOrderId = json['ExaCart_OrderId']; + isTimer = json['isTimer']; + timeSeconds = json['TimeSeconds']; + totalPendingSeconds = json['TotalPendingSeconds']; + timeMinute = json['TimeMinute']; + timeHour = json['TimeHour']; + timeTotalSeconds = json['TimeTotalSeconds']; + timeTotalMinute = json['TimeTotalMinute']; + timeTotalHour = json['TimeTotalHour']; + approvalStatus = json['ApprovalStatus']; + isActive = json['isActive']; + clickButton = json['ClickButton']; + pickupLocation = json['PickupLocation']; + dropOffLocation = json['DropOffLocation']; + clinicName = json['clinicName']; + doctorName = json['DoctorName']; + branch = json['Branch']; + time = json['Time']; + notes = json['Notes']; + } + + Map toJson() { + final Map data = new Map(); + data['ID'] = this.iD; + data['PatientId'] = this.patientId; + data['PatientOutSa'] = this.patientOutSa; + data['IsOutPatient'] = this.isOutPatient; + data['ProjectId'] = this.projectId; + data['NearestProjectId'] = this.nearestProjectId; + data['Longitude'] = this.longitude; + data['Latitude'] = this.latitude; + data['AppointmentNo'] = this.appointmentNo; + data['DischargeId'] = this.dischargeId; + data['StatusId'] = this.statusId; + data['ServiceId'] = this.serviceId; + data['Channel'] = this.channel; + if (this.orderpayment != null) { + data['orderpayment'] = this.orderpayment!.toJson(); + } + data['orderselectedservice'] = this.orderselectedservice; + + data['wforder'] = this.wforder; + data['orderapprovalobj'] = this.orderapprovalobj; + data['Created'] = this.created; + data['CreatedBy'] = this.createdBy; + data['Modified'] = this.modified; + data['ModifiedBy'] = this.modifiedBy; + data['IsDeleted'] = this.isDeleted; + data['StatusText'] = this.statusText; + data['PaymentStatus'] = this.paymentStatus; + data['ClientRequestid'] = this.clientRequestid; + data['PaymentStatusText'] = this.paymentStatusText; + data['ProjectName'] = this.projectName; + data['NearestProjectName'] = this.nearestProjectName; + data['PaymentAmount'] = this.paymentAmount; + if (this.wFOrder != null) { + data['WF_order'] = this.wFOrder!.toJson(); + } + data['ServiceText'] = this.serviceText; + data['isSentForApproval'] = this.isSentForApproval; + data['ExaCart_OrderId'] = this.exaCartOrderId; + data['isTimer'] = this.isTimer; + data['TimeSeconds'] = this.timeSeconds; + data['TotalPendingSeconds'] = this.totalPendingSeconds; + data['TimeMinute'] = this.timeMinute; + data['TimeHour'] = this.timeHour; + data['TimeTotalSeconds'] = this.timeTotalSeconds; + data['TimeTotalMinute'] = this.timeTotalMinute; + data['TimeTotalHour'] = this.timeTotalHour; + data['ApprovalStatus'] = this.approvalStatus; + data['isActive'] = this.isActive; + data['ClickButton'] = this.clickButton; + data['PickupLocation'] = this.pickupLocation; + data['DropOffLocation'] = this.dropOffLocation; + data['clinicName'] = this.clinicName; + data['DoctorName'] = this.doctorName; + data['Branch'] = this.branch; + data['Time'] = this.time; + data['Notes'] = this.notes; + return data; + } +} + +class Orderpayment { + int? iD; + int? orderId; + dynamic clientRequestId; + dynamic totalAmount; + int? paymentStatus; + dynamic order; + String? created; + dynamic createdBy; + dynamic modified; + dynamic modifiedBy; + bool? isDeleted; + + Orderpayment( + {this.iD, + this.orderId, + this.clientRequestId, + this.totalAmount, + this.paymentStatus, + this.order, + this.created, + this.createdBy, + this.modified, + this.modifiedBy, + this.isDeleted}); + + Orderpayment.fromJson(Map json) { + iD = json['ID']; + orderId = json['OrderId']; + clientRequestId = json['ClientRequestId']; + totalAmount = json['TotalAmount']; + paymentStatus = json['PaymentStatus']; + order = json['Order']; + created = json['Created']; + createdBy = json['CreatedBy']; + modified = json['Modified']; + modifiedBy = json['ModifiedBy']; + isDeleted = json['IsDeleted']; + } + + Map toJson() { + final Map data = new Map(); + data['ID'] = this.iD; + data['OrderId'] = this.orderId; + data['ClientRequestId'] = this.clientRequestId; + data['TotalAmount'] = this.totalAmount; + data['PaymentStatus'] = this.paymentStatus; + data['Order'] = this.order; + data['Created'] = this.created; + data['CreatedBy'] = this.createdBy; + data['Modified'] = this.modified; + data['ModifiedBy'] = this.modifiedBy; + data['IsDeleted'] = this.isDeleted; + return data; + } +} + +class WFOrder { + dynamic wfButtonsDTO; + int? iD; + int? orderId; + int? previousStep; + int? nextStep; + int? serviceId; + dynamic order; + String? created; + dynamic createdBy; + dynamic modified; + dynamic modifiedBy; + bool? isDeleted; + + WFOrder( + {this.wfButtonsDTO, + this.iD, + this.orderId, + this.previousStep, + this.nextStep, + this.serviceId, + this.order, + this.created, + this.createdBy, + this.modified, + this.modifiedBy, + this.isDeleted}); + + WFOrder.fromJson(Map json) { + wfButtonsDTO = json['wf_ButtonsDTO']; + iD = json['ID']; + orderId = json['OrderId']; + previousStep = json['PreviousStep']; + nextStep = json['NextStep']; + serviceId = json['ServiceId']; + order = json['Order']; + created = json['Created']; + createdBy = json['CreatedBy']; + modified = json['Modified']; + modifiedBy = json['ModifiedBy']; + isDeleted = json['IsDeleted']; + } + + Map toJson() { + final Map data = new Map(); + data['wf_ButtonsDTO'] = this.wfButtonsDTO; + data['ID'] = this.iD; + data['OrderId'] = this.orderId; + data['PreviousStep'] = this.previousStep; + data['NextStep'] = this.nextStep; + data['ServiceId'] = this.serviceId; + data['Order'] = this.order; + data['Created'] = this.created; + data['CreatedBy'] = this.createdBy; + data['Modified'] = this.modified; + data['ModifiedBy'] = this.modifiedBy; + data['IsDeleted'] = this.isDeleted; + return data; + } +} diff --git a/lib/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_get_items_request_model.dart b/lib/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_get_items_request_model.dart index 6880f9f5..98857fff 100644 --- a/lib/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_get_items_request_model.dart +++ b/lib/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_get_items_request_model.dart @@ -1,18 +1,18 @@ class CMCGetItemsRequestModel { - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - String sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; - int patientID; - String tokenID; - int patientTypeID; - int patientType; - int checkupType; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + String? sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + int? patientID; + String? tokenID; + int? patientTypeID; + int? patientType; + int? checkupType; CMCGetItemsRequestModel( {this.versionID, diff --git a/lib/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_get_items_response_model.dart b/lib/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_get_items_response_model.dart index 6f362baa..2aa8e35f 100644 --- a/lib/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_get_items_response_model.dart +++ b/lib/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_get_items_response_model.dart @@ -1,6 +1,6 @@ class CMCGetItemsResponseModel { - String itemDescription; - String itemName; + String? itemDescription; + String? itemName; CMCGetItemsResponseModel({this.itemDescription, this.itemName}); diff --git a/lib/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_insert_pres_order_request_model.dart b/lib/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_insert_pres_order_request_model.dart index 534988a7..5eb8877f 100644 --- a/lib/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_insert_pres_order_request_model.dart +++ b/lib/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_insert_pres_order_request_model.dart @@ -1,42 +1,44 @@ class CMCInsertPresOrderRequestModel { - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - String sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; - int patientID; - String tokenID; - int patientTypeID; - int patientType; - double latitude; - double longitude; - int createdBy; - int orderServiceID; - List patientERCMCInsertServicesList; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + String? sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + int? patientID; + String? tokenID; + int? patientTypeID; + int? patientType; + double? latitude; + double? longitude; + int? createdBy; + int? orderServiceID; + int? projectID; + List? patientERCMCInsertServicesList; CMCInsertPresOrderRequestModel( {this.versionID, - this.channel, - this.languageID, - this.iPAdress, - this.generalid, - this.patientOutSA, - this.sessionID, - this.isDentalAllowedBackend, - this.deviceTypeID, - this.patientID, - this.tokenID, - this.patientTypeID, - this.patientType, - this.latitude, - this.longitude, - this.createdBy, - this.orderServiceID, - this.patientERCMCInsertServicesList}); + this.channel, + this.languageID, + this.iPAdress, + this.generalid, + this.patientOutSA, + this.sessionID, + this.isDentalAllowedBackend, + this.deviceTypeID, + this.patientID, + this.tokenID, + this.patientTypeID, + this.patientType, + this.latitude, + this.longitude, + this.createdBy, + this.orderServiceID, + this.projectID, + this.patientERCMCInsertServicesList}); CMCInsertPresOrderRequestModel.fromJson(Map json) { versionID = json['VersionID']; @@ -56,12 +58,13 @@ class CMCInsertPresOrderRequestModel { longitude = json['Longitude']; createdBy = json['CreatedBy']; orderServiceID = json['OrderServiceID']; + projectID = json['ProjectId']; if (json['PatientER_CMC_InsertServicesList'] != null) { - patientERCMCInsertServicesList = - new List(); + patientERCMCInsertServicesList = []; json['PatientER_CMC_InsertServicesList'].forEach((v) { - patientERCMCInsertServicesList - .add(new PatientERCMCInsertServicesList.fromJson(v)); + patientERCMCInsertServicesList!.add( + new PatientERCMCInsertServicesList.fromJson(v), + ); }); } } @@ -73,43 +76,35 @@ class CMCInsertPresOrderRequestModel { data['LanguageID'] = this.languageID; data['IPAdress'] = this.iPAdress; data['generalid'] = this.generalid; - data['PatientOutSA'] = this.patientOutSA; + data['isOutPatient'] = this.patientOutSA == 0 ? false : true; data['SessionID'] = this.sessionID; data['isDentalAllowedBackend'] = this.isDentalAllowedBackend; data['DeviceTypeID'] = this.deviceTypeID; - data['PatientID'] = this.patientID; data['TokenID'] = this.tokenID; data['PatientTypeID'] = this.patientTypeID; data['PatientType'] = this.patientType; - data['Latitude'] = this.latitude; - data['Longitude'] = this.longitude; - data['CreatedBy'] = this.createdBy; + data['latitude'] = this.latitude; + data['longitude'] = this.longitude; + // data['CreatedBy'] = this.createdBy; data['OrderServiceID'] = this.orderServiceID; + data['ProjectID'] = this.projectID; if (this.patientERCMCInsertServicesList != null) { - data['PatientER_CMC_InsertServicesList'] = - this.patientERCMCInsertServicesList.map((v) => v.toJson()).toList(); + data['procedures'] = this.patientERCMCInsertServicesList!.map((v) => v.toJson()).toList(); } return data; } } class PatientERCMCInsertServicesList { - int recordID; - String serviceID; - String selectedServiceName; - String selectedServiceNameAR; + int? recordID; + String? serviceID; + String? selectedServiceName; + String? selectedServiceNameAR; dynamic price; dynamic vAT; dynamic totalPrice; - PatientERCMCInsertServicesList( - {this.recordID, - this.serviceID, - this.selectedServiceName, - this.selectedServiceNameAR, - this.price, - this.vAT, - this.totalPrice}); + PatientERCMCInsertServicesList({this.recordID, this.serviceID, this.selectedServiceName, this.selectedServiceNameAR, this.price, this.vAT, this.totalPrice}); PatientERCMCInsertServicesList.fromJson(Map json) { recordID = json['RecordID']; diff --git a/lib/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/get_cmc_service_request_model.dart b/lib/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/get_cmc_service_request_model.dart index e80b656d..2492a7b7 100644 --- a/lib/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/get_cmc_service_request_model.dart +++ b/lib/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/get_cmc_service_request_model.dart @@ -1,19 +1,19 @@ class GetCMCServicesRequestModel { - int channel; - int deviceTypeID; - int genderID; - String generalid; - String identificationNo; - String iPAdress; - bool isDentalAllowedBackend; - int languageID; - int patientID; - int patientOutSA; - int patientType; - int patientTypeID; - String sessionID; - String tokenID; - double versionID; + int? channel; + int? deviceTypeID; + int? genderID; + String? generalid; + String? identificationNo; + String? iPAdress; + bool? isDentalAllowedBackend; + int? languageID; + int? patientID; + int? patientOutSA; + int? patientType; + int? patientTypeID; + String? sessionID; + String? tokenID; + double? versionID; GetCMCServicesRequestModel( {this.channel, diff --git a/lib/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/get_cmc_service_response_model.dart b/lib/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/get_cmc_service_response_model.dart index 5f356e2b..38741b14 100644 --- a/lib/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/get_cmc_service_response_model.dart +++ b/lib/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/get_cmc_service_response_model.dart @@ -1,44 +1,56 @@ class GetCMCServicesResponseModel { - String description; - String descriptionN; - int iD; - bool isActive; + int? iD; + String? serviceID; + int? orderServiceID; + String? text; + String? textN; dynamic price; - int serviceID; - dynamic totalPrice; - dynamic vAT; + dynamic priceVAT; + dynamic priceTotal; + bool? isEnabled; + int? orderId; + int? quantity; GetCMCServicesResponseModel( - {this.description, - this.descriptionN, - this.iD, - this.isActive, - this.price, + {this.iD, this.serviceID, - this.totalPrice, - this.vAT}); + this.orderServiceID, + this.text, + this.textN, + this.price, + this.priceVAT, + this.priceTotal, + this.isEnabled, + this.orderId, + this.quantity}); GetCMCServicesResponseModel.fromJson(Map json) { - description = json['Description']; - descriptionN = json['DescriptionN']; iD = json['ID']; - isActive = json['IsActive']; - price = json['Price']; serviceID = json['ServiceID']; - totalPrice = json['TotalPrice']; - vAT = json['VAT']; + orderServiceID = json['OrderServiceID']; + text = json['Text']; + textN = json['TextN']; + price = json['Price']; + priceVAT = json['PriceVAT']; + priceTotal = json['PriceTotal']; + isEnabled = json['IsEnabled']; + orderId = json['OrderId']; + quantity = json['Quantity']; } Map toJson() { final Map data = new Map(); - data['Description'] = this.description; - data['DescriptionN'] = this.descriptionN; data['ID'] = this.iD; - data['IsActive'] = this.isActive; - data['Price'] = this.price; data['ServiceID'] = this.serviceID; - data['TotalPrice'] = this.totalPrice; - data['VAT'] = this.vAT; + data['OrderServiceID'] = this.orderServiceID; + data['Text'] = this.text; + data['TextN'] = this.textN; + data['Price'] = this.price; + data['PriceVAT'] = this.priceVAT; + data['PriceTotal'] = this.priceTotal; + data['IsEnabled'] = this.isEnabled; + data['OrderId'] = this.orderId; + data['Quantity'] = this.quantity; return data; } } diff --git a/lib/core/model/AlHabibMedicalService/EReferral/check_activation_code_for_e_referral_request_model.dart b/lib/core/model/AlHabibMedicalService/EReferral/check_activation_code_for_e_referral_request_model.dart index 3f26abe7..d95ced18 100644 --- a/lib/core/model/AlHabibMedicalService/EReferral/check_activation_code_for_e_referral_request_model.dart +++ b/lib/core/model/AlHabibMedicalService/EReferral/check_activation_code_for_e_referral_request_model.dart @@ -1,15 +1,15 @@ class CheckActivationCodeForEReferralResponseModel { - String logInTokenID; - String activationCode; - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - Null sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; + String? logInTokenID; + String? activationCode; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + dynamic sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; CheckActivationCodeForEReferralResponseModel( {this.logInTokenID, diff --git a/lib/core/model/AlHabibMedicalService/EReferral/create_e_referral_request_model.dart b/lib/core/model/AlHabibMedicalService/EReferral/create_e_referral_request_model.dart index e13de327..b63ba8e8 100644 --- a/lib/core/model/AlHabibMedicalService/EReferral/create_e_referral_request_model.dart +++ b/lib/core/model/AlHabibMedicalService/EReferral/create_e_referral_request_model.dart @@ -1,60 +1,60 @@ class CreateEReferralRequestModel { - bool isInsuredPatient; - String cityCode; - String cityName; - String requesterName; - String requesterContactNo; - int requesterRelationship; - String otherRelationship; - String fullName; - int identificationNo; - String patientMobileNumber; - int preferredBranchCode; - String preferredBranchName; - List medicalReportAttachment; + bool? isInsuredPatient; + String? cityCode; + String? cityName; + String? requesterName; + String? requesterContactNo; + int? requesterRelationship; + String? otherRelationship; + String? fullName; + int? identificationNo; + String? patientMobileNumber; + int? preferredBranchCode; + String? preferredBranchName; + List? medicalReportAttachment; dynamic insuranceCardAttachment; - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - String sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; - int patientID; - String tokenID; - int patientTypeID; - int patientType; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + String? sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + int? patientID; + String? tokenID; + int? patientTypeID; + int? patientType; CreateEReferralRequestModel( {this.isInsuredPatient, - this.cityCode, - this.cityName, - this.requesterName, - this.requesterContactNo, - this.requesterRelationship, - this.otherRelationship, - this.fullName, - this.identificationNo, - this.patientMobileNumber, - this.preferredBranchCode, - this.preferredBranchName, - this.medicalReportAttachment, - this.insuranceCardAttachment, - this.versionID, - this.channel, - this.languageID, - this.iPAdress, - this.generalid, - this.patientOutSA, - this.sessionID, - this.isDentalAllowedBackend, - this.deviceTypeID, - this.patientID, - this.tokenID, - this.patientTypeID, - this.patientType}); + this.cityCode, + this.cityName, + this.requesterName, + this.requesterContactNo, + this.requesterRelationship, + this.otherRelationship, + this.fullName, + this.identificationNo, + this.patientMobileNumber, + this.preferredBranchCode, + this.preferredBranchName, + this.medicalReportAttachment, + this.insuranceCardAttachment, + this.versionID, + this.channel, + this.languageID, + this.iPAdress, + this.generalid, + this.patientOutSA, + this.sessionID, + this.isDentalAllowedBackend, + this.deviceTypeID, + this.patientID, + this.tokenID, + this.patientTypeID, + this.patientType}); CreateEReferralRequestModel.fromJson(Map json) { isInsuredPatient = json['IsInsuredPatient']; @@ -70,14 +70,12 @@ class CreateEReferralRequestModel { preferredBranchCode = json['PreferredBranchCode']; preferredBranchName = json['PreferredBranchName']; if (json['MedicalReportAttachment'] != null) { - medicalReportAttachment = new List(); + medicalReportAttachment = []; json['MedicalReportAttachment'].forEach((v) { - medicalReportAttachment.add(new EReferralAttachment.fromJson(v)); + medicalReportAttachment!.add(EReferralAttachment.fromJson(v)); }); } - insuranceCardAttachment = json['InsuranceCardAttachment'] != null - ? new EReferralAttachment.fromJson(json['InsuranceCardAttachment']) - : null; + insuranceCardAttachment = json['InsuranceCardAttachment'] != null ? EReferralAttachment.fromJson(json['InsuranceCardAttachment']) : null; versionID = json['VersionID']; channel = json['Channel']; languageID = json['LanguageID']; @@ -108,8 +106,7 @@ class CreateEReferralRequestModel { data['PreferredBranchCode'] = this.preferredBranchCode; data['PreferredBranchName'] = this.preferredBranchName; if (this.medicalReportAttachment != null) { - data['MedicalReportAttachment'] = - this.medicalReportAttachment.map((v) => v.toJson()).toList(); + data['MedicalReportAttachment'] = this.medicalReportAttachment!.map((v) => v.toJson()).toList(); } if (this.insuranceCardAttachment == null) { data['InsuranceCardAttachment'] = {}; @@ -134,8 +131,8 @@ class CreateEReferralRequestModel { } class EReferralAttachment { - String fileName; - String base64String; + String? fileName; + String? base64String; EReferralAttachment({this.fileName, this.base64String}); diff --git a/lib/core/model/AlHabibMedicalService/EReferral/get_all_cities_request_model.dart b/lib/core/model/AlHabibMedicalService/EReferral/get_all_cities_request_model.dart index dd46a48b..f2302b2a 100644 --- a/lib/core/model/AlHabibMedicalService/EReferral/get_all_cities_request_model.dart +++ b/lib/core/model/AlHabibMedicalService/EReferral/get_all_cities_request_model.dart @@ -1,13 +1,13 @@ class GetAllCitiesRequestModel { - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - Null sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + dynamic sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; GetAllCitiesRequestModel( {this.versionID, diff --git a/lib/core/model/AlHabibMedicalService/EReferral/get_all_cities_response_model.dart b/lib/core/model/AlHabibMedicalService/EReferral/get_all_cities_response_model.dart index 224cb84d..efc3d58c 100644 --- a/lib/core/model/AlHabibMedicalService/EReferral/get_all_cities_response_model.dart +++ b/lib/core/model/AlHabibMedicalService/EReferral/get_all_cities_response_model.dart @@ -1,7 +1,7 @@ class GetAllCitiesResponseModel { - int iD; - String description; - String descriptionN; + int? iD; + String? description; + String? descriptionN; GetAllCitiesResponseModel({this.iD, this.description, this.descriptionN}); diff --git a/lib/core/model/AlHabibMedicalService/EReferral/get_all_projects_response_model.dart b/lib/core/model/AlHabibMedicalService/EReferral/get_all_projects_response_model.dart index 438f1630..c3d3b2cb 100644 --- a/lib/core/model/AlHabibMedicalService/EReferral/get_all_projects_response_model.dart +++ b/lib/core/model/AlHabibMedicalService/EReferral/get_all_projects_response_model.dart @@ -1,20 +1,20 @@ class GetAllProjectsResponseModel { - String desciption; - Null desciptionN; - int iD; - String legalName; - String legalNameN; - String name; - Null nameN; - String phoneNumber; - String setupID; - int distanceInKilometers; - bool isActive; - String latitude; - String longitude; - int mainProjectID; - Null projectOutSA; - bool usingInDoctorApp; + String? desciption; + dynamic desciptionN; + int? iD; + String? legalName; + String? legalNameN; + String? name; + dynamic nameN; + String? phoneNumber; + String? setupID; + int? distanceInKilometers; + bool? isActive; + String? latitude; + String? longitude; + int? mainProjectID; + dynamic projectOutSA; + bool? usingInDoctorApp; GetAllProjectsResponseModel( {this.desciption, diff --git a/lib/core/model/AlHabibMedicalService/EReferral/get_all_relationship_types_request_model.dart b/lib/core/model/AlHabibMedicalService/EReferral/get_all_relationship_types_request_model.dart index 10eb03de..a85b74ac 100644 --- a/lib/core/model/AlHabibMedicalService/EReferral/get_all_relationship_types_request_model.dart +++ b/lib/core/model/AlHabibMedicalService/EReferral/get_all_relationship_types_request_model.dart @@ -1,13 +1,13 @@ class GetAllRelationshipTypeRequestModel { - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - Null sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + dynamic sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; GetAllRelationshipTypeRequestModel( {this.versionID, diff --git a/lib/core/model/AlHabibMedicalService/EReferral/get_all_relationship_types_response_model.dart b/lib/core/model/AlHabibMedicalService/EReferral/get_all_relationship_types_response_model.dart index 997e3f3c..237017d3 100644 --- a/lib/core/model/AlHabibMedicalService/EReferral/get_all_relationship_types_response_model.dart +++ b/lib/core/model/AlHabibMedicalService/EReferral/get_all_relationship_types_response_model.dart @@ -1,8 +1,8 @@ class GetAllRelationshipTypeResponseModel { - int iD; - String text; - String textAr; - String textEn; + int? iD; + String? text; + String? textAr; + String? textEn; GetAllRelationshipTypeResponseModel( {this.iD, this.text, this.textAr, this.textEn}); diff --git a/lib/core/model/AlHabibMedicalService/EReferral/get_ereferral_response_model.dart b/lib/core/model/AlHabibMedicalService/EReferral/get_ereferral_response_model.dart index e873261d..e80e7d90 100644 --- a/lib/core/model/AlHabibMedicalService/EReferral/get_ereferral_response_model.dart +++ b/lib/core/model/AlHabibMedicalService/EReferral/get_ereferral_response_model.dart @@ -2,54 +2,53 @@ class GetEReferralResponseModel { dynamic acceptedBrachCode; dynamic acceptedBranchName; dynamic acceptedBranchNameAr; - Channel channel; + Channel? channel; dynamic identityCardAttachment; - String identityNumber; + String? identityNumber; dynamic insuranceCardAttachment; - bool isInsuredPatient; - String otherRelationship; - String patientContactNo; - int patientId; - String patientName; - int preferredBranchCode; - String preferredBranchName; - String referralDate; - int referralNumber; - Channel relationshipType; - String requesterContactNo; - String requesterName; - String status; - String statusAr; + bool? isInsuredPatient; + String? otherRelationship; + String? patientContactNo; + int? patientId; + String? patientName; + int? preferredBranchCode; + String? preferredBranchName; + String? referralDate; + int? referralNumber; + Channel? relationshipType; + String? requesterContactNo; + String? requesterName; + String? status; + String? statusAr; GetEReferralResponseModel( {this.acceptedBrachCode, - this.acceptedBranchName, - this.acceptedBranchNameAr, - this.channel, - this.identityCardAttachment, - this.identityNumber, - this.insuranceCardAttachment, - this.isInsuredPatient, - this.otherRelationship, - this.patientContactNo, - this.patientId, - this.patientName, - this.preferredBranchCode, - this.preferredBranchName, - this.referralDate, - this.referralNumber, - this.relationshipType, - this.requesterContactNo, - this.requesterName, - this.status, - this.statusAr}); + this.acceptedBranchName, + this.acceptedBranchNameAr, + this.channel, + this.identityCardAttachment, + this.identityNumber, + this.insuranceCardAttachment, + this.isInsuredPatient, + this.otherRelationship, + this.patientContactNo, + this.patientId, + this.patientName, + this.preferredBranchCode, + this.preferredBranchName, + this.referralDate, + this.referralNumber, + this.relationshipType, + this.requesterContactNo, + this.requesterName, + this.status, + this.statusAr}); GetEReferralResponseModel.fromJson(Map json) { acceptedBrachCode = json['AcceptedBrachCode']; acceptedBranchName = json['AcceptedBranchName']; acceptedBranchNameAr = json['AcceptedBranchNameAr']; - channel = - json['Channel'] != null ? new Channel.fromJson(json['Channel']) : null; + channel = json['Channel'] != null ? new Channel.fromJson(json['Channel']) : null; identityCardAttachment = json['IdentityCardAttachment']; identityNumber = json['IdentityNumber']; insuranceCardAttachment = json['InsuranceCardAttachment']; @@ -62,9 +61,7 @@ class GetEReferralResponseModel { preferredBranchName = json['PreferredBranchName']; referralDate = json['ReferralDate']; referralNumber = json['ReferralNumber']; - relationshipType = json['RelationshipType'] != null - ? new Channel.fromJson(json['RelationshipType']) - : null; + relationshipType = json['RelationshipType'] != null ? new Channel.fromJson(json['RelationshipType']) : null; requesterContactNo = json['RequesterContactNo']; requesterName = json['RequesterName']; status = json['Status']; @@ -77,7 +74,7 @@ class GetEReferralResponseModel { data['AcceptedBranchName'] = this.acceptedBranchName; data['AcceptedBranchNameAr'] = this.acceptedBranchNameAr; if (this.channel != null) { - data['Channel'] = this.channel.toJson(); + data['Channel'] = this.channel!.toJson(); } data['IdentityCardAttachment'] = this.identityCardAttachment; data['IdentityNumber'] = this.identityNumber; @@ -92,7 +89,7 @@ class GetEReferralResponseModel { data['ReferralDate'] = this.referralDate; data['ReferralNumber'] = this.referralNumber; if (this.relationshipType != null) { - data['RelationshipType'] = this.relationshipType.toJson(); + data['RelationshipType'] = this.relationshipType!.toJson(); } data['RequesterContactNo'] = this.requesterContactNo; data['RequesterName'] = this.requesterName; @@ -103,10 +100,10 @@ class GetEReferralResponseModel { } class Channel { - int iD; - String text; - String textAr; - String textEn; + int? iD; + String? text; + String? textAr; + String? textEn; Channel({this.iD, this.text, this.textAr, this.textEn}); diff --git a/lib/core/model/AlHabibMedicalService/EReferral/search_criteria_model.dart b/lib/core/model/AlHabibMedicalService/EReferral/search_criteria_model.dart index 3ddbe331..db73b395 100644 --- a/lib/core/model/AlHabibMedicalService/EReferral/search_criteria_model.dart +++ b/lib/core/model/AlHabibMedicalService/EReferral/search_criteria_model.dart @@ -1,7 +1,7 @@ class SearchCriteriaModel { - String name; - String nameAr; - int value; + String? name; + String? nameAr; + int? value; SearchCriteriaModel({this.name, this.nameAr, this.value}); diff --git a/lib/core/model/AlHabibMedicalService/EReferral/search_e_referral_request_model.dart b/lib/core/model/AlHabibMedicalService/EReferral/search_e_referral_request_model.dart index b06ce8e7..deb3a92d 100644 --- a/lib/core/model/AlHabibMedicalService/EReferral/search_e_referral_request_model.dart +++ b/lib/core/model/AlHabibMedicalService/EReferral/search_e_referral_request_model.dart @@ -1,16 +1,16 @@ class SearchEReferralRequestModel { - String patientMobileNumber; - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - Null sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; - int referralNumber; - String identificationNo; + String? patientMobileNumber; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + dynamic sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + int? referralNumber; + String? identificationNo; SearchEReferralRequestModel( {this.patientMobileNumber, diff --git a/lib/core/model/AlHabibMedicalService/EReferral/search_e_referral_response_model.dart b/lib/core/model/AlHabibMedicalService/EReferral/search_e_referral_response_model.dart index 801d8e13..6a1b4e8d 100644 --- a/lib/core/model/AlHabibMedicalService/EReferral/search_e_referral_response_model.dart +++ b/lib/core/model/AlHabibMedicalService/EReferral/search_e_referral_response_model.dart @@ -1,60 +1,128 @@ class SearchEReferralResponseModel { - String patientMobileNumber; - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - Null sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; - int referralNumber; - String identificationNo; + dynamic acceptedBrachCode; + dynamic acceptedBranchName; + dynamic acceptedBranchNameAr; + dynamic channel; + dynamic identityCardAttachment; + String? identityNumber; + dynamic insuranceCardAttachment; + bool? isInsuredPatient; + List? medicalReportAttachment; + String? otherRelationship; + String? patientContactNo; + int? patientId; + String? patientName; + int? preferredBranchCode; + String? preferredBranchName; + String? referralDate; + int? referralNumber; + RelationshipType? relationshipType; + String? requesterContactNo; + String? requesterName; + String? status; + String? statusAr; SearchEReferralResponseModel( - {this.patientMobileNumber, - this.versionID, - this.channel, - this.languageID, - this.iPAdress, - this.generalid, - this.patientOutSA, - this.sessionID, - this.isDentalAllowedBackend, - this.deviceTypeID, - this.referralNumber, - this.identificationNo}); + {this.acceptedBrachCode, + this.acceptedBranchName, + this.acceptedBranchNameAr, + this.channel, + this.identityCardAttachment, + this.identityNumber, + this.insuranceCardAttachment, + this.isInsuredPatient, + this.medicalReportAttachment, + this.otherRelationship, + this.patientContactNo, + this.patientId, + this.patientName, + this.preferredBranchCode, + this.preferredBranchName, + this.referralDate, + this.referralNumber, + this.relationshipType, + this.requesterContactNo, + this.requesterName, + this.status, + this.statusAr}); SearchEReferralResponseModel.fromJson(Map json) { - patientMobileNumber = json['PatientMobileNumber']; - versionID = json['VersionID']; + acceptedBrachCode = json['AcceptedBrachCode']; + acceptedBranchName = json['AcceptedBranchName']; + acceptedBranchNameAr = json['AcceptedBranchNameAr']; channel = json['Channel']; - languageID = json['LanguageID']; - iPAdress = json['IPAdress']; - generalid = json['generalid']; - patientOutSA = json['PatientOutSA']; - sessionID = json['SessionID']; - isDentalAllowedBackend = json['isDentalAllowedBackend']; - deviceTypeID = json['DeviceTypeID']; + identityCardAttachment = json['IdentityCardAttachment']; + identityNumber = json['IdentityNumber']; + insuranceCardAttachment = json['InsuranceCardAttachment']; + isInsuredPatient = json['IsInsuredPatient']; + otherRelationship = json['OtherRelationship']; + patientContactNo = json['PatientContactNo']; + patientId = json['PatientId']; + patientName = json['PatientName']; + preferredBranchCode = json['PreferredBranchCode']; + preferredBranchName = json['PreferredBranchName']; + referralDate = json['ReferralDate']; referralNumber = json['ReferralNumber']; - identificationNo = json['IdentificationNo']; + relationshipType = json['RelationshipType'] != null ? new RelationshipType.fromJson(json['RelationshipType']) : null; + requesterContactNo = json['RequesterContactNo']; + requesterName = json['RequesterName']; + status = json['Status']; + statusAr = json['StatusAr']; } Map toJson() { final Map data = new Map(); - data['PatientMobileNumber'] = this.patientMobileNumber; - data['VersionID'] = this.versionID; + data['AcceptedBrachCode'] = this.acceptedBrachCode; + data['AcceptedBranchName'] = this.acceptedBranchName; + data['AcceptedBranchNameAr'] = this.acceptedBranchNameAr; data['Channel'] = this.channel; - data['LanguageID'] = this.languageID; - data['IPAdress'] = this.iPAdress; - data['generalid'] = this.generalid; - data['PatientOutSA'] = this.patientOutSA; - data['SessionID'] = this.sessionID; - data['isDentalAllowedBackend'] = this.isDentalAllowedBackend; - data['DeviceTypeID'] = this.deviceTypeID; + data['IdentityCardAttachment'] = this.identityCardAttachment; + data['IdentityNumber'] = this.identityNumber; + data['InsuranceCardAttachment'] = this.insuranceCardAttachment; + data['IsInsuredPatient'] = this.isInsuredPatient; + if (this.medicalReportAttachment != null) { + data['MedicalReportAttachment'] = this.medicalReportAttachment!.map((v) => v.toJson()).toList(); + } + data['OtherRelationship'] = this.otherRelationship; + data['PatientContactNo'] = this.patientContactNo; + data['PatientId'] = this.patientId; + data['PatientName'] = this.patientName; + data['PreferredBranchCode'] = this.preferredBranchCode; + data['PreferredBranchName'] = this.preferredBranchName; + data['ReferralDate'] = this.referralDate; data['ReferralNumber'] = this.referralNumber; - data['IdentificationNo'] = this.identificationNo; + if (this.relationshipType != dynamic) { + data['RelationshipType'] = this.relationshipType!.toJson(); + } + data['RequesterContactNo'] = this.requesterContactNo; + data['RequesterName'] = this.requesterName; + data['Status'] = this.status; + data['StatusAr'] = this.statusAr; + return data; + } +} + +class RelationshipType { + int? iD; + String? text; + String? textAr; + String? textEn; + + RelationshipType({this.iD, this.text, this.textAr, this.textEn}); + + RelationshipType.fromJson(Map json) { + iD = json['ID']; + text = json['Text']; + textAr = json['Text_Ar']; + textEn = json['Text_En']; + } + + Map toJson() { + final Map data = new Map(); + data['ID'] = this.iD; + data['Text'] = this.text; + data['Text_Ar'] = this.textAr; + data['Text_En'] = this.textEn; return data; } } diff --git a/lib/core/model/AlHabibMedicalService/EReferral/send_activation_code_for_e_referral_request_model.dart b/lib/core/model/AlHabibMedicalService/EReferral/send_activation_code_for_e_referral_request_model.dart index 622ef143..43e4c2eb 100644 --- a/lib/core/model/AlHabibMedicalService/EReferral/send_activation_code_for_e_referral_request_model.dart +++ b/lib/core/model/AlHabibMedicalService/EReferral/send_activation_code_for_e_referral_request_model.dart @@ -1,31 +1,30 @@ class SendActivationCodeForEReferralRequestModel { - int patientMobileNumber; - String zipCode; - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - Null sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; + int? patientMobileNumber; + String? zipCode; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + dynamic sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; SendActivationCodeForEReferralRequestModel( {this.patientMobileNumber, - this.zipCode, - this.versionID, - this.channel, - this.languageID, - this.iPAdress, - this.generalid, - this.patientOutSA, - this.sessionID, - this.isDentalAllowedBackend, - this.deviceTypeID}); + this.zipCode, + this.versionID, + this.channel, + this.languageID, + this.iPAdress, + this.generalid, + this.patientOutSA, + this.sessionID, + this.isDentalAllowedBackend, + this.deviceTypeID}); - SendActivationCodeForEReferralRequestModel.fromJson( - Map json) { + SendActivationCodeForEReferralRequestModel.fromJson(Map json) { patientMobileNumber = json['PatientMobileNumber']; zipCode = json['ZipCode']; versionID = json['VersionID']; diff --git a/lib/core/model/AlHabibMedicalService/H2O/insert_user_activity_request_model.dart b/lib/core/model/AlHabibMedicalService/H2O/insert_user_activity_request_model.dart index 2d27729b..f2dc41d1 100644 --- a/lib/core/model/AlHabibMedicalService/H2O/insert_user_activity_request_model.dart +++ b/lib/core/model/AlHabibMedicalService/H2O/insert_user_activity_request_model.dart @@ -1,20 +1,20 @@ class InsertUserActivityRequestModel { - String identificationNo; - String mobileNumber; - int quantityIntake; - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - String sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; - int patientID; - String tokenID; - int patientTypeID; - int patientType; + String? identificationNo; + String? mobileNumber; + int? quantityIntake; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + String? sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + int? patientID; + String? tokenID; + int? patientTypeID; + int? patientType; InsertUserActivityRequestModel( {this.identificationNo, diff --git a/lib/core/model/AlHabibMedicalService/H2O/user_detail_model.dart b/lib/core/model/AlHabibMedicalService/H2O/user_detail_model.dart index bb100219..dd76ccf2 100644 --- a/lib/core/model/AlHabibMedicalService/H2O/user_detail_model.dart +++ b/lib/core/model/AlHabibMedicalService/H2O/user_detail_model.dart @@ -1,27 +1,27 @@ class UserDetailModel { - int userID; - int patientID; - int patientType; - bool patientOutSA; - String firstName; - String middleName; - String lastName; - String firstNameN; - String middleNameN; - String lastNameN; - String identificationNo; - String mobile; - String emailID; - String zipCode; - String dOB; - String gender; - int activityID; - String createdDate; - double height; - double weight; - bool isHeightInCM; - bool isWeightInKG; - bool isNotificationON; + int? userID; + int? patientID; + int? patientType; + bool? patientOutSA; + String? firstName; + String? middleName; + String? lastName; + String? firstNameN; + String? middleNameN; + String? lastNameN; + String? identificationNo; + String? mobile; + String? emailID; + String? zipCode; + String? dOB; + String? gender; + int? activityID; + String? createdDate; + double? height; + double? weight; + bool? isHeightInCM; + bool? isWeightInKG; + bool? isNotificationON; UserDetailModel( {this.userID, @@ -49,6 +49,7 @@ class UserDetailModel { this.isNotificationON}); UserDetailModel.fromJson(Map json) { + if (json == null) return; userID = json['UserID']; patientID = json['PatientID']; patientType = json['PatientType']; diff --git a/lib/core/model/AlHabibMedicalService/H2O/user_detail_request_model.dart b/lib/core/model/AlHabibMedicalService/H2O/user_detail_request_model.dart index 9d23d383..44ef6471 100644 --- a/lib/core/model/AlHabibMedicalService/H2O/user_detail_request_model.dart +++ b/lib/core/model/AlHabibMedicalService/H2O/user_detail_request_model.dart @@ -1,32 +1,32 @@ class UserDetailRequestModel { - String activityID; - int channel; - int deviceTypeID; - String dOB; - String email; - String firstName; - String gender; - String generalid; - double height; - String identificationNo; - String iPAdress; - bool isDentalAllowedBackend; - bool isHeightInCM; - bool isNotificationOn; - bool isWeightInKG; - int languageID; - String lastName; - String middleName; - String mobileNumber; - int patientID; - int patientOutSA; - int patientType; - int patientTypeID; - String sessionID; - String tokenID; - double versionID; - double weight; - String zipCode; + String? activityID; + int? channel; + int? deviceTypeID; + String? dOB; + String? email; + String? firstName; + String? gender; + String? generalid; + double? height; + String? identificationNo; + String? iPAdress; + bool? isDentalAllowedBackend; + bool? isHeightInCM; + bool? isNotificationOn; + bool? isWeightInKG; + int? languageID; + String? lastName; + String? middleName; + String? mobileNumber; + int? patientID; + int? patientOutSA; + int? patientType; + int? patientTypeID; + String? sessionID; + String? tokenID; + double? versionID; + double? weight; + String? zipCode; UserDetailRequestModel( {this.activityID, diff --git a/lib/core/model/AlHabibMedicalService/H2O/user_progress_for_month_data_model.dart b/lib/core/model/AlHabibMedicalService/H2O/user_progress_for_month_data_model.dart index a7f7805e..fc961dd9 100644 --- a/lib/core/model/AlHabibMedicalService/H2O/user_progress_for_month_data_model.dart +++ b/lib/core/model/AlHabibMedicalService/H2O/user_progress_for_month_data_model.dart @@ -1,7 +1,7 @@ class UserProgressForMonthDataModel { - int monthNumber; - String monthName; - int percentageConsumed; + int? monthNumber; + String? monthName; + int? percentageConsumed; UserProgressForMonthDataModel( {this.monthNumber, this.monthName, this.percentageConsumed}); diff --git a/lib/core/model/AlHabibMedicalService/H2O/user_progress_for_week_data_model.dart b/lib/core/model/AlHabibMedicalService/H2O/user_progress_for_week_data_model.dart index 2641a678..84655dc8 100644 --- a/lib/core/model/AlHabibMedicalService/H2O/user_progress_for_week_data_model.dart +++ b/lib/core/model/AlHabibMedicalService/H2O/user_progress_for_week_data_model.dart @@ -1,8 +1,8 @@ class UserProgressForWeekDataModel { - int dayNumber; + int? dayNumber; dynamic dayDate; - String dayName; - int percentageConsumed; + String? dayName; + int? percentageConsumed; UserProgressForWeekDataModel( {this.dayNumber, this.dayDate, this.dayName, this.percentageConsumed}); diff --git a/lib/core/model/AlHabibMedicalService/H2O/user_progress_request_model.dart b/lib/core/model/AlHabibMedicalService/H2O/user_progress_request_model.dart index d06e053b..b004162a 100644 --- a/lib/core/model/AlHabibMedicalService/H2O/user_progress_request_model.dart +++ b/lib/core/model/AlHabibMedicalService/H2O/user_progress_request_model.dart @@ -1,20 +1,20 @@ class UserProgressRequestModel { - int progress; - String mobileNumber; - String identificationNo; - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - String sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; - int patientID; - String tokenID; - int patientTypeID; - int patientType; + int? progress; + String? mobileNumber; + String? identificationNo; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + String? sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + int? patientID; + String? tokenID; + int? patientTypeID; + int? patientType; UserProgressRequestModel( {this.progress, diff --git a/lib/core/model/AlHabibMedicalService/HealthCalculator/ClinicCategory.dart b/lib/core/model/AlHabibMedicalService/HealthCalculator/ClinicCategory.dart index ff1f0eb0..dbc6b990 100644 --- a/lib/core/model/AlHabibMedicalService/HealthCalculator/ClinicCategory.dart +++ b/lib/core/model/AlHabibMedicalService/HealthCalculator/ClinicCategory.dart @@ -1,18 +1,18 @@ class ClinicCategory { - int clinicID; - int categoryID; - String categoryName; - String categoryNameN; - String icon; - String bodyImageEN; - String fullImageEN; - String bodyImageAR; - String fullmageAR; - bool isActive; - bool isCategoryGroup; - Null sortOrderAR; - Null sortOrderEN; - String clinicName; + int? clinicID; + int? categoryID; + String? categoryName; + String? categoryNameN; + String? icon; + String? bodyImageEN; + String? fullImageEN; + String? bodyImageAR; + String? fullmageAR; + bool? isActive; + bool? isCategoryGroup; + dynamic sortOrderAR; + dynamic sortOrderEN; + String? clinicName; ClinicCategory( {this.clinicID, diff --git a/lib/core/model/AlHabibMedicalService/HealthCalculator/DiseasesByClinic.dart b/lib/core/model/AlHabibMedicalService/HealthCalculator/DiseasesByClinic.dart index e92fa8da..04e839ec 100644 --- a/lib/core/model/AlHabibMedicalService/HealthCalculator/DiseasesByClinic.dart +++ b/lib/core/model/AlHabibMedicalService/HealthCalculator/DiseasesByClinic.dart @@ -1,12 +1,12 @@ class DiseasesByClinic { - int diseasesID; - String diseasesEN; - String diseasesAR; - int diseasesCategoryID; - Null diseasesCategoryEN; - Null diseasesCategoryAR; - String diseases; - Null diseasesCategory; + int? diseasesID; + String? diseasesEN; + String? diseasesAR; + int? diseasesCategoryID; + dynamic diseasesCategoryEN; + dynamic diseasesCategoryAR; + String? diseases; + dynamic diseasesCategory; DiseasesByClinic( {this.diseasesID, diff --git a/lib/core/model/AlHabibMedicalService/HomeHealthCare/HHC_get_all_services_request_modle.dart b/lib/core/model/AlHabibMedicalService/HomeHealthCare/HHC_get_all_services_request_modle.dart index 7b24c149..bf56a750 100644 --- a/lib/core/model/AlHabibMedicalService/HomeHealthCare/HHC_get_all_services_request_modle.dart +++ b/lib/core/model/AlHabibMedicalService/HomeHealthCare/HHC_get_all_services_request_modle.dart @@ -1,17 +1,17 @@ class HHCGetAllServicesRequestModel { - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - String sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; - int patientID; - String tokenID; - int patientTypeID; - int patientType; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + String? sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + int? patientID; + String? tokenID; + int? patientTypeID; + int? patientType; HHCGetAllServicesRequestModel( {this.versionID, diff --git a/lib/core/model/AlHabibMedicalService/HomeHealthCare/HHC_get_all_services_response_model.dart b/lib/core/model/AlHabibMedicalService/HomeHealthCare/HHC_get_all_services_response_model.dart index e2f39733..19148546 100644 --- a/lib/core/model/AlHabibMedicalService/HomeHealthCare/HHC_get_all_services_response_model.dart +++ b/lib/core/model/AlHabibMedicalService/HomeHealthCare/HHC_get_all_services_response_model.dart @@ -1,32 +1,56 @@ class HHCGetAllServicesResponseModel { - int iD; - int serviceID; - String description; - String descriptionN; - bool isActive; + int? iD; + String? serviceID; + int? orderServiceID; + String? text; + String? textN; + dynamic price; + dynamic priceVAT; + dynamic priceTotal; + bool? isEnabled; + int? orderId; + int? quantity; HHCGetAllServicesResponseModel( {this.iD, this.serviceID, - this.description, - this.descriptionN, - this.isActive}); + this.orderServiceID, + this.text, + this.textN, + this.price, + this.priceVAT, + this.priceTotal, + this.isEnabled, + this.orderId, + this.quantity}); HHCGetAllServicesResponseModel.fromJson(Map json) { iD = json['ID']; serviceID = json['ServiceID']; - description = json['Description']; - descriptionN = json['DescriptionN']; - isActive = json['IsActive']; + orderServiceID = json['OrderServiceID']; + text = json['Text']; + textN = json['TextN']; + price = json['Price']; + priceVAT = json['PriceVAT']; + priceTotal = json['PriceTotal']; + isEnabled = json['IsEnabled']; + orderId = json['OrderId']; + quantity = json['Quantity']; } Map toJson() { final Map data = new Map(); data['ID'] = this.iD; data['ServiceID'] = this.serviceID; - data['Description'] = this.description; - data['DescriptionN'] = this.descriptionN; - data['IsActive'] = this.isActive; + data['OrderServiceID'] = this.orderServiceID; + data['Text'] = this.text; + data['TextN'] = this.textN; + data['Price'] = this.price; + data['PriceVAT'] = this.priceVAT; + data['PriceTotal'] = this.priceTotal; + data['IsEnabled'] = this.isEnabled; + data['OrderId'] = this.orderId; + data['Quantity'] = this.quantity; return data; } } diff --git a/lib/core/model/AlHabibMedicalService/HomeHealthCare/PatientERHHCInsertServicesList.dart b/lib/core/model/AlHabibMedicalService/HomeHealthCare/PatientERHHCInsertServicesList.dart index bc5a4ddf..95b7ba83 100644 --- a/lib/core/model/AlHabibMedicalService/HomeHealthCare/PatientERHHCInsertServicesList.dart +++ b/lib/core/model/AlHabibMedicalService/HomeHealthCare/PatientERHHCInsertServicesList.dart @@ -1,11 +1,9 @@ - class PatientERHHCInsertServicesList { - int recordID; - int serviceID; - String serviceName; + int? recordID; + int? serviceID; + String? serviceName; - PatientERHHCInsertServicesList( - {this.recordID, this.serviceID, this.serviceName}); + PatientERHHCInsertServicesList({this.recordID, this.serviceID, this.serviceName}); PatientERHHCInsertServicesList.fromJson(Map json) { recordID = json['RecordID']; @@ -16,7 +14,7 @@ class PatientERHHCInsertServicesList { Map toJson() { final Map data = new Map(); data['RecordID'] = this.recordID; - data['ServiceID'] = this.serviceID; + data['ServiceID'] = this.serviceID.toString(); data['ServiceName'] = this.serviceName; return data; } diff --git a/lib/core/model/AlHabibMedicalService/HomeHealthCare/get_hhc_all_pres_orders_request_model.dart b/lib/core/model/AlHabibMedicalService/HomeHealthCare/get_hhc_all_pres_orders_request_model.dart index ed55b3a9..00b907e0 100644 --- a/lib/core/model/AlHabibMedicalService/HomeHealthCare/get_hhc_all_pres_orders_request_model.dart +++ b/lib/core/model/AlHabibMedicalService/HomeHealthCare/get_hhc_all_pres_orders_request_model.dart @@ -1,32 +1,32 @@ class GetHHCAllPresOrdersRequestModel { - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - String sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; - int patientID; - String tokenID; - int patientTypeID; - int patientType; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + String? sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + int? patientID; + String? tokenID; + int? patientTypeID; + int? patientType; GetHHCAllPresOrdersRequestModel( {this.versionID, - this.channel, - this.languageID, - this.iPAdress, - this.generalid, - this.patientOutSA, - this.sessionID, - this.isDentalAllowedBackend, - this.deviceTypeID, - this.patientID, - this.tokenID, - this.patientTypeID, - this.patientType}); + this.channel, + this.languageID, + this.iPAdress, + this.generalid, + this.patientOutSA, + this.sessionID, + this.isDentalAllowedBackend, + this.deviceTypeID, + this.patientID, + this.tokenID, + this.patientTypeID, + this.patientType}); GetHHCAllPresOrdersRequestModel.fromJson(Map json) { versionID = json['VersionID']; diff --git a/lib/core/model/AlHabibMedicalService/HomeHealthCare/get_hhc_all_pres_orders_response_model.dart b/lib/core/model/AlHabibMedicalService/HomeHealthCare/get_hhc_all_pres_orders_response_model.dart index 5dedac1c..1333c218 100644 --- a/lib/core/model/AlHabibMedicalService/HomeHealthCare/get_hhc_all_pres_orders_response_model.dart +++ b/lib/core/model/AlHabibMedicalService/HomeHealthCare/get_hhc_all_pres_orders_response_model.dart @@ -1,34 +1,34 @@ class GetHHCAllPresOrdersResponseModel { - int iD; - String patientID; - bool patientOutSA; - bool isOutPatient; - int projectID; - int nearestProjectID; - double longitude; - double latitude; - String appointmentNo; - String dischargeID; - int lineItemNo; - int status; - String description; - String descriptionN; - String createdOn; - int serviceID; - int createdBy; - String editedOn; - int editedBy; - int channel; + int? iD; + String? patientID; + bool? patientOutSA; + bool? isOutPatient; + int? projectID; + int? nearestProjectID; + double? longitude; + double? latitude; + String? appointmentNo; + String? dischargeID; + int? lineItemNo; + int? status; + String? description; + String? descriptionN; + String? createdOn; + int? serviceID; + int? createdBy; + String? editedOn; + int? editedBy; + int? channel; dynamic clientRequestID; - bool returnedToQueue; + bool? returnedToQueue; dynamic pickupDateTime; dynamic pickupLocationName; dynamic dropoffLocationName; - int realRRTHaveTransactions; - String nearestProjectDescription; - String nearestProjectDescriptionN; - String projectDescription; - String projectDescriptionN; + int? realRRTHaveTransactions; + String? nearestProjectDescription; + String? nearestProjectDescriptionN; + String? projectDescription; + String? projectDescriptionN; GetHHCAllPresOrdersResponseModel( {this.iD, diff --git a/lib/core/model/AlHabibMedicalService/HomeHealthCare/get_order_detail_by_order_iD_request_model.dart b/lib/core/model/AlHabibMedicalService/HomeHealthCare/get_order_detail_by_order_iD_request_model.dart index 04b69b98..62af618e 100644 --- a/lib/core/model/AlHabibMedicalService/HomeHealthCare/get_order_detail_by_order_iD_request_model.dart +++ b/lib/core/model/AlHabibMedicalService/HomeHealthCare/get_order_detail_by_order_iD_request_model.dart @@ -1,18 +1,18 @@ class GetOrderDetailByOrderIDRequestModel { - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - String sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; - int patientID; - String tokenID; - int patientTypeID; - int patientType; - int presOrderID; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + String? sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + int? patientID; + String? tokenID; + int? patientTypeID; + int? patientType; + int? presOrderID; GetOrderDetailByOrderIDRequestModel( {this.versionID, diff --git a/lib/core/model/AlHabibMedicalService/HomeHealthCare/get_order_detail_by_order_iD_response_model.dart b/lib/core/model/AlHabibMedicalService/HomeHealthCare/get_order_detail_by_order_iD_response_model.dart index 6fc31ce8..d26af589 100644 --- a/lib/core/model/AlHabibMedicalService/HomeHealthCare/get_order_detail_by_order_iD_response_model.dart +++ b/lib/core/model/AlHabibMedicalService/HomeHealthCare/get_order_detail_by_order_iD_response_model.dart @@ -1,14 +1,14 @@ class GetOrderDetailByOrderIDResponseModel { - int iD; - int presOrderID; - int hHCServiceID; - int createdBy; - String createdOn; - int editedBy; - String editedOn; - bool isActive; - String description; - String descriptionN; + int? iD; + int? presOrderID; + int? hHCServiceID; + int? createdBy; + String? createdOn; + int? editedBy; + String? editedOn; + bool? isActive; + String? description; + String? descriptionN; GetOrderDetailByOrderIDResponseModel( {this.iD, diff --git a/lib/core/model/AlHabibMedicalService/HomeHealthCare/patient_er_insert_pres_order_request_model.dart b/lib/core/model/AlHabibMedicalService/HomeHealthCare/patient_er_insert_pres_order_request_model.dart index 6987ee44..e8da3ed6 100644 --- a/lib/core/model/AlHabibMedicalService/HomeHealthCare/patient_er_insert_pres_order_request_model.dart +++ b/lib/core/model/AlHabibMedicalService/HomeHealthCare/patient_er_insert_pres_order_request_model.dart @@ -1,45 +1,44 @@ import 'PatientERHHCInsertServicesList.dart'; class PatientERInsertPresOrderRequestModel { - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - String sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; - int patientID; - String tokenID; - int patientTypeID; - int patientType; - double latitude; - double longitude; - int createdBy; - int orderServiceID; - List patientERHHCInsertServicesList = List(); + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + String? sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + int? patientID; + String? tokenID; + int? patientTypeID; + int? patientType; + double? latitude; + double? longitude; + int? createdBy; + int? orderServiceID; + List? patientERHHCInsertServicesList = []; PatientERInsertPresOrderRequestModel( {this.versionID, - this.channel, - this.languageID, - this.iPAdress, - this.generalid, - this.patientOutSA, - this.sessionID, - this.isDentalAllowedBackend, - this.deviceTypeID, - this.patientID, - this.tokenID, - this.patientTypeID, - this.patientType, - this.latitude, - this.longitude, - this.createdBy, - this.orderServiceID, - this.patientERHHCInsertServicesList - }); + this.channel, + this.languageID, + this.iPAdress, + this.generalid, + this.patientOutSA, + this.sessionID, + this.isDentalAllowedBackend, + this.deviceTypeID, + this.patientID, + this.tokenID, + this.patientTypeID, + this.patientType, + this.latitude, + this.longitude, + this.createdBy, + this.orderServiceID, + this.patientERHHCInsertServicesList}); PatientERInsertPresOrderRequestModel.fromJson(Map json) { versionID = json['VersionID']; @@ -60,11 +59,9 @@ class PatientERInsertPresOrderRequestModel { createdBy = json['CreatedBy']; orderServiceID = json['OrderServiceID']; if (json['PatientER_HHC_InsertServicesList'] != null) { - patientERHHCInsertServicesList = - new List(); + patientERHHCInsertServicesList = []; json['PatientER_HHC_InsertServicesList'].forEach((v) { - patientERHHCInsertServicesList - .add(new PatientERHHCInsertServicesList.fromJson(v)); + patientERHHCInsertServicesList!.add(new PatientERHHCInsertServicesList.fromJson(v)); }); } } @@ -76,7 +73,8 @@ class PatientERInsertPresOrderRequestModel { data['LanguageID'] = this.languageID; data['IPAdress'] = this.iPAdress; data['generalid'] = this.generalid; - data['PatientOutSA'] = this.patientOutSA; + data['isOutPatient'] = this.patientOutSA == 0 ? false : true; + // data['PatientOutSA'] = this.patientOutSA; data['SessionID'] = this.sessionID; data['isDentalAllowedBackend'] = this.isDentalAllowedBackend; data['DeviceTypeID'] = this.deviceTypeID; @@ -84,13 +82,12 @@ class PatientERInsertPresOrderRequestModel { data['TokenID'] = this.tokenID; data['PatientTypeID'] = this.patientTypeID; data['PatientType'] = this.patientType; - data['Latitude'] = this.latitude; - data['Longitude'] = this.longitude; - data['CreatedBy'] = this.createdBy; + data['latitude'] = this.latitude; + data['longitude'] = this.longitude; + // data['CreatedBy'] = this.createdBy; data['OrderServiceID'] = this.orderServiceID; if (this.patientERHHCInsertServicesList != null) { - data['PatientER_HHC_InsertServicesList'] = - this.patientERHHCInsertServicesList.map((v) => v.toJson()).toList(); + data['procedures'] = this.patientERHHCInsertServicesList!.map((v) => v.toJson()).toList(); } return data; } diff --git a/lib/core/model/AlHabibMedicalService/HomeHealthCare/update_pres_oreder_request_model.dart b/lib/core/model/AlHabibMedicalService/HomeHealthCare/update_pres_oreder_request_model.dart index 3b0ef151..b32d51a5 100644 --- a/lib/core/model/AlHabibMedicalService/HomeHealthCare/update_pres_oreder_request_model.dart +++ b/lib/core/model/AlHabibMedicalService/HomeHealthCare/update_pres_oreder_request_model.dart @@ -1,21 +1,21 @@ class UpdatePresOrderRequestModel { - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - String sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; - int patientID; - String tokenID; - int patientTypeID; - int patientType; - int presOrderID; - int presOrderStatus; - int editedBy; - String rejectionReason; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + String? sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + int? patientID; + String? tokenID; + int? patientTypeID; + int? patientType; + int? presOrderID; + int? presOrderStatus; + int? editedBy; + String? rejectionReason; UpdatePresOrderRequestModel( {this.versionID, @@ -71,7 +71,8 @@ class UpdatePresOrderRequestModel { data['TokenID'] = this.tokenID; data['PatientTypeID'] = this.patientTypeID; data['PatientType'] = this.patientType; - data['PresOrderID'] = this.presOrderID; + data['Id'] = this.presOrderID; + data['ClickButton'] = 14; data['PresOrderStatus'] = this.presOrderStatus; data['EditedBy'] = this.editedBy; data['RejectionReason'] = this.rejectionReason; diff --git a/lib/core/model/Allergy/Allergy.dart b/lib/core/model/Allergy/Allergy.dart index be71c7fe..de9fe5d6 100644 --- a/lib/core/model/Allergy/Allergy.dart +++ b/lib/core/model/Allergy/Allergy.dart @@ -1,8 +1,8 @@ class Allergy { - int patientID; - int allergyDiseaseType; - int allergyDiseaseID; - String description; + int? patientID; + int? allergyDiseaseType; + int? allergyDiseaseID; + String? description; dynamic descriptionN; dynamic remarks; dynamic avgDoctorRatingList; diff --git a/lib/core/model/ImagesInfo.dart b/lib/core/model/ImagesInfo.dart index 54e8042b..5455d1bb 100644 --- a/lib/core/model/ImagesInfo.dart +++ b/lib/core/model/ImagesInfo.dart @@ -1,7 +1,7 @@ class ImagesInfo { - final String imageAr; - final String imageEn; - final bool isAsset; + final String? imageAr; + final String? imageEn; + final bool? isAsset; ImagesInfo({this.imageAr, this.imageEn, this.isAsset = false}); } diff --git a/lib/core/model/ResponseModel.dart b/lib/core/model/ResponseModel.dart index f34abf7d..41f28412 100644 --- a/lib/core/model/ResponseModel.dart +++ b/lib/core/model/ResponseModel.dart @@ -1,7 +1,7 @@ class ResponseModel{ - final bool status; - final String error; - final T data; + final bool? status; + final String? error; + final T? data; ResponseModel({this.status, this.data, this.error}); } \ No newline at end of file diff --git a/lib/core/model/active_medications/ActivePrescriptionReport.dart b/lib/core/model/active_medications/ActivePrescriptionReport.dart index 866cb728..50e3d45a 100644 --- a/lib/core/model/active_medications/ActivePrescriptionReport.dart +++ b/lib/core/model/active_medications/ActivePrescriptionReport.dart @@ -2,73 +2,75 @@ import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; class ActivePrescriptionReport { dynamic address; - int appointmentNo; + int? appointmentNo; dynamic clinic; dynamic companyName; - int days; + int? days; dynamic doctorName; - int doseDailyQuantity; - String frequency; - int frequencyNumber; - List image; - String imageExtension; - dynamic imageSRCUrl; - String imageString; - dynamic imageThumbUrl; + int? doseDailyQuantity; + String? frequency; + int? frequencyNumber; + + // List image; + // String imageExtension; + // dynamic imageSRCUrl; + String? imageString; + + // dynamic imageThumbUrl; dynamic isCovered; - String itemDescription; - int itemID; - DateTime orderDate; - int patientID; + String? itemDescription; + int? itemID; + DateTime? orderDate; + int? patientID; dynamic patientName; dynamic phoneOffice1; dynamic prescriptionQR; - int prescriptionTimes; + int? prescriptionTimes; dynamic productImage; - String productImageBase64; - String productImageString; - int projectID; + String? productImageBase64; + String? productImageString; + int? projectID; dynamic projectName; dynamic remarks; - String route; - String sKU; - int scaleOffset; - DateTime startDate; + String? route; + String? sKU; + int? scaleOffset; + DateTime? startDate; ActivePrescriptionReport( {this.address, - this.appointmentNo, - this.clinic, - this.companyName, - this.days, - this.doctorName, - this.doseDailyQuantity, - this.frequency, - this.frequencyNumber, - this.image, - this.imageExtension, - this.imageSRCUrl, - this.imageString, - this.imageThumbUrl, - this.isCovered, - this.itemDescription, - this.itemID, - this.orderDate, - this.patientID, - this.patientName, - this.phoneOffice1, - this.prescriptionQR, - this.prescriptionTimes, - this.productImage, - this.productImageBase64, - this.productImageString, - this.projectID, - this.projectName, - this.remarks, - this.route, - this.sKU, - this.scaleOffset, - this.startDate}); + this.appointmentNo, + this.clinic, + this.companyName, + this.days, + this.doctorName, + this.doseDailyQuantity, + this.frequency, + this.frequencyNumber, + // this.image, + // this.imageExtension, + // this.imageSRCUrl, + this.imageString, + // this.imageThumbUrl, + this.isCovered, + this.itemDescription, + this.itemID, + this.orderDate, + this.patientID, + this.patientName, + this.phoneOffice1, + this.prescriptionQR, + this.prescriptionTimes, + this.productImage, + this.productImageBase64, + this.productImageString, + this.projectID, + this.projectName, + this.remarks, + this.route, + this.sKU, + this.scaleOffset, + this.startDate}); ActivePrescriptionReport.fromJson(Map json) { address = json['Address']; @@ -80,11 +82,11 @@ class ActivePrescriptionReport { doseDailyQuantity = json['DoseDailyQuantity']; frequency = json['Frequency']; frequencyNumber = json['FrequencyNumber']; - image = json['Image'].cast(); - imageExtension = json['ImageExtension']; - imageSRCUrl = json['ImageSRCUrl']; + // image = json['Image'].cast(); + // imageExtension = json['ImageExtension']; + // imageSRCUrl = json['ImageSRCUrl']; imageString = json['ImageString']; - imageThumbUrl = json['ImageThumbUrl']; + // imageThumbUrl = json['ImageThumbUrl']; isCovered = json['IsCovered']; itemDescription = json['ItemDescription']; itemID = json['ItemID']; @@ -117,11 +119,11 @@ class ActivePrescriptionReport { data['DoseDailyQuantity'] = this.doseDailyQuantity; data['Frequency'] = this.frequency; data['FrequencyNumber'] = this.frequencyNumber; - data['Image'] = this.image; - data['ImageExtension'] = this.imageExtension; - data['ImageSRCUrl'] = this.imageSRCUrl; + // data['Image'] = this.image; + // data['ImageExtension'] = this.imageExtension; + // data['ImageSRCUrl'] = this.imageSRCUrl; data['ImageString'] = this.imageString; - data['ImageThumbUrl'] = this.imageThumbUrl; + // data['ImageThumbUrl'] = this.imageThumbUrl; data['IsCovered'] = this.isCovered; data['ItemDescription'] = this.itemDescription; data['ItemID'] = this.itemID; diff --git a/lib/core/model/ask_doctor/AskDoctorReqTypes.dart b/lib/core/model/ask_doctor/AskDoctorReqTypes.dart index b306f97b..e7e9b4ee 100644 --- a/lib/core/model/ask_doctor/AskDoctorReqTypes.dart +++ b/lib/core/model/ask_doctor/AskDoctorReqTypes.dart @@ -1,9 +1,9 @@ class AskDoctorReqTypes { dynamic setupID; - int parameterGroup; - int parameterType; - int parameterCode; - String description; + int? parameterGroup; + int? parameterType; + int? parameterCode; + String? description; dynamic descriptionN; dynamic alias; dynamic aliasN; @@ -12,10 +12,10 @@ class AskDoctorReqTypes { dynamic isColorCodingRequired; dynamic backColor; dynamic foreColor; - bool isBuiltIn; - bool isActive; - int createdBy; - String createdOn; + bool? isBuiltIn; + bool? isActive; + int? createdBy; + String? createdOn; dynamic editedBy; dynamic editedOn; dynamic rowVer; diff --git a/lib/core/model/ask_doctor/DoctorResponse.dart b/lib/core/model/ask_doctor/DoctorResponse.dart index 0dcd41b0..6b26a63f 100644 --- a/lib/core/model/ask_doctor/DoctorResponse.dart +++ b/lib/core/model/ask_doctor/DoctorResponse.dart @@ -1,19 +1,19 @@ class DoctorResponse { - int projectID; - int transactionNo; - int patientID; - int doctorID; - int requestType; - String requestTypeDescription; + int? projectID; + int? transactionNo; + int? patientID; + int? doctorID; + int? requestType; + String? requestTypeDescription; dynamic requestTypeDescriptionN; - int status; - String remarks; - String createdOn; + int? status; + String? remarks; + String? createdOn; dynamic readStatus; - String doctorName; - bool isDoctorRespond; - bool isPatientRead; - List transactions; + String? doctorName; + bool? isDoctorRespond; + bool? isPatientRead; + List? transactions; DoctorResponse( {this.projectID, @@ -69,7 +69,7 @@ class DoctorResponse { data['IsDoctorRespond'] = this.isDoctorRespond; data['IsPatientRead'] = this.isPatientRead; if (this.transactions != null) { - data['Transactions'] = this.transactions.map((v) => v.toJson()).toList(); + data['Transactions'] = this.transactions!.map((v) => v.toJson()).toList(); } return data; } diff --git a/lib/core/model/blooddonation/blood_donation_free_slots_response.dart b/lib/core/model/blooddonation/blood_donation_free_slots_response.dart new file mode 100644 index 00000000..df62f895 --- /dev/null +++ b/lib/core/model/blooddonation/blood_donation_free_slots_response.dart @@ -0,0 +1,25 @@ +class BloodDonationFreeSlotsResponseModel { + int? clinicID; + int? doctorID; + String? freeTimeSlots; + int? projectID; + + BloodDonationFreeSlotsResponseModel( + {this.clinicID, this.doctorID, this.freeTimeSlots, this.projectID}); + + BloodDonationFreeSlotsResponseModel.fromJson(Map json) { + clinicID = json['ClinicID']; + doctorID = json['DoctorID']; + freeTimeSlots = json['FreeTimeSlots']; + projectID = json['ProjectID']; + } + + Map toJson() { + final Map data = new Map(); + data['ClinicID'] = this.clinicID; + data['DoctorID'] = this.doctorID; + data['FreeTimeSlots'] = this.freeTimeSlots; + data['ProjectID'] = this.projectID; + return data; + } +} diff --git a/lib/core/model/blooddonation/blood_donation_projects_list_response.dart b/lib/core/model/blooddonation/blood_donation_projects_list_response.dart new file mode 100644 index 00000000..3ba5952d --- /dev/null +++ b/lib/core/model/blooddonation/blood_donation_projects_list_response.dart @@ -0,0 +1,46 @@ +class BloodDonationProjectsListResponse { + int? rowID; + int? iD; + int? projectID; + int? numberOfRooms; + bool? isActive; + int? createdBy; + String? createdOn; + dynamic editedBy; + dynamic editedON; + String? projectName; + dynamic projectNameN; + + BloodDonationProjectsListResponse( + {this.rowID, this.iD, this.projectID, this.numberOfRooms, this.isActive, this.createdBy, this.createdOn, this.editedBy, this.editedON, this.projectName, this.projectNameN}); + + BloodDonationProjectsListResponse.fromJson(Map json) { + rowID = json['RowID']; + iD = json['ID']; + projectID = json['ProjectID']; + numberOfRooms = json['NumberOfRooms']; + isActive = json['IsActive']; + createdBy = json['CreatedBy']; + createdOn = json['CreatedOn']; + editedBy = json['EditedBy']; + editedON = json['EditedON']; + projectName = json['ProjectName']; + projectNameN = json['ProjectNameN']; + } + + Map toJson() { + final Map data = new Map(); + data['RowID'] = this.rowID; + data['ID'] = this.iD; + data['ProjectID'] = this.projectID; + data['NumberOfRooms'] = this.numberOfRooms; + data['IsActive'] = this.isActive; + data['CreatedBy'] = this.createdBy; + data['CreatedOn'] = this.createdOn; + data['EditedBy'] = this.editedBy; + data['EditedON'] = this.editedON; + data['ProjectName'] = this.projectName; + data['ProjectNameN'] = this.projectNameN; + return data; + } +} diff --git a/lib/core/model/blooddonation/blood_groub_details.dart b/lib/core/model/blooddonation/blood_groub_details.dart index 34dcafe0..77c2d944 100644 --- a/lib/core/model/blooddonation/blood_groub_details.dart +++ b/lib/core/model/blooddonation/blood_groub_details.dart @@ -1,21 +1,21 @@ import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; class List_BloodGroupDetailsModel { - int iD; - int patientID; - int patientType; - bool patientOutSA; - int zipCode; - String cellNumber; - String cityCode; - String city; - int gender; - String bloodGroup; - String nationalID; - bool isActive; - int createdBy; - DateTime createdOn; - int editedBy; - DateTime editedOn; + int? iD; + int? patientID; + int? patientType; + bool? patientOutSA; + int? zipCode; + String? cellNumber; + String? cityCode; + String? city; + int? gender; + String? bloodGroup; + String? nationalID; + bool? isActive; + int? createdBy; + DateTime? createdOn; + int? editedBy; + DateTime? editedOn; List_BloodGroupDetailsModel( {this.iD, diff --git a/lib/core/model/blooddonation/get_all_cities.dart b/lib/core/model/blooddonation/get_all_cities.dart index 3d685bb6..cf7e6318 100644 --- a/lib/core/model/blooddonation/get_all_cities.dart +++ b/lib/core/model/blooddonation/get_all_cities.dart @@ -1,7 +1,7 @@ class CitiesModel { - int iD; - String description; - String descriptionN; + int? iD; + String? description; + String? descriptionN; CitiesModel({this.iD, this.description, this.descriptionN}); diff --git a/lib/core/model/childvaccines/List_BabyInformationModel.dart b/lib/core/model/childvaccines/List_BabyInformationModel.dart index 0711b8a2..cce3e248 100644 --- a/lib/core/model/childvaccines/List_BabyInformationModel.dart +++ b/lib/core/model/childvaccines/List_BabyInformationModel.dart @@ -1,13 +1,13 @@ import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; class List_BabyInformationModel { - int alertBy; - int babyID; - String babyName; - DateTime dOB; - int gender; - String genderDescription; - int patientID; - int userID; + int? alertBy; + int? babyID; + String? babyName; + DateTime? dOB; + int? gender; + String? genderDescription; + int? patientID; + int? userID; List_BabyInformationModel( {this.alertBy, diff --git a/lib/core/model/childvaccines/add_newchild_model.dart b/lib/core/model/childvaccines/add_newchild_model.dart index 9bbfe6ad..1f6afa32 100644 --- a/lib/core/model/childvaccines/add_newchild_model.dart +++ b/lib/core/model/childvaccines/add_newchild_model.dart @@ -1,50 +1,50 @@ class CreateNewBaby { - String babyName; - String gender; - String strDOB; - int editedBy; - int createdBy; - bool tempValue; - int userID; - bool isLogin; - int alertBy; - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - String sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; - int patientID; - String tokenID; - int patientTypeID; - int patientType; + String? babyName; + String? gender; + String? strDOB; + int? editedBy; + int? createdBy; + bool? tempValue; + int? userID; + bool? isLogin; + int? alertBy; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + String? sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + int? patientID; + String? tokenID; + int? patientTypeID; + int? patientType; CreateNewBaby( {this.babyName, - this.gender, - this.strDOB, - this.editedBy, - this.createdBy, - this.tempValue, - this.userID, - this.isLogin, - this.alertBy, - this.versionID, - this.channel, - this.languageID, - this.iPAdress, - this.generalid, - this.patientOutSA, - this.sessionID, - this.isDentalAllowedBackend, - this.deviceTypeID, - this.patientID, - this.tokenID, - this.patientTypeID, - this.patientType}); + this.gender, + this.strDOB, + this.editedBy, + this.createdBy, + this.tempValue, + this.userID, + this.isLogin, + this.alertBy, + this.versionID, + this.channel, + this.languageID, + this.iPAdress, + this.generalid, + this.patientOutSA, + this.sessionID, + this.isDentalAllowedBackend, + this.deviceTypeID, + this.patientID, + this.tokenID, + this.patientTypeID, + this.patientType}); CreateNewBaby.fromJson(Map json) { babyName = json['BabyName']; @@ -97,4 +97,4 @@ class CreateNewBaby { data['PatientType'] = this.patientType; return data; } -} \ No newline at end of file +} diff --git a/lib/core/model/childvaccines/create_new_user_model.dart b/lib/core/model/childvaccines/create_new_user_model.dart index 980567e2..2d496651 100644 --- a/lib/core/model/childvaccines/create_new_user_model.dart +++ b/lib/core/model/childvaccines/create_new_user_model.dart @@ -1,82 +1,82 @@ class CreateNewUser_New { - Null date; - int languageID; - int serviceName; - Null time; - Null androidLink; - Null authenticationTokenID; - Null data; - bool dataw; - int dietType; - Null errorCode; - Null errorEndUserMessage; - Null errorEndUserMessageN; - Null errorMessage; - int errorType; - int foodCategory; - Null iOSLink; - bool isAuthenticated; - int mealOrderStatus; - int mealType; - int messageStatus; - int numberOfResultRecords; - Null patientBlodType; - Null successMsg; - Null successMsgN; - Null htmlResult; - bool isHMGPatient; - bool isRegister; - bool isSendSMS; - Null listBabyInformationModel; - Null listBabyNeedReminderModel; - Null listCreateVaccinationTableModel; - Null listHisPatientModel; - Null listUserInformationModel; - Null listUserInformationModelNew; - Null listVaccinationTableModel; - Null tokinID; - int userID; - Null verificationCode; + dynamic date; + int? languageID; + int? serviceName; + dynamic time; + dynamic androidLink; + dynamic authenticationTokenID; + dynamic data; + bool? dataw; + int? dietType; + dynamic errorCode; + dynamic errorEndUserMessage; + dynamic errorEndUserMessageN; + dynamic errorMessage; + int? errorType; + int? foodCategory; + dynamic iOSLink; + bool? isAuthenticated; + int? mealOrderStatus; + int? mealType; + int? messageStatus; + int? numberOfResultRecords; + dynamic patientBlodType; + dynamic successMsg; + dynamic successMsgN; + dynamic htmlResult; + bool? isHMGPatient; + bool? isRegister; + bool? isSendSMS; + dynamic listBabyInformationModel; + dynamic listBabyNeedReminderModel; + dynamic listCreateVaccinationTableModel; + dynamic listHisPatientModel; + dynamic listUserInformationModel; + dynamic listUserInformationModelNew; + dynamic listVaccinationTableModel; + dynamic tokinID; + int? userID; + dynamic verificationCode; CreateNewUser_New( {this.date, - this.languageID, - this.serviceName, - this.time, - this.androidLink, - this.authenticationTokenID, - this.data, - this.dataw, - this.dietType, - this.errorCode, - this.errorEndUserMessage, - this.errorEndUserMessageN, - this.errorMessage, - this.errorType, - this.foodCategory, - this.iOSLink, - this.isAuthenticated, - this.mealOrderStatus, - this.mealType, - this.messageStatus, - this.numberOfResultRecords, - this.patientBlodType, - this.successMsg, - this.successMsgN, - this.htmlResult, - this.isHMGPatient, - this.isRegister, - this.isSendSMS, - this.listBabyInformationModel, - this.listBabyNeedReminderModel, - this.listCreateVaccinationTableModel, - this.listHisPatientModel, - this.listUserInformationModel, - this.listUserInformationModelNew, - this.listVaccinationTableModel, - this.tokinID, - this.userID, - this.verificationCode}); + this.languageID, + this.serviceName, + this.time, + this.androidLink, + this.authenticationTokenID, + this.data, + this.dataw, + this.dietType, + this.errorCode, + this.errorEndUserMessage, + this.errorEndUserMessageN, + this.errorMessage, + this.errorType, + this.foodCategory, + this.iOSLink, + this.isAuthenticated, + this.mealOrderStatus, + this.mealType, + this.messageStatus, + this.numberOfResultRecords, + this.patientBlodType, + this.successMsg, + this.successMsgN, + this.htmlResult, + this.isHMGPatient, + this.isRegister, + this.isSendSMS, + this.listBabyInformationModel, + this.listBabyNeedReminderModel, + this.listCreateVaccinationTableModel, + this.listHisPatientModel, + this.listUserInformationModel, + this.listUserInformationModelNew, + this.listVaccinationTableModel, + this.tokinID, + this.userID, + this.verificationCode}); CreateNewUser_New.fromJson(Map json) { date = json['Date']; @@ -151,8 +151,7 @@ class CreateNewUser_New { data['IsSendSMS'] = this.isSendSMS; data['List_BabyInformationModel'] = this.listBabyInformationModel; data['List_BabyNeedReminderModel'] = this.listBabyNeedReminderModel; - data['List_CreateVaccinationTableModel'] = - this.listCreateVaccinationTableModel; + data['List_CreateVaccinationTableModel'] = this.listCreateVaccinationTableModel; data['List_His_PatientModel'] = this.listHisPatientModel; data['List_UserInformationModel'] = this.listUserInformationModel; data['List_UserInformationModel_New'] = this.listUserInformationModelNew; @@ -162,4 +161,4 @@ class CreateNewUser_New { data['VerificationCode'] = this.verificationCode; return data; } -} \ No newline at end of file +} diff --git a/lib/core/model/childvaccines/create_vaccination_table.dart b/lib/core/model/childvaccines/create_vaccination_table.dart index d39f2a64..32b2ffff 100644 --- a/lib/core/model/childvaccines/create_vaccination_table.dart +++ b/lib/core/model/childvaccines/create_vaccination_table.dart @@ -1,8 +1,8 @@ class CreateVaccinationTable { - String givenAt; - String status; - String vaccinesDescription; - String visit; + String? givenAt; + String? status; + String? vaccinesDescription; + String? visit; CreateVaccinationTable( {this.givenAt, this.status, this.vaccinesDescription, this.visit}); diff --git a/lib/core/model/childvaccines/delete_baby_model.dart b/lib/core/model/childvaccines/delete_baby_model.dart index 9274b1e8..4d20bef5 100644 --- a/lib/core/model/childvaccines/delete_baby_model.dart +++ b/lib/core/model/childvaccines/delete_baby_model.dart @@ -1,20 +1,20 @@ class DeleteBaby { - bool isLogin; - int babyID; - int editedBy; - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - String sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; - int patientID; - String tokenID; - int patientTypeID; - int patientType; + bool? isLogin; + int? babyID; + int? editedBy; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + String? sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + int? patientID; + String? tokenID; + int? patientTypeID; + int? patientType; DeleteBaby( {this.isLogin, diff --git a/lib/core/model/childvaccines/get_vacainations_itemsmodel.dart b/lib/core/model/childvaccines/get_vacainations_itemsmodel.dart index 14891852..5ac35904 100644 --- a/lib/core/model/childvaccines/get_vacainations_itemsmodel.dart +++ b/lib/core/model/childvaccines/get_vacainations_itemsmodel.dart @@ -1,6 +1,6 @@ class GET_VACCINATIONS_ITEMSMODEL { - String dESCRIPTION; - String iTEMCODE; + String? dESCRIPTION; + String? iTEMCODE; GET_VACCINATIONS_ITEMSMODEL({this.dESCRIPTION, this.iTEMCODE}); diff --git a/lib/core/model/childvaccines/user_information_model.dart b/lib/core/model/childvaccines/user_information_model.dart index 9e1687d3..9e3ba427 100644 --- a/lib/core/model/childvaccines/user_information_model.dart +++ b/lib/core/model/childvaccines/user_information_model.dart @@ -1,24 +1,15 @@ class List_UserInformationModel { - int userID; - String mobileNumber; - String nationalID; - String emailAddress; - int patientID; - int patientType; - bool patientOutSA; - int createdBy; - int editedBy; + int? userID; + String? mobileNumber; + String? nationalID; + String? emailAddress; + int? patientID; + int? patientType; + bool? patientOutSA; + int? createdBy; + int? editedBy; - List_UserInformationModel( - {this.userID, - this.mobileNumber, - this.nationalID, - this.emailAddress, - this.patientID, - this.patientType, - this.patientOutSA, - this.createdBy, - this.editedBy}); + List_UserInformationModel({this.userID, this.mobileNumber, this.nationalID, this.emailAddress, this.patientID, this.patientType, this.patientOutSA, this.createdBy, this.editedBy}); List_UserInformationModel.fromJson(Map json) { userID = json['UserID']; @@ -45,4 +36,4 @@ class List_UserInformationModel { data['EditedBy'] = this.editedBy; return data; } -} \ No newline at end of file +} diff --git a/lib/core/model/contactus/get_hmg_locations.dart b/lib/core/model/contactus/get_hmg_locations.dart index 89d26951..d15b8534 100644 --- a/lib/core/model/contactus/get_hmg_locations.dart +++ b/lib/core/model/contactus/get_hmg_locations.dart @@ -1,20 +1,20 @@ class GetHMGLocationsModel { dynamic cityID; - String cityName; + String? cityName; dynamic cityNameN; dynamic distanceInKilometers; - bool isActive; - String latitude; - int locationID; - String locationName; + bool? isActive; + String? latitude; + int? locationID; + String? locationName; dynamic locationNameN; dynamic locationType; - String longitude; - int pharmacyLocationID; - String phoneNumber; - int projectID; - String projectImageURL; - int setupID; + String? longitude; + int? pharmacyLocationID; + String? phoneNumber; + int? projectID; + String? projectImageURL; + int? setupID; dynamic sortOrder; GetHMGLocationsModel( diff --git a/lib/core/model/contactus/get_patientI_cprojects.dart b/lib/core/model/contactus/get_patientI_cprojects.dart index e9a6b712..72a1968c 100644 --- a/lib/core/model/contactus/get_patientI_cprojects.dart +++ b/lib/core/model/contactus/get_patientI_cprojects.dart @@ -1,28 +1,20 @@ import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; class GetPatientICProjectsModel { - int id; - String projectName; - String projectNameN; - String value; + int? id; + String? projectName; + String? projectNameN; + String? value; dynamic languageId; - DateTime createdOn; - String createdBy; + DateTime? createdOn; + String? createdBy; dynamic editedOn; dynamic editedBy; - bool isActive; + bool? isActive; + dynamic distanceInKilometers; GetPatientICProjectsModel( - {this.id, - this.projectName, - this.projectNameN, - this.value, - this.languageId, - this.createdOn, - this.createdBy, - this.editedOn, - this.editedBy, - this.isActive}); + {this.id, this.projectName, this.projectNameN, this.value, this.languageId, this.createdOn, this.createdBy, this.editedOn, this.editedBy, this.distanceInKilometers, this.isActive}); GetPatientICProjectsModel.fromJson(Map json) { id = json['id']; @@ -35,6 +27,7 @@ class GetPatientICProjectsModel { editedOn = json['EditedOn']; editedBy = json['EditedBy']; isActive = json['IsActive']; + distanceInKilometers = json['DistanceInKilometers']; } Map toJson() { @@ -49,6 +42,7 @@ class GetPatientICProjectsModel { data['EditedOn'] = this.editedOn; data['EditedBy'] = this.editedBy; data['IsActive'] = this.isActive; + data['DistanceInKilometers'] = this.distanceInKilometers; return data; } -} \ No newline at end of file +} diff --git a/lib/core/model/doctor/doctor_profile.dart b/lib/core/model/doctor/doctor_profile.dart index 9e222e5a..36d77f53 100644 --- a/lib/core/model/doctor/doctor_profile.dart +++ b/lib/core/model/doctor/doctor_profile.dart @@ -1,88 +1,88 @@ class DoctorProfile { - int doctorID; - String doctorName; - Null doctorNameN; - int clinicID; - String clinicDescription; - Null clinicDescriptionN; - Null licenseExpiry; - int employmentType; - Null setupID; - int projectID; - String projectName; - String nationalityID; - String nationalityName; - Null nationalityNameN; - int gender; - String genderDescription; - Null genderDescriptionN; - Null doctorTitle; - Null projectNameN; - bool isAllowWaitList; - String titleDescription; - Null titleDescriptionN; - Null isRegistered; - Null isDoctorDummy; - bool isActive; - Null isDoctorAppointmentDisplayed; - bool doctorClinicActive; - Null isbookingAllowed; - String doctorCases; - Null doctorPicture; - String doctorProfileInfo; - List specialty; - int actualDoctorRate; - String doctorImageURL; - int doctorRate; - String doctorTitleForProfile; - bool isAppointmentAllowed; - String nationalityFlagURL; - int noOfPatientsRate; - String qR; - int serviceID; + int? doctorID; + String? doctorName; + dynamic doctorNameN; + int? clinicID; + String? clinicDescription; + dynamic clinicDescriptionN; + dynamic licenseExpiry; + int? employmentType; + dynamic setupID; + int? projectID; + String? projectName; + String? nationalityID; + String? nationalityName; + dynamic nationalityNameN; + int? gender; + String? genderDescription; + dynamic genderDescriptionN; + dynamic doctorTitle; + dynamic projectNameN; + bool? isAllowWaitList; + String? titleDescription; + dynamic titleDescriptionN; + dynamic isRegistered; + dynamic isDoctorDummy; + bool? isActive; + dynamic isDoctorAppointmentDisplayed; + bool? doctorClinicActive; + dynamic isbookingAllowed; + String? doctorCases; + dynamic doctorPicture; + String? doctorProfileInfo; + List? specialty; + int? actualDoctorRate; + String? doctorImageURL; + int? doctorRate; + String? doctorTitleForProfile; + bool? isAppointmentAllowed; + String? nationalityFlagURL; + int? noOfPatientsRate; + String? qR; + int? serviceID; DoctorProfile( {this.doctorID, - this.doctorName, - this.doctorNameN, - this.clinicID, - this.clinicDescription, - this.clinicDescriptionN, - this.licenseExpiry, - this.employmentType, - this.setupID, - this.projectID, - this.projectName, - this.nationalityID, - this.nationalityName, - this.nationalityNameN, - this.gender, - this.genderDescription, - this.genderDescriptionN, - this.doctorTitle, - this.projectNameN, - this.isAllowWaitList, - this.titleDescription, - this.titleDescriptionN, - this.isRegistered, - this.isDoctorDummy, - this.isActive, - this.isDoctorAppointmentDisplayed, - this.doctorClinicActive, - this.isbookingAllowed, - this.doctorCases, - this.doctorPicture, - this.doctorProfileInfo, - this.specialty, - this.actualDoctorRate, - this.doctorImageURL, - this.doctorRate, - this.doctorTitleForProfile, - this.isAppointmentAllowed, - this.nationalityFlagURL, - this.noOfPatientsRate, - this.qR, - this.serviceID}); + this.doctorName, + this.doctorNameN, + this.clinicID, + this.clinicDescription, + this.clinicDescriptionN, + this.licenseExpiry, + this.employmentType, + this.setupID, + this.projectID, + this.projectName, + this.nationalityID, + this.nationalityName, + this.nationalityNameN, + this.gender, + this.genderDescription, + this.genderDescriptionN, + this.doctorTitle, + this.projectNameN, + this.isAllowWaitList, + this.titleDescription, + this.titleDescriptionN, + this.isRegistered, + this.isDoctorDummy, + this.isActive, + this.isDoctorAppointmentDisplayed, + this.doctorClinicActive, + this.isbookingAllowed, + this.doctorCases, + this.doctorPicture, + this.doctorProfileInfo, + this.specialty, + this.actualDoctorRate, + this.doctorImageURL, + this.doctorRate, + this.doctorTitleForProfile, + this.isAppointmentAllowed, + this.nationalityFlagURL, + this.noOfPatientsRate, + this.qR, + this.serviceID}); DoctorProfile.fromJson(Map json) { doctorID = json['DoctorID']; diff --git a/lib/core/model/doctor/doctor_rating.dart b/lib/core/model/doctor/doctor_rating.dart index f02e052b..7996cbaa 100644 --- a/lib/core/model/doctor/doctor_rating.dart +++ b/lib/core/model/doctor/doctor_rating.dart @@ -1,9 +1,9 @@ class DoctorRating { - Null projectID; - Null clinicID; - int doctorID; - int patientNumber; - int doctorRate; + dynamic projectID; + dynamic clinicID; + int? doctorID; + int? patientNumber; + int? doctorRate; DoctorRating( {this.projectID, diff --git a/lib/core/model/doctor/patient_doctor_appointment.dart b/lib/core/model/doctor/patient_doctor_appointment.dart index 265561cd..9ee31e04 100644 --- a/lib/core/model/doctor/patient_doctor_appointment.dart +++ b/lib/core/model/doctor/patient_doctor_appointment.dart @@ -1,156 +1,156 @@ import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; class PatientDoctorAppointment { - String setupID; - int projectID; - int appointmentNo; - DateTime appointmentDate; - String appointmentDateN; - bool appointmentType; - DateTime bookDate; - bool patientType; - int patientID; - int clinicID; - int doctorID; - DateTime endDate; - String startTime; - String endTime; - bool status; - bool visitType; - String visitFor; - String patientStatusType; - String actualVisitStartTime; - String actualVisitEndTime; - bool isReminderActivated; - String reminderDisplayInterval; - String reminderDisplayIntervalUnit; - String mainAppointmentNo; - String notes; - int companyID; - String dHCCPatApptRef; - String bookedBy; - DateTime bookedOn; - String confirmedBy; - DateTime confirmedOn; - String arrivalChangedBy; - DateTime arrivedOn; - String rescheduledBy; - String rescheduledOn; - String mRStatus; - String mRSentBy; - String mRSentOn; - String mRReceiptBy; - String mRReceiptOn; - String isDocumentScanned; - String documentScanDateTime; - String documentScannedUser; - String editedBy; - String editedOn; - String isRecordedByNurse; - String isCheckedByDoctor; - String isVisitClosed; - String isRecurring; - String isPersonallyConfirmed; - String confirmationBy; - String relationId; - int appointmentDays; - int isActive; - int actualDoctorRate; - String clinicName; - String doctorCases; - String doctorImageURL; - String doctorInfo; - String doctorName; - int doctorRate; - String doctorTitle; - int gender; - String genderDescription; - bool isActiveDoctorProfile; - bool isAppointmentAllowed; - bool isDoctorAllowVedioCall; - String nationalityFlagURL; - String nationalityID; - String nationalityName; - int noOfPatientsRate; - String projectName; - String qR; - List speciality; + String? setupID; + int? projectID; + int? appointmentNo; + DateTime? appointmentDate; + String? appointmentDateN; + bool? appointmentType; + DateTime? bookDate; + bool? patientType; + int? patientID; + int? clinicID; + int? doctorID; + DateTime? endDate; + String? startTime; + String? endTime; + bool? status; + bool? visitType; + String? visitFor; + String? patientStatusType; + String? actualVisitStartTime; + String? actualVisitEndTime; + bool? isReminderActivated; + String? reminderDisplayInterval; + String? reminderDisplayIntervalUnit; + String? mainAppointmentNo; + String? notes; + int? companyID; + String? dHCCPatApptRef; + String? bookedBy; + DateTime? bookedOn; + String? confirmedBy; + DateTime? confirmedOn; + String? arrivalChangedBy; + DateTime? arrivedOn; + String? rescheduledBy; + String? rescheduledOn; + String? mRStatus; + String? mRSentBy; + String? mRSentOn; + String? mRReceiptBy; + String? mRReceiptOn; + String? isDocumentScanned; + String? documentScanDateTime; + String? documentScannedUser; + String? editedBy; + String? editedOn; + String? isRecordedByNurse; + String? isCheckedByDoctor; + String? isVisitClosed; + String? isRecurring; + String? isPersonallyConfirmed; + String? confirmationBy; + String? relationId; + int? appointmentDays; + int? isActive; + int? actualDoctorRate; + String? clinicName; + String? doctorCases; + String? doctorImageURL; + String? doctorInfo; + String? doctorName; + int? doctorRate; + String? doctorTitle; + int? gender; + String? genderDescription; + bool? isActiveDoctorProfile; + bool? isAppointmentAllowed; + bool? isDoctorAllowVedioCall; + String? nationalityFlagURL; + String? nationalityID; + String? nationalityName; + int? noOfPatientsRate; + String? projectName; + String? qR; + List? speciality; PatientDoctorAppointment( {this.setupID, - this.projectID, - this.appointmentNo, - this.appointmentDate, - this.appointmentDateN, - this.appointmentType, - this.bookDate, - this.patientType, - this.patientID, - this.clinicID, - this.doctorID, - this.endDate, - this.startTime, - this.endTime, - this.status, - this.visitType, - this.visitFor, - this.patientStatusType, - this.actualVisitStartTime, - this.actualVisitEndTime, - this.isReminderActivated, - this.reminderDisplayInterval, - this.reminderDisplayIntervalUnit, - this.mainAppointmentNo, - this.notes, - this.companyID, - this.dHCCPatApptRef, - this.bookedBy, - this.bookedOn, - this.confirmedBy, - this.confirmedOn, - this.arrivalChangedBy, - this.arrivedOn, - this.rescheduledBy, - this.rescheduledOn, - this.mRStatus, - this.mRSentBy, - this.mRSentOn, - this.mRReceiptBy, - this.mRReceiptOn, - this.isDocumentScanned, - this.documentScanDateTime, - this.documentScannedUser, - this.editedBy, - this.editedOn, - this.isRecordedByNurse, - this.isCheckedByDoctor, - this.isVisitClosed, - this.isRecurring, - this.isPersonallyConfirmed, - this.confirmationBy, - this.relationId, - this.appointmentDays, - this.isActive, - this.actualDoctorRate, - this.clinicName, - this.doctorCases, - this.doctorImageURL, - this.doctorInfo, - this.doctorName, - this.doctorRate, - this.doctorTitle, - this.gender, - this.genderDescription, - this.isActiveDoctorProfile, - this.isAppointmentAllowed, - this.isDoctorAllowVedioCall, - this.nationalityFlagURL, - this.nationalityID, - this.nationalityName, - this.noOfPatientsRate, - this.projectName, - this.qR, - this.speciality}); + this.projectID, + this.appointmentNo, + this.appointmentDate, + this.appointmentDateN, + this.appointmentType, + this.bookDate, + this.patientType, + this.patientID, + this.clinicID, + this.doctorID, + this.endDate, + this.startTime, + this.endTime, + this.status, + this.visitType, + this.visitFor, + this.patientStatusType, + this.actualVisitStartTime, + this.actualVisitEndTime, + this.isReminderActivated, + this.reminderDisplayInterval, + this.reminderDisplayIntervalUnit, + this.mainAppointmentNo, + this.notes, + this.companyID, + this.dHCCPatApptRef, + this.bookedBy, + this.bookedOn, + this.confirmedBy, + this.confirmedOn, + this.arrivalChangedBy, + this.arrivedOn, + this.rescheduledBy, + this.rescheduledOn, + this.mRStatus, + this.mRSentBy, + this.mRSentOn, + this.mRReceiptBy, + this.mRReceiptOn, + this.isDocumentScanned, + this.documentScanDateTime, + this.documentScannedUser, + this.editedBy, + this.editedOn, + this.isRecordedByNurse, + this.isCheckedByDoctor, + this.isVisitClosed, + this.isRecurring, + this.isPersonallyConfirmed, + this.confirmationBy, + this.relationId, + this.appointmentDays, + this.isActive, + this.actualDoctorRate, + this.clinicName, + this.doctorCases, + this.doctorImageURL, + this.doctorInfo, + this.doctorName, + this.doctorRate, + this.doctorTitle, + this.gender, + this.genderDescription, + this.isActiveDoctorProfile, + this.isAppointmentAllowed, + this.isDoctorAllowVedioCall, + this.nationalityFlagURL, + this.nationalityID, + this.nationalityName, + this.noOfPatientsRate, + this.projectName, + this.qR, + this.speciality}); PatientDoctorAppointment.fromJson(Map json) { try { @@ -182,11 +182,11 @@ class PatientDoctorAppointment { companyID = json['CompanyID']; dHCCPatApptRef = json['DHCCPatApptRef']; bookedBy = json['BookedBy']; - // bookedOn = DateUtil.convertStringToDate(json['BookedOn']); + // bookedOn = DateUtil.convertStringToDate(json['BookedOn']); confirmedBy = json['ConfirmedBy']; - // confirmedOn = DateUtil.convertStringToDate(json['ConfirmedOn']); + // confirmedOn = DateUtil.convertStringToDate(json['ConfirmedOn']); arrivalChangedBy = json['ArrivalChangedBy']; - // arrivedOn = DateUtil.convertStringToDate(json['ArrivedOn']); + // arrivedOn = DateUtil.convertStringToDate(json['ArrivedOn']); rescheduledBy = json['RescheduledBy']; rescheduledOn = json['RescheduledOn']; mRStatus = json['MRStatus']; @@ -227,7 +227,7 @@ class PatientDoctorAppointment { noOfPatientsRate = json['NoOfPatientsRate']; projectName = json['ProjectName']; qR = json['QR']; - // speciality = json['Speciality'].cast(); + // speciality = json['Speciality'].cast(); } catch (e) { print(e); } @@ -313,13 +313,11 @@ class PatientDoctorAppointment { } } -class PatientDoctorAppointmentList{ +class PatientDoctorAppointmentList { + String? filterName = ""; + List patientDoctorAppointmentList = []; - String filterName =""; - List patientDoctorAppointmentList = List(); - - PatientDoctorAppointmentList({this.filterName,PatientDoctorAppointment patientDoctorAppointment}){ - patientDoctorAppointmentList.add(patientDoctorAppointment); + PatientDoctorAppointmentList({this.filterName, PatientDoctorAppointment? patientDoctorAppointment}) { + patientDoctorAppointmentList.add(patientDoctorAppointment!); } - } diff --git a/lib/core/model/doctor/reques_patient_doctor_appointmentt.dart b/lib/core/model/doctor/reques_patient_doctor_appointmentt.dart index 8ed90132..883b11dc 100644 --- a/lib/core/model/doctor/reques_patient_doctor_appointmentt.dart +++ b/lib/core/model/doctor/reques_patient_doctor_appointmentt.dart @@ -1,38 +1,38 @@ class RequestPatientDoctorAppointment { - int top; - double versionID; - int beforeDays; - int exludType; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - String sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; - int patientID; - String tokenID; - int patientTypeID; - int patientType; + int? top; + double? versionID; + int? beforeDays; + int? exludType; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + String? sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + int? patientID; + String? tokenID; + int? patientTypeID; + int? patientType; RequestPatientDoctorAppointment( {this.top, - this.versionID, - this.beforeDays, - this.exludType, - this.channel, - this.languageID, - this.iPAdress, - this.generalid, - this.patientOutSA, - this.sessionID, - this.isDentalAllowedBackend, - this.deviceTypeID, - this.patientID, - this.tokenID, - this.patientTypeID, - this.patientType}); + this.versionID, + this.beforeDays, + this.exludType, + this.channel, + this.languageID, + this.iPAdress, + this.generalid, + this.patientOutSA, + this.sessionID, + this.isDentalAllowedBackend, + this.deviceTypeID, + this.patientID, + this.tokenID, + this.patientTypeID, + this.patientType}); RequestPatientDoctorAppointment.fromJson(Map json) { top = json['Top']; diff --git a/lib/core/model/doctor/request_doctor_profile.dart b/lib/core/model/doctor/request_doctor_profile.dart index 80766b3f..cae86c2f 100644 --- a/lib/core/model/doctor/request_doctor_profile.dart +++ b/lib/core/model/doctor/request_doctor_profile.dart @@ -1,19 +1,19 @@ class RequestDoctorProfile { - int doctorID; - bool license; - bool isRegistered; - int projectID; - int clinicID; - int patientID; - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - String sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; + int? doctorID; + bool? license; + bool? isRegistered; + int? projectID; + int? clinicID; + int? patientID; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + String? sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; RequestDoctorProfile( {this.doctorID, diff --git a/lib/core/model/doctor/request_doctor_rating.dart b/lib/core/model/doctor/request_doctor_rating.dart index fcc9386b..ca9e82d4 100644 --- a/lib/core/model/doctor/request_doctor_rating.dart +++ b/lib/core/model/doctor/request_doctor_rating.dart @@ -1,26 +1,16 @@ class RequestDoctorRating { - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - String sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; - int doctorID; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + String? sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + int? doctorID; - RequestDoctorRating( - {this.versionID, - this.channel, - this.languageID, - this.iPAdress, - this.generalid, - this.patientOutSA, - this.sessionID, - this.isDentalAllowedBackend, - this.deviceTypeID, - this.doctorID}); + RequestDoctorRating({this.versionID, this.channel, this.languageID, this.iPAdress, this.generalid, this.patientOutSA, this.sessionID, this.isDentalAllowedBackend, this.deviceTypeID, this.doctorID}); RequestDoctorRating.fromJson(Map json) { versionID = json['VersionID']; diff --git a/lib/core/model/er/AmbulanceRequestOrdersModel.dart b/lib/core/model/er/AmbulanceRequestOrdersModel.dart new file mode 100644 index 00000000..6993183c --- /dev/null +++ b/lib/core/model/er/AmbulanceRequestOrdersModel.dart @@ -0,0 +1,346 @@ +class AmbulanceRequestOrdersModel { + String? statusText; + num? paymentStatus; + dynamic clientRequestid; + dynamic paymentStatusText; + dynamic projectName; + String? nearestProjectName; + num? paymentAmount; + WFOrder? wFOrder; + String? serviceText; + bool? isSentForApproval; + num? exaCartOrderId; + String? exaCartGUID; + bool? isTimer; + num? timeSeconds; + num? totalPendingSeconds; + num? timeMinute; + num? timeHour; + num? timeTotalSeconds; + num? timeTotalMinute; + num? timeTotalHour; + dynamic approvalStatus; + bool? isActive; + num? clickButton; + dynamic orderHistory; + String? pickupLocation; + String? dropOffLocation; + String? clinicName; + String? doctorName; + String? branch; + String? time; + String? notes; + int? iD; + num? patientId; + num? patientOutSa; + bool? isOutPatient; + num? projectId; + num? nearestProjectId; + dynamic longitude; + dynamic latitude; + dynamic appointmentNo; + dynamic dischargeId; + int? statusId; + num? serviceId; + num? channel; + Orderpayment? orderpayment; + dynamic wforder; + dynamic orderapprovalobj; + String? created; + dynamic createdBy; + dynamic modified; + dynamic modifiedBy; + bool? isDeleted; + + AmbulanceRequestOrdersModel( + {this.statusText, + this.paymentStatus, + this.clientRequestid, + this.paymentStatusText, + this.projectName, + this.nearestProjectName, + this.paymentAmount, + this.wFOrder, + this.serviceText, + this.isSentForApproval, + this.exaCartOrderId, + this.exaCartGUID, + this.isTimer, + this.timeSeconds, + this.totalPendingSeconds, + this.timeMinute, + this.timeHour, + this.timeTotalSeconds, + this.timeTotalMinute, + this.timeTotalHour, + this.approvalStatus, + this.isActive, + this.clickButton, + this.orderHistory, + this.pickupLocation, + this.dropOffLocation, + this.clinicName, + this.doctorName, + this.branch, + this.time, + this.notes, + this.iD, + this.patientId, + this.patientOutSa, + this.isOutPatient, + this.projectId, + this.nearestProjectId, + this.longitude, + this.latitude, + this.appointmentNo, + this.dischargeId, + this.statusId, + this.serviceId, + this.channel, + this.orderpayment, + this.wforder, + this.orderapprovalobj, + this.created, + this.createdBy, + this.modified, + this.modifiedBy, + this.isDeleted}); + + AmbulanceRequestOrdersModel.fromJson(Map json) { + statusText = json['StatusText']; + paymentStatus = json['PaymentStatus']; + clientRequestid = json['ClientRequestid']; + paymentStatusText = json['PaymentStatusText']; + projectName = json['ProjectName']; + nearestProjectName = json['NearestProjectName']; + paymentAmount = json['PaymentAmount']; + wFOrder = json['WF_order'] != null + ? new WFOrder.fromJson(json['WF_order']) + : null; + serviceText = json['ServiceText']; + isSentForApproval = json['isSentForApproval']; + exaCartOrderId = json['ExaCart_OrderId']; + exaCartGUID = json['ExaCart_GUID']; + isTimer = json['isTimer']; + timeSeconds = json['TimeSeconds']; + totalPendingSeconds = json['TotalPendingSeconds']; + timeMinute = json['TimeMinute']; + timeHour = json['TimeHour']; + timeTotalSeconds = json['TimeTotalSeconds']; + timeTotalMinute = json['TimeTotalMinute']; + timeTotalHour = json['TimeTotalHour']; + approvalStatus = json['ApprovalStatus']; + isActive = json['isActive']; + clickButton = json['ClickButton']; + orderHistory = json['OrderHistory']; + pickupLocation = json['PickupLocation']; + dropOffLocation = json['DropOffLocation']; + clinicName = json['clinicName']; + doctorName = json['DoctorName']; + branch = json['Branch']; + time = json['Time']; + notes = json['Notes']; + iD = json['ID']; + patientId = json['PatientId']; + patientOutSa = json['PatientOutSa']; + isOutPatient = json['IsOutPatient']; + projectId = json['ProjectId']; + nearestProjectId = json['NearestProjectId']; + longitude = json['Longitude']; + latitude = json['Latitude']; + appointmentNo = json['AppointmentNo']; + dischargeId = json['DischargeId']; + statusId = json['StatusId']; + serviceId = json['ServiceId']; + channel = json['Channel']; + orderpayment = json['orderpayment'] != null + ? new Orderpayment.fromJson(json['orderpayment']) + : null; + wforder = json['wforder']; + orderapprovalobj = json['orderapprovalobj']; + created = json['Created']; + createdBy = json['CreatedBy']; + modified = json['Modified']; + modifiedBy = json['ModifiedBy']; + isDeleted = json['IsDeleted']; + } + + Map toJson() { + final Map data = new Map(); + data['StatusText'] = this.statusText; + data['PaymentStatus'] = this.paymentStatus; + data['ClientRequestid'] = this.clientRequestid; + data['PaymentStatusText'] = this.paymentStatusText; + data['ProjectName'] = this.projectName; + data['NearestProjectName'] = this.nearestProjectName; + data['PaymentAmount'] = this.paymentAmount; + if (this.wFOrder != null) { + data['WF_order'] = this.wFOrder!.toJson(); + } + data['ServiceText'] = this.serviceText; + data['isSentForApproval'] = this.isSentForApproval; + data['ExaCart_OrderId'] = this.exaCartOrderId; + data['ExaCart_GUID'] = this.exaCartGUID; + data['isTimer'] = this.isTimer; + data['TimeSeconds'] = this.timeSeconds; + data['TotalPendingSeconds'] = this.totalPendingSeconds; + data['TimeMinute'] = this.timeMinute; + data['TimeHour'] = this.timeHour; + data['TimeTotalSeconds'] = this.timeTotalSeconds; + data['TimeTotalMinute'] = this.timeTotalMinute; + data['TimeTotalHour'] = this.timeTotalHour; + data['ApprovalStatus'] = this.approvalStatus; + data['isActive'] = this.isActive; + data['ClickButton'] = this.clickButton; + data['OrderHistory'] = this.orderHistory; + data['PickupLocation'] = this.pickupLocation; + data['DropOffLocation'] = this.dropOffLocation; + data['clinicName'] = this.clinicName; + data['DoctorName'] = this.doctorName; + data['Branch'] = this.branch; + data['Time'] = this.time; + data['Notes'] = this.notes; + data['ID'] = this.iD; + data['PatientId'] = this.patientId; + data['PatientOutSa'] = this.patientOutSa; + data['IsOutPatient'] = this.isOutPatient; + data['ProjectId'] = this.projectId; + data['NearestProjectId'] = this.nearestProjectId; + data['Longitude'] = this.longitude; + data['Latitude'] = this.latitude; + data['AppointmentNo'] = this.appointmentNo; + data['DischargeId'] = this.dischargeId; + data['StatusId'] = this.statusId; + data['ServiceId'] = this.serviceId; + data['Channel'] = this.channel; + if (this.orderpayment != null) { + data['orderpayment'] = this.orderpayment!.toJson(); + } + data['wforder'] = this.wforder; + data['orderapprovalobj'] = this.orderapprovalobj; + data['Created'] = this.created; + data['CreatedBy'] = this.createdBy; + data['Modified'] = this.modified; + data['ModifiedBy'] = this.modifiedBy; + data['IsDeleted'] = this.isDeleted; + return data; + } +} + +class WFOrder { + dynamic wfButtonsDTO; + num? iD; + num? orderId; + num? previousStep; + num? nextStep; + num? serviceId; + dynamic order; + String? created; + dynamic createdBy; + dynamic modified; + dynamic modifiedBy; + bool? isDeleted; + + WFOrder( + {this.wfButtonsDTO, + this.iD, + this.orderId, + this.previousStep, + this.nextStep, + this.serviceId, + this.order, + this.created, + this.createdBy, + this.modified, + this.modifiedBy, + this.isDeleted}); + + WFOrder.fromJson(Map json) { + wfButtonsDTO = json['wf_ButtonsDTO']; + iD = json['ID']; + orderId = json['OrderId']; + previousStep = json['PreviousStep']; + nextStep = json['NextStep']; + serviceId = json['ServiceId']; + order = json['Order']; + created = json['Created']; + createdBy = json['CreatedBy']; + modified = json['Modified']; + modifiedBy = json['ModifiedBy']; + isDeleted = json['IsDeleted']; + } + + Map toJson() { + final Map data = new Map(); + data['wf_ButtonsDTO'] = this.wfButtonsDTO; + data['ID'] = this.iD; + data['OrderId'] = this.orderId; + data['PreviousStep'] = this.previousStep; + data['NextStep'] = this.nextStep; + data['ServiceId'] = this.serviceId; + data['Order'] = this.order; + data['Created'] = this.created; + data['CreatedBy'] = this.createdBy; + data['Modified'] = this.modified; + data['ModifiedBy'] = this.modifiedBy; + data['IsDeleted'] = this.isDeleted; + return data; + } +} + +class Orderpayment { + num? iD; + num? orderId; + dynamic clientRequestId; + num? totalAmount; + num? paymentStatus; + dynamic order; + String? created; + dynamic createdBy; + dynamic modified; + dynamic modifiedBy; + bool? isDeleted; + + Orderpayment( + {this.iD, + this.orderId, + this.clientRequestId, + this.totalAmount, + this.paymentStatus, + this.order, + this.created, + this.createdBy, + this.modified, + this.modifiedBy, + this.isDeleted}); + + Orderpayment.fromJson(Map json) { + iD = json['ID']; + orderId = json['OrderId']; + clientRequestId = json['ClientRequestId']; + totalAmount = json['TotalAmount']; + paymentStatus = json['PaymentStatus']; + order = json['Order']; + created = json['Created']; + createdBy = json['CreatedBy']; + modified = json['Modified']; + modifiedBy = json['ModifiedBy']; + isDeleted = json['IsDeleted']; + } + + Map toJson() { + final Map data = new Map(); + data['ID'] = this.iD; + data['OrderId'] = this.orderId; + data['ClientRequestId'] = this.clientRequestId; + data['TotalAmount'] = this.totalAmount; + data['PaymentStatus'] = this.paymentStatus; + data['Order'] = this.order; + data['Created'] = this.created; + data['CreatedBy'] = this.createdBy; + data['Modified'] = this.modified; + data['ModifiedBy'] = this.modifiedBy; + data['IsDeleted'] = this.isDeleted; + return data; + } +} diff --git a/lib/core/model/er/ErPatientShareModel.dart b/lib/core/model/er/ErPatientShareModel.dart index 4c6a4165..cf07be7b 100644 --- a/lib/core/model/er/ErPatientShareModel.dart +++ b/lib/core/model/er/ErPatientShareModel.dart @@ -1,23 +1,23 @@ class ErPatientShareModel { - int cashPrice; - int cashPriceTax; - int cashPriceWithTax; - int companyId; - String companyName; - int companyShareWithTax; + int? cashPrice; + int? cashPriceTax; + int? cashPriceWithTax; + int? companyId; + String? companyName; + int? companyShareWithTax; dynamic errCode; - int groupID; + int? groupID; dynamic insurancePolicyNo; - String message; + String? message; dynamic patientCardID; - double patientShare; - double patientShareWithTax; - double patientTaxAmount; - int policyId; - String policyName; - String procedureName; + num? patientShare; + num? patientShareWithTax; + num? patientTaxAmount; + int? policyId; + String? policyName; + String? procedureName; dynamic setupID; - int statusCode; + int? statusCode; dynamic subPolicyNo; ErPatientShareModel( diff --git a/lib/core/model/er/PatientAllPresOrders.dart b/lib/core/model/er/PatientAllPresOrders.dart index 90ce074a..59d184d3 100644 --- a/lib/core/model/er/PatientAllPresOrders.dart +++ b/lib/core/model/er/PatientAllPresOrders.dart @@ -1,34 +1,34 @@ class PatientAllPresOrders { - int iD; - String patientID; - bool patientOutSA; - bool isOutPatient; - int projectID; - int nearestProjectID; - double longitude; - double latitude; - String appointmentNo; - String dischargeID; - int lineItemNo; - int status; - String description; - String descriptionN; - String createdOn; - int serviceID; - int createdBy; - String editedOn; - int editedBy; - int channel; + int? iD; + String? patientID; + bool? patientOutSA; + bool? isOutPatient; + int? projectID; + int? nearestProjectID; + double? longitude; + double? latitude; + String? appointmentNo; + String? dischargeID; + int? lineItemNo; + int? status; + String? description; + String? descriptionN; + String? createdOn; + int? serviceID; + int? createdBy; + String? editedOn; + int? editedBy; + int? channel; dynamic clientRequestID; - bool returnedToQueue; + bool? returnedToQueue; dynamic pickupDateTime; dynamic pickupLocationName; dynamic dropoffLocationName; - int realRRTHaveTransactions; - String nearestProjectDescription; - String nearestProjectDescriptionN; - String projectDescription; - String projectDescriptionN; + int? realRRTHaveTransactions; + String? nearestProjectDescription; + String? nearestProjectDescriptionN; + String? projectDescription; + String? projectDescriptionN; PatientAllPresOrders( {this.iD, diff --git a/lib/core/model/er/PatientER.dart b/lib/core/model/er/PatientER.dart index f1694f9e..f8248956 100644 --- a/lib/core/model/er/PatientER.dart +++ b/lib/core/model/er/PatientER.dart @@ -3,55 +3,55 @@ import 'package:diplomaticquarterapp/core/enum/Ambulate.dart'; import 'get_all_transportation_method_list_model.dart'; class PatientER { - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - String sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; - int patientID; - String tokenID; - int patientTypeID; - int patientType; - int orderServiceID; - String patientIdentificationID; - int direction; - bool haveAppointment; - int tripType; - int pickupUrgency; - int pickupSpot; - String pickupDateTime; - int transportationMethodId; - int selectedAmbulate; - String requesterNote; - int requesterFileNo; - String requesterMobileNo; - bool requesterIsOutSA; - int isOutPatient; - String pickupLocationName; - String dropoffLocationName; - int projectID; - int createdBy; - int lineItemNo; - double cost; - double vAT; - double totalPrice; - String pickupLocationLattitude; - String pickupLocationLongitude; - String dropoffLocationLattitude; - String dropoffLocationLongitude; - String latitude; - String longitude; - String appointmentNo; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + dynamic patientOutSA; + String? sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + int? patientID; + String? tokenID; + int? patientTypeID; + int? patientType; + int? orderServiceID; + String? patientIdentificationID; + int? direction; + bool? haveAppointment; + int? tripType; + int? pickupUrgency; + int? pickupSpot; + String? pickupDateTime; + int? transportationMethodId; + int? selectedAmbulate; + String? requesterNote; + int? requesterFileNo; + String? requesterMobileNo; + bool? requesterIsOutSA; + int? isOutPatient; + String? pickupLocationName; + String? dropoffLocationName; + int? projectID; + int? createdBy; + int? lineItemNo; + double? cost; + double? vAT; + double? totalPrice; + String? pickupLocationLattitude; + String? pickupLocationLongitude; + String? dropoffLocationLattitude; + String? dropoffLocationLongitude; + String? latitude; + String? longitude; + String? appointmentNo; dynamic appointmentClinicName; dynamic appointmentDoctorName; dynamic appointmentBranch; dynamic appointmentTime; - PatientERTransportationMethod patientERTransportationMethod; - Ambulate ambulate; + PatientERTransportationMethod? patientERTransportationMethod; + Ambulate? ambulate; PatientER( {this.versionID, this.channel, @@ -164,7 +164,7 @@ class PatientER { data['SessionID'] = this.sessionID; data['isDentalAllowedBackend'] = this.isDentalAllowedBackend; data['DeviceTypeID'] = this.deviceTypeID; - data['PatientID'] = this.patientID; + data['PatientID'] = this.patientID.toString(); data['TokenID'] = this.tokenID; data['PatientTypeID'] = this.patientTypeID; data['PatientType'] = this.patientType; diff --git a/lib/core/model/er/PatientER_RC.dart b/lib/core/model/er/PatientER_RC.dart new file mode 100644 index 00000000..cd4d8d5d --- /dev/null +++ b/lib/core/model/er/PatientER_RC.dart @@ -0,0 +1,204 @@ +import 'package:diplomaticquarterapp/core/model/er/get_all_transportation_method_list_model.dart'; + +class PatientER_RC { + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + bool? patientOutSA; + String? sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + int? patientID; + String? tokenID; + int? patientTypeID; + int? patientType; + int? orderServiceID; + String? patientIdentificationID; + dynamic patientOutSa; + int? projectID; + int? lineItemNo; + TransportationDetails? transportationDetails; + PatientERTransportationMethod? patientERTransportationMethod; + + PatientER_RC( + {this.versionID, + this.channel, + this.languageID, + this.iPAdress, + this.generalid, + this.patientOutSA, + this.sessionID, + this.isDentalAllowedBackend, + this.deviceTypeID, + this.patientID, + this.tokenID, + this.patientTypeID, + this.patientType, + this.orderServiceID, + this.patientIdentificationID, + this.patientOutSa, + this.projectID, + this.lineItemNo, + this.transportationDetails}); + + PatientER_RC.fromJson(Map json) { + versionID = json['VersionID']; + channel = json['Channel']; + languageID = json['LanguageID']; + iPAdress = json['IPAdress']; + generalid = json['generalid']; + patientOutSA = json['PatientOutSA']; + sessionID = json['SessionID']; + isDentalAllowedBackend = json['isDentalAllowedBackend']; + deviceTypeID = json['DeviceTypeID']; + patientID = json['PatientID']; + tokenID = json['TokenID']; + patientTypeID = json['PatientTypeID']; + patientType = json['PatientType']; + orderServiceID = json['OrderServiceID']; + patientIdentificationID = json['PatientIdentificationID']; + patientOutSa = json['patientOutSa']; + projectID = json['projectID']; + lineItemNo = json['lineItemNo']; + transportationDetails = json['transportationDetails'] != null + ? new TransportationDetails.fromJson(json['transportationDetails']) + : null; + } + + Map toJson() { + final Map data = new Map(); + data['VersionID'] = this.versionID; + data['Channel'] = this.channel; + data['LanguageID'] = this.languageID; + data['IPAdress'] = this.iPAdress; + data['generalid'] = this.generalid; + data['PatientOutSA'] = this.patientOutSA; + data['SessionID'] = this.sessionID; + data['isDentalAllowedBackend'] = this.isDentalAllowedBackend; + data['DeviceTypeID'] = this.deviceTypeID; + data['PatientID'] = this.patientID; + data['TokenID'] = this.tokenID; + data['PatientTypeID'] = this.patientTypeID; + data['PatientType'] = this.patientType; + data['OrderServiceID'] = this.orderServiceID; + data['PatientIdentificationID'] = this.patientIdentificationID; + data['patientOutSa'] = this.patientOutSa; + data['projectID'] = this.projectID; + data['lineItemNo'] = this.lineItemNo; + if (this.transportationDetails != null) { + data['transportationDetails'] = this.transportationDetails!.toJson(); + } + return data; + } +} + +class TransportationDetails { + int? direction; + int? haveAppointment; + int? tripType; + int? pickupUrgency; + int? pickupSpot; + String? pickupDateTime; + String? transportationType; + int? ambulate; + String? ambulateTitle; + String? notes; + int? requesterFileNo; + String? requesterMobileNo; + bool? requesterIsOutSA; + String? pickupLocationName; + String? dropoffLocationName; + String? pickupLatitude; + String? pickupLongitude; + String? dropoffLatitude; + String? dropoffLongitude; + String? appointmentNo; + String? appointmentClinicName; + String? appointmentDoctorName; + String? appointmentBranch; + String? appointmentTime; + + TransportationDetails( + {this.direction, + this.haveAppointment, + this.tripType, + this.pickupUrgency, + this.pickupSpot, + this.pickupDateTime, + this.transportationType, + this.ambulate, + this.ambulateTitle, + this.notes, + this.requesterFileNo, + this.requesterMobileNo, + this.requesterIsOutSA, + this.pickupLocationName, + this.dropoffLocationName, + this.pickupLatitude, + this.pickupLongitude, + this.dropoffLatitude, + this.dropoffLongitude, + this.appointmentNo, + this.appointmentClinicName, + this.appointmentDoctorName, + this.appointmentBranch, + this.appointmentTime}); + + TransportationDetails.fromJson(Map json) { + direction = json['direction']; + haveAppointment = json['haveAppointment']; + tripType = json['tripType']; + pickupUrgency = json['pickupUrgency']; + pickupSpot = json['pickupSpot']; + pickupDateTime = json['pickupDateTime']; + transportationType = json['transportationType']; + ambulate = json['ambulate']; + ambulateTitle = ""; + notes = json['notes']; + requesterFileNo = json['requesterFileNo']; + requesterMobileNo = json['requesterMobileNo']; + requesterIsOutSA = json['requesterIsOutSA']; + pickupLocationName = json['pickupLocationName']; + dropoffLocationName = json['dropoffLocationName']; + pickupLatitude = json['pickup_Latitude']; + pickupLongitude = json['pickup_Longitude']; + dropoffLatitude = json['dropoff_Latitude']; + dropoffLongitude = json['dropoff_Longitude']; + appointmentNo = json['appointmentNo']; + appointmentClinicName = json['appointmentClinicName']; + appointmentDoctorName = json['appointmentDoctorName']; + appointmentBranch = json['appointmentBranch']; + appointmentTime = json['appointmentTime']; + } + + Map toJson() { + final Map data = new Map(); + data['direction'] = this.direction; + data['haveAppointment'] = this.haveAppointment; + data['tripType'] = this.tripType; + data['pickupUrgency'] = this.pickupUrgency; + data['pickupSpot'] = this.pickupSpot; + data['pickupDateTime'] = this.pickupDateTime; + data['transportationType'] = this.transportationType; + data['ambulate'] = this.ambulate; + data['ambulateTitle'] = this.ambulateTitle; + data['notes'] = this.notes; + data['requesterFileNo'] = this.requesterFileNo; + data['requesterMobileNo'] = this.requesterMobileNo; + data['requesterIsOutSA'] = this.requesterIsOutSA; + data['pickupLocationName'] = this.pickupLocationName; + data['dropoffLocationName'] = this.dropoffLocationName; + data['pickup_Latitude'] = this.pickupLatitude; + data['pickup_Longitude'] = this.pickupLongitude; + data['dropoff_Latitude'] = this.dropoffLatitude; + data['dropoff_Longitude'] = this.dropoffLongitude; + data['appointmentNo'] = this.appointmentNo; + data['appointmentClinicName'] = this.appointmentClinicName; + data['appointmentDoctorName'] = this.appointmentDoctorName; + data['appointmentBranch'] = this.appointmentBranch; + data['appointmentTime'] = this.appointmentTime; + return data; + } +} diff --git a/lib/core/model/er/PickUpRequestPresOrder.dart b/lib/core/model/er/PickUpRequestPresOrder.dart index c4f359f5..75f39ea4 100644 --- a/lib/core/model/er/PickUpRequestPresOrder.dart +++ b/lib/core/model/er/PickUpRequestPresOrder.dart @@ -1,52 +1,52 @@ class PickUpRequestPresOrder { - int id; - int presOrderID; - String createDate; - String lastEditDate; - int createdBy; - int lastEditBy; - bool isActive; - String requestNo; - int requesterId; - int direction; - bool haveAppointment; + int? id; + int? presOrderID; + String? createDate; + String? lastEditDate; + int? createdBy; + int? lastEditBy; + bool? isActive; + String? requestNo; + int? requesterId; + int? direction; + bool? haveAppointment; dynamic appointmentId; - int tripType; - int pickupUrgency; - String pickupDateTime; + int? tripType; + int? pickupUrgency; + String? pickupDateTime; dynamic pickupLocationId; - int pickupSpot; + int? pickupSpot; dynamic dropoffLocationId; - int transportationMethodId; + int? transportationMethodId; dynamic cost; dynamic vAT; - double totalPrice; - int amountCollected; - int selectedAmbulate; - String requesterNote; - int status; - int paymentStatus; + double? totalPrice; + int? amountCollected; + int? selectedAmbulate; + String? requesterNote; + int? status; + int? paymentStatus; dynamic rejectReason; - int visibility; + int? visibility; dynamic durationId; dynamic imageId; - String requesterFileNo; - String requesterMobileNo; - bool requesterIsOutSA; - String pickupLocationLongitude; - String pickupLocationLattitude; - String dropoffLocationLongitude; - String dropoffLocationLattitude; + String? requesterFileNo; + String? requesterMobileNo; + bool? requesterIsOutSA; + String? pickupLocationLongitude; + String? pickupLocationLattitude; + String? dropoffLocationLongitude; + String? dropoffLocationLattitude; dynamic appointmentClinicName; dynamic appointmentDoctorName; dynamic appointmentBranch; dynamic appointmentTime; - String pickupLocationName; - String dropoffLocationName; - String title; - String titleAR; - String ambulateDescription; - String ambulateDescriptionN; + String? pickupLocationName; + String? dropoffLocationName; + String? title; + String? titleAR; + String? ambulateDescription; + String? ambulateDescriptionN; PickUpRequestPresOrder( {this.id, diff --git a/lib/core/model/er/TriageInformationRequest.dart b/lib/core/model/er/TriageInformationRequest.dart index a9717d3d..53d4bfb0 100644 --- a/lib/core/model/er/TriageInformationRequest.dart +++ b/lib/core/model/er/TriageInformationRequest.dart @@ -1,34 +1,36 @@ import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; class TriageInformationRequest { - double versionID; - int channel; - int languageID; - String iPAdress; - String sessionID; - int patientID; - String tokenID; - String generalid; - int patientOutSA; - int patientTypeID; - int patientType; - int projectID; - ERTriageInformation eRTriageInformation; - HospitalsModel selectedHospital; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? sessionID; + int? patientID; + String? tokenID; + String? generalid; + int? patientOutSA; + int? patientTypeID; + int? patientType; + int? projectID; + ERTriageInformation? eRTriageInformation; + HospitalsModel? selectedHospital; + TriageInformationRequest( {this.versionID, - this.channel, - this.languageID, - this.iPAdress, - this.sessionID, - this.patientID, - this.tokenID, - this.generalid, - this.patientOutSA, - this.patientTypeID, - this.patientType, - this.projectID, - this.eRTriageInformation,this.selectedHospital}); + this.channel, + this.languageID, + this.iPAdress, + this.sessionID, + this.patientID, + this.tokenID, + this.generalid, + this.patientOutSA, + this.patientTypeID, + this.patientType, + this.projectID, + this.eRTriageInformation, + this.selectedHospital}); TriageInformationRequest.fromJson(Map json) { versionID = json['VersionID']; @@ -43,9 +45,7 @@ class TriageInformationRequest { patientTypeID = json['PatientTypeID']; patientType = json['PatientType']; projectID = json['ProjectID']; - eRTriageInformation = json['ERTriageInformation'] != null - ? new ERTriageInformation.fromJson(json['ERTriageInformation']) - : null; + eRTriageInformation = json['ERTriageInformation'] != null ? new ERTriageInformation.fromJson(json['ERTriageInformation']) : null; } Map toJson() { @@ -63,27 +63,21 @@ class TriageInformationRequest { data['PatientType'] = this.patientType; data['ProjectID'] = this.projectID; if (this.eRTriageInformation != null) { - data['ERTriageInformation'] = this.eRTriageInformation.toJson(); + data['ERTriageInformation'] = this.eRTriageInformation!.toJson(); } return data; } } class ERTriageInformation { - String notes; - String chiefComplaint; - int patientId; - int projectId; - int riskScore; - List checklist; + String? notes; + String? chiefComplaint; + int? patientId; + int? projectId; + int? riskScore; + List? checklist; - ERTriageInformation( - {this.notes, - this.chiefComplaint, - this.patientId, - this.projectId, - this.riskScore, - this.checklist}); + ERTriageInformation({this.notes, this.chiefComplaint, this.patientId, this.projectId, this.riskScore, this.checklist}); ERTriageInformation.fromJson(Map json) { notes = json['Notes']; @@ -92,9 +86,9 @@ class ERTriageInformation { projectId = json['ProjectId']; riskScore = json['RiskScore']; if (json['checklist'] != null) { - checklist = new List(); + checklist = []; json['checklist'].forEach((v) { - checklist.add(new Checklist.fromJson(v)); + checklist!.add(new Checklist.fromJson(v)); }); } } @@ -107,25 +101,20 @@ class ERTriageInformation { data['ProjectId'] = this.projectId; data['RiskScore'] = this.riskScore; if (this.checklist != null) { - data['checklist'] = this.checklist.map((v) => v.toJson()).toList(); + data['checklist'] = this.checklist!.map((v) => v.toJson()).toList(); } return data; } } class Checklist { - int isSelected; - int parameterCode; - int parameterGroup; - int parameterType; - int score; + int? isSelected; + int? parameterCode; + int? parameterGroup; + int? parameterType; + int? score; - Checklist( - {this.isSelected, - this.parameterCode, - this.parameterGroup, - this.parameterType, - this.score}); + Checklist({this.isSelected, this.parameterCode, this.parameterGroup, this.parameterType, this.score}); Checklist.fromJson(Map json) { isSelected = json['IsSelected']; diff --git a/lib/core/model/er/TriageQuestionsModel.dart b/lib/core/model/er/TriageQuestionsModel.dart index 8960973e..5467cb7d 100644 --- a/lib/core/model/er/TriageQuestionsModel.dart +++ b/lib/core/model/er/TriageQuestionsModel.dart @@ -1,14 +1,14 @@ class TriageQuestionsModel { - String adultPoints; - String headerSequence; - int parameterCode; - int parameterGroup; - int parameterType; - String pediaPoints; - String question; - String questionN; - String scoreGroup; - String titles; + String? adultPoints; + String? headerSequence; + int? parameterCode; + int? parameterGroup; + int? parameterType; + String? pediaPoints; + String? question; + String? questionN; + String? scoreGroup; + String? titles; TriageQuestionsModel( {this.adultPoints, diff --git a/lib/core/model/er/get_all_transportation_method_list_model.dart b/lib/core/model/er/get_all_transportation_method_list_model.dart index ebc9caf7..80c30da9 100644 --- a/lib/core/model/er/get_all_transportation_method_list_model.dart +++ b/lib/core/model/er/get_all_transportation_method_list_model.dart @@ -1,79 +1,56 @@ -import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; class PatientERTransportationMethod { - dynamic id; - DateTime createDate; - DateTime lastEditDate; - dynamic createdBy; - dynamic lastEditBy; - bool isActive; - String title; - String titleAR; + int? iD; + String? serviceID; + int? orderServiceID; + String? text; + String? textN; dynamic price; - dynamic isDefault; - dynamic visibility; - dynamic durationId; - String description; - String descriptionAR; - dynamic totalPrice; - dynamic vAT; + dynamic priceVAT; + dynamic priceTotal; + bool? isEnabled; + int? orderId; + int? quantity; PatientERTransportationMethod( - { - this.id, - this.createDate, - this.lastEditDate, - this.createdBy, - this.lastEditBy, - this.isActive, - this.title, - this.titleAR, + {this.iD, + this.serviceID, + this.orderServiceID, + this.text, + this.textN, this.price, - this.isDefault, - this.visibility, - this.durationId, - this.description, - this.descriptionAR, - this.totalPrice, - this.vAT}); + this.priceVAT, + this.priceTotal, + this.isEnabled, + this.orderId, + this.quantity}); - PatientERTransportationMethod.fromJson( - Map json) { - id = json['Id']; - createDate = DateUtil.convertStringToDate(json['CreateDate']); - lastEditDate = DateUtil.convertStringToDate(json['LastEditDate']); - createdBy = json['CreatedBy']; - lastEditBy = json['LastEditBy']; - isActive = json['IsActive']; - title = json['Title']; - titleAR = json['TitleAR']; + PatientERTransportationMethod.fromJson(Map json) { + iD = json['ID']; + serviceID = json['ServiceID']; + orderServiceID = json['OrderServiceID']; + text = json['Text']; + textN = json['TextN']; price = json['Price']; - isDefault = json['isDefault']; - visibility = json['Visibility']; - durationId = json['DurationId']; - description = json['Description']; - descriptionAR = json['DescriptionAR']; - totalPrice = json['TotalPrice']; - vAT = json['VAT']; + priceVAT = json['PriceVAT']; + priceTotal = json['PriceTotal']; + isEnabled = json['IsEnabled']; + orderId = json['OrderId']; + quantity = json['Quantity']; } Map toJson() { final Map data = new Map(); - data['Id'] = this.id; - data['CreateDate'] = this.createDate; - data['LastEditDate'] = this.lastEditDate; - data['CreatedBy'] = this.createdBy; - data['LastEditBy'] = this.lastEditBy; - data['IsActive'] = this.isActive; - data['Title'] = this.title; - data['TitleAR'] = this.titleAR; + data['ID'] = this.iD; + data['ServiceID'] = this.serviceID; + data['OrderServiceID'] = this.orderServiceID; + data['Text'] = this.text; + data['TextN'] = this.textN; data['Price'] = this.price; - data['isDefault'] = this.isDefault; - data['Visibility'] = this.visibility; - data['DurationId'] = this.durationId; - data['Description'] = this.description; - data['DescriptionAR'] = this.descriptionAR; - data['TotalPrice'] = this.totalPrice; - data['VAT'] = this.vAT; + data['PriceVAT'] = this.priceVAT; + data['PriceTotal'] = this.priceTotal; + data['IsEnabled'] = this.isEnabled; + data['OrderId'] = this.orderId; + data['Quantity'] = this.quantity; return data; } -} \ No newline at end of file +} diff --git a/lib/core/model/er/projectavgerwaitingtime.dart b/lib/core/model/er/projectavgerwaitingtime.dart index 9b21ec66..ccc92a7e 100644 --- a/lib/core/model/er/projectavgerwaitingtime.dart +++ b/lib/core/model/er/projectavgerwaitingtime.dart @@ -1,14 +1,14 @@ class ProjectAvgERWaitingTime { - int iD; - int projectID; - int avgTimeInMinutes; - String avgTimeInHHMM; + int? iD; + int? projectID; + int? avgTimeInMinutes; + String? avgTimeInHHMM; dynamic distanceInKilometers; - String latitude; - String longitude; - String phoneNumber; - String projectImageURL; - String projectName; + String? latitude; + String? longitude; + String? phonenumber; + String? projectImageURL; + String? projectName; ProjectAvgERWaitingTime( {this.iD, @@ -18,7 +18,7 @@ class ProjectAvgERWaitingTime { this.distanceInKilometers, this.latitude, this.longitude, - this.phoneNumber, + this.phonenumber, this.projectImageURL, this.projectName}); @@ -30,7 +30,7 @@ class ProjectAvgERWaitingTime { distanceInKilometers = json['DistanceInKilometers']; latitude = json['Latitude']; longitude = json['Longitude']; - phoneNumber = json['PhoneNumber']; + phonenumber = json['PhoneNumber']; projectImageURL = json['ProjectImageURL']; projectName = json['ProjectName']; } @@ -44,23 +44,23 @@ class ProjectAvgERWaitingTime { data['DistanceInKilometers'] = this.distanceInKilometers; data['Latitude'] = this.latitude; data['Longitude'] = this.longitude; - data['PhoneNumber'] = this.phoneNumber; + data['PhoneNumber'] = this.phonenumber; data['ProjectImageURL'] = this.projectImageURL; data['ProjectName'] = this.projectName; return data; } } //class ProjectAvgERWaitingTime { -// int iD; -// int projectID; -// int avgTimeInMinutes; -// String avgTimeInHHMM; -// String distanceInKilometers; -// String latitude; -// String longitude; -// String phoneNumber; -// String projectImageURL; -// String projectName; +// int? iD; +// int? projectID; +// int? avgTimeInMinutes; +// String? avgTimeInHHMM; +// String? distanceInKilometers; +// String? latitude; +// String? longitude; +// String? phonenum?ber; +// String? projectImageURL; +// String? projectName; // // ProjectAvgERWaitingTime( // {this.iD, @@ -70,7 +70,7 @@ class ProjectAvgERWaitingTime { // this.distanceInKilometers, // this.latitude, // this.longitude, -// this.phoneNumber, +// this.phonenum?ber, // this.projectImageURL, // this.projectName}); // @@ -82,7 +82,7 @@ class ProjectAvgERWaitingTime { // distanceInKilometers = json['DistanceInKilometers']; // latitude = json['Latitude']; // longitude = json['Longitude']; -// phoneNumber = json['PhoneNumber']; +// phonenum?ber = json['Phonenum?ber']; // projectImageURL = json['ProjectImageURL']; // projectName = json['ProjectName']; // } @@ -96,7 +96,7 @@ class ProjectAvgERWaitingTime { // data['DistanceInKilometers'] = this.distanceInKilometers; // data['Latitude'] = this.latitude; // data['Longitude'] = this.longitude; -// data['PhoneNumber'] = this.phoneNumber; +// data['Phonenum?ber'] = this.phonenum?ber; // data['ProjectImageURL'] = this.projectImageURL; // data['ProjectName'] = this.projectName; // return data; diff --git a/lib/core/model/eye/AppoimentAllHistoryResult.dart b/lib/core/model/eye/AppoimentAllHistoryResult.dart index ed123023..fb62f3f5 100644 --- a/lib/core/model/eye/AppoimentAllHistoryResult.dart +++ b/lib/core/model/eye/AppoimentAllHistoryResult.dart @@ -1,139 +1,141 @@ import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; class AppoimentAllHistoryResultList { - String setupID; - int projectID; - int appointmentNo; - String appointmentDate; - Null appointmentDateN; - int appointmentType; - DateTime bookDate; + String? setupID; + int? projectID; + int? appointmentNo; + String? appointmentDate; + dynamic appointmentDateN; + int? appointmentType; + DateTime? bookDate; dynamic patientType; - int patientID; + int? patientID; dynamic clinicID; - int doctorID; - String endDate; - String startTime; - String endTime; + int? doctorID; + String? endDate; + String? startTime; + String? endTime; dynamic status; dynamic visitType; - int visitFor; - int patientStatusType; - int companyID; - int bookedBy; - String bookedOn; - int confirmedBy; - String confirmedOn; - int arrivalChangedBy; - String arrivedOn; - Null editedBy; - Null editedOn; - Null doctorName; - Null doctorNameN; - String statusDesc; - Null statusDescN; - bool vitalStatus; - Null vitalSignAppointmentNo; - int episodeID; - int actualDoctorRate; - String clinicName; - bool complainExists; - String doctorImageURL; - String doctorNameObj; - int doctorRate; - List doctorSpeciality; - String doctorTitle; - int gender; - String genderDescription; - bool iSAllowOnlineCheckedIN; - bool isActiveDoctor; - bool isActiveDoctorProfile; - bool isDoctorAllowVedioCall; - bool isExecludeDoctor; - int isFollowup; - bool isLiveCareAppointment; - bool isMedicalReportRequested; - bool isOnlineCheckedIN; - String latitude; - List listHISGetContactLensPerscription; - List listHISGetGlassPerscription; - String longitude; - int nextAction; - int noOfPatientsRate; - int originalClinicID; - int originalProjectID; - String projectName; - String qR; - int remaniningHoursTocanPay; - bool sMSButtonVisable; + int? visitFor; + int? patientStatusType; + int? companyID; + int? bookedBy; + String? bookedOn; + int? confirmedBy; + String? confirmedOn; + int? arrivalChangedBy; + String? arrivedOn; + dynamic editedBy; + dynamic editedOn; + dynamic doctorName; + dynamic doctorNameN; + String? statusDesc; + dynamic statusDescN; + bool? vitalStatus; + dynamic vitalSignAppointmentNo; + int? episodeID; + int? actualDoctorRate; + String? clinicName; + bool? complainExists; + String? doctorImageURL; + String? doctorNameObj; + int? doctorRate; + List? doctorSpeciality; + String? doctorTitle; + int? gender; + String? genderDescription; + bool? iSAllowOnlineCheckedIN; + bool? isActiveDoctor; + bool? isActiveDoctorProfile; + bool? isDoctorAllowVedioCall; + bool? isExecludeDoctor; + int? isFollowup; + bool? isLiveCareAppointment; + bool? isMedicalReportRequested; + bool? isOnlineCheckedIN; + String? latitude; + List? listHISGetContactLensPerscription; + List? listHISGetGlassPerscription; + String? longitude; + int? nextAction; + int? noOfPatientsRate; + int? originalClinicID; + int? originalProjectID; + String? projectName; + String? qR; + int? remaniningHoursTocanPay; + bool? sMSButtonVisable; + bool? isInOutPatient; - AppoimentAllHistoryResultList( - {this.setupID, - this.projectID, - this.appointmentNo, - this.appointmentDate, - this.appointmentDateN, - this.appointmentType, - this.bookDate, - this.patientID, - this.doctorID, - this.endDate, - this.startTime, - this.endTime, - this.status, - this.visitFor, - this.patientStatusType, - this.companyID, - this.bookedBy, - this.bookedOn, - this.confirmedBy, - this.confirmedOn, - this.arrivalChangedBy, - this.arrivedOn, - this.editedBy, - this.editedOn, - this.doctorName, - this.doctorNameN, - this.statusDesc, - this.statusDescN, - this.vitalStatus, - this.vitalSignAppointmentNo, - this.episodeID, - this.actualDoctorRate, - this.clinicName, - this.complainExists, - this.doctorImageURL, - this.doctorNameObj, - this.doctorRate, - this.doctorSpeciality, - this.doctorTitle, - this.gender, - this.genderDescription, - this.iSAllowOnlineCheckedIN, - this.isActiveDoctor, - this.isActiveDoctorProfile, - this.isDoctorAllowVedioCall, - this.isExecludeDoctor, - this.isFollowup, - this.isLiveCareAppointment, - this.isMedicalReportRequested, - this.isOnlineCheckedIN, - this.latitude, - this.listHISGetContactLensPerscription, - this.listHISGetGlassPerscription, - this.longitude, - this.nextAction, - this.noOfPatientsRate, - this.originalClinicID, - this.originalProjectID, - this.projectName, - this.qR, - this.remaniningHoursTocanPay, - this.sMSButtonVisable, - this.clinicID, - this.patientType, - - this.visitType}); + AppoimentAllHistoryResultList({ + this.setupID, + this.projectID, + this.appointmentNo, + this.appointmentDate, + this.appointmentDateN, + this.appointmentType, + this.bookDate, + this.patientID, + this.doctorID, + this.endDate, + this.startTime, + this.endTime, + this.status, + this.visitFor, + this.patientStatusType, + this.companyID, + this.bookedBy, + this.bookedOn, + this.confirmedBy, + this.confirmedOn, + this.arrivalChangedBy, + this.arrivedOn, + this.editedBy, + this.editedOn, + this.doctorName, + this.doctorNameN, + this.statusDesc, + this.statusDescN, + this.vitalStatus, + this.vitalSignAppointmentNo, + this.episodeID, + this.actualDoctorRate, + this.clinicName, + this.complainExists, + this.doctorImageURL, + this.doctorNameObj, + this.doctorRate, + this.doctorSpeciality, + this.doctorTitle, + this.gender, + this.genderDescription, + this.iSAllowOnlineCheckedIN, + this.isActiveDoctor, + this.isActiveDoctorProfile, + this.isDoctorAllowVedioCall, + this.isExecludeDoctor, + this.isFollowup, + this.isLiveCareAppointment, + this.isMedicalReportRequested, + this.isOnlineCheckedIN, + this.latitude, + this.listHISGetContactLensPerscription, + this.listHISGetGlassPerscription, + this.longitude, + this.nextAction, + this.noOfPatientsRate, + this.originalClinicID, + this.originalProjectID, + this.projectName, + this.qR, + this.remaniningHoursTocanPay, + this.sMSButtonVisable, + this.clinicID, + this.patientType, + this.visitType, + this.isInOutPatient, + }); AppoimentAllHistoryResultList.fromJson(Map json) { setupID = json['SetupID']; @@ -176,7 +178,7 @@ class AppoimentAllHistoryResultList { doctorImageURL = json['DoctorImageURL']; doctorNameObj = json['DoctorNameObj']; doctorRate = json['DoctorRate']; - // doctorSpeciality = json['DoctorSpeciality'].cast(); + if (doctorSpeciality != null) doctorSpeciality = json['DoctorSpeciality'].cast(); doctorTitle = json['DoctorTitle']; gender = json['Gender']; genderDescription = json['GenderDescription']; @@ -191,18 +193,15 @@ class AppoimentAllHistoryResultList { isOnlineCheckedIN = json['IsOnlineCheckedIN']; latitude = json['Latitude']; if (json['List_HIS_GetContactLensPerscription'] != null) { - listHISGetContactLensPerscription = - new List(); + listHISGetContactLensPerscription = []; json['List_HIS_GetContactLensPerscription'].forEach((v) { - listHISGetContactLensPerscription - .add(new ListHISGetContactLensPerscription.fromJson(v)); + listHISGetContactLensPerscription!.add(new ListHISGetContactLensPerscription.fromJson(v)); }); } if (json['List_HIS_GetGlassPerscription'] != null) { - listHISGetGlassPerscription = new List(); + listHISGetGlassPerscription = []; json['List_HIS_GetGlassPerscription'].forEach((v) { - listHISGetGlassPerscription - .add(new ListHISGetGlassPerscription.fromJson(v)); + listHISGetGlassPerscription!.add(new ListHISGetGlassPerscription.fromJson(v)); }); } longitude = json['Longitude']; @@ -218,9 +217,10 @@ class AppoimentAllHistoryResultList { patientType = json['patientType']; status = json['status']; visitType = json['visitType']; + isInOutPatient = json['IsInOutPatient']; } - Map toJson() { + Map toJson() { final Map data = new Map(); data['SetupID'] = this.setupID; data['ProjectID'] = this.projectID; @@ -278,13 +278,19 @@ class AppoimentAllHistoryResultList { data['Latitude'] = this.latitude; if (this.listHISGetContactLensPerscription != null) { data['List_HIS_GetContactLensPerscription'] = this - .listHISGetContactLensPerscription - .map((v) => v.toJson()) + .listHISGetContactLensPerscription! + .map( + (v) => v.toJson(), + ) .toList(); } if (this.listHISGetGlassPerscription != null) { - data['List_HIS_GetGlassPerscription'] = - this.listHISGetGlassPerscription.map((v) => v.toJson()).toList(); + data['List_HIS_GetGlassPerscription'] = this + .listHISGetGlassPerscription! + .map( + (v) => v.toJson(), + ) + .toList(); } data['Longitude'] = this.longitude; data['NextAction'] = this.nextAction; @@ -304,13 +310,13 @@ class AppoimentAllHistoryResultList { } class ListHISGetContactLensPerscription { - String setupId; - int projectId; - int patientType; - int patientId; - int encounterType; - int encounterNo; - int oDOS; + String? setupId; + int? projectId; + int? patientType; + int? patientId; + int? encounterType; + int? encounterNo; + int? oDOS; dynamic brand; dynamic baseCurve; dynamic power; @@ -318,30 +324,30 @@ class ListHISGetContactLensPerscription { dynamic oZ; dynamic cT; dynamic blend; - String remarks; - int status; - bool isActive; - String createdOn; + String? remarks; + int? status; + bool? isActive; + String? createdOn; ListHISGetContactLensPerscription( {this.setupId, - this.projectId, - this.patientType, - this.patientId, - this.encounterType, - this.encounterNo, - this.oDOS, - this.brand, - this.baseCurve, - this.power, - this.diameter, - this.oZ, - this.cT, - this.blend, - this.remarks, - this.status, - this.isActive, - this.createdOn}); + this.projectId, + this.patientType, + this.patientId, + this.encounterType, + this.encounterNo, + this.oDOS, + this.brand, + this.baseCurve, + this.power, + this.diameter, + this.oZ, + this.cT, + this.blend, + this.remarks, + this.status, + this.isActive, + this.createdOn}); ListHISGetContactLensPerscription.fromJson(Map json) { setupId = json['SetupId']; @@ -364,7 +370,7 @@ class ListHISGetContactLensPerscription { createdOn = json['CreatedOn']; } - Map toJson() { + Map toJson() { final Map data = new Map(); data['SetupId'] = this.setupId; data['ProjectId'] = this.projectId; @@ -390,53 +396,53 @@ class ListHISGetContactLensPerscription { class ListHISGetGlassPerscription { dynamic projectID; - String setupID; + String? setupID; dynamic patientId; dynamic encounterType; dynamic encounterNo; - String visionType; - double rightEyeSpherical; + String? visionType; + double? rightEyeSpherical; dynamic rightEyeCylinder; dynamic rightEyeAxis; dynamic rightEyePrism; dynamic rightEyeVA; - String rightEyeRemarks; + String? rightEyeRemarks; dynamic leftEyeSpherical; dynamic leftEyeCylinder; dynamic leftEyeAxis; dynamic leftEyePrism; dynamic leftEyeVA; - String leftEyeRemarks; + String? leftEyeRemarks; dynamic pD; dynamic bVD; dynamic status; - bool isActive; - String createdOn; + bool? isActive; + String? createdOn; ListHISGetGlassPerscription( {this.projectID, - this.setupID, - this.patientId, - this.encounterType, - this.encounterNo, - this.visionType, - this.rightEyeSpherical, - this.rightEyeCylinder, - this.rightEyeAxis, - this.rightEyePrism, - this.rightEyeVA, - this.rightEyeRemarks, - this.leftEyeSpherical, - this.leftEyeCylinder, - this.leftEyeAxis, - this.leftEyePrism, - this.leftEyeVA, - this.leftEyeRemarks, - this.pD, - this.bVD, - this.status, - this.isActive, - this.createdOn}); + this.setupID, + this.patientId, + this.encounterType, + this.encounterNo, + this.visionType, + this.rightEyeSpherical, + this.rightEyeCylinder, + this.rightEyeAxis, + this.rightEyePrism, + this.rightEyeVA, + this.rightEyeRemarks, + this.leftEyeSpherical, + this.leftEyeCylinder, + this.leftEyeAxis, + this.leftEyePrism, + this.leftEyeVA, + this.leftEyeRemarks, + this.pD, + this.bVD, + this.status, + this.isActive, + this.createdOn}); ListHISGetGlassPerscription.fromJson(Map json) { projectID = json['ProjectID']; @@ -464,7 +470,7 @@ class ListHISGetGlassPerscription { createdOn = json['CreatedOn']; } - Map toJson() { + Map toJson() { final Map data = new Map(); data['ProjectID'] = this.projectID; data['SetupID'] = this.setupID; @@ -492,6 +498,3 @@ class ListHISGetGlassPerscription { return data; } } - - - diff --git a/lib/core/model/eye/AppointmentFilter.dart b/lib/core/model/eye/AppointmentFilter.dart index 1f4b0ae5..58146a92 100644 --- a/lib/core/model/eye/AppointmentFilter.dart +++ b/lib/core/model/eye/AppointmentFilter.dart @@ -1,8 +1,8 @@ import 'AppoimentAllHistoryResult.dart'; class AppointmentFilter { - List appointmentAllHistoryResultList = List(); - String filterName; + ListappointmentAllHistoryResultList = []; + String? filterName; AppointmentFilter( AppoimentAllHistoryResultList allHistoryResultList, String filterName) { diff --git a/lib/core/model/family-file/add_family_file_request.dart b/lib/core/model/family-file/add_family_file_request.dart index cfec8e39..f03fa80a 100644 --- a/lib/core/model/family-file/add_family_file_request.dart +++ b/lib/core/model/family-file/add_family_file_request.dart @@ -1,24 +1,24 @@ class AddFamilyFileReq { - int searchType; - int sharedPatientID; - String sharedPatientIdentificationID; - String sharedPatientMobileNumber; - String zipCode; - bool isRegister; - int patientStatus; - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - String sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; - int patientID; - String tokenID; - int patientTypeID; - int patientType; + int? searchType; + int? sharedPatientID; + String? sharedPatientIdentificationID; + String? sharedPatientMobileNumber; + String? zipCode; + bool? isRegister; + int? patientStatus; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + String? sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + int? patientID; + String? tokenID; + int? patientTypeID; + int? patientType; AddFamilyFileReq( {this.searchType, diff --git a/lib/core/model/family-file/insert_share_file_request.dart b/lib/core/model/family-file/insert_share_file_request.dart index 02fa9a0b..b153a366 100644 --- a/lib/core/model/family-file/insert_share_file_request.dart +++ b/lib/core/model/family-file/insert_share_file_request.dart @@ -1,21 +1,21 @@ class InsertSharePatientFileReq { - int responseID; - String shareFamilyPatientName; - int status; - int regionID; - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - String sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; - int patientID; - String tokenID; - int patientTypeID; - int patientType; + int? responseID; + String? shareFamilyPatientName; + int? status; + int? regionID; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + String? sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + int? patientID; + String? tokenID; + int? patientTypeID; + int? patientType; InsertSharePatientFileReq( {this.responseID, diff --git a/lib/core/model/feedback/COC_items.dart b/lib/core/model/feedback/COC_items.dart index 068c8bee..ed62d8ba 100644 --- a/lib/core/model/feedback/COC_items.dart +++ b/lib/core/model/feedback/COC_items.dart @@ -1,60 +1,63 @@ class COCItem { - Null appointment; - String appointmentClinicName; - String appointmentDate; - String appointmentProjectName; - String cOCID; - String cOCTitle; - String channel; + dynamic appointment; + String? appointmentClinicName; + String? appointmentDate; + String? appointmentProjectName; + String? cOCID; + String? cOCTitle; + String? channel; dynamic clinic; - String clinicID; - String date; + String? clinicID; + String? date; dynamic detail; dynamic doctor; - String doctorID; - String formType; - int formTypeID; + String? doctorID; + String? formType; + int? formTypeID; dynamic identificationNo; - int itemID; + int? itemID; dynamic mobileNo; dynamic naturename; dynamic patientID; dynamic patientName; dynamic project; dynamic projectID; - String solution; - String status; - String statusAr; + String? solution; + String? status; + String? statusAr; dynamic statusEn; + int? statusId; - COCItem( - {this.appointment, - this.appointmentClinicName, - this.appointmentDate, - this.appointmentProjectName, - this.cOCID, - this.cOCTitle, - this.channel, - this.clinic, - this.clinicID, - this.date, - this.detail, - this.doctor, - this.doctorID, - this.formType, - this.formTypeID, - this.identificationNo, - this.itemID, - this.mobileNo, - this.naturename, - this.patientID, - this.patientName, - this.project, - this.projectID, - this.solution, - this.status, - this.statusAr, - this.statusEn}); + COCItem({ + this.appointment, + this.appointmentClinicName, + this.appointmentDate, + this.appointmentProjectName, + this.cOCID, + this.cOCTitle, + this.channel, + this.clinic, + this.clinicID, + this.date, + this.detail, + this.doctor, + this.doctorID, + this.formType, + this.formTypeID, + this.identificationNo, + this.itemID, + this.mobileNo, + this.naturename, + this.patientID, + this.patientName, + this.project, + this.projectID, + this.solution, + this.status, + this.statusAr, + this.statusEn, + this.statusId, + }); COCItem.fromJson(Map json) { appointment = json['Appointment']; @@ -84,6 +87,7 @@ class COCItem { status = json['Status']; statusAr = json['StatusAr']; statusEn = json['StatusEn']; + statusId = json['StatusId']; } Map toJson() { diff --git a/lib/core/model/feedback/request_insert_coc_item.dart b/lib/core/model/feedback/request_insert_coc_item.dart index e8b6fce5..e285999c 100644 --- a/lib/core/model/feedback/request_insert_coc_item.dart +++ b/lib/core/model/feedback/request_insert_coc_item.dart @@ -1,66 +1,68 @@ class RequestInsertCOCItem { - bool isUserLoggedIn; - String mobileNo; - int identificationNo; - int patientID; - int patientOutSA; - int patientTypeID; - String tokenID; - String patientName; - int projectID; - String fileName; - String attachment; - String uILanguage; - String browserInfo; - String cOCTypeName; - String formTypeID; - String details; - String deviceInfo; - String deviceType; - String title; - String resolution; - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - String sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; - int patientType; - double appVersion; + bool? isUserLoggedIn; + String? mobileNo; + int? identificationNo; + int? patientID; + int? patientOutSA; + int? patientTypeID; + String? tokenID; + String? patientName; + int? projectID; + String? fileName; + String? attachment; + String? uILanguage; + String? browserInfo; + String? cOCTypeName; + String? formTypeID; + String? details; + String? deviceInfo; + String? deviceType; + String? title; + String? resolution; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + String? sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + int? patientType; + double? appVersion; + bool? forDemo; RequestInsertCOCItem( {this.isUserLoggedIn, - this.mobileNo, - this.identificationNo, - this.patientID, - this.patientOutSA, - this.patientTypeID, - this.tokenID, - this.patientName, - this.projectID, - this.fileName, - this.attachment, - this.uILanguage, - this.browserInfo, - this.cOCTypeName, - this.formTypeID, - this.details, - this.deviceInfo, - this.deviceType, - this.title, - this.resolution, - this.versionID, - this.channel, - this.languageID, - this.iPAdress, - this.generalid, - this.sessionID, - this.isDentalAllowedBackend, - this.deviceTypeID, - this.patientType, - this.appVersion}); + this.mobileNo, + this.identificationNo, + this.patientID, + this.patientOutSA, + this.patientTypeID, + this.tokenID, + this.patientName, + this.projectID, + this.fileName, + this.attachment, + this.uILanguage, + this.browserInfo, + this.cOCTypeName, + this.formTypeID, + this.details, + this.deviceInfo, + this.deviceType, + this.title, + this.resolution, + this.versionID, + this.channel, + this.languageID, + this.iPAdress, + this.generalid, + this.sessionID, + this.isDentalAllowedBackend, + this.deviceTypeID, + this.patientType, + this.appVersion, + this.forDemo}); RequestInsertCOCItem.fromJson(Map json) { isUserLoggedIn = json['IsUserLoggedIn']; @@ -93,6 +95,7 @@ class RequestInsertCOCItem { deviceTypeID = json['DeviceTypeID']; patientType = json['PatientType']; appVersion = json['AppVersion']; + forDemo = json['ForDemo']; } Map toJson() { @@ -127,6 +130,8 @@ class RequestInsertCOCItem { data['DeviceTypeID'] = this.deviceTypeID; data['PatientType'] = this.patientType; data['AppVersion'] = this.appVersion; + data['ForDemo'] = this.forDemo; + return data; } } diff --git a/lib/core/model/geofencing/requests/GeoZonesRequestModel.dart b/lib/core/model/geofencing/requests/GeoZonesRequestModel.dart index 219c46ae..265fedde 100644 --- a/lib/core/model/geofencing/requests/GeoZonesRequestModel.dart +++ b/lib/core/model/geofencing/requests/GeoZonesRequestModel.dart @@ -1,5 +1,5 @@ class GeoZonesRequestModel { - final String PatientID; + final String? PatientID; GeoZonesRequestModel({this.PatientID}); diff --git a/lib/core/model/geofencing/requests/LogGeoZoneRequestModel.dart b/lib/core/model/geofencing/requests/LogGeoZoneRequestModel.dart index e21a7d69..abf67a61 100644 --- a/lib/core/model/geofencing/requests/LogGeoZoneRequestModel.dart +++ b/lib/core/model/geofencing/requests/LogGeoZoneRequestModel.dart @@ -4,7 +4,7 @@ class LogGeoZoneRequestModel { final int PointsID; final int GeoType; - LogGeoZoneRequestModel({@required this.PointsID, @required this.GeoType}); + LogGeoZoneRequestModel({required this.PointsID, required this.GeoType}); Map toFlatMap() { return {"PointsID": PointsID.toString(), "GeoType": GeoType.toString()}; diff --git a/lib/core/model/geofencing/responses/GeoZonesResponseModel.dart b/lib/core/model/geofencing/responses/GeoZonesResponseModel.dart index 58771fab..eaf89db5 100644 --- a/lib/core/model/geofencing/responses/GeoZonesResponseModel.dart +++ b/lib/core/model/geofencing/responses/GeoZonesResponseModel.dart @@ -1,27 +1,27 @@ import 'package:diplomaticquarterapp/generated/json/base/json_convert_content.dart'; import 'package:diplomaticquarterapp/generated/json/base/json_field.dart'; -class GeoZonesResponseModel with JsonConvert { +class GeoZonesResponseModel extends JsonConvert { @JSONField(name: "GEOF_ID") - int geofId; + int? geofId; @JSONField(name: "Description") - String description; + String? description; @JSONField(name: "DescriptionN") - String descriptionN; + String? descriptionN; @JSONField(name: "Latitude") - String latitude; + String? latitude; @JSONField(name: "Longitude") - String longitude; + String? longitude; @JSONField(name: "Radius") - int radius; + int? radius; @JSONField(name: "Type") - int type; + int? type; @JSONField(name: "ProjectID") - int projectID; + int? projectID; @JSONField(name: "ImageURL") - String imageURL; + String? imageURL; @JSONField(name: "IsCity") - bool isCity; + bool? isCity; // Outside Server Response bool isRegistered = false; @@ -29,7 +29,7 @@ class GeoZonesResponseModel with JsonConvert { bool onExit = true; String geofenceId() { - return "$geofId\_${description.replaceAll(" ", "")}"; + return "$geofId\_${description!.replaceAll(" ", "")}"; } static get(String coordinates, int radius, String name) { diff --git a/lib/core/model/geofencing/responses/LogGeoZoneResponseModel.dart b/lib/core/model/geofencing/responses/LogGeoZoneResponseModel.dart index 2242755f..e27633a4 100644 --- a/lib/core/model/geofencing/responses/LogGeoZoneResponseModel.dart +++ b/lib/core/model/geofencing/responses/LogGeoZoneResponseModel.dart @@ -1,26 +1,26 @@ import 'package:diplomaticquarterapp/generated/json/base/json_convert_content.dart'; import 'package:diplomaticquarterapp/generated/json/base/json_field.dart'; -class LogGeoZoneResponseModel with JsonConvert { +class LogGeoZoneResponseModel extends JsonConvert { @JSONField(name: "LanguageID") - int languageID; + int? languageID; @JSONField(name: "ErrorCode") dynamic errorCode; @JSONField(name: "ErrorEndUserMessage") - String errorEndUserMessage; + String? errorEndUserMessage; @JSONField(name: "ErrorEndUserMessageN") dynamic errorEndUserMessageN; @JSONField(name: "ErrorMessage") dynamic errorMessage; @JSONField(name: "ErrorType") - int errorType; + int? errorType; @JSONField(name: "IsAuthenticated") - bool isAuthenticated; + bool? isAuthenticated; @JSONField(name: "SuccessMsg") dynamic successMsg; @JSONField(name: "SuccessMsgN") dynamic successMsgN; - int statusCode; + int? statusCode; @JSONField(name: "MessageStatus") - int messageStatus; + int? messageStatus; } diff --git a/lib/core/model/health_calcolator/get_doctor_by_time_model.dart b/lib/core/model/health_calcolator/get_doctor_by_time_model.dart new file mode 100644 index 00000000..754668c7 --- /dev/null +++ b/lib/core/model/health_calcolator/get_doctor_by_time_model.dart @@ -0,0 +1,198 @@ +class DoctorListByTimeModel { + dynamic clinicID; + String? clinicName; + String? doctorTitle; + dynamic iD; + String? name; + dynamic projectID; + String? projectName; + dynamic actualDoctorRate; + dynamic clinicRoomNo; + dynamic date; + dynamic dayName; + double? decimalDoctorRate; + dynamic doctorAvailability; + dynamic doctorID; + String? doctorImageURL; + dynamic doctorProfile; + dynamic doctorProfileInfo; + dynamic doctorRate; + dynamic doctorStarsRate; + dynamic gender; + String? genderDescription; + bool? isAllowWaitList; + bool? isAppointmentAllowed; + bool? isDoctorAllowVedioCall; + bool? isDoctorDummy; + bool? isDoctorHasPrePostImages; + bool? isLiveCare; + String? latitude; + String? longitude; + String? nationalityFlagURL; + String? nationalityID; + String? nationalityName; + dynamic nearestFreeSlot; + dynamic noOfPatientsRate; + dynamic originalClinicID; + dynamic personRate; + dynamic projectDistanceInKiloMeters; + String? qR; + dynamic qRString; + dynamic rateNumber; + dynamic serviceID; + String? setupID; + List? speciality; + dynamic workingHours; + + DoctorListByTimeModel( + {this.clinicID, + this.clinicName, + this.doctorTitle, + this.iD, + this.name, + this.projectID, + this.projectName, + this.actualDoctorRate, + this.clinicRoomNo, + this.date, + this.dayName, + this.decimalDoctorRate, + this.doctorAvailability, + this.doctorID, + this.doctorImageURL, + this.doctorProfile, + this.doctorProfileInfo, + this.doctorRate, + this.doctorStarsRate, + this.gender, + this.genderDescription, + this.isAllowWaitList, + this.isAppointmentAllowed, + this.isDoctorAllowVedioCall, + this.isDoctorDummy, + this.isDoctorHasPrePostImages, + this.isLiveCare, + this.latitude, + this.longitude, + this.nationalityFlagURL, + this.nationalityID, + this.nationalityName, + this.nearestFreeSlot, + this.noOfPatientsRate, + this.originalClinicID, + this.personRate, + this.projectDistanceInKiloMeters, + this.qR, + this.qRString, + this.rateNumber, + this.serviceID, + this.setupID, + this.speciality, + this.workingHours}); + + DoctorListByTimeModel.fromJson(Map json) { + clinicID = json['ClinicID']; + clinicName = json['ClinicName']; + doctorTitle = json['DoctorTitle']; + iD = json['ID']; + name = json['Name']; + projectID = json['ProjectID']; + projectName = json['ProjectName']; + actualDoctorRate = json['ActualDoctorRate']; + clinicRoomNo = json['ClinicRoomNo']; + date = json['Date']; + dayName = json['DayName']; + decimalDoctorRate = json['DecimalDoctorRate']; + doctorAvailability = json['DoctorAvailability']; + doctorID = json['DoctorID']; + doctorImageURL = json['DoctorImageURL']; + doctorProfile = json['DoctorProfile']; + doctorProfileInfo = json['DoctorProfileInfo']; + doctorRate = json['DoctorRate']; + doctorStarsRate = json['DoctorStarsRate']; + gender = json['Gender']; + genderDescription = json['GenderDescription']; + isAllowWaitList = json['IsAllowWaitList']; + isAppointmentAllowed = json['IsAppointmentAllowed']; + isDoctorAllowVedioCall = json['IsDoctorAllowVedioCall']; + isDoctorDummy = json['IsDoctorDummy']; + isDoctorHasPrePostImages = json['IsDoctorHasPrePostImages']; + isLiveCare = json['IsLiveCare']; + latitude = json['Latitude']; + longitude = json['Longitude']; + nationalityFlagURL = json['NationalityFlagURL']; + nationalityID = json['NationalityID']; + nationalityName = json['NationalityName']; + nearestFreeSlot = json['NearestFreeSlot']; + noOfPatientsRate = json['NoOfPatientsRate']; + originalClinicID = json['OriginalClinicID']; + personRate = json['PersonRate']; + projectDistanceInKiloMeters = json['ProjectDistanceInKiloMeters']; + qR = json['QR']; + qRString = json['QRString']; + rateNumber = json['RateNumber']; + serviceID = json['ServiceID']; + setupID = json['SetupID']; + speciality = json['Speciality'].cast(); + workingHours = json['WorkingHours']; + } + + Map toJson() { + final Map data = new Map(); + data['ClinicID'] = this.clinicID; + data['ClinicName'] = this.clinicName; + data['DoctorTitle'] = this.doctorTitle; + data['ID'] = this.iD; + data['Name'] = this.name; + data['ProjectID'] = this.projectID; + data['ProjectName'] = this.projectName; + data['ActualDoctorRate'] = this.actualDoctorRate; + data['ClinicRoomNo'] = this.clinicRoomNo; + data['Date'] = this.date; + data['DayName'] = this.dayName; + data['DecimalDoctorRate'] = this.decimalDoctorRate; + data['DoctorAvailability'] = this.doctorAvailability; + data['DoctorID'] = this.doctorID; + data['DoctorImageURL'] = this.doctorImageURL; + data['DoctorProfile'] = this.doctorProfile; + data['DoctorProfileInfo'] = this.doctorProfileInfo; + data['DoctorRate'] = this.doctorRate; + data['DoctorStarsRate'] = this.doctorStarsRate; + data['Gender'] = this.gender; + data['GenderDescription'] = this.genderDescription; + data['IsAllowWaitList'] = this.isAllowWaitList; + data['IsAppointmentAllowed'] = this.isAppointmentAllowed; + data['IsDoctorAllowVedioCall'] = this.isDoctorAllowVedioCall; + data['IsDoctorDummy'] = this.isDoctorDummy; + data['IsDoctorHasPrePostImages'] = this.isDoctorHasPrePostImages; + data['IsLiveCare'] = this.isLiveCare; + data['Latitude'] = this.latitude; + data['Longitude'] = this.longitude; + data['NationalityFlagURL'] = this.nationalityFlagURL; + data['NationalityID'] = this.nationalityID; + data['NationalityName'] = this.nationalityName; + data['NearestFreeSlot'] = this.nearestFreeSlot; + data['NoOfPatientsRate'] = this.noOfPatientsRate; + data['OriginalClinicID'] = this.originalClinicID; + data['PersonRate'] = this.personRate; + data['ProjectDistanceInKiloMeters'] = this.projectDistanceInKiloMeters; + data['QR'] = this.qR; + data['QRString'] = this.qRString; + data['RateNumber'] = this.rateNumber; + data['ServiceID'] = this.serviceID; + data['SetupID'] = this.setupID; + data['Speciality'] = this.speciality; + data['WorkingHours'] = this.workingHours; + return data; + } +} + +class DoctorsListTime { + List doctorsByTimeList = []; + String filterName = ""; + + DoctorsListTime({filterName, DoctorListByTimeModel? doctor}) { + doctorsByTimeList.add(doctor!); + this.filterName = filterName; + } +} diff --git a/lib/core/model/health_calcolator/get_doctor_by_time_request_model.dart b/lib/core/model/health_calcolator/get_doctor_by_time_request_model.dart new file mode 100644 index 00000000..98c1c3d0 --- /dev/null +++ b/lib/core/model/health_calcolator/get_doctor_by_time_request_model.dart @@ -0,0 +1,80 @@ +class DoctorListByTimeRequestModel { + int? clinicID; + bool? isGetNearAppointment; + bool? continueDentalPlan; + bool? isSearchAppointmnetByClinicID; + int? patientID; + int? latitude; + int? longitude; + bool? license; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + dynamic sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + + DoctorListByTimeRequestModel( + {this.clinicID, + this.isGetNearAppointment, + this.continueDentalPlan, + this.isSearchAppointmnetByClinicID, + this.patientID, + this.latitude, + this.longitude, + this.license, + this.versionID, + this.channel, + this.languageID, + this.iPAdress, + this.generalid, + this.patientOutSA, + this.sessionID, + this.isDentalAllowedBackend, + this.deviceTypeID}); + + DoctorListByTimeRequestModel.fromJson(Map json) { + clinicID = json['ClinicID']; + isGetNearAppointment = json['IsGetNearAppointment']; + continueDentalPlan = json['ContinueDentalPlan']; + isSearchAppointmnetByClinicID = json['IsSearchAppointmnetByClinicID']; + patientID = json['PatientID']; + latitude = json['Latitude']; + longitude = json['Longitude']; + license = json['License']; + versionID = json['VersionID']; + channel = json['Channel']; + languageID = json['LanguageID']; + iPAdress = json['IPAdress']; + generalid = json['generalid']; + patientOutSA = json['PatientOutSA']; + sessionID = json['SessionID']; + isDentalAllowedBackend = json['isDentalAllowedBackend']; + deviceTypeID = json['DeviceTypeID']; + } + + Map toJson() { + final Map data = new Map(); + data['ClinicID'] = this.clinicID; + data['IsGetNearAppointment'] = this.isGetNearAppointment; + data['ContinueDentalPlan'] = this.continueDentalPlan; + data['IsSearchAppointmnetByClinicID'] = this.isSearchAppointmnetByClinicID; + data['PatientID'] = this.patientID; + data['Latitude'] = this.latitude; + data['Longitude'] = this.longitude; + data['License'] = this.license; + data['VersionID'] = this.versionID; + data['Channel'] = this.channel; + data['LanguageID'] = this.languageID; + data['IPAdress'] = this.iPAdress; + data['generalid'] = this.generalid; + data['PatientOutSA'] = this.patientOutSA; + data['SessionID'] = this.sessionID; + data['isDentalAllowedBackend'] = this.isDentalAllowedBackend; + data['DeviceTypeID'] = this.deviceTypeID; + return data; + } +} diff --git a/lib/core/model/health_calcolator/get_doctor_list_calcolation_model.dart b/lib/core/model/health_calcolator/get_doctor_list_calcolation_model.dart new file mode 100644 index 00000000..22c5b37f --- /dev/null +++ b/lib/core/model/health_calcolator/get_doctor_list_calcolation_model.dart @@ -0,0 +1,64 @@ +class GetDoctorListModel { + int? calcID; + int? projectID; + int? clinicID; + String? clinicName; + int? doctorID; + String? doctorImageURL; + String? doctorName; + String? doctorTitle; + int? gender; + String? genderDescription; + String? nationality; + String? nationalityFlagURL; + String? projectName; + + GetDoctorListModel( + {this.calcID, + this.projectID, + this.clinicID, + this.clinicName, + this.doctorID, + this.doctorImageURL, + this.doctorName, + this.doctorTitle, + this.gender, + this.genderDescription, + this.nationality, + this.nationalityFlagURL, + this.projectName}); + + GetDoctorListModel.fromJson(Map json) { + calcID = json['CalcID']; + projectID = json['ProjectID']; + clinicID = json['ClinicID']; + clinicName = json['ClinicName']; + doctorID = json['DoctorID']; + doctorImageURL = json['DoctorImageURL']; + doctorName = json['DoctorName']; + doctorTitle = json['DoctorTitle']; + gender = json['Gender']; + genderDescription = json['GenderDescription']; + nationality = json['Nationality']; + nationalityFlagURL = json['NationalityFlagURL']; + projectName = json['ProjectName']; + } + + Map toJson() { + final Map data = new Map(); + data['CalcID'] = this.calcID; + data['ProjectID'] = this.projectID; + data['ClinicID'] = this.clinicID; + data['ClinicName'] = this.clinicName; + data['DoctorID'] = this.doctorID; + data['DoctorImageURL'] = this.doctorImageURL; + data['DoctorName'] = this.doctorName; + data['DoctorTitle'] = this.doctorTitle; + data['Gender'] = this.gender; + data['GenderDescription'] = this.genderDescription; + data['Nationality'] = this.nationality; + data['NationalityFlagURL'] = this.nationalityFlagURL; + data['ProjectName'] = this.projectName; + return data; + } +} diff --git a/lib/core/model/health_calcolator/get_doctor_list_calcolation_request_model.dart b/lib/core/model/health_calcolator/get_doctor_list_calcolation_request_model.dart new file mode 100644 index 00000000..25be36a4 --- /dev/null +++ b/lib/core/model/health_calcolator/get_doctor_list_calcolation_request_model.dart @@ -0,0 +1,52 @@ +class GetDoctorListRequestModel { + int? calculationID; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + String? sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + + GetDoctorListRequestModel( + {this.calculationID, + this.versionID, + this.channel, + this.languageID, + this.iPAdress, + this.generalid, + this.patientOutSA, + this.sessionID, + this.isDentalAllowedBackend, + this.deviceTypeID}); + + GetDoctorListRequestModel.fromJson(Map json) { + calculationID = json['CalculationID']; + versionID = json['VersionID']; + channel = json['Channel']; + languageID = json['LanguageID']; + iPAdress = json['IPAdress']; + generalid = json['generalid']; + patientOutSA = json['PatientOutSA']; + sessionID = json['SessionID']; + isDentalAllowedBackend = json['isDentalAllowedBackend']; + deviceTypeID = json['DeviceTypeID']; + } + + Map toJson() { + final Map data = new Map(); + data['CalculationID'] = this.calculationID; + data['VersionID'] = this.versionID; + data['Channel'] = this.channel; + data['LanguageID'] = this.languageID; + data['IPAdress'] = this.iPAdress; + data['generalid'] = this.generalid; + data['PatientOutSA'] = this.patientOutSA; + data['SessionID'] = this.sessionID; + data['isDentalAllowedBackend'] = this.isDentalAllowedBackend; + data['DeviceTypeID'] = this.deviceTypeID; + return data; + } +} diff --git a/lib/core/model/hospitals/hospitals_model.dart b/lib/core/model/hospitals/hospitals_model.dart index 246de0b1..cc13ed81 100644 --- a/lib/core/model/hospitals/hospitals_model.dart +++ b/lib/core/model/hospitals/hospitals_model.dart @@ -1,20 +1,25 @@ class HospitalsModel { - String desciption; + String? desciption; dynamic desciptionN; dynamic iD; - String legalName; - String legalNameN; - String name; + String? legalName; + String? legalNameN; + String? name; dynamic nameN; - String phoneNumber; - String setupID; + String? phoneNumber; + String? setupID; dynamic distanceInKilometers; - bool isActive; - String latitude; - String longitude; + bool? isActive; + String? latitude; + String? longitude; dynamic mainProjectID; - dynamic projectOutSA; - bool usingInDoctorApp; + bool? projectOutSA; + bool? usingInDoctorApp; + bool? isHMC; + String? region; + String? regionArabic; + String? regionEnglish; + String? regionID; HospitalsModel( {this.desciption, @@ -32,7 +37,13 @@ class HospitalsModel { this.longitude, this.mainProjectID, this.projectOutSA, - this.usingInDoctorApp}); + this.usingInDoctorApp, + this.isHMC, + this.region, + this.regionArabic, + this.regionEnglish, + this.regionID, + }); HospitalsModel.fromJson(Map json) { desciption = json['Desciption']; @@ -51,6 +62,23 @@ class HospitalsModel { mainProjectID = json['MainProjectID']; projectOutSA = json['ProjectOutSA']; usingInDoctorApp = json['UsingInDoctorApp']; + this.isHMC = json["IsHMC"]; + this.regionArabic = json['RegionNameN']; + this.regionEnglish = json['RegionName']; + } + + String? getRegionName(bool isArabic) { + if (isArabic) { + return regionArabic; + } + return regionEnglish; + } + + String? getName(bool isArabic) { + if (isArabic) { + return "$nameN"; + } + return name; } Map toJson() { diff --git a/lib/core/model/hospitals/request_get_hospitals_model.dart b/lib/core/model/hospitals/request_get_hospitals_model.dart index be163654..9c0b8842 100644 --- a/lib/core/model/hospitals/request_get_hospitals_model.dart +++ b/lib/core/model/hospitals/request_get_hospitals_model.dart @@ -1,15 +1,15 @@ class RequestGetHospitalsModel { - int latitude; - int longitude; - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - String sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; + int? latitude; + int? longitude; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + String? sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; RequestGetHospitalsModel( {this.latitude, diff --git a/lib/core/model/insurance/Insurance_card_details.dart b/lib/core/model/insurance/Insurance_card_details.dart index ddc33b2e..c9287a2a 100644 --- a/lib/core/model/insurance/Insurance_card_details.dart +++ b/lib/core/model/insurance/Insurance_card_details.dart @@ -1,44 +1,44 @@ class InsuranceCardDetailsModel { - int approvalLimit; - int companyGroupID; - String companyName; - String companyRemarks; - String dOB; - int deductible; - String effectiveFrom; - String effectiveTo; - String eligabilityFailureReason; - bool isMemberEligible; - String memberID; - String memberName; - String memberStatus; + int? approvalLimit; + int? companyGroupID; + String? companyName; + String? companyRemarks; + String? dOB; + int? deductible; + String? effectiveFrom; + String? effectiveTo; + String? eligabilityFailureReason; + bool? isMemberEligible; + String? memberID; + String? memberName; + String? memberStatus; dynamic message; - String nationalId; - String policyNumber; - String responseMessage; - String room; - String subCategory; + String? nationalId; + String? policyNumber; + String? responseMessage; + String? room; + String? subCategory; InsuranceCardDetailsModel( {this.approvalLimit, - this.companyGroupID, - this.companyName, - this.companyRemarks, - this.dOB, - this.deductible, - this.effectiveFrom, - this.effectiveTo, - this.eligabilityFailureReason, - this.isMemberEligible, - this.memberID, - this.memberName, - this.memberStatus, - this.message, - this.nationalId, - this.policyNumber, - this.responseMessage, - this.room, - this.subCategory}); + this.companyGroupID, + this.companyName, + this.companyRemarks, + this.dOB, + this.deductible, + this.effectiveFrom, + this.effectiveTo, + this.eligabilityFailureReason, + this.isMemberEligible, + this.memberID, + this.memberName, + this.memberStatus, + this.message, + this.nationalId, + this.policyNumber, + this.responseMessage, + this.room, + this.subCategory}); InsuranceCardDetailsModel.fromJson(Map json) { approvalLimit = json['ApprovalLimit']; diff --git a/lib/core/model/insurance/ReauestInsuranceApprovalModel.dart b/lib/core/model/insurance/ReauestInsuranceApprovalModel.dart index 5f41f878..6f154022 100644 --- a/lib/core/model/insurance/ReauestInsuranceApprovalModel.dart +++ b/lib/core/model/insurance/ReauestInsuranceApprovalModel.dart @@ -1,21 +1,22 @@ -class ReauestInsuranceApprovalModel { - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - String sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; - int patientID; - String tokenID; - int patientTypeID; - int patientType; - int eXuldAPPNO; - int projectID; +class RequestInsuranceApprovalModel { + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + String? sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + int? patientID; + String? tokenID; + int? patientTypeID; + int? patientType; + int? eXuldAPPNO; + int? projectID; + int? appointmentNo; - ReauestInsuranceApprovalModel( + RequestInsuranceApprovalModel( {this.versionID, this.channel, this.languageID, @@ -30,9 +31,10 @@ class ReauestInsuranceApprovalModel { this.patientTypeID, this.patientType, this.eXuldAPPNO, - this.projectID}); + this.projectID, + this.appointmentNo}); - ReauestInsuranceApprovalModel.fromJson(Map json) { + RequestInsuranceApprovalModel.fromJson(Map json) { versionID = json['VersionID']; channel = json['Channel']; languageID = json['LanguageID']; @@ -48,6 +50,7 @@ class ReauestInsuranceApprovalModel { patientType = json['PatientType']; eXuldAPPNO = json['EXuldAPPNO']; projectID = json['ProjectID']; + appointmentNo = json['AppointmentNo']; } Map toJson() { @@ -67,6 +70,7 @@ class ReauestInsuranceApprovalModel { data['PatientType'] = this.patientType; data['EXuldAPPNO'] = this.eXuldAPPNO; data['ProjectID'] = this.projectID; + data['AppointmentNo'] = this.appointmentNo; return data; } } diff --git a/lib/core/model/insurance/insuranceManualUpdateRequest.dart b/lib/core/model/insurance/insuranceManualUpdateRequest.dart new file mode 100644 index 00000000..5c1f17df --- /dev/null +++ b/lib/core/model/insurance/insuranceManualUpdateRequest.dart @@ -0,0 +1,68 @@ +class InsuranceManualUpdateRequest { + String? setupID; + String? patientIdentificationID; + int? projectID; + String? mobileNo; + int? activityId; + String? component; + bool? enableLogging; + String? insuranceCompanyName; + String? cardHolderName; + String? memberShipNo; + String? policyNo; + String? schemeClass; + int? requestType; + int? patientID; + + InsuranceManualUpdateRequest( + {this.setupID, + this.patientIdentificationID, + this.projectID, + this.mobileNo, + this.activityId, + this.component, + this.enableLogging, + this.insuranceCompanyName, + this.cardHolderName, + this.memberShipNo, + this.policyNo, + this.schemeClass, + this.requestType, + this.patientID}); + + InsuranceManualUpdateRequest.fromJson(Map json) { + setupID = json['SetupID']; + patientIdentificationID = json['PatientIdentificationID']; + projectID = json['ProjectID']; + mobileNo = json['MobileNo']; + activityId = json['activityId']; + component = json['component']; + enableLogging = json['enableLogging']; + insuranceCompanyName = json['InsuranceCompanyName']; + cardHolderName = json['CardHolderName']; + memberShipNo = json['MemberShipNo']; + policyNo = json['PolicyNo']; + schemeClass = json['SchemeClass']; + requestType = json['RequestType']; + patientID = json['PatientID']; + } + + Map toJson() { + final Map data = new Map(); + data['SetupID'] = this.setupID; + data['PatientIdentificationID'] = this.patientIdentificationID; + data['ProjectID'] = this.projectID; + data['MobileNo'] = this.mobileNo; + data['activityId'] = this.activityId; + data['component'] = this.component; + data['enableLogging'] = this.enableLogging; + data['InsuranceCompanyName'] = this.insuranceCompanyName; + data['CardHolderName'] = this.cardHolderName; + data['MemberShipNo'] = this.memberShipNo; + data['PolicyNo'] = this.policyNo; + data['SchemeClass'] = this.schemeClass; + data['RequestType'] = this.requestType; + data['PatientID'] = this.patientID; + return data; + } +} diff --git a/lib/core/model/insurance/insurance_approval.dart b/lib/core/model/insurance/insurance_approval.dart index 894fad46..df8102bd 100644 --- a/lib/core/model/insurance/insurance_approval.dart +++ b/lib/core/model/insurance/insurance_approval.dart @@ -1,140 +1,465 @@ -class InsuranceApprovalDetails { - String procedureName; - String status; - String isInvoicedDesc; - - InsuranceApprovalDetails({ - this.procedureName, - this.status, - this.isInvoicedDesc, - }); - - InsuranceApprovalDetails.fromJson(Map json) { - try { - isInvoicedDesc = json['IsInvoicedDesc']; - status = json['Status']; - procedureName = json['ProcedureName']; - } catch (e) { - print(e); - } - } -} - class InsuranceApprovalModel { - InsuranceApprovalDetails approvalDetails; - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - String sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; - int patientID; - String tokenID; - int patientTypeID; - int patientType; - int eXuldAPPNO; - int projectID; - String doctorName; - String clinicName; - String patientDescription; - int approvalNo; - String approvalStatusDescption; - int unUsedCount; - - //String companyName; - String expiryDate; - String rceiptOn; - int appointmentNo; + String? setupID; + int? projectID; + int? approvalNo; + String? approvalDate; + int? patientType; + int? patientID; + int? companyID; + int? subCategoryID; + int? doctorID; + int? clinicID; + int? approvalType; + String? inpatientApprovalSubType; + String? validFrom; + String? vaildDays; + String? validTo; + bool? isApprovalOnGross; + bool? isPackage; + int? requestedAmount; + int? actualApprovedAmount; + int? aviliableAmount; + String? companyApprovalNo; + int? progNoteOrderNo; + String? submitOn; + String? receiptOn; + String? remarks1; + String? remarks2; + int? status; + String? feedbackStatusBy; + String? feedbackStatus; + String? feedbackStatusOn; + int? authorizerID; + String? expiryDate; + int? appointmentNo; + int? admissionNo; + int? admissionRequestNo; + int? createdBy; + String? createdOn; + int? editedBy; + String? editedOn; + String? rowVer; + bool? isAddlDiscApplied; + int? inProgressReasonID; + String? extendedBy; + String? extendedOn; + int? subPolicyNo; + int? noOrderAuthorizerID; + bool? isVerbalApproval; + String? subStatus; + bool? isNotificationSend; + String? eApprovalStatus; + String? eApprovalRemarks; + bool? isEmailSentOnDelayApproval; + int? eAuthorizationID; + InsuranceApprovalDetails? apporvalDetails; + String? approvalStatusDescption; + String? clinicName; + String? clinicNameN; + String? companyName; + String? doctorImageURL; + String? doctorName; + String? doctorNameN; + int? doctorRate; + String? doctorTitle; + int? gender; + String? genderDescription; + bool? isActiveDoctorProfile; + bool? isExecludeDoctor; + bool? isInOutPatient; + String? isInOutPatientDescription; + String? isInOutPatientDescriptionN; + bool? isLiveCareAppointment; + String? projectName; + String? projectNameN; + String? qR; + List? speciality; + String? strApprovalDate; + String? strExpiryDate; + String? strSubmitDate; + int? totaUnUsedCount; + int? unUsedCount; InsuranceApprovalModel( - {this.versionID, - this.channel, - this.languageID, - this.iPAdress, - this.generalid, - this.patientOutSA, - this.sessionID, - this.isDentalAllowedBackend, - this.deviceTypeID, - this.patientID, - this.tokenID, - this.patientTypeID, - this.patientType, - this.eXuldAPPNO, + {this.setupID, this.projectID, - this.doctorName, - this.clinicName, - this.patientDescription, this.approvalNo, - this.approvalStatusDescption, - this.unUsedCount, - //this.companyName, + this.approvalDate, + this.patientType, + this.patientID, + this.companyID, + this.subCategoryID, + this.doctorID, + this.clinicID, + this.approvalType, + this.inpatientApprovalSubType, + this.validFrom, + this.vaildDays, + this.validTo, + this.isApprovalOnGross, + this.isPackage, + this.requestedAmount, + this.actualApprovedAmount, + this.aviliableAmount, + this.companyApprovalNo, + this.progNoteOrderNo, + this.submitOn, + this.receiptOn, + this.remarks1, + this.remarks2, + this.status, + this.feedbackStatusBy, + this.feedbackStatus, + this.feedbackStatusOn, + this.authorizerID, this.expiryDate, - this.rceiptOn, - this.approvalDetails, - this.appointmentNo}); - - InsuranceApprovalDetails x = InsuranceApprovalDetails(); + this.appointmentNo, + this.admissionNo, + this.admissionRequestNo, + this.createdBy, + this.createdOn, + this.editedBy, + this.editedOn, + this.rowVer, + this.isAddlDiscApplied, + this.inProgressReasonID, + this.extendedBy, + this.extendedOn, + this.subPolicyNo, + this.noOrderAuthorizerID, + this.isVerbalApproval, + this.subStatus, + this.isNotificationSend, + this.eApprovalStatus, + this.eApprovalRemarks, + this.isEmailSentOnDelayApproval, + this.eAuthorizationID, + this.apporvalDetails, + this.approvalStatusDescption, + this.clinicName, + this.clinicNameN, + this.companyName, + this.doctorImageURL, + this.doctorName, + this.doctorNameN, + this.doctorRate, + this.doctorTitle, + this.gender, + this.genderDescription, + this.isActiveDoctorProfile, + this.isExecludeDoctor, + this.isInOutPatient, + this.isInOutPatientDescription, + this.isInOutPatientDescriptionN, + this.isLiveCareAppointment, + this.projectName, + this.projectNameN, + this.qR, + this.speciality, + this.strApprovalDate, + this.strExpiryDate, + this.strSubmitDate, + this.totaUnUsedCount, + this.unUsedCount}); InsuranceApprovalModel.fromJson(Map json) { - try { - rceiptOn = json['ReceiptOn']; - expiryDate = json['ExpiryDate']; - //companyName = json['CompanyName']; - unUsedCount = json['TotaUnUsedCount']; - approvalStatusDescption = json['ApprovalStatusDescption']; - approvalNo = json['ApprovalNo']; - patientDescription = json['IsInOutPatientDescription']; - versionID = json['VersionID']; - channel = json['Channel']; - languageID = json['LanguageID']; - iPAdress = json['IPAdress']; - generalid = json['generalid']; - patientOutSA = json['PatientOutSA']; - sessionID = json['SessionID']; - isDentalAllowedBackend = json['isDentalAllowedBackend']; - deviceTypeID = json['DeviceTypeID']; - patientID = json['PatientID']; - tokenID = json['TokenID']; - patientTypeID = json['PatientTypeID']; - patientType = json['PatientType']; - eXuldAPPNO = json['EXuldAPPNO']; - projectID = json['ProjectID']; - doctorName = json['DoctorName']; - clinicName = json['ClinicName']; - approvalDetails = - InsuranceApprovalDetails.fromJson(json['ApporvalDetails'][0]); - appointmentNo = json['AppointmentNo']; - } catch (e) { - print(e); + setupID = json['SetupID']; + projectID = json['ProjectID']; + approvalNo = json['ApprovalNo']; + approvalDate = json['ApprovalDate']; + patientType = json['PatientType']; + patientID = json['PatientID']; + companyID = json['CompanyID']; + subCategoryID = json['SubCategoryID']; + doctorID = json['DoctorID']; + clinicID = json['ClinicID']; + approvalType = json['ApprovalType']; + inpatientApprovalSubType = json['InpatientApprovalSubType']; + validFrom = json['ValidFrom']; + vaildDays = json['VaildDays']; + validTo = json['ValidTo']; + isApprovalOnGross = json['IsApprovalOnGross']; + isPackage = json['IsPackage']; + requestedAmount = json['RequestedAmount']; + actualApprovedAmount = json['ActualApprovedAmount']; + aviliableAmount = json['AviliableAmount']; + companyApprovalNo = json['CompanyApprovalNo']; + progNoteOrderNo = json['ProgNoteOrderNo']; + submitOn = json['SubmitOn']; + receiptOn = json['ReceiptOn']; + remarks1 = json['Remarks1']; + remarks2 = json['Remarks2']; + status = json['Status']; + feedbackStatusBy = json['FeedbackStatusBy']; + feedbackStatus = json['FeedbackStatus']; + feedbackStatusOn = json['FeedbackStatusOn']; + authorizerID = json['AuthorizerID']; + expiryDate = json['ExpiryDate']; + appointmentNo = json['AppointmentNo']; + admissionNo = json['AdmissionNo']; + admissionRequestNo = json['AdmissionRequestNo']; + createdBy = json['CreatedBy']; + createdOn = json['CreatedOn']; + editedBy = json['EditedBy']; + editedOn = json['EditedOn']; + rowVer = json['RowVer']; + isAddlDiscApplied = json['IsAddlDiscApplied']; + inProgressReasonID = json['InProgressReasonID']; + extendedBy = json['ExtendedBy']; + extendedOn = json['ExtendedOn']; + subPolicyNo = json['SubPolicyNo']; + noOrderAuthorizerID = json['NoOrderAuthorizerID']; + isVerbalApproval = json['isVerbalApproval']; + subStatus = json['SubStatus']; + isNotificationSend = json['IsNotificationSend']; + eApprovalStatus = json['EApprovalStatus']; + eApprovalRemarks = json['EApprovalRemarks']; + isEmailSentOnDelayApproval = json['IsEmailSentOnDelayApproval']; + eAuthorizationID = json['EAuthorizationID']; + if (json['ApporvalDetails'] != null && json['ApporvalDetails'].length != 0) { + apporvalDetails = InsuranceApprovalDetails.fromJson(json['ApporvalDetails'][0]); } + approvalStatusDescption = json['ApprovalStatusDescption']; + clinicName = json['ClinicName']; + clinicNameN = json['ClinicNameN']; + companyName = json['CompanyName']; + doctorImageURL = json['DoctorImageURL']; + doctorName = json['DoctorName']; + doctorNameN = json['DoctorNameN']; + doctorRate = json['DoctorRate']; + doctorTitle = json['DoctorTitle']; + gender = json['Gender']; + genderDescription = json['GenderDescription']; + isActiveDoctorProfile = json['IsActiveDoctorProfile']; + isExecludeDoctor = json['IsExecludeDoctor']; + isInOutPatient = json['IsInOutPatient']; + isInOutPatientDescription = json['IsInOutPatientDescription']; + isInOutPatientDescriptionN = json['IsInOutPatientDescriptionN']; + isLiveCareAppointment = json['IsLiveCareAppointment']; + projectName = json['ProjectName']; + projectNameN = json['ProjectNameN']; + qR = json['QR']; + if (json['Speciality'] != null) speciality = json['Speciality'].cast(); + strApprovalDate = json['StrApprovalDate']; + strExpiryDate = json['StrExpiryDate']; + strSubmitDate = json['StrSubmitDate']; + totaUnUsedCount = json['TotaUnUsedCount']; + unUsedCount = json['UnUsedCount']; } Map toJson() { final Map data = new Map(); - data['VersionID'] = this.versionID; - data['Channel'] = this.channel; - data['LanguageID'] = this.languageID; - data['IPAdress'] = this.iPAdress; - data['generalid'] = this.generalid; - data['PatientOutSA'] = this.patientOutSA; - data['SessionID'] = this.sessionID; - data['isDentalAllowedBackend'] = this.isDentalAllowedBackend; - data['DeviceTypeID'] = this.deviceTypeID; - data['PatientID'] = this.patientID; - data['TokenID'] = this.tokenID; - data['PatientTypeID'] = this.patientTypeID; + data['SetupID'] = this.setupID; + data['ProjectID'] = this.projectID; + data['ApprovalNo'] = this.approvalNo; + data['ApprovalDate'] = this.approvalDate; data['PatientType'] = this.patientType; - if (appointmentNo == null) { - data['EXuldAPPNO'] = this.eXuldAPPNO; - data['ProjectID'] = this.projectID; - } - if (appointmentNo != null) { - data['AppointmentNo'] = this.appointmentNo; + data['PatientID'] = this.patientID; + data['CompanyID'] = this.companyID; + data['SubCategoryID'] = this.subCategoryID; + data['DoctorID'] = this.doctorID; + data['ClinicID'] = this.clinicID; + data['ApprovalType'] = this.approvalType; + data['InpatientApprovalSubType'] = this.inpatientApprovalSubType; + data['ValidFrom'] = this.validFrom; + data['VaildDays'] = this.vaildDays; + data['ValidTo'] = this.validTo; + data['IsApprovalOnGross'] = this.isApprovalOnGross; + data['IsPackage'] = this.isPackage; + data['RequestedAmount'] = this.requestedAmount; + data['ActualApprovedAmount'] = this.actualApprovedAmount; + data['AviliableAmount'] = this.aviliableAmount; + data['CompanyApprovalNo'] = this.companyApprovalNo; + data['ProgNoteOrderNo'] = this.progNoteOrderNo; + data['SubmitOn'] = this.submitOn; + data['ReceiptOn'] = this.receiptOn; + data['Remarks1'] = this.remarks1; + data['Remarks2'] = this.remarks2; + data['Status'] = this.status; + data['FeedbackStatusBy'] = this.feedbackStatusBy; + data['FeedbackStatus'] = this.feedbackStatus; + data['FeedbackStatusOn'] = this.feedbackStatusOn; + data['AuthorizerID'] = this.authorizerID; + data['ExpiryDate'] = this.expiryDate; + data['AppointmentNo'] = this.appointmentNo; + data['AdmissionNo'] = this.admissionNo; + data['AdmissionRequestNo'] = this.admissionRequestNo; + data['CreatedBy'] = this.createdBy; + data['CreatedOn'] = this.createdOn; + data['EditedBy'] = this.editedBy; + data['EditedOn'] = this.editedOn; + data['RowVer'] = this.rowVer; + data['IsAddlDiscApplied'] = this.isAddlDiscApplied; + data['InProgressReasonID'] = this.inProgressReasonID; + data['ExtendedBy'] = this.extendedBy; + data['ExtendedOn'] = this.extendedOn; + data['SubPolicyNo'] = this.subPolicyNo; + data['NoOrderAuthorizerID'] = this.noOrderAuthorizerID; + data['isVerbalApproval'] = this.isVerbalApproval; + data['SubStatus'] = this.subStatus; + data['IsNotificationSend'] = this.isNotificationSend; + data['EApprovalStatus'] = this.eApprovalStatus; + data['EApprovalRemarks'] = this.eApprovalRemarks; + data['IsEmailSentOnDelayApproval'] = this.isEmailSentOnDelayApproval; + data['EAuthorizationID'] = this.eAuthorizationID; + if (this.apporvalDetails != null) { + data['ApporvalDetails'] = this.apporvalDetails!.toJson; } + data['ApprovalStatusDescption'] = this.approvalStatusDescption; + data['ClinicName'] = this.clinicName; + data['ClinicNameN'] = this.clinicNameN; + data['CompanyName'] = this.companyName; + data['DoctorImageURL'] = this.doctorImageURL; + data['DoctorName'] = this.doctorName; + data['DoctorNameN'] = this.doctorNameN; + data['DoctorRate'] = this.doctorRate; + data['DoctorTitle'] = this.doctorTitle; + data['Gender'] = this.gender; + data['GenderDescription'] = this.genderDescription; + data['IsActiveDoctorProfile'] = this.isActiveDoctorProfile; + data['IsExecludeDoctor'] = this.isExecludeDoctor; + data['IsInOutPatient'] = this.isInOutPatient; + data['IsInOutPatientDescription'] = this.isInOutPatientDescription; + data['IsInOutPatientDescriptionN'] = this.isInOutPatientDescriptionN; + data['IsLiveCareAppointment'] = this.isLiveCareAppointment; + data['ProjectName'] = this.projectName; + data['ProjectNameN'] = this.projectNameN; + data['QR'] = this.qR; + data['Speciality'] = this.speciality; + data['StrApprovalDate'] = this.strApprovalDate; + data['StrExpiryDate'] = this.strExpiryDate; + data['StrSubmitDate'] = this.strSubmitDate; + data['TotaUnUsedCount'] = this.totaUnUsedCount; + data['UnUsedCount'] = this.unUsedCount; + return data; + } +} + +class InsuranceApprovalDetails { + int? setupID; + int? projectID; + int? approvalNo; + int? lineItemNo; + int? orderType; + int? procedureID; + int? toothNo; + int? price; + int? approvedAmount; + String? unapprovedPatientShare; + int? waivedAmount; + String? discountType; + int? discountValue; + String? shareType; + String? patientShareTypeValue; + String? companyShareTypeValue; + String? patientShare; + String? companyShare; + int? deductableAmount; + String? disapprovedRemarks; + int? progNoteOrderNo; + int? progNoteLineItemNo; + String? invoiceTransactionType; + int? invoiceNo; + String? procedureName; + String? procedureNameN; + String? status; + bool? isInvoiced; + String? isInvoicedDesc; + + InsuranceApprovalDetails( + {this.setupID, + this.projectID, + this.approvalNo, + this.lineItemNo, + this.orderType, + this.procedureID, + this.toothNo, + this.price, + this.approvedAmount, + this.unapprovedPatientShare, + this.waivedAmount, + this.discountType, + this.discountValue, + this.shareType, + this.patientShareTypeValue, + this.companyShareTypeValue, + this.patientShare, + this.companyShare, + this.deductableAmount, + this.disapprovedRemarks, + this.progNoteOrderNo, + this.progNoteLineItemNo, + this.invoiceTransactionType, + this.invoiceNo, + this.procedureName, + this.procedureNameN, + this.status, + this.isInvoiced, + this.isInvoicedDesc}); + + InsuranceApprovalDetails.fromJson(Map json) { + setupID = json['SetupID']; + projectID = json['ProjectID']; + approvalNo = json['ApprovalNo']; + lineItemNo = json['LineItemNo']; + orderType = json['OrderType']; + procedureID = json['ProcedureID']; + toothNo = json['ToothNo']; + price = json['Price']; + approvedAmount = json['ApprovedAmount']; + unapprovedPatientShare = json['UnapprovedPatientShare']; + waivedAmount = json['WaivedAmount']; + discountType = json['DiscountType']; + discountValue = json['DiscountValue']; + shareType = json['ShareType']; + patientShareTypeValue = json['PatientShareTypeValue']; + companyShareTypeValue = json['CompanyShareTypeValue']; + patientShare = json['PatientShare']; + companyShare = json['CompanyShare']; + deductableAmount = json['DeductableAmount']; + disapprovedRemarks = json['DisapprovedRemarks']; + progNoteOrderNo = json['ProgNoteOrderNo']; + progNoteLineItemNo = json['ProgNoteLineItemNo']; + invoiceTransactionType = json['InvoiceTransactionType']; + invoiceNo = json['InvoiceNo']; + procedureName = json['ProcedureName']; + procedureNameN = json['ProcedureNameN']; + status = json['Status']; + isInvoiced = json['IsInvoiced']; + isInvoicedDesc = json['IsInvoicedDesc']; + } + + Map toJson() { + final Map data = new Map(); + data['SetupID'] = this.setupID; + data['ProjectID'] = this.projectID; + data['ApprovalNo'] = this.approvalNo; + data['LineItemNo'] = this.lineItemNo; + data['OrderType'] = this.orderType; + data['ProcedureID'] = this.procedureID; + data['ToothNo'] = this.toothNo; + data['Price'] = this.price; + data['ApprovedAmount'] = this.approvedAmount; + data['UnapprovedPatientShare'] = this.unapprovedPatientShare; + data['WaivedAmount'] = this.waivedAmount; + data['DiscountType'] = this.discountType; + data['DiscountValue'] = this.discountValue; + data['ShareType'] = this.shareType; + data['PatientShareTypeValue'] = this.patientShareTypeValue; + data['CompanyShareTypeValue'] = this.companyShareTypeValue; + data['PatientShare'] = this.patientShare; + data['CompanyShare'] = this.companyShare; + data['DeductableAmount'] = this.deductableAmount; + data['DisapprovedRemarks'] = this.disapprovedRemarks; + data['ProgNoteOrderNo'] = this.progNoteOrderNo; + data['ProgNoteLineItemNo'] = this.progNoteLineItemNo; + data['InvoiceTransactionType'] = this.invoiceTransactionType; + data['InvoiceNo'] = this.invoiceNo; + data['ProcedureName'] = this.procedureName; + data['ProcedureNameN'] = this.procedureNameN; + data['Status'] = this.status; + data['IsInvoiced'] = this.isInvoiced; + data['IsInvoicedDesc'] = this.isInvoicedDesc; return data; } } diff --git a/lib/core/model/insurance/insurance_card.dart b/lib/core/model/insurance/insurance_card.dart index ebab8d71..364a7269 100644 --- a/lib/core/model/insurance/insurance_card.dart +++ b/lib/core/model/insurance/insurance_card.dart @@ -1,53 +1,50 @@ -import 'dart:convert'; - class InsuranceCardModel { - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - String sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; - int patientID; - String tokenID; - int patientTypeID; - int patientType; - String groupName; - String companyName; - int companyID; - String subCategoryDesc; - int subCategoryID; - String patientCardID; - String insurancePolicyNumber; - bool isActive; - String cardValidTo; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + String? sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + int? patientID; + String? tokenID; + int? patientTypeID; + int? patientType; + String? groupName; + String? companyName; + int? companyID; + String? subCategoryDesc; + int? subCategoryID; + String? patientCardID; + String? insurancePolicyNumber; + bool? isActive; + String? cardValidTo; - InsuranceCardModel({ - this.insurancePolicyNumber, - this.subCategoryDesc, - this.subCategoryID, - this.versionID, - this.channel, - this.languageID, - this.iPAdress, - this.generalid, - this.patientOutSA, - this.sessionID, - this.isDentalAllowedBackend, - this.deviceTypeID, - this.patientID, - this.tokenID, - this.patientTypeID, - this.patientType, - this.groupName, - this.companyName, - this.companyID, - this.patientCardID, - this.isActive, - this.cardValidTo - }); + InsuranceCardModel( + {this.insurancePolicyNumber, + this.subCategoryDesc, + this.subCategoryID, + this.versionID, + this.channel, + this.languageID, + this.iPAdress, + this.generalid, + this.patientOutSA, + this.sessionID, + this.isDentalAllowedBackend, + this.deviceTypeID, + this.patientID, + this.tokenID, + this.patientTypeID, + this.patientType, + this.groupName, + this.companyName, + this.companyID, + this.patientCardID, + this.isActive, + this.cardValidTo}); InsuranceCardModel.fromJson(Map json) { isActive = json['IsActive']; diff --git a/lib/core/model/insurance/insurance_card_update_model.dart b/lib/core/model/insurance/insurance_card_update_model.dart index 6f5331ce..d14f65bd 100644 --- a/lib/core/model/insurance/insurance_card_update_model.dart +++ b/lib/core/model/insurance/insurance_card_update_model.dart @@ -1,22 +1,20 @@ -import 'dart:convert'; -import 'package:intl/intl.dart'; class InsuranceUpdateModel { - int patientID; - int patientType; - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - String sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; - String createdOn; - String statusDescription; - int appointmentNo; + int? patientID; + int? patientType; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + String? sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + String? createdOn; + String? statusDescription; + int? appointmentNo; InsuranceUpdateModel( {this.patientID, diff --git a/lib/core/model/labs/LabOrderResult.dart b/lib/core/model/labs/LabOrderResult.dart index ecb4ae65..d282c6b4 100644 --- a/lib/core/model/labs/LabOrderResult.dart +++ b/lib/core/model/labs/LabOrderResult.dart @@ -1,23 +1,23 @@ class LabOrderResult { - String description; + String? description; dynamic femaleInterpretativeData; - int gender; - int lineItemNo; + int? gender; + int? lineItemNo; dynamic maleInterpretativeData; dynamic notes; - String packageID; - int patientID; - String projectID; - String referanceRange; - String resultValue; - String sampleCollectedOn; - String sampleReceivedOn; - String setupID; + String? packageID; + int? patientID; + String? projectID; + String? referanceRange; + String? resultValue; + String? sampleCollectedOn; + String? sampleReceivedOn; + String? setupID; dynamic superVerifiedOn; - String testCode; - String uOM; - String verifiedOn; - String verifiedOnDateTime; + String? testCode; + String? uOM; + String? verifiedOn; + String? verifiedOnDateTime; LabOrderResult( {this.description, diff --git a/lib/core/model/labs/lab_result.dart b/lib/core/model/labs/lab_result.dart index 2deb13f3..3de55ff1 100644 --- a/lib/core/model/labs/lab_result.dart +++ b/lib/core/model/labs/lab_result.dart @@ -1,57 +1,81 @@ +class LabResultList { + String? filterName = ""; + List? patientLabResultList = []; + + LabResultList({this.filterName, LabResult? lab}) { + patientLabResultList!.add(lab!); + } +} + class LabResult { - String description; + String? description; dynamic femaleInterpretativeData; - int gender; - int lineItemNo; + int? gender; + bool? isCertificateAllowed; + int? lineItemNo; dynamic maleInterpretativeData; - String notes; - String packageID; - int patientID; - String projectID; - String referanceRange; - String resultValue; - String sampleCollectedOn; - String sampleReceivedOn; - String setupID; + dynamic notes; + int? orderLineItemNo; + int? orderNo; + String? packageID; + int? patientID; + String? projectID; + String? referanceRange; + String? resultValue; + int? resultValueBasedLineItemNo; + String? resultValueFlag; + String? sampleCollectedOn; + String? sampleReceivedOn; + String? setupID; dynamic superVerifiedOn; - String testCode; - String uOM; - String verifiedOn; + String? testCode; + String? uOM; + String? verifiedOn; dynamic verifiedOnDateTime; LabResult( {this.description, - this.femaleInterpretativeData, - this.gender, - this.lineItemNo, - this.maleInterpretativeData, - this.notes, - this.packageID, - this.patientID, - this.projectID, - this.referanceRange, - this.resultValue, - this.sampleCollectedOn, - this.sampleReceivedOn, - this.setupID, - this.superVerifiedOn, - this.testCode, - this.uOM, - this.verifiedOn, - this.verifiedOnDateTime}); + this.femaleInterpretativeData, + this.gender, + this.isCertificateAllowed, + this.lineItemNo, + this.maleInterpretativeData, + this.notes, + this.orderLineItemNo, + this.orderNo, + this.packageID, + this.patientID, + this.projectID, + this.referanceRange, + this.resultValue, + this.resultValueBasedLineItemNo, + this.resultValueFlag, + this.sampleCollectedOn, + this.sampleReceivedOn, + this.setupID, + this.superVerifiedOn, + this.testCode, + this.uOM, + this.verifiedOn, + this.verifiedOnDateTime}); LabResult.fromJson(Map json) { description = json['Description']; femaleInterpretativeData = json['FemaleInterpretativeData']; gender = json['Gender']; + isCertificateAllowed = json['IsCertificateAllowed']; lineItemNo = json['LineItemNo']; maleInterpretativeData = json['MaleInterpretativeData']; notes = json['Notes']; + orderLineItemNo = json['OrderLineItemNo']; + orderNo = json['OrderNo']; packageID = json['PackageID']; patientID = json['PatientID']; projectID = json['ProjectID']; referanceRange = json['ReferanceRange']; resultValue = json['ResultValue']; + resultValueBasedLineItemNo = json['ResultValueBasedLineItemNo']; + resultValueFlag = json['ResultValueFlag']; sampleCollectedOn = json['SampleCollectedOn']; sampleReceivedOn = json['SampleReceivedOn']; setupID = json['SetupID']; @@ -67,14 +91,19 @@ class LabResult { data['Description'] = this.description; data['FemaleInterpretativeData'] = this.femaleInterpretativeData; data['Gender'] = this.gender; + data['IsCertificateAllowed'] = this.isCertificateAllowed; data['LineItemNo'] = this.lineItemNo; data['MaleInterpretativeData'] = this.maleInterpretativeData; data['Notes'] = this.notes; + data['OrderLineItemNo'] = this.orderLineItemNo; + data['OrderNo'] = this.orderNo; data['PackageID'] = this.packageID; data['PatientID'] = this.patientID; data['ProjectID'] = this.projectID; data['ReferanceRange'] = this.referanceRange; data['ResultValue'] = this.resultValue; + data['ResultValueBasedLineItemNo'] = this.resultValueBasedLineItemNo; + data['ResultValueFlag'] = this.resultValueFlag; data['SampleCollectedOn'] = this.sampleCollectedOn; data['SampleReceivedOn'] = this.sampleReceivedOn; data['SetupID'] = this.setupID; @@ -86,13 +115,3 @@ class LabResult { return data; } } - - -class LabResultList { - String filterName = ""; - List patientLabResultList = List(); - - LabResultList({this.filterName, LabResult lab}) { - patientLabResultList.add(lab); - } -} diff --git a/lib/core/model/labs/patient_lab_orders.dart b/lib/core/model/labs/patient_lab_orders.dart index 3c49b80a..2f3b1629 100644 --- a/lib/core/model/labs/patient_lab_orders.dart +++ b/lib/core/model/labs/patient_lab_orders.dart @@ -1,40 +1,44 @@ import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; class PatientLabOrders { - int actualDoctorRate; - String clinicDescription; - String clinicDescriptionEnglish; - Null clinicDescriptionN; - int clinicID; - int doctorID; - String doctorImageURL; - String doctorName; - String doctorNameEnglish; - Null doctorNameN; - int doctorRate; - String doctorTitle; - int gender; - String genderDescription; - String invoiceNo; - bool isActiveDoctorProfile; - bool isDoctorAllowVedioCall; - bool isExecludeDoctor; - bool isInOutPatient; - String isInOutPatientDescription; - String isInOutPatientDescriptionN; - bool isRead; - String nationalityFlagURL; - int noOfPatientsRate; - DateTime orderDate; - String orderNo; - String patientID; - String projectID; - String projectName; - Null projectNameN; - String qR; - String setupID; - List speciality; - bool isLiveCareAppointment; + int? actualDoctorRate; + String? clinicDescription; + String? clinicDescriptionEnglish; + dynamic clinicDescriptionN; + int? clinicID; + int? doctorID; + String? doctorImageURL; + String? doctorName; + String? doctorNameEnglish; + dynamic doctorNameN; + int? doctorRate; + String ?doctorTitle; + int? gender; + String? genderDescription; + String? invoiceNo; + String? invoiceNo_VP; + String? invoiceType; + bool? isActiveDoctorProfile; + bool? isDoctorAllowVedioCall; + bool? isExecludeDoctor; + bool? isInOutPatient; + String? isInOutPatientDescription; + String? isInOutPatientDescriptionN; + bool? isRead; + String? nationalityFlagURL; + int? noOfPatientsRate; + DateTime? orderDate; + String? orderNo; + String? patientID; + String? projectID; + String? projectName; + dynamic projectNameN; + String? qR; + String? setupID; + List? speciality; + bool? isLiveCareAppointment; + int? status; + String? statusDesc; PatientLabOrders( {this.actualDoctorRate, this.clinicDescription, @@ -68,7 +72,12 @@ class PatientLabOrders { this.projectNameN, this.qR, this.setupID, - this.speciality,this.isLiveCareAppointment}); + this.invoiceNo_VP, + this.invoiceType, + this.speciality, + this.isLiveCareAppointment, + this.status, + this.statusDesc,}); PatientLabOrders.fromJson(Map json) { actualDoctorRate = json['ActualDoctorRate']; @@ -103,8 +112,12 @@ class PatientLabOrders { projectNameN = json['ProjectNameN']; qR = json['QR']; setupID = json['SetupID']; + invoiceNo_VP = json['invoiceNo_VP']; + invoiceType = json['InvoiceType']; isLiveCareAppointment = json['IsLiveCareAppointment']; - // speciality = json['Speciality'].cast(); + status = json['Status']; + statusDesc = json['StatusDesc']; + // speciality = json['Speciality'].cast(); } Map toJson() { @@ -143,16 +156,18 @@ class PatientLabOrders { data['SetupID'] = this.setupID; data['Speciality'] = this.speciality; data['IsLiveCareAppointment'] = this.isLiveCareAppointment; + data['invoiceNo_VP'] = this.invoiceNo_VP; + data['Status'] = this.status; + data['StatusDesc'] = this.statusDesc; return data; } } class PatientLabOrdersList { - String filterName = ""; - List patientLabOrdersList = List(); + String? filterName = ""; + List patientLabOrdersList = []; - PatientLabOrdersList( - {this.filterName, PatientLabOrders patientDoctorAppointment}) { + PatientLabOrdersList({this.filterName, required PatientLabOrders patientDoctorAppointment}) { patientLabOrdersList.add(patientDoctorAppointment); } } diff --git a/lib/core/model/labs/patient_lab_special_result.dart b/lib/core/model/labs/patient_lab_special_result.dart index 2fbcb832..87301f94 100644 --- a/lib/core/model/labs/patient_lab_special_result.dart +++ b/lib/core/model/labs/patient_lab_special_result.dart @@ -1,9 +1,9 @@ class PatientLabSpecialResult { - String invoiceNo; - String moduleID; - String resultData; - String resultDataHTML; - Null resultDataTxt; + String? invoiceNo; + String? moduleID; + String? resultData; + String? resultDataHTML; + dynamic resultDataTxt; PatientLabSpecialResult( {this.invoiceNo, diff --git a/lib/core/model/labs/request_patient_lab_orders.dart b/lib/core/model/labs/request_patient_lab_orders.dart index ce9263ef..9f9dd4d3 100644 --- a/lib/core/model/labs/request_patient_lab_orders.dart +++ b/lib/core/model/labs/request_patient_lab_orders.dart @@ -1,17 +1,17 @@ class RequestPatientLabOrders { - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - String sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; - int patientID; - String tokenID; - int patientTypeID; - int patientType; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + String? sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + int? patientID; + String? tokenID; + int? patientTypeID; + int? patientType; RequestPatientLabOrders( {this.versionID, diff --git a/lib/core/model/labs/request_patient_lab_special_result.dart b/lib/core/model/labs/request_patient_lab_special_result.dart index bdeb3930..b1e1e4e3 100644 --- a/lib/core/model/labs/request_patient_lab_special_result.dart +++ b/lib/core/model/labs/request_patient_lab_special_result.dart @@ -1,45 +1,51 @@ class RequestPatientLabSpecialResult { - String invoiceNo; - String orderNo; - String setupID; - String projectID; - int clinicID; - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - String sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; - int patientID; - String tokenID; - int patientTypeID; - int patientType; + String? invoiceNo; + String? invoiceNoVP; + String? invoiceType; + String? orderNo; + String? setupID; + String? projectID; + int? clinicID; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + String? sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + int? patientID; + String? tokenID; + int? patientTypeID; + int? patientType; RequestPatientLabSpecialResult( {this.invoiceNo, - this.orderNo, - this.setupID, - this.projectID, - this.clinicID, - this.versionID, - this.channel, - this.languageID, - this.iPAdress, - this.generalid, - this.patientOutSA, - this.sessionID, - this.isDentalAllowedBackend, - this.deviceTypeID, - this.patientID, - this.tokenID, - this.patientTypeID, - this.patientType}); + this.invoiceNoVP, + this.invoiceType, + this.orderNo, + this.setupID, + this.projectID, + this.clinicID, + this.versionID, + this.channel, + this.languageID, + this.iPAdress, + this.generalid, + this.patientOutSA, + this.sessionID, + this.isDentalAllowedBackend, + this.deviceTypeID, + this.patientID, + this.tokenID, + this.patientTypeID, + this.patientType}); RequestPatientLabSpecialResult.fromJson(Map json) { invoiceNo = json['InvoiceNo']; + invoiceNo = json['InvoiceNo_VP']; + invoiceType = json['InvoiceType']; orderNo = json['OrderNo']; setupID = json['SetupID']; projectID = json['ProjectID']; @@ -62,6 +68,8 @@ class RequestPatientLabSpecialResult { Map toJson() { final Map data = new Map(); data['InvoiceNo'] = this.invoiceNo; + data['InvoiceNo_VP'] = this.invoiceNoVP; + data['InvoiceType'] = this.invoiceType; data['OrderNo'] = this.orderNo; data['SetupID'] = this.setupID; data['ProjectID'] = this.projectID; diff --git a/lib/core/model/labs/request_send_lab_report_email.dart b/lib/core/model/labs/request_send_lab_report_email.dart index 118da906..bfd99e52 100644 --- a/lib/core/model/labs/request_send_lab_report_email.dart +++ b/lib/core/model/labs/request_send_lab_report_email.dart @@ -1,29 +1,34 @@ class RequestSendLabReportEmail { - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - String sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; - int patientID; - String tokenID; - int patientTypeID; - int patientType; - String to; - String dateofBirth; - String patientIditificationNum; - String patientMobileNumber; - String patientName; - String setupID; - String projectName; - String clinicName; - String doctorName; - String projectID; - String invoiceNo; - String orderDate; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + String? sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + int? patientID; + String? tokenID; + int? patientTypeID; + int? patientType; + String? to; + String? dateofBirth; + String? patientIditificationNum; + String? patientMobileNumber; + String? patientName; + String? setupID; + String? projectName; + String? clinicName; + String? doctorName; + String? projectID; + String? invoiceNo; + String? invoiceNoVP; + String? invoiceType; + String? orderDate; + String? orderNo; + bool? isDownload; + int? doctorID; RequestSendLabReportEmail( {this.versionID, @@ -50,7 +55,12 @@ class RequestSendLabReportEmail { this.doctorName, this.projectID, this.invoiceNo, - this.orderDate}); + this.invoiceNoVP, + this.invoiceType, + this.orderDate, + this.orderNo, + this.isDownload, + this.doctorID}); RequestSendLabReportEmail.fromJson(Map json) { versionID = json['VersionID']; @@ -77,7 +87,12 @@ class RequestSendLabReportEmail { doctorName = json['DoctorName']; projectID = json['ProjectID']; invoiceNo = json['InvoiceNo']; + invoiceNoVP = json['InvoiceNo_VP']; + invoiceType = json['InvoiceType']; orderDate = json['OrderDate']; + orderNo = json['OrderNo']; + isDownload = json['IsDownload']; + doctorID = json['DoctorID']; } Map toJson() { @@ -106,7 +121,12 @@ class RequestSendLabReportEmail { data['DoctorName'] = this.doctorName; data['ProjectID'] = this.projectID; data['InvoiceNo'] = this.invoiceNo; + data['InvoiceNo_VP'] = this.invoiceNoVP; + data['InvoiceType'] = this.invoiceType; data['OrderDate'] = this.orderDate; + data['OrderNo'] = this.orderNo; + data['IsDownload'] = this.isDownload; + data['DoctorID'] = this.doctorID; return data; } } diff --git a/lib/core/model/my_balance/AdvanceModel.dart b/lib/core/model/my_balance/AdvanceModel.dart index d2792990..a186f9f6 100644 --- a/lib/core/model/my_balance/AdvanceModel.dart +++ b/lib/core/model/my_balance/AdvanceModel.dart @@ -2,16 +2,16 @@ import 'package:diplomaticquarterapp/core/model/blooddonation/get_all_cities.dar import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; class AdvanceModel { - String fileNumber; - String amount; - HospitalsModel hospitalsModel; - String email; - String note; - String depositorName; - String mobileNumber; - String patientName; - int projectID; - CitiesModel citiessModel; + String? fileNumber; + String? amount; + HospitalsModel? hospitalsModel; + String? email; + String? note; + String? depositorName; + String? mobileNumber; + String? patientName; + int? projectID; + CitiesModel? citiessModel; AdvanceModel( {this.amount, diff --git a/lib/core/model/my_balance/patient_advance_balance_amount.dart b/lib/core/model/my_balance/patient_advance_balance_amount.dart index 44a5083f..3d8b133f 100644 --- a/lib/core/model/my_balance/patient_advance_balance_amount.dart +++ b/lib/core/model/my_balance/patient_advance_balance_amount.dart @@ -1,8 +1,8 @@ class PatientAdvanceBalanceAmount { - int distanceInKilometers; + num? distanceInKilometers; dynamic patientAdvanceBalanceAmount; - String projectDescription; - int projectID; + String? projectDescription; + int? projectID; PatientAdvanceBalanceAmount( {this.distanceInKilometers, diff --git a/lib/core/model/my_balance/patient_info.dart b/lib/core/model/my_balance/patient_info.dart index 6004f014..0f307ec4 100644 --- a/lib/core/model/my_balance/patient_info.dart +++ b/lib/core/model/my_balance/patient_info.dart @@ -1,9 +1,9 @@ class PatientInfo { - String fullName; - String mobileNumber; - int patientID; - int projectID; - String zipCode; + String? fullName; + String? mobileNumber; + int? patientID; + int? projectID; + String? zipCode; PatientInfo( {this.fullName, diff --git a/lib/core/model/my_balance/patient_info_and_mobile_number.dart b/lib/core/model/my_balance/patient_info_and_mobile_number.dart index 8f05b4d9..45b9402e 100644 --- a/lib/core/model/my_balance/patient_info_and_mobile_number.dart +++ b/lib/core/model/my_balance/patient_info_and_mobile_number.dart @@ -1,42 +1,42 @@ class PatientInfoAndMobileNumber { - String setupID; - int projectID; - int mainAccountID; - int patientType; - int patientID; - String firstName; - Null middleName; - Null lastName; - Null firstNameN; - Null middleNameN; - Null lastNameN; - Null gender; - Null dateofBirth; - Null dateofBirthN; - Null nationalityID; - String mobileNumber; - String emailAddress; - Null zipCode; + String? setupID; + int? projectID; + int? mainAccountID; + int? patientType; + int? patientID; + String? firstName; + dynamic middleName; + dynamic lastName; + dynamic firstNameN; + dynamic middleNameN; + dynamic lastNameN; + dynamic gender; + dynamic dateofBirth; + dynamic dateofBirthN; + dynamic nationalityID; + String? mobileNumber; + String? emailAddress; + dynamic zipCode; PatientInfoAndMobileNumber( {this.setupID, - this.projectID, - this.mainAccountID, - this.patientType, - this.patientID, - this.firstName, - this.middleName, - this.lastName, - this.firstNameN, - this.middleNameN, - this.lastNameN, - this.gender, - this.dateofBirth, - this.dateofBirthN, - this.nationalityID, - this.mobileNumber, - this.emailAddress, - this.zipCode}); + this.projectID, + this.mainAccountID, + this.patientType, + this.patientID, + this.firstName, + this.middleName, + this.lastName, + this.firstNameN, + this.middleNameN, + this.lastNameN, + this.gender, + this.dateofBirth, + this.dateofBirthN, + this.nationalityID, + this.mobileNumber, + this.emailAddress, + this.zipCode}); PatientInfoAndMobileNumber.fromJson(Map json) { setupID = json['SetupID']; diff --git a/lib/core/model/my_balance/tamara_installment_details.dart b/lib/core/model/my_balance/tamara_installment_details.dart new file mode 100644 index 00000000..12769cdd --- /dev/null +++ b/lib/core/model/my_balance/tamara_installment_details.dart @@ -0,0 +1,83 @@ +class TamaraInstallmentDetails { + String? name; + String? description; + MinLimit? minLimit; + MinLimit? maxLimit; + List? supportedInstalments; + + TamaraInstallmentDetails({this.name, this.description, this.minLimit, this.maxLimit, this.supportedInstalments}); + + TamaraInstallmentDetails.fromJson(Map json) { + name = json['name']; + description = json['description']; + minLimit = json['minLimit'] != null ? new MinLimit.fromJson(json['minLimit']) : null; + maxLimit = json['maxLimit'] != null ? new MinLimit.fromJson(json['maxLimit']) : null; + if (json['supportedInstalments'] != null) { + supportedInstalments = []; + json['supportedInstalments'].forEach((v) { + supportedInstalments!.add(new SupportedInstalments.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + data['name'] = this.name; + data['description'] = this.description; + if (this.minLimit != null) { + data['minLimit'] = this.minLimit!.toJson(); + } + if (this.maxLimit != null) { + data['maxLimit'] = this.maxLimit!.toJson(); + } + if (this.supportedInstalments != null) { + data['supportedInstalments'] = this.supportedInstalments!.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class MinLimit { + String? currency; + int? amount; + + MinLimit({this.currency, this.amount}); + + MinLimit.fromJson(Map json) { + currency = json['currency']; + amount = json['amount']; + } + + Map toJson() { + final Map data = new Map(); + data['currency'] = this.currency; + data['amount'] = this.amount; + return data; + } +} + +class SupportedInstalments { + int? instalments; + MinLimit? minLimit; + MinLimit? maxLimit; + + SupportedInstalments({this.instalments, this.minLimit, this.maxLimit}); + + SupportedInstalments.fromJson(Map json) { + instalments = json['instalments']; + minLimit = json['minLimit'] != null ? new MinLimit.fromJson(json['minLimit']) : null; + maxLimit = json['maxLimit'] != null ? new MinLimit.fromJson(json['maxLimit']) : null; + } + + Map toJson() { + final Map data = new Map(); + data['instalments'] = this.instalments; + if (this.minLimit != null) { + data['minLimit'] = this.minLimit!.toJson(); + } + if (this.maxLimit != null) { + data['maxLimit'] = this.maxLimit!.toJson(); + } + return data; + } +} diff --git a/lib/core/model/my_trakers/blood_pressur/BloodPressureResult.dart b/lib/core/model/my_trakers/blood_pressur/BloodPressureResult.dart index 57f2cd54..1528c5f7 100644 --- a/lib/core/model/my_trakers/blood_pressur/BloodPressureResult.dart +++ b/lib/core/model/my_trakers/blood_pressur/BloodPressureResult.dart @@ -1,23 +1,23 @@ import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; class BloodPressureResult { - int patientID; - int lineItemNo; - DateTime bloodPressureDate; - int measuredArm; - int systolicePressure; - int diastolicPressure; + int? patientID; + int? lineItemNo; + DateTime? bloodPressureDate; + int? measuredArm; + int? systolicePressure; + int? diastolicPressure; dynamic remark; - bool isActive; - int chartYear; - String chartMonth; + bool? isActive; + int? chartYear; + String? chartMonth; dynamic yearSystolicePressureAverageResult; dynamic monthSystolicePressureResult; dynamic weekSystolicePressureResult; - int yearDiastolicPressureAverageResult; + int? yearDiastolicPressureAverageResult; dynamic monthDiastolicPressureResult; dynamic weekDiastolicPressureResult; - String measuredArmDesc; + String? measuredArmDesc; dynamic weekDesc; BloodPressureResult( diff --git a/lib/core/model/my_trakers/blood_pressur/MonthBloodPressureResultAverage.dart b/lib/core/model/my_trakers/blood_pressur/MonthBloodPressureResultAverage.dart index 5343119c..ea0061a1 100644 --- a/lib/core/model/my_trakers/blood_pressur/MonthBloodPressureResultAverage.dart +++ b/lib/core/model/my_trakers/blood_pressur/MonthBloodPressureResultAverage.dart @@ -7,9 +7,9 @@ class MonthBloodPressureResultAverage { dynamic weektwoDiastolicPressureAverageResult; dynamic weekoneSystolicePressureAverageResult; dynamic weekoneDiastolicPressureAverageResult; - String weekDesc; - int weekDiastolicPressureAverageResult; - int weekSystolicePressureAverageResult; + String? weekDesc; + int? weekDiastolicPressureAverageResult; + int? weekSystolicePressureAverageResult; MonthBloodPressureResultAverage( {this.weekfourSystolicePressureAverageResult, diff --git a/lib/core/model/my_trakers/blood_pressur/WeekBloodPressureResultAverage.dart b/lib/core/model/my_trakers/blood_pressur/WeekBloodPressureResultAverage.dart index b7f3fc80..b3fd4b7f 100644 --- a/lib/core/model/my_trakers/blood_pressur/WeekBloodPressureResultAverage.dart +++ b/lib/core/model/my_trakers/blood_pressur/WeekBloodPressureResultAverage.dart @@ -1,9 +1,9 @@ import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; class WeekBloodPressureResultAverage { - int dailySystolicePressureAverageResult; - int dailyDiastolicPressureAverageResult; - DateTime bloodPressureDate; + int? dailySystolicePressureAverageResult; + int? dailyDiastolicPressureAverageResult; + DateTime? bloodPressureDate; WeekBloodPressureResultAverage( {this.dailySystolicePressureAverageResult, diff --git a/lib/core/model/my_trakers/blood_pressur/YearBloodPressureResultAverage.dart b/lib/core/model/my_trakers/blood_pressur/YearBloodPressureResultAverage.dart index 095738d6..bd78d04c 100644 --- a/lib/core/model/my_trakers/blood_pressur/YearBloodPressureResultAverage.dart +++ b/lib/core/model/my_trakers/blood_pressur/YearBloodPressureResultAverage.dart @@ -1,12 +1,12 @@ import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; class YearBloodPressureResultAverage { - int monthSystolicePressureAverageResult; - int monthDiastolicPressureAverageResult; + int? monthSystolicePressureAverageResult; + int? monthDiastolicPressureAverageResult; dynamic monthNumber; - String monthName; - String yearName; - DateTime date; + String? monthName; + String? yearName; + DateTime? date; YearBloodPressureResultAverage( {this.monthSystolicePressureAverageResult, @@ -23,7 +23,7 @@ class YearBloodPressureResultAverage { monthNumber = json['monthNumber']; monthName = json['monthName']; yearName = json['yearName']; - date = DateUtil.getMonthDateTime(monthName,yearName); + date = DateUtil.getMonthDateTime(monthName!,yearName); } diff --git a/lib/core/model/my_trakers/blood_sugar/DiabtecPatientResult.dart b/lib/core/model/my_trakers/blood_sugar/DiabtecPatientResult.dart index 86263155..62decb02 100644 --- a/lib/core/model/my_trakers/blood_sugar/DiabtecPatientResult.dart +++ b/lib/core/model/my_trakers/blood_sugar/DiabtecPatientResult.dart @@ -1,26 +1,26 @@ import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; class DiabtecPatientResult { - String chartMonth; + String? chartMonth; var chartYear; - DateTime dateChart; + DateTime? dateChart; var description; var descriptionN; - int diabtecAvarage; - bool isActive; - int lineItemNo; + int? diabtecAvarage; + bool? isActive; + int? lineItemNo; var listMonth; var listWeek; - int measured; - String measuredDesc; + int? measured; + String? measuredDesc; var monthAverageResult; - int patientID; + int? patientID; var remark; var resultDesc; dynamic resultValue; - String unit; + String? unit; var weekAverageResult; - String weekDesc; + String? weekDesc; var yearAverageResult; DiabtecPatientResult( @@ -74,7 +74,7 @@ class DiabtecPatientResult { final Map data = new Map(); data['ChartMonth'] = this.chartMonth; data['ChartYear'] = this.chartYear; - data['DateChart'] = DateUtil.convertDateToString(this.dateChart); + data['DateChart'] = DateUtil.convertDateToString(this.dateChart!); data['Description'] = this.description; data['DescriptionN'] = this.descriptionN; data['DiabtecAvarage'] = this.diabtecAvarage; diff --git a/lib/core/model/my_trakers/blood_sugar/MonthDiabtectResultAverage.dart b/lib/core/model/my_trakers/blood_sugar/MonthDiabtectResultAverage.dart index 65522098..c52c08f3 100644 --- a/lib/core/model/my_trakers/blood_sugar/MonthDiabtectResultAverage.dart +++ b/lib/core/model/my_trakers/blood_sugar/MonthDiabtectResultAverage.dart @@ -4,7 +4,7 @@ class MonthDiabtectResultAverage { var weektwoAverageResult; var weekoneAverageResult; dynamic weekAverageResult; - String weekDesc; + String? weekDesc; MonthDiabtectResultAverage( {this.weekfourAverageResult, diff --git a/lib/core/model/my_trakers/blood_sugar/WeekDiabtectResultAverage.dart b/lib/core/model/my_trakers/blood_sugar/WeekDiabtectResultAverage.dart index 3b1a8d9c..4d7c7952 100644 --- a/lib/core/model/my_trakers/blood_sugar/WeekDiabtectResultAverage.dart +++ b/lib/core/model/my_trakers/blood_sugar/WeekDiabtectResultAverage.dart @@ -2,7 +2,7 @@ import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; class WeekDiabtectResultAverage { dynamic dailyAverageResult; - DateTime dateChart; + DateTime? dateChart; WeekDiabtectResultAverage({this.dailyAverageResult, this.dateChart}); @@ -14,7 +14,7 @@ class WeekDiabtectResultAverage { Map toJson() { final Map data = new Map(); data['DailyAverageResult'] = this.dailyAverageResult; - data['DateChart'] = DateUtil.convertDateToString(this.dateChart); + data['DateChart'] = DateUtil.convertDateToString(this.dateChart!); return data; } } diff --git a/lib/core/model/my_trakers/blood_sugar/YearDiabtecResultAverage.dart b/lib/core/model/my_trakers/blood_sugar/YearDiabtecResultAverage.dart index cfdec286..8521e011 100644 --- a/lib/core/model/my_trakers/blood_sugar/YearDiabtecResultAverage.dart +++ b/lib/core/model/my_trakers/blood_sugar/YearDiabtecResultAverage.dart @@ -3,9 +3,9 @@ import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; class YearDiabtecResultAverage { dynamic monthAverageResult; var monthNumber; - String monthName; - String yearName; - DateTime date; + String? monthName; + String? yearName; + DateTime? date; YearDiabtecResultAverage( {this.monthAverageResult, @@ -19,7 +19,7 @@ class YearDiabtecResultAverage { monthNumber = json['monthNumber']; monthName = json['monthName']; yearName = json['yearName']; - date = DateUtil.getMonthDateTime(monthName,yearName); + date = DateUtil.getMonthDateTime(monthName!,yearName); } catch (e) { print(e); } diff --git a/lib/core/model/my_trakers/chartData/WeekChartDate.dart b/lib/core/model/my_trakers/chartData/WeekChartDate.dart index d972265d..ae3a9f47 100644 --- a/lib/core/model/my_trakers/chartData/WeekChartDate.dart +++ b/lib/core/model/my_trakers/chartData/WeekChartDate.dart @@ -1,5 +1,5 @@ class WeekChartDate { - final DateTime x; + final DateTime? x; final dynamic y; WeekChartDate({this.x, this.y}); diff --git a/lib/core/model/my_trakers/weight/MonthWeightMeasurementResultAverage.dart b/lib/core/model/my_trakers/weight/MonthWeightMeasurementResultAverage.dart index 8165302d..0296399a 100644 --- a/lib/core/model/my_trakers/weight/MonthWeightMeasurementResultAverage.dart +++ b/lib/core/model/my_trakers/weight/MonthWeightMeasurementResultAverage.dart @@ -4,7 +4,7 @@ class MonthWeightMeasurementResultAverage { dynamic weektwoAverageResult; dynamic weekoneAverageResult; dynamic weekAverageResult; - String weekDesc; + String? weekDesc; MonthWeightMeasurementResultAverage( {this.weekfourAverageResult, diff --git a/lib/core/model/my_trakers/weight/WeekWeightMeasurementResultAverage.dart b/lib/core/model/my_trakers/weight/WeekWeightMeasurementResultAverage.dart index b7345ad7..1c3566a9 100644 --- a/lib/core/model/my_trakers/weight/WeekWeightMeasurementResultAverage.dart +++ b/lib/core/model/my_trakers/weight/WeekWeightMeasurementResultAverage.dart @@ -2,7 +2,7 @@ import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; class WeekWeightMeasurementResultAverage { dynamic dailyAverageResult; - DateTime weightDate; + DateTime? weightDate; WeekWeightMeasurementResultAverage( {this.dailyAverageResult, this.weightDate}); diff --git a/lib/core/model/my_trakers/weight/WeightMeasurementResult.dart b/lib/core/model/my_trakers/weight/WeightMeasurementResult.dart index 337e8662..7436eccc 100644 --- a/lib/core/model/my_trakers/weight/WeightMeasurementResult.dart +++ b/lib/core/model/my_trakers/weight/WeightMeasurementResult.dart @@ -1,17 +1,17 @@ import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; class WeightMeasurementResult { - int patientID; - int lineItemNo; - int weightMeasured; - DateTime weightDate; + int? patientID; + int? lineItemNo; + int? weightMeasured; + DateTime? weightDate; dynamic remark; - bool isActive; - int measured; + bool? isActive; + int? measured; dynamic unit; - int chartYear; + int? chartYear; dynamic chartMonth; - double yearAverageResult; + double? yearAverageResult; dynamic monthAverageResult; dynamic weekAverageResult; dynamic weekDesc; diff --git a/lib/core/model/my_trakers/weight/YearWeightMeasurementResultAverage.dart b/lib/core/model/my_trakers/weight/YearWeightMeasurementResultAverage.dart index c2e20cb9..a8d64423 100644 --- a/lib/core/model/my_trakers/weight/YearWeightMeasurementResultAverage.dart +++ b/lib/core/model/my_trakers/weight/YearWeightMeasurementResultAverage.dart @@ -2,10 +2,10 @@ import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; class YearWeightMeasurementResultAverage { dynamic monthAverageResult; - int monthNumber; - String monthName; - String yearName; - DateTime date; + int? monthNumber; + String? monthName; + String? yearName; + DateTime? date; YearWeightMeasurementResultAverage( {this.monthAverageResult, @@ -18,7 +18,7 @@ class YearWeightMeasurementResultAverage { monthNumber = json['monthNumber']; monthName = json['monthName']; yearName = json['yearName']; - date = DateUtil.getMonthDateTime(monthName,yearName); + date = DateUtil.getMonthDateTime(monthName!,yearName); } diff --git a/lib/core/model/notifications/get_notifications_request_model.dart b/lib/core/model/notifications/get_notifications_request_model.dart index 9659754a..1cf99092 100644 --- a/lib/core/model/notifications/get_notifications_request_model.dart +++ b/lib/core/model/notifications/get_notifications_request_model.dart @@ -1,7 +1,7 @@ class GetNotificationsRequestModel { - int notificationStatusID; - int pagingSize; - int currentPage; + int? notificationStatusID; + int? pagingSize; + int? currentPage; GetNotificationsRequestModel( {this.notificationStatusID, this.pagingSize, this.currentPage}); diff --git a/lib/core/model/notifications/get_notifications_response_model.dart b/lib/core/model/notifications/get_notifications_response_model.dart index 1f3bbc28..60b9c764 100644 --- a/lib/core/model/notifications/get_notifications_response_model.dart +++ b/lib/core/model/notifications/get_notifications_response_model.dart @@ -1,25 +1,25 @@ class GetNotificationsResponseModel { - int id; - int recordId; - int patientID; - bool projectOutSA; - String deviceType; - String deviceToken; - String message; - String messageType; - String messageTypeData; + int? id; + int? recordId; + int? patientID; + bool? projectOutSA; + String? deviceType; + String? deviceToken; + String? message; + String? messageType; + String? messageTypeData; dynamic videoURL; - bool isQueue; - String isQueueOn; - String createdOn; - String createdBy; - String notificationType; - bool isSent; - String isSentOn; - bool isRead; - String isReadOn; - int channelID; - int projectID; + bool? isQueue; + String? isQueueOn; + String? createdOn; + String? createdBy; + String? notificationType; + bool? isSent; + String? isSentOn; + bool? isRead; + String? isReadOn; + int? channelID; + int? projectID; GetNotificationsResponseModel( {this.id, diff --git a/lib/core/model/notifications/mark_message_as_read_request_model.dart b/lib/core/model/notifications/mark_message_as_read_request_model.dart index 99dab006..9bf84bbe 100644 --- a/lib/core/model/notifications/mark_message_as_read_request_model.dart +++ b/lib/core/model/notifications/mark_message_as_read_request_model.dart @@ -1,5 +1,5 @@ class MarkMessageAsReadRequestModel { - int notificationPoolID; + int? notificationPoolID; MarkMessageAsReadRequestModel({this.notificationPoolID}); diff --git a/lib/core/model/packages_offers/requests/AddProductToCartRequestModel.dart b/lib/core/model/packages_offers/requests/AddProductToCartRequestModel.dart index 69e56ad7..f9a4e718 100644 --- a/lib/core/model/packages_offers/requests/AddProductToCartRequestModel.dart +++ b/lib/core/model/packages_offers/requests/AddProductToCartRequestModel.dart @@ -1,10 +1,10 @@ import 'package:flutter/cupertino.dart'; class AddProductToCartRequestModel { - int quantity; - int product_id; - String shopping_cart_type; - int customer_id; + int? quantity; + int? product_id; + String? shopping_cart_type; + int? customer_id; AddProductToCartRequestModel({@required this.product_id, this.customer_id, this.shopping_cart_type = "ShoppingCart", this.quantity = 1}); @@ -21,6 +21,6 @@ class AddProductToCartRequestModel { } class UpdateProductToCartRequestModel extends AddProductToCartRequestModel{ - UpdateProductToCartRequestModel({@required int product_id, @required int customer_id, String shopping_cart_type = "ShoppingCart", int quantity = 1}) + UpdateProductToCartRequestModel({required int product_id, required int customer_id, String shopping_cart_type = "ShoppingCart", int quantity = 1}) : super(customer_id: customer_id, product_id: product_id, quantity: quantity, shopping_cart_type: shopping_cart_type); } diff --git a/lib/core/model/packages_offers/requests/CreateCustomerRequestModel.dart b/lib/core/model/packages_offers/requests/CreateCustomerRequestModel.dart index 116545bd..58161886 100644 --- a/lib/core/model/packages_offers/requests/CreateCustomerRequestModel.dart +++ b/lib/core/model/packages_offers/requests/CreateCustomerRequestModel.dart @@ -1,20 +1,44 @@ +import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:flutter/cupertino.dart'; class PackagesCustomerRequestModel { - String email; - String phoneNumber; + String? username; + String? first_name; + String? last_name; + String? email; + 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; + + String isoDateTime = DateUtil.getISODateFormat(user.dateofBirthDataTime!); + this.date_of_birth = isoDateTime; + } 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/model/packages_offers/requests/OffersCategoriesRequestModel.dart b/lib/core/model/packages_offers/requests/OffersCategoriesRequestModel.dart index 13dba945..ecaf0a5c 100644 --- a/lib/core/model/packages_offers/requests/OffersCategoriesRequestModel.dart +++ b/lib/core/model/packages_offers/requests/OffersCategoriesRequestModel.dart @@ -1,16 +1,16 @@ class OffersCategoriesRequestModel { - final int limit; - final int page; - final int sinceId; + final int? limit; + final int? page; + final int? sinceId; OffersCategoriesRequestModel({this.limit, this.page, this.sinceId}); Map toFlatMap() { return { - if(limit != null && limit > 0) + if(limit != null && limit! > 0) "limit": limit.toString(), - if(page != null && page > 0) + if(page != null && page! > 0) "page": page.toString(), }; } diff --git a/lib/core/model/packages_offers/requests/OffersProductsRequestModel.dart b/lib/core/model/packages_offers/requests/OffersProductsRequestModel.dart index 583932bb..00e71e54 100644 --- a/lib/core/model/packages_offers/requests/OffersProductsRequestModel.dart +++ b/lib/core/model/packages_offers/requests/OffersProductsRequestModel.dart @@ -1,23 +1,27 @@ class OffersProductsRequestModel { - final int categoryId; - final int limit; + final int? categoryId; + final int? storeId; + final int? limit; // final int page; - int sinceId; + int? sinceId; - OffersProductsRequestModel({this.categoryId, this.limit = 50}); + OffersProductsRequestModel({this.categoryId, this.limit = 50, this.storeId}); Map toFlatMap() { return { - if(limit != null && limit > 0) + if(limit != null && limit! > 0) "limit": limit.toString(), // if(page != null && page > 0) // "page": page.toString(), - if(categoryId != null && categoryId > 0) + if(categoryId != null && categoryId! > 0) "categoryId": categoryId.toString(), + if(storeId != null && storeId! > 0) + "store_id": storeId.toString(), + "sinceId": sinceId != null ? sinceId.toString() : "0", }; } diff --git a/lib/core/model/packages_offers/responses/PackagesCartItemsResponseModel.dart b/lib/core/model/packages_offers/responses/PackagesCartItemsResponseModel.dart index 99c8a8b4..31350efb 100644 --- a/lib/core/model/packages_offers/responses/PackagesCartItemsResponseModel.dart +++ b/lib/core/model/packages_offers/responses/PackagesCartItemsResponseModel.dart @@ -1,36 +1,34 @@ - import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart'; class PackagesCartItemsResponseModel { - int _quantity; + int? _quantity; set quantity(int value) { _quantity = value; } - String _shoppingCartType; - int _productId; - PackagesResponseModel _product; - int _id; - - int get quantity => _quantity; - String get shoppingCartType => _shoppingCartType; - int get productId => _productId; - PackagesResponseModel get product => _product; - int get id => _id; - - PackagesCartItemsResponseModel({ - int quantity, - String shoppingCartType, - int productId, - PackagesResponseModel product, - int id}){ - _quantity = quantity; + String? _shoppingCartType; + int? _productId; + PackagesResponseModel? _product; + int? _id; + + int get quantity => _quantity!; + + String get shoppingCartType => _shoppingCartType!; + + int get productId => _productId!; + + PackagesResponseModel get product => _product!; + + int get id => _id!; + + PackagesCartItemsResponseModel({int? quantity, String? shoppingCartType, int? productId, PackagesResponseModel? product, int? id}) { + _quantity = quantity!; _shoppingCartType = shoppingCartType; _productId = productId; _product = product; _id = id; -} + } PackagesCartItemsResponseModel.fromJson(dynamic json) { _quantity = json["quantity"]; @@ -46,39 +44,37 @@ class PackagesCartItemsResponseModel { map["shopping_cart_type"] = _shoppingCartType; map["product_id"] = _productId; if (_product != null) { - map["product"] = _product.toJson(); + map["product"] = _product!.toJson(); } map["id"] = _id; return map; } - } class Images { - int _id; - int _pictureId; - int _position; - String _src; + int? _id; + int? _pictureId; + int? _position; + String? _src; dynamic _attachment; - int get id => _id; - int get pictureId => _pictureId; - int get position => _position; - String get src => _src; + int get id => _id!; + + int get pictureId => _pictureId!; + + int get position => _position!; + + String get src => _src!; + dynamic get attachment => _attachment; - Images({ - int id, - int pictureId, - int position, - String src, - dynamic attachment}){ + Images({int? id, int? pictureId, int? position, String? src, dynamic attachment}) { _id = id; _pictureId = pictureId; _position = position; _src = src; _attachment = attachment; -} + } Images.fromJson(dynamic json) { _id = json["id"]; @@ -97,25 +93,23 @@ class Images { map["attachment"] = _attachment; return map; } - } /// language_id : 1 /// localized_name : "Dermatology testing" class Localized_names { - int _languageId; - String _localizedName; + int? _languageId; + String? _localizedName; - int get languageId => _languageId; - String get localizedName => _localizedName; + int get languageId => _languageId!; - Localized_names({ - int languageId, - String localizedName}){ + String get localizedName => _localizedName!; + + Localized_names({int? languageId, String? localizedName}) { _languageId = languageId; _localizedName = localizedName; -} + } Localized_names.fromJson(dynamic json) { _languageId = json["language_id"]; @@ -128,5 +122,4 @@ class Localized_names { map["localized_name"] = _localizedName; return map; } - -} \ No newline at end of file +} diff --git a/lib/core/model/packages_offers/responses/PackagesCategoriesResponseModel.dart b/lib/core/model/packages_offers/responses/PackagesCategoriesResponseModel.dart index 292022c0..7db2b736 100644 --- a/lib/core/model/packages_offers/responses/PackagesCategoriesResponseModel.dart +++ b/lib/core/model/packages_offers/responses/PackagesCategoriesResponseModel.dart @@ -1,77 +1,77 @@ import 'package:diplomaticquarterapp/generated/json/base/json_convert_content.dart'; import 'package:diplomaticquarterapp/generated/json/base/json_field.dart'; -class PackagesCategoriesResponseModel with JsonConvert { - int id; - String name; - String namen; +class PackagesCategoriesResponseModel extends JsonConvert { + int? id; + String? name; + String? namen; @JSONField(name: "localized_names") - List localizedNames; + List? localizedNames; dynamic description; @JSONField(name: "category_template_id") - int categoryTemplateId; + int? categoryTemplateId; @JSONField(name: "meta_keywords") - String metaKeywords; + String? metaKeywords; @JSONField(name: "meta_description") - String metaDescription; + String? metaDescription; @JSONField(name: "meta_title") - String metaTitle; + String? metaTitle; @JSONField(name: "parent_category_id") - int parentCategoryId; + int? parentCategoryId; @JSONField(name: "page_size") - int pageSize; + int? pageSize; @JSONField(name: "page_size_options") - String pageSizeOptions; + String? pageSizeOptions; @JSONField(name: "price_ranges") dynamic priceRanges; @JSONField(name: "show_on_home_page") - bool showOnHomePage; + bool? showOnHomePage; @JSONField(name: "include_in_top_menu") - bool includeInTopMenu; + bool? includeInTopMenu; @JSONField(name: "has_discounts_applied") dynamic hasDiscountsApplied; - bool published; - bool deleted; + bool? published; + bool? deleted; @JSONField(name: "display_order") - int displayOrder; + int? displayOrder; @JSONField(name: "created_on_utc") - String createdOnUtc; + String? createdOnUtc; @JSONField(name: "updated_on_utc") - String updatedOnUtc; + String? updatedOnUtc; @JSONField(name: "role_ids") - List roleIds; + List? roleIds; @JSONField(name: "discount_ids") - List discountIds; + List? discountIds; @JSONField(name: "store_ids") - List storeIds; - OfferCategoriesResponseModelImage image; + List? storeIds; + OfferCategoriesResponseModelImage? image; @JSONField(name: "se_name") - String seName; + String? seName; @JSONField(name: "is_leaf") - bool isLeaf; + bool? isLeaf; @override String toString() { - if(localizedNames.length == 2){ - if(localizedNames.first.languageId == 1) - return localizedNames.first.localizedName ?? name; + if(localizedNames!.length == 2){ + if(localizedNames!.first.languageId == 1) + return localizedNames?.first.localizedName ?? name.toString(); - else if(localizedNames.first.languageId == 2) - return localizedNames.last.localizedName ?? name; + else if(localizedNames?.first.languageId == 2) + return localizedNames?.last.localizedName ?? name.toString(); } - return name; + return name.toString(); } } -class OfferCategoriesResponseModelLocalizedName with JsonConvert { +class OfferCategoriesResponseModelLocalizedName extends JsonConvert { @JSONField(name: "language_id") - int languageId; + int? languageId; @JSONField(name: "localized_name") - String localizedName; + String? localizedName; } -class OfferCategoriesResponseModelImage with JsonConvert { - String src; +class OfferCategoriesResponseModelImage extends JsonConvert { + String? src; dynamic thumb; dynamic attachment; } diff --git a/lib/core/model/packages_offers/responses/PackagesCustomerResponseModel.dart b/lib/core/model/packages_offers/responses/PackagesCustomerResponseModel.dart index 245973dd..8ddfd322 100644 --- a/lib/core/model/packages_offers/responses/PackagesCustomerResponseModel.dart +++ b/lib/core/model/packages_offers/responses/PackagesCustomerResponseModel.dart @@ -29,90 +29,90 @@ import 'PackagesCartItemsResponseModel.dart'; /// id : 76823 class PackagesCustomerResponseModel { - List _shoppingCartItems; + List? _shoppingCartItems; dynamic _billingAddress; dynamic _shippingAddress; - List _addresses; - String _customerGuid; + List? _addresses; + String? _customerGuid; dynamic _username; - String _email; + String? _email; dynamic _firstName; dynamic _lastName; dynamic _languageId; dynamic _dateOfBirth; dynamic _gender; dynamic _adminComment; - bool _isTaxExempt; - bool _hasShoppingCartItems; - bool _active; - bool _deleted; - bool _isSystemAccount; + bool? _isTaxExempt; + bool? _hasShoppingCartItems; + bool? _active; + bool? _deleted; + bool? _isSystemAccount; dynamic _systemName; dynamic _lastIpAddress; - String _createdOnUtc; + String? _createdOnUtc; dynamic _lastLoginDateUtc; - String _lastActivityDateUtc; - int _registeredInStoreId; - bool _subscribedToNewsletter; - List _roleIds; - int _id; + String? _lastActivityDateUtc; + int? _registeredInStoreId; + bool? _subscribedToNewsletter; + List? _roleIds; + int? _id; - List get shoppingCartItems => _shoppingCartItems; + List get shoppingCartItems => _shoppingCartItems!; dynamic get billingAddress => _billingAddress; dynamic get shippingAddress => _shippingAddress; - List get addresses => _addresses; - String get customerGuid => _customerGuid; + List get addresses => _addresses!; + String get customerGuid => _customerGuid!; dynamic get username => _username; - String get email => _email; + String get email => _email!; dynamic get firstName => _firstName; dynamic get lastName => _lastName; dynamic get languageId => _languageId; dynamic get dateOfBirth => _dateOfBirth; dynamic get gender => _gender; dynamic get adminComment => _adminComment; - bool get isTaxExempt => _isTaxExempt; - bool get hasShoppingCartItems => _hasShoppingCartItems; - bool get active => _active; - bool get deleted => _deleted; - bool get isSystemAccount => _isSystemAccount; + bool get isTaxExempt => _isTaxExempt!; + bool get hasShoppingCartItems => _hasShoppingCartItems!; + bool get active => _active!; + bool get deleted => _deleted!; + bool get isSystemAccount => _isSystemAccount!; dynamic get systemName => _systemName; dynamic get lastIpAddress => _lastIpAddress; - String get createdOnUtc => _createdOnUtc; + String get createdOnUtc => _createdOnUtc!; dynamic get lastLoginDateUtc => _lastLoginDateUtc; - String get lastActivityDateUtc => _lastActivityDateUtc; - int get registeredInStoreId => _registeredInStoreId; - bool get subscribedToNewsletter => _subscribedToNewsletter; - List get roleIds => _roleIds; - int get id => _id; + String get lastActivityDateUtc => _lastActivityDateUtc!; + int get registeredInStoreId => _registeredInStoreId!; + bool get subscribedToNewsletter => _subscribedToNewsletter!; + List get roleIds => _roleIds!; + int get id => _id!; PackagesCustomerResponseModel({ - List shoppingCartItems, + List? shoppingCartItems, dynamic billingAddress, dynamic shippingAddress, - List addresses, - String customerGuid, + List? addresses, + String? customerGuid, dynamic username, - String email, + String? email, dynamic firstName, dynamic lastName, dynamic languageId, dynamic dateOfBirth, dynamic gender, dynamic adminComment, - bool isTaxExempt, - bool hasShoppingCartItems, - bool active, - bool deleted, - bool isSystemAccount, + bool? isTaxExempt, + bool? hasShoppingCartItems, + bool? active, + bool? deleted, + bool? isSystemAccount, dynamic systemName, dynamic lastIpAddress, - String createdOnUtc, + String? createdOnUtc, dynamic lastLoginDateUtc, - String lastActivityDateUtc, - int registeredInStoreId, - bool subscribedToNewsletter, - List roleIds, - int id}){ + String? lastActivityDateUtc, + int? registeredInStoreId, + bool? subscribedToNewsletter, + List? roleIds, + int? id}){ _shoppingCartItems = shoppingCartItems; _billingAddress = billingAddress; _shippingAddress = shippingAddress; @@ -148,7 +148,7 @@ class PackagesCustomerResponseModel { if (json["addresses"] != null) { _addresses = []; json["addresses"].forEach((v) { - _addresses.add(Addresses.fromJson(v)); + _addresses!.add(Addresses.fromJson(v)); }); } _customerGuid = json["customer_guid"]; @@ -176,14 +176,14 @@ class PackagesCustomerResponseModel { if (json["role_ids"] != null) { _roleIds = []; json["role_ids"].forEach((v) { - _roleIds.add(v); + _roleIds!.add(v); }); } if (json["shopping_cart_items"] != null) { _shoppingCartItems = []; json["shopping_cart_items"].forEach((v) { - _shoppingCartItems.add(PackagesCartItemsResponseModel.fromJson(v)); + _shoppingCartItems!.add(PackagesCartItemsResponseModel.fromJson(v)); }); } @@ -193,12 +193,12 @@ class PackagesCustomerResponseModel { Map toJson() { var map = {}; if (_shoppingCartItems != null) { - map["shopping_cart_items"] = _shoppingCartItems.map((v) => v.toJson()).toList(); + map["shopping_cart_items"] = _shoppingCartItems!.map((v) => v.toJson()).toList(); } map["billing_address"] = _billingAddress; map["shipping_address"] = _shippingAddress; if (_addresses != null) { - map["addresses"] = _addresses.map((v) => v.toJson()).toList(); + map["addresses"] = _addresses!.map((v) => v.toJson()).toList(); } map["customer_guid"] = _customerGuid; map["username"] = _username; @@ -222,7 +222,7 @@ class PackagesCustomerResponseModel { map["registered_in_store_id"] = _registeredInStoreId; map["subscribed_to_newsletter"] = _subscribedToNewsletter; if (_roleIds != null) { - map["role_ids"] = _roleIds.map((v) => v).toList(); + map["role_ids"] = _roleIds!.map((v) => v).toList(); } map["id"] = _id; return map; @@ -251,7 +251,7 @@ class PackagesCustomerResponseModel { class Addresses { dynamic _firstName; dynamic _lastName; - String _email; + String? _email; dynamic _company; dynamic _countryId; dynamic _country; @@ -260,16 +260,16 @@ class Addresses { dynamic _address1; dynamic _address2; dynamic _zipPostalCode; - String _phoneNumber; + String? _phoneNumber; dynamic _faxNumber; dynamic _customerAttributes; - String _createdOnUtc; + String? _createdOnUtc; dynamic _province; - int _id; + int? _id; dynamic get firstName => _firstName; dynamic get lastName => _lastName; - String get email => _email; + String get email => _email!; dynamic get company => _company; dynamic get countryId => _countryId; dynamic get country => _country; @@ -278,17 +278,17 @@ class Addresses { dynamic get address1 => _address1; dynamic get address2 => _address2; dynamic get zipPostalCode => _zipPostalCode; - String get phoneNumber => _phoneNumber; + String get phoneNumber => _phoneNumber!; dynamic get faxNumber => _faxNumber; dynamic get customerAttributes => _customerAttributes; - String get createdOnUtc => _createdOnUtc; + String get createdOnUtc => _createdOnUtc!; dynamic get province => _province; - int get id => _id; + int get id => _id!; Addresses({ dynamic firstName, dynamic lastName, - String email, + String? email, dynamic company, dynamic countryId, dynamic country, @@ -297,12 +297,12 @@ class Addresses { dynamic address1, dynamic address2, dynamic zipPostalCode, - String phoneNumber, + String? phoneNumber, dynamic faxNumber, dynamic customerAttributes, - String createdOnUtc, + String? createdOnUtc, dynamic province, - int id}){ + int? id}){ _firstName = firstName; _lastName = lastName; _email = email; diff --git a/lib/core/model/packages_offers/responses/PackagesResponseModel.dart b/lib/core/model/packages_offers/responses/PackagesResponseModel.dart index 7297a20a..90feacfa 100644 --- a/lib/core/model/packages_offers/responses/PackagesResponseModel.dart +++ b/lib/core/model/packages_offers/responses/PackagesResponseModel.dart @@ -1,26 +1,26 @@ import 'package:diplomaticquarterapp/generated/json/base/json_convert_content.dart'; import 'package:diplomaticquarterapp/generated/json/base/json_field.dart'; -class PackagesResponseModel with JsonConvert { - int id; +class PackagesResponseModel extends JsonConvert { + int? id; @JSONField(name: "visible_individually") - bool visibleIndividually; - String name; - String namen; + bool? visibleIndividually; + String? name; + String? namen; @JSONField(name: "localized_names") - List localizedNames; + List? localizedNames; @JSONField(name: "short_description") - String shortDescription; + String? shortDescription; @JSONField(name: "short_descriptionn") - String shortDescriptionn; + String? shortDescriptionn; @JSONField(name: "full_description") - String fullDescription; + String? fullDescription; @JSONField(name: "full_descriptionn") - String fullDescriptionn; + String? fullDescriptionn; @JSONField(name: "markas_new") - bool markasNew; + bool? markasNew; @JSONField(name: "show_on_home_page") - bool showOnHomePage; + bool? showOnHomePage; @JSONField(name: "meta_keywords") dynamic metaKeywords; @JSONField(name: "meta_description") @@ -28,20 +28,20 @@ class PackagesResponseModel with JsonConvert { @JSONField(name: "meta_title") dynamic metaTitle; @JSONField(name: "allow_customer_reviews") - bool allowCustomerReviews; + bool? allowCustomerReviews; @JSONField(name: "approved_rating_sum") - int approvedRatingSum; + int? approvedRatingSum; @JSONField(name: "not_approved_rating_sum") - int notApprovedRatingSum; + int? notApprovedRatingSum; @JSONField(name: "approved_total_reviews") - int approvedTotalReviews; + int? approvedTotalReviews; @JSONField(name: "not_approved_total_reviews") - int notApprovedTotalReviews; - String sku; + int? notApprovedTotalReviews; + String? sku; @JSONField(name: "is_rx") - bool isRx; + bool? isRx; @JSONField(name: "prescription_required") - bool prescriptionRequired; + bool? prescriptionRequired; @JSONField(name: "rx_message") dynamic rxMessage; @JSONField(name: "rx_messagen") @@ -50,88 +50,89 @@ class PackagesResponseModel with JsonConvert { dynamic manufacturerPartNumber; dynamic gtin; @JSONField(name: "is_gift_card") - bool isGiftCard; + bool? isGiftCard; @JSONField(name: "require_other_products") - bool requireOtherProducts; + bool? requireOtherProducts; @JSONField(name: "automatically_add_required_products") - bool automaticallyAddRequiredProducts; + bool? automaticallyAddRequiredProducts; @JSONField(name: "is_download") - bool isDownload; + bool? isDownload; + @JSONField(name: "unlimited_downloads") - bool unlimitedDownloads; + bool? unlimitedDownloads; @JSONField(name: "max_number_of_downloads") - int maxNumberOfDownloads; + int? maxNumberOfDownloads; @JSONField(name: "download_expiration_days") dynamic downloadExpirationDays; @JSONField(name: "has_sample_download") - bool hasSampleDownload; + bool? hasSampleDownload; @JSONField(name: "has_user_agreement") - bool hasUserAgreement; + bool? hasUserAgreement; @JSONField(name: "is_recurring") - bool isRecurring; + bool? isRecurring; @JSONField(name: "recurring_cycle_length") - int recurringCycleLength; + int? recurringCycleLength; @JSONField(name: "recurring_total_cycles") - int recurringTotalCycles; + int? recurringTotalCycles; @JSONField(name: "is_rental") - bool isRental; + bool? isRental; @JSONField(name: "rental_price_length") - int rentalPriceLength; + int? rentalPriceLength; @JSONField(name: "is_ship_enabled") - bool isShipEnabled; + bool? isShipEnabled; @JSONField(name: "is_free_shipping") - bool isFreeShipping; + bool? isFreeShipping; @JSONField(name: "ship_separately") - bool shipSeparately; + bool? shipSeparately; @JSONField(name: "additional_shipping_charge") - double additionalShippingCharge; + double? additionalShippingCharge; @JSONField(name: "is_tax_exempt") - bool isTaxExempt; + bool? isTaxExempt; @JSONField(name: "is_telecommunications_or_broadcasting_or_electronic_services") - bool isTelecommunicationsOrBroadcastingOrElectronicServices; + bool? isTelecommunicationsOrBroadcastingOrElectronicServices; @JSONField(name: "use_multiple_warehouses") - bool useMultipleWarehouses; + bool? useMultipleWarehouses; @JSONField(name: "manage_inventory_method_id") - int manageInventoryMethodId; + int? manageInventoryMethodId; @JSONField(name: "stock_quantity") - int stockQuantity; + int? stockQuantity; @JSONField(name: "stock_availability") - String stockAvailability; + String? stockAvailability; @JSONField(name: "stock_availabilityn") - String stockAvailabilityn; + String? stockAvailabilityn; @JSONField(name: "display_stock_availability") - bool displayStockAvailability; + bool? displayStockAvailability; @JSONField(name: "display_stock_quantity") - bool displayStockQuantity; + bool? displayStockQuantity; @JSONField(name: "min_stock_quantity") - int minStockQuantity; + int? minStockQuantity; @JSONField(name: "notify_admin_for_quantity_below") - int notifyAdminForQuantityBelow; + int? notifyAdminForQuantityBelow; @JSONField(name: "allow_back_in_stock_subscriptions") - bool allowBackInStockSubscriptions; + bool? allowBackInStockSubscriptions; @JSONField(name: "order_minimum_quantity") - int orderMinimumQuantity; + int? orderMinimumQuantity; @JSONField(name: "order_maximum_quantity") - int orderMaximumQuantity; + int? orderMaximumQuantity; @JSONField(name: "allowed_quantities") dynamic allowedQuantities; @JSONField(name: "allow_adding_only_existing_attribute_combinations") - bool allowAddingOnlyExistingAttributeCombinations; + bool? allowAddingOnlyExistingAttributeCombinations; @JSONField(name: "disable_buy_button") - bool disableBuyButton; + bool? disableBuyButton; @JSONField(name: "disable_wishlist_button") - bool disableWishlistButton; + bool? disableWishlistButton; @JSONField(name: "available_for_pre_order") - bool availableForPreOrder; + bool? availableForPreOrder; @JSONField(name: "pre_order_availability_start_date_time_utc") dynamic preOrderAvailabilityStartDateTimeUtc; @JSONField(name: "call_for_price") - bool callForPrice; - double price; + bool? callForPrice; + double? price; @JSONField(name: "old_price") - double oldPrice; + double? oldPrice; @JSONField(name: "product_cost") - double productCost; + double? productCost; @JSONField(name: "special_price") dynamic specialPrice; @JSONField(name: "special_price_start_date_time_utc") @@ -139,21 +140,21 @@ class PackagesResponseModel with JsonConvert { @JSONField(name: "special_price_end_date_time_utc") dynamic specialPriceEndDateTimeUtc; @JSONField(name: "customer_enters_price") - bool customerEntersPrice; + bool? customerEntersPrice; @JSONField(name: "minimum_customer_entered_price") - double minimumCustomerEnteredPrice; + double? minimumCustomerEnteredPrice; @JSONField(name: "maximum_customer_entered_price") - double maximumCustomerEnteredPrice; + double? maximumCustomerEnteredPrice; @JSONField(name: "baseprice_enabled") - bool basepriceEnabled; + bool? basepriceEnabled; @JSONField(name: "baseprice_amount") - double basepriceAmount; + double? basepriceAmount; @JSONField(name: "baseprice_base_amount") - double basepriceBaseAmount; + double? basepriceBaseAmount; @JSONField(name: "has_tier_prices") - bool hasTierPrices; + bool? hasTierPrices; @JSONField(name: "has_discounts_applied") - bool hasDiscountsApplied; + bool? hasDiscountsApplied; @JSONField(name: "discount_name") dynamic discountName; @JSONField(name: "discount_namen") @@ -164,83 +165,83 @@ class PackagesResponseModel with JsonConvert { dynamic discountDescriptionn; @JSONField(name: "discount_percentage") dynamic discountPercentage; - String currency; - String currencyn; - double weight; - double length; - double width; - double height; + String? currency; + String? currencyn; + double? weight; + double? length; + double? width; + double? height; @JSONField(name: "available_start_date_time_utc") dynamic availableStartDateTimeUtc; @JSONField(name: "available_end_date_time_utc") dynamic availableEndDateTimeUtc; @JSONField(name: "display_order") - int displayOrder; - bool published; - bool deleted; + int? displayOrder; + bool? published; + bool? deleted; @JSONField(name: "created_on_utc") - String createdOnUtc; + String? createdOnUtc; @JSONField(name: "updated_on_utc") - String updatedOnUtc; + String? updatedOnUtc; @JSONField(name: "product_type") - String productType; + String? productType; @JSONField(name: "parent_grouped_product_id") - int parentGroupedProductId; + int? parentGroupedProductId; @JSONField(name: "role_ids") - List roleIds; + List? roleIds; @JSONField(name: "discount_ids") - List discountIds; + List? discountIds; @JSONField(name: "store_ids") - List storeIds; + List? storeIds; + @JSONField(name: "store_names") + List? storeNames; @JSONField(name: "manufacturer_ids") - List manufacturerIds; - List reviews; - List images; - List attributes; - List specifications; + List? manufacturerIds; + List? reviews; + List? images; + List? attributes; + List? specifications; @JSONField(name: "associated_product_ids") - List associatedProductIds; - List tags; + List? associatedProductIds; + List? tags; @JSONField(name: "vendor_id") - int vendorId; + int? vendorId; @JSONField(name: "se_name") - String seName; + String? seName; String getName() { - if(localizedNames.length == 2){ - if(localizedNames.first.languageId == 2) - return localizedNames.first.localizedName ?? name; - - else if(localizedNames.first.languageId == 1) - return localizedNames.last.localizedName ?? name; + if (localizedNames!.length == 2) { + if (localizedNames?.first.languageId == 2) + return localizedNames!.first.localizedName ?? name.toString(); + else if (localizedNames!.first.languageId == 1) return localizedNames?.last.localizedName ?? name.toString(); } - return name; + return name.toString(); } } -class OfferProductsResponseModelLocalizedName with JsonConvert { +class OfferProductsResponseModelLocalizedName extends JsonConvert { @JSONField(name: "language_id") - int languageId; + int? languageId; @JSONField(name: "localized_name") - String localizedName; + String? localizedName; } -class OfferProductsResponseModelImage with JsonConvert { - int id; - int position; - String src; - String thumb; - String attachment; +class OfferProductsResponseModelImage extends JsonConvert { + int? id; + int? position; + String? src; + String? thumb; + String? attachment; } -class OfferProductsResponseModelSpecification with JsonConvert { - int id; +class OfferProductsResponseModelSpecification extends JsonConvert { + int? id; @JSONField(name: "display_order") - int displayOrder; + int? displayOrder; @JSONField(name: "default_value") - String defaultValue; + String? defaultValue; @JSONField(name: "default_valuen") - String defaultValuen; - String name; - String nameN; + String? defaultValuen; + String? name; + String? nameN; } diff --git a/lib/core/model/packages_offers/responses/offers_stores_response_model.dart b/lib/core/model/packages_offers/responses/offers_stores_response_model.dart new file mode 100644 index 00000000..b219aa56 --- /dev/null +++ b/lib/core/model/packages_offers/responses/offers_stores_response_model.dart @@ -0,0 +1,44 @@ +class OfferProjectsResponseModel { + OfferProjectsResponseModel({ + this.project,}); + + OfferProjectsResponseModel.fromJson(dynamic json) { + if (json['stores'] != null) { + project = []; + json['stores'].forEach((v) { + project!.add(OfferProject.fromJson(v)); + }); + } + } + List? project; + + Map toJson() { + final map = {}; + if (project != null) { + map['stores'] = project!.map((v) => v.toJson()).toList(); + } + return map; + } + +} + +class OfferProject { + OfferProject({ + this.name, + this.id,}); + + OfferProject.fromJson(dynamic json) { + name = json['name']; + id = json['id']; + } + String? name; + int? id; + + Map toJson() { + final map = {}; + map['name'] = name; + map['id'] = id; + return map; + } + +} \ No newline at end of file diff --git a/lib/core/model/packages_offers/responses/order_response_model.dart b/lib/core/model/packages_offers/responses/order_response_model.dart index ed53a765..aea27a86 100644 --- a/lib/core/model/packages_offers/responses/order_response_model.dart +++ b/lib/core/model/packages_offers/responses/order_response_model.dart @@ -1,35 +1,34 @@ - - import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCustomerResponseModel.dart'; + import 'PackagesCartItemsResponseModel.dart'; class PackagesOrderResponseModel { - String _customOrderNumber; - int _storeId; + String? _customOrderNumber; + int? _storeId; dynamic _pickUpInStore; - String _paymentMethodSystemName; - String _customerCurrencyCode; - double _currencyRate; - int _customerTaxDisplayTypeId; + String? _paymentMethodSystemName; + String? _customerCurrencyCode; + double? _currencyRate; + int? _customerTaxDisplayTypeId; dynamic _vatNumber; - double _orderSubtotalInclTax; - double _orderSubtotalExclTax; - double _orderSubTotalDiscountInclTax; - double _orderSubTotalDiscountExclTax; - double _orderShippingInclTax; - double _orderShippingExclTax; - double _paymentMethodAdditionalFeeInclTax; - double _paymentMethodAdditionalFeeExclTax; - String _taxRates; - double _orderTax; - double _orderDiscount; - double _orderTotal; - double _refundedAmount; + double? _orderSubtotalInclTax; + double? _orderSubtotalExclTax; + double? _orderSubTotalDiscountInclTax; + double? _orderSubTotalDiscountExclTax; + double? _orderShippingInclTax; + double? _orderShippingExclTax; + double? _paymentMethodAdditionalFeeInclTax; + double? _paymentMethodAdditionalFeeExclTax; + String? _taxRates; + double? _orderTax; + double? _orderDiscount; + double? _orderTotal; + double? _refundedAmount; dynamic _rewardPointsWereAdded; - String _checkoutAttributeDescription; - int _customerLanguageId; - int _affiliateId; - String _customerIp; + String? _checkoutAttributeDescription; + int? _customerLanguageId; + int? _affiliateId; + String? _customerIp; dynamic _authorizationTransactionId; dynamic _authorizationTransactionCode; dynamic _authorizationTransactionResult; @@ -39,147 +38,195 @@ class PackagesOrderResponseModel { dynamic _paidDateUtc; dynamic _shippingMethod; dynamic _shippingRateComputationMethodSystemName; - String _customValuesXml; + String? _customValuesXml; dynamic _paymentOption; - bool _deleted; - String _createdOnUtc; - PackagesCustomerResponseModel _customer; - int _customerId; + bool? _deleted; + String? _createdOnUtc; + PackagesCustomerResponseModel? _customer; + int? _customerId; dynamic _billingAddress; dynamic _shippingAddress; - List _orderItems; - String _orderStatus; - String _paymentStatus; - String _shippingStatus; - String _customerTaxDisplayType; - int _id; - - String get customOrderNumber => _customOrderNumber; - int get storeId => _storeId; + List? _orderItems; + String? _orderStatus; + String? _paymentStatus; + String? _shippingStatus; + String? _customerTaxDisplayType; + int? _id; + + String get customOrderNumber => _customOrderNumber!; + + int get storeId => _storeId!; + dynamic get pickUpInStore => _pickUpInStore; - String get paymentMethodSystemName => _paymentMethodSystemName; - String get customerCurrencyCode => _customerCurrencyCode; - double get currencyRate => _currencyRate; - int get customerTaxDisplayTypeId => _customerTaxDisplayTypeId; + + String get paymentMethodSystemName => _paymentMethodSystemName!; + + String get customerCurrencyCode => _customerCurrencyCode!; + + double get currencyRate => _currencyRate!; + + int get customerTaxDisplayTypeId => _customerTaxDisplayTypeId!; + dynamic get vatNumber => _vatNumber; - double get orderSubtotalInclTax => _orderSubtotalInclTax; - double get orderSubtotalExclTax => _orderSubtotalExclTax; - double get orderSubTotalDiscountInclTax => _orderSubTotalDiscountInclTax; - double get orderSubTotalDiscountExclTax => _orderSubTotalDiscountExclTax; - double get orderShippingInclTax => _orderShippingInclTax; - double get orderShippingExclTax => _orderShippingExclTax; - double get paymentMethodAdditionalFeeInclTax => _paymentMethodAdditionalFeeInclTax; - double get paymentMethodAdditionalFeeExclTax => _paymentMethodAdditionalFeeExclTax; - String get taxRates => _taxRates; - double get orderTax => _orderTax; - double get orderDiscount => _orderDiscount; - double get orderTotal => _orderTotal; - double get refundedAmount => _refundedAmount; + + double get orderSubtotalInclTax => _orderSubtotalInclTax!; + + double get orderSubtotalExclTax => _orderSubtotalExclTax!; + + double get orderSubTotalDiscountInclTax => _orderSubTotalDiscountInclTax!; + + double get orderSubTotalDiscountExclTax => _orderSubTotalDiscountExclTax!; + + double get orderShippingInclTax => _orderShippingInclTax!; + + double get orderShippingExclTax => _orderShippingExclTax!; + + double get paymentMethodAdditionalFeeInclTax => _paymentMethodAdditionalFeeInclTax!; + + double get paymentMethodAdditionalFeeExclTax => _paymentMethodAdditionalFeeExclTax!; + + String get taxRates => _taxRates!; + + double get orderTax => _orderTax!; + + double get orderDiscount => _orderDiscount!; + + double get orderTotal => _orderTotal!; + + double get refundedAmount => _refundedAmount!; + dynamic get rewardPointsWereAdded => _rewardPointsWereAdded; - String get checkoutAttributeDescription => _checkoutAttributeDescription; - int get customerLanguageId => _customerLanguageId; - int get affiliateId => _affiliateId; - String get customerIp => _customerIp; + + String get checkoutAttributeDescription => _checkoutAttributeDescription!; + + int get customerLanguageId => _customerLanguageId!; + + int get affiliateId => _affiliateId!; + + String get customerIp => _customerIp!; + dynamic get authorizationTransactionId => _authorizationTransactionId; + dynamic get authorizationTransactionCode => _authorizationTransactionCode; + dynamic get authorizationTransactionResult => _authorizationTransactionResult; + dynamic get captureTransactionId => _captureTransactionId; + dynamic get captureTransactionResult => _captureTransactionResult; + dynamic get subscriptionTransactionId => _subscriptionTransactionId; + dynamic get paidDateUtc => _paidDateUtc; + dynamic get shippingMethod => _shippingMethod; + dynamic get shippingRateComputationMethodSystemName => _shippingRateComputationMethodSystemName; - String get customValuesXml => _customValuesXml; + + String get customValuesXml => _customValuesXml!; + dynamic get paymentOption => _paymentOption; - bool get deleted => _deleted; - String get createdOnUtc => _createdOnUtc; - PackagesCustomerResponseModel get customer => _customer; - int get customerId => _customerId; + + bool get deleted => _deleted!; + + String get createdOnUtc => _createdOnUtc!; + + PackagesCustomerResponseModel get customer => _customer!; + + int get customerId => _customerId!; + dynamic get billingAddress => _billingAddress; + dynamic get shippingAddress => _shippingAddress; - List get orderItems => _orderItems; - String get orderStatus => _orderStatus; - String get paymentStatus => _paymentStatus; - String get shippingStatus => _shippingStatus; - String get customerTaxDisplayType => _customerTaxDisplayType; - int get id => _id; - - OrderResponseModel({ - String customOrderNumber, - int storeId, - dynamic pickUpInStore, - String paymentMethodSystemName, - String customerCurrencyCode, - double currencyRate, - int customerTaxDisplayTypeId, - dynamic vatNumber, - double orderSubtotalInclTax, - double orderSubtotalExclTax, - double orderSubTotalDiscountInclTax, - double orderSubTotalDiscountExclTax, - double orderShippingInclTax, - double orderShippingExclTax, - double paymentMethodAdditionalFeeInclTax, - double paymentMethodAdditionalFeeExclTax, - String taxRates, - double orderTax, - double orderDiscount, - double orderTotal, - double refundedAmount, - dynamic rewardPointsWereAdded, - String checkoutAttributeDescription, - int customerLanguageId, - int affiliateId, - String customerIp, - dynamic authorizationTransactionId, - dynamic authorizationTransactionCode, - dynamic authorizationTransactionResult, - dynamic captureTransactionId, - dynamic captureTransactionResult, - dynamic subscriptionTransactionId, - dynamic paidDateUtc, - dynamic shippingMethod, - dynamic shippingRateComputationMethodSystemName, - String customValuesXml, - dynamic paymentOption, - bool deleted, - String createdOnUtc, - PackagesCustomerResponseModel customer, - int customerId, - dynamic billingAddress, - dynamic shippingAddress, - List orderItems, - String orderStatus, - String paymentStatus, - String shippingStatus, - String customerTaxDisplayType, - int id}){ - _customOrderNumber = customOrderNumber; - _storeId = storeId; + + List get orderItems => _orderItems!; + + String get orderStatus => _orderStatus!; + + String get paymentStatus => _paymentStatus!; + + String get shippingStatus => _shippingStatus!; + + String get customerTaxDisplayType => _customerTaxDisplayType!; + + int get id => _id!; + + OrderResponseModel( + {String? customOrderNumber, + int? storeId, + dynamic pickUpInStore, + String? paymentMethodSystemName, + String? customerCurrencyCode, + double? currencyRate, + int? customerTaxDisplayTypeId, + dynamic vatNumber, + double? orderSubtotalInclTax, + double? orderSubtotalExclTax, + double? orderSubTotalDiscountInclTax, + double? orderSubTotalDiscountExclTax, + double? orderShippingInclTax, + double? orderShippingExclTax, + double? paymentMethodAdditionalFeeInclTax, + double? paymentMethodAdditionalFeeExclTax, + String? taxRates, + double? orderTax, + double? orderDiscount, + double? orderTotal, + double? refundedAmount, + dynamic rewardPointsWereAdded, + String? checkoutAttributeDescription, + int? customerLanguageId, + int? affiliateId, + String? customerIp, + dynamic authorizationTransactionId, + dynamic authorizationTransactionCode, + dynamic authorizationTransactionResult, + dynamic captureTransactionId, + dynamic captureTransactionResult, + dynamic subscriptionTransactionId, + dynamic paidDateUtc, + dynamic shippingMethod, + dynamic shippingRateComputationMethodSystemName, + String? customValuesXml, + dynamic paymentOption, + bool? deleted, + String? createdOnUtc, + PackagesCustomerResponseModel? customer, + int? customerId, + dynamic billingAddress, + dynamic shippingAddress, + List? orderItems, + String? orderStatus, + String? paymentStatus, + String? shippingStatus, + String? customerTaxDisplayType, + int? id}) { + _customOrderNumber = customOrderNumber!; + _storeId = storeId!; _pickUpInStore = pickUpInStore; - _paymentMethodSystemName = paymentMethodSystemName; - _customerCurrencyCode = customerCurrencyCode; - _currencyRate = currencyRate; - _customerTaxDisplayTypeId = customerTaxDisplayTypeId; + _paymentMethodSystemName = paymentMethodSystemName!; + _customerCurrencyCode = customerCurrencyCode!; + _currencyRate = currencyRate!; + _customerTaxDisplayTypeId = customerTaxDisplayTypeId!; _vatNumber = vatNumber; - _orderSubtotalInclTax = orderSubtotalInclTax; - _orderSubtotalExclTax = orderSubtotalExclTax; - _orderSubTotalDiscountInclTax = orderSubTotalDiscountInclTax; - _orderSubTotalDiscountExclTax = orderSubTotalDiscountExclTax; - _orderShippingInclTax = orderShippingInclTax; - _orderShippingExclTax = orderShippingExclTax; - _paymentMethodAdditionalFeeInclTax = paymentMethodAdditionalFeeInclTax; - _paymentMethodAdditionalFeeExclTax = paymentMethodAdditionalFeeExclTax; - _taxRates = taxRates; - _orderTax = orderTax; - _orderDiscount = orderDiscount; - _orderTotal = orderTotal; - _refundedAmount = refundedAmount; + _orderSubtotalInclTax = orderSubtotalInclTax!; + _orderSubtotalExclTax = orderSubtotalExclTax!; + _orderSubTotalDiscountInclTax = orderSubTotalDiscountInclTax!; + _orderSubTotalDiscountExclTax = orderSubTotalDiscountExclTax!; + _orderShippingInclTax = orderShippingInclTax!; + _orderShippingExclTax = orderShippingExclTax!; + _paymentMethodAdditionalFeeInclTax = paymentMethodAdditionalFeeInclTax!; + _paymentMethodAdditionalFeeExclTax = paymentMethodAdditionalFeeExclTax!; + _taxRates = taxRates!; + _orderTax = orderTax!; + _orderDiscount = orderDiscount!; + _orderTotal = orderTotal!; + _refundedAmount = refundedAmount!; _rewardPointsWereAdded = rewardPointsWereAdded; - _checkoutAttributeDescription = checkoutAttributeDescription; - _customerLanguageId = customerLanguageId; - _affiliateId = affiliateId; - _customerIp = customerIp; + _checkoutAttributeDescription = checkoutAttributeDescription!; + _customerLanguageId = customerLanguageId!; + _affiliateId = affiliateId!; + _customerIp = customerIp!; _authorizationTransactionId = authorizationTransactionId; _authorizationTransactionCode = authorizationTransactionCode; _authorizationTransactionResult = authorizationTransactionResult; @@ -189,21 +236,21 @@ class PackagesOrderResponseModel { _paidDateUtc = paidDateUtc; _shippingMethod = shippingMethod; _shippingRateComputationMethodSystemName = shippingRateComputationMethodSystemName; - _customValuesXml = customValuesXml; + _customValuesXml = customValuesXml!; _paymentOption = paymentOption; - _deleted = deleted; - _createdOnUtc = createdOnUtc; - _customer = customer; - _customerId = customerId; + _deleted = deleted!; + _createdOnUtc = createdOnUtc!; + _customer = customer!; + _customerId = customerId!; _billingAddress = billingAddress; _shippingAddress = shippingAddress; - _orderItems = orderItems; - _orderStatus = orderStatus; - _paymentStatus = paymentStatus; - _shippingStatus = shippingStatus; - _customerTaxDisplayType = customerTaxDisplayType; - _id = id; -} + _orderItems = orderItems!; + _orderStatus = orderStatus!; + _paymentStatus = paymentStatus!; + _shippingStatus = shippingStatus!; + _customerTaxDisplayType = customerTaxDisplayType!; + _id = id!; + } PackagesOrderResponseModel.fromJson(dynamic json) { _customOrderNumber = json["custom_order_number"]; @@ -212,7 +259,7 @@ class PackagesOrderResponseModel { _paymentMethodSystemName = json["payment_method_system_name"]; _customerCurrencyCode = json["customer_currency_code"]; _currencyRate = json["currency_rate"]; - _customerTaxDisplayTypeId = json["customer_tax_display_type_id"]; + _customerTaxDisplayTypeId = json["customer_tax_display_type_id"]!; _vatNumber = json["vat_number"]; _orderSubtotalInclTax = json["order_subtotal_incl_tax"]; _orderSubtotalExclTax = json["order_subtotal_excl_tax"]; @@ -245,15 +292,15 @@ class PackagesOrderResponseModel { _paymentOption = json["payment_option"]; _deleted = json["deleted"]; _createdOnUtc = json["created_on_utc"]; - _customer = json["customer"] != null ? PackagesCustomerResponseModel.fromJson(json["customer"]) : null; + _customer = (json["customer"] != null ? PackagesCustomerResponseModel.fromJson(json["customer"]) : null)!; _customerId = json["customer_id"]; _billingAddress = json["billing_address"]; _shippingAddress = json["shipping_address"]; if (json["order_items"] != null) { _orderItems = []; json["order_items"].forEach((v) { - _orderItems.add(PackagesCartItemsResponseModel.fromJson(v)); - }); + _orderItems!.add(PackagesCartItemsResponseModel.fromJson(v)); + })!; } _orderStatus = json["order_status"]; _paymentStatus = json["payment_status"]; @@ -304,13 +351,13 @@ class PackagesOrderResponseModel { map["deleted"] = _deleted; map["created_on_utc"] = _createdOnUtc; if (_customer != null) { - map["customer"] = _customer.toJson(); + map["customer"] = _customer!.toJson(); } map["customer_id"] = _customerId; map["billing_address"] = _billingAddress; map["shipping_address"] = _shippingAddress; if (_orderItems != null) { - map["order_items"] = _orderItems.map((v) => v.toJson()).toList(); + map["order_items"] = _orderItems!.map((v) => v.toJson()).toList(); } map["order_status"] = _orderStatus; map["payment_status"] = _paymentStatus; @@ -319,5 +366,4 @@ class PackagesOrderResponseModel { map["id"] = _id; return map; } - } 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..dd82287f --- /dev/null +++ b/lib/core/model/packages_offers/responses/tamara_payment_option.dart @@ -0,0 +1,36 @@ +class TamaraPaymentOption { + String? name; + double? minLimit; + double? maxLimit; + int? id; + bool? enable = true; + + 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/model/pharmacies/Addresses.dart b/lib/core/model/pharmacies/Addresses.dart index b00b1a17..791ffc7f 100644 --- a/lib/core/model/pharmacies/Addresses.dart +++ b/lib/core/model/pharmacies/Addresses.dart @@ -1,23 +1,23 @@ class Addresses { - String id; - String firstName; - String lastName; - String email; - String company; - int countryId; - String country; - String stateProvinceId; - String city; - String address1; - String address2; - String zipPostalCode; - String phoneNumber; - String faxNumber; - String customerAttributes; - String createdOnUtc; - String province; - String latLong; - bool isChecked; + String? id; + String? firstName; + String? lastName; + String? email; + String? company; + int? countryId; + String? country; + String? stateProvinceId; + String? city; + String? address1; + String? address2; + String? zipPostalCode; + String? phoneNumber; + String? faxNumber; + String? customerAttributes; + String? createdOnUtc; + String? province; + String? latLong; + bool? isChecked; Addresses( {this.id, @@ -86,4 +86,9 @@ class Addresses { return data; } + @override + String toString() { + return "${address1 ?? ""} ${address2 ?? ""}"; + } + } diff --git a/lib/core/model/pharmacies/BillingAddress.dart b/lib/core/model/pharmacies/BillingAddress.dart index 418b28a7..faa56a45 100644 --- a/lib/core/model/pharmacies/BillingAddress.dart +++ b/lib/core/model/pharmacies/BillingAddress.dart @@ -1,24 +1,24 @@ import 'package:google_maps_flutter/google_maps_flutter.dart'; class BillingAddress { - String id; - String firstName; - String lastName; - String email; - String company; - int countryId; - String country; - String stateProvinceId; - String city; - String address1; - String address2; - String zipPostalCode; - String phoneNumber; - String faxNumber; - String customerAttributes; - String createdOnUtc; - String province; - String latLong; + String? id; + String? firstName; + String? lastName; + String? email; + String? company; + int? countryId; + String? country; + String? stateProvinceId; + String? city; + String? address1; + String? address2; + String? zipPostalCode; + String? phoneNumber; + String? faxNumber; + String? customerAttributes; + String? createdOnUtc; + String? province; + String? latLong; BillingAddress( {this.id, @@ -85,17 +85,18 @@ class BillingAddress { } LatLng getLocation(){ - if(latLong.contains(',')){ - var parts = latLong.trim().split(','); + if(latLong!.contains(',')){ + var parts = latLong!.trim().split(','); if(parts.length == 2){ var lat = double.tryParse(parts.first); var lng = double.tryParse(parts.last); if(lat != null || lng != null) { - var location = LatLng(lat, lng); + var location = LatLng(lat!, lng!); return location; } } } - return null; + return LatLng(double.nan, double.nan); + //Changed By Aamir } } diff --git a/lib/core/model/pharmacies/Country.dart b/lib/core/model/pharmacies/Country.dart index 77f519d3..26225d71 100644 --- a/lib/core/model/pharmacies/Country.dart +++ b/lib/core/model/pharmacies/Country.dart @@ -1,9 +1,9 @@ class CountryData { - int id; - String name; - String namen; - String twoLetterIsoCode; - String threeLetterIsoCode; + int? id; + String? name; + String? namen; + String? twoLetterIsoCode; + String? threeLetterIsoCode; CountryData( {this.id, diff --git a/lib/core/model/pharmacies/Customer.dart b/lib/core/model/pharmacies/Customer.dart index 9042930e..5d3e49c3 100644 --- a/lib/core/model/pharmacies/Customer.dart +++ b/lib/core/model/pharmacies/Customer.dart @@ -2,37 +2,37 @@ import 'package:diplomaticquarterapp/core/model/pharmacies/Addresses.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/BillingAddress.dart'; class Customer { - BillingAddress billingAddress; - BillingAddress shippingAddress; - List addresses; - String fileNumber; - String iqamaNumber; - int isOutSa; - int patientType; - String gender; - String birthDate; - String phone; - String countryCode; - String yahalaAccountno; - String id; - String username; - String email; - String firstName; - String lastName; - String languageId; - String adminComment; - bool isTaxExempt; - bool hasShoppingCartItems; - bool active; - bool deleted; - bool isSystemAccount; - String systemName; - String lastIpAddress; - String createdOnUtc; - String lastLoginDateUtc; - String lastActivityDateUtc; - int registeredInStoreId; - List roleIds; + BillingAddress? billingAddress; + BillingAddress? shippingAddress; + List? addresses; + String? fileNumber; + String? iqamaNumber; + int? isOutSa; + int? patientType; + String? gender; + String? birthDate; + String? phone; + String? countryCode; + String? yahalaAccountno; + String? id; + String? username; + String? email; + String? firstName; + String? lastName; + String? languageId; + String? adminComment; + bool? isTaxExempt; + bool? hasShoppingCartItems; + bool? active; + bool? deleted; + bool? isSystemAccount; + String? systemName; + String? lastIpAddress; + String? createdOnUtc; + String? lastLoginDateUtc; + String? lastActivityDateUtc; + int? registeredInStoreId; + List? roleIds; Customer( {this.billingAddress, @@ -75,9 +75,9 @@ class Customer { ? new BillingAddress.fromJson(json['shipping_address']) : null; if (json['addresses'] != null) { - addresses = new List(); + addresses = []; json['addresses'].forEach((v) { - addresses.add(new Addresses.fromJson(v)); + addresses!.add(new Addresses.fromJson(v)); }); } fileNumber = json['file_number']; @@ -108,9 +108,9 @@ class Customer { lastActivityDateUtc = json['last_activity_date_utc']; registeredInStoreId = json['registered_in_store_id']; if (json['role_ids'] != null) { - roleIds = new List(); + roleIds = []; json['role_ids'].forEach((v) { - roleIds.add(v); + roleIds!.add(v); }); } } @@ -118,13 +118,13 @@ class Customer { Map toJson() { final Map data = new Map(); if (this.billingAddress != null) { - data['billing_address'] = this.billingAddress.toJson(); + data['billing_address'] = this.billingAddress!.toJson(); } if (this.shippingAddress != null) { - data['shipping_address'] = this.shippingAddress.toJson(); + data['shipping_address'] = this.shippingAddress!.toJson(); } if (this.addresses != null) { - data['addresses'] = this.addresses.map((v) => v.toJson()).toList(); + data['addresses'] = this.addresses!.map((v) => v.toJson()).toList(); } data['file_number'] = this.fileNumber; data['iqama_number'] = this.iqamaNumber; diff --git a/lib/core/model/pharmacies/LacumAccountInformation.dart b/lib/core/model/pharmacies/LacumAccountInformation.dart index 4f1d0455..c78b1563 100644 --- a/lib/core/model/pharmacies/LacumAccountInformation.dart +++ b/lib/core/model/pharmacies/LacumAccountInformation.dart @@ -2,414 +2,414 @@ import 'LakumInquiryInformationObjVersion.dart'; class LacumAccountInformation { - String date; - int languageID; - int serviceName; - String time; - String androidLink; - String authenticationTokenID; - String data; - bool dataw; - int dietType; - String errorCode; - String errorEndUserMessage; - String errorEndUserMessageN; - String errorMessage; - int errorType; - int foodCategory; - String iOSLink; - bool isAuthenticated; - int mealOrderStatus; - int mealType; - int messageStatus; - int numberOfResultRecords; - String patientBlodType; - String successMsg; - String successMsgN; - int accountStatus; - String activeArchiveObject; - int activeMedicationCount; - String allMedicationTakenDuringAdmissionList; - int appointmentNo; - String arePatientsOnlineList; - String balanceAmount; - String bloodGroupList; - int cVIUnreadCount; - String checkUserHasAccount; - int complaintNo; - String dischargeList; - int episodeID; - String finalRadiologyList; - String fullName; - String geoFPointsList; - String geoGetPateintInfo; - String getAllDoctorsByProjectAndClinicList; - String getAppointmentNumbersForDoctorList; - String getCheckUpItemsList; - String getCosmeticConferenceForTodayList; - String getDoctorERClinicResult; - String getInvoiceApprovalList; - String getNearestProjectList; - String getPatientAdmissionOrAppoinmentNoList; - String getPatientBloodType; - String getPatientInsuranceCardStatusStatisticsList; - String getSurveyList; - String getTotalRegisteredPatientList; - String getUserDetailsList; - String getCustomerPointInfo; - String hISApprovalList; - String hISInpAdmissionList; - String hISProgNoteAssesmentModelList; - String hMGGetAllOffersList; - bool hasApproval; - bool hasConsultation; - bool hasDental; - bool hasLab; - bool hasPharmacy; - bool hasRad; - String hmgSMSGetByProjectIDAndPatientIDList; - int hoursLeft; - String iNPMGetAllAdmissionList; - String iNPMGetPatientInfoForSickLeaveReportList; - String iNPMHISPatientMedicalStatusUnreadCount; - String iNPMLABGetPatientLabOrdersResultsList; - String iNPMLABGetPatientLabResultsList; - String iNPMLABGetPatientRADReportList; - String iNPMLABGetPatientRadResultsList; - String iNPMRadGetPatientRadOrdersCVIList; - String iNPMRadGetPatientRadOrdersList; - String iNPMRadGetRadMedicalRecordsList; - String iNPGetPrescriptionDischargesList; - String iNPGetPrescriptionReportList; - String identificationNo; - bool isHomeMedicineDeliverySupported; - int isInsertedOrUpdated; - bool isMainAcoountEqualPatienID; - bool isPatientAlreadyAgreed; - bool isPatientCallBackBlackList; - bool isPatientHaveFingerPrint; - bool isPatientOnline; - bool isPatientTokenRemoved; - bool isPaused; - bool isProjectWorkingHours; - String isStoreRateAllowed; - String isStoreRateInserted; - String isStoreRateUpdated; - int labRadUpdatedToRead; - int labReportUnreadNo; - String lakumInquiryInformationObj; - LakumInquiryInformationObjVersion lakumInquiryInformationObjVersion; - String lakumResponseList; - String laserGetBodyPartsByCategoryList; - String laserGetCategoriesList; - String list; - int listCount; - int listCountDeliverd; - int listCountUnDeliverd; - String listDeviceInfo; - String listFamilyAppointments; - String listLabResultsByAppNo; - String listLakumInquiryInformationObj; - String listOpinionGetAllPeriod; - String listOpinionGetAllServices; - String listOpinionGetIsAgreeValue; - String listOpinionGetOpinionLogin; - String listOpinionGetRequestedSerives; - String listOpinionGetShareServicesDetails; - String listOpinionUserTerms; - String listPLO; - String listPLR; - String listPLSR; - String listPRM; - String listPatientFamilyFiles; - String listPatientFileInfo; - String listRAD; - String listRADAPI; - String listActiveGetPrescriptionReportByPatientID; - String listAppointmentsForDentalClinic; - String listBabyInfoResult; - String listCheckInsuranceCoverage; - String listCompanyClass; - String listConsentMedicalReport; - String listDentalAppointments; - String listDeviceTokenIDByAppointmentNo; - String listDischargeDiagnosis; - String listDischargeMedicine; - String listDischargeSummary; - String listDoctorResponse; - String listDoneVaccines; - String listEReferralResult; - String listEReferrals; - String listGetAllPatientsLiveCareAdmin; - String listGetDataForExcel; - String listGetMainCountID; - String listGetPrescriptionReportByPatientID; - String listGetSickLeave; - String listHISInvoice; - String listHISInvoiceProcedures; - String listInpatientInvoices; - String listInsuranceCheckList; - String listInsuranceCompanies; - String listInsuranceCompaniesGroup; - String listInsuranceUpdateDetails; - String listInvoiceApprovalProcedureInfo; - String listIsLastSatisfactionSurveyReviewedModel; - String listLabOrderDetailsModel; - String listMedicalReport; - String listMedicalReportApprovals; - String listMedicalReportStatus; - String listMonthBloodPressureResult; - String listMonthBloodPressureResultAverage; - String listMonthDiabtecPatientResult; - String listMonthDiabtectResultAverage; - String listMonthWeightMeasurementResult; - String listMonthWeightMeasurementResultAverage; - String listOnlinePrescriptionResult; - String listOutPatientInvoices; - String listPHRInvoice; - String listPHRInvoiceItems; - String listPHRPaymentMethods; - String listPateintDetails; - String listPateintInformation; - String listPatientAdmissionInfo; - String listPatientAdvanceBalanceAmount; - String listPatientCallBackLogs; - String listPatientCallBackToUpdateFromICServer; - String listPatientCount; - String listPatientDashboard; - String listPatientERGetAdminClinicsModel; - String listPatientERGetAdminProjectsModel; - String listPatientERGetAllClinicsModel; - String listPatientHISInvoices; - String listPatientICProjects; - String listPatientICProjectsByID; - String listPatientICProjectsTimings; - String listPatientIDByUID; - String listPatientIDForSurveyResult; - String listPatientInfo; - String listPatientInfoForDDScreen; - String listPatientInfoForSickleaveReport; - String listPatientInsuranceCard; - String listPatientInsuranceCardHistory; - String listPatientInsuranceDetails; - String listPatientPHRInvoices; - String listPatientServicePoint; - String listPatientStatusCount; - String listPatientChatRequestMapModel; - String listPatientChatRequestModel; - String listPatientChatRequestVCModel; - String listPaymentMethods; - String listPointServices; - String listPregnancyStagesInfo; - String listProjectAvgERWaitingTime; - String listProjectAvgERWaitingTimeHourly; - String listRadMedicalRecords; - String listRadMedicalRecordsAPI; - String listRadMedicalRecordsCVI; - String listRadMedicalRecordsCVIAPI; - String listRadMedicalRecordsResults; - String listSickLeave; - String listTransaction; - String listVideoConferenceSessions; - String listWeekBloodPressureResult; - String listWeekBloodPressureResultAverage; - String listWeekDiabtecPatientResult; - String listWeekDiabtectResultAverage; - String listWeekWeightMeasurementResult; - String listWeekWeightMeasurementResultAverage; - String listYearBloodPressureResult; - String listYearBloodPressureResultAverage; - String listYearDiabtecPatientResult; - String listYearDiabtecResultAverage; - String listYearWeightMeasurementResult; - String listYearWeightMeasurementResultAverage; - String listEInvoiceForDental; - String listEInvoiceForOnlineCheckIn; - String medGetActivitiesTransactionsStsList; - String medGetAvgMonthTransactionsStsList; - String medGetAvgWeekTransactionsStsList; - String medGetCategoriesList; - String medGetMonthActivitiesTransactionsStsList; - String medGetMonthStepsTransactionsStsList; - String medGetMonthTransactionsStsList; - String medGetPatientLastRecordList; - String medGetSubCategoriesList; - String medGetTransactionsAndActTransactionsResult; - String medGetTransactionsList; - String medGetWeekActivitiesTransactionsStsList; - String medGetWeekStepsTransactionsStsList; - String medGetWeekTransactionsStsList; - String medGetYearActivitiesTransactionsStsList; - String medGetYearSleepTransactionsStsList; - String medGetYearStepsTransactionsStsList; - String medGetYearTransactionsStsList; - String medInsertTransactionsOutputsList; - String medicalRecordImages; - int medicalReportToRead; - int medicalReportUnreadNo; - bool missingIDCardAttachment; - bool missingInsuranceCardAttachment; - bool missingMedicalReportAttachment; - bool missingOtherRelationship; - bool missingPatientContactNo; - bool missingPatientId; - bool missingPatientIdentityNumber; - bool missingPatientName; - bool missingReferralContactNo; - bool missingReferralRelationship; - bool missingReferralRequesterName; - String mobileNumber; - int nationalityNumber; - String onlineCheckInAppointments; - String opinionUserAgreementContent; - bool orderInsert; - String pateintInfoForUpdateList; - String pateintUpatedList; - String patientBirthdayCertificate; - String patientERCMCRequestSummaryByProject; - String patientERCMCRequestWithTotal; - String patientERCMCGetAllServicesList; - String patientERCMCGetTransactionsForOrderList; - String patientERCoordinates; - String patientERCountOrderList; - String patientERCountsForApprovalOffice; - String patientERDeleteOldCurrentDoctorsOutputsList; - String patientERDeliveryGetAllDeliverdOrderList; - String patientERDeliveryGetAllOrderList; - bool patientERDeliveryIsOrderInserted; - bool patientERDeliveryIsOrderUpdated; - bool patientERDeliveryIsPausedChanged; - String patientERDeliveryNextOrder; - int patientERDeliveryOrderInsert; - int patientERDeliveryUpdateOrderStatus; - bool patientERDriverUpdate; - String patientERExacartCheckIsDispenseAccpetableList; - String patientERExacartGetDispenseQuantitiesByOrderIDList; - String patientERExacartGetOrderDetailsByePharmacyOrderNoList; - String patientERExacartGetOrderDetailsList; - String patientERExacartGetTotalDispenseQuantitiesByPresNoList; - bool patientERExacartIsDispenseAdded; - String patientERExacartIsDispenseAddedList; - bool patientERExacartIsOrderCompleted; - String patientERGetAdminByProjectAndRoleList; - String patientERGetAdminProjectsList; - String patientERGetAllDriversList; - String patientERGetAllNeedAproveStatusList; - String patientERGetAllPresOrdersStatusList; - String patientERGetAllProjectsList; - String patientERGetArchiveInformationList; - String patientERGetAskDoctorTotalByDateFilterList; - String patientERGetBookScheduleConfigsList; - String patientERGetClinicAndTimeAndEpisodeForAppointmentList; - String patientERGetClinicAndTimeForDischargeList; - String patientERGetDashboardDataforApporvalSectionForAdminList; - String patientERGetDashboardDataforApporvalSectionList; - String patientERGetDashboardDataforHHCSectionForAdminList; - String patientERGetDashboardDataforHHCSectionList; - String patientERGetDashboardDataforPrescriptionSectionForAdminList; - String patientERGetDashboardDataforPrescriptionSectionList; - String patientERGetDoctorDashboardDataModelList; - String patientERGetDriverLocationList; - String patientERGetInsuranceCardRequestByDateFilterList; - String patientERGetLiveCareSummaryBookedAppoinmentStatusList; - String patientERGetLiveCareSummaryCovidList; - String patientERGetLiveCareSummaryForCMCList; - String patientERGetLiveCareSummaryForHHCList; - String patientERGetLiveCareSummaryForHomeDeliveryList; - String patientERGetLiveCareSummaryForInsuranceCardRequestList; - String patientERGetLiveCareSummaryForNewFilesList; - String patientERGetLiveCareSummaryForOnlinePaymetRequestList; - String patientERGetLiveCareSummaryForOnlinePharmacyOrdersList; - String patientERGetLiveCareSummaryForTrasnportationList; - String patientERGetLiveCareSummaryLiveCareCountsList; - String patientERGetMedicalRequestTotalByDateFilterList; - String patientERGetNearestPendingOrdersList; - String patientERGetNeedAproveHistoryForOrderList; - String patientERGetNeedAprovePendingOrdersList; - String patientERGetNeedAproveStatusStatisticsList; - String patientERGetPatientAllPresOrdersList; - String patientERGetPendingPatientsCountList; - String patientERGetPresOrdersHistoryForAdminList; - String patientERGetPresOrdersHistoryForOrderList; - String patientERGetPresOrdersStatusStatisticsList; - String patientERHHCRequest; - String patientERHHCRequestSummaryByProject; - String patientERHHCRequestWithTotal; - String patientERHHCGetAllServicesList; - String patientERHHCGetTransactionsForOrderList; - String patientERHomeDeliveryCounts; - bool patientERInsertDriver; - String patientERInsertNewCurrentDoctorsOutputsList; - String patientERInsuranceStatusCountList; - bool patientERIsNearestProjectUpdated; - bool patientERIsNeedAproveReturnedToQueue; - bool patientERIsNeedAproveUpdated; - bool patientERIsOrderClientRequestUpdated; - bool patientERIsOrderReturnedToQueue; - bool patientERIsPresOrderInserted; - bool patientERIsPresOrderUpdated; - bool patientERIsProjectUpdated; - String patientERNotCompletedDetails; - String patientERPatientsCountByCallStatus; - String patientERPeakHourCounts; - String patientERPresOrderInfo; - String patientERPrescriptionCounts; - String patientERProjectsContribution; - String patientERRRTGetAllQuestionsList; - String patientERRRTGetAllTransportationMethodList; - String patientERRRTGetPickUpRequestByPresOrderIDList; - String patientERRealRRTGetAllServicesList; - String patientERRealRRTGetOrderDetailsList; - String patientERRealRRTGetTransactionsForOrderList; - bool patientERRealRRTIsTransInserted; - String patientERRequestList; - String patientERTransportationRequestWithTotal; - String patientERealRRTGetServicePriceList; - String patientInfoByAdmissionNoList; - String patientMonitorGetPatientHeartRate; - int patientNotServedCounts; - String patientPrescriptionList; - String patientAllergies; - String patientCheckAppointmentValidationList; - String patientLoginTokenList; - String patientQRLoginInfoList; - String patientSELECTDeviceIMEIbyIMEIList; - String pharmList; - String prefLang; - int radReportUnreadNo; - String radGetPatientRadOrdersForDentalList; - int referralNumber; - String reminderConfigurations; - String requestNo; - int rowCount; - String servicePrivilegeList; - String shareFamilyFileObj; - String status; - int successCode; - String surveyRate; - String symptomCheckerConditionList; - String symptomCheckerGetAllDefaultQuestionsList; - String symptomCheckerGetBodyPartSymptomsList; - String symptomCheckerGetBodyPartsByCodeList; - String symptomCheckerGetBodyPartsList; - String symptomCheckerJsonResponseInString; - int timerTime; - int totalAdvanceBalanceAmount; - int totalPatientsCount; - int totalPendingApprovalCount; - int totalUnUsedCount; - int transactionNo; - int unReadCounts; - bool updateStatus; - String userAgreementContent; - int yahalaAccountNo; - bool check24HourComplaint; - String currency; - String message; - int patientID; - int returnValue; - String returnValueStr; - int statusCode; + String? date; + int? languageID; + int? serviceName; + String? time; + String? androidLink; + String? authenticationTokenID; + String? data; + bool? dataw; + int? dietType; + String? errorCode; + String? errorEndUserMessage; + String? errorEndUserMessageN; + String? errorMessage; + int? errorType; + int? foodCategory; + String? iOSLink; + bool? isAuthenticated; + int? mealOrderStatus; + int? mealType; + int? messageStatus; + int? numberOfResultRecords; + String? patientBlodType; + String? successMsg; + String? successMsgN; + int? accountStatus; + String? activeArchiveObject; + int? activeMedicationCount; + String? allMedicationTakenDuringAdmissionList; + int? appointmentNo; + String? arePatientsOnlineList; + String? balanceAmount; + String? bloodGroupList; + int? cVIUnreadCount; + String? checkUserHasAccount; + int? complaintNo; + String? dischargeList; + int? episodeID; + String? finalRadiologyList; + String? fullName; + String? geoFPointsList; + String? geoGetPateintInfo; + String? getAllDoctorsByProjectAndClinicList; + String? getAppointmentNumbersForDoctorList; + String? getCheckUpItemsList; + String? getCosmeticConferenceForTodayList; + String? getDoctorERClinicResult; + String? getInvoiceApprovalList; + String? getNearestProjectList; + String? getPatientAdmissionOrAppoinmentNoList; + String? getPatientBloodType; + String? getPatientInsuranceCardStatusStatisticsList; + String? getSurveyList; + String? getTotalRegisteredPatientList; + String? getUserDetailsList; + String? getCustomerPointInfo; + String? hISApprovalList; + String? hISInpAdmissionList; + String? hISProgNoteAssesmentModelList; + String? hMGGetAllOffersList; + bool? hasApproval; + bool? hasConsultation; + bool? hasDental; + bool? hasLab; + bool? hasPharmacy; + bool? hasRad; + String? hmgSMSGetByProjectIDAndPatientIDList; + int? hoursLeft; + String? iNPMGetAllAdmissionList; + String? iNPMGetPatientInfoForSickLeaveReportList; + String? iNPMHISPatientMedicalStatusUnreadCount; + String? iNPMLABGetPatientLabOrdersResultsList; + String? iNPMLABGetPatientLabResultsList; + String? iNPMLABGetPatientRADReportList; + String? iNPMLABGetPatientRadResultsList; + String? iNPMRadGetPatientRadOrdersCVIList; + String? iNPMRadGetPatientRadOrdersList; + String? iNPMRadGetRadMedicalRecordsList; + String? iNPGetPrescriptionDischargesList; + String? iNPGetPrescriptionReportList; + String? identificationNo; + bool? isHomeMedicineDeliverySupported; + int? isInsertedOrUpdated; + bool? isMainAcoountEqualPatienID; + bool? isPatientAlreadyAgreed; + bool? isPatientCallBackBlackList; + bool? isPatientHaveFingerPrint; + bool? isPatientOnline; + bool? isPatientTokenRemoved; + bool? isPaused; + bool? isProjectWorkingHours; + String? isStoreRateAllowed; + String? isStoreRateInserted; + String? isStoreRateUpdated; + int? labRadUpdatedToRead; + int? labReportUnreadNo; + String? lakumInquiryInformationObj; + LakumInquiryInformationObjVersion? lakumInquiryInformationObjVersion; + String? lakumResponseList; + String? laserGetBodyPartsByCategoryList; + String? laserGetCategoriesList; + String? list; + int? listCount; + int? listCountDeliverd; + int? listCountUnDeliverd; + String? listDeviceInfo; + String? listFamilyAppointments; + String? listLabResultsByAppNo; + String? listLakumInquiryInformationObj; + String? listOpinionGetAllPeriod; + String? listOpinionGetAllServices; + String? listOpinionGetIsAgreeValue; + String? listOpinionGetOpinionLogin; + String? listOpinionGetRequestedSerives; + String? listOpinionGetShareServicesDetails; + String? listOpinionUserTerms; + String? listPLO; + String? listPLR; + String? listPLSR; + String? listPRM; + String? listPatientFamilyFiles; + String? listPatientFileInfo; + String? listRAD; + String? listRADAPI; + String? listActiveGetPrescriptionReportByPatientID; + String? listAppointmentsForDentalClinic; + String? listBabyInfoResult; + String? listCheckInsuranceCoverage; + String? listCompanyClass; + String? listConsentMedicalReport; + String? listDentalAppointments; + String? listDeviceTokenIDByAppointmentNo; + String? listDischargeDiagnosis; + String? listDischargeMedicine; + String? listDischargeSummary; + String? listDoctorResponse; + String? listDoneVaccines; + String? listEReferralResult; + String? listEReferrals; + String? listGetAllPatientsLiveCareAdmin; + String? listGetDataForExcel; + String? listGetMainCountID; + String? listGetPrescriptionReportByPatientID; + String? listGetSickLeave; + String? listHISInvoice; + String? listHISInvoiceProcedures; + String? listInpatientInvoices; + String? listInsuranceCheckList; + String? listInsuranceCompanies; + String? listInsuranceCompaniesGroup; + String? listInsuranceUpdateDetails; + String? listInvoiceApprovalProcedureInfo; + String? listIsLastSatisfactionSurveyReviewedModel; + String? listLabOrderDetailsModel; + String? listMedicalReport; + String? listMedicalReportApprovals; + String? listMedicalReportStatus; + String? listMonthBloodPressureResult; + String? listMonthBloodPressureResultAverage; + String? listMonthDiabtecPatientResult; + String? listMonthDiabtectResultAverage; + String? listMonthWeightMeasurementResult; + String? listMonthWeightMeasurementResultAverage; + String? listOnlinePrescriptionResult; + String? listOutPatientInvoices; + String? listPHRInvoice; + String? listPHRInvoiceItems; + String? listPHRPaymentMethods; + String? listPateintDetails; + String? listPateintInformation; + String? listPatientAdmissionInfo; + String? listPatientAdvanceBalanceAmount; + String? listPatientCallBackLogs; + String? listPatientCallBackToUpdateFromICServer; + String? listPatientCount; + String? listPatientDashboard; + String? listPatientERGetAdminClinicsModel; + String? listPatientERGetAdminProjectsModel; + String? listPatientERGetAllClinicsModel; + String? listPatientHISInvoices; + String? listPatientICProjects; + String? listPatientICProjectsByID; + String? listPatientICProjectsTimings; + String? listPatientIDByUID; + String? listPatientIDForSurveyResult; + String? listPatientInfo; + String? listPatientInfoForDDScreen; + String? listPatientInfoForSickleaveReport; + String? listPatientInsuranceCard; + String? listPatientInsuranceCardHistory; + String? listPatientInsuranceDetails; + String? listPatientPHRInvoices; + String? listPatientServicePoint; + String? listPatientStatusCount; + String? listPatientChatRequestMapModel; + String? listPatientChatRequestModel; + String? listPatientChatRequestVCModel; + String? listPaymentMethods; + String? listPointServices; + String? listPregnancyStagesInfo; + String? listProjectAvgERWaitingTime; + String? listProjectAvgERWaitingTimeHourly; + String? listRadMedicalRecords; + String? listRadMedicalRecordsAPI; + String? listRadMedicalRecordsCVI; + String? listRadMedicalRecordsCVIAPI; + String? listRadMedicalRecordsResults; + String? listSickLeave; + String? listTransaction; + String? listVideoConferenceSessions; + String? listWeekBloodPressureResult; + String? listWeekBloodPressureResultAverage; + String? listWeekDiabtecPatientResult; + String? listWeekDiabtectResultAverage; + String? listWeekWeightMeasurementResult; + String? listWeekWeightMeasurementResultAverage; + String? listYearBloodPressureResult; + String? listYearBloodPressureResultAverage; + String? listYearDiabtecPatientResult; + String? listYearDiabtecResultAverage; + String? listYearWeightMeasurementResult; + String? listYearWeightMeasurementResultAverage; + String? listEInvoiceForDental; + String? listEInvoiceForOnlineCheckIn; + String? medGetActivitiesTransactionsStsList; + String? medGetAvgMonthTransactionsStsList; + String? medGetAvgWeekTransactionsStsList; + String? medGetCategoriesList; + String? medGetMonthActivitiesTransactionsStsList; + String? medGetMonthStepsTransactionsStsList; + String? medGetMonthTransactionsStsList; + String? medGetPatientLastRecordList; + String? medGetSubCategoriesList; + String? medGetTransactionsAndActTransactionsResult; + String? medGetTransactionsList; + String? medGetWeekActivitiesTransactionsStsList; + String? medGetWeekStepsTransactionsStsList; + String? medGetWeekTransactionsStsList; + String? medGetYearActivitiesTransactionsStsList; + String? medGetYearSleepTransactionsStsList; + String? medGetYearStepsTransactionsStsList; + String? medGetYearTransactionsStsList; + String? medInsertTransactionsOutputsList; + String? medicalRecordImages; + int? medicalReportToRead; + int? medicalReportUnreadNo; + bool? missingIDCardAttachment; + bool? missingInsuranceCardAttachment; + bool? missingMedicalReportAttachment; + bool? missingOtherRelationship; + bool? missingPatientContactNo; + bool? missingPatientId; + bool? missingPatientIdentityNumber; + bool? missingPatientName; + bool? missingReferralContactNo; + bool? missingReferralRelationship; + bool? missingReferralRequesterName; + String? mobileNumber; + int? nationalityNumber; + String? onlineCheckInAppointments; + String? opinionUserAgreementContent; + bool? orderInsert; + String? pateintInfoForUpdateList; + String? pateintUpatedList; + String? patientBirthdayCertificate; + String? patientERCMCRequestSummaryByProject; + String? patientERCMCRequestWithTotal; + String? patientERCMCGetAllServicesList; + String? patientERCMCGetTransactionsForOrderList; + String? patientERCoordinates; + String? patientERCountOrderList; + String? patientERCountsForApprovalOffice; + String? patientERDeleteOldCurrentDoctorsOutputsList; + String? patientERDeliveryGetAllDeliverdOrderList; + String? patientERDeliveryGetAllOrderList; + bool? patientERDeliveryIsOrderInserted; + bool? patientERDeliveryIsOrderUpdated; + bool? patientERDeliveryIsPausedChanged; + String? patientERDeliveryNextOrder; + int? patientERDeliveryOrderInsert; + int? patientERDeliveryUpdateOrderStatus; + bool? patientERDriverUpdate; + String? patientERExacartCheckIsDispenseAccpetableList; + String? patientERExacartGetDispenseQuantitiesByOrderIDList; + String? patientERExacartGetOrderDetailsByePharmacyOrderNoList; + String? patientERExacartGetOrderDetailsList; + String? patientERExacartGetTotalDispenseQuantitiesByPresNoList; + bool? patientERExacartIsDispenseAdded; + String? patientERExacartIsDispenseAddedList; + bool? patientERExacartIsOrderCompleted; + String? patientERGetAdminByProjectAndRoleList; + String? patientERGetAdminProjectsList; + String? patientERGetAllDriversList; + String? patientERGetAllNeedAproveStatusList; + String? patientERGetAllPresOrdersStatusList; + String? patientERGetAllProjectsList; + String? patientERGetArchiveInformationList; + String? patientERGetAskDoctorTotalByDateFilterList; + String? patientERGetBookScheduleConfigsList; + String? patientERGetClinicAndTimeAndEpisodeForAppointmentList; + String? patientERGetClinicAndTimeForDischargeList; + String? patientERGetDashboardDataforApporvalSectionForAdminList; + String? patientERGetDashboardDataforApporvalSectionList; + String? patientERGetDashboardDataforHHCSectionForAdminList; + String? patientERGetDashboardDataforHHCSectionList; + String? patientERGetDashboardDataforPrescriptionSectionForAdminList; + String? patientERGetDashboardDataforPrescriptionSectionList; + String? patientERGetDoctorDashboardDataModelList; + String? patientERGetDriverLocationList; + String? patientERGetInsuranceCardRequestByDateFilterList; + String? patientERGetLiveCareSummaryBookedAppoinmentStatusList; + String? patientERGetLiveCareSummaryCovidList; + String? patientERGetLiveCareSummaryForCMCList; + String? patientERGetLiveCareSummaryForHHCList; + String? patientERGetLiveCareSummaryForHomeDeliveryList; + String? patientERGetLiveCareSummaryForInsuranceCardRequestList; + String? patientERGetLiveCareSummaryForNewFilesList; + String? patientERGetLiveCareSummaryForOnlinePaymetRequestList; + String? patientERGetLiveCareSummaryForOnlinePharmacyOrdersList; + String? patientERGetLiveCareSummaryForTrasnportationList; + String? patientERGetLiveCareSummaryLiveCareCountsList; + String? patientERGetMedicalRequestTotalByDateFilterList; + String? patientERGetNearestPendingOrdersList; + String? patientERGetNeedAproveHistoryForOrderList; + String? patientERGetNeedAprovePendingOrdersList; + String? patientERGetNeedAproveStatusStatisticsList; + String? patientERGetPatientAllPresOrdersList; + String? patientERGetPendingPatientsCountList; + String? patientERGetPresOrdersHistoryForAdminList; + String? patientERGetPresOrdersHistoryForOrderList; + String? patientERGetPresOrdersStatusStatisticsList; + String? patientERHHCRequest; + String? patientERHHCRequestSummaryByProject; + String? patientERHHCRequestWithTotal; + String? patientERHHCGetAllServicesList; + String? patientERHHCGetTransactionsForOrderList; + String? patientERHomeDeliveryCounts; + bool? patientERInsertDriver; + String? patientERInsertNewCurrentDoctorsOutputsList; + String? patientERInsuranceStatusCountList; + bool? patientERIsNearestProjectUpdated; + bool? patientERIsNeedAproveReturnedToQueue; + bool? patientERIsNeedAproveUpdated; + bool? patientERIsOrderClientRequestUpdated; + bool? patientERIsOrderReturnedToQueue; + bool? patientERIsPresOrderInserted; + bool? patientERIsPresOrderUpdated; + bool? patientERIsProjectUpdated; + String? patientERNotCompletedDetails; + String? patientERPatientsCountByCallStatus; + String? patientERPeakHourCounts; + String? patientERPresOrderInfo; + String? patientERPrescriptionCounts; + String? patientERProjectsContribution; + String? patientERRRTGetAllQuestionsList; + String? patientERRRTGetAllTransportationMethodList; + String? patientERRRTGetPickUpRequestByPresOrderIDList; + String? patientERRealRRTGetAllServicesList; + String? patientERRealRRTGetOrderDetailsList; + String? patientERRealRRTGetTransactionsForOrderList; + bool? patientERRealRRTIsTransInserted; + String? patientERRequestList; + String? patientERTransportationRequestWithTotal; + String? patientERealRRTGetServicePriceList; + String? patientInfoByAdmissionNoList; + String? patientMonitorGetPatientHeartRate; + int? patientNotServedCounts; + String? patientPrescriptionList; + String? patientAllergies; + String? patientCheckAppointmentValidationList; + String? patientLoginTokenList; + String? patientQRLoginInfoList; + String? patientSELECTDeviceIMEIbyIMEIList; + String? pharmList; + String? prefLang; + int? radReportUnreadNo; + String? radGetPatientRadOrdersForDentalList; + int? referralNumber; + String? reminderConfigurations; + String? requestNo; + int? rowCount; + String? servicePrivilegeList; + String? shareFamilyFileObj; + String? status; + int? successCode; + String? surveyRate; + String? symptomCheckerConditionList; + String? symptomCheckerGetAllDefaultQuestionsList; + String? symptomCheckerGetBodyPartSymptomsList; + String? symptomCheckerGetBodyPartsByCodeList; + String? symptomCheckerGetBodyPartsList; + String? symptomCheckerJsonResponseInString; + int? timerTime; + int? totalAdvanceBalanceAmount; + int? totalPatientsCount; + int? totalPendingApprovalCount; + int? totalUnUsedCount; + int? transactionNo; + int? unReadCounts; + bool? updateStatus; + String? userAgreementContent; + int? yahalaAccountNo; + bool? check24HourComplaint; + String? currency; + String? message; + int? patientID; + int? returnValue; + String? returnValueStr; + int? statusCode; LacumAccountInformation( {this.date, @@ -935,7 +935,7 @@ class LacumAccountInformation { lakumInquiryInformationObj = json['LakumInquiryInformationObj']; lakumInquiryInformationObjVersion = json['LakumInquiryInformationObjVersion'] != null - ? new LakumInquiryInformationObjVersion.fromJson( + ? LakumInquiryInformationObjVersion.fromJson( json['LakumInquiryInformationObjVersion']) : null; lakumResponseList = json['LakumResponseList']; @@ -1477,7 +1477,7 @@ class LacumAccountInformation { data['LakumInquiryInformationObj'] = this.lakumInquiryInformationObj; if (this.lakumInquiryInformationObjVersion != null) { data['LakumInquiryInformationObjVersion'] = - this.lakumInquiryInformationObjVersion.toJson(); + this.lakumInquiryInformationObjVersion!.toJson(); } data['LakumResponseList'] = this.lakumResponseList; data['Laser_GetBodyPartsByCategoryList'] = diff --git a/lib/core/model/pharmacies/LakumInquiryInformationObjVersion.dart b/lib/core/model/pharmacies/LakumInquiryInformationObjVersion.dart index c609fa0b..37f5c662 100644 --- a/lib/core/model/pharmacies/LakumInquiryInformationObjVersion.dart +++ b/lib/core/model/pharmacies/LakumInquiryInformationObjVersion.dart @@ -2,35 +2,36 @@ import 'PointsAmountPerYear.dart'; import 'PointsDetails.dart'; class LakumInquiryInformationObjVersion { - int accountNumber; - String accountStatus; - String barCode; - int consumedPoints; - String consumedPointsAmount; - List consumedPointsAmountPerYear; - List consumedPointsDetails; - String createdDate; - int expiredPoints; - String expiryDate; - int gainedPoints; - List gainedPointsAmountPerYear; - List gainedPointsDetails; - String lakumMessageStatus; - String memberName; - String memberUniversalId; - String mobileNumber; - int pointsBalance; - int pointsBalanceAmount; - int pointsWillBeExpired; - String prefLang; - int statusCode; - int transferPoints; - List transferPointsAmountPerYear; - List transferPointsDetails; + num? accountNumber; + String? accountStatus; + String? barCode; + num? consumedPoints; + String? consumedPointsAmount; + List? consumedPointsAmountPerYear; + List? consumedPointsDetails; + String? createdDate; + num? expiredPoints; + String? expiryDate; + num? gainedPoints; + num? gainedPointsAmount; + List? gainedPointsAmountPerYear; + List? gainedPointsDetails; + String? lakumMessageStatus; + String? memberName; + String? memberUniversalId; + String? mobileNumber; + num? pointsBalance; + num? pointsBalanceAmount; + num? pointsWillBeExpired; + String? prefLang; + num? statusCode; + num? transferPoints; + List? transferPointsAmountPerYear; + List? transferPointsDetails; dynamic waitingPoints; dynamic loyalityAmount; dynamic loyalityPoints; - int purchaseRate; + num? purchaseRate; LakumInquiryInformationObjVersion( {this.accountNumber, @@ -44,6 +45,7 @@ class LakumInquiryInformationObjVersion { this.expiredPoints, this.expiryDate, this.gainedPoints, + this.gainedPointsAmount, this.gainedPointsAmountPerYear, this.gainedPointsDetails, this.lakumMessageStatus, @@ -70,31 +72,32 @@ class LakumInquiryInformationObjVersion { consumedPoints = json['ConsumedPoints']; consumedPointsAmount = json['ConsumedPointsAmount']; if (json['ConsumedPointsAmountPerYear'] != null) { - consumedPointsAmountPerYear = new List(); + consumedPointsAmountPerYear = []; json['ConsumedPointsAmountPerYear'].forEach((v) { - consumedPointsAmountPerYear.add(PointsAmountPerYear.fromJson(v)); + consumedPointsAmountPerYear!.add(PointsAmountPerYear.fromJson(v)); }); } if (json['ConsumedPointsDetails'] != null) { - consumedPointsDetails = new List(); + consumedPointsDetails = []; json['ConsumedPointsDetails'].forEach((v) { - consumedPointsDetails.add(PointsDetails.fromJson(v)); + consumedPointsDetails!.add(PointsDetails.fromJson(v)); }); } createdDate = json['CreatedDate']; expiredPoints = json['ExpiredPoints']; expiryDate = json['ExpiryDate']; gainedPoints = json['GainedPoints']; + gainedPointsAmount = json['GainedPointsAmount']; if (json['GainedPointsAmountPerYear'] != null) { - gainedPointsAmountPerYear = new List(); + gainedPointsAmountPerYear = []; json['GainedPointsAmountPerYear'].forEach((v) { - gainedPointsAmountPerYear.add(PointsAmountPerYear.fromJson(v)); + gainedPointsAmountPerYear!.add(PointsAmountPerYear.fromJson(v)); }); } if (json['GainedPointsDetails'] != null) { - gainedPointsDetails = new List(); + gainedPointsDetails = []; json['GainedPointsDetails'].forEach((v) { - gainedPointsDetails.add(PointsDetails.fromJson(v)); + gainedPointsDetails!.add(PointsDetails.fromJson(v)); }); } lakumMessageStatus = json['LakumMessageStatus']; @@ -108,15 +111,15 @@ class LakumInquiryInformationObjVersion { statusCode = json['StatusCode']; transferPoints = json['TransferPoints']; if (json['TransferPointsAmountPerYear'] != null) { - transferPointsAmountPerYear = new List(); + transferPointsAmountPerYear = []; json['TransferPointsAmountPerYear'].forEach((v) { - transferPointsAmountPerYear.add(PointsAmountPerYear.fromJson(v)); + transferPointsAmountPerYear!.add(PointsAmountPerYear.fromJson(v)); }); } if (json['TransferPointsDetails'] != null) { - transferPointsDetails = new List(); + transferPointsDetails = []; json['TransferPointsDetails'].forEach((v) { - transferPointsDetails.add(PointsDetails.fromJson(v)); + transferPointsDetails!.add(PointsDetails.fromJson(v)); }); } waitingPoints = json['WaitingPoints']; @@ -134,23 +137,24 @@ class LakumInquiryInformationObjVersion { data['ConsumedPointsAmount'] = this.consumedPointsAmount; if (this.consumedPointsAmountPerYear != null) { data['ConsumedPointsAmountPerYear'] = - this.consumedPointsAmountPerYear.map((v) => v).toList(); + this.consumedPointsAmountPerYear!.map((v) => v).toList(); } if (this.consumedPointsDetails != null) { data['ConsumedPointsDetails'] = - this.consumedPointsDetails.map((v) => v).toList(); + this.consumedPointsDetails!.map((v) => v).toList(); } data['CreatedDate'] = this.createdDate; data['ExpiredPoints'] = this.expiredPoints; data['ExpiryDate'] = this.expiryDate; data['GainedPoints'] = this.gainedPoints; + data['GainedPointsAmount'] = this.gainedPointsAmount; if (this.gainedPointsAmountPerYear != null) { data['GainedPointsAmountPerYear'] = - this.gainedPointsAmountPerYear.map((v) => v).toList(); + this.gainedPointsAmountPerYear!.map((v) => v).toList(); } if (this.gainedPointsDetails != null) { data['GainedPointsDetails'] = - this.gainedPointsDetails.map((v) => v).toList(); + this.gainedPointsDetails!.map((v) => v).toList(); } data['LakumMessageStatus'] = this.lakumMessageStatus; data['MemberName'] = this.memberName; @@ -164,11 +168,11 @@ class LakumInquiryInformationObjVersion { data['TransferPoints'] = this.transferPoints; if (this.transferPointsAmountPerYear != null) { data['TransferPointsAmountPerYear'] = - this.transferPointsAmountPerYear.map((v) => v).toList(); + this.transferPointsAmountPerYear!.map((v) => v).toList(); } if (this.transferPointsDetails != null) { data['TransferPointsDetails'] = - this.transferPointsDetails.map((v) => v).toList(); + this.transferPointsDetails!.map((v) => v).toList(); } data['WaitingPoints'] = this.waitingPoints; data['loyalityAmount'] = this.loyalityAmount; diff --git a/lib/core/model/pharmacies/ListUserAgreement.dart b/lib/core/model/pharmacies/ListUserAgreement.dart index 4237e304..3c2a6231 100644 --- a/lib/core/model/pharmacies/ListUserAgreement.dart +++ b/lib/core/model/pharmacies/ListUserAgreement.dart @@ -1,8 +1,8 @@ class ListUserAgreement { - String userAgreementLAKUM; - String userAgreementLAKUMn; - String userAgreementTxt; - String userAgreementTxtn; + String? userAgreementLAKUM; + String? userAgreementLAKUMn; + String? userAgreementTxt; + String? userAgreementTxtn; ListUserAgreement( {this.userAgreementLAKUM, diff --git a/lib/core/model/pharmacies/Manufacturer.dart b/lib/core/model/pharmacies/Manufacturer.dart index 3b16337b..543a1b43 100644 --- a/lib/core/model/pharmacies/Manufacturer.dart +++ b/lib/core/model/pharmacies/Manufacturer.dart @@ -1,24 +1,24 @@ import 'PharmacyImageObject.dart'; class Manufacturer { - String id; - String name; - String namen; + String? id; + String? name; + String? namen; // List localizedNames; - String description; - int manufacturerTemplateId; - String metaKeywords; - String metaDescription; - String metaTitle; - int pageSize; - String pageSizeOptions; - String priceRanges; - bool published; - bool deleted; - int displayOrder; - String createdOnUtc; - String updatedOnUtc; - PharmacyImageObject image; + String? description; + int? manufacturerTemplateId; + String? metaKeywords; + String? metaDescription; + String? metaTitle; + int? pageSize; + String? pageSizeOptions; + String? priceRanges; + bool? published; + bool? deleted; + int? displayOrder; + String? createdOnUtc; + String? updatedOnUtc; + PharmacyImageObject? image; Manufacturer( {this.id, @@ -91,7 +91,7 @@ class Manufacturer { data['created_on_utc'] = this.createdOnUtc; data['updated_on_utc'] = this.updatedOnUtc; if (this.image != null) { - data['image'] = this.image.toJson(); + data['image'] = this.image!.toJson(); } return data; } diff --git a/lib/core/model/pharmacies/PharmacyAddressesModel.dart b/lib/core/model/pharmacies/PharmacyAddressesModel.dart index db9c20ae..82d448ed 100644 --- a/lib/core/model/pharmacies/PharmacyAddressesModel.dart +++ b/lib/core/model/pharmacies/PharmacyAddressesModel.dart @@ -10,14 +10,14 @@ class PharmacyAddressesModel { this.customers, }); - List customers; + List? customers; factory PharmacyAddressesModel.fromJson(Map json) => PharmacyAddressesModel( customers: List.from(json["customers"].map((x) => Customer.fromJson(x))), ); Map toJson() => { - "customers": List.from(customers.map((x) => x.toJson())), + "customers": List.from(customers!.map((x) => x.toJson())), }; } @@ -26,14 +26,14 @@ class Customer { this.addresses, }); - List
addresses; + List
? addresses; factory Customer.fromJson(Map json) => Customer( addresses: List
.from(json["addresses"].map((x) => Address.fromJson(x))), ); Map toJson() => { - "addresses": List.from(addresses.map((x) => x.toJson())), + "addresses": List.from(addresses!.map((x) => x.toJson())), }; } @@ -59,35 +59,35 @@ class Address { this.latLong, }); - String id; - FirstName firstName; - LastName lastName; - Email email; + String? id; + FirstName? firstName; + LastName? lastName; + Email? email; dynamic company; - int countryId; - Country country; + int? countryId; + Country? country; dynamic stateProvinceId; - City city; - String address1; - String address2; - String zipPostalCode; - String phoneNumber; + City? city; + String? address1; + String? address2; + String? zipPostalCode; + String? phoneNumber; dynamic faxNumber; - String customerAttributes; - DateTime createdOnUtc; + String? customerAttributes; + DateTime? createdOnUtc; dynamic province; - String latLong; + String? latLong; factory Address.fromJson(Map json) => Address( id: json["id"], - firstName: firstNameValues.map[json["first_name"]], - lastName: lastNameValues.map[json["last_name"]], - email: emailValues.map[json["email"]], + firstName: firstNameValues.map![json["first_name"]], + lastName: lastNameValues.map![json["last_name"]], + email: emailValues.map![json["email"]], company: json["company"], countryId: json["country_id"], - country: countryValues.map[json["country"]], + country: countryValues.map![json["country"]], stateProvinceId: json["state_province_id"], - city: cityValues.map[json["city"]], + city: cityValues.map![json["city"]], address1: json["address1"], address2: json["address2"], zipPostalCode: json["zip_postal_code"], @@ -115,7 +115,7 @@ class Address { "phone_number": phoneNumber, "fax_number": faxNumber, "customer_attributes": customerAttributes, - "created_on_utc": createdOnUtc.toIso8601String(), + "created_on_utc": createdOnUtc!.toIso8601String(), "province": province, "lat_long": latLong, }; @@ -156,15 +156,15 @@ final lastNameValues = EnumValues({ }); class EnumValues { - Map map; - Map reverseMap; + Map? map; + Map? reverseMap; EnumValues(this.map); Map get reverse { if (reverseMap == null) { - reverseMap = map.map((k, v) => new MapEntry(v, k)); + reverseMap = map!.map((k, v) => new MapEntry(v, k)); } - return reverseMap; + return reverseMap!; } } diff --git a/lib/core/model/pharmacies/PharmacyImageObject.dart b/lib/core/model/pharmacies/PharmacyImageObject.dart index d3db634b..2806551e 100644 --- a/lib/core/model/pharmacies/PharmacyImageObject.dart +++ b/lib/core/model/pharmacies/PharmacyImageObject.dart @@ -1,9 +1,9 @@ class PharmacyImageObject { - int id; - int position; - String src; - String thumb; - String attachment; + int? id; + int? position; + String? src; + String? thumb; + String? attachment; PharmacyImageObject({this.id, this.position, this.src, this.thumb, this.attachment}); diff --git a/lib/core/model/pharmacies/PharmacyProduct.dart b/lib/core/model/pharmacies/PharmacyProduct.dart index f69d035b..3656aac8 100644 --- a/lib/core/model/pharmacies/PharmacyProduct.dart +++ b/lib/core/model/pharmacies/PharmacyProduct.dart @@ -5,115 +5,115 @@ import 'Reviews.dart'; class PharmacyProduct { dynamic id; - bool visibleIndividually; + bool? visibleIndividually; dynamic name; dynamic namen; dynamic shortDescription; dynamic shortDescriptionn; dynamic fullDescription; dynamic fullDescriptionn; - bool markasNew; - bool showOnHomePage; + bool? markasNew; + bool? showOnHomePage; dynamic metaKeywords; dynamic metaDescription; dynamic metaTitle; - bool allowCustomerReviews; - int approvedRatingSum; - int notApprovedRatingSum; - int approvedTotalReviews; - int notApprovedTotalReviews; + bool? allowCustomerReviews; + int? approvedRatingSum; + int? notApprovedRatingSum; + dynamic approvedTotalReviews; + int? notApprovedTotalReviews; dynamic sku; - bool isRx; - bool prescriptionRequired; + bool? isRx; + bool? prescriptionRequired; dynamic rxMessage; dynamic rxMessagen; - String manufacturerPartNumber; - String gtin; - bool isGiftCard; - bool requireOtherProducts; - bool automaticallyAddRequiredProducts; - bool isDownload; - bool unlimitedDownloads; - int maxNumberOfDownloads; - String downloadExpirationDays; - bool hasSampleDownload; - bool hasUserAgreement; - bool isRecurring; - int recurringCycleLength; - int recurringTotalCycles; - bool isRental; - int rentalPriceLength; - bool isShipEnabled; - bool isFreeShipping; - bool shipSeparately; - double additionalShippingCharge; - bool isTaxExempt; - bool isTelecommunicationsOrBroadcastingOrElectronicServices; - bool useMultipleWarehouses; - int manageInventoryMethodId; - int stockQuantity; - String stockAvailability; - String stockAvailabilityn; - bool displayStockAvailability; - bool displayStockQuantity; - int minStockQuantity; - int notifyAdminForQuantityBelow; - bool allowBackInStockSubscriptions; - int orderMinimumQuantity; - int orderMaximumQuantity; - String allowedQuantities; - bool allowAddingOnlyExistingAttributeCombinations; - bool disableBuyButton; - bool disableWishlistButton; - bool availableForPreOrder; - String preOrderAvailabilityStartDateTimeUtc; - bool callForPrice; - double price; - double oldPrice; - double productCost; - String specialPrice; - String specialPriceStartDateTimeUtc; - String specialPriceEndDateTimeUtc; - bool customerEntersPrice; - double minimumCustomerEnteredPrice; - double maximumCustomerEnteredPrice; - bool basepriceEnabled; - double basepriceAmount; - double basepriceBaseAmount; - bool hasTierPrices; - bool hasDiscountsApplied; - String discountName; - String discountNamen; - String discountDescription; - String discountDescriptionn; - String discountPercentage; - String currency; - String currencyn; - double weight; - double length; - double width; - double height; - String availableStartDateTimeUtc; - String availableEndDateTimeUtc; - int displayOrder; - bool published; - bool deleted; - String createdOnUtc; - String updatedOnUtc; - String productType; - int parentGroupedProductId; - List roleIds; - List discountIds; - List storeIds; - List manufacturerIds; - List reviews; - List images; - List attributes; - List specifications; - List associatedProductIds; - List tags; - int vendorId; - String seName; + String? manufacturerPartNumber; + String? gtin; + bool? isGiftCard; + bool? requireOtherProducts; + bool? automaticallyAddRequiredProducts; + bool? isDownload; + bool? unlimitedDownloads; + int? maxNumberOfDownloads; + String? downloadExpirationDays; + bool? hasSampleDownload; + bool? hasUserAgreement; + bool? isRecurring; + int? recurringCycleLength; + int? recurringTotalCycles; + bool? isRental; + int? rentalPriceLength; + bool? isShipEnabled; + bool? isFreeShipping; + bool? shipSeparately; + double? additionalShippingCharge; + bool? isTaxExempt; + bool? isTelecommunicationsOrBroadcastingOrElectronicServices; + bool? useMultipleWarehouses; + int? manageInventoryMethodId; + int? stockQuantity; + String? stockAvailability; + String? stockAvailabilityn; + bool? displayStockAvailability; + bool? displayStockQuantity; + int? minStockQuantity; + int? notifyAdminForQuantityBelow; + bool? allowBackInStockSubscriptions; + int? orderMinimumQuantity; + int? orderMaximumQuantity; + String? allowedQuantities; + bool? allowAddingOnlyExistingAttributeCombinations; + bool? disableBuyButton; + bool? disableWishlistButton; + bool? availableForPreOrder; + String? preOrderAvailabilityStartDateTimeUtc; + bool? callForPrice; + double? price; + double? oldPrice; + double? productCost; + String? specialPrice; + String? specialPriceStartDateTimeUtc; + String? specialPriceEndDateTimeUtc; + bool? customerEntersPrice; + double? minimumCustomerEnteredPrice; + double? maximumCustomerEnteredPrice; + bool? basepriceEnabled; + double? basepriceAmount; + double? basepriceBaseAmount; + bool? hasTierPrices; + bool? hasDiscountsApplied; + String? discountName; + String? discountNamen; + String? discountDescription; + String? discountDescriptionn; + String? discountPercentage; + String? currency; + String? currencyn; + double? weight; + double? length; + double? width; + double? height; + String? availableStartDateTimeUtc; + String? availableEndDateTimeUtc; + int? displayOrder; + bool? published; + bool? deleted; + String? createdOnUtc; + String? updatedOnUtc; + String? productType; + int? parentGroupedProductId; + List? roleIds; + List? discountIds; + List? storeIds; + List? manufacturerIds; + List? reviews; + List? images; + List? attributes; + List? specifications; + List? associatedProductIds; + List? tags; + int? vendorId; + String? seName; PharmacyProduct( {this.id, @@ -331,63 +331,63 @@ class PharmacyProduct { productType = json['product_type']; parentGroupedProductId = json['parent_grouped_product_id']; if (json['role_ids'] != null) { - roleIds = new List(); + roleIds = []; json['role_ids'].forEach((v) { - roleIds.add(v); + roleIds!.add(v); }); } if (json['discount_ids'] != null) { - discountIds = new List(); + discountIds = []; json['discount_ids'].forEach((v) { - discountIds.add(v); + discountIds!.add(v); }); } if (json['store_ids'] != null) { - storeIds = new List(); + storeIds = []; json['store_ids'].forEach((v) { - storeIds.add(v); + storeIds!.add(v); }); } if (json['manufacturer_ids'] != null) { - manufacturerIds = new List(); + manufacturerIds =[]; json['manufacturer_ids'].forEach((v) { - manufacturerIds.add(v); + manufacturerIds!.add(v); }); } if (json['reviews'] != null) { - reviews = new List(); + reviews = []; json['reviews'].forEach((v) { - reviews.add(new Reviews.fromJson(v)); + reviews!.add(new Reviews.fromJson(v)); }); } if (json['images'] != null) { - images = new List(); + images =[]; json['images'].forEach((v) { - images.add(new PharmacyImageObject.fromJson(v)); + images!.add(new PharmacyImageObject.fromJson(v)); }); } if (json['attributes'] != null) { - attributes = new List(); + attributes = []; json['attributes'].forEach((v) { - attributes.add(v); + attributes!.add(v); }); } if (json['specifications'] != null) { - specifications = new List(); + specifications = []; json['specifications'].forEach((v) { - specifications.add(new Specifications.fromJson(v)); + specifications!.add(new Specifications.fromJson(v)); }); } if (json['associated_product_ids'] != null) { - associatedProductIds = new List(); + associatedProductIds =[]; json['associated_product_ids'].forEach((v) { - associatedProductIds.add(v); + associatedProductIds!.add(v); }); } if (json['tags'] != null) { - tags = new List(); + tags = []; json['tags'].forEach((v) { - tags.add(v); + tags!.add(v); }); } vendorId = json['vendor_id']; @@ -501,34 +501,34 @@ class PharmacyProduct { data['product_type'] = this.productType; data['parent_grouped_product_id'] = this.parentGroupedProductId; if (this.roleIds != null) { - data['role_ids'] = this.roleIds.map((v) => v).toList(); + data['role_ids'] = this.roleIds!.map((v) => v).toList(); } if (this.discountIds != null) { - data['discount_ids'] = this.discountIds.map((v) => v).toList(); + data['discount_ids'] = this.discountIds!.map((v) => v).toList(); } if (this.storeIds != null) { - data['store_ids'] = this.storeIds.map((v) => v).toList(); + data['store_ids'] = this.storeIds!.map((v) => v).toList(); } data['manufacturer_ids'] = this.manufacturerIds; if (this.reviews != null) { - data['reviews'] = this.reviews.map((v) => v.toJson()).toList(); + data['reviews'] = this.reviews!.map((v) => v.toJson()).toList(); } if (this.images != null) { - data['images'] = this.images.map((v) => v.toJson()).toList(); + data['images'] = this.images!.map((v) => v.toJson()).toList(); } if (this.attributes != null) { - data['attributes'] = this.attributes.map((v) => v).toList(); + data['attributes'] = this.attributes!.map((v) => v).toList(); } if (this.specifications != null) { data['specifications'] = - this.specifications.map((v) => v.toJson()).toList(); + this.specifications!.map((v) => v.toJson()).toList(); } if (this.associatedProductIds != null) { data['associated_product_ids'] = - this.associatedProductIds.map((v) => v).toList(); + this.associatedProductIds!.map((v) => v).toList(); } if (this.tags != null) { - data['tags'] = this.tags.map((v) => v).toList(); + data['tags'] = this.tags!.map((v) => v).toList(); } data['vendor_id'] = this.vendorId; data['se_name'] = this.seName; diff --git a/lib/core/model/pharmacies/PointsAmountPerMonth.dart b/lib/core/model/pharmacies/PointsAmountPerMonth.dart index 71cf3498..2504975c 100644 --- a/lib/core/model/pharmacies/PointsAmountPerMonth.dart +++ b/lib/core/model/pharmacies/PointsAmountPerMonth.dart @@ -1,11 +1,11 @@ import 'PointsAmountPerday.dart'; class PointsAmountPerMonth { - double amountPerMonth; - String month; - int monthNumber; - List pointsAmountPerday; - double pointsPerMonth; + num? amountPerMonth; + String? month; + num? monthNumber; + List? pointsAmountPerday; + num? pointsPerMonth; PointsAmountPerMonth( {this.amountPerMonth, @@ -19,9 +19,9 @@ class PointsAmountPerMonth { month = json['Month']; monthNumber = json['MonthNumber']; if (json['PointsAmountPerday'] != null) { - pointsAmountPerday = new List(); + pointsAmountPerday = []; json['PointsAmountPerday'].forEach((v) { - pointsAmountPerday.add(new PointsAmountPerday.fromJson(v)); + pointsAmountPerday!.add(new PointsAmountPerday.fromJson(v)); }); } pointsPerMonth = json['PointsPerMonth']; @@ -34,7 +34,7 @@ class PointsAmountPerMonth { data['MonthNumber'] = this.monthNumber; if (this.pointsAmountPerday != null) { data['PointsAmountPerday'] = - this.pointsAmountPerday.map((v) => v.toJson()).toList(); + this.pointsAmountPerday!.map((v) => v.toJson()).toList(); } data['PointsPerMonth'] = this.pointsPerMonth; return data; diff --git a/lib/core/model/pharmacies/PointsAmountPerYear.dart b/lib/core/model/pharmacies/PointsAmountPerYear.dart index eef74064..3affcd65 100644 --- a/lib/core/model/pharmacies/PointsAmountPerYear.dart +++ b/lib/core/model/pharmacies/PointsAmountPerYear.dart @@ -1,10 +1,10 @@ import 'PointsAmountPerMonth.dart'; class PointsAmountPerYear { - int amountPerYear; - List pointsAmountPerMonth; - int pointsPerYear; - int year; + int? amountPerYear; + List? pointsAmountPerMonth; + int? pointsPerYear; + int? year; PointsAmountPerYear( {this.amountPerYear, @@ -15,9 +15,9 @@ class PointsAmountPerYear { PointsAmountPerYear.fromJson(Map json) { amountPerYear = json['AmountPerYear']; if (json['PointsAmountPerMonth'] != null) { - pointsAmountPerMonth = new List(); + pointsAmountPerMonth = []; json['PointsAmountPerMonth'].forEach((v) { - pointsAmountPerMonth.add(new PointsAmountPerMonth.fromJson(v)); + pointsAmountPerMonth!.add(new PointsAmountPerMonth.fromJson(v)); }); } pointsPerYear = json['PointsPerYear']; @@ -29,7 +29,7 @@ class PointsAmountPerYear { data['AmountPerYear'] = this.amountPerYear; if (this.pointsAmountPerMonth != null) { data['PointsAmountPerMonth'] = - this.pointsAmountPerMonth.map((v) => v.toJson()).toList(); + this.pointsAmountPerMonth!.map((v) => v.toJson()).toList(); } data['PointsPerYear'] = this.pointsPerYear; data['Year'] = this.year; diff --git a/lib/core/model/pharmacies/PointsAmountPerday.dart b/lib/core/model/pharmacies/PointsAmountPerday.dart index e78e87b7..28515bc6 100644 --- a/lib/core/model/pharmacies/PointsAmountPerday.dart +++ b/lib/core/model/pharmacies/PointsAmountPerday.dart @@ -1,11 +1,11 @@ import 'PointsDetails.dart'; class PointsAmountPerday { - double amountPerDay; - String day; - List pointsDetails; - double pointsPerDay; - String transationDate; + num? amountPerDay; + String? day; + List? pointsDetails; + num? pointsPerDay; + String? transationDate; PointsAmountPerday( {this.amountPerDay, @@ -18,9 +18,9 @@ class PointsAmountPerday { amountPerDay = json['AmountPerDay']; day = json['Day']; if (json['PointsDetails'] != null) { - pointsDetails = new List(); + pointsDetails = []; json['PointsDetails'].forEach((v) { - pointsDetails.add(new PointsDetails.fromJson(v)); + pointsDetails!.add(new PointsDetails.fromJson(v)); }); } pointsPerDay = json['PointsPerDay']; @@ -33,7 +33,7 @@ class PointsAmountPerday { data['Day'] = this.day; if (this.pointsDetails != null) { data['PointsDetails'] = - this.pointsDetails.map((v) => v.toJson()).toList(); + this.pointsDetails!.map((v) => v.toJson()).toList(); } data['PointsPerDay'] = this.pointsPerDay; data['TransationDate'] = this.transationDate; diff --git a/lib/core/model/pharmacies/PointsDetails.dart b/lib/core/model/pharmacies/PointsDetails.dart index 7b342af9..f3091b1d 100644 --- a/lib/core/model/pharmacies/PointsDetails.dart +++ b/lib/core/model/pharmacies/PointsDetails.dart @@ -1,14 +1,14 @@ class PointsDetails { - int accNumber; - String accountStatus; - double amount; - int lineItemNo; - String operationType; - double points; - double purchasePoints; - int subTransactionType; - String subTransactionTypeDescription; - String transactionDate; + int? accNumber; + String? accountStatus; + num? amount; + int? lineItemNo; + String? operationType; + num? points; + num? purchasePoints; + int? subTransactionType; + String? subTransactionTypeDescription; + String? transactionDate; PointsDetails( {this.accNumber, diff --git a/lib/core/model/pharmacies/Prescriptions.dart b/lib/core/model/pharmacies/Prescriptions.dart deleted file mode 100644 index 80caff0a..00000000 --- a/lib/core/model/pharmacies/Prescriptions.dart +++ /dev/null @@ -1,157 +0,0 @@ - - -import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; - -class Prescriptions { - String setupID; - int projectID; - int patientID; - int appointmentNo; - String appointmentDate; - String doctorName; - String clinicDescription; - String name; - int episodeID; - int actualDoctorRate; - int admission; - int clinicID; - String companyName; - String despensedStatus; - DateTime dischargeDate; - int dischargeNo; - int doctorID; - String doctorImageURL; - int doctorRate; - String doctorTitle; - int gender; - String genderDescription; - bool isActiveDoctorProfile; - bool isDoctorAllowVedioCall; - bool isExecludeDoctor; - bool isInOutPatient; - String isInOutPatientDescription; - String isInOutPatientDescriptionN; - bool isInsurancePatient; - String nationalityFlagURL; - int noOfPatientsRate; - String qR; - List speciality; - - Prescriptions( - {this.setupID, - this.projectID, - this.patientID, - this.appointmentNo, - this.appointmentDate, - this.doctorName, - this.clinicDescription, - this.name, - this.episodeID, - this.actualDoctorRate, - this.admission, - this.clinicID, - this.companyName, - this.despensedStatus, - this.dischargeDate, - this.dischargeNo, - this.doctorID, - this.doctorImageURL, - this.doctorRate, - this.doctorTitle, - this.gender, - this.genderDescription, - this.isActiveDoctorProfile, - this.isDoctorAllowVedioCall, - this.isExecludeDoctor, - this.isInOutPatient, - this.isInOutPatientDescription, - this.isInOutPatientDescriptionN, - this.isInsurancePatient, - this.nationalityFlagURL, - this.noOfPatientsRate, - this.qR, - this.speciality}); - - Prescriptions.fromJson(Map json) { - setupID = json['SetupID']; - projectID = json['ProjectID']; - patientID = json['PatientID']; - appointmentNo = json['AppointmentNo']; - appointmentDate = json['AppointmentDate']; - doctorName = json['DoctorName']; - clinicDescription = json['ClinicDescription']; - name = json['Name']; - episodeID = json['EpisodeID']; - actualDoctorRate = json['ActualDoctorRate']; - admission = json['Admission']; - clinicID = json['ClinicID']; - companyName = json['CompanyName']; - despensedStatus = json['Despensed_Status']; - dischargeDate = DateUtil.convertStringToDate(json['DischargeDate']); - dischargeNo = json['DischargeNo']; - doctorID = json['DoctorID']; - doctorImageURL = json['DoctorImageURL']; - doctorRate = json['DoctorRate']; - doctorTitle = json['DoctorTitle']; - gender = json['Gender']; - genderDescription = json['GenderDescription']; - isActiveDoctorProfile = json['IsActiveDoctorProfile']; - isDoctorAllowVedioCall = json['IsDoctorAllowVedioCall']; - isExecludeDoctor = json['IsExecludeDoctor']; - isInOutPatient = json['IsInOutPatient']; - isInOutPatientDescription = json['IsInOutPatientDescription']; - isInOutPatientDescriptionN = json['IsInOutPatientDescriptionN']; - isInsurancePatient = json['IsInsurancePatient']; - nationalityFlagURL = json['NationalityFlagURL']; - noOfPatientsRate = json['NoOfPatientsRate']; - qR = json['QR']; - // speciality = json['Speciality'].cast(); - } - - Map toJson() { - final Map data = new Map(); - data['SetupID'] = this.setupID; - data['ProjectID'] = this.projectID; - data['PatientID'] = this.patientID; - data['AppointmentNo'] = this.appointmentNo; - data['AppointmentDate'] = this.appointmentDate; - data['DoctorName'] = this.doctorName; - data['ClinicDescription'] = this.clinicDescription; - data['Name'] = this.name; - data['EpisodeID'] = this.episodeID; - data['ActualDoctorRate'] = this.actualDoctorRate; - data['Admission'] = this.admission; - data['ClinicID'] = this.clinicID; - data['CompanyName'] = this.companyName; - data['Despensed_Status'] = this.despensedStatus; - data['DischargeDate'] = this.dischargeDate; - data['DischargeNo'] = this.dischargeNo; - data['DoctorID'] = this.doctorID; - data['DoctorImageURL'] = this.doctorImageURL; - data['DoctorRate'] = this.doctorRate; - data['DoctorTitle'] = this.doctorTitle; - data['Gender'] = this.gender; - data['GenderDescription'] = this.genderDescription; - data['IsActiveDoctorProfile'] = this.isActiveDoctorProfile; - data['IsDoctorAllowVedioCall'] = this.isDoctorAllowVedioCall; - data['IsExecludeDoctor'] = this.isExecludeDoctor; - data['IsInOutPatient'] = this.isInOutPatient; - data['IsInOutPatientDescription'] = this.isInOutPatientDescription; - data['IsInOutPatientDescriptionN'] = this.isInOutPatientDescriptionN; - data['IsInsurancePatient'] = this.isInsurancePatient; - data['NationalityFlagURL'] = this.nationalityFlagURL; - data['NoOfPatientsRate'] = this.noOfPatientsRate; - data['QR'] = this.qR; - data['Speciality'] = this.speciality; - return data; - } -} - -//class PrescriptionsList { -// String filterName = ""; -// List prescriptionsList = List(); -// -// PrescriptionsList({this.filterName, Prescriptions prescriptions}) { -// prescriptionsList.add(prescriptions); -// } -//} diff --git a/lib/core/model/pharmacies/Reviews.dart b/lib/core/model/pharmacies/Reviews.dart index 2c767cdd..47975cdd 100644 --- a/lib/core/model/pharmacies/Reviews.dart +++ b/lib/core/model/pharmacies/Reviews.dart @@ -1,22 +1,22 @@ import '../pharmacies/Customer.dart'; class Reviews { - int id; - int position; - int reviewId; - int customerId; - int productId; - int storeId; - bool isApproved; - String title; - String reviewText; - String replyText; - int rating; - int helpfulYesTotal; - int helpfulNoTotal; - String createdOnUtc; - Customer customer; - //Null product; + int? id; + int? position; + int? reviewId; + int? customerId; + int? productId; + int? storeId; + bool? isApproved; + String? title; + String? reviewText; + String? replyText; + int? rating; + int? helpfulYesTotal; + int? helpfulNoTotal; + String? createdOnUtc; + Customer? customer; + //dynamic product; Reviews( {this.id, @@ -75,7 +75,7 @@ class Reviews { data['helpful_no_total'] = this.helpfulNoTotal; data['created_on_utc'] = this.createdOnUtc; if (this.customer != null) { - data['customer'] = this.customer.toJson(); + data['customer'] = this.customer!.toJson(); } // data['product'] = this.product; return data; diff --git a/lib/core/model/pharmacies/ShippingOption.dart b/lib/core/model/pharmacies/ShippingOption.dart index 1b589537..4b161b4c 100644 --- a/lib/core/model/pharmacies/ShippingOption.dart +++ b/lib/core/model/pharmacies/ShippingOption.dart @@ -1,48 +1,48 @@ class ShippingOption { - String shippingRateComputationMethodSystemName; - double rate; - double rateVat; - double rateVatPercent; - String name; - String namen; - String description; - String descriptionn; - bool allowShippingSunday; - bool allowShippingMonday; - bool allowShippingTuesday; - bool allowShippingWednesday; - bool allowShippingThursday; - bool allowShippingFriday; - bool allowShippingSaturday; - String allowShippingTime1From; - String allowShippingTime1To; - String allowShippingTime2From; - String allowShippingTime2To; - String allowShippingNote; - String allowShippingNoten; + String? shippingRateComputationMethodSystemName; + double? rate; + double? rateVat; + double? rateVatPercent; + String? name; + String? namen; + String? description; + String? descriptionn; + bool? allowShippingSunday; + bool? allowShippingMonday; + bool? allowShippingTuesday; + bool? allowShippingWednesday; + bool? allowShippingThursday; + bool? allowShippingFriday; + bool? allowShippingSaturday; + String? allowShippingTime1From; + String? allowShippingTime1To; + String? allowShippingTime2From; + String? allowShippingTime2To; + String? allowShippingNote; + String? allowShippingNoten; ShippingOption( {this.shippingRateComputationMethodSystemName, - this.rate, - this.rateVat, - this.rateVatPercent, - this.name, - this.namen, - this.description, - this.descriptionn, - this.allowShippingSunday, - this.allowShippingMonday, - this.allowShippingTuesday, - this.allowShippingWednesday, - this.allowShippingThursday, - this.allowShippingFriday, - this.allowShippingSaturday, - this.allowShippingTime1From, - this.allowShippingTime1To, - this.allowShippingTime2From, - this.allowShippingTime2To, - this.allowShippingNote, - this.allowShippingNoten}); + this.rate, + this.rateVat, + this.rateVatPercent, + this.name, + this.namen, + this.description, + this.descriptionn, + this.allowShippingSunday, + this.allowShippingMonday, + this.allowShippingTuesday, + this.allowShippingWednesday, + this.allowShippingThursday, + this.allowShippingFriday, + this.allowShippingSaturday, + this.allowShippingTime1From, + this.allowShippingTime1To, + this.allowShippingTime2From, + this.allowShippingTime2To, + this.allowShippingNote, + this.allowShippingNoten}); ShippingOption.fromJson(Map json) { shippingRateComputationMethodSystemName = json['shipping_rate_computation_method_system_name']; @@ -70,8 +70,7 @@ class ShippingOption { Map toJson() { final Map data = new Map(); - data['shipping_rate_computation_method_system_name'] = - this.shippingRateComputationMethodSystemName; + data['shipping_rate_computation_method_system_name'] = this.shippingRateComputationMethodSystemName; data['rate'] = this.rate; data['rate_vat'] = this.rateVat; data['rate_vat_percent'] = this.rateVatPercent; diff --git a/lib/core/model/pharmacies/ShoppingCart.dart b/lib/core/model/pharmacies/ShoppingCart.dart index 4bd460aa..09629352 100644 --- a/lib/core/model/pharmacies/ShoppingCart.dart +++ b/lib/core/model/pharmacies/ShoppingCart.dart @@ -2,11 +2,11 @@ import 'package:diplomaticquarterapp/core/model/pharmacies/Customer.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; class ShoppingCart { - int languageId; - String id; - // List productAttributes; - double customerEnteredPrice; - int quantity; + int? languageId; + String? id; + // List productAttributes; + double? customerEnteredPrice; + int? quantity; dynamic discountAmountInclTax; dynamic subtotal; dynamic subtotalWithVat; @@ -19,21 +19,21 @@ class ShoppingCart { dynamic createdOnUtc; dynamic updatedOnUtc; dynamic shoppingCartType; - int productId; - PharmacyProduct product; - int customerId; - Customer customer; - double unitPriceInclTax; - double unitPriceExclTax; - double priceInclTax; - double priceExclTax; + int? productId; + PharmacyProduct? product; + int? customerId; + Customer? customer; + double? unitPriceInclTax; + double? unitPriceExclTax; + double? priceInclTax; + double? priceExclTax; dynamic discountAmountExclTax; - double originalProductCost; - String attributeDescription; - int downloadCount; - bool isDownloadActivated; - int licenseDownloadId; - double itemWeight; + double? originalProductCost; + String? attributeDescription; + int? downloadCount; + bool? isDownloadActivated; + int? licenseDownloadId; + double? itemWeight; ShoppingCart( {this.languageId, @@ -74,9 +74,9 @@ class ShoppingCart { languageId = json['language_id']; id = json['id']; /*if (json['product_attributes'] != null) { - productAttributes = new List(); + productAttributes = new List(); json['product_attributes'].forEach((v) { - productAttributes.add(new Null.fromJson(v)); + productAttributes.add(new dynamic.fromJson(v)); }); }*/ customerEnteredPrice = json['customer_entered_price']; @@ -139,11 +139,11 @@ class ShoppingCart { data['shopping_cart_type'] = this.shoppingCartType; data['product_id'] = this.productId; if (this.product != null) { - data['product'] = this.product.toJson(); + data['product'] = this.product!.toJson(); } data['customer_id'] = this.customerId; if (this.customer != null) { - data['customer'] = this.customer.toJson(); + data['customer'] = this.customer!.toJson(); } data['unit_price_incl_tax'] = this.unitPriceInclTax; data['unit_price_excl_tax'] = this.unitPriceExclTax; diff --git a/lib/core/model/pharmacies/ShoppingCartResponse.dart b/lib/core/model/pharmacies/ShoppingCartResponse.dart index 96b751ae..ff0ed1ae 100644 --- a/lib/core/model/pharmacies/ShoppingCartResponse.dart +++ b/lib/core/model/pharmacies/ShoppingCartResponse.dart @@ -1,27 +1,27 @@ import 'package:diplomaticquarterapp/core/model/pharmacies/ShoppingCart.dart'; import 'package:flutter/material.dart'; -class ShoppingCartResponse with ChangeNotifier { - int itemCount; - int quantityCount; - double subtotal; - double subtotalWithVat; - double subtotalVatAmount; - double subtotalVatRate; - List shoppingCarts; +class ShoppingCartResponse { + int? itemCount; + int? quantityCount; + double? subtotal; + double? subtotalWithVat; + double? subtotalVatAmount; + double? subtotalVatRate; + double? totalAmount; + List? shoppingCarts; ShoppingCartResponse( - {this.itemCount, - this.quantityCount, - this.subtotal, - this.subtotalWithVat, - this.subtotalVatAmount, - this.subtotalVatRate, + {this.itemCount =0, + this.quantityCount =0, + this.subtotal=0.0, + this.subtotalWithVat = 0.0, + this.subtotalVatAmount = 0.0, + this.subtotalVatRate = 0.0, + this.totalAmount = 0.0, this.shoppingCarts}); - void updateShoppingCard() { - notifyListeners(); - } + ShoppingCartResponse.fromJson(Map json) { itemCount = json['item_count']; @@ -31,9 +31,9 @@ class ShoppingCartResponse with ChangeNotifier { subtotalVatAmount = json['subtotal_vat_amount']; subtotalVatRate = json['subtotal_vat_rate']; if (json['shopping_carts'] != null) { - shoppingCarts = new List(); + shoppingCarts = []; json['shopping_carts'].forEach((v) { - shoppingCarts.add(new ShoppingCart.fromJson(v)); + shoppingCarts!.add(new ShoppingCart.fromJson(v)); }); } } @@ -48,7 +48,7 @@ class ShoppingCartResponse with ChangeNotifier { data['subtotal_vat_rate'] = this.subtotalVatRate; if (this.shoppingCarts != null) { data['shopping_carts'] = - this.shoppingCarts.map((v) => v.toJson()).toList(); + this.shoppingCarts!.map((v) => v.toJson()).toList(); } return data; } diff --git a/lib/core/model/pharmacies/Specifications.dart b/lib/core/model/pharmacies/Specifications.dart index f227de69..30a4a7cd 100644 --- a/lib/core/model/pharmacies/Specifications.dart +++ b/lib/core/model/pharmacies/Specifications.dart @@ -1,10 +1,10 @@ class Specifications { - int id; - int displayOrder; - String defaultValue; - String defaultValuen; - String name; - String nameN; + dynamic id; + dynamic displayOrder; + dynamic defaultValue; + dynamic defaultValuen; + dynamic name; + dynamic nameN; Specifications( {this.id, diff --git a/lib/core/model/pharmacies/order_detail.dart b/lib/core/model/pharmacies/order_detail.dart index 74e89295..d6a6dd70 100644 --- a/lib/core/model/pharmacies/order_detail.dart +++ b/lib/core/model/pharmacies/order_detail.dart @@ -3,37 +3,37 @@ import 'package:diplomaticquarterapp/core/model/pharmacies/Customer.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/ShoppingCart.dart'; class OrderDetailModel { - String id; - int storeId; - String orderGuid; - bool pickUpInStore; - String paymentMethodSystemName; - String paymentName; - String paymentNamen; - String customerCurrencyCode; + String? id; + int? storeId; + String? orderGuid; + bool? pickUpInStore; + String? paymentMethodSystemName; + String? paymentName; + String? paymentNamen; + String? customerCurrencyCode; dynamic currencyRate; dynamic customerTaxDisplayTypeId; dynamic vatNumber; - double orderSubtotalInclTax; - double orderSubtotalExclTax; + double? orderSubtotalInclTax; + double? orderSubtotalExclTax; dynamic orderSubTotalDiscountInclTax; dynamic orderSubTotalDiscountExclTax; - double orderShippingInclTax; + double? orderShippingInclTax; dynamic orderShippingExclTax; dynamic paymentMethodAdditionalFeeInclTax; dynamic paymentMethodAdditionalFeeExclTax; - String taxRates; - double orderTax; + String? taxRates; + double? orderTax; dynamic orderDiscount; dynamic productCount; dynamic orderTotal; dynamic refundedAmount; dynamic rewardPointsWereAdded; dynamic rxAttachments; - String checkoutAttributeDescription; - int customerLanguageId; - int affiliateId; - String customerIp; + String? checkoutAttributeDescription; + int? customerLanguageId; + int? affiliateId; + String? customerIp; dynamic authorizationTransactionId; dynamic authorizationTransactionCode; dynamic authorizationTransactionResult; @@ -41,100 +41,101 @@ class OrderDetailModel { dynamic captureTransactionResult; dynamic subscriptionTransactionId; dynamic paidDateUtc; - String shippingMethod; - String shippingRateComputationMethodSystemName; - String customValuesXml; - bool deleted; - String createdOnUtc; - Customer customer; - int customerId; - BillingAddress billingAddress; - BillingAddress shippingAddress; - List orderItems; - int orderStatusId; - String orderStatus; - String orderStatusn; - int paymentStatusId; - String paymentStatus; - String paymentStatusn; - String shippingStatus; - String shippingStatusn; - String customerTaxDisplayType; - bool canCancel; - bool canRefund; + String? shippingMethod; + String? shippingRateComputationMethodSystemName; + String? customValuesXml; + bool? deleted; + String? createdOnUtc; + Customer? customer; + int? customerId; + BillingAddress? billingAddress; + BillingAddress? shippingAddress; + List? orderItems; + int? orderStatusId; + String? orderStatus; + String? orderStatusn; + int? paymentStatusId; + String? paymentStatus; + String? paymentStatusn; + String? shippingStatus; + String? shippingStatusn; + String? customerTaxDisplayType; + bool? canCancel; + bool? canRefund; dynamic lakumAmount; - String preferDeliveryDate; - String preferDeliveryTime; - String preferDeliveryTimen; - String driverOTP; - String driverID; + String? preferDeliveryDate; + String? preferDeliveryTime; + String? preferDeliveryTimen; + String? driverOTP; + String? driverID; - OrderDetailModel( - {this.id, - this.storeId, - this.orderGuid, - this.pickUpInStore, - this.paymentMethodSystemName, - this.paymentName, - this.paymentNamen, - this.customerCurrencyCode, - this.currencyRate, - this.customerTaxDisplayTypeId, - this.vatNumber, - this.orderSubtotalInclTax, - this.orderSubtotalExclTax, - this.orderSubTotalDiscountInclTax, - this.orderSubTotalDiscountExclTax, - this.orderShippingInclTax, - this.orderShippingExclTax, - this.paymentMethodAdditionalFeeInclTax, - this.paymentMethodAdditionalFeeExclTax, - this.taxRates, - this.orderTax, - this.orderDiscount, - this.productCount, - this.orderTotal, - this.refundedAmount, - this.rewardPointsWereAdded, - this.rxAttachments, - this.checkoutAttributeDescription, - this.customerLanguageId, - this.affiliateId, - this.customerIp, - this.authorizationTransactionId, - this.authorizationTransactionCode, - this.authorizationTransactionResult, - this.captureTransactionId, - this.captureTransactionResult, - this.subscriptionTransactionId, - this.paidDateUtc, - this.shippingMethod, - this.shippingRateComputationMethodSystemName, - this.customValuesXml, - this.deleted, - this.createdOnUtc, - this.customer, - this.customerId, - this.billingAddress, - this.shippingAddress, - this.orderItems, - this.orderStatusId, - this.orderStatus, - this.orderStatusn, - this.paymentStatusId, - this.paymentStatus, - this.paymentStatusn, - this.shippingStatus, - this.shippingStatusn, - this.customerTaxDisplayType, - this.canCancel, - this.canRefund, - this.lakumAmount, - this.preferDeliveryDate, - this.preferDeliveryTime, - this.preferDeliveryTimen, - this.driverID, - this.driverOTP,}); + OrderDetailModel({ + this.id, + this.storeId, + this.orderGuid, + this.pickUpInStore, + this.paymentMethodSystemName, + this.paymentName, + this.paymentNamen, + this.customerCurrencyCode, + this.currencyRate, + this.customerTaxDisplayTypeId, + this.vatNumber, + this.orderSubtotalInclTax, + this.orderSubtotalExclTax, + this.orderSubTotalDiscountInclTax, + this.orderSubTotalDiscountExclTax, + this.orderShippingInclTax, + this.orderShippingExclTax, + this.paymentMethodAdditionalFeeInclTax, + this.paymentMethodAdditionalFeeExclTax, + this.taxRates, + this.orderTax, + this.orderDiscount, + this.productCount, + this.orderTotal, + this.refundedAmount, + this.rewardPointsWereAdded, + this.rxAttachments, + this.checkoutAttributeDescription, + this.customerLanguageId, + this.affiliateId, + this.customerIp, + this.authorizationTransactionId, + this.authorizationTransactionCode, + this.authorizationTransactionResult, + this.captureTransactionId, + this.captureTransactionResult, + this.subscriptionTransactionId, + this.paidDateUtc, + this.shippingMethod, + this.shippingRateComputationMethodSystemName, + this.customValuesXml, + this.deleted, + this.createdOnUtc, + this.customer, + this.customerId, + this.billingAddress, + this.shippingAddress, + this.orderItems, + this.orderStatusId, + this.orderStatus, + this.orderStatusn, + this.paymentStatusId, + this.paymentStatus, + this.paymentStatusn, + this.shippingStatus, + this.shippingStatusn, + this.customerTaxDisplayType, + this.canCancel, + this.canRefund, + this.lakumAmount, + this.preferDeliveryDate, + this.preferDeliveryTime, + this.preferDeliveryTimen, + this.driverID, + this.driverOTP, + }); OrderDetailModel.fromJson(Map json) { id = json['id']; @@ -154,10 +155,8 @@ class OrderDetailModel { orderSubTotalDiscountExclTax = json['order_sub_total_discount_excl_tax']; orderShippingInclTax = json['order_shipping_incl_tax']; orderShippingExclTax = json['order_shipping_excl_tax']; - paymentMethodAdditionalFeeInclTax = - json['payment_method_additional_fee_incl_tax']; - paymentMethodAdditionalFeeExclTax = - json['payment_method_additional_fee_excl_tax']; + paymentMethodAdditionalFeeInclTax = json['payment_method_additional_fee_incl_tax']; + paymentMethodAdditionalFeeExclTax = json['payment_method_additional_fee_excl_tax']; taxRates = json['tax_rates']; orderTax = json['order_tax']; orderDiscount = json['order_discount']; @@ -178,25 +177,18 @@ class OrderDetailModel { subscriptionTransactionId = json['subscription_transaction_id']; paidDateUtc = json['paid_date_utc']; shippingMethod = json['shipping_method']; - shippingRateComputationMethodSystemName = - json['shipping_rate_computation_method_system_name']; + shippingRateComputationMethodSystemName = json['shipping_rate_computation_method_system_name']; customValuesXml = json['custom_values_xml']; deleted = json['deleted']; createdOnUtc = json['created_on_utc']; - customer = json['customer'] != null - ? new Customer.fromJson(json['customer']) - : null; + customer = json['customer'] != null ? new Customer.fromJson(json['customer']) : null; customerId = json['customer_id']; - billingAddress = json['billing_address'] != null - ? new BillingAddress.fromJson(json['billing_address']) - : null; - shippingAddress = json['shipping_address'] != null - ? new BillingAddress.fromJson(json['shipping_address']) - : null; + billingAddress = json['billing_address'] != null ? new BillingAddress.fromJson(json['billing_address']) : null; + shippingAddress = json['shipping_address'] != null ? new BillingAddress.fromJson(json['shipping_address']) : null; if (json['order_items'] != null) { - orderItems = new List(); + orderItems = []; json['order_items'].forEach((v) { - orderItems.add(new ShoppingCart.fromJson(v)); + orderItems!.add(new ShoppingCart.fromJson(v)); }); } orderStatusId = json['order_status_id']; @@ -216,8 +208,10 @@ class OrderDetailModel { preferDeliveryTimen = json['prefer_delivery_timen']; // Driver Detail - driverID: json["DriverID"]; - driverOTP: json["DriverOTP"]; + driverID: + json["DriverID"]; + driverOTP: + json["DriverOTP"]; } Map toJson() { @@ -235,16 +229,12 @@ class OrderDetailModel { data['vat_number'] = this.vatNumber; data['order_subtotal_incl_tax'] = this.orderSubtotalInclTax; data['order_subtotal_excl_tax'] = this.orderSubtotalExclTax; - data['order_sub_total_discount_incl_tax'] = - this.orderSubTotalDiscountInclTax; - data['order_sub_total_discount_excl_tax'] = - this.orderSubTotalDiscountExclTax; + data['order_sub_total_discount_incl_tax'] = this.orderSubTotalDiscountInclTax; + data['order_sub_total_discount_excl_tax'] = this.orderSubTotalDiscountExclTax; data['order_shipping_incl_tax'] = this.orderShippingInclTax; data['order_shipping_excl_tax'] = this.orderShippingExclTax; - data['payment_method_additional_fee_incl_tax'] = - this.paymentMethodAdditionalFeeInclTax; - data['payment_method_additional_fee_excl_tax'] = - this.paymentMethodAdditionalFeeExclTax; + data['payment_method_additional_fee_incl_tax'] = this.paymentMethodAdditionalFeeInclTax; + data['payment_method_additional_fee_excl_tax'] = this.paymentMethodAdditionalFeeExclTax; data['tax_rates'] = this.taxRates; data['order_tax'] = this.orderTax; data['order_discount'] = this.orderDiscount; @@ -259,30 +249,28 @@ class OrderDetailModel { data['customer_ip'] = this.customerIp; data['authorization_transaction_id'] = this.authorizationTransactionId; data['authorization_transaction_code'] = this.authorizationTransactionCode; - data['authorization_transaction_result'] = - this.authorizationTransactionResult; + data['authorization_transaction_result'] = this.authorizationTransactionResult; data['capture_transaction_id'] = this.captureTransactionId; data['capture_transaction_result'] = this.captureTransactionResult; data['subscription_transaction_id'] = this.subscriptionTransactionId; data['paid_date_utc'] = this.paidDateUtc; data['shipping_method'] = this.shippingMethod; - data['shipping_rate_computation_method_system_name'] = - this.shippingRateComputationMethodSystemName; + data['shipping_rate_computation_method_system_name'] = this.shippingRateComputationMethodSystemName; data['custom_values_xml'] = this.customValuesXml; data['deleted'] = this.deleted; data['created_on_utc'] = this.createdOnUtc; if (this.customer != null) { - data['customer'] = this.customer.toJson(); + data['customer'] = this.customer!.toJson(); } data['customer_id'] = this.customerId; if (this.billingAddress != null) { - data['billing_address'] = this.billingAddress.toJson(); + data['billing_address'] = this.billingAddress!.toJson(); } if (this.shippingAddress != null) { - data['shipping_address'] = this.shippingAddress.toJson(); + data['shipping_address'] = this.shippingAddress!.toJson(); } if (this.orderItems != null) { - data['order_items'] = this.orderItems.map((v) => v.toJson()).toList(); + data['order_items'] = this.orderItems!.map((v) => v.toJson()).toList(); } data['order_status_id'] = this.orderStatusId; data['order_status'] = this.orderStatus; @@ -301,5 +289,4 @@ class OrderDetailModel { data['prefer_delivery_timen'] = this.preferDeliveryTimen; return data; } - -} \ No newline at end of file +} diff --git a/lib/core/model/pharmacies/order_model.dart b/lib/core/model/pharmacies/order_model.dart index d025faa6..005d9337 100644 --- a/lib/core/model/pharmacies/order_model.dart +++ b/lib/core/model/pharmacies/order_model.dart @@ -1,4 +1,3 @@ - import 'dart:convert'; import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyImageObject.dart'; @@ -9,72 +8,71 @@ List orderModelFromJson(String str) => List.from(json.de String orderModelToJson(List data) => json.encode(List.from(data.map((x) => x.toJson()))); class OrderModel { - - String id; + String? id; dynamic storeId; - String orderGuid; - bool pickUpInStore; - PaymentMethodSystemName paymentMethodSystemName; - PaymentName paymentName; - PaymentName paymentNamen; - CustomerCurrencyCode customerCurrencyCode; + String? orderGuid; + bool? pickUpInStore; + PaymentMethodSystemName? paymentMethodSystemName; + PaymentName? paymentName; + PaymentName? paymentNamen; + CustomerCurrencyCode? customerCurrencyCode; dynamic currencyRate; dynamic customerTaxDisplayTypeId; dynamic vatNumber; - double orderSubtotalInclTax; - double orderSubtotalExclTax; + double? orderSubtotalInclTax; + double? orderSubtotalExclTax; dynamic orderSubTotalDiscountInclTax; dynamic orderSubTotalDiscountExclTax; - double orderShippingInclTax; + double? orderShippingInclTax; dynamic orderShippingExclTax; dynamic paymentMethodAdditionalFeeInclTax; dynamic paymentMethodAdditionalFeeExclTax; - String taxRates; - double orderTax; + String? taxRates; + double? orderTax; dynamic orderDiscount; dynamic productCount; - double orderTotal; + double? orderTotal; dynamic refundedAmount; dynamic rewardPointsWereAdded; - String rxAttachments; - CheckoutAttributeDescription checkoutAttributeDescription; + String? rxAttachments; + CheckoutAttributeDescription? checkoutAttributeDescription; dynamic customerLanguageId; dynamic affiliateId; - CustomerIp customerIp; - String authorizationTransactionId; + CustomerIp? customerIp; + String? authorizationTransactionId; dynamic authorizationTransactionCode; dynamic authorizationTransactionResult; dynamic captureTransactionId; dynamic captureTransactionResult; dynamic subscriptionTransactionId; - DateTime paidDateUtc; - ShippingMethod shippingMethod; - ShippingRateComputationMethodSystemName shippingRateComputationMethodSystemName; - String customValuesXml; - bool deleted; - DateTime createdOnUtc; - OrderModelCustomer customer; + DateTime? paidDateUtc; + ShippingMethod? shippingMethod; + ShippingRateComputationMethodSystemName? shippingRateComputationMethodSystemName; + String? customValuesXml; + bool? deleted; + DateTime? createdOnUtc; + OrderModelCustomer? customer; dynamic customerId; - IngAddress billingAddress; - IngAddress shippingAddress; - List orderItems; + IngAddress? billingAddress; + IngAddress? shippingAddress; + List? orderItems; dynamic orderStatusId; - OrderStatus orderStatus; - OrderStatusn orderStatusn; + OrderStatus? orderStatus; + OrderStatusn? orderStatusn; dynamic paymentStatusId; - PaymentStatus paymentStatus; - PaymentStatusn paymentStatusn; - ShippingStatus shippingStatus; - ShippingStatusn shippingStatusn; - CustomerTaxDisplayType customerTaxDisplayType; - bool canCancel; - bool canRefund; + PaymentStatus? paymentStatus; + PaymentStatusn? paymentStatusn; + ShippingStatus? shippingStatus; + ShippingStatusn? shippingStatusn; + CustomerTaxDisplayType? customerTaxDisplayType; + bool? canCancel; + bool? canRefund; dynamic lakumAmount; - DateTime preferDeliveryDate; - PreferDeliveryTime preferDeliveryTime; - PreferDeliveryTimen preferDeliveryTimen; - String driverOTP; - String driverID; + DateTime? preferDeliveryDate; + PreferDeliveryTime? preferDeliveryTime; + PreferDeliveryTimen? preferDeliveryTimen; + String? driverOTP; + String? driverID; OrderModel({ this.id, @@ -145,140 +143,141 @@ class OrderModel { }); factory OrderModel.fromJson(Map json) => OrderModel( - id: json["id"], - storeId: json["store_id"], - orderGuid: json["order_guid"], - pickUpInStore: json["pick_up_in_store"], - paymentMethodSystemName: paymentMethodSystemNameValues.map[json["payment_method_system_name"]], - paymentName: paymentNameValues.map[json["payment_name"]], - paymentNamen: paymentNameValues.map[json["payment_namen"]], - customerCurrencyCode: customerCurrencyCodeValues.map[json["customer_currency_code"]], - currencyRate: json["currency_rate"], - customerTaxDisplayTypeId: json["customer_tax_display_type_id"], - vatNumber: json["vat_number"], - orderSubtotalInclTax: json["order_subtotal_incl_tax"].toDouble(), - orderSubtotalExclTax: json["order_subtotal_excl_tax"].toDouble(), - orderSubTotalDiscountInclTax: json["order_sub_total_discount_incl_tax"], - orderSubTotalDiscountExclTax: json["order_sub_total_discount_excl_tax"], - orderShippingInclTax: json["order_shipping_incl_tax"].toDouble(), - orderShippingExclTax: json["order_shipping_excl_tax"], - paymentMethodAdditionalFeeInclTax: json["payment_method_additional_fee_incl_tax"], - paymentMethodAdditionalFeeExclTax: json["payment_method_additional_fee_excl_tax"], - taxRates: json["tax_rates"], - orderTax: json["order_tax"].toDouble(), - orderDiscount: json["order_discount"], - productCount: json["product_count"], - orderTotal: json["order_total"].toDouble(), - refundedAmount: json["refunded_amount"], - rewardPointsWereAdded: json["reward_points_were_added"], - rxAttachments: json["rx_attachments"] == null ? null : json["rx_attachments"], - checkoutAttributeDescription: checkoutAttributeDescriptionValues.map[json["checkout_attribute_description"]], - customerLanguageId: json["customer_language_id"], - affiliateId: json["affiliate_id"], - customerIp: customerIpValues.map[json["customer_ip"]], - authorizationTransactionId: json["authorization_transaction_id"] == null ? null : json["authorization_transaction_id"], - authorizationTransactionCode: json["authorization_transaction_code"], - authorizationTransactionResult: json["authorization_transaction_result"], - captureTransactionId: json["capture_transaction_id"], - captureTransactionResult: json["capture_transaction_result"], - subscriptionTransactionId: json["subscription_transaction_id"], - paidDateUtc: json["paid_date_utc"] == null ? null : DateTime.parse(json["paid_date_utc"]), - shippingMethod: shippingMethodValues.map[json["shipping_method"]], - shippingRateComputationMethodSystemName: shippingRateComputationMethodSystemNameValues.map[json["shipping_rate_computation_method_system_name"]], - customValuesXml: json["custom_values_xml"], - deleted: json["deleted"], - createdOnUtc: DateTime.parse(json["created_on_utc"]), - customer: OrderModelCustomer.fromJson(json["customer"]), - customerId: json["customer_id"], - billingAddress: IngAddress.fromJson(json["billing_address"]), - shippingAddress: IngAddress.fromJson(json["shipping_address"]), - orderItems: List.from(json["order_items"].map((x) => OrderItem.fromJson(x))), - orderStatusId: json["order_status_id"], - orderStatus: orderStatusValues.map[json["order_status"]], - orderStatusn: orderStatusnValues.map[json["order_statusn"]], - paymentStatusId: json["payment_status_id"], - paymentStatus: paymentStatusValues.map[json["payment_status"]], - paymentStatusn: paymentStatusnValues.map[json["payment_statusn"]], - shippingStatus: shippingStatusValues.map[json["shipping_status"]], - shippingStatusn: shippingStatusnValues.map[json["shipping_statusn"]], - customerTaxDisplayType: customerTaxDisplayTypeValues.map[json["customer_tax_display_type"]], - canCancel: json["can_cancel"], - canRefund: json["can_refund"], - lakumAmount: json["lakum_amount"], - preferDeliveryDate: json["prefer_delivery_date"] == null ? null : DateTime.parse(json["prefer_delivery_date"]), - preferDeliveryTime: json["prefer_delivery_time"] == null ? null : preferDeliveryTimeValues.map[json["prefer_delivery_time"]], - preferDeliveryTimen: json["prefer_delivery_timen"] == null ? null : preferDeliveryTimenValues.map[json["prefer_delivery_timen"]], - - // Driver Detail - driverID: json["DriverID"], - driverOTP: json["DriverOTP"], - - ); + id: json["id"], + storeId: json["store_id"], + orderGuid: json["order_guid"], + pickUpInStore: json["pick_up_in_store"], + paymentMethodSystemName: paymentMethodSystemNameValues.map![json["payment_method_system_name"]], + paymentName: paymentNameValues.map![json["payment_name"]], + paymentNamen: paymentNameValues.map![json["payment_namen"]], + customerCurrencyCode: customerCurrencyCodeValues.map![json["customer_currency_code"]], + currencyRate: json["currency_rate"], + customerTaxDisplayTypeId: json["customer_tax_display_type_id"], + vatNumber: json["vat_number"], + orderSubtotalInclTax: json["order_subtotal_incl_tax"].toDouble(), + orderSubtotalExclTax: json["order_subtotal_excl_tax"].toDouble(), + orderSubTotalDiscountInclTax: json["order_sub_total_discount_incl_tax"], + orderSubTotalDiscountExclTax: json["order_sub_total_discount_excl_tax"], + orderShippingInclTax: json["order_shipping_incl_tax"].toDouble(), + orderShippingExclTax: json["order_shipping_excl_tax"], + paymentMethodAdditionalFeeInclTax: json["payment_method_additional_fee_incl_tax"], + paymentMethodAdditionalFeeExclTax: json["payment_method_additional_fee_excl_tax"], + taxRates: json["tax_rates"], + orderTax: json["order_tax"].toDouble(), + orderDiscount: json["order_discount"], + productCount: json["product_count"], + orderTotal: json["order_total"].toDouble(), + refundedAmount: json["refunded_amount"], + rewardPointsWereAdded: json["reward_points_were_added"], + rxAttachments: json["rx_attachments"] == null ? null : json["rx_attachments"], + checkoutAttributeDescription: checkoutAttributeDescriptionValues.map![json["checkout_attribute_description"]], + customerLanguageId: json["customer_language_id"], + affiliateId: json["affiliate_id"], + customerIp: customerIpValues.map![json["customer_ip"]], + authorizationTransactionId: json["authorization_transaction_id"] == null ? null : json["authorization_transaction_id"], + authorizationTransactionCode: json["authorization_transaction_code"], + authorizationTransactionResult: json["authorization_transaction_result"], + captureTransactionId: json["capture_transaction_id"], + captureTransactionResult: json["capture_transaction_result"], + subscriptionTransactionId: json["subscription_transaction_id"], + paidDateUtc: json["paid_date_utc"] == null ? null : DateTime.parse(json["paid_date_utc"]), + shippingMethod: shippingMethodValues.map![json["shipping_method"]], + shippingRateComputationMethodSystemName: shippingRateComputationMethodSystemNameValues.map![json["shipping_rate_computation_method_system_name"]], + customValuesXml: json["custom_values_xml"], + deleted: json["deleted"], + createdOnUtc: DateTime.parse(json["created_on_utc"]), + customer: OrderModelCustomer.fromJson(json["customer"]), + customerId: json["customer_id"], + billingAddress: IngAddress.fromJson(json["billing_address"]), + shippingAddress: IngAddress.fromJson(json["shipping_address"]), + orderItems: List.from(json["order_items"].map((x) => OrderItem.fromJson(x))), + orderStatusId: json["order_status_id"], + orderStatus: orderStatusValues.map![json["order_status"]], + orderStatusn: orderStatusnValues.map![json["order_statusn"]], + paymentStatusId: json["payment_status_id"], + paymentStatus: paymentStatusValues.map![json["payment_status"]], + paymentStatusn: paymentStatusnValues.map![json["payment_statusn"]], + shippingStatus: shippingStatusValues.map![json["shipping_status"]], + shippingStatusn: shippingStatusnValues.map![json["shipping_statusn"]], + customerTaxDisplayType: customerTaxDisplayTypeValues.map![json["customer_tax_display_type"]], + canCancel: json["can_cancel"], + canRefund: json["can_refund"], + lakumAmount: json["lakum_amount"], + preferDeliveryDate: json["prefer_delivery_date"] == null ? null : DateTime.parse(json["prefer_delivery_date"]), + preferDeliveryTime: json["prefer_delivery_time"] == null ? null : preferDeliveryTimeValues.map![json["prefer_delivery_time"]], + preferDeliveryTimen: json["prefer_delivery_timen"] == null ? null : preferDeliveryTimenValues.map![json["prefer_delivery_timen"]], + + // Driver Detail + driverID: json["DriverID"], + driverOTP: json["DriverOTP"], + ); Map toJson() => { - "id": id, - "store_id": storeId, - "order_guid": orderGuid, - "pick_up_in_store": pickUpInStore, - "payment_method_system_name": paymentMethodSystemNameValues.reverse[paymentMethodSystemName], - "payment_name": paymentNameValues.reverse[paymentName], - "payment_namen": paymentNameValues.reverse[paymentNamen], - "customer_currency_code": customerCurrencyCodeValues.reverse[customerCurrencyCode], - "currency_rate": currencyRate, - "customer_tax_display_type_id": customerTaxDisplayTypeId, - "vat_number": vatNumber, - "order_subtotal_incl_tax": orderSubtotalInclTax, - "order_subtotal_excl_tax": orderSubtotalExclTax, - "order_sub_total_discount_incl_tax": orderSubTotalDiscountInclTax, - "order_sub_total_discount_excl_tax": orderSubTotalDiscountExclTax, - "order_shipping_incl_tax": orderShippingInclTax, - "order_shipping_excl_tax": orderShippingExclTax, - "payment_method_additional_fee_incl_tax": paymentMethodAdditionalFeeInclTax, - "payment_method_additional_fee_excl_tax": paymentMethodAdditionalFeeExclTax, - "tax_rates": taxRates, - "order_tax": orderTax, - "order_discount": orderDiscount, - "order_total": orderTotal, - "refunded_amount": refundedAmount, - "reward_points_were_added": rewardPointsWereAdded, - "rx_attachments": rxAttachments == null ? null : rxAttachments, - "checkout_attribute_description": checkoutAttributeDescriptionValues.reverse[checkoutAttributeDescription], - "customer_language_id": customerLanguageId, - "affiliate_id": affiliateId, - "customer_ip": customerIpValues.reverse[customerIp], - "authorization_transaction_id": authorizationTransactionId == null ? null : authorizationTransactionId, - "authorization_transaction_code": authorizationTransactionCode, - "authorization_transaction_result": authorizationTransactionResult, - "capture_transaction_id": captureTransactionId, - "capture_transaction_result": captureTransactionResult, - "subscription_transaction_id": subscriptionTransactionId, - "paid_date_utc": paidDateUtc == null ? null : paidDateUtc.toIso8601String(), - "shipping_method": shippingMethodValues.reverse[shippingMethod], - "shipping_rate_computation_method_system_name": shippingRateComputationMethodSystemNameValues.reverse[shippingRateComputationMethodSystemName], - "custom_values_xml": customValuesXml, - "deleted": deleted, - "created_on_utc": createdOnUtc.toIso8601String(), - "customer": customer.toJson(), - "customer_id": customerId, - "billing_address": billingAddress.toJson(), - "shipping_address": shippingAddress.toJson(), - "order_items": List.from(orderItems.map((x) => x.toJson())), - "order_status_id": orderStatusId, - "order_status": orderStatusValues.reverse[orderStatus], - "order_statusn": orderStatusnValues.reverse[orderStatusn], - "payment_status_id": paymentStatusId, - "payment_status": paymentStatusValues.reverse[paymentStatus], - "payment_statusn": paymentStatusnValues.reverse[paymentStatusn], - "shipping_status": shippingStatusValues.reverse[shippingStatus], - "shipping_statusn": shippingStatusnValues.reverse[shippingStatusn], - "customer_tax_display_type": customerTaxDisplayTypeValues.reverse[customerTaxDisplayType], - "can_cancel": canCancel, - "can_refund": canRefund, - "lakum_amount": lakumAmount, - "prefer_delivery_date": preferDeliveryDate == null ? null : "${preferDeliveryDate.year.toString().padLeft(4, '0')}-${preferDeliveryDate.month.toString().padLeft(2, '0')}-${preferDeliveryDate.day.toString().padLeft(2, '0')}", - "prefer_delivery_time": preferDeliveryTime == null ? null : preferDeliveryTimeValues.reverse[preferDeliveryTime], - "prefer_delivery_timen": preferDeliveryTimen == null ? null : preferDeliveryTimenValues.reverse[preferDeliveryTimen], - }; + "id": id, + "store_id": storeId, + "order_guid": orderGuid, + "pick_up_in_store": pickUpInStore, + "payment_method_system_name": paymentMethodSystemNameValues.reverse[paymentMethodSystemName], + "payment_name": paymentNameValues.reverse[paymentName], + "payment_namen": paymentNameValues.reverse[paymentNamen], + "customer_currency_code": customerCurrencyCodeValues.reverse[customerCurrencyCode], + "currency_rate": currencyRate, + "customer_tax_display_type_id": customerTaxDisplayTypeId, + "vat_number": vatNumber, + "order_subtotal_incl_tax": orderSubtotalInclTax, + "order_subtotal_excl_tax": orderSubtotalExclTax, + "order_sub_total_discount_incl_tax": orderSubTotalDiscountInclTax, + "order_sub_total_discount_excl_tax": orderSubTotalDiscountExclTax, + "order_shipping_incl_tax": orderShippingInclTax, + "order_shipping_excl_tax": orderShippingExclTax, + "payment_method_additional_fee_incl_tax": paymentMethodAdditionalFeeInclTax, + "payment_method_additional_fee_excl_tax": paymentMethodAdditionalFeeExclTax, + "tax_rates": taxRates, + "order_tax": orderTax, + "order_discount": orderDiscount, + "order_total": orderTotal, + "refunded_amount": refundedAmount, + "reward_points_were_added": rewardPointsWereAdded, + "rx_attachments": rxAttachments == null ? null : rxAttachments, + "checkout_attribute_description": checkoutAttributeDescriptionValues.reverse[checkoutAttributeDescription], + "customer_language_id": customerLanguageId, + "affiliate_id": affiliateId, + "customer_ip": customerIpValues.reverse[customerIp], + "authorization_transaction_id": authorizationTransactionId == null ? null : authorizationTransactionId, + "authorization_transaction_code": authorizationTransactionCode, + "authorization_transaction_result": authorizationTransactionResult, + "capture_transaction_id": captureTransactionId, + "capture_transaction_result": captureTransactionResult, + "subscription_transaction_id": subscriptionTransactionId, + "paid_date_utc": paidDateUtc == null ? null : paidDateUtc!.toIso8601String(), + "shipping_method": shippingMethodValues.reverse[shippingMethod], + "shipping_rate_computation_method_system_name": shippingRateComputationMethodSystemNameValues.reverse[shippingRateComputationMethodSystemName], + "custom_values_xml": customValuesXml, + "deleted": deleted, + "created_on_utc": createdOnUtc!.toIso8601String(), + "customer": customer!.toJson(), + "customer_id": customerId, + "billing_address": billingAddress!.toJson(), + "shipping_address": shippingAddress!.toJson(), + "order_items": List.from(orderItems!.map((x) => x.toJson())), + "order_status_id": orderStatusId, + "order_status": orderStatusValues.reverse[orderStatus], + "order_statusn": orderStatusnValues.reverse[orderStatusn], + "payment_status_id": paymentStatusId, + "payment_status": paymentStatusValues.reverse[paymentStatus], + "payment_statusn": paymentStatusnValues.reverse[paymentStatusn], + "shipping_status": shippingStatusValues.reverse[shippingStatus], + "shipping_statusn": shippingStatusnValues.reverse[shippingStatusn], + "customer_tax_display_type": customerTaxDisplayTypeValues.reverse[customerTaxDisplayType], + "can_cancel": canCancel, + "can_refund": canRefund, + "lakum_amount": lakumAmount, + "prefer_delivery_date": preferDeliveryDate == null + ? null + : "${preferDeliveryDate!.year.toString().padLeft(4, '0')}-${preferDeliveryDate!.month.toString().padLeft(2, '0')}-${preferDeliveryDate!.day.toString().padLeft(2, '0')}", + "prefer_delivery_time": preferDeliveryTime == null ? null : preferDeliveryTimeValues.reverse[preferDeliveryTime], + "prefer_delivery_timen": preferDeliveryTimen == null ? null : preferDeliveryTimenValues.reverse[preferDeliveryTimen], + }; } class IngAddress { @@ -303,84 +302,93 @@ class IngAddress { this.latLong, }); - String id; - FirstName firstName; - LastName lastName; - BillingAddressEmail email; + String? id; + FirstName? firstName; + LastName? lastName; + BillingAddressEmail? email; dynamic company; dynamic countryId; - Country country; + Country? country; dynamic stateProvinceId; - City city; - Address1 address1; - Address2 address2; - String zipPostalCode; - String phoneNumber; + City? city; + Address1? address1; + Address2? address2; + String? zipPostalCode; + String? phoneNumber; dynamic faxNumber; - String customerAttributes; - DateTime createdOnUtc; + String? customerAttributes; + DateTime? createdOnUtc; dynamic province; - String latLong; + String? latLong; - LatLng getLocation(){ - if(latLong.contains(',')){ - var parts = latLong.trim().split(','); - if(parts.length == 2){ + LatLng getLocation() { + if (latLong!.contains(',')) { + var parts = latLong!.trim().split(','); + if (parts.length == 2) { var lat = double.tryParse(parts.first); var lng = double.tryParse(parts.last); - if(lat != null || lng != null) { - var location = LatLng(lat, lng); + if (lat != null || lng != null) { + var location = LatLng(lat!, lng!); return location; } } } - return null; + return LatLng(double.nan, double.nan); + //changed by Aamir } factory IngAddress.fromJson(Map json) => IngAddress( - id: json["id"], - firstName: firstNameValues.map[json["first_name"]], - lastName: lastNameValues.map[json["last_name"]], - email: billingAddressEmailValues.map[json["email"]], - company: json["company"], - countryId: json["country_id"], - country: countryValues.map[json["country"]], - stateProvinceId: json["state_province_id"], - city: cityValues.map[json["city"]], - address1: address1Values.map[json["address1"]], - address2: address2Values.map[json["address2"]], - zipPostalCode: json["zip_postal_code"], - phoneNumber: json["phone_number"], - faxNumber: json["fax_number"], - customerAttributes: json["customer_attributes"], - createdOnUtc: DateTime.parse(json["created_on_utc"]), - province: json["province"], - latLong: json["lat_long"], - ); + id: json["id"], + firstName: firstNameValues.map![json["first_name"]], + lastName: lastNameValues.map![json["last_name"]], + email: billingAddressEmailValues.map![json["email"]], + company: json["company"], + countryId: json["country_id"], + country: countryValues.map![json["country"]], + stateProvinceId: json["state_province_id"], + city: cityValues.map![json["city"]], + address1: address1Values.map![json["address1"]], + address2: address2Values.map![json["address2"]], + zipPostalCode: json["zip_postal_code"], + phoneNumber: json["phone_number"], + faxNumber: json["fax_number"], + customerAttributes: json["customer_attributes"], + createdOnUtc: DateTime.parse(json["created_on_utc"]), + province: json["province"], + latLong: json["lat_long"], + ); Map toJson() => { - "id": id, - "first_name": firstNameValues.reverse[firstName], - "last_name": lastNameValues.reverse[lastName], - "email": billingAddressEmailValues.reverse[email], - "company": company, - "country_id": countryId, - "country": countryValues.reverse[country], - "state_province_id": stateProvinceId, - "city": cityValues.reverse[city], - "address1": address1Values.reverse[address1], - "address2": address2Values.reverse[address2], - "zip_postal_code": zipPostalCode, - "phone_number": phoneNumber, - "fax_number": faxNumber, - "customer_attributes": customerAttributes, - "created_on_utc": createdOnUtc.toIso8601String(), - "province": province, - "lat_long": latLong, - }; + "id": id, + "first_name": firstNameValues.reverse[firstName], + "last_name": lastNameValues.reverse[lastName], + "email": billingAddressEmailValues.reverse[email], + "company": company, + "country_id": countryId, + "country": countryValues.reverse[country], + "state_province_id": stateProvinceId, + "city": cityValues.reverse[city], + "address1": address1Values.reverse[address1], + "address2": address2Values.reverse[address2], + "zip_postal_code": zipPostalCode, + "phone_number": phoneNumber, + "fax_number": faxNumber, + "customer_attributes": customerAttributes, + "created_on_utc": createdOnUtc!.toIso8601String(), + "province": province, + "lat_long": latLong, + }; } -enum Address1 { THE_7960_MOSAB_IBN_UMAIR_STREET_AL_RIYADH, THE_6500_AL_AMEEN_ABDULLAH_AL_ALI_AL_NAEEM_STREET_AL_RIYADH, THE_6603_IBRAHIM_IBN_AL_HAMASI_AR_RIYAD, THE_9626_SALAH_AD_DIN_AL_AYYUBI_ROAD_AL_RIYADH, THE_3075_PRINCE_MANSUR_BIN_ABDULAZIZ_STREET_AL_RIYADH, THE_40, THE_7801_AL_IHSA_AL_RIYADH } +enum Address1 { + THE_7960_MOSAB_IBN_UMAIR_STREET_AL_RIYADH, + THE_6500_AL_AMEEN_ABDULLAH_AL_ALI_AL_NAEEM_STREET_AL_RIYADH, + THE_6603_IBRAHIM_IBN_AL_HAMASI_AR_RIYAD, + THE_9626_SALAH_AD_DIN_AL_AYYUBI_ROAD_AL_RIYADH, + THE_3075_PRINCE_MANSUR_BIN_ABDULAZIZ_STREET_AL_RIYADH, + THE_40, + THE_7801_AL_IHSA_AL_RIYADH +} final address1Values = EnumValues({ "3075, Prince Mansur Bin Abdulaziz Street, Al Riyadh, ": Address1.THE_3075_PRINCE_MANSUR_BIN_ABDULAZIZ_STREET_AL_RIYADH, @@ -392,7 +400,15 @@ final address1Values = EnumValues({ "9626, Salah Ad Din Al Ayyubi Road, Al Riyadh, ": Address1.THE_9626_SALAH_AD_DIN_AL_AYYUBI_ROAD_AL_RIYADH }); -enum Address2 { AL_MALAZ_RIYADH_PROVINCE_3460, AL_MALAZ_RIYADH_PROVINCE_2817, AR_RAHMANIYYAH_RIYADH_PROVINCE_3816, AL_MALAZ_RIYADH_PROVINCE_3815, AL_WIZARAT_RIYADH_PROVINCE_7039, EASTERN_PROVINCE, AL_MALAZ_RIYADH_PROVINCE_3084 } +enum Address2 { + AL_MALAZ_RIYADH_PROVINCE_3460, + AL_MALAZ_RIYADH_PROVINCE_2817, + AR_RAHMANIYYAH_RIYADH_PROVINCE_3816, + AL_MALAZ_RIYADH_PROVINCE_3815, + AL_WIZARAT_RIYADH_PROVINCE_7039, + EASTERN_PROVINCE, + AL_MALAZ_RIYADH_PROVINCE_3084 +} final address2Values = EnumValues({ "Al Malaz, Riyadh Province, 2817, ": Address2.AL_MALAZ_RIYADH_PROVINCE_2817, @@ -406,16 +422,11 @@ final address2Values = EnumValues({ enum City { RIYADH, DAMMAM } -final cityValues = EnumValues({ - "Dammam": City.DAMMAM, - "Riyadh": City.RIYADH -}); +final cityValues = EnumValues({"Dammam": City.DAMMAM, "Riyadh": City.RIYADH}); enum Country { SAUDI_ARABIA } -final countryValues = EnumValues({ - "Saudi Arabia": Country.SAUDI_ARABIA -}); +final countryValues = EnumValues({"Saudi Arabia": Country.SAUDI_ARABIA}); enum BillingAddressEmail { TAMER_FANASHEH_GMAIL_COM, TAMER_DASDASDAS_GMAIL_COM, TAMER_FANASHEH_DRSULAIMANALHABIB_COM } @@ -427,21 +438,23 @@ final billingAddressEmailValues = EnumValues({ enum FirstName { TAMER, TAMER_FANASHEH, FIRST_NAME_TAMER } -final firstNameValues = EnumValues({ - "tamer": FirstName.FIRST_NAME_TAMER, - "TAMER": FirstName.TAMER, - "TAMER FANASHEH": FirstName.TAMER_FANASHEH -}); +final firstNameValues = EnumValues({"tamer": FirstName.FIRST_NAME_TAMER, "TAMER": FirstName.TAMER, "TAMER FANASHEH": FirstName.TAMER_FANASHEH}); enum LastName { FANASHEH, MUSA, LAST_NAME_FANASHEH } -final lastNameValues = EnumValues({ - "FANASHEH": LastName.FANASHEH, - "Fanasheh": LastName.LAST_NAME_FANASHEH, - "MUSA": LastName.MUSA -}); - -enum LatLong { THE_246784385694919524674091019299842, THE_24664749106968054673501121876645, THE_2470993657522702246664724647270134, THE_246626170308533764673348444086107, THE_24664875225999005467347443322574, THE_24674331807435784671024726818286, THE_263430228396836664991113909164471, THE_246767400793488074673774399406786, THE_24665374673515 } +final lastNameValues = EnumValues({"FANASHEH": LastName.FANASHEH, "Fanasheh": LastName.LAST_NAME_FANASHEH, "MUSA": LastName.MUSA}); + +enum LatLong { + THE_246784385694919524674091019299842, + THE_24664749106968054673501121876645, + THE_2470993657522702246664724647270134, + THE_246626170308533764673348444086107, + THE_24664875225999005467347443322574, + THE_24674331807435784671024726818286, + THE_263430228396836664991113909164471, + THE_246767400793488074673774399406786, + THE_24665374673515 +} final latLongValues = EnumValues({ "24.662617030853376,46.73348444086107": LatLong.THE_246626170308533764673348444086107, @@ -457,10 +470,7 @@ final latLongValues = EnumValues({ enum CheckoutAttributeDescription { EMPTY, CHECKOUT_ATTRIBUTE_DESCRIPTION } -final checkoutAttributeDescriptionValues = EnumValues({ - "ارفاق وصفة: ": CheckoutAttributeDescription.CHECKOUT_ATTRIBUTE_DESCRIPTION, - "": CheckoutAttributeDescription.EMPTY -}); +final checkoutAttributeDescriptionValues = EnumValues({"ارفاق وصفة: ": CheckoutAttributeDescription.CHECKOUT_ATTRIBUTE_DESCRIPTION, "": CheckoutAttributeDescription.EMPTY}); class OrderModelCustomer { OrderModelCustomer({ @@ -485,88 +495,82 @@ class OrderModelCustomer { this.roleIds, }); - String id; + String? id; dynamic username; dynamic email; dynamic firstName; dynamic lastName; - String languageId; + String? languageId; dynamic adminComment; - bool isTaxExempt; - bool hasShoppingCartItems; - bool active; - bool deleted; - bool isSystemAccount; + bool? isTaxExempt; + bool? hasShoppingCartItems; + bool? active; + bool? deleted; + bool? isSystemAccount; dynamic systemName; dynamic lastIpAddress; dynamic createdOnUtc; dynamic lastLoginDateUtc; dynamic lastActivityDateUtc; dynamic registeredInStoreId; - List roleIds; + List? roleIds; factory OrderModelCustomer.fromJson(Map json) => OrderModelCustomer( - id: json["id"], - username: usernameValues.map[json["username"]], - email: billingAddressEmailValues.map[json["email"]], - firstName: firstNameValues.map[json["first_name"]], - lastName: lastNameValues.map[json["last_name"]], - languageId: json["language_id"], - adminComment: json["admin_comment"], - isTaxExempt: json["is_tax_exempt"], - hasShoppingCartItems: json["has_shopping_cart_items"], - active: json["active"], - deleted: json["deleted"], - isSystemAccount: json["is_system_account"], - systemName: json["system_name"], - lastIpAddress: lastIpAddressValues.map[json["last_ip_address"]], - createdOnUtc: (json["created_on_utc"] != null) ? DateTime.parse(json["created_on_utc"]) : null, - lastLoginDateUtc: (json["created_on_utc"] != null) ? DateTime.parse(json["last_login_date_utc"]) : null, - lastActivityDateUtc: (json["created_on_utc"] != null) ? DateTime.parse(json["last_activity_date_utc"]) : null, - registeredInStoreId: json["registered_in_store_id"], - roleIds: List.from(json["role_ids"].map((x) => x)), - ); + id: json["id"], + username: usernameValues.map![json["username"]], + email: billingAddressEmailValues.map![json["email"]], + firstName: firstNameValues.map![json["first_name"]], + lastName: lastNameValues.map![json["last_name"]], + languageId: json["language_id"], + adminComment: json["admin_comment"], + isTaxExempt: json["is_tax_exempt"], + hasShoppingCartItems: json["has_shopping_cart_items"], + active: json["active"], + deleted: json["deleted"], + isSystemAccount: json["is_system_account"], + systemName: json["system_name"], + lastIpAddress: lastIpAddressValues.map![json["last_ip_address"]], + createdOnUtc: (json["created_on_utc"] != null) ? DateTime.parse(json["created_on_utc"]) : null, + lastLoginDateUtc: (json["created_on_utc"] != null) ? DateTime.parse(json["last_login_date_utc"]) : null, + lastActivityDateUtc: (json["created_on_utc"] != null) ? DateTime.parse(json["last_activity_date_utc"]) : null, + registeredInStoreId: json["registered_in_store_id"], + roleIds: List.from(json["role_ids"].map((x) => x)), + ); Map toJson() => { - "id": id, - "username": usernameValues.reverse[username], - "email": billingAddressEmailValues.reverse[email], - "first_name": firstNameValues.reverse[firstName], - "last_name": lastNameValues.reverse[lastName], - "language_id": languageId, - "admin_comment": adminComment, - "is_tax_exempt": isTaxExempt, - "has_shopping_cart_items": hasShoppingCartItems, - "active": active, - "deleted": deleted, - "is_system_account": isSystemAccount, - "system_name": systemName, - "last_ip_address": lastIpAddressValues.reverse[lastIpAddress], - "created_on_utc": createdOnUtc.toIso8601String(), - "last_login_date_utc": lastLoginDateUtc.toIso8601String(), - "last_activity_date_utc": lastActivityDateUtc.toIso8601String(), - "registered_in_store_id": registeredInStoreId, - "role_ids": List.from(roleIds.map((x) => x)), - }; + "id": id, + "username": usernameValues.reverse[username], + "email": billingAddressEmailValues.reverse[email], + "first_name": firstNameValues.reverse[firstName], + "last_name": lastNameValues.reverse[lastName], + "language_id": languageId, + "admin_comment": adminComment, + "is_tax_exempt": isTaxExempt, + "has_shopping_cart_items": hasShoppingCartItems, + "active": active, + "deleted": deleted, + "is_system_account": isSystemAccount, + "system_name": systemName, + "last_ip_address": lastIpAddressValues.reverse[lastIpAddress], + "created_on_utc": createdOnUtc.toIso8601String(), + "last_login_date_utc": lastLoginDateUtc.toIso8601String(), + "last_activity_date_utc": lastActivityDateUtc.toIso8601String(), + "registered_in_store_id": registeredInStoreId, + "role_ids": List.from(roleIds!.map((x) => x)), + }; } enum LastIpAddress { THE_1050220126 } -final lastIpAddressValues = EnumValues({ - "10.50.220.126": LastIpAddress.THE_1050220126 -}); +final lastIpAddressValues = EnumValues({"10.50.220.126": LastIpAddress.THE_1050220126}); enum Username { TAMERF } -final usernameValues = EnumValues({ - "tamerf": Username.TAMERF -}); +final usernameValues = EnumValues({"tamerf": Username.TAMERF}); enum CustomerCurrencyCode { SAR } -final customerCurrencyCodeValues = EnumValues({ - "SAR": CustomerCurrencyCode.SAR -}); +final customerCurrencyCodeValues = EnumValues({"SAR": CustomerCurrencyCode.SAR}); enum CustomerIp { THE_105010210, THE_127001, THE_1020200101, THE_102020041, THE_10501028, THE_102020033, THE_1020200170, THE_102020011 } @@ -583,10 +587,7 @@ final customerIpValues = EnumValues({ enum CustomerTaxDisplayType { EXCLUDING_TAX } -final customerTaxDisplayTypeValues = EnumValues({ - "ExcludingTax": CustomerTaxDisplayType.EXCLUDING_TAX -}); - +final customerTaxDisplayTypeValues = EnumValues({"ExcludingTax": CustomerTaxDisplayType.EXCLUDING_TAX}); class OrderItem { OrderItem({ @@ -610,62 +611,62 @@ class OrderItem { }); dynamic quantity; - double unitPriceInclTax; - double unitPriceExclTax; - double priceInclTax; - double priceExclTax; - double discountAmountInclTax; - double discountAmountExclTax; - double originalProductCost; - String attributeDescription; + double? unitPriceInclTax; + double? unitPriceExclTax; + double? priceInclTax; + double? priceExclTax; + double? discountAmountInclTax; + double? discountAmountExclTax; + double? originalProductCost; + String? attributeDescription; dynamic downloadCount; - bool isDownloadActivated; + bool? isDownloadActivated; dynamic licenseDownloadId; - double itemWeight; + double? itemWeight; dynamic rentalStartDateUtc; dynamic rentalEndDateUtc; - Product product; + Product? product; dynamic productId; factory OrderItem.fromJson(Map json) => OrderItem( - quantity: json["quantity"], - unitPriceInclTax: json["unit_price_incl_tax"].toDouble(), - unitPriceExclTax: json["unit_price_excl_tax"].toDouble(), - priceInclTax: json["price_incl_tax"].toDouble(), - priceExclTax: json["price_excl_tax"].toDouble(), - discountAmountInclTax: json["discount_amount_incl_tax"].toDouble(), - discountAmountExclTax: json["discount_amount_excl_tax"].toDouble(), - originalProductCost: json["original_product_cost"].toDouble(), - attributeDescription: json["attribute_description"], - downloadCount: json["download_count"], - isDownloadActivated: json["isDownload_activated"], - licenseDownloadId: json["license_download_id"], - itemWeight: json["item_weight"].toDouble(), - rentalStartDateUtc: json["rental_start_date_utc"], - rentalEndDateUtc: json["rental_end_date_utc"], - product: Product.fromJson(json["product"]), - productId: json["product_id"], - ); + quantity: json["quantity"], + unitPriceInclTax: json["unit_price_incl_tax"].toDouble(), + unitPriceExclTax: json["unit_price_excl_tax"].toDouble(), + priceInclTax: json["price_incl_tax"].toDouble(), + priceExclTax: json["price_excl_tax"].toDouble(), + discountAmountInclTax: json["discount_amount_incl_tax"].toDouble(), + discountAmountExclTax: json["discount_amount_excl_tax"].toDouble(), + originalProductCost: json["original_product_cost"].toDouble(), + attributeDescription: json["attribute_description"], + downloadCount: json["download_count"], + isDownloadActivated: json["isDownload_activated"], + licenseDownloadId: json["license_download_id"], + itemWeight: json["item_weight"].toDouble(), + rentalStartDateUtc: json["rental_start_date_utc"], + rentalEndDateUtc: json["rental_end_date_utc"], + product: Product.fromJson(json["product"]), + productId: json["product_id"], + ); Map toJson() => { - "quantity": quantity, - "unit_price_incl_tax": unitPriceInclTax, - "unit_price_excl_tax": unitPriceExclTax, - "price_incl_tax": priceInclTax, - "price_excl_tax": priceExclTax, - "discount_amount_incl_tax": discountAmountInclTax, - "discount_amount_excl_tax": discountAmountExclTax, - "original_product_cost": originalProductCost, - "attribute_description": attributeDescription, - "download_count": downloadCount, - "isDownload_activated": isDownloadActivated, - "license_download_id": licenseDownloadId, - "item_weight": itemWeight, - "rental_start_date_utc": rentalStartDateUtc, - "rental_end_date_utc": rentalEndDateUtc, - "product": product.toJson(), - "product_id": productId, - }; + "quantity": quantity, + "unit_price_incl_tax": unitPriceInclTax, + "unit_price_excl_tax": unitPriceExclTax, + "price_incl_tax": priceInclTax, + "price_excl_tax": priceExclTax, + "discount_amount_incl_tax": discountAmountInclTax, + "discount_amount_excl_tax": discountAmountExclTax, + "original_product_cost": originalProductCost, + "attribute_description": attributeDescription, + "download_count": downloadCount, + "isDownload_activated": isDownloadActivated, + "license_download_id": licenseDownloadId, + "item_weight": itemWeight, + "rental_start_date_utc": rentalStartDateUtc, + "rental_end_date_utc": rentalEndDateUtc, + "product": product!.toJson(), + "product_id": productId, + }; } class Product { @@ -783,85 +784,85 @@ class Product { this.seName, }); - String id; - bool visibleIndividually; - String name; - String namen; + String? id; + bool? visibleIndividually; + String? name; + String? namen; dynamic localizedNames; - String shortDescription; - String shortDescriptionn; - String fullDescription; - String fullDescriptionn; - bool markasNew; - bool showOnHomePage; - String metaKeywords; - String metaDescription; - String metaTitle; - bool allowCustomerReviews; + String? shortDescription; + String? shortDescriptionn; + String? fullDescription; + String? fullDescriptionn; + bool? markasNew; + bool? showOnHomePage; + String? metaKeywords; + String? metaDescription; + String? metaTitle; + bool? allowCustomerReviews; dynamic approvedRatingSum; dynamic notApprovedRatingSum; dynamic approvedTotalReviews; dynamic notApprovedTotalReviews; - String sku; - bool isRx; - bool prescriptionRequired; + String? sku; + bool? isRx; + bool? prescriptionRequired; dynamic rxMessage; dynamic rxMessagen; dynamic manufacturerPartNumber; dynamic gtin; - bool isGiftCard; - bool requireOtherProducts; - bool automaticallyAddRequiredProducts; - bool isDownload; - bool unlimitedDownloads; + bool? isGiftCard; + bool? requireOtherProducts; + bool? automaticallyAddRequiredProducts; + bool? isDownload; + bool? unlimitedDownloads; dynamic maxNumberOfDownloads; dynamic downloadExpirationDays; - bool hasSampleDownload; - bool hasUserAgreement; - bool isRecurring; + bool? hasSampleDownload; + bool? hasUserAgreement; + bool? isRecurring; dynamic recurringCycleLength; dynamic recurringTotalCycles; - bool isRental; + bool? isRental; dynamic rentalPriceLength; - bool isShipEnabled; - bool isFreeShipping; - bool shipSeparately; + bool? isShipEnabled; + bool? isFreeShipping; + bool? shipSeparately; dynamic additionalShippingCharge; - bool isTaxExempt; - bool isTelecommunicationsOrBroadcastingOrElectronicServices; - bool useMultipleWarehouses; + bool? isTaxExempt; + bool? isTelecommunicationsOrBroadcastingOrElectronicServices; + bool? useMultipleWarehouses; dynamic manageInventoryMethodId; dynamic stockQuantity; dynamic stockAvailability; dynamic stockAvailabilityn; - bool displayStockAvailability; - bool displayStockQuantity; + bool? displayStockAvailability; + bool? displayStockQuantity; dynamic minStockQuantity; dynamic notifyAdminForQuantityBelow; - bool allowBackInStockSubscriptions; + bool? allowBackInStockSubscriptions; dynamic orderMinimumQuantity; dynamic orderMaximumQuantity; dynamic allowedQuantities; - bool allowAddingOnlyExistingAttributeCombinations; - bool disableBuyButton; - bool disableWishlistButton; - bool availableForPreOrder; + bool? allowAddingOnlyExistingAttributeCombinations; + bool? disableBuyButton; + bool? disableWishlistButton; + bool? availableForPreOrder; dynamic preOrderAvailabilityStartDateTimeUtc; - bool callForPrice; - double price; + bool? callForPrice; + double? price; dynamic oldPrice; - double productCost; + double? productCost; dynamic specialPrice; dynamic specialPriceStartDateTimeUtc; dynamic specialPriceEndDateTimeUtc; - bool customerEntersPrice; + bool? customerEntersPrice; dynamic minimumCustomerEnteredPrice; dynamic maximumCustomerEnteredPrice; - bool basepriceEnabled; + bool? basepriceEnabled; dynamic basepriceAmount; dynamic basepriceBaseAmount; - bool hasTierPrices; - bool hasDiscountsApplied; + bool? hasTierPrices; + bool? hasDiscountsApplied; dynamic discountName; dynamic discountNamen; dynamic discountDescription; @@ -869,15 +870,15 @@ class Product { dynamic discountPercentage; dynamic currency; dynamic currencyn; - double weight; + double? weight; dynamic length; dynamic width; dynamic height; dynamic availableStartDateTimeUtc; dynamic availableEndDateTimeUtc; dynamic displayOrder; - bool published; - bool deleted; + bool? published; + bool? deleted; dynamic createdOnUtc; dynamic updatedOnUtc; dynamic productType; @@ -886,249 +887,247 @@ class Product { dynamic discountIds; dynamic storeIds; dynamic manufacturerIds; - List reviews; - List images; + List? reviews; + List? images; dynamic attributes; dynamic specifications; dynamic associatedProductIds; - List tags; + List? tags; dynamic vendorId; - String seName; + String? seName; factory Product.fromJson(Map json) => Product( - id: json["id"], - visibleIndividually: json["visible_individually"], - name: json["name"], - namen: json["namen"], - localizedNames: json["localized_names"], - shortDescription: json["short_description"] == null ? null : json["short_description"], - shortDescriptionn: json["short_descriptionn"] == null ? null : json["short_descriptionn"], - fullDescription: json["full_description"], - fullDescriptionn: json["full_descriptionn"], - markasNew: json["markas_new"], - showOnHomePage: json["show_on_home_page"], - metaKeywords: json["meta_keywords"] == null ? null : json["meta_keywords"], - metaDescription: json["meta_description"] == null ? null : json["meta_description"], - metaTitle: json["meta_title"] == null ? null : json["meta_title"], - allowCustomerReviews: json["allow_customer_reviews"], - approvedRatingSum: json["approved_rating_sum"], - notApprovedRatingSum: json["not_approved_rating_sum"], - approvedTotalReviews: json["approved_total_reviews"], - notApprovedTotalReviews: json["not_approved_total_reviews"], - sku: json["sku"], - isRx: json["is_rx"], - prescriptionRequired: json["prescription_required"], - rxMessage: json["rx_message"], - rxMessagen: json["rx_messagen"], - manufacturerPartNumber: json["manufacturer_part_number"], - gtin: json["gtin"], - isGiftCard: json["is_gift_card"], - requireOtherProducts: json["require_other_products"], - automaticallyAddRequiredProducts: json["automatically_add_required_products"], - isDownload: json["is_download"], - unlimitedDownloads: json["unlimited_downloads"], - maxNumberOfDownloads: json["max_number_of_downloads"], - downloadExpirationDays: json["download_expiration_days"], - hasSampleDownload: json["has_sample_download"], - hasUserAgreement: json["has_user_agreement"], - isRecurring: json["is_recurring"], - recurringCycleLength: json["recurring_cycle_length"], - recurringTotalCycles: json["recurring_total_cycles"], - isRental: json["is_rental"], - rentalPriceLength: json["rental_price_length"], - isShipEnabled: json["is_ship_enabled"], - isFreeShipping: json["is_free_shipping"], - shipSeparately: json["ship_separately"], - additionalShippingCharge: json["additional_shipping_charge"], - isTaxExempt: json["is_tax_exempt"], - isTelecommunicationsOrBroadcastingOrElectronicServices: json["is_telecommunications_or_broadcasting_or_electronic_services"], - useMultipleWarehouses: json["use_multiple_warehouses"], - manageInventoryMethodId: json["manage_inventory_method_id"], - stockQuantity: json["stock_quantity"], - stockAvailability: json["stock_availability"], - stockAvailabilityn: json["stock_availabilityn"], - displayStockAvailability: json["display_stock_availability"], - displayStockQuantity: json["display_stock_quantity"], - minStockQuantity: json["min_stock_quantity"], - notifyAdminForQuantityBelow: json["notify_admin_for_quantity_below"], - allowBackInStockSubscriptions: json["allow_back_in_stock_subscriptions"], - orderMinimumQuantity: json["order_minimum_quantity"], - orderMaximumQuantity: json["order_maximum_quantity"], - allowedQuantities: json["allowed_quantities"], - allowAddingOnlyExistingAttributeCombinations: json["allow_adding_only_existing_attribute_combinations"], - disableBuyButton: json["disable_buy_button"], - disableWishlistButton: json["disable_wishlist_button"], - availableForPreOrder: json["available_for_pre_order"], - preOrderAvailabilityStartDateTimeUtc: json["pre_order_availability_start_date_time_utc"], - callForPrice: json["call_for_price"], - price: json["price"].toDouble(), - oldPrice: json["old_price"], - productCost: json["product_cost"].toDouble(), - specialPrice: json["special_price"], - specialPriceStartDateTimeUtc: json["special_price_start_date_time_utc"], - specialPriceEndDateTimeUtc: json["special_price_end_date_time_utc"], - customerEntersPrice: json["customer_enters_price"], - minimumCustomerEnteredPrice: json["minimum_customer_entered_price"], - maximumCustomerEnteredPrice: json["maximum_customer_entered_price"], - basepriceEnabled: json["baseprice_enabled"], - basepriceAmount: json["baseprice_amount"], - basepriceBaseAmount: json["baseprice_base_amount"], - hasTierPrices: json["has_tier_prices"], - hasDiscountsApplied: json["has_discounts_applied"], - discountName: json["discount_name"], - discountNamen: json["discount_namen"], - discountDescription: json["discount_description"], - discountDescriptionn: json["discount_Descriptionn"], - discountPercentage: json["discount_percentage"], - currency: json["currency"], - currencyn: json["currencyn"], - weight: json["weight"].toDouble(), - length: json["length"], - width: json["width"], - height: json["height"], - availableStartDateTimeUtc: json["available_start_date_time_utc"], - availableEndDateTimeUtc: json["available_end_date_time_utc"], - displayOrder: json["display_order"], - published: json["published"], - deleted: json["deleted"], - createdOnUtc: DateTime.parse(json["created_on_utc"]), - updatedOnUtc: DateTime.parse(json["updated_on_utc"]), - productType: productTypeValues.map[json["product_type"]], - parentGroupedProductId: json["parent_grouped_product_id"], - roleIds: json["role_ids"], - discountIds: json["discount_ids"], - storeIds: json["store_ids"], - manufacturerIds: json["manufacturer_ids"], - reviews: List.from(json["reviews"].map((x) => Review.fromJson(x))), - images: List.from(json["images"].map((x) => PharmacyImageObject.fromJson(x))), - attributes: json["attributes"], - specifications: json["specifications"], - associatedProductIds: json["associated_product_ids"], - tags: List.from(json["tags"].map((x) => x)), - vendorId: json["vendor_id"], - seName: json["se_name"], - ); + id: json["id"], + visibleIndividually: json["visible_individually"], + name: json["name"], + namen: json["namen"], + localizedNames: json["localized_names"], + shortDescription: json["short_description"] == null ? null : json["short_description"], + shortDescriptionn: json["short_descriptionn"] == null ? null : json["short_descriptionn"], + fullDescription: json["full_description"], + fullDescriptionn: json["full_descriptionn"], + markasNew: json["markas_new"], + showOnHomePage: json["show_on_home_page"], + metaKeywords: json["meta_keywords"] == null ? null : json["meta_keywords"], + metaDescription: json["meta_description"] == null ? null : json["meta_description"], + metaTitle: json["meta_title"] == null ? null : json["meta_title"], + allowCustomerReviews: json["allow_customer_reviews"], + approvedRatingSum: json["approved_rating_sum"], + notApprovedRatingSum: json["not_approved_rating_sum"], + approvedTotalReviews: json["approved_total_reviews"], + notApprovedTotalReviews: json["not_approved_total_reviews"], + sku: json["sku"], + isRx: json["is_rx"], + prescriptionRequired: json["prescription_required"], + rxMessage: json["rx_message"], + rxMessagen: json["rx_messagen"], + manufacturerPartNumber: json["manufacturer_part_number"], + gtin: json["gtin"], + isGiftCard: json["is_gift_card"], + requireOtherProducts: json["require_other_products"], + automaticallyAddRequiredProducts: json["automatically_add_required_products"], + isDownload: json["is_download"], + unlimitedDownloads: json["unlimited_downloads"], + maxNumberOfDownloads: json["max_number_of_downloads"], + downloadExpirationDays: json["download_expiration_days"], + hasSampleDownload: json["has_sample_download"], + hasUserAgreement: json["has_user_agreement"], + isRecurring: json["is_recurring"], + recurringCycleLength: json["recurring_cycle_length"], + recurringTotalCycles: json["recurring_total_cycles"], + isRental: json["is_rental"], + rentalPriceLength: json["rental_price_length"], + isShipEnabled: json["is_ship_enabled"], + isFreeShipping: json["is_free_shipping"], + shipSeparately: json["ship_separately"], + additionalShippingCharge: json["additional_shipping_charge"], + isTaxExempt: json["is_tax_exempt"], + isTelecommunicationsOrBroadcastingOrElectronicServices: json["is_telecommunications_or_broadcasting_or_electronic_services"], + useMultipleWarehouses: json["use_multiple_warehouses"], + manageInventoryMethodId: json["manage_inventory_method_id"], + stockQuantity: json["stock_quantity"], + stockAvailability: json["stock_availability"], + stockAvailabilityn: json["stock_availabilityn"], + displayStockAvailability: json["display_stock_availability"], + displayStockQuantity: json["display_stock_quantity"], + minStockQuantity: json["min_stock_quantity"], + notifyAdminForQuantityBelow: json["notify_admin_for_quantity_below"], + allowBackInStockSubscriptions: json["allow_back_in_stock_subscriptions"], + orderMinimumQuantity: json["order_minimum_quantity"], + orderMaximumQuantity: json["order_maximum_quantity"], + allowedQuantities: json["allowed_quantities"], + allowAddingOnlyExistingAttributeCombinations: json["allow_adding_only_existing_attribute_combinations"], + disableBuyButton: json["disable_buy_button"], + disableWishlistButton: json["disable_wishlist_button"], + availableForPreOrder: json["available_for_pre_order"], + preOrderAvailabilityStartDateTimeUtc: json["pre_order_availability_start_date_time_utc"], + callForPrice: json["call_for_price"], + price: json["price"].toDouble(), + oldPrice: json["old_price"], + productCost: json["product_cost"].toDouble(), + specialPrice: json["special_price"], + specialPriceStartDateTimeUtc: json["special_price_start_date_time_utc"], + specialPriceEndDateTimeUtc: json["special_price_end_date_time_utc"], + customerEntersPrice: json["customer_enters_price"], + minimumCustomerEnteredPrice: json["minimum_customer_entered_price"], + maximumCustomerEnteredPrice: json["maximum_customer_entered_price"], + basepriceEnabled: json["baseprice_enabled"], + basepriceAmount: json["baseprice_amount"], + basepriceBaseAmount: json["baseprice_base_amount"], + hasTierPrices: json["has_tier_prices"], + hasDiscountsApplied: json["has_discounts_applied"], + discountName: json["discount_name"], + discountNamen: json["discount_namen"], + discountDescription: json["discount_description"], + discountDescriptionn: json["discount_Descriptionn"], + discountPercentage: json["discount_percentage"], + currency: json["currency"], + currencyn: json["currencyn"], + weight: json["weight"].toDouble(), + length: json["length"], + width: json["width"], + height: json["height"], + availableStartDateTimeUtc: json["available_start_date_time_utc"], + availableEndDateTimeUtc: json["available_end_date_time_utc"], + displayOrder: json["display_order"], + published: json["published"], + deleted: json["deleted"], + createdOnUtc: DateTime.parse(json["created_on_utc"]), + updatedOnUtc: DateTime.parse(json["updated_on_utc"]), + productType: productTypeValues.map![json["product_type"]], + parentGroupedProductId: json["parent_grouped_product_id"], + roleIds: json["role_ids"], + discountIds: json["discount_ids"], + storeIds: json["store_ids"], + manufacturerIds: json["manufacturer_ids"], + reviews: List.from(json["reviews"].map((x) => Review.fromJson(x))), + images: List.from(json["images"].map((x) => PharmacyImageObject.fromJson(x))), + attributes: json["attributes"], + specifications: json["specifications"], + associatedProductIds: json["associated_product_ids"], + tags: List.from(json["tags"].map((x) => x)), + vendorId: json["vendor_id"], + seName: json["se_name"], + ); Map toJson() => { - "id": id, - "visible_individually": visibleIndividually, - "name": name, - "namen": namen, - "localized_names": localizedNames, - "short_description": shortDescription == null ? null : shortDescription, - "short_descriptionn": shortDescriptionn == null ? null : shortDescriptionn, - "full_description": fullDescription, - "full_descriptionn": fullDescriptionn, - "markas_new": markasNew, - "show_on_home_page": showOnHomePage, - "meta_keywords": metaKeywords == null ? null : metaKeywords, - "meta_description": metaDescription == null ? null : metaDescription, - "meta_title": metaTitle == null ? null : metaTitle, - "allow_customer_reviews": allowCustomerReviews, - "approved_rating_sum": approvedRatingSum, - "not_approved_rating_sum": notApprovedRatingSum, - "approved_total_reviews": approvedTotalReviews, - "not_approved_total_reviews": notApprovedTotalReviews, - "sku": sku, - "is_rx": isRx, - "prescription_required": prescriptionRequired, - "rx_message": rxMessage, - "rx_messagen": rxMessagen, - "manufacturer_part_number": manufacturerPartNumber, - "gtin": gtin, - "is_gift_card": isGiftCard, - "require_other_products": requireOtherProducts, - "automatically_add_required_products": automaticallyAddRequiredProducts, - "is_download": isDownload, - "unlimited_downloads": unlimitedDownloads, - "max_number_of_downloads": maxNumberOfDownloads, - "download_expiration_days": downloadExpirationDays, - "has_sample_download": hasSampleDownload, - "has_user_agreement": hasUserAgreement, - "is_recurring": isRecurring, - "recurring_cycle_length": recurringCycleLength, - "recurring_total_cycles": recurringTotalCycles, - "is_rental": isRental, - "rental_price_length": rentalPriceLength, - "is_ship_enabled": isShipEnabled, - "is_free_shipping": isFreeShipping, - "ship_separately": shipSeparately, - "additional_shipping_charge": additionalShippingCharge, - "is_tax_exempt": isTaxExempt, - "is_telecommunications_or_broadcasting_or_electronic_services": isTelecommunicationsOrBroadcastingOrElectronicServices, - "use_multiple_warehouses": useMultipleWarehouses, - "manage_inventory_method_id": manageInventoryMethodId, - "stock_quantity": stockQuantity, - "stock_availability": stockAvailability, - "stock_availabilityn": stockAvailabilityn, - "display_stock_availability": displayStockAvailability, - "display_stock_quantity": displayStockQuantity, - "min_stock_quantity": minStockQuantity, - "notify_admin_for_quantity_below": notifyAdminForQuantityBelow, - "allow_back_in_stock_subscriptions": allowBackInStockSubscriptions, - "order_minimum_quantity": orderMinimumQuantity, - "order_maximum_quantity": orderMaximumQuantity, - "allowed_quantities": allowedQuantities, - "allow_adding_only_existing_attribute_combinations": allowAddingOnlyExistingAttributeCombinations, - "disable_buy_button": disableBuyButton, - "disable_wishlist_button": disableWishlistButton, - "available_for_pre_order": availableForPreOrder, - "pre_order_availability_start_date_time_utc": preOrderAvailabilityStartDateTimeUtc, - "call_for_price": callForPrice, - "price": price, - "old_price": oldPrice, - "product_cost": productCost, - "special_price": specialPrice, - "special_price_start_date_time_utc": specialPriceStartDateTimeUtc, - "special_price_end_date_time_utc": specialPriceEndDateTimeUtc, - "customer_enters_price": customerEntersPrice, - "minimum_customer_entered_price": minimumCustomerEnteredPrice, - "maximum_customer_entered_price": maximumCustomerEnteredPrice, - "baseprice_enabled": basepriceEnabled, - "baseprice_amount": basepriceAmount, - "baseprice_base_amount": basepriceBaseAmount, - "has_tier_prices": hasTierPrices, - "has_discounts_applied": hasDiscountsApplied, - "discount_name": discountName, - "discount_namen": discountNamen, - "discount_description": discountDescription, - "discount_Descriptionn": discountDescriptionn, - "discount_percentage": discountPercentage, - "currency": currency, - "currencyn": currencyn, - "weight": weight, - "length": length, - "width": width, - "height": height, - "available_start_date_time_utc": availableStartDateTimeUtc, - "available_end_date_time_utc": availableEndDateTimeUtc, - "display_order": displayOrder, - "published": published, - "deleted": deleted, - "created_on_utc": createdOnUtc.toIso8601String(), - "updated_on_utc": updatedOnUtc.toIso8601String(), - "product_type": productTypeValues.reverse[productType], - "parent_grouped_product_id": parentGroupedProductId, - "role_ids": roleIds, - "discount_ids": discountIds, - "store_ids": storeIds, - "manufacturer_ids": manufacturerIds, - "reviews": List.from(reviews.map((x) => x.toJson())), - "images": List.from(images.map((x) => x.toJson())), - "attributes": attributes, - "specifications": specifications, - "associated_product_ids": associatedProductIds, - "tags": List.from(tags.map((x) => x)), - "vendor_id": vendorId, - "se_name": seName, - }; + "id": id, + "visible_individually": visibleIndividually, + "name": name, + "namen": namen, + "localized_names": localizedNames, + "short_description": shortDescription == null ? null : shortDescription, + "short_descriptionn": shortDescriptionn == null ? null : shortDescriptionn, + "full_description": fullDescription, + "full_descriptionn": fullDescriptionn, + "markas_new": markasNew, + "show_on_home_page": showOnHomePage, + "meta_keywords": metaKeywords == null ? null : metaKeywords, + "meta_description": metaDescription == null ? null : metaDescription, + "meta_title": metaTitle == null ? null : metaTitle, + "allow_customer_reviews": allowCustomerReviews, + "approved_rating_sum": approvedRatingSum, + "not_approved_rating_sum": notApprovedRatingSum, + "approved_total_reviews": approvedTotalReviews, + "not_approved_total_reviews": notApprovedTotalReviews, + "sku": sku, + "is_rx": isRx, + "prescription_required": prescriptionRequired, + "rx_message": rxMessage, + "rx_messagen": rxMessagen, + "manufacturer_part_number": manufacturerPartNumber, + "gtin": gtin, + "is_gift_card": isGiftCard, + "require_other_products": requireOtherProducts, + "automatically_add_required_products": automaticallyAddRequiredProducts, + "is_download": isDownload, + "unlimited_downloads": unlimitedDownloads, + "max_number_of_downloads": maxNumberOfDownloads, + "download_expiration_days": downloadExpirationDays, + "has_sample_download": hasSampleDownload, + "has_user_agreement": hasUserAgreement, + "is_recurring": isRecurring, + "recurring_cycle_length": recurringCycleLength, + "recurring_total_cycles": recurringTotalCycles, + "is_rental": isRental, + "rental_price_length": rentalPriceLength, + "is_ship_enabled": isShipEnabled, + "is_free_shipping": isFreeShipping, + "ship_separately": shipSeparately, + "additional_shipping_charge": additionalShippingCharge, + "is_tax_exempt": isTaxExempt, + "is_telecommunications_or_broadcasting_or_electronic_services": isTelecommunicationsOrBroadcastingOrElectronicServices, + "use_multiple_warehouses": useMultipleWarehouses, + "manage_inventory_method_id": manageInventoryMethodId, + "stock_quantity": stockQuantity, + "stock_availability": stockAvailability, + "stock_availabilityn": stockAvailabilityn, + "display_stock_availability": displayStockAvailability, + "display_stock_quantity": displayStockQuantity, + "min_stock_quantity": minStockQuantity, + "notify_admin_for_quantity_below": notifyAdminForQuantityBelow, + "allow_back_in_stock_subscriptions": allowBackInStockSubscriptions, + "order_minimum_quantity": orderMinimumQuantity, + "order_maximum_quantity": orderMaximumQuantity, + "allowed_quantities": allowedQuantities, + "allow_adding_only_existing_attribute_combinations": allowAddingOnlyExistingAttributeCombinations, + "disable_buy_button": disableBuyButton, + "disable_wishlist_button": disableWishlistButton, + "available_for_pre_order": availableForPreOrder, + "pre_order_availability_start_date_time_utc": preOrderAvailabilityStartDateTimeUtc, + "call_for_price": callForPrice, + "price": price, + "old_price": oldPrice, + "product_cost": productCost, + "special_price": specialPrice, + "special_price_start_date_time_utc": specialPriceStartDateTimeUtc, + "special_price_end_date_time_utc": specialPriceEndDateTimeUtc, + "customer_enters_price": customerEntersPrice, + "minimum_customer_entered_price": minimumCustomerEnteredPrice, + "maximum_customer_entered_price": maximumCustomerEnteredPrice, + "baseprice_enabled": basepriceEnabled, + "baseprice_amount": basepriceAmount, + "baseprice_base_amount": basepriceBaseAmount, + "has_tier_prices": hasTierPrices, + "has_discounts_applied": hasDiscountsApplied, + "discount_name": discountName, + "discount_namen": discountNamen, + "discount_description": discountDescription, + "discount_Descriptionn": discountDescriptionn, + "discount_percentage": discountPercentage, + "currency": currency, + "currencyn": currencyn, + "weight": weight, + "length": length, + "width": width, + "height": height, + "available_start_date_time_utc": availableStartDateTimeUtc, + "available_end_date_time_utc": availableEndDateTimeUtc, + "display_order": displayOrder, + "published": published, + "deleted": deleted, + "created_on_utc": createdOnUtc.toIso8601String(), + "updated_on_utc": updatedOnUtc.toIso8601String(), + "product_type": productTypeValues.reverse[productType], + "parent_grouped_product_id": parentGroupedProductId, + "role_ids": roleIds, + "discount_ids": discountIds, + "store_ids": storeIds, + "manufacturer_ids": manufacturerIds, + "reviews": List.from(reviews!.map((x) => x.toJson())), + "images": List.from(images!.map((x) => x.toJson())), + "attributes": attributes, + "specifications": specifications, + "associated_product_ids": associatedProductIds, + "tags": List.from(tags!.map((x) => x)), + "vendor_id": vendorId, + "se_name": seName, + }; } enum ProductType { SIMPLE_PRODUCT } -final productTypeValues = EnumValues({ - "SimpleProduct": ProductType.SIMPLE_PRODUCT -}); +final productTypeValues = EnumValues({"SimpleProduct": ProductType.SIMPLE_PRODUCT}); class Review { Review({ @@ -1156,7 +1155,7 @@ class Review { dynamic customerId; dynamic productId; dynamic storeId; - bool isApproved; + bool? isApproved; dynamic title; dynamic reviewText; dynamic replyText; @@ -1168,42 +1167,42 @@ class Review { dynamic product; factory Review.fromJson(Map json) => Review( - id: json["id"], - position: json["position"], - reviewId: json["review_id"], - customerId: json["customer_id"], - productId: json["product_id"], - storeId: json["store_id"], - isApproved: json["is_approved"], - title: titleValues.map[json["title"]], - reviewText: reviewTextValues.map[json["review_text"]], - replyText: json["reply_text"], - rating: json["rating"], - helpfulYesTotal: json["helpful_yes_total"], - helpfulNoTotal: json["helpful_no_total"], - createdOnUtc: DateTime.parse(json["created_on_utc"]), - customer: ReviewCustomer.fromJson(json["customer"]), - product: json["product"], - ); + id: json["id"], + position: json["position"], + reviewId: json["review_id"], + customerId: json["customer_id"], + productId: json["product_id"], + storeId: json["store_id"], + isApproved: json["is_approved"], + title: titleValues.map![json["title"]], + reviewText: reviewTextValues.map![json["review_text"]], + replyText: json["reply_text"], + rating: json["rating"], + helpfulYesTotal: json["helpful_yes_total"], + helpfulNoTotal: json["helpful_no_total"], + createdOnUtc: DateTime.parse(json["created_on_utc"]), + customer: ReviewCustomer.fromJson(json["customer"]), + product: json["product"], + ); Map toJson() => { - "id": id, - "position": position, - "review_id": reviewId, - "customer_id": customerId, - "product_id": productId, - "store_id": storeId, - "is_approved": isApproved, - "title": titleValues.reverse[title], - "review_text": reviewTextValues.reverse[reviewText], - "reply_text": replyText, - "rating": rating, - "helpful_yes_total": helpfulYesTotal, - "helpful_no_total": helpfulNoTotal, - "created_on_utc": createdOnUtc.toIso8601String(), - "customer": customer.toJson(), - "product": product, - }; + "id": id, + "position": position, + "review_id": reviewId, + "customer_id": customerId, + "product_id": productId, + "store_id": storeId, + "is_approved": isApproved, + "title": titleValues.reverse[title], + "review_text": reviewTextValues.reverse[reviewText], + "reply_text": replyText, + "rating": rating, + "helpful_yes_total": helpfulYesTotal, + "helpful_no_total": helpfulNoTotal, + "created_on_utc": createdOnUtc.toIso8601String(), + "customer": customer.toJson(), + "product": product, + }; } class ReviewCustomer { @@ -1252,9 +1251,9 @@ class ReviewCustomer { dynamic yahalaAccountno; dynamic billingAddress; dynamic shippingAddress; - List addresses; - String id; - String username; + List? addresses; + String? id; + String? username; dynamic email; dynamic firstName; dynamic lastName; @@ -1271,75 +1270,75 @@ class ReviewCustomer { dynamic lastLoginDateUtc; dynamic lastActivityDateUtc; dynamic registeredInStoreId; - List roleIds; + List? roleIds; factory ReviewCustomer.fromJson(Map json) => ReviewCustomer( - fileNumber: json["file_number"], - iqamaNumber: json["iqama_number"], - isOutSa: json["is_out_sa"], - patientType: json["patient_type"], - gender: json["gender"], - birthDate: DateTime.parse(json["birth_date"]), - phone: json["phone"], - countryCode: json["country_code"], - yahalaAccountno: json["yahala_accountno"], - billingAddress: json["billing_address"], - shippingAddress: json["shipping_address"], - addresses: List.from(json["addresses"].map((x) => x)), - id: json["id"], - username: json["username"], - email: purpleEmailValues.map[json["email"]], - firstName: json["first_name"], - lastName: json["last_name"], - languageId: json["language_id"], - adminComment: json["admin_comment"], - isTaxExempt: json["is_tax_exempt"], - hasShoppingCartItems: json["has_shopping_cart_items"], - active: json["active"], - deleted: json["deleted"], - isSystemAccount: json["is_system_account"], - systemName: json["system_name"], - lastIpAddress: json["last_ip_address"], - createdOnUtc: json["created_on_utc"], - lastLoginDateUtc: json["last_login_date_utc"], - lastActivityDateUtc: json["last_activity_date_utc"], - registeredInStoreId: json["registered_in_store_id"], - roleIds: List.from(json["role_ids"].map((x) => x)), - ); + fileNumber: json["file_number"], + iqamaNumber: json["iqama_number"], + isOutSa: json["is_out_sa"], + patientType: json["patient_type"], + gender: json["gender"], + birthDate: DateTime.parse(json["birth_date"]), + phone: json["phone"], + countryCode: json["country_code"], + yahalaAccountno: json["yahala_accountno"], + billingAddress: json["billing_address"], + shippingAddress: json["shipping_address"], + addresses: List.from(json["addresses"].map((x) => x)), + id: json["id"], + username: json["username"], + email: purpleEmailValues.map![json["email"]], + firstName: json["first_name"], + lastName: json["last_name"], + languageId: json["language_id"], + adminComment: json["admin_comment"], + isTaxExempt: json["is_tax_exempt"], + hasShoppingCartItems: json["has_shopping_cart_items"], + active: json["active"], + deleted: json["deleted"], + isSystemAccount: json["is_system_account"], + systemName: json["system_name"], + lastIpAddress: json["last_ip_address"], + createdOnUtc: json["created_on_utc"], + lastLoginDateUtc: json["last_login_date_utc"], + lastActivityDateUtc: json["last_activity_date_utc"], + registeredInStoreId: json["registered_in_store_id"], + roleIds: List.from(json["role_ids"].map((x) => x)), + ); Map toJson() => { - "file_number": fileNumber, - "iqama_number": iqamaNumber, - "is_out_sa": isOutSa, - "patient_type": patientType, - "gender": gender, - "birth_date": birthDate.toIso8601String(), - "phone": phone, - "country_code": countryCode, - "yahala_accountno": yahalaAccountno, - "billing_address": billingAddress, - "shipping_address": shippingAddress, - "addresses": List.from(addresses.map((x) => x)), - "id": id, - "username": username, - "email": purpleEmailValues.reverse[email], - "first_name": firstName, - "last_name": lastName, - "language_id": languageId, - "admin_comment": adminComment, - "is_tax_exempt": isTaxExempt, - "has_shopping_cart_items": hasShoppingCartItems, - "active": active, - "deleted": deleted, - "is_system_account": isSystemAccount, - "system_name": systemName, - "last_ip_address": lastIpAddress, - "created_on_utc": createdOnUtc, - "last_login_date_utc": lastLoginDateUtc, - "last_activity_date_utc": lastActivityDateUtc, - "registered_in_store_id": registeredInStoreId, - "role_ids": List.from(roleIds.map((x) => x)), - }; + "file_number": fileNumber, + "iqama_number": iqamaNumber, + "is_out_sa": isOutSa, + "patient_type": patientType, + "gender": gender, + "birth_date": birthDate.toIso8601String(), + "phone": phone, + "country_code": countryCode, + "yahala_accountno": yahalaAccountno, + "billing_address": billingAddress, + "shipping_address": shippingAddress, + "addresses": List.from(addresses!.map((x) => x)), + "id": id, + "username": username, + "email": purpleEmailValues.reverse[email], + "first_name": firstName, + "last_name": lastName, + "language_id": languageId, + "admin_comment": adminComment, + "is_tax_exempt": isTaxExempt, + "has_shopping_cart_items": hasShoppingCartItems, + "active": active, + "deleted": deleted, + "is_system_account": isSystemAccount, + "system_name": systemName, + "last_ip_address": lastIpAddress, + "created_on_utc": createdOnUtc, + "last_login_date_utc": lastLoginDateUtc, + "last_activity_date_utc": lastActivityDateUtc, + "registered_in_store_id": registeredInStoreId, + "role_ids": List.from(roleIds!.map((x) => x)), + }; } enum PurpleEmail { STEVE_GATES_NOP_COMMERCE_COM, TAMER_FANASHEH_DRSULAIMANALHABIB_COM, ASIF_RAZA_DRSULAIMANALHABIB_COM, ABOSAMI_YMAIL_COM } @@ -1369,13 +1368,9 @@ final reviewTextValues = EnumValues({ enum Title { EMPTY, GOOD, TITLE } -final titleValues = EnumValues({ - "": Title.EMPTY, - "Good": Title.GOOD, - "ممتاز": Title.TITLE -}); +final titleValues = EnumValues({"": Title.EMPTY, "Good": Title.GOOD, "ممتاز": Title.TITLE}); -enum OrderStatus { ORDER_SUBMITTED, PENDING, ORDER_IN_PROGRESS,ORDER_SENT_FOR_DELIVERY, ORDER_COMPLETED, CANCELLED, PROCESSING, ORDER_REFUNDED, COMPLETE } +enum OrderStatus { ORDER_SUBMITTED, PENDING, ORDER_IN_PROGRESS, ORDER_SENT_FOR_DELIVERY, ORDER_COMPLETED, CANCELLED, PROCESSING, ORDER_REFUNDED, COMPLETE } final orderStatusValues = EnumValues({ "Cancelled": OrderStatus.CANCELLED, @@ -1405,81 +1400,54 @@ final orderStatusnValues = EnumValues({ enum PaymentMethodSystemName { PAYMENTS_PAY_FORT, PAYMENTS_CASH_ON_DELIVERY } -final paymentMethodSystemNameValues = EnumValues({ - "Payments.CashOnDelivery": PaymentMethodSystemName.PAYMENTS_CASH_ON_DELIVERY, - "Payments.PayFort": PaymentMethodSystemName.PAYMENTS_PAY_FORT -}); +final paymentMethodSystemNameValues = EnumValues({"Payments.CashOnDelivery": PaymentMethodSystemName.PAYMENTS_CASH_ON_DELIVERY, "Payments.PayFort": PaymentMethodSystemName.PAYMENTS_PAY_FORT}); enum PaymentName { CREDIT_DEBIT_CARD_PAYFORT, CASH_ON_DELIVERY_COD } -final paymentNameValues = EnumValues({ - "Cash On Delivery (COD)": PaymentName.CASH_ON_DELIVERY_COD, - "Credit / Debit Card Payfort": PaymentName.CREDIT_DEBIT_CARD_PAYFORT -}); +final paymentNameValues = EnumValues({"Cash On Delivery (COD)": PaymentName.CASH_ON_DELIVERY_COD, "Credit / Debit Card Payfort": PaymentName.CREDIT_DEBIT_CARD_PAYFORT}); enum PaymentStatus { PAID, PENDING } -final paymentStatusValues = EnumValues({ - "Paid": PaymentStatus.PAID, - "Pending": PaymentStatus.PENDING -}); +final paymentStatusValues = EnumValues({"Paid": PaymentStatus.PAID, "Pending": PaymentStatus.PENDING}); enum PaymentStatusn { EMPTY, PAYMENT_STATUSN } -final paymentStatusnValues = EnumValues({ - "تم الدفع": PaymentStatusn.EMPTY, - "قيد الإنتظار": PaymentStatusn.PAYMENT_STATUSN -}); +final paymentStatusnValues = EnumValues({"تم الدفع": PaymentStatusn.EMPTY, "قيد الإنتظار": PaymentStatusn.PAYMENT_STATUSN}); enum PreferDeliveryTime { THE_1000_AM_330_PM, THE_530_PM_730_PM } -final preferDeliveryTimeValues = EnumValues({ - "10:00 AM - 3:30 PM": PreferDeliveryTime.THE_1000_AM_330_PM, - "5:30 PM - 7:30 PM": PreferDeliveryTime.THE_530_PM_730_PM -}); +final preferDeliveryTimeValues = EnumValues({"10:00 AM - 3:30 PM": PreferDeliveryTime.THE_1000_AM_330_PM, "5:30 PM - 7:30 PM": PreferDeliveryTime.THE_530_PM_730_PM}); enum PreferDeliveryTimen { THE_1000330, THE_530730 } -final preferDeliveryTimenValues = EnumValues({ - "10:00 ص - 3:30 م": PreferDeliveryTimen.THE_1000330, - "5:30 م - 7:30 م": PreferDeliveryTimen.THE_530730 -}); +final preferDeliveryTimenValues = EnumValues({"10:00 ص - 3:30 م": PreferDeliveryTimen.THE_1000330, "5:30 م - 7:30 م": PreferDeliveryTimen.THE_530730}); enum ShippingMethod { EMPTY, FIXED_PRICE } -final shippingMethodValues = EnumValues({ - "سعر ثابت ": ShippingMethod.EMPTY, - "Fixed Price": ShippingMethod.FIXED_PRICE -}); +final shippingMethodValues = EnumValues({"سعر ثابت ": ShippingMethod.EMPTY, "Fixed Price": ShippingMethod.FIXED_PRICE}); enum ShippingRateComputationMethodSystemName { SHIPPING_FIXED_OR_BY_WEIGHT } -final shippingRateComputationMethodSystemNameValues = EnumValues({ - "Shipping.FixedOrByWeight": ShippingRateComputationMethodSystemName.SHIPPING_FIXED_OR_BY_WEIGHT -}); +final shippingRateComputationMethodSystemNameValues = EnumValues({"Shipping.FixedOrByWeight": ShippingRateComputationMethodSystemName.SHIPPING_FIXED_OR_BY_WEIGHT}); enum ShippingStatus { NOT_YET_SHIPPED } -final shippingStatusValues = EnumValues({ - "NotYetShipped": ShippingStatus.NOT_YET_SHIPPED -}); +final shippingStatusValues = EnumValues({"NotYetShipped": ShippingStatus.NOT_YET_SHIPPED}); enum ShippingStatusn { EMPTY } -final shippingStatusnValues = EnumValues({ - "لم يتم شحنها بعد": ShippingStatusn.EMPTY -}); +final shippingStatusnValues = EnumValues({"لم يتم شحنها بعد": ShippingStatusn.EMPTY}); class EnumValues { - Map map; - Map reverseMap; + Map? map; + Map? reverseMap; EnumValues(this.map); Map get reverse { if (reverseMap == null) { - reverseMap = map.map((k, v) => new MapEntry(v, k)); + reverseMap = map!.map((k, v) => new MapEntry(v, k)); } - return reverseMap; + return reverseMap!; } -} \ No newline at end of file +} diff --git a/lib/core/model/pharmacies/orders_model.dart b/lib/core/model/pharmacies/orders_model.dart index 0ad94767..74caaf13 100644 --- a/lib/core/model/pharmacies/orders_model.dart +++ b/lib/core/model/pharmacies/orders_model.dart @@ -1,13 +1,13 @@ class OrdersModel { - List orders; + List? orders; OrdersModel({this.orders}); OrdersModel.fromJson(Map json) { if (json['orders'] != null) { - orders = new List(); + orders = []; json['orders'].forEach((v) { - orders.add(new Orders.fromJson(v)); + orders!.add(new Orders.fromJson(v)); }); } } @@ -15,26 +15,27 @@ class OrdersModel { Map toJson() { final Map data = new Map(); if (this.orders != null) { - data['orders'] = this.orders.map((v) => v.toJson()).toList(); + data['orders'] = this.orders!.map((v) => v.toJson()).toList(); } return data; } } class Orders { - String id; - int productCount; - double orderTotal; - String createdOnUtc; - int orderStatusId; - String orderStatus; - String orderStatusn; - bool canCancel; - bool canRefund; + String? id; + int? productCount; + dynamic orderTotal; + String? createdOnUtc; + int? orderStatusId; + String? orderStatus; + String? orderStatusn; + bool? canCancel; + bool? canRefund; + String? orderGuid; dynamic customerId; - double orderSubtotalExclTax; + dynamic orderSubtotalExclTax; dynamic orderShippingExclTax; - double orderTax; + dynamic orderTax; Orders( @@ -47,6 +48,7 @@ class Orders { this.orderStatusn, this.canCancel, this.canRefund, + this.orderGuid, this.customerId, this.orderShippingExclTax, this.orderSubtotalExclTax, @@ -63,10 +65,11 @@ class Orders { orderStatusn = json['order_statusn']; canCancel = json['can_cancel']; canRefund = json['can_refund']; + orderGuid = json['order_guid']; 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/core/model/pharmacies/payment-checkout-data.dart b/lib/core/model/pharmacies/payment-checkout-data.dart index dd9e0e54..60cd7b23 100644 --- a/lib/core/model/pharmacies/payment-checkout-data.dart +++ b/lib/core/model/pharmacies/payment-checkout-data.dart @@ -5,17 +5,15 @@ import 'package:flutter/material.dart'; import 'ShippingOption.dart'; -class PaymentCheckoutData with ChangeNotifier{ - Addresses address; - PaymentOption paymentOption; - LacumAccountInformation lacumInformation; - bool cartDataVisible; - ShippingOption shippingOption; - int usedLakumPoints; +class PaymentCheckoutData { + Addresses? address; + PaymentOption? paymentOption; + LacumAccountInformation? lacumInformation; + bool? cartDataVisible; + ShippingOption? shippingOption; + num? usedLakumPoints; PaymentCheckoutData({this.address, this.paymentOption, this.lacumInformation, this.cartDataVisible = false, this.shippingOption, this.usedLakumPoints = 0}); - void updateData() { - notifyListeners(); - } + } diff --git a/lib/core/model/pharmacies/pharmacies_list_model.dart b/lib/core/model/pharmacies/pharmacies_list_model.dart index 01a43a0a..1935be55 100644 --- a/lib/core/model/pharmacies/pharmacies_list_model.dart +++ b/lib/core/model/pharmacies/pharmacies_list_model.dart @@ -1,26 +1,26 @@ class PharmaciesListModel { - int itemID; - int patientTypeID; - int languageID; - String stamp; - String iPAdress; - double versionID; - String tokenID; - String sessionID; - bool isLoginForDoctorApp; - int patientOutSA; - int channel; - int doctorID; - int editedBy; - int projectID; - int clinicID; - double price; - String imageLocation; - String desLocation; - String itemDes; - String phoneNumber; - String longitude; - String latitude; + int? itemID; + int? patientTypeID; + int? languageID; + String? stamp; + String? iPAdress; + double? versionID; + String? tokenID; + String? sessionID; + bool? isLoginForDoctorApp; + int? patientOutSA; + int? channel; + int? doctorID; + int? editedBy; + int? projectID; + int? clinicID; + double? price; + String? imageLocation; + String? desLocation; + String? itemDes; + String? phoneNumber; + String? longitude; + String? latitude; PharmaciesListModel( {this.itemID, diff --git a/lib/core/model/pharmacies/pharmacies_model.dart b/lib/core/model/pharmacies/pharmacies_model.dart index d1b9b967..e6b41f14 100644 --- a/lib/core/model/pharmacies/pharmacies_model.dart +++ b/lib/core/model/pharmacies/pharmacies_model.dart @@ -1,26 +1,26 @@ class PharmaciesModel { - String pHRItemName; - int pageIndex; - int pageSize; - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - String sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; - int doctorID; - int editedBy; - int projectID; - int clinicID; - String tokenID; - String stamp; - bool isLoginForDoctorApp; - String itemDes; - String productImage; - int itemID; + String? pHRItemName; + int? pageIndex; + int? pageSize; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + String? sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + int? doctorID; + int? editedBy; + int? projectID; + int? clinicID; + String? tokenID; + String? stamp; + bool? isLoginForDoctorApp; + String? itemDes; + String? productImage; + int? itemID; PharmaciesModel( {this.pHRItemName, diff --git a/lib/core/model/pharmacies/recommendedProduct_model.dart b/lib/core/model/pharmacies/recommendedProduct_model.dart index e1e88cd8..c8f39955 100644 --- a/lib/core/model/pharmacies/recommendedProduct_model.dart +++ b/lib/core/model/pharmacies/recommendedProduct_model.dart @@ -1,247 +1,251 @@ class RecommendedProductModel { - List products; - - RecommendedProductModel({this.products}); - - RecommendedProductModel.fromJson(Map json) { - if (json['products'] != null) { - products = new List(); - json['products'].forEach((v) { - products.add(new Products.fromJson(v)); - }); - } - } - - Map toJson() { - final Map data = new Map(); - if (this.products != null) { - data['products'] = this.products.map((v) => v.toJson()).toList(); - } - return data; - } -} - -class Products { - String id; - bool visibleIndividually; - String name; - String namen; - String shortDescription; - String shortDescriptionn; - String fullDescription; - String fullDescriptionn; - bool markasNew; - bool showOnHomePage; - dynamic metaKeywords; - dynamic metaDescription; - dynamic metaTitle; - bool allowCustomerReviews; + dynamic id; + bool? visibleIndividually; + dynamic name; + dynamic namen; + List? localizedNames; + dynamic shortDescription; + dynamic shortDescriptionn; + dynamic fullDescription; + dynamic fullDescriptionn; + bool? markasNew; + bool? showOnHomePage; +// dynamic metaKeywords; +// dynamic metaDescription; +// dynamic metaTitle; + bool? allowCustomerReviews; dynamic approvedRatingSum; dynamic notApprovedRatingSum; dynamic approvedTotalReviews; dynamic notApprovedTotalReviews; - String sku; - bool isRx; - bool prescriptionRequired; + dynamic sku; + bool? isRx; + bool? prescriptionRequired; dynamic rxMessage; dynamic rxMessagen; - dynamic manufacturerPartNumber; - dynamic gtin; - bool isGiftCard; - bool requireOtherProducts; - bool automaticallyAddRequiredProducts; - bool isDownload; - bool unlimitedDownloads; +// dynamic manufacturerPartNumber; +// dynamic gtin; + bool? isGiftCard; + bool? requireOtherProducts; + bool? automaticallyAddRequiredProducts; + bool? isDownload; + bool? unlimitedDownloads; dynamic maxNumberOfDownloads; - dynamic downloadExpirationDays; - bool hasSampleDownload; - bool hasUserAgreement; - bool isRecurring; +// dynamic downloadExpirationDays; + bool? hasSampleDownload; + bool? hasUserAgreement; + bool? isRecurring; dynamic recurringCycleLength; dynamic recurringTotalCycles; - bool isRental; + bool? isRental; dynamic rentalPriceLength; - bool isShipEnabled; - bool isFreeShipping; - bool shipSeparately; + bool? isShipEnabled; + bool? isFreeShipping; + bool? shipSeparately; dynamic additionalShippingCharge; - bool isTaxExempt; - bool isTelecommunicationsOrBroadcastingOrElectronicServices; - bool useMultipleWarehouses; + bool? isTaxExempt; + bool? isTelecommunicationsOrBroadcastingOrElectronicServices; + bool? useMultipleWarehouses; dynamic manageInventoryMethodId; dynamic stockQuantity; - String stockAvailability; - String stockAvailabilityn; - bool displayStockAvailability; - bool displayStockQuantity; + dynamic stockAvailability; + dynamic stockAvailabilityn; + bool? displayStockAvailability; + bool? displayStockQuantity; dynamic minStockQuantity; dynamic notifyAdminForQuantityBelow; - bool allowBackInStockSubscriptions; + bool? allowBackInStockSubscriptions; dynamic orderMinimumQuantity; dynamic orderMaximumQuantity; - dynamic allowedQuantities; - bool allowAddingOnlyExistingAttributeCombinations; - bool disableBuyButton; - bool disableWishlistButton; - bool availableForPreOrder; - dynamic preOrderAvailabilityStartDateTimeUtc; - bool callForPrice; +// dynamic allowedQuantities; + bool? allowAddingOnlyExistingAttributeCombinations; + bool? disableBuyButton; + bool? disableWishlistButton; + bool? availableForPreOrder; +// dynamic preOrderAvailabilityStartDateTimeUtc; + bool? callForPrice; dynamic price; dynamic oldPrice; dynamic productCost; - dynamic specialPrice; - dynamic specialPriceStartDateTimeUtc; - dynamic specialPriceEndDateTimeUtc; - bool customerEntersPrice; +// dynamic specialPrice; +// dynamic specialPriceStartDateTimeUtc; +// dynamic specialPriceEndDateTimeUtc; + bool? customerEntersPrice; dynamic minimumCustomerEnteredPrice; dynamic maximumCustomerEnteredPrice; - bool basepriceEnabled; + bool? basepriceEnabled; dynamic basepriceAmount; dynamic basepriceBaseAmount; - bool hasTierPrices; - bool hasDiscountsApplied; - dynamic discountName; - dynamic discountNamen; - dynamic discountDescription; - dynamic discountDescriptionn; - dynamic discountPercentage; - String currency; - String currencyn; - double weight; + bool? hasTierPrices; + bool? hasDiscountsApplied; +// dynamic discountName; +// dynamic discountNamen; +// dynamic discountDescription; +// dynamic discountDescriptionn; +// dynamic discountPercentage; + dynamic currency; + dynamic currencyn; + dynamic weight; dynamic length; dynamic width; dynamic height; - dynamic availableStartDateTimeUtc; - dynamic availableEndDateTimeUtc; +// dynamic availableStartDateTimeUtc; +// dynamic availableEndDateTimeUtc; dynamic displayOrder; - bool published; - bool deleted; - String createdOnUtc; - String updatedOnUtc; - String productType; + bool? published; + bool? deleted; + dynamic createdOnUtc; + dynamic updatedOnUtc; + dynamic productType; dynamic parentGroupedProductId; +// List roleIds; +// List discountIds; +// List storeIds; + List? manufacturerIds; +// List reviews; + List? images; +// List attributes; + List? specifications; +// List associatedProductIds; +// List tags; dynamic vendorId; - String seName; - List images; + dynamic seName; + bool? isinwishlist; - Products({ - this.id, - this.visibleIndividually, - this.name, - this.namen, - this.shortDescription, - this.shortDescriptionn, - this.fullDescription, - this.fullDescriptionn, - this.markasNew, - this.showOnHomePage, - this.metaKeywords, - this.metaDescription, - this.metaTitle, - this.allowCustomerReviews, - this.approvedRatingSum, - this.notApprovedRatingSum, - this.approvedTotalReviews, - this.notApprovedTotalReviews, - this.sku, - this.isRx, - this.prescriptionRequired, - this.rxMessage, - this.rxMessagen, - this.manufacturerPartNumber, - this.gtin, - this.isGiftCard, - this.requireOtherProducts, - this.automaticallyAddRequiredProducts, - this.isDownload, - this.unlimitedDownloads, - this.maxNumberOfDownloads, - this.downloadExpirationDays, - this.hasSampleDownload, - this.hasUserAgreement, - this.isRecurring, - this.recurringCycleLength, - this.recurringTotalCycles, - this.isRental, - this.rentalPriceLength, - this.isShipEnabled, - this.isFreeShipping, - this.shipSeparately, - this.additionalShippingCharge, - this.isTaxExempt, - this.isTelecommunicationsOrBroadcastingOrElectronicServices, - this.useMultipleWarehouses, - this.manageInventoryMethodId, - this.stockQuantity, - this.stockAvailability, - this.stockAvailabilityn, - this.displayStockAvailability, - this.displayStockQuantity, - this.minStockQuantity, - this.notifyAdminForQuantityBelow, - this.allowBackInStockSubscriptions, - this.orderMinimumQuantity, - this.orderMaximumQuantity, - this.allowedQuantities, - this.allowAddingOnlyExistingAttributeCombinations, - this.disableBuyButton, - this.disableWishlistButton, - this.availableForPreOrder, - this.preOrderAvailabilityStartDateTimeUtc, - this.callForPrice, - this.price, - this.oldPrice, - this.productCost, - this.specialPrice, - this.specialPriceStartDateTimeUtc, - this.specialPriceEndDateTimeUtc, - this.customerEntersPrice, - this.minimumCustomerEnteredPrice, - this.maximumCustomerEnteredPrice, - this.basepriceEnabled, - this.basepriceAmount, - this.basepriceBaseAmount, - this.hasTierPrices, - this.hasDiscountsApplied, - this.discountName, - this.discountNamen, - this.discountDescription, - this.discountDescriptionn, - this.discountPercentage, - this.currency, - this.currencyn, - this.weight, - this.length, - this.width, - this.height, - this.availableStartDateTimeUtc, - this.availableEndDateTimeUtc, - this.displayOrder, - this.published, - this.deleted, - this.createdOnUtc, - this.updatedOnUtc, - this.productType, - this.parentGroupedProductId, - this.vendorId, - this.seName, - this.images, - }); + RecommendedProductModel( + {this.id, + this.visibleIndividually, + this.name, + this.namen, + this.localizedNames, + this.shortDescription, + this.shortDescriptionn, + this.fullDescription, + this.fullDescriptionn, + this.markasNew, + this.showOnHomePage, +// this.metaKeywords, +// this.metaDescription, +// this.metaTitle, + this.allowCustomerReviews, + this.approvedRatingSum, + this.notApprovedRatingSum, + this.approvedTotalReviews, + this.notApprovedTotalReviews, + this.sku, + this.isRx, + this.prescriptionRequired, + this.rxMessage, + this.rxMessagen, +// this.manufacturerPartNumber, +// this.gtin, + this.isGiftCard, + this.requireOtherProducts, + this.automaticallyAddRequiredProducts, + this.isDownload, + this.unlimitedDownloads, + this.maxNumberOfDownloads, +// this.downloadExpirationDays, + this.hasSampleDownload, + this.hasUserAgreement, + this.isRecurring, + this.recurringCycleLength, + this.recurringTotalCycles, + this.isRental, + this.rentalPriceLength, + this.isShipEnabled, + this.isFreeShipping, + this.shipSeparately, + this.additionalShippingCharge, + this.isTaxExempt, + this.isTelecommunicationsOrBroadcastingOrElectronicServices, + this.useMultipleWarehouses, + this.manageInventoryMethodId, + this.stockQuantity, + this.stockAvailability, + this.stockAvailabilityn, + this.displayStockAvailability, + this.displayStockQuantity, + this.minStockQuantity, + this.notifyAdminForQuantityBelow, + this.allowBackInStockSubscriptions, + this.orderMinimumQuantity, + this.orderMaximumQuantity, +// this.allowedQuantities, + this.allowAddingOnlyExistingAttributeCombinations, + this.disableBuyButton, + this.disableWishlistButton, + this.availableForPreOrder, +// this.preOrderAvailabilityStartDateTimeUtc, + this.callForPrice, + this.price, + this.oldPrice, + this.productCost, +// this.specialPrice, +// this.specialPriceStartDateTimeUtc, +// this.specialPriceEndDateTimeUtc, + this.customerEntersPrice, + this.minimumCustomerEnteredPrice, + this.maximumCustomerEnteredPrice, + this.basepriceEnabled, + this.basepriceAmount, + this.basepriceBaseAmount, + this.hasTierPrices, + this.hasDiscountsApplied, +// this.discountName, +// this.discountNamen, +// this.discountDescription, +// this.discountDescriptionn, +// this.discountPercentage, + this.currency, + this.currencyn, + this.weight, + this.length, + this.width, + this.height, +// this.availableStartDateTimeUtc, +// this.availableEndDateTimeUtc, + this.displayOrder, + this.published, + this.deleted, + this.createdOnUtc, + this.updatedOnUtc, + this.productType, + this.parentGroupedProductId, +// this.roleIds, +// this.discountIds, +// this.storeIds, + this.manufacturerIds, +// this.reviews, + this.images, +// this.attributes, + this.specifications, +// this.associatedProductIds, +// this.tags, + this.vendorId, + this.seName, + this.isinwishlist}); - Products.fromJson(Map json) { + RecommendedProductModel.fromJson(Map json) { id = json['id']; visibleIndividually = json['visible_individually']; name = json['name']; namen = json['namen']; + if (json['localized_names'] != null) { + localizedNames = []; + json['localized_names'].forEach((v) { + localizedNames!.add(new LocalizedNames.fromJson(v)); + }); + } shortDescription = json['short_description']; shortDescriptionn = json['short_descriptionn']; fullDescription = json['full_description']; fullDescriptionn = json['full_descriptionn']; markasNew = json['markas_new']; showOnHomePage = json['show_on_home_page']; - metaKeywords = json['meta_keywords']; - metaDescription = json['meta_description']; - metaTitle = json['meta_title']; +// metaKeywords = json['meta_keywords']; +// metaDescription = json['meta_description']; +// metaTitle = json['meta_title']; allowCustomerReviews = json['allow_customer_reviews']; approvedRatingSum = json['approved_rating_sum']; notApprovedRatingSum = json['not_approved_rating_sum']; @@ -252,16 +256,16 @@ class Products { prescriptionRequired = json['prescription_required']; rxMessage = json['rx_message']; rxMessagen = json['rx_messagen']; - manufacturerPartNumber = json['manufacturer_part_number']; - gtin = json['gtin']; +// manufacturerPartNumber = json['manufacturer_part_number']; +// gtin = json['gtin']; isGiftCard = json['is_gift_card']; requireOtherProducts = json['require_other_products']; automaticallyAddRequiredProducts = - json['automatically_add_required_products']; + json['automatically_add_required_products']; isDownload = json['is_download']; unlimitedDownloads = json['unlimited_downloads']; maxNumberOfDownloads = json['max_number_of_downloads']; - downloadExpirationDays = json['download_expiration_days']; +// downloadExpirationDays = json['download_expiration_days']; hasSampleDownload = json['has_sample_download']; hasUserAgreement = json['has_user_agreement']; isRecurring = json['is_recurring']; @@ -275,7 +279,7 @@ class Products { additionalShippingCharge = json['additional_shipping_charge']; isTaxExempt = json['is_tax_exempt']; isTelecommunicationsOrBroadcastingOrElectronicServices = - json['is_telecommunications_or_broadcasting_or_electronic_services']; + json['is_telecommunications_or_broadcasting_or_electronic_services']; useMultipleWarehouses = json['use_multiple_warehouses']; manageInventoryMethodId = json['manage_inventory_method_id']; stockQuantity = json['stock_quantity']; @@ -288,21 +292,21 @@ class Products { allowBackInStockSubscriptions = json['allow_back_in_stock_subscriptions']; orderMinimumQuantity = json['order_minimum_quantity']; orderMaximumQuantity = json['order_maximum_quantity']; - allowedQuantities = json['allowed_quantities']; +// allowedQuantities = json['allowed_quantities']; allowAddingOnlyExistingAttributeCombinations = - json['allow_adding_only_existing_attribute_combinations']; + json['allow_adding_only_existing_attribute_combinations']; disableBuyButton = json['disable_buy_button']; disableWishlistButton = json['disable_wishlist_button']; availableForPreOrder = json['available_for_pre_order']; - preOrderAvailabilityStartDateTimeUtc = - json['pre_order_availability_start_date_time_utc']; +// preOrderAvailabilityStartDateTimeUtc = +// json['pre_order_availability_start_date_time_utc']; callForPrice = json['call_for_price']; price = json['price']; oldPrice = json['old_price']; productCost = json['product_cost']; - specialPrice = json['special_price']; - specialPriceStartDateTimeUtc = json['special_price_start_date_time_utc']; - specialPriceEndDateTimeUtc = json['special_price_end_date_time_utc']; +// specialPrice = json['special_price']; +// specialPriceStartDateTimeUtc = json['special_price_start_date_time_utc']; +// specialPriceEndDateTimeUtc = json['special_price_end_date_time_utc']; customerEntersPrice = json['customer_enters_price']; minimumCustomerEnteredPrice = json['minimum_customer_entered_price']; maximumCustomerEnteredPrice = json['maximum_customer_entered_price']; @@ -311,19 +315,19 @@ class Products { basepriceBaseAmount = json['baseprice_base_amount']; hasTierPrices = json['has_tier_prices']; hasDiscountsApplied = json['has_discounts_applied']; - discountName = json['discount_name']; - discountNamen = json['discount_namen']; - discountDescription = json['discount_description']; - discountDescriptionn = json['discount_Descriptionn']; - discountPercentage = json['discount_percentage']; +// discountName = json['discount_name']; +// discountNamen = json['discount_namen']; +// discountDescription = json['discount_description']; +// discountDescriptionn = json['discount_Descriptionn']; +// discountPercentage = json['discount_percentage']; currency = json['currency']; currencyn = json['currencyn']; weight = json['weight']; length = json['length']; width = json['width']; height = json['height']; - availableStartDateTimeUtc = json['available_start_date_time_utc']; - availableEndDateTimeUtc = json['available_end_date_time_utc']; +// availableStartDateTimeUtc = json['available_start_date_time_utc']; +// availableEndDateTimeUtc = json['available_end_date_time_utc']; displayOrder = json['display_order']; published = json['published']; deleted = json['deleted']; @@ -331,14 +335,64 @@ class Products { updatedOnUtc = json['updated_on_utc']; productType = json['product_type']; parentGroupedProductId = json['parent_grouped_product_id']; - vendorId = json['vendor_id']; - seName = json['se_name']; +// if (json['role_ids'] != null) { +// roleIds = new List(); +// json['role_ids'].forEach((v) { +// roleIds.add(new dynamic.fromJson(v)); +// }); +// } +// if (json['discount_ids'] != null) { +// discountIds = new List(); +// json['discount_ids'].forEach((v) { +// discountIds.add(new dynamic.fromJson(v)); +// }); +// } +// if (json['store_ids'] != null) { +// storeIds = new List(); +// json['store_ids'].forEach((v) { +// storeIds.add(new dynamic.fromJson(v)); +// }); +// } + manufacturerIds = json['manufacturer_ids'].cast(); +// if (json['reviews'] != null) { +// reviews = new List(); +// json['reviews'].forEach((v) { +// reviews.add(new dynamic.fromJson(v)); +// }); +// } if (json['images'] != null) { - images = new List(); + images = []; json['images'].forEach((v) { - images.add(new Images.fromJson(v)); + images!.add(new Images.fromJson(v)); + }); + } +// if (json['attributes'] != null) { +// attributes = new List(); +// json['attributes'].forEach((v) { +// attributes.add(new dynamic.fromJson(v)); +// }); +// } + if (json['specifications'] != null) { + specifications = []; + json['specifications'].forEach((v) { + specifications!.add(new Specifications.fromJson(v)); }); } +// if (json['associated_product_ids'] != null) { +// associatedProductIds = new List(); +// json['associated_product_ids'].forEach((v) { +// associatedProductIds.add(new dynamic.fromJson(v)); +// }); +// } +// if (json['tags'] != null) { +// tags = new List(); +// json['tags'].forEach((v) { +// tags.add(new dynamic.fromJson(v)); +// }); +// } + vendorId = json['vendor_id']; + seName = json['se_name']; + isinwishlist = json['isinwishlist']; } Map toJson() { @@ -347,15 +401,19 @@ class Products { data['visible_individually'] = this.visibleIndividually; data['name'] = this.name; data['namen'] = this.namen; + if (this.localizedNames != null) { + data['localized_names'] = + this.localizedNames!.map((v) => v.toJson()).toList(); + } data['short_description'] = this.shortDescription; data['short_descriptionn'] = this.shortDescriptionn; data['full_description'] = this.fullDescription; data['full_descriptionn'] = this.fullDescriptionn; data['markas_new'] = this.markasNew; data['show_on_home_page'] = this.showOnHomePage; - data['meta_keywords'] = this.metaKeywords; - data['meta_description'] = this.metaDescription; - data['meta_title'] = this.metaTitle; +// data['meta_keywords'] = this.metaKeywords; +// data['meta_description'] = this.metaDescription; +// data['meta_title'] = this.metaTitle; data['allow_customer_reviews'] = this.allowCustomerReviews; data['approved_rating_sum'] = this.approvedRatingSum; data['not_approved_rating_sum'] = this.notApprovedRatingSum; @@ -366,8 +424,8 @@ class Products { data['prescription_required'] = this.prescriptionRequired; data['rx_message'] = this.rxMessage; data['rx_messagen'] = this.rxMessagen; - data['manufacturer_part_number'] = this.manufacturerPartNumber; - data['gtin'] = this.gtin; +// data['manufacturer_part_number'] = this.manufacturerPartNumber; +// data['gtin'] = this.gtin; data['is_gift_card'] = this.isGiftCard; data['require_other_products'] = this.requireOtherProducts; data['automatically_add_required_products'] = @@ -375,7 +433,7 @@ class Products { data['is_download'] = this.isDownload; data['unlimited_downloads'] = this.unlimitedDownloads; data['max_number_of_downloads'] = this.maxNumberOfDownloads; - data['download_expiration_days'] = this.downloadExpirationDays; +// data['download_expiration_days'] = this.downloadExpirationDays; data['has_sample_download'] = this.hasSampleDownload; data['has_user_agreement'] = this.hasUserAgreement; data['is_recurring'] = this.isRecurring; @@ -403,22 +461,22 @@ class Products { this.allowBackInStockSubscriptions; data['order_minimum_quantity'] = this.orderMinimumQuantity; data['order_maximum_quantity'] = this.orderMaximumQuantity; - data['allowed_quantities'] = this.allowedQuantities; +// data['allowed_quantities'] = this.allowedQuantities; data['allow_adding_only_existing_attribute_combinations'] = this.allowAddingOnlyExistingAttributeCombinations; data['disable_buy_button'] = this.disableBuyButton; data['disable_wishlist_button'] = this.disableWishlistButton; data['available_for_pre_order'] = this.availableForPreOrder; - data['pre_order_availability_start_date_time_utc'] = - this.preOrderAvailabilityStartDateTimeUtc; +// data['pre_order_availability_start_date_time_utc'] = +// this.preOrderAvailabilityStartDateTimeUtc; data['call_for_price'] = this.callForPrice; data['price'] = this.price; data['old_price'] = this.oldPrice; data['product_cost'] = this.productCost; - data['special_price'] = this.specialPrice; - data['special_price_start_date_time_utc'] = - this.specialPriceStartDateTimeUtc; - data['special_price_end_date_time_utc'] = this.specialPriceEndDateTimeUtc; +// data['special_price'] = this.specialPrice; +// data['special_price_start_date_time_utc'] = +// this.specialPriceStartDateTimeUtc; +// data['special_price_end_date_time_utc'] = this.specialPriceEndDateTimeUtc; data['customer_enters_price'] = this.customerEntersPrice; data['minimum_customer_entered_price'] = this.minimumCustomerEnteredPrice; data['maximum_customer_entered_price'] = this.maximumCustomerEnteredPrice; @@ -427,19 +485,19 @@ class Products { data['baseprice_base_amount'] = this.basepriceBaseAmount; data['has_tier_prices'] = this.hasTierPrices; data['has_discounts_applied'] = this.hasDiscountsApplied; - data['discount_name'] = this.discountName; - data['discount_namen'] = this.discountNamen; - data['discount_description'] = this.discountDescription; - data['discount_Descriptionn'] = this.discountDescriptionn; - data['discount_percentage'] = this.discountPercentage; +// data['discount_name'] = this.discountName; +// data['discount_namen'] = this.discountNamen; +// data['discount_description'] = this.discountDescription; +// data['discount_Descriptionn'] = this.discountDescriptionn; +// data['discount_percentage'] = this.discountPercentage; data['currency'] = this.currency; data['currencyn'] = this.currencyn; data['weight'] = this.weight; data['length'] = this.length; data['width'] = this.width; data['height'] = this.height; - data['available_start_date_time_utc'] = this.availableStartDateTimeUtc; - data['available_end_date_time_utc'] = this.availableEndDateTimeUtc; +// data['available_start_date_time_utc'] = this.availableStartDateTimeUtc; +// data['available_end_date_time_utc'] = this.availableEndDateTimeUtc; data['display_order'] = this.displayOrder; data['published'] = this.published; data['deleted'] = this.deleted; @@ -447,22 +505,68 @@ class Products { data['updated_on_utc'] = this.updatedOnUtc; data['product_type'] = this.productType; data['parent_grouped_product_id'] = this.parentGroupedProductId; - data['vendor_id'] = this.vendorId; - data['se_name'] = this.seName; +// if (this.roleIds != null) { +// data['role_ids'] = this.roleIds.map((v) => v.toJson()).toList(); +// } +// if (this.discountIds != null) { +// data['discount_ids'] = this.discountIds.map((v) => v.toJson()).toList(); +// } +// if (this.storeIds != null) { +// data['store_ids'] = this.storeIds.map((v) => v.toJson()).toList(); +// } + data['manufacturer_ids'] = this.manufacturerIds; +// if (this.reviews != null) { +// data['reviews'] = this.reviews.map((v) => v.toJson()).toList(); +// } if (this.images != null) { - data['images'] = this.images.map((v) => v.toJson()).toList(); + data['images'] = this.images!.map((v) => v.toJson()).toList(); + } +// if (this.attributes != null) { +// data['attributes'] = this.attributes.map((v) => v.toJson()).toList(); +// } + if (this.specifications != null) { + data['specifications'] = + this.specifications!.map((v) => v.toJson()).toList(); } +// if (this.associatedProductIds != null) { +// data['associated_product_ids'] = +// this.associatedProductIds.map((v) => v.toJson()).toList(); +// } +// if (this.tags != null) { +// data['tags'] = this.tags.map((v) => v.toJson()).toList(); +// } + data['vendor_id'] = this.vendorId; + data['se_name'] = this.seName; + data['isinwishlist'] = this.isinwishlist; + return data; + } +} + +class LocalizedNames { + dynamic languageId; + String? localizedName; + + LocalizedNames({this.languageId, this.localizedName}); + LocalizedNames.fromJson(Map json) { + languageId = json['language_id']; + localizedName = json['localized_name']; + } + + Map toJson() { + final Map data = new Map(); + data['language_id'] = this.languageId; + data['localized_name'] = this.localizedName; return data; } } class Images { - int id; - int position; - String src; - String thumb; - String attachment; + dynamic id; + dynamic position; + String? src; + String? thumb; + String? attachment; Images({this.id, this.position, this.src, this.thumb, this.attachment}); @@ -484,3 +588,40 @@ class Images { return data; } } + +class Specifications { + dynamic id; + dynamic displayOrder; + String? defaultValue; + String? defaultValuen; + String? name; + String? nameN; + + Specifications( + {this.id, + this.displayOrder, + this.defaultValue, + this.defaultValuen, + this.name, + this.nameN}); + + Specifications.fromJson(Map json) { + id = json['id']; + displayOrder = json['display_order']; + defaultValue = json['default_value']; + defaultValuen = json['default_valuen']; + name = json['name']; + nameN = json['nameN']; + } + + Map toJson() { + final Map data = new Map(); + data['id'] = this.id; + data['display_order'] = this.displayOrder; + data['default_value'] = this.defaultValue; + data['default_valuen'] = this.defaultValuen; + data['name'] = this.name; + data['nameN'] = this.nameN; + return data; + } +} \ No newline at end of file diff --git a/lib/core/model/pharmacy/brands_model.dart b/lib/core/model/pharmacy/brands_model.dart index 03cd689e..9747012f 100644 --- a/lib/core/model/pharmacy/brands_model.dart +++ b/lib/core/model/pharmacy/brands_model.dart @@ -1,8 +1,8 @@ class BrandsModel { - String id; - String name; - String namen; - Null image; + String? id; + String? name; + String? namen; + dynamic image; BrandsModel({this.id, this.name, this.namen, this.image}); diff --git a/lib/core/model/pharmacy/categorise_parent_model.dart b/lib/core/model/pharmacy/categorise_parent_model.dart index 82c5b55f..de67df68 100644 --- a/lib/core/model/pharmacy/categorise_parent_model.dart +++ b/lib/core/model/pharmacy/categorise_parent_model.dart @@ -1,13 +1,13 @@ class CategoriseParentModel { - String id; - String name; - String namen; - List localizedNames; + String? id; + String? name; + String? namen; + List? localizedNames; dynamic description; - int parentCategoryId; - int displayOrder; + int? parentCategoryId; + int? displayOrder; dynamic image; - bool isLeaf; + bool? isLeaf; CategoriseParentModel( {this.id, @@ -25,9 +25,9 @@ class CategoriseParentModel { name = json['name']; namen = json['namen']; if (json['localized_names'] != null) { - localizedNames = new List(); + localizedNames = []; json['localized_names'].forEach((v) { - localizedNames.add(new LocalizedNames.fromJson(v)); + localizedNames!.add(new LocalizedNames.fromJson(v)); }); } description = json['description']; @@ -44,7 +44,7 @@ class CategoriseParentModel { data['namen'] = this.namen; if (this.localizedNames != null) { data['localized_names'] = - this.localizedNames.map((v) => v.toJson()).toList(); + this.localizedNames!.map((v) => v.toJson()).toList(); } data['description'] = this.description; data['parent_category_id'] = this.parentCategoryId; @@ -56,8 +56,8 @@ class CategoriseParentModel { } class LocalizedNames { - int languageId; - String localizedName; + int? languageId; + String? localizedName; LocalizedNames({this.languageId, this.localizedName}); diff --git a/lib/core/model/pharmacy/final_products_model.dart b/lib/core/model/pharmacy/final_products_model.dart index 52ab1d2d..d2d0ccae 100644 --- a/lib/core/model/pharmacy/final_products_model.dart +++ b/lib/core/model/pharmacy/final_products_model.dart @@ -1,21 +1,21 @@ class FinalProductsModel { - String id; - String name; - String namen; - List localizedNames; - String shortDescription; - String fullDescription; - String fullDescriptionn; + String? id; + String? name; + String? namen; + List? localizedNames; + String? shortDescription; + String? fullDescription; + String? fullDescriptionn; dynamic approvedRatingSum; dynamic approvedTotalReviews; - String sku; - bool isRx; + String? sku; + bool? isRx; dynamic rxMessage; dynamic rxMessagen; dynamic stockQuantity; - String stockAvailability; - String stockAvailabilityn; - bool allowBackInStockSubscriptions; + String? stockAvailability; + String? stockAvailabilityn; + bool? allowBackInStockSubscriptions; dynamic orderMinimumQuantity; dynamic orderMaximumQuantity; dynamic price; @@ -24,9 +24,9 @@ class FinalProductsModel { dynamic discountNamen; dynamic discountPercentage; dynamic displayOrder; - List discountIds; - List reviews; - List images; + List? discountIds; + List? reviews; + List? images; FinalProductsModel( {this.id, @@ -62,16 +62,16 @@ class FinalProductsModel { id = json['id']; name = json['name']; if (json['images'] != null) { - images = new List(); + images = []; json['images'].forEach((v) { - images.add(new Images.fromJson(v)); + images!.add(new Images.fromJson(v)); }); } namen = json['namen']; if (json['localized_names'] != null) { - localizedNames = new List(); + localizedNames = []; json['localized_names'].forEach((v) { - localizedNames.add(new LocalizedNames.fromJson(v)); + localizedNames!.add(new LocalizedNames.fromJson(v)); }); } shortDescription = json['short_description']; @@ -104,7 +104,7 @@ class FinalProductsModel { data['namen'] = this.namen; if (this.localizedNames != null) { data['localized_names'] = - this.localizedNames.map((v) => v.toJson()).toList(); + this.localizedNames!.map((v) => v.toJson()).toList(); } data['short_description'] = this.shortDescription; data['full_description'] = this.fullDescription; @@ -130,15 +130,15 @@ class FinalProductsModel { data['display_order'] = this.displayOrder; if (this.images != null) { - data['images'] = this.images.map((v) => v.toJson()).toList(); + data['images'] = this.images!.map((v) => v.toJson()).toList(); } return data; } } class LocalizedNames { - int languageId; - String localizedName; + int? languageId; + String? localizedName; LocalizedNames({this.languageId, this.localizedName}); @@ -156,11 +156,11 @@ class LocalizedNames { } class Images { - int id; - int position; - String src; - String thumb; - String attachment; + int? id; + int? position; + String? src; + String? thumb; + String? attachment; Images({this.id, this.position, this.src, this.thumb, this.attachment}); diff --git a/lib/core/model/pharmacy/offer_products_model.dart b/lib/core/model/pharmacy/offer_products_model.dart index f41b731b..52520e39 100644 --- a/lib/core/model/pharmacy/offer_products_model.dart +++ b/lib/core/model/pharmacy/offer_products_model.dart @@ -1,90 +1,90 @@ class OfferProductsModel { - String id; - bool visibleIndividually; - String name; - String namen; - List localizedNames; - String shortDescription; - String shortDescriptionn; - String fullDescription; - String fullDescriptionn; - bool markasNew; - bool showOnHomePage; + String? id; + bool? visibleIndividually; + String? name; + String? namen; + List? localizedNames; + String? shortDescription; + String? shortDescriptionn; + String? fullDescription; + String? fullDescriptionn; + bool? markasNew; + bool? showOnHomePage; dynamic metaKeywords; dynamic metaDescription; dynamic metaTitle; - bool allowCustomerReviews; + bool? allowCustomerReviews; dynamic approvedRatingSum; dynamic notApprovedRatingSum; dynamic approvedTotalReviews; dynamic notApprovedTotalReviews; - String sku; - bool isRx; - bool prescriptionRequired; + String? sku; + bool? isRx; + bool? prescriptionRequired; dynamic rxMessage; dynamic rxMessagen; dynamic manufacturerPartNumber; dynamic gtin; - bool isGiftCard; - bool requireOtherProducts; - bool automaticallyAddRequiredProducts; - bool isDownload; - bool unlimitedDownloads; + bool? isGiftCard; + bool? requireOtherProducts; + bool? automaticallyAddRequiredProducts; + bool? isDownload; + bool? unlimitedDownloads; dynamic maxNumberOfDownloads; dynamic downloadExpirationDays; - bool hasSampleDownload; - bool hasUserAgreement; - bool isRecurring; + bool? hasSampleDownload; + bool? hasUserAgreement; + bool? isRecurring; dynamic recurringCycleLength; dynamic recurringTotalCycles; - bool isRental; + bool? isRental; dynamic rentalPriceLength; - bool isShipEnabled; - bool isFreeShipping; - bool shipSeparately; + bool? isShipEnabled; + bool? isFreeShipping; + bool? shipSeparately; dynamic additionalShippingCharge; - bool isTaxExempt; - bool isTelecommunicationsOrBroadcastingOrElectronicServices; - bool useMultipleWarehouses; + bool? isTaxExempt; + bool? isTelecommunicationsOrBroadcastingOrElectronicServices; + bool? useMultipleWarehouses; dynamic manageInventoryMethodId; dynamic stockQuantity; - String stockAvailability; - String stockAvailabilityn; - bool displayStockAvailability; - bool displayStockQuantity; + String? stockAvailability; + String? stockAvailabilityn; + bool? displayStockAvailability; + bool? displayStockQuantity; dynamic minStockQuantity; dynamic notifyAdminForQuantityBelow; - bool allowBackInStockSubscriptions; + bool? allowBackInStockSubscriptions; dynamic orderMinimumQuantity; dynamic orderMaximumQuantity; dynamic allowedQuantities; - bool allowAddingOnlyExistingAttributeCombinations; - bool disableBuyButton; - bool disableWishlistButton; - bool availableForPreOrder; + bool? allowAddingOnlyExistingAttributeCombinations; + bool? disableBuyButton; + bool? disableWishlistButton; + bool? availableForPreOrder; dynamic preOrderAvailabilityStartDateTimeUtc; - bool callForPrice; + bool? callForPrice; dynamic price; dynamic oldPrice; dynamic productCost; dynamic specialPrice; dynamic specialPriceStartDateTimeUtc; dynamic specialPriceEndDateTimeUtc; - bool customerEntersPrice; + bool? customerEntersPrice; dynamic minimumCustomerEnteredPrice; dynamic maximumCustomerEnteredPrice; - bool basepriceEnabled; + bool? basepriceEnabled; dynamic basepriceAmount; dynamic basepriceBaseAmount; - bool hasTierPrices; - bool hasDiscountsApplied; - String discountName; - String discountNamen; - String discountDescription; - String discountDescriptionn; + bool? hasTierPrices; + bool? hasDiscountsApplied; + String? discountName; + String? discountNamen; + String? discountDescription; + String? discountDescriptionn; dynamic discountPercentage; - String currency; - String currencyn; + String? currency; + String? currencyn; dynamic weight; dynamic length; dynamic width; @@ -92,24 +92,24 @@ class OfferProductsModel { dynamic availableStartDateTimeUtc; dynamic availableEndDateTimeUtc; dynamic displayOrder; - bool published; - bool deleted; - String createdOnUtc; - String updatedOnUtc; - String productType; + bool? published; + bool? deleted; + String? createdOnUtc; + String? updatedOnUtc; + String? productType; dynamic parentGroupedProductId; - List roleIds; - List discountIds; - List storeIds; - List manufacturerIds; - List reviews; - List images; - List attributes; - List specifications; - List associatedProductIds; - List tags; + List? roleIds; + List? discountIds; + List? storeIds; + List? manufacturerIds; + List? reviews; + List? images; + List? attributes; + List? specifications; + List? associatedProductIds; + List? tags; dynamic vendorId; - String seName; + String? seName; OfferProductsModel( {this.id, @@ -230,9 +230,9 @@ class OfferProductsModel { name = json['name']; namen = json['namen']; if (json['localized_names'] != null) { - localizedNames = new List(); + localizedNames = []; json['localized_names'].forEach((v) { - localizedNames.add(new LocalizedNames.fromJson(v)); + localizedNames!.add(new LocalizedNames.fromJson(v)); }); } shortDescription = json['short_description']; @@ -337,9 +337,9 @@ class OfferProductsModel { discountIds = json['discount_ids'].cast(); if (json['images'] != null) { - images = new List(); + images = []; json['images'].forEach((v) { - images.add(new Images.fromJson(v)); + images!.add(new Images.fromJson(v)); }); } @@ -355,7 +355,7 @@ class OfferProductsModel { data['namen'] = this.namen; if (this.localizedNames != null) { data['localized_names'] = - this.localizedNames.map((v) => v.toJson()).toList(); + this.localizedNames!.map((v) => v.toJson()).toList(); } data['short_description'] = this.shortDescription; data['short_descriptionn'] = this.shortDescriptionn; @@ -458,35 +458,35 @@ class OfferProductsModel { data['product_type'] = this.productType; data['parent_grouped_product_id'] = this.parentGroupedProductId; if (this.roleIds != null) { - data['role_ids'] = this.roleIds.map((v) => v.toJson()).toList(); + data['role_ids'] = this.roleIds!.map((v) => v.toJson()).toList(); } data['discount_ids'] = this.discountIds; if (this.storeIds != null) { - data['store_ids'] = this.storeIds.map((v) => v.toJson()).toList(); + data['store_ids'] = this.storeIds!.map((v) => v.toJson()).toList(); } if (this.manufacturerIds != null) { data['manufacturer_ids'] = - this.manufacturerIds.map((v) => v.toJson()).toList(); + this.manufacturerIds!.map((v) => v.toJson()).toList(); } if (this.reviews != null) { - data['reviews'] = this.reviews.map((v) => v.toJson()).toList(); + data['reviews'] = this.reviews!.map((v) => v.toJson()).toList(); } if (this.images != null) { - data['images'] = this.images.map((v) => v.toJson()).toList(); + data['images'] = this.images!.map((v) => v.toJson()).toList(); } if (this.attributes != null) { - data['attributes'] = this.attributes.map((v) => v.toJson()).toList(); + data['attributes'] = this.attributes!.map((v) => v.toJson()).toList(); } if (this.specifications != null) { data['specifications'] = - this.specifications.map((v) => v.toJson()).toList(); + this.specifications!.map((v) => v.toJson()).toList(); } if (this.associatedProductIds != null) { data['associated_product_ids'] = - this.associatedProductIds.map((v) => v.toJson()).toList(); + this.associatedProductIds!.map((v) => v.toJson()).toList(); } if (this.tags != null) { - data['tags'] = this.tags.map((v) => v.toJson()).toList(); + data['tags'] = this.tags!.map((v) => v.toJson()).toList(); } data['vendor_id'] = this.vendorId; data['se_name'] = this.seName; @@ -495,8 +495,8 @@ class OfferProductsModel { } class LocalizedNames { - int languageId; - String localizedName; + int? languageId; + String? localizedName; LocalizedNames({this.languageId, this.localizedName}); @@ -514,11 +514,11 @@ class LocalizedNames { } class Images { - int id; - int position; - String src; - String thumb; - String attachment; + int? id; + int? position; + String? src; + String? thumb; + String? attachment; Images({this.id, this.position, this.src, this.thumb, this.attachment}); @@ -542,12 +542,12 @@ class Images { } class Specifications { - int id; - int displayOrder; - String defaultValue; - String defaultValuen; - String name; - String nameN; + int? id; + int? displayOrder; + String? defaultValue; + String? defaultValuen; + String? name; + String? nameN; Specifications( {this.id, diff --git a/lib/core/model/pharmacy/offers_model.dart b/lib/core/model/pharmacy/offers_model.dart index 3add1d3d..99d31135 100644 --- a/lib/core/model/pharmacy/offers_model.dart +++ b/lib/core/model/pharmacy/offers_model.dart @@ -1,31 +1,31 @@ class OffersModel { - String id; - String name; - String namen; - List localizedNames; - Null description; - int categoryTemplateId; - String metaKeywords; - String metaDescription; - String metaTitle; - int parentCategoryId; - int pageSize; - String pageSizeOptions; - Null priceRanges; - bool showOnHomePage; - bool includeInTopMenu; - Null hasDiscountsApplied; - bool published; - bool deleted; - int displayOrder; - String createdOnUtc; - String updatedOnUtc; - List roleIds; - List discountIds; - List storeIds; - Image image; - String seName; - bool isLeaf; + String? id; + String? name; + String? namen; + List? localizedNames; + dynamic description; + int? categoryTemplateId; + String? metaKeywords; + String? metaDescription; + String? metaTitle; + int? parentCategoryId; + int? pageSize; + String? pageSizeOptions; + dynamic priceRanges; + bool? showOnHomePage; + bool? includeInTopMenu; + dynamic hasDiscountsApplied; + bool? published; + bool? deleted; + int? displayOrder; + String? createdOnUtc; + String? updatedOnUtc; + List? roleIds; + List? discountIds; + List? storeIds; + Image? image; + String? seName; + bool? isLeaf; OffersModel( {this.id, @@ -61,9 +61,9 @@ class OffersModel { name = json['name']; namen = json['namen']; if (json['localized_names'] != null) { - localizedNames = new List(); + localizedNames =[]; json['localized_names'].forEach((v) { - localizedNames.add(new LocalizedNames.fromJson(v)); + localizedNames!.add(new LocalizedNames.fromJson(v)); }); } description = json['description']; @@ -96,7 +96,7 @@ class OffersModel { data['namen'] = this.namen; if (this.localizedNames != null) { data['localized_names'] = - this.localizedNames.map((v) => v.toJson()).toList(); + this.localizedNames!.map((v) => v.toJson()).toList(); } data['description'] = this.description; data['category_template_id'] = this.categoryTemplateId; @@ -116,16 +116,16 @@ class OffersModel { data['created_on_utc'] = this.createdOnUtc; data['updated_on_utc'] = this.updatedOnUtc; if (this.roleIds != null) { - data['role_ids'] = this.roleIds.map((v) => v.toJson()).toList(); + data['role_ids'] = this.roleIds!.map((v) => v.toJson()).toList(); } if (this.discountIds != null) { - data['discount_ids'] = this.discountIds.map((v) => v.toJson()).toList(); + data['discount_ids'] = this.discountIds!.map((v) => v.toJson()).toList(); } if (this.storeIds != null) { - data['store_ids'] = this.storeIds.map((v) => v.toJson()).toList(); + data['store_ids'] = this.storeIds!.map((v) => v.toJson()).toList(); } if (this.image != null) { - data['image'] = this.image.toJson(); + data['image'] = this.image!.toJson(); } data['se_name'] = this.seName; data['is_leaf'] = this.isLeaf; @@ -134,8 +134,8 @@ class OffersModel { } class LocalizedNames { - int languageId; - String localizedName; + int? languageId; + String? localizedName; LocalizedNames({this.languageId, this.localizedName}); @@ -153,9 +153,9 @@ class LocalizedNames { } class Image { - String src; - Null thumb; - Null attachment; + String? src; + dynamic thumb; + dynamic attachment; Image({this.src, this.thumb, this.attachment}); diff --git a/lib/core/model/pharmacy/parent_products_model.dart b/lib/core/model/pharmacy/parent_products_model.dart index 55495416..14d4f03d 100644 --- a/lib/core/model/pharmacy/parent_products_model.dart +++ b/lib/core/model/pharmacy/parent_products_model.dart @@ -3,7 +3,7 @@ class ParentProductsModel { dynamic visibleIndividually; dynamic name; dynamic namen; - List localizedNames; + List? localizedNames; dynamic shortDescription; dynamic shortDescriptionn; dynamic fullDescription; @@ -98,18 +98,18 @@ class ParentProductsModel { dynamic updatedOnUtc; dynamic productType; dynamic parentGroupedProductId; - List roleIds; - List discountIds; - List storeIds; - List manufacturerIds; - List reviews; - List images; - List attributes; - List specifications; - List associatedProductIds; - List tags; + List? roleIds; + List? discountIds; + List? storeIds; + List? manufacturerIds; + List? reviews; + List? images; + List? attributes; + List? specifications; + List? associatedProductIds; + List? tags; dynamic vendorId; - String seName; + String? seName; ParentProductsModel( {this.id, @@ -229,16 +229,16 @@ class ParentProductsModel { visibleIndividually = json['visible_individually']; name = json['name']; if (json['images'] != null) { - images = new List(); + images = []; json['images'].forEach((v) { - images.add(new Images.fromJson(v)); + images!.add(new Images.fromJson(v)); }); } namen = json['namen']; if (json['localized_names'] != null) { - localizedNames = new List(); + localizedNames = []; json['localized_names'].forEach((v) { - localizedNames.add(new LocalizedNames.fromJson(v)); + localizedNames!.add(new LocalizedNames.fromJson(v)); }); } shortDescription = json['short_description']; @@ -264,8 +264,7 @@ class ParentProductsModel { gtin = json['gtin']; isGiftCard = json['is_gift_card']; requireOtherProducts = json['require_other_products']; - automaticallyAddRequiredProducts = - json['automatically_add_required_products']; + automaticallyAddRequiredProducts = json['automatically_add_required_products']; isDownload = json['is_download']; unlimitedDownloads = json['unlimited_downloads']; maxNumberOfDownloads = json['max_number_of_downloads']; @@ -282,8 +281,7 @@ class ParentProductsModel { shipSeparately = json['ship_separately']; additionalShippingCharge = json['additional_shipping_charge']; isTaxExempt = json['is_tax_exempt']; - isTelecommunicationsOrBroadcastingOrElectronicServices = - json['is_telecommunications_or_broadcasting_or_electronic_services']; + isTelecommunicationsOrBroadcastingOrElectronicServices = json['is_telecommunications_or_broadcasting_or_electronic_services']; useMultipleWarehouses = json['use_multiple_warehouses']; manageInventoryMethodId = json['manage_inventory_method_id']; stockQuantity = json['stock_quantity']; @@ -297,13 +295,11 @@ class ParentProductsModel { orderMinimumQuantity = json['order_minimum_quantity']; orderMaximumQuantity = json['order_maximum_quantity']; allowedQuantities = json['allowed_quantities']; - allowAddingOnlyExistingAttributeCombinations = - json['allow_adding_only_existing_attribute_combinations']; + allowAddingOnlyExistingAttributeCombinations = json['allow_adding_only_existing_attribute_combinations']; disableBuyButton = json['disable_buy_button']; disableWishlistButton = json['disable_wishlist_button']; availableForPreOrder = json['available_for_pre_order']; - preOrderAvailabilityStartDateTimeUtc = - json['pre_order_availability_start_date_time_utc']; + preOrderAvailabilityStartDateTimeUtc = json['pre_order_availability_start_date_time_utc']; callForPrice = json['call_for_price']; price = json['price']; oldPrice = json['old_price']; @@ -343,9 +339,9 @@ class ParentProductsModel { manufacturerIds = json['manufacturer_ids'].cast(); if (json['specifications'] != null) { - specifications = new List(); + specifications = []; json['specifications'].forEach((v) { - specifications.add(new Specifications.fromJson(v)); + specifications!.add(new Specifications.fromJson(v)); }); } @@ -360,8 +356,7 @@ class ParentProductsModel { data['name'] = this.name; data['namen'] = this.namen; if (this.localizedNames != null) { - data['localized_names'] = - this.localizedNames.map((v) => v.toJson()).toList(); + data['localized_names'] = this.localizedNames!.map((v) => v.toJson()).toList(); } data['short_description'] = this.shortDescription; data['short_descriptionn'] = this.shortDescriptionn; @@ -386,8 +381,7 @@ class ParentProductsModel { data['gtin'] = this.gtin; data['is_gift_card'] = this.isGiftCard; data['require_other_products'] = this.requireOtherProducts; - data['automatically_add_required_products'] = - this.automaticallyAddRequiredProducts; + data['automatically_add_required_products'] = this.automaticallyAddRequiredProducts; data['is_download'] = this.isDownload; data['unlimited_downloads'] = this.unlimitedDownloads; data['max_number_of_downloads'] = this.maxNumberOfDownloads; @@ -404,8 +398,7 @@ class ParentProductsModel { data['ship_separately'] = this.shipSeparately; data['additional_shipping_charge'] = this.additionalShippingCharge; data['is_tax_exempt'] = this.isTaxExempt; - data['is_telecommunications_or_broadcasting_or_electronic_services'] = - this.isTelecommunicationsOrBroadcastingOrElectronicServices; + data['is_telecommunications_or_broadcasting_or_electronic_services'] = this.isTelecommunicationsOrBroadcastingOrElectronicServices; data['use_multiple_warehouses'] = this.useMultipleWarehouses; data['manage_inventory_method_id'] = this.manageInventoryMethodId; data['stock_quantity'] = this.stockQuantity; @@ -415,25 +408,21 @@ class ParentProductsModel { data['display_stock_quantity'] = this.displayStockQuantity; data['min_stock_quantity'] = this.minStockQuantity; data['notify_admin_for_quantity_below'] = this.notifyAdminForQuantityBelow; - data['allow_back_in_stock_subscriptions'] = - this.allowBackInStockSubscriptions; + data['allow_back_in_stock_subscriptions'] = this.allowBackInStockSubscriptions; data['order_minimum_quantity'] = this.orderMinimumQuantity; data['order_maximum_quantity'] = this.orderMaximumQuantity; data['allowed_quantities'] = this.allowedQuantities; - data['allow_adding_only_existing_attribute_combinations'] = - this.allowAddingOnlyExistingAttributeCombinations; + data['allow_adding_only_existing_attribute_combinations'] = this.allowAddingOnlyExistingAttributeCombinations; data['disable_buy_button'] = this.disableBuyButton; data['disable_wishlist_button'] = this.disableWishlistButton; data['available_for_pre_order'] = this.availableForPreOrder; - data['pre_order_availability_start_date_time_utc'] = - this.preOrderAvailabilityStartDateTimeUtc; + data['pre_order_availability_start_date_time_utc'] = this.preOrderAvailabilityStartDateTimeUtc; data['call_for_price'] = this.callForPrice; data['price'] = this.price; data['old_price'] = this.oldPrice; data['product_cost'] = this.productCost; data['special_price'] = this.specialPrice; - data['special_price_start_date_time_utc'] = - this.specialPriceStartDateTimeUtc; + data['special_price_start_date_time_utc'] = this.specialPriceStartDateTimeUtc; data['special_price_end_date_time_utc'] = this.specialPriceEndDateTimeUtc; data['customer_enters_price'] = this.customerEntersPrice; data['minimum_customer_entered_price'] = this.minimumCustomerEnteredPrice; @@ -467,12 +456,11 @@ class ParentProductsModel { data['manufacturer_ids'] = this.manufacturerIds; if (this.images != null) { - data['images'] = this.images.map((v) => v.toJson()).toList(); + data['images'] = this.images!.map((v) => v.toJson()).toList(); } if (this.specifications != null) { - data['specifications'] = - this.specifications.map((v) => v.toJson()).toList(); + data['specifications'] = this.specifications!.map((v) => v.toJson()).toList(); } data['vendor_id'] = this.vendorId; @@ -482,8 +470,8 @@ class ParentProductsModel { } class LocalizedNames { - int languageId; - String localizedName; + int? languageId; + String? localizedName; LocalizedNames({this.languageId, this.localizedName}); @@ -501,11 +489,11 @@ class LocalizedNames { } class Images { - int id; - int position; - String src; - String thumb; - String attachment; + int? id; + int? position; + String? src; + String? thumb; + String? attachment; Images({this.id, this.position, this.src, this.thumb, this.attachment}); @@ -529,20 +517,14 @@ class Images { } class Specifications { - int id; - int displayOrder; - String defaultValue; - String defaultValuen; - String name; - String nameN; + int? id; + int? displayOrder; + String? defaultValue; + String? defaultValuen; + String? name; + String? nameN; - Specifications( - {this.id, - this.displayOrder, - this.defaultValue, - this.defaultValuen, - this.name, - this.nameN}); + Specifications({this.id, this.displayOrder, this.defaultValue, this.defaultValuen, this.name, this.nameN}); Specifications.fromJson(Map json) { id = json['id']; diff --git a/lib/core/model/pharmacy/pharmacy_categorise.dart b/lib/core/model/pharmacy/pharmacy_categorise.dart index 33ac26f1..7b0762e9 100644 --- a/lib/core/model/pharmacy/pharmacy_categorise.dart +++ b/lib/core/model/pharmacy/pharmacy_categorise.dart @@ -1,24 +1,15 @@ class PharmacyCategorise { dynamic id; - String name; + String? name; dynamic namen; - List localizedNames; + List? localizedNames; dynamic description; dynamic parentCategoryId; dynamic displayOrder; dynamic image; dynamic isLeaf; - PharmacyCategorise( - {this.id, - this.name, - this.namen, - this.localizedNames, - this.description, - this.parentCategoryId, - this.displayOrder, - this.image, - this.isLeaf}); + PharmacyCategorise({this.id, this.name, this.namen, this.localizedNames, this.description, this.parentCategoryId, this.displayOrder, this.image, this.isLeaf}); PharmacyCategorise.fromJson(Map json) { try { @@ -26,9 +17,9 @@ class PharmacyCategorise { name = json['name']; namen = json['namen']; if (json['localized_names'] != null) { - localizedNames = new List(); + localizedNames = []; json['localized_names'].forEach((v) { - localizedNames.add(new LocalizedNames.fromJson(v)); + localizedNames!.add(new LocalizedNames.fromJson(v)); }); } description = json['description']; @@ -47,8 +38,7 @@ class PharmacyCategorise { data['name'] = this.name; data['namen'] = this.namen; if (this.localizedNames != null) { - data['localized_names'] = - this.localizedNames.map((v) => v.toJson()).toList(); + data['localized_names'] = this.localizedNames!.map((v) => v.toJson()).toList(); } data['description'] = this.description; data['parent_category_id'] = this.parentCategoryId; @@ -62,8 +52,8 @@ class PharmacyCategorise { } class LocalizedNames { - int languageId; - String localizedName; + int? languageId; + String? localizedName; LocalizedNames({this.languageId, this.localizedName}); @@ -81,9 +71,9 @@ class LocalizedNames { } class Image { - String src; - Null thumb; - Null attachment; + String? src; + dynamic thumb; + dynamic attachment; Image({this.src, this.thumb, this.attachment}); diff --git a/lib/core/model/pharmacy/scan_qr_model.dart b/lib/core/model/pharmacy/scan_qr_model.dart index 71e25e8d..3adcba75 100644 --- a/lib/core/model/pharmacy/scan_qr_model.dart +++ b/lib/core/model/pharmacy/scan_qr_model.dart @@ -1,115 +1,115 @@ class ScanQrModel { - String id; - bool visibleIndividually; - String name; - String namen; - List localizedNames; - String shortDescription; - String shortDescriptionn; - String fullDescription; - String fullDescriptionn; - bool markasNew; - bool showOnHomePage; + String? id; + bool? visibleIndividually; + String? name; + String? namen; + List? localizedNames; + String? shortDescription; + String? shortDescriptionn; + String? fullDescription; + String? fullDescriptionn; + bool? markasNew; + bool? showOnHomePage; dynamic metaKeywords; dynamic metaDescription; dynamic metaTitle; - bool allowCustomerReviews; + bool? allowCustomerReviews; dynamic approvedRatingSum; dynamic notApprovedRatingSum; dynamic approvedTotalReviews; dynamic notApprovedTotalReviews; - String sku; - bool isRx; - bool prescriptionRequired; + String? sku; + bool? isRx; + bool? prescriptionRequired; dynamic rxMessage; dynamic rxMessagen; dynamic manufacturerPartNumber; dynamic gtin; - bool isGiftCard; - bool requireOtherProducts; - bool automaticallyAddRequiredProducts; - bool isDownload; - bool unlimitedDownloads; + bool? isGiftCard; + bool? requireOtherProducts; + bool? automaticallyAddRequiredProducts; + bool? isDownload; + bool? unlimitedDownloads; dynamic maxNumberOfDownloads; dynamic downloadExpirationDays; - bool hasSampleDownload; - bool hasUserAgreement; - bool isRecurring; + bool? hasSampleDownload; + bool? hasUserAgreement; + bool? isRecurring; dynamic recurringCycleLength; dynamic recurringTotalCycles; - bool isRental; + bool? isRental; dynamic rentalPriceLength; - bool isShipEnabled; - bool isFreeShipping; - bool shipSeparately; + bool? isShipEnabled; + bool? isFreeShipping; + bool? shipSeparately; dynamic additionalShippingCharge; - bool isTaxExempt; - bool isTelecommunicationsOrBroadcastingOrElectronicServices; - bool useMultipleWarehouses; + bool? isTaxExempt; + bool? isTelecommunicationsOrBroadcastingOrElectronicServices; + bool? useMultipleWarehouses; dynamic manageInventoryMethodId; dynamic stockQuantity; - String stockAvailability; - String stockAvailabilityn; - bool displayStockAvailability; - bool displayStockQuantity; + String? stockAvailability; + String? stockAvailabilityn; + bool? displayStockAvailability; + bool? displayStockQuantity; dynamic minStockQuantity; dynamic notifyAdminForQuantityBelow; - bool allowBackInStockSubscriptions; + bool? allowBackInStockSubscriptions; dynamic orderMinimumQuantity; dynamic orderMaximumQuantity; dynamic allowedQuantities; - bool allowAddingOnlyExistingAttributeCombinations; - bool disableBuyButton; - bool disableWishlistButton; - bool availableForPreOrder; + bool? allowAddingOnlyExistingAttributeCombinations; + bool? disableBuyButton; + bool? disableWishlistButton; + bool? availableForPreOrder; dynamic preOrderAvailabilityStartDateTimeUtc; - bool callForPrice; + bool? callForPrice; dynamic price; dynamic oldPrice; dynamic productCost; dynamic specialPrice; dynamic specialPriceStartDateTimeUtc; dynamic specialPriceEndDateTimeUtc; - bool customerEntersPrice; + bool? customerEntersPrice; dynamic minimumCustomerEnteredPrice; dynamic maximumCustomerEnteredPrice; - bool basepriceEnabled; + bool? basepriceEnabled; dynamic basepriceAmount; dynamic basepriceBaseAmount; - bool hasTierPrices; - bool hasDiscountsApplied; + bool? hasTierPrices; + bool? hasDiscountsApplied; dynamic discountName; dynamic discountNamen; dynamic discountDescription; dynamic discountDescriptionn; dynamic discountPercentage; - String currency; - String currencyn; - double weight; + String? currency; + String? currencyn; + double? weight; dynamic length; dynamic width; dynamic height; dynamic availableStartDateTimeUtc; dynamic availableEndDateTimeUtc; dynamic displayOrder; - bool published; - bool deleted; - String createdOnUtc; - String updatedOnUtc; - String productType; + bool? published; + bool? deleted; + String? createdOnUtc; + String? updatedOnUtc; + String? productType; dynamic parentGroupedProductId; - List roleIds; - List discountIds; - List storeIds; - List manufacturerIds; - List reviews; - List images; - List attributes; - List specifications; - List associatedProductIds; - List tags; + List? roleIds; + List? discountIds; + List? storeIds; + List? manufacturerIds; + List? reviews; + List? images; + List? attributes; + List? specifications; + List? associatedProductIds; + List? tags; dynamic vendorId; - String seName; + String? seName; ScanQrModel( {this.id, @@ -230,9 +230,9 @@ class ScanQrModel { name = json['name']; namen = json['namen']; if (json['localized_names'] != null) { - localizedNames = new List(); + localizedNames = []; json['localized_names'].forEach((v) { - localizedNames.add(new LocalizedNames.fromJson(v)); + localizedNames!.add(new LocalizedNames.fromJson(v)); }); } shortDescription = json['short_description']; @@ -258,8 +258,7 @@ class ScanQrModel { gtin = json['gtin']; isGiftCard = json['is_gift_card']; requireOtherProducts = json['require_other_products']; - automaticallyAddRequiredProducts = - json['automatically_add_required_products']; + automaticallyAddRequiredProducts = json['automatically_add_required_products']; isDownload = json['is_download']; unlimitedDownloads = json['unlimited_downloads']; maxNumberOfDownloads = json['max_number_of_downloads']; @@ -276,8 +275,7 @@ class ScanQrModel { shipSeparately = json['ship_separately']; additionalShippingCharge = json['additional_shipping_charge']; isTaxExempt = json['is_tax_exempt']; - isTelecommunicationsOrBroadcastingOrElectronicServices = - json['is_telecommunications_or_broadcasting_or_electronic_services']; + isTelecommunicationsOrBroadcastingOrElectronicServices = json['is_telecommunications_or_broadcasting_or_electronic_services']; useMultipleWarehouses = json['use_multiple_warehouses']; manageInventoryMethodId = json['manage_inventory_method_id']; stockQuantity = json['stock_quantity']; @@ -291,13 +289,11 @@ class ScanQrModel { orderMinimumQuantity = json['order_minimum_quantity']; orderMaximumQuantity = json['order_maximum_quantity']; allowedQuantities = json['allowed_quantities']; - allowAddingOnlyExistingAttributeCombinations = - json['allow_adding_only_existing_attribute_combinations']; + allowAddingOnlyExistingAttributeCombinations = json['allow_adding_only_existing_attribute_combinations']; disableBuyButton = json['disable_buy_button']; disableWishlistButton = json['disable_wishlist_button']; availableForPreOrder = json['available_for_pre_order']; - preOrderAvailabilityStartDateTimeUtc = - json['pre_order_availability_start_date_time_utc']; + preOrderAvailabilityStartDateTimeUtc = json['pre_order_availability_start_date_time_utc']; callForPrice = json['call_for_price']; price = json['price']; oldPrice = json['old_price']; @@ -334,38 +330,38 @@ class ScanQrModel { productType = json['product_type']; parentGroupedProductId = json['parent_grouped_product_id']; if (json['role_ids'] != null) { - roleIds = new List(); + roleIds = []; } if (json['discount_ids'] != null) { - discountIds = new List(); + discountIds = []; } if (json['store_ids'] != null) { - storeIds = new List(); + storeIds = []; } manufacturerIds = json['manufacturer_ids'].cast(); if (json['reviews'] != null) { - reviews = new List(); + reviews = []; } if (json['images'] != null) { - images = new List(); + images = []; json['images'].forEach((v) { - images.add(new Images.fromJson(v)); + images!.add(new Images.fromJson(v)); }); } if (json['attributes'] != null) { - attributes = new List(); + attributes = []; } if (json['specifications'] != null) { - specifications = new List(); + specifications = []; json['specifications'].forEach((v) { - specifications.add(new Specifications.fromJson(v)); + specifications!.add(new Specifications.fromJson(v)); }); } if (json['associated_product_ids'] != null) { - associatedProductIds = new List(); + associatedProductIds = []; } if (json['tags'] != null) { - tags = new List(); + tags = []; } vendorId = json['vendor_id']; seName = json['se_name']; @@ -378,8 +374,7 @@ class ScanQrModel { data['name'] = this.name; data['namen'] = this.namen; if (this.localizedNames != null) { - data['localized_names'] = - this.localizedNames.map((v) => v.toJson()).toList(); + data['localized_names'] = this.localizedNames!.map((v) => v.toJson()).toList(); } data['short_description'] = this.shortDescription; data['short_descriptionn'] = this.shortDescriptionn; @@ -404,8 +399,7 @@ class ScanQrModel { data['gtin'] = this.gtin; data['is_gift_card'] = this.isGiftCard; data['require_other_products'] = this.requireOtherProducts; - data['automatically_add_required_products'] = - this.automaticallyAddRequiredProducts; + data['automatically_add_required_products'] = this.automaticallyAddRequiredProducts; data['is_download'] = this.isDownload; data['unlimited_downloads'] = this.unlimitedDownloads; data['max_number_of_downloads'] = this.maxNumberOfDownloads; @@ -422,8 +416,7 @@ class ScanQrModel { data['ship_separately'] = this.shipSeparately; data['additional_shipping_charge'] = this.additionalShippingCharge; data['is_tax_exempt'] = this.isTaxExempt; - data['is_telecommunications_or_broadcasting_or_electronic_services'] = - this.isTelecommunicationsOrBroadcastingOrElectronicServices; + data['is_telecommunications_or_broadcasting_or_electronic_services'] = this.isTelecommunicationsOrBroadcastingOrElectronicServices; data['use_multiple_warehouses'] = this.useMultipleWarehouses; data['manage_inventory_method_id'] = this.manageInventoryMethodId; data['stock_quantity'] = this.stockQuantity; @@ -433,25 +426,21 @@ class ScanQrModel { data['display_stock_quantity'] = this.displayStockQuantity; data['min_stock_quantity'] = this.minStockQuantity; data['notify_admin_for_quantity_below'] = this.notifyAdminForQuantityBelow; - data['allow_back_in_stock_subscriptions'] = - this.allowBackInStockSubscriptions; + data['allow_back_in_stock_subscriptions'] = this.allowBackInStockSubscriptions; data['order_minimum_quantity'] = this.orderMinimumQuantity; data['order_maximum_quantity'] = this.orderMaximumQuantity; data['allowed_quantities'] = this.allowedQuantities; - data['allow_adding_only_existing_attribute_combinations'] = - this.allowAddingOnlyExistingAttributeCombinations; + data['allow_adding_only_existing_attribute_combinations'] = this.allowAddingOnlyExistingAttributeCombinations; data['disable_buy_button'] = this.disableBuyButton; data['disable_wishlist_button'] = this.disableWishlistButton; data['available_for_pre_order'] = this.availableForPreOrder; - data['pre_order_availability_start_date_time_utc'] = - this.preOrderAvailabilityStartDateTimeUtc; + data['pre_order_availability_start_date_time_utc'] = this.preOrderAvailabilityStartDateTimeUtc; data['call_for_price'] = this.callForPrice; data['price'] = this.price; data['old_price'] = this.oldPrice; data['product_cost'] = this.productCost; data['special_price'] = this.specialPrice; - data['special_price_start_date_time_utc'] = - this.specialPriceStartDateTimeUtc; + data['special_price_start_date_time_utc'] = this.specialPriceStartDateTimeUtc; data['special_price_end_date_time_utc'] = this.specialPriceEndDateTimeUtc; data['customer_enters_price'] = this.customerEntersPrice; data['minimum_customer_entered_price'] = this.minimumCustomerEnteredPrice; @@ -485,12 +474,11 @@ class ScanQrModel { data['manufacturer_ids'] = this.manufacturerIds; if (this.images != null) { - data['images'] = this.images.map((v) => v.toJson()).toList(); + data['images'] = this.images!.map((v) => v.toJson()).toList(); } if (this.specifications != null) { - data['specifications'] = - this.specifications.map((v) => v.toJson()).toList(); + data['specifications'] = this.specifications!.map((v) => v.toJson()).toList(); } data['vendor_id'] = this.vendorId; @@ -500,8 +488,8 @@ class ScanQrModel { } class LocalizedNames { - int languageId; - String localizedName; + int? languageId; + String? localizedName; LocalizedNames({this.languageId, this.localizedName}); @@ -519,11 +507,11 @@ class LocalizedNames { } class Images { - int id; - int position; - String src; - String thumb; - String attachment; + int? id; + int? position; + String? src; + String? thumb; + String? attachment; Images({this.id, this.position, this.src, this.thumb, this.attachment}); @@ -547,20 +535,14 @@ class Images { } class Specifications { - int id; - int displayOrder; - String defaultValue; - String defaultValuen; - String name; - String nameN; + int? id; + int? displayOrder; + String? defaultValue; + String? defaultValuen; + String? name; + String? nameN; - Specifications( - {this.id, - this.displayOrder, - this.defaultValue, - this.defaultValuen, - this.name, - this.nameN}); + Specifications({this.id, this.displayOrder, this.defaultValue, this.defaultValuen, this.name, this.nameN}); Specifications.fromJson(Map json) { id = json['id']; diff --git a/lib/core/model/pharmacy/sub_categories_model.dart b/lib/core/model/pharmacy/sub_categories_model.dart index 916ec023..cbaf4b16 100644 --- a/lib/core/model/pharmacy/sub_categories_model.dart +++ b/lib/core/model/pharmacy/sub_categories_model.dart @@ -1,13 +1,13 @@ class SubCategoriesModel { - String id; - String name; - String namen; - List localizedNames; - String description; - int parentCategoryId; - int displayOrder; + String? id; + String? name; + String? namen; + List? localizedNames; + String? description; + int? parentCategoryId; + int? displayOrder; dynamic image; - bool isLeaf; + bool? isLeaf; SubCategoriesModel( {this.id, @@ -25,9 +25,9 @@ class SubCategoriesModel { name = json['name']; namen = json['namen']; if (json['localized_names'] != null) { - localizedNames = new List(); + localizedNames = []; json['localized_names'].forEach((v) { - localizedNames.add(new LocalizedNames.fromJson(v)); + localizedNames!.add(new LocalizedNames.fromJson(v)); }); } description = json['description']; @@ -44,7 +44,7 @@ class SubCategoriesModel { data['namen'] = this.namen; if (this.localizedNames != null) { data['localized_names'] = - this.localizedNames.map((v) => v.toJson()).toList(); + this.localizedNames!.map((v) => v.toJson()).toList(); } data['description'] = this.description; data['parent_category_id'] = this.parentCategoryId; @@ -56,8 +56,8 @@ class SubCategoriesModel { } class LocalizedNames { - int languageId; - String localizedName; + int? languageId; + String? localizedName; LocalizedNames({this.languageId, this.localizedName}); diff --git a/lib/core/model/pharmacy/sub_products_model.dart b/lib/core/model/pharmacy/sub_products_model.dart index 6e8964c9..fe5c8dd1 100644 --- a/lib/core/model/pharmacy/sub_products_model.dart +++ b/lib/core/model/pharmacy/sub_products_model.dart @@ -1,115 +1,115 @@ class SubProductsModel { - String id; - bool visibleIndividually; - String name; - String namen; - List localizedNames; - String shortDescription; - String shortDescriptionn; - String fullDescription; - String fullDescriptionn; - bool markasNew; - bool showOnHomePage; + String? id; + bool? visibleIndividually; + String? name; + String? namen; + List? localizedNames; + String? shortDescription; + String? shortDescriptionn; + String? fullDescription; + String? fullDescriptionn; + bool? markasNew; + bool? showOnHomePage; dynamic metaKeywords; dynamic metaDescription; dynamic metaTitle; - bool allowCustomerReviews; + bool? allowCustomerReviews; dynamic approvedRatingSum; dynamic notApprovedRatingSum; dynamic approvedTotalReviews; dynamic notApprovedTotalReviews; - String sku; - bool isRx; - bool prescriptionRequired; + String? sku; + bool? isRx; + bool? prescriptionRequired; dynamic rxMessage; dynamic rxMessagen; dynamic manufacturerPartNumber; dynamic gtin; - bool isGiftCard; - bool requireOtherProducts; - bool automaticallyAddRequiredProducts; - bool isDownload; - bool unlimitedDownloads; + bool? isGiftCard; + bool? requireOtherProducts; + bool? automaticallyAddRequiredProducts; + bool? isDownload; + bool? unlimitedDownloads; dynamic maxNumberOfDownloads; dynamic downloadExpirationDays; - bool hasSampleDownload; - bool hasUserAgreement; - bool isRecurring; + bool? hasSampleDownload; + bool? hasUserAgreement; + bool? isRecurring; dynamic recurringCycleLength; dynamic recurringTotalCycles; - bool isRental; + bool? isRental; dynamic rentalPriceLength; - bool isShipEnabled; - bool isFreeShipping; - bool shipSeparately; + bool? isShipEnabled; + bool? isFreeShipping; + bool? shipSeparately; dynamic additionalShippingCharge; - bool isTaxExempt; - bool isTelecommunicationsOrBroadcastingOrElectronicServices; - bool useMultipleWarehouses; + bool? isTaxExempt; + bool? isTelecommunicationsOrBroadcastingOrElectronicServices; + bool? useMultipleWarehouses; dynamic manageInventoryMethodId; dynamic stockQuantity; - String stockAvailability; - String stockAvailabilityn; - bool displayStockAvailability; - bool displayStockQuantity; + String? stockAvailability; + String? stockAvailabilityn; + bool? displayStockAvailability; + bool? displayStockQuantity; dynamic minStockQuantity; dynamic notifyAdminForQuantityBelow; - bool allowBackInStockSubscriptions; + bool? allowBackInStockSubscriptions; dynamic orderMinimumQuantity; dynamic orderMaximumQuantity; dynamic allowedQuantities; - bool allowAddingOnlyExistingAttributeCombinations; - bool disableBuyButton; - bool disableWishlistButton; - bool availableForPreOrder; + bool? allowAddingOnlyExistingAttributeCombinations; + bool? disableBuyButton; + bool? disableWishlistButton; + bool? availableForPreOrder; dynamic preOrderAvailabilityStartDateTimeUtc; - bool callForPrice; + bool? callForPrice; dynamic price; dynamic oldPrice; dynamic productCost; dynamic specialPrice; dynamic specialPriceStartDateTimeUtc; dynamic specialPriceEndDateTimeUtc; - bool customerEntersPrice; + bool? customerEntersPrice; dynamic minimumCustomerEnteredPrice; dynamic maximumCustomerEnteredPrice; - bool basepriceEnabled; + bool? basepriceEnabled; dynamic basepriceAmount; dynamic basepriceBaseAmount; - bool hasTierPrices; - bool hasDiscountsApplied; + bool? hasTierPrices; + bool? hasDiscountsApplied; dynamic discountName; dynamic discountNamen; dynamic discountDescription; dynamic discountDescriptionn; dynamic discountPercentage; - String currency; - String currencyn; - double weight; + String? currency; + String? currencyn; + double? weight; dynamic length; dynamic width; dynamic height; dynamic availableStartDateTimeUtc; dynamic availableEndDateTimeUtc; dynamic displayOrder; - bool published; - bool deleted; - String createdOnUtc; - String updatedOnUtc; - String productType; + bool? published; + bool? deleted; + String? createdOnUtc; + String? updatedOnUtc; + String? productType; dynamic parentGroupedProductId; - List roleIds; - List discountIds; - List storeIds; - List manufacturerIds; - List reviews; - List images; - List attributes; - List specifications; - List associatedProductIds; - List tags; + List? roleIds; + List? discountIds; + List? storeIds; + List? manufacturerIds; + List? reviews; + List? images; + List? attributes; + List? specifications; + List? associatedProductIds; + List? tags; dynamic vendorId; - String seName; + String? seName; SubProductsModel( {this.id, @@ -229,16 +229,16 @@ class SubProductsModel { visibleIndividually = json['visible_individually']; name = json['name']; if (json['images'] != null) { - images = new List(); + images = []; json['images'].forEach((v) { - images.add(new Images.fromJson(v)); + images!.add(new Images.fromJson(v)); }); } namen = json['namen']; if (json['localized_names'] != null) { - localizedNames = new List(); + localizedNames = []; json['localized_names'].forEach((v) { - localizedNames.add(new LocalizedNames.fromJson(v)); + localizedNames!.add(new LocalizedNames.fromJson(v)); }); } shortDescription = json['short_description']; @@ -343,9 +343,9 @@ class SubProductsModel { manufacturerIds = json['manufacturer_ids'].cast(); if (json['specifications'] != null) { - specifications = new List(); + specifications = []; json['specifications'].forEach((v) { - specifications.add(new Specifications.fromJson(v)); + specifications!.add(new Specifications.fromJson(v)); }); } @@ -361,7 +361,7 @@ class SubProductsModel { data['namen'] = this.namen; if (this.localizedNames != null) { data['localized_names'] = - this.localizedNames.map((v) => v.toJson()).toList(); + this.localizedNames!.map((v) => v.toJson()).toList(); } data['short_description'] = this.shortDescription; data['short_descriptionn'] = this.shortDescriptionn; @@ -468,7 +468,7 @@ class SubProductsModel { if (this.specifications != null) { data['specifications'] = - this.specifications.map((v) => v.toJson()).toList(); + this.specifications!.map((v) => v.toJson()).toList(); } data['vendor_id'] = this.vendorId; @@ -478,8 +478,8 @@ class SubProductsModel { } class LocalizedNames { - int languageId; - String localizedName; + int? languageId; + String? localizedName; LocalizedNames({this.languageId, this.localizedName}); @@ -497,11 +497,11 @@ class LocalizedNames { } class Images { - int id; - int position; - String src; - String thumb; - String attachment; + int? id; + int? position; + String? src; + String? thumb; + String? attachment; Images({this.id, this.position, this.src, this.thumb, this.attachment}); @@ -525,12 +525,12 @@ class Images { } class Specifications { - int id; - int displayOrder; - String defaultValue; - String defaultValuen; - String name; - String nameN; + int? id; + int? displayOrder; + String? defaultValue; + String? defaultValuen; + String? name; + String? nameN; Specifications( {this.id, diff --git a/lib/core/model/prescriptions/Prescriptions.dart b/lib/core/model/prescriptions/Prescriptions.dart index 0169010f..6e63bdad 100644 --- a/lib/core/model/prescriptions/Prescriptions.dart +++ b/lib/core/model/prescriptions/Prescriptions.dart @@ -1,40 +1,40 @@ import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; class Prescriptions { - String setupID; - int projectID; - int patientID; - int appointmentNo; - String appointmentDate; - String doctorName; - String clinicDescription; - String name; - int episodeID; - int actualDoctorRate; - int admission; - int clinicID; - String companyName; - String despensedStatus; - DateTime dischargeDate; - int dischargeNo; - int doctorID; - String doctorImageURL; - int doctorRate; - String doctorTitle; - int gender; - String genderDescription; - bool isActiveDoctorProfile; - bool isDoctorAllowVedioCall; - bool isExecludeDoctor; - bool isInOutPatient; - bool isLiveCareAppointment; - String isInOutPatientDescription; - String isInOutPatientDescriptionN; - bool isInsurancePatient; - String nationalityFlagURL; - int noOfPatientsRate; - String qR; - List speciality; + String? setupID; + int? projectID; + int? patientID; + int? appointmentNo; + String? appointmentDate; + String? doctorName; + String? clinicDescription; + String? name; + int? episodeID; + int? actualDoctorRate; + int? admission; + int? clinicID; + String? companyName; + String? despensedStatus; + DateTime? dischargeDate; + int? dischargeNo; + int? doctorID; + String? doctorImageURL; + int? doctorRate; + String? doctorTitle; + int? gender; + String? genderDescription; + bool? isActiveDoctorProfile; + bool? isDoctorAllowVedioCall; + bool? isExecludeDoctor; + bool? isInOutPatient; + bool? isLiveCareAppointment; + String? isInOutPatientDescription; + String? isInOutPatientDescriptionN; + bool? isInsurancePatient; + String? nationalityFlagURL; + int? noOfPatientsRate; + String? qR; + List? speciality; Prescriptions( {this.setupID, @@ -149,10 +149,10 @@ class Prescriptions { } class PrescriptionsList { - String filterName = ""; - List prescriptionsList = List(); + String? filterName = ""; + List? prescriptionsList = []; - PrescriptionsList({this.filterName, Prescriptions prescriptions}) { - prescriptionsList.add(prescriptions); + PrescriptionsList({this.filterName, Prescriptions? prescriptions}) { + prescriptionsList!.add(prescriptions!); } } diff --git a/lib/core/model/prescriptions/perscription_pharmacy.dart b/lib/core/model/prescriptions/perscription_pharmacy.dart index 3adaef7e..5207ab4f 100644 --- a/lib/core/model/prescriptions/perscription_pharmacy.dart +++ b/lib/core/model/prescriptions/perscription_pharmacy.dart @@ -1,28 +1,28 @@ class PharmacyPrescriptions { - String expiryDate; + String? expiryDate; dynamic sellingPrice; - int quantity; - int itemID; - int locationID; - int projectID; - String setupID; - String locationDescription; - Null locationDescriptionN; - String itemDescription; - Null itemDescriptionN; - String alias; - int locationTypeID; - int barcode; - Null companybarcode; - int cityID; - String cityName; - int distanceInKilometers; - String latitude; - int locationType; - String longitude; - String phoneNumber; - String projectImageURL; - Null sortOrder; + int? quantity; + int? itemID; + int? locationID; + int? projectID; + String? setupID; + String? locationDescription; + dynamic locationDescriptionN; + String? itemDescription; + dynamic itemDescriptionN; + String? alias; + int? locationTypeID; + int? barcode; + dynamic companybarcode; + int? cityID; + String? cityName; + dynamic distanceInKilometers; + String? latitude; + int? locationType; + String? longitude; + String? phoneNumber; + String? projectImageURL; + dynamic sortOrder; PharmacyPrescriptions( {this.expiryDate, diff --git a/lib/core/model/prescriptions/prescription_info_rc_model.dart b/lib/core/model/prescriptions/prescription_info_rc_model.dart new file mode 100644 index 00000000..fffb9bdd --- /dev/null +++ b/lib/core/model/prescriptions/prescription_info_rc_model.dart @@ -0,0 +1,52 @@ +class PrescriptionInfoRCModel { + String? itemDescription; + String? image; + String? sKU; + dynamic productId; + dynamic productName; + int? quantity; + int? orderId; + int? totalPrice; + int? dispenseQuantity; + dynamic itemhand; + + PrescriptionInfoRCModel( + {this.itemDescription, + this.image, + this.sKU, + this.productId, + this.productName, + this.quantity, + this.orderId, + this.totalPrice, + this.dispenseQuantity, + this.itemhand}); + + PrescriptionInfoRCModel.fromJson(Map json) { + itemDescription = json['ItemDescription']; + image = json['image']; + sKU = json['SKU']; + productId = json['ProductId']; + productName = json['ProductName']; + quantity = json['Quantity']; + orderId = json['OrderId']; + totalPrice = json['TotalPrice']; + dispenseQuantity = json['DispenseQuantity']; + itemhand = json['itemhand']; + } + + Map toJson() { + final Map data = new Map(); + data['ItemDescription'] = this.itemDescription; + data['image'] = this.image; + data['SKU'] = this.sKU; + data['ProductId'] = this.productId; + data['ProductName'] = this.productName; + data['Quantity'] = this.quantity; + data['OrderId'] = this.orderId; + data['TotalPrice'] = this.totalPrice; + data['DispenseQuantity'] = this.dispenseQuantity; + data['itemhand'] = this.itemhand; + return data; + } +} diff --git a/lib/core/model/prescriptions/prescription_report.dart b/lib/core/model/prescriptions/prescription_report.dart index 8c18df62..b4a3e0b7 100644 --- a/lib/core/model/prescriptions/prescription_report.dart +++ b/lib/core/model/prescriptions/prescription_report.dart @@ -1,50 +1,50 @@ -import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; + class PrescriptionReport { - String address; - int appointmentNo; - String clinic; - String companyName; - int days; - String doctorName; - var doseDailyQuantity; - String frequency; - int frequencyNumber; - String image; - String imageExtension; - String imageSRCUrl; - String imageString; - String imageThumbUrl; - String isCovered; - String itemDescription; - int itemID; - String orderDate; - int patientID; - String patientName; - String phoneOffice1; - String prescriptionQR; - int prescriptionTimes; - String productImage; - String productImageBase64; - String productImageString; - int projectID; - String projectName; - String remarks; - String route; - String sKU; - int scaleOffset; - String startDate; + String? address; + int? appointmentNo; + String? clinic; + String? companyName; + int? days; + String? doctorName; + num? doseDailyQuantity; + String? frequency; + int? frequencyNumber; + String? image; + String? imageExtension; + String? imageSRCUrl; + String? imageString; + String? imageThumbUrl; + String? isCovered; + String? itemDescription; + int? itemID; + String? orderDate; + int? patientID; + String? patientName; + String? phoneOffice1; + String? prescriptionQR; + num? prescriptionTimes; + String? productImage; + String? productImageBase64; + String? productImageString; + int? projectID; + String? projectName; + String? remarks; + String? route; + String? sKU; + int? scaleOffset; + String? startDate; - String patientAge; - String patientGender; - String phoneOffice; - int doseTimingID; - int frequencyID; - int routeID; - String name; - String itemDescriptionN; - String routeN; - String frequencyN; + String? patientAge; + String? patientGender; + String? phoneOffice; + int? doseTimingID; + int? frequencyID; + int? routeID; + String? name; + String? itemDescriptionN; + String? routeN; + String? frequencyN; PrescriptionReport({ this.address, @@ -134,7 +134,7 @@ class PrescriptionReport { frequencyID = json['frequencyID']; routeID = json['routeID']; name = json['name']; - itemDescriptionN = json['itemDescriptionN']; + itemDescriptionN = json['ItemDescriptionN']; routeN = json['routeN']; frequencyN = json['frequencyN']; } diff --git a/lib/core/model/prescriptions/prescription_report_enh.dart b/lib/core/model/prescriptions/prescription_report_enh.dart index 203eaaff..15fad569 100644 --- a/lib/core/model/prescriptions/prescription_report_enh.dart +++ b/lib/core/model/prescriptions/prescription_report_enh.dart @@ -1,72 +1,74 @@ class PrescriptionReportEnh { - String address; - int appointmentNo; - String clinic; - Null companyName; - int days; - String doctorName; - int doseDailyQuantity; - String frequency; - int frequencyNumber; - Null image; - Null imageExtension; - String imageSRCUrl; - Null imageString; - String imageThumbUrl; - String isCovered; - String itemDescription; - int itemID; - String orderDate; - int patientID; - String patientName; - String phoneOffice1; - Null prescriptionQR; - int prescriptionTimes; - Null productImage; - Null productImageBase64; - String productImageString; - int projectID; - String projectName; - String remarks; - String route; - String sKU; - int scaleOffset; - String startDate; + String? address; + int? appointmentNo; + String? clinic; + dynamic companyName; + int? days; + String? doctorName; + num? doseDailyQuantity; + String? frequency; + int? frequencyNumber; + dynamic image; + dynamic imageExtension; + String? imageSRCUrl; + dynamic imageString; + String? imageThumbUrl; + String? isCovered; + String? itemDescription; + String? itemDescriptionN; + int? itemID; + String? orderDate; + int? patientID; + String? patientName; + String? phoneOffice1; + dynamic prescriptionQR; + num? prescriptionTimes; + dynamic productImage; + dynamic productImageBase64; + String? productImageString; + int? projectID; + String? projectName; + String? remarks; + String? route; + String? sKU; + int? scaleOffset; + String? startDate; PrescriptionReportEnh( {this.address, - this.appointmentNo, - this.clinic, - this.companyName, - this.days, - this.doctorName, - this.doseDailyQuantity, - this.frequency, - this.frequencyNumber, - this.image, - this.imageExtension, - this.imageSRCUrl, - this.imageString, - this.imageThumbUrl, - this.isCovered, - this.itemDescription, - this.itemID, - this.orderDate, - this.patientID, - this.patientName, - this.phoneOffice1, - this.prescriptionQR, - this.prescriptionTimes, - this.productImage, - this.productImageBase64, - this.productImageString, - this.projectID, - this.projectName, - this.remarks, - this.route, - this.sKU, - this.scaleOffset, - this.startDate}); + this.appointmentNo, + this.clinic, + this.companyName, + this.days, + this.doctorName, + this.doseDailyQuantity, + this.frequency, + this.frequencyNumber, + this.image, + this.imageExtension, + this.imageSRCUrl, + this.imageString, + this.imageThumbUrl, + this.isCovered, + this.itemDescription, + this.itemDescriptionN, + this.itemID, + this.orderDate, + this.patientID, + this.patientName, + this.phoneOffice1, + this.prescriptionQR, + this.prescriptionTimes, + this.productImage, + this.productImageBase64, + this.productImageString, + this.projectID, + this.projectName, + this.remarks, + this.route, + this.sKU, + this.scaleOffset, + this.startDate}); PrescriptionReportEnh.fromJson(Map json) { address = json['Address']; @@ -85,6 +87,7 @@ class PrescriptionReportEnh { imageThumbUrl = json['ImageThumbUrl']; isCovered = json['IsCovered']; itemDescription = json['ItemDescription']; + itemDescriptionN = json['ItemDescriptionN']; itemID = json['ItemID']; orderDate = json['OrderDate']; patientID = json['PatientID']; @@ -122,6 +125,7 @@ class PrescriptionReportEnh { data['ImageThumbUrl'] = this.imageThumbUrl; data['IsCovered'] = this.isCovered; data['ItemDescription'] = this.itemDescription; + data['ItemDescriptionN'] = this.itemDescriptionN; data['ItemID'] = this.itemID; data['OrderDate'] = this.orderDate; data['PatientID'] = this.patientID; diff --git a/lib/core/model/prescriptions/prescription_report_inp.dart b/lib/core/model/prescriptions/prescription_report_inp.dart new file mode 100644 index 00000000..24fd8d24 --- /dev/null +++ b/lib/core/model/prescriptions/prescription_report_inp.dart @@ -0,0 +1,124 @@ +class PrescriptionReportINP { + int? patientID; + String? patientName; + String? patientAge; + String? patientGender; + String? address; + String? phoneOffice; + String? itemDescription; + int? doseTimingID; + int? frequencyID; + int? routeID; + String? clinic; + String? doctorName; + String? route; + String? frequency; + String? remarks; + String? name; + int? days; + String? startDate; + String? orderDate; + num? doseDailyQuantity; + int? itemID; + dynamic productImage; + String? sKU; + String? itemDescriptionN; + String? routeN; + String? frequencyN; + String? imageSRCUrl; + String? imageThumbUrl; + + PrescriptionReportINP( + {this.patientID, + this.patientName, + this.patientAge, + this.patientGender, + this.address, + this.phoneOffice, + this.itemDescription, + this.doseTimingID, + this.frequencyID, + this.routeID, + this.clinic, + this.doctorName, + this.route, + this.frequency, + this.remarks, + this.name, + this.days, + this.startDate, + this.orderDate, + this.doseDailyQuantity, + this.itemID, + this.productImage, + this.sKU, + this.itemDescriptionN, + this.routeN, + this.frequencyN, + this.imageSRCUrl, + this.imageThumbUrl}); + + PrescriptionReportINP.fromJson(Map json) { + patientID = json['PatientID']; + patientName = json['PatientName']; + patientAge = json['PatientAge']; + patientGender = json['PatientGender']; + address = json['Address']; + phoneOffice = json['PhoneOffice']; + itemDescription = json['ItemDescription']; + doseTimingID = json['DoseTimingID']; + frequencyID = json['FrequencyID']; + routeID = json['RouteID']; + clinic = json['Clinic']; + doctorName = json['DoctorName']; + route = json['Route']; + frequency = json['Frequency']; + remarks = json['Remarks']; + name = json['Name']; + days = json['Days']; + startDate = json['StartDate']; + orderDate = json['OrderDate']; + doseDailyQuantity = json['DoseDailyQuantity']; + itemID = json['ItemID']; + productImage = json['ProductImage']; + sKU = json['SKU']; + itemDescriptionN = json['ItemDescriptionN']; + routeN = json['RouteN']; + frequencyN = json['FrequencyN']; + imageSRCUrl = json['ImageSRCUrl']; + imageThumbUrl = json['ImageThumbUrl']; + } + + Map toJson() { + final Map data = new Map(); + data['PatientID'] = this.patientID; + data['PatientName'] = this.patientName; + data['PatientAge'] = this.patientAge; + data['PatientGender'] = this.patientGender; + data['Address'] = this.address; + data['PhoneOffice'] = this.phoneOffice; + data['ItemDescription'] = this.itemDescription; + data['DoseTimingID'] = this.doseTimingID; + data['FrequencyID'] = this.frequencyID; + data['RouteID'] = this.routeID; + data['Clinic'] = this.clinic; + data['DoctorName'] = this.doctorName; + data['Route'] = this.route; + data['Frequency'] = this.frequency; + data['Remarks'] = this.remarks; + data['Name'] = this.name; + data['Days'] = this.days; + data['StartDate'] = this.startDate; + data['OrderDate'] = this.orderDate; + data['DoseDailyQuantity'] = this.doseDailyQuantity; + data['ItemID'] = this.itemID; + data['ProductImage'] = this.productImage; + data['SKU'] = this.sKU; + data['ItemDescriptionN'] = this.itemDescriptionN; + data['RouteN'] = this.routeN; + data['FrequencyN'] = this.frequencyN; + data['ImageSRCUrl'] = this.imageSRCUrl; + data['ImageThumbUrl'] = this.imageThumbUrl; + return data; + } +} diff --git a/lib/core/model/prescriptions/prescriptions_order.dart b/lib/core/model/prescriptions/prescriptions_order.dart index fdcbf203..1241ea15 100644 --- a/lib/core/model/prescriptions/prescriptions_order.dart +++ b/lib/core/model/prescriptions/prescriptions_order.dart @@ -1,37 +1,52 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; class PrescriptionsOrder { - int iD; + int? iD; dynamic patientID; - bool patientOutSA; - bool isOutPatient; - int projectID; - int nearestProjectID; - double longitude; - double latitude; + bool? patientOutSA; + bool? isOutPatient; + int? projectID; + int? nearestProjectID; + double? longitude; + double? latitude; dynamic appointmentNo; dynamic dischargeID; - int lineItemNo; - int status; + int? lineItemNo; + int? status; dynamic description; dynamic descriptionN; - DateTime createdOn; - int serviceID; - int createdBy; - DateTime editedOn; - int editedBy; - int channel; + DateTime? createdOn; + int? serviceID; + int? createdBy; + DateTime? editedOn; + int? editedBy; + int? channel; dynamic clientRequestID; - bool returnedToQueue; + bool? returnedToQueue; dynamic pickupDateTime; dynamic pickupLocationName; dynamic dropoffLocationName; - int realRRTHaveTransactions; + int? realRRTHaveTransactions; dynamic nearestProjectDescription; dynamic nearestProjectDescriptionN; dynamic projectDescription; dynamic projectDescriptionN; + String getNearestProjectDescription(){ + return isAppArabic ? nearestProjectDescriptionN : nearestProjectDescription; + } + String getStatusName(TranslationBase localize){ + if(status == 1) + return localize.pending; + else if(status == 3) + return localize.completed; + return '$status'; + } + + String getFormattedDateTime()=> DateUtil.getWeekDayMonthDayYearDateFormatted(createdOn!, isAppArabic ? 'ar' : 'en'); + PrescriptionsOrder( {this.iD, this.patientID, diff --git a/lib/core/model/prescriptions/request_get_list_pharmacy_for_prescriptions.dart b/lib/core/model/prescriptions/request_get_list_pharmacy_for_prescriptions.dart index 739bb838..b870a617 100644 --- a/lib/core/model/prescriptions/request_get_list_pharmacy_for_prescriptions.dart +++ b/lib/core/model/prescriptions/request_get_list_pharmacy_for_prescriptions.dart @@ -1,16 +1,16 @@ class RequestGetListPharmacyForPrescriptions { - int latitude; - int longitude; - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - String sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; - int itemID; + dynamic latitude; + dynamic longitude; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + String? sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + int? itemID; RequestGetListPharmacyForPrescriptions( {this.latitude, diff --git a/lib/core/model/prescriptions/request_prescription_report.dart b/lib/core/model/prescriptions/request_prescription_report.dart index c8323740..73b6655c 100644 --- a/lib/core/model/prescriptions/request_prescription_report.dart +++ b/lib/core/model/prescriptions/request_prescription_report.dart @@ -1,44 +1,44 @@ class RequestPrescriptionReport { - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - String sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; - int patientID; - String tokenID; - int patientTypeID; - int patientType; - int appointmentNo; - String setupID; - int episodeID; - int clinicID; - int projectID; - int dischargeNo; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + String? sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + int? patientID; + String? tokenID; + int? patientTypeID; + int? patientType; + int? appointmentNo; + String? setupID; + int? episodeID; + int? clinicID; + int? projectID; + int? dischargeNo; RequestPrescriptionReport( {this.versionID, - this.channel, - this.languageID, - this.iPAdress, - this.generalid, - this.patientOutSA, - this.sessionID, - this.isDentalAllowedBackend, - this.deviceTypeID, - this.patientID, - this.tokenID, - this.patientTypeID, - this.patientType, - this.appointmentNo, - this.setupID, - this.episodeID, - this.clinicID, - this.projectID, - this.dischargeNo}); + this.channel, + this.languageID, + this.iPAdress, + this.generalid, + this.patientOutSA, + this.sessionID, + this.isDentalAllowedBackend, + this.deviceTypeID, + this.patientID, + this.tokenID, + this.patientTypeID, + this.patientType, + this.appointmentNo, + this.setupID, + this.episodeID, + this.clinicID, + this.projectID, + this.dischargeNo}); RequestPrescriptionReport.fromJson(Map json) { versionID = json['VersionID']; diff --git a/lib/core/model/prescriptions/request_prescription_report_enh.dart b/lib/core/model/prescriptions/request_prescription_report_enh.dart index 4905fc2a..81cdeae3 100644 --- a/lib/core/model/prescriptions/request_prescription_report_enh.dart +++ b/lib/core/model/prescriptions/request_prescription_report_enh.dart @@ -1,23 +1,23 @@ class RequestPrescriptionReportEnh { - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - String sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; - int patientID; - String tokenID; - int patientTypeID; - int patientType; - int appointmentNo; - String setupID; - int dischargeNo; - int episodeID; - int clinicID; - int projectID; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + String? sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + int? patientID; + String? tokenID; + int? patientTypeID; + int? patientType; + int? appointmentNo; + String? setupID; + int? dischargeNo; + int? episodeID; + int? clinicID; + int? projectID; RequestPrescriptionReportEnh( {this.versionID, diff --git a/lib/core/model/prescriptions/request_prescriptions.dart b/lib/core/model/prescriptions/request_prescriptions.dart index abb39143..605ba800 100644 --- a/lib/core/model/prescriptions/request_prescriptions.dart +++ b/lib/core/model/prescriptions/request_prescriptions.dart @@ -1,17 +1,17 @@ class RequestPrescriptions { - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - String sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; - int patientID; - String tokenID; - int patientTypeID; - int patientType; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + String? sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + int? patientID; + String? tokenID; + int? patientTypeID; + int? patientType; RequestPrescriptions( {this.versionID, diff --git a/lib/core/model/prescriptions/request_prescriptions_orders.dart b/lib/core/model/prescriptions/request_prescriptions_orders.dart index 9aaab33d..73b877b4 100644 --- a/lib/core/model/prescriptions/request_prescriptions_orders.dart +++ b/lib/core/model/prescriptions/request_prescriptions_orders.dart @@ -1,14 +1,14 @@ class RequestPrescriptionsOrders { - int patientID; - int patientOutSA; - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - String sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; + int? patientID; + int? patientOutSA; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + String? sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; RequestPrescriptionsOrders( {this.patientID, diff --git a/lib/core/model/prescriptions/request_send_prescription_email.dart b/lib/core/model/prescriptions/request_send_prescription_email.dart index 2d1f3aa3..ccb522cf 100644 --- a/lib/core/model/prescriptions/request_send_prescription_email.dart +++ b/lib/core/model/prescriptions/request_send_prescription_email.dart @@ -1,30 +1,34 @@ import 'package:diplomaticquarterapp/core/model/prescriptions/prescription_report.dart'; +import 'package:diplomaticquarterapp/core/model/prescriptions/prescription_report_inp.dart'; class RequestSendPrescriptionEmail { - String appointmentDate; - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - String sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; - int patientID; - String tokenID; - int patientTypeID; - int patientType; - String to; - String dateofBirth; - String patientIditificationNum; - String patientMobileNumber; - String patientName; - String setupID; - String clinicName; - String doctorName; - int projectID; - List listPrescriptions; + String? appointmentDate; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + String? sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + int? patientID; + String? tokenID; + int? patientTypeID; + int? patientType; + String? to; + String? dateofBirth; + String? patientIditificationNum; + String? patientMobileNumber; + String? patientName; + String? setupID; + String? clinicName; + String? doctorName; + int? doctorID; + int? projectID; + List? listPrescriptions; + List? listPrescriptionsINP; + bool? isDownload; RequestSendPrescriptionEmail( {this.appointmentDate, @@ -49,7 +53,9 @@ class RequestSendPrescriptionEmail { this.setupID, this.clinicName, this.doctorName, - this.projectID}); + this.projectID, + this.doctorID, + this.isDownload}); RequestSendPrescriptionEmail.fromJson(Map json) { appointmentDate = json['AppointmentDate']; @@ -75,6 +81,7 @@ class RequestSendPrescriptionEmail { clinicName = json['ClinicName']; doctorName = json['DoctorName']; projectID = json['ProjectID']; + doctorID = json['DoctorID']; } Map toJson() { @@ -99,14 +106,17 @@ class RequestSendPrescriptionEmail { data['PatientMobileNumber'] = this.patientMobileNumber; data['PatientName'] = this.patientName; data['SetupID'] = this.setupID; - if (this.listPrescriptions != null) { - data['ListPrescriptions'] = - this.listPrescriptions.map((v) => v.toJson()).toList(); + if (this.listPrescriptions != null && this.listPrescriptions!.isNotEmpty) { + data['ListPrescriptions'] = this.listPrescriptions!.map((v) => v.toJson()).toList(); + } + if (this.listPrescriptionsINP != null && this.listPrescriptionsINP!.isNotEmpty) { + data['ListPrescriptions'] = this.listPrescriptionsINP!.map((v) => v.toJson()).toList(); } data['ClinicName'] = this.clinicName; data['DoctorName'] = this.doctorName; data['ProjectID'] = this.projectID; - + data['DoctorID'] = this.doctorID; + data['IsDownload'] = this.isDownload; return data; } } diff --git a/lib/core/model/privilege/HMCProjectListModel.dart b/lib/core/model/privilege/HMCProjectListModel.dart new file mode 100644 index 00000000..6af7bfbb --- /dev/null +++ b/lib/core/model/privilege/HMCProjectListModel.dart @@ -0,0 +1,15 @@ +class HMCProjectListModel { + int? projectID; + + HMCProjectListModel({this.projectID}); + + HMCProjectListModel.fromJson(Map json) { + projectID = json['ProjectID']; + } + + Map toJson() { + final Map data = new Map(); + data['ProjectID'] = this.projectID; + return data; + } +} diff --git a/lib/core/model/privilege/PrivilegeModel.dart b/lib/core/model/privilege/PrivilegeModel.dart index 3b629fde..587490b7 100644 --- a/lib/core/model/privilege/PrivilegeModel.dart +++ b/lib/core/model/privilege/PrivilegeModel.dart @@ -1,7 +1,7 @@ class PrivilegeModel { - int iD; - String serviceName; - bool privilege; + int? iD; + String? serviceName; + bool? privilege; dynamic region; PrivilegeModel({this.iD, this.serviceName, this.privilege, this.region}); diff --git a/lib/core/model/privilege/ProjectDetailListModel.dart b/lib/core/model/privilege/ProjectDetailListModel.dart new file mode 100644 index 00000000..782c376b --- /dev/null +++ b/lib/core/model/privilege/ProjectDetailListModel.dart @@ -0,0 +1,32 @@ +class ProjectDetailListModel { + int? projectID; + String? latitude; + String? longitude; + int? geofenceRadius; + String? checkInQrCode; + + ProjectDetailListModel( + {this.projectID, + this.latitude, + this.longitude, + this.geofenceRadius, + this.checkInQrCode}); + + ProjectDetailListModel.fromJson(Map json) { + projectID = json['ProjectID']; + latitude = json['Latitude']; + longitude = json['Longitude']; + geofenceRadius = json['GeofenceRadius']; + checkInQrCode = json['CheckInQrCode']; + } + + Map toJson() { + final Map data = new Map(); + data['ProjectID'] = this.projectID; + data['Latitude'] = this.latitude; + data['Longitude'] = this.longitude; + data['GeofenceRadius'] = this.geofenceRadius; + data['CheckInQrCode'] = this.checkInQrCode; + return data; + } +} diff --git a/lib/core/model/privilege/VidaPlusProjectListModel.dart b/lib/core/model/privilege/VidaPlusProjectListModel.dart new file mode 100644 index 00000000..75978110 --- /dev/null +++ b/lib/core/model/privilege/VidaPlusProjectListModel.dart @@ -0,0 +1,15 @@ +class VidaPlusProjectListModel { + int? projectID; + + VidaPlusProjectListModel({this.projectID}); + + VidaPlusProjectListModel.fromJson(Map json) { + projectID = json['ProjectID']; + } + + Map toJson() { + final Map data = new Map(); + data['ProjectID'] = this.projectID; + return data; + } +} diff --git a/lib/core/model/qr/qr_parking_model.dart b/lib/core/model/qr/qr_parking_model.dart index 1df927bc..8311ac3a 100644 --- a/lib/core/model/qr/qr_parking_model.dart +++ b/lib/core/model/qr/qr_parking_model.dart @@ -1,86 +1,86 @@ class QRParkingModel { - Null totalRecords; - Null nRowID; - int qRParkingID; - String description; - String descriptionN; - Null qRCompare; - Null qRValue; - String imagePath; - bool isActive; - int parkingID; - int branchID; - int companyID; - int buildingID; - int rowID; - int gateID; - int floorID; - Null imagePath1; - int createdBy; - String createdOn; - Null editedBy; - Null editedOn; - String parkingDescription; - String parkingDescriptionN; - String gateDescription; - String gateDescriptionN; - String branchDescription; - String branchDescriptionN; - String companyDescription; - String companyDescriptionN; - String rowDescription; - String rowDescriptionN; - String floorDescription; - String floorDescriptionN; - String buildingDescription; - String buildingDescriptionN; - String qRParkingCode; - String parkingCode; - double latitude; - double longitude; - String qRImageStr; + dynamic totalRecords; + dynamic nRowID; + int? qRParkingID; + String? description; + String? descriptionN; + dynamic qRCompare; + dynamic qRValue; + String? imagePath; + bool? isActive; + int? parkingID; + int? branchID; + int? companyID; + int? buildingID; + int? rowID; + int? gateID; + int? floorID; + dynamic imagePath1; + int? createdBy; + String? createdOn; + dynamic editedBy; + dynamic editedOn; + String? parkingDescription; + String? parkingDescriptionN; + String? gateDescription; + String? gateDescriptionN; + String? branchDescription; + String? branchDescriptionN; + String? companyDescription; + String? companyDescriptionN; + String? rowDescription; + String? rowDescriptionN; + String? floorDescription; + String? floorDescriptionN; + String? buildingDescription; + String? buildingDescriptionN; + String? qRParkingCode; + String? parkingCode; + double? latitude; + double? longitude; + String? qRImageStr; QRParkingModel( {this.totalRecords, - this.nRowID, - this.qRParkingID, - this.description, - this.descriptionN, - this.qRCompare, - this.qRValue, - this.imagePath, - this.isActive, - this.parkingID, - this.branchID, - this.companyID, - this.buildingID, - this.rowID, - this.gateID, - this.floorID, - this.imagePath1, - this.createdBy, - this.createdOn, - this.editedBy, - this.editedOn, - this.parkingDescription, - this.parkingDescriptionN, - this.gateDescription, - this.gateDescriptionN, - this.branchDescription, - this.branchDescriptionN, - this.companyDescription, - this.companyDescriptionN, - this.rowDescription, - this.rowDescriptionN, - this.floorDescription, - this.floorDescriptionN, - this.buildingDescription, - this.buildingDescriptionN, - this.qRParkingCode, - this.parkingCode, - this.latitude, - this.longitude, - this.qRImageStr}); + this.nRowID, + this.qRParkingID, + this.description, + this.descriptionN, + this.qRCompare, + this.qRValue, + this.imagePath, + this.isActive, + this.parkingID, + this.branchID, + this.companyID, + this.buildingID, + this.rowID, + this.gateID, + this.floorID, + this.imagePath1, + this.createdBy, + this.createdOn, + this.editedBy, + this.editedOn, + this.parkingDescription, + this.parkingDescriptionN, + this.gateDescription, + this.gateDescriptionN, + this.branchDescription, + this.branchDescriptionN, + this.companyDescription, + this.companyDescriptionN, + this.rowDescription, + this.rowDescriptionN, + this.floorDescription, + this.floorDescriptionN, + this.buildingDescription, + this.buildingDescriptionN, + this.qRParkingCode, + this.parkingCode, + this.latitude, + this.longitude, + this.qRImageStr}); QRParkingModel.fromJson(Map json) { totalRecords = json['TotalRecords']; diff --git a/lib/core/model/radiology/final_radiology.dart b/lib/core/model/radiology/final_radiology.dart index ed47b51d..ca3403a3 100644 --- a/lib/core/model/radiology/final_radiology.dart +++ b/lib/core/model/radiology/final_radiology.dart @@ -1,47 +1,50 @@ import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; class FinalRadiology { - String setupID; - int projectID; - Null patientID; - int invoiceLineItemNo; - int invoiceNo; - int doctorID; - int clinicID; - DateTime orderDate; - String reportData; - String imageURL; - String procedureID; - int appointmentNo; - Null dIAPacsURL; - bool isRead; - String readOn; + String? setupID; + int? projectID; + dynamic patientID; + int? invoiceLineItemNo; + int? invoiceNo; + dynamic invoiceNo_VP; + String? invoiceType; + int? doctorID; + int? clinicID; + DateTime? orderDate; + String? reportData; + String? imageURL; + String? procedureID; + int? appointmentNo; + dynamic dIAPacsURL; + bool? isRead; + String? readOn; var admissionNo; - bool isInOutPatient; - int actualDoctorRate; - String clinicDescription; - String dIAPACSURL; - String doctorImageURL; - String doctorName; - int doctorRate; - String doctorTitle; - int gender; - String genderDescription; - bool isActiveDoctorProfile; - bool isExecludeDoctor; - String isInOutPatientDescription; - String isInOutPatientDescriptionN; - String nationalityFlagURL; - int noOfPatientsRate; - int orderNo; - String projectName; - String qR; - String reportDataHTML; - String reportDataTextString; - List speciality; - bool isCVI; - bool isRadMedicalReport; - bool isLiveCareAppointment; + bool? isInOutPatient; + int? actualDoctorRate; + String? clinicDescription; + String? dIAPACSURL; + String? doctorImageURL; + String? doctorName; + int? doctorRate; + String? doctorTitle; + int? gender; + String? genderDescription; + bool? isActiveDoctorProfile; + bool? isExecludeDoctor; + String? isInOutPatientDescription; + String? isInOutPatientDescriptionN; + String? nationalityFlagURL; + int? noOfPatientsRate; + int? orderNo; + String? projectName; + String? qR; + String? reportDataHTML; + String? reportDataTextString; + List? speciality; + bool? isCVI; + bool? isRadMedicalReport; + bool? isLiveCareAppointment; + String? exam_Id; FinalRadiology( {this.setupID, @@ -49,6 +52,8 @@ class FinalRadiology { this.patientID, this.invoiceLineItemNo, this.invoiceNo, + this.invoiceNo_VP, + this.invoiceType, this.doctorID, this.clinicID, this.orderDate, @@ -83,7 +88,9 @@ class FinalRadiology { this.reportDataTextString, this.speciality, this.isCVI, - this.isRadMedicalReport,this.isLiveCareAppointment}); + this.isRadMedicalReport, + this.isLiveCareAppointment, + this.exam_Id}); FinalRadiology.fromJson(Map json) { try { @@ -92,6 +99,8 @@ class FinalRadiology { patientID = json['PatientID']; invoiceLineItemNo = json['InvoiceLineItemNo']; invoiceNo = json['InvoiceNo']; + invoiceNo_VP = json['InvoiceNo_VP']; + invoiceType = json['InvoiceType']; doctorID = json['DoctorID']; clinicID = json['ClinicID']; orderDate = DateUtil.convertStringToDate(json['OrderDate']); @@ -125,10 +134,10 @@ class FinalRadiology { isLiveCareAppointment = json['IsLiveCareAppointment']; reportDataHTML = json['ReportDataHTML']; reportDataTextString = json['ReportDataTextString']; - // speciality = json['Speciality'].cast(); + // speciality = json['Speciality'].cast(); isCVI = json['isCVI']; isRadMedicalReport = json['isRadMedicalReport']; - + exam_Id = json['Exam_id']; } catch (e) { print(e); } @@ -141,6 +150,8 @@ class FinalRadiology { data['PatientID'] = this.patientID; data['InvoiceLineItemNo'] = this.invoiceLineItemNo; data['InvoiceNo'] = this.invoiceNo; + data['InvoiceNo_VP'] = this.invoiceNo_VP; + data['InvoiceType'] = this.invoiceType; data['DoctorID'] = this.doctorID; data['ClinicID'] = this.clinicID; data['OrderDate'] = this.orderDate; @@ -181,10 +192,11 @@ class FinalRadiology { } class FinalRadiologyList { - String filterName = ""; - List finalRadiologyList = List(); + String? filterName = ""; + List? finalRadiologyList = []; - FinalRadiologyList({this.filterName, FinalRadiology finalRadiology}) { - finalRadiologyList.add(finalRadiology); - } + FinalRadiologyList({this.filterName, this.finalRadiologyList}); +// { +// finalRadiologyList.add(finalRadiology); +// } } diff --git a/lib/core/model/radiology/request_patient_rad_orders_details.dart b/lib/core/model/radiology/request_patient_rad_orders_details.dart index 9e3458d5..bd90193b 100644 --- a/lib/core/model/radiology/request_patient_rad_orders_details.dart +++ b/lib/core/model/radiology/request_patient_rad_orders_details.dart @@ -1,46 +1,46 @@ class RequestPatientRadOrdersDetails { - int projectID; - int orderNo; - int invoiceNo; - String setupID; - String procedureID; - bool isMedicalReport; - bool isCVI; - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - String sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; - int patientID; - String tokenID; - int patientTypeID; - int patientType; + int? projectID; + int? orderNo; + int? invoiceNo; + String? setupID; + String? procedureID; + bool? isMedicalReport; + bool? isCVI; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + String? sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + int? patientID; + String? tokenID; + int? patientTypeID; + int? patientType; RequestPatientRadOrdersDetails( {this.projectID, - this.orderNo, - this.invoiceNo, - this.setupID, - this.procedureID, - this.isMedicalReport, - this.isCVI, - this.versionID, - this.channel, - this.languageID, - this.iPAdress, - this.generalid, - this.patientOutSA, - this.sessionID, - this.isDentalAllowedBackend, - this.deviceTypeID, - this.patientID, - this.tokenID, - this.patientTypeID, - this.patientType}); + this.orderNo, + this.invoiceNo, + this.setupID, + this.procedureID, + this.isMedicalReport, + this.isCVI, + this.versionID, + this.channel, + this.languageID, + this.iPAdress, + this.generalid, + this.patientOutSA, + this.sessionID, + this.isDentalAllowedBackend, + this.deviceTypeID, + this.patientID, + this.tokenID, + this.patientTypeID, + this.patientType}); RequestPatientRadOrdersDetails.fromJson(Map json) { projectID = json['ProjectID']; diff --git a/lib/core/model/radiology/request_send_rad_report_email.dart b/lib/core/model/radiology/request_send_rad_report_email.dart index 6d68653d..9cc39a0d 100644 --- a/lib/core/model/radiology/request_send_rad_report_email.dart +++ b/lib/core/model/radiology/request_send_rad_report_email.dart @@ -1,30 +1,34 @@ class RequestSendRadReportEmail { - int channel; - String clinicName; - String dateofBirth; - int deviceTypeID; - String doctorName; - String generalid; - int invoiceNo; - String iPAdress; - bool isDentalAllowedBackend; - int languageID; - String orderDate; - int patientID; - String patientIditificationNum; - String patientMobileNumber; - String patientName; - int patientOutSA; - int patientType; - int patientTypeID; - int projectID; - String projectName; - String radResult; - String sessionID; - String setupID; - String to; - String tokenID; - double versionID; + int? channel; + String? clinicName; + String? dateofBirth; + int? deviceTypeID; + String? doctorName; + String? generalid; + int? invoiceNo; + int? invoiceNo_VP; + String? invoiceType; + String? iPAdress; + bool? isDentalAllowedBackend; + int? languageID; + String? orderDate; + int? patientID; + String? patientIditificationNum; + String? patientMobileNumber; + String? patientName; + int? patientOutSA; + int? patientType; + int? patientTypeID; + int? projectID; + String? projectName; + String? radResult; + String? sessionID; + String? setupID; + String? to; + String? tokenID; + double? versionID; + int? invoiceLineItemNo; + bool? isDownload; RequestSendRadReportEmail( {this.channel, @@ -34,6 +38,8 @@ class RequestSendRadReportEmail { this.doctorName, this.generalid, this.invoiceNo, + this.invoiceNo_VP, + this.invoiceType, this.iPAdress, this.isDentalAllowedBackend, this.languageID, @@ -52,7 +58,7 @@ class RequestSendRadReportEmail { this.setupID, this.to, this.tokenID, - this.versionID}); + this.versionID, this.isDownload}); RequestSendRadReportEmail.fromJson(Map json) { channel = json['Channel']; @@ -62,6 +68,8 @@ class RequestSendRadReportEmail { doctorName = json['DoctorName']; generalid = json['generalid']; invoiceNo = json['InvoiceNo']; + invoiceNo_VP = json['InvoiceNo_VP']; + invoiceType = json['InvoiceType']; iPAdress = json['IPAdress']; isDentalAllowedBackend = json['isDentalAllowedBackend']; languageID = json['LanguageID']; @@ -81,6 +89,7 @@ class RequestSendRadReportEmail { to = json['To']; tokenID = json['TokenID']; versionID = json['VersionID']; + invoiceLineItemNo = json['InvoiceLineItemNo']; } Map toJson() { @@ -92,6 +101,8 @@ class RequestSendRadReportEmail { data['DoctorName'] = this.doctorName; data['generalid'] = this.generalid; data['InvoiceNo'] = this.invoiceNo; + data['InvoiceNo_VP'] = this.invoiceNo_VP; + data['InvoiceType'] = this.invoiceType; data['IPAdress'] = this.iPAdress; data['isDentalAllowedBackend'] = this.isDentalAllowedBackend; data['LanguageID'] = this.languageID; @@ -111,6 +122,8 @@ class RequestSendRadReportEmail { data['To'] = this.to; data['TokenID'] = this.tokenID; data['VersionID'] = this.versionID; + data['InvoiceLineItemNo'] = this.invoiceLineItemNo; + data['IsDownload'] = this.isDownload; return data; } } diff --git a/lib/core/model/rate/appointment_details.dart b/lib/core/model/rate/appointment_details.dart index 77d759db..2900bced 100644 --- a/lib/core/model/rate/appointment_details.dart +++ b/lib/core/model/rate/appointment_details.dart @@ -1,10 +1,10 @@ class AppointmentDetails { - String setupID; - int projectID; - int patientID; - int appointmentNo; - int clinicID; - int doctorID; + String? setupID; + int? projectID; + int? patientID; + int? appointmentNo; + int? clinicID; + int? doctorID; dynamic startTime; dynamic endTime; dynamic appointmentDate; diff --git a/lib/core/model/rate/appointment_rate.dart b/lib/core/model/rate/appointment_rate.dart index abb249f4..91070f29 100644 --- a/lib/core/model/rate/appointment_rate.dart +++ b/lib/core/model/rate/appointment_rate.dart @@ -1,26 +1,26 @@ class AppointmentRate { - int rate; - int appointmentNo; - int projectID; - int doctorID; - int clinicID; - String note; - String mobileNumber; - int createdBy; - int editedBy; - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - String sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; - int patientID; - String tokenID; - int patientTypeID; - int patientType; + int? rate; + int? appointmentNo; + int? projectID; + int? doctorID; + int? clinicID; + String? note; + String? mobileNumber; + int? createdBy; + int? editedBy; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + String? sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + int? patientID; + String? tokenID; + int? patientTypeID; + int? patientType; AppointmentRate( {this.rate, diff --git a/lib/core/model/rate/appoitment_rated.dart b/lib/core/model/rate/appoitment_rated.dart index 95358b23..64c0f579 100644 --- a/lib/core/model/rate/appoitment_rated.dart +++ b/lib/core/model/rate/appoitment_rated.dart @@ -1,40 +1,40 @@ class AppoitmentRated { - String setupID; - int projectID; - int appointmentNo; - String appointmentDate; - String appointmentDateN; - int appointmentType; - String bookDate; - int patientType; - int patientID; - int clinicID; - int doctorID; - String endDate; - String startTime; - String endTime; - int status; - int visitType; - int visitFor; - int patientStatusType; - int companyID; - int bookedBy; - String bookedOn; - int confirmedBy; - String confirmedOn; - int arrivalChangedBy; - String arrivedOn; - int editedBy; - String editedOn; - Null doctorName; - String doctorNameN; - String statusDesc; - String statusDescN; - bool vitalStatus; - Null vitalSignAppointmentNo; - int episodeID; - String doctorTitle; - bool isAppoitmentLiveCare; + String? setupID; + int? projectID; + int? appointmentNo; + String? appointmentDate; + String? appointmentDateN; + int? appointmentType; + String? bookDate; + int? patientType; + int? patientID; + int? clinicID; + int? doctorID; + String? endDate; + String? startTime; + String? endTime; + int? status; + int? visitType; + int? visitFor; + int? patientStatusType; + int? companyID; + int? bookedBy; + String? bookedOn; + int? confirmedBy; + String? confirmedOn; + int? arrivalChangedBy; + String? arrivedOn; + int? editedBy; + String? editedOn; + dynamic doctorName; + String? doctorNameN; + String? statusDesc; + String? statusDescN; + bool? vitalStatus; + dynamic vitalSignAppointmentNo; + int? episodeID; + String? doctorTitle; + bool? isAppoitmentLiveCare; AppoitmentRated( {this.setupID, diff --git a/lib/core/model/reports/Reports.dart b/lib/core/model/reports/Reports.dart index 6791a3d4..9e3d59f0 100644 --- a/lib/core/model/reports/Reports.dart +++ b/lib/core/model/reports/Reports.dart @@ -1,33 +1,34 @@ import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; class Reports { - int status; - DateTime encounterDate; - int projectID; - int invoiceNo; - int encounterNo; - String procedureId; - int requestType; - String setupId; - int patientID; - int doctorID; + int? status; + DateTime? encounterDate; + int? projectID; + int? invoiceNo; + dynamic invoiceNo_VP; + int? encounterNo; + String? procedureId; + int? requestType; + String? setupId; + int? patientID; + int? doctorID; dynamic clinicID; - DateTime requestDate; - bool isRead; - DateTime isReadOn; - int actualDoctorRate; - String clinicDescription; + DateTime? requestDate; + bool? isRead; + DateTime? isReadOn; + int? actualDoctorRate; + String? clinicDescription; dynamic clinicDescriptionN; - String docName; - Null docNameN; - String doctorImageURL; + String? docName; + dynamic docNameN; + String? doctorImageURL; dynamic doctorName; dynamic doctorNameN; - int doctorRate; - bool isDoctorAllowVedioCall; - bool isExecludeDoctor; - int noOfPatientsRate; - String projectName; + int? doctorRate; + bool? isDoctorAllowVedioCall; + bool? isExecludeDoctor; + int? noOfPatientsRate; + String? projectName; dynamic projectNameN; Reports( @@ -35,6 +36,7 @@ class Reports { this.encounterDate, this.projectID, this.invoiceNo, + this.invoiceNo_VP, this.encounterNo, this.procedureId, this.requestType, @@ -63,10 +65,10 @@ class Reports { Reports.fromJson(Map json) { try { status = json['Status']; - encounterDate = DateUtil.convertStringToDate( - json['EncounterDate']); //json['EncounterDate']; + encounterDate = DateUtil.convertStringToDate(json['EncounterDate']); //json['EncounterDate']; projectID = json['ProjectID']; invoiceNo = json['InvoiceNo']; + invoiceNo_VP = json['InvoiceNo_VP']; encounterNo = json['EncounterNo']; procedureId = json['ProcedureId']; requestType = json['RequestType']; @@ -74,11 +76,9 @@ class Reports { patientID = json['PatientID']; doctorID = json['DoctorID']; clinicID = json['ClinicID']; - requestDate = DateUtil.convertStringToDate( - json['RequestDate']); //json['RequestDate']; + requestDate = DateUtil.convertStringToDate(json['RequestDate']); //json['RequestDate']; isRead = json['IsRead']; - isReadOn = - DateUtil.convertStringToDate(json['IsReadOn']); //json['IsReadOn']; + isReadOn = DateUtil.convertStringToDate(json['IsReadOn']); //json['IsReadOn']; actualDoctorRate = json['ActualDoctorRate']; clinicDescription = json['ClinicDescription']; clinicDescriptionN = json['ClinicDescriptionN']; @@ -93,7 +93,7 @@ class Reports { noOfPatientsRate = json['NoOfPatientsRate']; projectName = json['ProjectName']; projectNameN = json['ProjectNameN']; - }catch(e){ + } catch (e) { print(e); } } @@ -104,6 +104,7 @@ class Reports { data['EncounterDate'] = this.encounterDate; data['ProjectID'] = this.projectID; data['InvoiceNo'] = this.invoiceNo; + data['InvoiceNo_VP'] = this.invoiceNo_VP; data['EncounterNo'] = this.encounterNo; data['ProcedureId'] = this.procedureId; data['RequestType'] = this.requestType; @@ -133,11 +134,11 @@ class Reports { } class ReportsList { - String filterName = ""; + String? filterName = ""; - List reportsList = List(); + List reportsList = []; - ReportsList({this.filterName, Reports reports}) { - reportsList.add(reports); + ReportsList({this.filterName, Reports? reports}) { + reportsList.add(reports!); } } diff --git a/lib/core/model/reports/admission_for_medical_report.dart b/lib/core/model/reports/admission_for_medical_report.dart new file mode 100644 index 00000000..a807b2fe --- /dev/null +++ b/lib/core/model/reports/admission_for_medical_report.dart @@ -0,0 +1,228 @@ +class AdmissionMedicalReport { + int? rowID; + String? setupID; + int? projectID; + int? admissionNo; + String? admissionDate; + int? admissionRequestNo; + int? admissionType; + int? patientType; + int? patientID; + int? clinicID; + int? doctorID; + int? admittingClinicID; + int? admittingDoctorID; + int? categoryID; + String? roomID; + String? bedID; + String? dischargeDate; + int? approvalNo; + dynamic relativeID; + String? registrationDate; + String? firstName; + String? middleName; + String? lastName; + String? firstNameN; + String? middleNameN; + String? lastNameN; + int? patientCategory; + int? gender; + String? dateofBirth; + String? dateofBirthN; + String? nationalityID; + String? firstVisit; + String? lastVisit; + int? noOfVisit; + String? mobileNumber; + String? patientIdentificationNo; + int? sTATUS; + int? admissionStatus; + int? buildingID; + String? buildingDescription; + String? buildingDescriptionN; + int? floorID; + int? bedGender; + int? tariffType; + dynamic cRSVerificationStatus; + String? nursingStationID; + String? description; + String? clinicName; + String? doctorNameObj; + int? patientDataVerified; + String? projectName; + dynamic projectNameN; + String? statusDescription; + String? statusDescriptionN; + + AdmissionMedicalReport( + {this.rowID, + this.setupID, + this.projectID, + this.admissionNo, + this.admissionDate, + this.admissionRequestNo, + this.admissionType, + this.patientType, + this.patientID, + this.clinicID, + this.doctorID, + this.admittingClinicID, + this.admittingDoctorID, + this.categoryID, + this.roomID, + this.bedID, + this.dischargeDate, + this.approvalNo, + this.relativeID, + this.registrationDate, + this.firstName, + this.middleName, + this.lastName, + this.firstNameN, + this.middleNameN, + this.lastNameN, + this.patientCategory, + this.gender, + this.dateofBirth, + this.dateofBirthN, + this.nationalityID, + this.firstVisit, + this.lastVisit, + this.noOfVisit, + this.mobileNumber, + this.patientIdentificationNo, + this.sTATUS, + this.admissionStatus, + this.buildingID, + this.buildingDescription, + this.buildingDescriptionN, + this.floorID, + this.bedGender, + this.tariffType, + this.cRSVerificationStatus, + this.nursingStationID, + this.description, + this.clinicName, + this.doctorNameObj, + this.patientDataVerified, + this.projectName, + this.projectNameN, + this.statusDescription, + this.statusDescriptionN}); + + AdmissionMedicalReport.fromJson(Map json) { + rowID = json['RowID']; + setupID = json['SetupID']; + projectID = json['ProjectID']; + admissionNo = json['AdmissionNo']; + admissionDate = json['AdmissionDate']; + admissionRequestNo = json['AdmissionRequestNo']; + admissionType = json['AdmissionType']; + patientType = json['PatientType']; + patientID = json['PatientID']; + clinicID = json['ClinicID']; + doctorID = json['DoctorID']; + admittingClinicID = json['AdmittingClinicID']; + admittingDoctorID = json['AdmittingDoctorID']; + categoryID = json['CategoryID']; + roomID = json['RoomID']; + bedID = json['BedID']; + dischargeDate = json['DischargeDate']; + approvalNo = json['ApprovalNo']; + relativeID = json['RelativeID']; + registrationDate = json['RegistrationDate']; + firstName = json['FirstName']; + middleName = json['MiddleName']; + lastName = json['LastName']; + firstNameN = json['FirstNameN']; + middleNameN = json['MiddleNameN']; + lastNameN = json['LastNameN']; + patientCategory = json['PatientCategory']; + gender = json['Gender']; + dateofBirth = json['DateofBirth']; + dateofBirthN = json['DateofBirthN']; + nationalityID = json['NationalityID']; + firstVisit = json['FirstVisit']; + lastVisit = json['LastVisit']; + noOfVisit = json['NoOfVisit']; + mobileNumber = json['MobileNumber']; + patientIdentificationNo = json['PatientIdentificationNo']; + sTATUS = json['STATUS']; + admissionStatus = json['AdmissionStatus']; + buildingID = json['BuildingID']; + buildingDescription = json['BuildingDescription']; + buildingDescriptionN = json['BuildingDescriptionN']; + floorID = json['FloorID']; + bedGender = json['BedGender']; + tariffType = json['TariffType']; + cRSVerificationStatus = json['CRSVerificationStatus']; + nursingStationID = json['NursingStationID']; + description = json['Description']; + clinicName = json['ClinicName']; + doctorNameObj = json['DoctorNameObj']; + patientDataVerified = json['PatientDataVerified']; + projectName = json['ProjectName']; + projectNameN = json['ProjectNameN']; + statusDescription = json['StatusDescription']; + statusDescriptionN = json['StatusDescriptionN']; + } + + Map toJson() { + final Map data = new Map(); + data['RowID'] = this.rowID; + data['SetupID'] = this.setupID; + data['ProjectID'] = this.projectID; + data['AdmissionNo'] = this.admissionNo; + data['AdmissionDate'] = this.admissionDate; + data['AdmissionRequestNo'] = this.admissionRequestNo; + data['AdmissionType'] = this.admissionType; + data['PatientType'] = this.patientType; + data['PatientID'] = this.patientID; + data['ClinicID'] = this.clinicID; + data['DoctorID'] = this.doctorID; + data['AdmittingClinicID'] = this.admittingClinicID; + data['AdmittingDoctorID'] = this.admittingDoctorID; + data['CategoryID'] = this.categoryID; + data['RoomID'] = this.roomID; + data['BedID'] = this.bedID; + data['DischargeDate'] = this.dischargeDate; + data['ApprovalNo'] = this.approvalNo; + data['RelativeID'] = this.relativeID; + data['RegistrationDate'] = this.registrationDate; + data['FirstName'] = this.firstName; + data['MiddleName'] = this.middleName; + data['LastName'] = this.lastName; + data['FirstNameN'] = this.firstNameN; + data['MiddleNameN'] = this.middleNameN; + data['LastNameN'] = this.lastNameN; + data['PatientCategory'] = this.patientCategory; + data['Gender'] = this.gender; + data['DateofBirth'] = this.dateofBirth; + data['DateofBirthN'] = this.dateofBirthN; + data['NationalityID'] = this.nationalityID; + data['FirstVisit'] = this.firstVisit; + data['LastVisit'] = this.lastVisit; + data['NoOfVisit'] = this.noOfVisit; + data['MobileNumber'] = this.mobileNumber; + data['PatientIdentificationNo'] = this.patientIdentificationNo; + data['STATUS'] = this.sTATUS; + data['AdmissionStatus'] = this.admissionStatus; + data['BuildingID'] = this.buildingID; + data['BuildingDescription'] = this.buildingDescription; + data['BuildingDescriptionN'] = this.buildingDescriptionN; + data['FloorID'] = this.floorID; + data['BedGender'] = this.bedGender; + data['TariffType'] = this.tariffType; + data['CRSVerificationStatus'] = this.cRSVerificationStatus; + data['NursingStationID'] = this.nursingStationID; + data['Description'] = this.description; + data['ClinicName'] = this.clinicName; + data['DoctorNameObj'] = this.doctorNameObj; + data['PatientDataVerified'] = this.patientDataVerified; + data['ProjectName'] = this.projectName; + data['ProjectNameN'] = this.projectNameN; + data['StatusDescription'] = this.statusDescription; + data['StatusDescriptionN'] = this.statusDescriptionN; + return data; + } +} diff --git a/lib/core/model/reports/request_report_history.dart b/lib/core/model/reports/request_report_history.dart index f7d02cc5..d3bf22cf 100644 --- a/lib/core/model/reports/request_report_history.dart +++ b/lib/core/model/reports/request_report_history.dart @@ -1,20 +1,20 @@ class RequestReportHistory { - int projectID; - int clinicID; - bool isForMedicalReport; - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - String sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; - int patientID; - String tokenID; - int patientTypeID; - int patientType; + int? projectID; + int? clinicID; + bool? isForMedicalReport; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + String? sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + int? patientID; + String? tokenID; + int? patientTypeID; + int? patientType; RequestReportHistory( {this.projectID, diff --git a/lib/core/model/reports/request_reports.dart b/lib/core/model/reports/request_reports.dart index 14359591..045f76b6 100644 --- a/lib/core/model/reports/request_reports.dart +++ b/lib/core/model/reports/request_reports.dart @@ -1,38 +1,40 @@ class RequestReports { - bool isReport; - int encounterType; - int requestType; - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - String sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; - int patientID; - String tokenID; - int patientTypeID; - int patientType; + bool? isReport; + int? encounterType; + int? requestType; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + String? sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + int? patientID; + String? tokenID; + int? patientTypeID; + int? patientType; + int? projectID; RequestReports( {this.isReport, - this.encounterType, - this.requestType, - this.versionID, - this.channel, - this.languageID, - this.iPAdress, - this.generalid, - this.patientOutSA, - this.sessionID, - this.isDentalAllowedBackend, - this.deviceTypeID, - this.patientID, - this.tokenID, - this.patientTypeID, - this.patientType}); + this.encounterType, + this.requestType, + this.versionID, + this.channel, + this.languageID, + this.iPAdress, + this.generalid, + this.patientOutSA, + this.sessionID, + this.isDentalAllowedBackend, + this.deviceTypeID, + this.patientID, + this.tokenID, + this.patientTypeID, + this.patientType, + this.projectID}); RequestReports.fromJson(Map json) { isReport = json['IsReport']; @@ -51,6 +53,7 @@ class RequestReports { tokenID = json['TokenID']; patientTypeID = json['PatientTypeID']; patientType = json['PatientType']; + projectID = json['ProjectID']; } Map toJson() { @@ -71,6 +74,7 @@ class RequestReports { data['TokenID'] = this.tokenID; data['PatientTypeID'] = this.patientTypeID; data['PatientType'] = this.patientType; + data['ProjectID'] = this.projectID; return data; } -} \ No newline at end of file +} diff --git a/lib/core/model/search_products_model.dart b/lib/core/model/search_products_model.dart index d63fd4b0..30444e56 100644 --- a/lib/core/model/search_products_model.dart +++ b/lib/core/model/search_products_model.dart @@ -1,32 +1,32 @@ class SearchProductsModel { - String id; - String name; - String namen; - List localizedNames; - String shortDescription; - String fullDescription; - String fullDescriptionn; + String? id; + String? name; + String? namen; + List? localizedNames; + String? shortDescription; + String? fullDescription; + String? fullDescriptionn; dynamic approvedRatingSum; dynamic approvedTotalReviews; - String sku; - bool isRx; + String? sku; + bool? isRx; dynamic rxMessage; dynamic rxMessagen; dynamic stockQuantity; - String stockAvailability; - String stockAvailabilityn; - bool allowBackInStockSubscriptions; + String? stockAvailability; + String? stockAvailabilityn; + bool? allowBackInStockSubscriptions; dynamic orderMinimumQuantity; dynamic orderMaximumQuantity; - double price; + double? price; dynamic oldPrice; dynamic discountName; dynamic discountNamen; dynamic discountPercentage; dynamic displayOrder; - List discountIds; - List reviews; - List images; + List? discountIds; + List? reviews; + List? images; SearchProductsModel( {this.id, @@ -63,9 +63,9 @@ class SearchProductsModel { name = json['name']; namen = json['namen']; if (json['localized_names'] != null) { - localizedNames = new List(); + localizedNames = []; json['localized_names'].forEach((v) { - localizedNames.add(new LocalizedNames.fromJson(v)); + localizedNames!.add(new LocalizedNames.fromJson(v)); }); } shortDescription = json['short_description']; @@ -91,9 +91,9 @@ class SearchProductsModel { displayOrder = json['display_order']; if (json['images'] != null) { - images = new List(); + images = []; json['images'].forEach((v) { - images.add(new Images.fromJson(v)); + images!.add(new Images.fromJson(v)); }); } } @@ -104,8 +104,7 @@ class SearchProductsModel { data['name'] = this.name; data['namen'] = this.namen; if (this.localizedNames != null) { - data['localized_names'] = - this.localizedNames.map((v) => v.toJson()).toList(); + data['localized_names'] = this.localizedNames!.map((v) => v.toJson()).toList(); } data['short_description'] = this.shortDescription; data['full_description'] = this.fullDescription; @@ -119,8 +118,7 @@ class SearchProductsModel { data['stock_quantity'] = this.stockQuantity; data['stock_availability'] = this.stockAvailability; data['stock_availabilityn'] = this.stockAvailabilityn; - data['allow_back_in_stock_subscriptions'] = - this.allowBackInStockSubscriptions; + data['allow_back_in_stock_subscriptions'] = this.allowBackInStockSubscriptions; data['order_minimum_quantity'] = this.orderMinimumQuantity; data['order_maximum_quantity'] = this.orderMaximumQuantity; data['price'] = this.price; @@ -131,15 +129,15 @@ class SearchProductsModel { data['display_order'] = this.displayOrder; if (this.images != null) { - data['images'] = this.images.map((v) => v.toJson()).toList(); + data['images'] = this.images!.map((v) => v.toJson()).toList(); } return data; } } class LocalizedNames { - int languageId; - String localizedName; + int? languageId; + String? localizedName; LocalizedNames({this.languageId, this.localizedName}); @@ -157,11 +155,11 @@ class LocalizedNames { } class Images { - int id; - int position; - String src; - String thumb; - String attachment; + int? id; + int? position; + String? src; + String? thumb; + String? attachment; Images({this.id, this.position, this.src, this.thumb, this.attachment}); diff --git a/lib/core/model/sick_leave/admission_status_for_sick_leave.dart b/lib/core/model/sick_leave/admission_status_for_sick_leave.dart new file mode 100644 index 00000000..9532a5dd --- /dev/null +++ b/lib/core/model/sick_leave/admission_status_for_sick_leave.dart @@ -0,0 +1,64 @@ +class AdmissionStatusForSickLeave { + String? setupID; + int? projectID; + int? patientID; + int? patientType; + int? requestNo; + String? requestDate; + int? sickLeaveDays; + int? appointmentNo; + int? admissionNo; + String? reportDate; + String? placeOfWork; + int? status; + dynamic dischargeDate; + + AdmissionStatusForSickLeave( + {this.setupID, + this.projectID, + this.patientID, + this.patientType, + this.requestNo, + this.requestDate, + this.sickLeaveDays, + this.appointmentNo, + this.admissionNo, + this.reportDate, + this.placeOfWork, + this.status, + this.dischargeDate}); + + AdmissionStatusForSickLeave.fromJson(Map json) { + setupID = json['SetupID']; + projectID = json['ProjectID']; + patientID = json['PatientID']; + patientType = json['PatientType']; + requestNo = json['RequestNo']; + requestDate = json['RequestDate']; + sickLeaveDays = json['SickLeaveDays']; + appointmentNo = json['AppointmentNo']; + admissionNo = json['AdmissionNo']; + reportDate = json['ReportDate']; + placeOfWork = json['PlaceOfWork']; + status = json['Status']; + dischargeDate = json['DischargeDate']; + } + + Map toJson() { + final Map data = new Map(); + data['SetupID'] = this.setupID; + data['ProjectID'] = this.projectID; + data['PatientID'] = this.patientID; + data['PatientType'] = this.patientType; + data['RequestNo'] = this.requestNo; + data['RequestDate'] = this.requestDate; + data['SickLeaveDays'] = this.sickLeaveDays; + data['AppointmentNo'] = this.appointmentNo; + data['AdmissionNo'] = this.admissionNo; + data['ReportDate'] = this.reportDate; + data['PlaceOfWork'] = this.placeOfWork; + data['Status'] = this.status; + data['DischargeDate'] = this.dischargeDate; + return data; + } +} diff --git a/lib/core/model/sick_leave/sick_leave.dart b/lib/core/model/sick_leave/sick_leave.dart index 6811a552..d089366f 100644 --- a/lib/core/model/sick_leave/sick_leave.dart +++ b/lib/core/model/sick_leave/sick_leave.dart @@ -1,38 +1,39 @@ import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; class SickLeave { - String setupID; - int projectID; - int patientID; - int patientType; - int clinicID; - int doctorID; - int requestNo; - DateTime requestDate; - int sickLeaveDays; - int appointmentNo; - int admissionNo; - int actualDoctorRate; - String appointmentDate; - String clinicName; - String doctorImageURL; - String doctorName; - int doctorRate; - String doctorTitle; - int gender; - String genderDescription; - bool isActiveDoctorProfile; - bool isDoctorAllowVedioCall; - bool isExecludeDoctor; - bool isInOutPatient; - String isInOutPatientDescription; - String isInOutPatientDescriptionN; - int noOfPatientsRate; - Null patientName; - String projectName; - String qR; - List speciality; - bool isLiveCareAppointment; + String? setupID; + int? projectID; + int? patientID; + int? patientType; + int? clinicID; + int? doctorID; + int? requestNo; + DateTime? requestDate; + int? sickLeaveDays; + int? appointmentNo; + int? admissionNo; + int? actualDoctorRate; + DateTime? appointmentDate; + String? clinicName; + String? doctorImageURL; + String? doctorName; + int? doctorRate; + String? doctorTitle; + int? gender; + String? genderDescription; + bool? isActiveDoctorProfile; + bool? isDoctorAllowVedioCall; + bool? isExecludeDoctor; + bool? isInOutPatient; + String? isInOutPatientDescription; + String? isInOutPatientDescriptionN; + int? noOfPatientsRate; + dynamic patientName; + String? projectName; + String? qR; + List? speciality; + bool? isLiveCareAppointment; + int? status; SickLeave( {this.setupID, @@ -65,7 +66,7 @@ class SickLeave { this.patientName, this.projectName, this.qR, - this.speciality,this.isLiveCareAppointment}); + this.speciality,this.isLiveCareAppointment, this.status}); SickLeave.fromJson(Map json) { setupID = json['SetupID']; @@ -80,7 +81,7 @@ class SickLeave { appointmentNo = json['AppointmentNo']; admissionNo = json['AdmissionNo']; actualDoctorRate = json['ActualDoctorRate']; - appointmentDate = json['AppointmentDate']; + appointmentDate = DateUtil.convertStringToDate(json['AppointmentDate']); clinicName = json['ClinicName']; doctorImageURL = json['DoctorImageURL']; doctorName = json['DoctorName']; @@ -98,6 +99,7 @@ class SickLeave { patientName = json['PatientName']; projectName = json['ProjectName']; qR = json['QR']; + status = json['Status']; isLiveCareAppointment = json['IsLiveCareAppointment']; if(json['Speciality']!=null) speciality = json['Speciality'].cast(); @@ -112,7 +114,7 @@ class SickLeave { data['ClinicID'] = this.clinicID; data['DoctorID'] = this.doctorID; data['RequestNo'] = this.requestNo; - data['RequestDate'] = DateUtil.convertDateToString(requestDate); + data['RequestDate'] = DateUtil.convertDateToString(requestDate!); data['SickLeaveDays'] = this.sickLeaveDays; data['AppointmentNo'] = this.appointmentNo; data['AdmissionNo'] = this.admissionNo; @@ -135,6 +137,7 @@ class SickLeave { data['PatientName'] = this.patientName; data['ProjectName'] = this.projectName; data['QR'] = this.qR; + data['Status'] = this.status; data['Speciality'] = this.speciality; return data; } diff --git a/lib/core/model/vaccine/my_vaccine.dart b/lib/core/model/vaccine/my_vaccine.dart index dc921c12..0c55bf55 100644 --- a/lib/core/model/vaccine/my_vaccine.dart +++ b/lib/core/model/vaccine/my_vaccine.dart @@ -1,76 +1,76 @@ class VaccineModel { - String setupID; - int projectID; - int patientID; - int invoiceNo; - String procedureID; - String vaccineName; - Null vaccineNameN; - String invoiceDate; - int doctorID; - int clinicID; - String firstName; - String middleName; - String lastName; - Null firstNameN; - Null middleNameN; - Null lastNameN; - String dateofBirth; - int actualDoctorRate; - String age; - String clinicName; - String doctorImageURL; - String doctorName; - int doctorRate; - String doctorTitle; - int gender; - String genderDescription; - bool isActiveDoctorProfile; - bool isDoctorAllowVedioCall; - bool isExecludeDoctor; - int noOfPatientsRate; - String patientName; - String projectName; - String qR; - List speciality; - String vaccinationDate; + String? setupID; + int? projectID; + int? patientID; + int? invoiceNo; + String? procedureID; + String? vaccineName; + dynamic vaccineNameN; + String? invoiceDate; + int? doctorID; + int? clinicID; + String? firstName; + String? middleName; + String? lastName; + dynamic firstNameN; + dynamic middleNameN; + dynamic lastNameN; + String? dateofBirth; + int? actualDoctorRate; + String? age; + String? clinicName; + String? doctorImageURL; + String? doctorName; + int? doctorRate; + String? doctorTitle; + int? gender; + String? genderDescription; + bool? isActiveDoctorProfile; + bool? isDoctorAllowVedioCall; + bool? isExecludeDoctor; + int? noOfPatientsRate; + String? patientName; + String? projectName; + String? qR; + List? speciality; + String? vaccinationDate; VaccineModel( {this.setupID, - this.projectID, - this.patientID, - this.invoiceNo, - this.procedureID, - this.vaccineName, - this.vaccineNameN, - this.invoiceDate, - this.doctorID, - this.clinicID, - this.firstName, - this.middleName, - this.lastName, - this.firstNameN, - this.middleNameN, - this.lastNameN, - this.dateofBirth, - this.actualDoctorRate, - this.age, - this.clinicName, - this.doctorImageURL, - this.doctorName, - this.doctorRate, - this.doctorTitle, - this.gender, - this.genderDescription, - this.isActiveDoctorProfile, - this.isDoctorAllowVedioCall, - this.isExecludeDoctor, - this.noOfPatientsRate, - this.patientName, - this.projectName, - this.qR, - this.speciality, - this.vaccinationDate}); + this.projectID, + this.patientID, + this.invoiceNo, + this.procedureID, + this.vaccineName, + this.vaccineNameN, + this.invoiceDate, + this.doctorID, + this.clinicID, + this.firstName, + this.middleName, + this.lastName, + this.firstNameN, + this.middleNameN, + this.lastNameN, + this.dateofBirth, + this.actualDoctorRate, + this.age, + this.clinicName, + this.doctorImageURL, + this.doctorName, + this.doctorRate, + this.doctorTitle, + this.gender, + this.genderDescription, + this.isActiveDoctorProfile, + this.isDoctorAllowVedioCall, + this.isExecludeDoctor, + this.noOfPatientsRate, + this.patientName, + this.projectName, + this.qR, + this.speciality, + this.vaccinationDate}); VaccineModel.fromJson(Map json) { setupID = json['SetupID']; @@ -106,7 +106,7 @@ class VaccineModel { patientName = json['PatientName']; projectName = json['ProjectName']; qR = json['QR']; - speciality = json['Speciality'].cast(); + speciality = json['Speciality'] != null ? json['Speciality'].cast() : []; vaccinationDate = json['VaccinationDate']; } diff --git a/lib/core/model/vaccine/vaccination_item.dart b/lib/core/model/vaccine/vaccination_item.dart index 0009ea7d..63201361 100644 --- a/lib/core/model/vaccine/vaccination_item.dart +++ b/lib/core/model/vaccine/vaccination_item.dart @@ -1,6 +1,6 @@ class VaccinationItem { - String dESCRIPTION; - String iTEMCODE; + String? dESCRIPTION; + String? iTEMCODE; VaccinationItem({this.dESCRIPTION, this.iTEMCODE}); diff --git a/lib/core/model/vaccine/vaccination_on_hand.dart b/lib/core/model/vaccine/vaccination_on_hand.dart index daf3e886..18571a73 100644 --- a/lib/core/model/vaccine/vaccination_on_hand.dart +++ b/lib/core/model/vaccine/vaccination_on_hand.dart @@ -1,12 +1,12 @@ class VaccinationOnHand { - int distanceInKilometers; - int iTEMONHAND; - bool isThereItems; - String oRGANIZATIONCODE; - String oRGANIZATIONNAME; - String projectAlias; - int projectID; - String projectName; + int? distanceInKilometers; + int? iTEMONHAND; + bool? isThereItems; + String? oRGANIZATIONCODE; + String? oRGANIZATIONNAME; + String? projectAlias; + int? projectID; + String? projectName; VaccinationOnHand( {this.distanceInKilometers, diff --git a/lib/core/model/vital_sign/vital_sign_req_model.dart b/lib/core/model/vital_sign/vital_sign_req_model.dart index 7cad3ef7..f39566aa 100644 --- a/lib/core/model/vital_sign/vital_sign_req_model.dart +++ b/lib/core/model/vital_sign/vital_sign_req_model.dart @@ -1,18 +1,18 @@ class VitalSignReqModel { - int patientID; - int projectID; - int patientTypeID; - int inOutpatientType; - int transNo; - int languageID; - String stamp ; - String iPAdress; - double versionID; - int channel; - String tokenID; - String sessionID; - bool isLoginForDoctorApp; - bool patientOutSA; + int? patientID; + int? projectID; + int? patientTypeID; + int? inOutpatientType; + int? transNo; + int? languageID; + String? stamp ; + String? iPAdress; + double? versionID; + int? channel; + String? tokenID; + String? sessionID; + bool? isLoginForDoctorApp; + bool? patientOutSA; VitalSignReqModel( {this.patientID, diff --git a/lib/core/model/vital_sign/vital_sign_res_model.dart b/lib/core/model/vital_sign/vital_sign_res_model.dart index 1377e626..53b385fe 100644 --- a/lib/core/model/vital_sign/vital_sign_res_model.dart +++ b/lib/core/model/vital_sign/vital_sign_res_model.dart @@ -27,9 +27,9 @@ class VitalSignResModel { var painDuration; var painCharacter; var painFrequency; - bool isPainManagementDone; + bool? isPainManagementDone; var status; - bool isVitalsRequired; + bool? isVitalsRequired; var patientID; var createdOn; var doctorID; @@ -37,7 +37,7 @@ class VitalSignResModel { var triageCategory; var gCScore; var lineItemNo; - DateTime vitalSignDate; + DateTime? vitalSignDate; var actualTimeTaken; var sugarLevel; var fBS; diff --git a/lib/core/model/weahter/weather_model.dart b/lib/core/model/weahter/weather_model.dart index 37ee5983..ddef871c 100644 --- a/lib/core/model/weahter/weather_model.dart +++ b/lib/core/model/weahter/weather_model.dart @@ -1,34 +1,34 @@ class WeatherIndicatorModel { - Null date; - int languageID; - int serviceName; - Null time; - Null androidLink; - Null authenticationTokenID; - Null data; - bool dataw; - int dietType; - Null errorCode; - Null errorEndUserMessage; - Null errorEndUserMessageN; - Null errorMessage; - int errorType; - int foodCategory; - Null iOSLink; - bool isAuthenticated; - int mealOrderStatus; - int mealType; - int messageStatus; - int numberOfResultRecords; - Null patientBlodType; - Null successMsg; - Null successMsgN; - Null citiesList; - Null cityName; - Null get5DaysWeatherForecastList; - List getCityInfoList; - Null getTodayWeatherForecastList; - Null iniciesList; + dynamic date; + int? languageID; + int? serviceName; + dynamic time; + dynamic androidLink; + dynamic authenticationTokenID; + dynamic data; + bool? dataw; + int? dietType; + dynamic errorCode; + dynamic errorEndUserMessage; + dynamic errorEndUserMessageN; + dynamic errorMessage; + int? errorType; + int? foodCategory; + dynamic iOSLink; + bool? isAuthenticated; + int? mealOrderStatus; + int? mealType; + int? messageStatus; + int? numberOfResultRecords; + dynamic patientBlodType; + dynamic successMsg; + dynamic successMsgN; + dynamic citiesList; + dynamic cityName; + dynamic get5DaysWeatherForecastList; + List? getCityInfoList; + dynamic getTodayWeatherForecastList; + dynamic iniciesList; WeatherIndicatorModel( {this.date, @@ -91,9 +91,9 @@ class WeatherIndicatorModel { cityName = json['CityName']; get5DaysWeatherForecastList = json['Get5DaysWeatherForecastList']; if (json['GetCityInfo_List'] != null) { - getCityInfoList = new List(); + getCityInfoList = []; json['GetCityInfo_List'].forEach((v) { - getCityInfoList.add(new GetCityInfoList.fromJson(v)); + getCityInfoList!.add(new GetCityInfoList.fromJson(v)); }); } getTodayWeatherForecastList = json['GetTodayWeatherForecastList']; @@ -131,7 +131,7 @@ class WeatherIndicatorModel { data['Get5DaysWeatherForecastList'] = this.get5DaysWeatherForecastList; if (this.getCityInfoList != null) { data['GetCityInfo_List'] = - this.getCityInfoList.map((v) => v.toJson()).toList(); + this.getCityInfoList!.map((v) => v.toJson()).toList(); } data['GetTodayWeatherForecastList'] = this.getTodayWeatherForecastList; data['IniciesList'] = this.iniciesList; @@ -140,25 +140,25 @@ class WeatherIndicatorModel { } class GetCityInfoList { - CategoriesNames categoriesNames; - String category; - String categoryValue; - int cityID; - String cityName; - String cityNameN; - String colorName; - String createdOn; - String iD; - int iniceID; - bool isOrderEmpty; - bool isValuesReversed; - bool language; - double latitude; - double longitude; - String name; - int orderNum; - double temperature; - String value; + CategoriesNames? categoriesNames; + String? category; + String? categoryValue; + int? cityID; + String? cityName; + String? cityNameN; + String? colorName; + String? createdOn; + String? iD; + int? iniceID; + bool? isOrderEmpty; + bool? isValuesReversed; + bool? language; + double? latitude; + double? longitude; + String? name; + int? orderNum; + double? temperature; + String? value; GetCityInfoList( {this.categoriesNames, @@ -208,7 +208,7 @@ class GetCityInfoList { Map toJson() { final Map data = new Map(); if (this.categoriesNames != null) { - data['CategoriesNames'] = this.categoriesNames.toJson(); + data['CategoriesNames'] = this.categoriesNames!.toJson(); } data['Category'] = this.category; data['CategoryValue'] = this.categoryValue; @@ -233,11 +233,11 @@ class GetCityInfoList { } class CategoriesNames { - String category1; - String category2; - String category3; - String category4; - String category5; + String? category1; + String? category2; + String? category3; + String? category4; + String? category5; CategoriesNames( {this.category1, diff --git a/lib/core/service/AlHabibMedicalService/H2O_service.dart b/lib/core/service/AlHabibMedicalService/H2O_service.dart index 9483bc31..6c17a750 100644 --- a/lib/core/service/AlHabibMedicalService/H2O_service.dart +++ b/lib/core/service/AlHabibMedicalService/H2O_service.dart @@ -9,21 +9,25 @@ import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/H2O/user_p import 'package:diplomaticquarterapp/core/service/base_service.dart'; class H2OService extends BaseService { - List userProgressForTodayDataList = List(); - List userProgressForWeekDataList = List(); - List userProgressForMonthDataList = List(); + List userProgressForTodayDataList = []; + List userProgressForWeekDataList = []; + List userProgressForMonthDataList = []; UserProgressRequestModel userProgressRequestModel = UserProgressRequestModel(); UserDetailModel userDetailModel = UserDetailModel(); Future getUserDetail() async { userProgressRequestModel.progress = 1; - userProgressRequestModel.mobileNumber = user.mobileNumber.substring(1); + userProgressRequestModel.mobileNumber = user.mobileNumber!.substring(1); userProgressRequestModel.identificationNo = user.patientIdentificationNo; hasError = false; await baseAppClient.post(H2O_GET_USER_DETAIL, onSuccess: (dynamic response, int statusCode) { - userDetailModel = UserDetailModel.fromJson(response["UserDetailData_New"]); + if (response["UserDetailData_New"] != null) { + userDetailModel = UserDetailModel.fromJson(response["UserDetailData_New"]); + } else { + userDetailModel = UserDetailModel(); + } }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; @@ -32,7 +36,7 @@ class H2OService extends BaseService { Future updateUserDetail(UserDetailModel userDetail) async { userProgressRequestModel.progress = 1; - userProgressRequestModel.mobileNumber = user.mobileNumber.substring(1); + userProgressRequestModel.mobileNumber = user.mobileNumber!.substring(1); userProgressRequestModel.identificationNo = user.patientIdentificationNo; UserDetailRequestModel _requestModel = UserDetailRequestModel(); @@ -75,7 +79,7 @@ class H2OService extends BaseService { Future getUserProgressForTodayData() async { userProgressRequestModel.progress = 1; - userProgressRequestModel.mobileNumber = user.mobileNumber.substring(1); + userProgressRequestModel.mobileNumber = user.mobileNumber!.substring(1); userProgressRequestModel.identificationNo = user.patientIdentificationNo; hasError = false; @@ -92,7 +96,7 @@ class H2OService extends BaseService { Future getUserProgressForWeekData() async { userProgressRequestModel.progress = 2; - userProgressRequestModel.mobileNumber = super.user.mobileNumber.substring(1); + userProgressRequestModel.mobileNumber = super.user.mobileNumber!.substring(1); userProgressRequestModel.identificationNo = super.user.patientIdentificationNo; hasError = false; @@ -109,7 +113,7 @@ class H2OService extends BaseService { Future getUserProgressForMonthData() async { userProgressRequestModel.progress = 3; - userProgressRequestModel.mobileNumber = super.user.mobileNumber.substring(1); + userProgressRequestModel.mobileNumber = super.user.mobileNumber!.substring(1); userProgressRequestModel.identificationNo = super.user.patientIdentificationNo; hasError = false; @@ -139,7 +143,7 @@ class H2OService extends BaseService { Future undoUserActivity() async { userProgressRequestModel.progress = 1; - userProgressRequestModel.mobileNumber = user.mobileNumber.substring(1); + userProgressRequestModel.mobileNumber = user.mobileNumber!.substring(1); userProgressRequestModel.identificationNo = user.patientIdentificationNo; hasError = false; diff --git a/lib/core/service/AlHabibMedicalService/cmc_service.dart b/lib/core/service/AlHabibMedicalService/cmc_service.dart index 9e99f3ad..4def8cb1 100644 --- a/lib/core/service/AlHabibMedicalService/cmc_service.dart +++ b/lib/core/service/AlHabibMedicalService/cmc_service.dart @@ -1,12 +1,12 @@ import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/core/enum/OrderService.dart'; +import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/GetCMCAllOrdersResponseModel.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_get_items_request_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_get_items_response_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_insert_pres_order_request_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/get_cmc_service_request_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/get_cmc_service_response_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/get_hHC_all_pres_orders_request_model.dart'; -import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/get_hhc_all_pres_orders_response_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/get_order_detail_by_order_iD_request_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/get_order_detail_by_order_iD_response_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/update_pres_oreder_request_model.dart'; @@ -14,104 +14,148 @@ import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealth import '../base_service.dart'; class CMCService extends BaseService { - List cmcAllServicesList = List(); - List cmcAllPresOrdersList = List(); + List cmcAllServicesList = []; + List cmcAllPresOrdersList = []; - List cmcAllOrderDetail = List(); - List checkupItemsList = List(); + List cmcAllOrderDetail = []; + List checkupItemsList = []; - bool isOrderUpdated; + bool? isOrderUpdated; Future getCMCAllServices() async { - - - GetCMCServicesRequestModel getCMCServicesRequestModel= new GetCMCServicesRequestModel(genderID: user.gender, identificationNo: user.patientIdentificationNo); + GetCMCServicesRequestModel getCMCServicesRequestModel = + GetCMCServicesRequestModel(genderID: authenticatedUserObject.user.gender, identificationNo: authenticatedUserObject.user.patientIdentificationNo); hasError = false; - await baseAppClient.post(HHC_GET_ALL_CMC_SERVICES, + + // RC IMPLEMENTATION + await baseAppClient.post(GET_ALL_CMC_SERVICES_RC + "?patientID=" + authenticatedUserObject.user.patientID.toString(), isRCService: true, isAllowAny: true, onSuccess: (dynamic response, int statusCode) { cmcAllServicesList.clear(); - response['PatientER_CMC_GetAllServicesList'].forEach((data) { + response['response'].forEach((data) { cmcAllServicesList.add(GetCMCServicesResponseModel.fromJson(data)); }); }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; - }, body: getCMCServicesRequestModel.toJson()); + }, body: {}); + + // await baseAppClient.post(HHC_GET_ALL_CMC_SERVICES, onSuccess: (dynamic response, int statusCode) { + // cmcAllServicesList.clear(); + // response['PatientER_CMC_GetAllServicesList'].forEach((data) { + // cmcAllServicesList.add(GetCMCServicesResponseModel.fromJson(data)); + // }); + // }, onFailure: (String error, int statusCode) { + // hasError = true; + // super.error = error; + // }, body: getCMCServicesRequestModel.toJson()); } - - Future getCmcAllPresOrders() async { + GetHHCAllPresOrdersRequestModel getHHCAllPresOrdersRequestModel = GetHHCAllPresOrdersRequestModel(); + hasError = false; + await baseAppClient.post(GET_PATIENT_ALL_PRES_ORDERS, onSuccess: (dynamic response, int statusCode) { + cmcAllPresOrdersList.clear(); + cmcAllOrderDetail.clear(); + response['response'].forEach((data) { + if (data['ServiceID'] == OrderService.Comprehensive_Medical_Checkup.getIdOrderService()) cmcAllPresOrdersList.add(GetCMCAllOrdersResponseModel.fromJson(data)); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: getHHCAllPresOrdersRequestModel.toJson()); + } - GetHHCAllPresOrdersRequestModel getHHCAllPresOrdersRequestModel= GetHHCAllPresOrdersRequestModel(); + Future getCmcAllPresOrdersRC() async { + GetHHCAllPresOrdersRequestModel getHHCAllPresOrdersRequestModel = GetHHCAllPresOrdersRequestModel(); hasError = false; - await baseAppClient.post(GET_PATIENT_ALL_PRES_ORDERS, - onSuccess: (dynamic response, int statusCode) { - cmcAllPresOrdersList.clear(); - cmcAllOrderDetail.clear(); - response['PatientER_GetPatientAllPresOrdersList'].forEach((data) { - if (data['ServiceID'] == OrderService.Comprehensive_Medical_Checkup.getIdOrderService()) - cmcAllPresOrdersList - .add(GetHHCAllPresOrdersResponseModel.fromJson(data)); + await baseAppClient.post(GET_ALL_CMC_ORDERS_RC, isRCService: true, onSuccess: (dynamic response, int statusCode) { + cmcAllPresOrdersList.clear(); + cmcAllOrderDetail.clear(); + + response['response'].forEach((data) { + cmcAllPresOrdersList.add(GetCMCAllOrdersResponseModel.fromJson(data)); }); - }, onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }, body: getHHCAllPresOrdersRequestModel.toJson()); + + // response['PatientER_GetPatientAllPresOrdersList'].forEach((data) { + // if (data['ServiceID'] == OrderService.Comprehensive_Medical_Checkup.getIdOrderService()) cmcAllPresOrdersList.add(GetHHCAllPresOrdersResponseModel.fromJson(data)); + // }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: getHHCAllPresOrdersRequestModel.toJson()); } Future getOrderDetailByOrderID(GetOrderDetailByOrderIDRequestModel getOrderDetailByOrderIDRequestModel) async { - hasError = false; - await baseAppClient.post(GET_CMC_ORDER_DETAIL_BY_ID, - onSuccess: (dynamic response, int statusCode) { - cmcAllOrderDetail.clear(); - response['PatientER_CMC_GetTransactionsForOrderList'].forEach((data) { - cmcAllOrderDetail.add(GetOrderDetailByOrderIDResponseModel.fromJson(data)); - }); - }, onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }, body: getOrderDetailByOrderIDRequestModel.toJson()); + await baseAppClient.post(GET_CMC_ORDER_DETAIL_BY_ID, onSuccess: (dynamic response, int statusCode) { + cmcAllOrderDetail.clear(); + response['PatientER_CMC_GetTransactionsForOrderList'].forEach((data) { + cmcAllOrderDetail.add(GetOrderDetailByOrderIDResponseModel.fromJson(data)); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: getOrderDetailByOrderIDRequestModel.toJson()); } - Future getCheckupItems(CMCGetItemsRequestModel cMCGetItemsRequestModel) async { - hasError = false; - await baseAppClient.post(GET_CHECK_UP_ITEMS, - onSuccess: (dynamic response, int statusCode) { - checkupItemsList.clear(); - response['GetCheckUpItemsList'].forEach((data) { - checkupItemsList.add(CMCGetItemsResponseModel.fromJson(data)); - }); - }, onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }, body: cMCGetItemsRequestModel.toJson()); + await baseAppClient.post(GET_CHECK_UP_ITEMS, onSuccess: (dynamic response, int statusCode) { + checkupItemsList.clear(); + response['GetCheckUpItemsList'].forEach((data) { + checkupItemsList.add(CMCGetItemsResponseModel.fromJson(data)); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: cMCGetItemsRequestModel.toJson()); } Future updateCmcPresOrder(UpdatePresOrderRequestModel updatePresOrderRequestModel) async { + hasError = false; + await baseAppClient.post(PATIENT_ER_UPDATE_PRES_ORDER, onSuccess: (dynamic response, int statusCode) { + isOrderUpdated = true; + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: updatePresOrderRequestModel.toJson()); + } + Future updateCmcPresOrderRC(UpdatePresOrderRequestModel updatePresOrderRequestModel) async { hasError = false; - await baseAppClient.post(PATIENT_ER_UPDATE_PRES_ORDER, - onSuccess: (dynamic response, int statusCode) { - isOrderUpdated = true; - }, onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }, body: updatePresOrderRequestModel.toJson()); + await baseAppClient.post(UPDATE_CMC_ORDER_RC, isRCService: true, onSuccess: (dynamic response, int statusCode) { + isOrderUpdated = true; + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: updatePresOrderRequestModel.toJson()); } - Future insertPresPresOrder({CMCInsertPresOrderRequestModel order}) async { + Future insertCMCOrderRC({CMCInsertPresOrderRequestModel? order}) async { + hasError = false; + String reqId = ""; + order!.latitude = 0.0; + order.longitude = 0.0; + await baseAppClient.post(ADD_CMC_ORDER_RC, isRCService: true, onSuccess: (dynamic response, int statusCode) { + isOrderUpdated = true; + reqId = response['response'].toString(); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: order.toJson()); + return reqId; + } + Future insertPresPresOrder({CMCInsertPresOrderRequestModel? order}) async { hasError = false; - await baseAppClient.post(PATIENT_ER_INSERT_PRES_ORDER, - onSuccess: (dynamic response, int statusCode) { - isOrderUpdated = true; - }, onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }, body: order.toJson()); + String reqId = ""; + await baseAppClient.post(PATIENT_ER_INSERT_PRES_ORDER, onSuccess: (dynamic response, int statusCode) { + isOrderUpdated = true; + reqId = response['RequestNo'].toString(); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: order!.toJson()); + return reqId; } } diff --git a/lib/core/service/AlHabibMedicalService/customer_addresses_service.dart b/lib/core/service/AlHabibMedicalService/customer_addresses_service.dart index ea5d03ca..7f8a92a9 100644 --- a/lib/core/service/AlHabibMedicalService/customer_addresses_service.dart +++ b/lib/core/service/AlHabibMedicalService/customer_addresses_service.dart @@ -1,99 +1,79 @@ import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/add_new_address_Request_Model.dart'; -import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:intl/intl.dart'; -import '../../../locator.dart'; import '../base_service.dart'; class CustomerAddressesService extends BaseService { - - List addressesList = List(); - CustomerInfo customerInfo; - - - Future addAddressInfo({ AddNewAddressRequestModel - addNewAddressRequestModel }) async { - - addNewAddressRequestModel.customer.email = customerInfo.email; - addNewAddressRequestModel.customer.id = customerInfo.customerId; - addNewAddressRequestModel.customer.roleIds = [3]; - addNewAddressRequestModel.customer.addresses[0].email = customerInfo.email; - addNewAddressRequestModel.customer.addresses[0].phoneNumber = customerInfo.mobileNumber; - addNewAddressRequestModel.customer.addresses[0].firstName = user.firstName; - addNewAddressRequestModel.customer.addresses[0].lastName = user.lastName; - addNewAddressRequestModel.customer.addresses[0].countryId = 69; + List addressesList = []; + CustomerInfo customerInfo = new CustomerInfo(); + + Future addAddressInfo({AddNewAddressRequestModel? addNewAddressRequestModel}) async { + var customerId = await sharedPref.getString(PHARMACY_CUSTOMER_ID); + addNewAddressRequestModel!.customer!.email = addNewAddressRequestModel.customer!.addresses![0].email; + addNewAddressRequestModel.customer!.id = customerId; + addNewAddressRequestModel.customer!.roleIds = [3]; + addNewAddressRequestModel.customer!.addresses![0].phoneNumber = addNewAddressRequestModel.customer!.addresses![0].phoneNumber; + addNewAddressRequestModel.customer!.addresses![0].firstName = authenticatedUserObject.user!.firstName; + addNewAddressRequestModel.customer!.addresses![0].lastName = authenticatedUserObject.user!.lastName; + addNewAddressRequestModel.customer!.addresses![0].countryId = 69; var f = DateFormat('E, d MMM yyyy HH:mm:ss'); var date = f.format(DateTime.now().toUtc()) + " GMT"; - addNewAddressRequestModel.customer.addresses[0].createdOnUtc = date; + addNewAddressRequestModel.customer!.addresses![0].createdOnUtc = date; hasError = false; - await baseAppClient.post(ADD_CUSTOMER_ADDRESS, - onSuccess: (dynamic response, int statusCode) { - addressesList.clear(); - response["customers"][0]["addresses"].forEach((data) { - addressesList - .add(AddressInfo.fromJson(data)); - }); - }, onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }, body: addNewAddressRequestModel.toJson(), isAllowAny: true); + await baseAppClient.postPharmacy(ADD_ADDRESS_INFO, onSuccess: (dynamic response, int statusCode) { + addressesList.clear(); + response["customers"][0]["addresses"].forEach((data) { + addressesList.add(AddressInfo.fromJson(data)); + }); + }, onFailure: (String error, int statusCode) { + hasError = false; + // super.error = error; + }, body: addNewAddressRequestModel.toJson(), isAllowAny: true); } Future getCustomerAddresses() async { - Map queryParams = { - 'fields':'addresses' - }; + Map queryParams = {'fields': 'addresses'}; hasError = false; - await baseAppClient.getPharmacy("$BASE_PHARMACY_URL$GET_CUSTOMER_ADDRESSES${customerInfo.customerId}", - onSuccess: (dynamic response, int statusCode) { - addressesList.clear(); - response["customers"][0]["addresses"].forEach((data) { - addressesList - .add(AddressInfo.fromJson(data)); - }); - }, onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }, queryParams: queryParams, isExternal: true); + var customerID = await sharedPref.getObject(PHARMACY_CUSTOMER_ID); + var customerGUID = await sharedPref.getObject(PHARMACY_CUSTOMER_GUID); + await baseAppClient.getPharmacy("$BASE_PHARMACY_URL$GET_CUSTOMER_ADDRESSES$customerID/$customerGUID", onSuccess: (dynamic response, int statusCode) { + addressesList.clear(); + response["customers"][0]["addresses"].forEach((data) { + addressesList.add(AddressInfo.fromJson(data)); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, queryParams: queryParams, isExternal: true); } - Future getCustomerInfo() async { - Map queryParams = { - 'FileNumber':'${user.patientID}' - }; + Map queryParams = {'FileNumber': '${authenticatedUserObject.user!.patientID}'}; hasError = false; - await baseAppClient.getPharmacy(BASE_PHARMACY_URL+GET_CUSTOMER_INFO, - onSuccess: (dynamic response, int statusCode) { - customerInfo= CustomerInfo.fromJson(response); - }, onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }, queryParams: queryParams, isExternal: true); + await baseAppClient.getPharmacy(BASE_PHARMACY_URL + GET_CUSTOMER_INFO, onSuccess: (dynamic response, int statusCode) { + customerInfo = CustomerInfo.fromJson(response); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, queryParams: queryParams, isExternal: true); } } - class CustomerInfo { - bool isRegistered; - String userName; + bool? isRegistered; + dynamic userName; dynamic password; - String email; + dynamic email; dynamic errorMessage; - String mobileNumber; - int customerId; + dynamic mobileNumber; + dynamic customerId; - CustomerInfo( - {this.isRegistered, - this.userName, - this.password, - this.email, - this.errorMessage, - this.mobileNumber, - this.customerId}); + CustomerInfo({this.isRegistered, this.userName, this.password, this.email, this.errorMessage, this.mobileNumber, this.customerId}); CustomerInfo.fromJson(Map json) { isRegistered = json['IsRegistered']; @@ -118,46 +98,45 @@ class CustomerInfo { } } - class AddressInfo { - String id; - String firstName; - String lastName; - String email; + String? id; + String? firstName; + String? lastName; + String? email; dynamic company; - int countryId; - String country; + dynamic countryId; + String? country; dynamic stateProvinceId; - String city; - String address1; - String address2; - String zipPostalCode; - String phoneNumber; + String? city; + String? address1; + String? address2; + String? zipPostalCode; + String? phoneNumber; dynamic faxNumber; - String customerAttributes; - String createdOnUtc; + String? customerAttributes; + String? createdOnUtc; dynamic province; - String latLong; + String? latLong; AddressInfo( {this.id, - this.firstName, - this.lastName, - this.email, - this.company, - this.countryId, - this.country, - this.stateProvinceId, - this.city, - this.address1, - this.address2, - this.zipPostalCode, - this.phoneNumber, - this.faxNumber, - this.customerAttributes, - this.createdOnUtc, - this.province, - this.latLong}); + this.firstName, + this.lastName, + this.email, + this.company, + this.countryId, + this.country, + this.stateProvinceId, + this.city, + this.address1, + this.address2, + this.zipPostalCode, + this.phoneNumber, + this.faxNumber, + this.customerAttributes, + this.createdOnUtc, + this.province, + this.latLong}); AddressInfo.fromJson(Map json) { id = json['id']; diff --git a/lib/core/service/AlHabibMedicalService/e_referral_service.dart b/lib/core/service/AlHabibMedicalService/e_referral_service.dart index 6c356f5c..ba488d14 100644 --- a/lib/core/service/AlHabibMedicalService/e_referral_service.dart +++ b/lib/core/service/AlHabibMedicalService/e_referral_service.dart @@ -7,19 +7,26 @@ import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/EReferral/ import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/EReferral/search_e_referral_response_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/EReferral/send_activation_code_for_e_referral_request_model.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; +import 'package:flutter/material.dart'; class EReferralService extends BaseService { - List _relationTypes = List(); + List _relationTypes =[]; + List get relationTypes => _relationTypes; - List _allCities = List(); + List _allCities = []; + List get allCities => _allCities; - List _allReferral = List(); + List _allReferral = []; + List get allReferral => _allReferral; - String _activationCode; - String _logInTokenID; + String? _activationCode; + String? _logInTokenID; + String? _referralNumber; + + String get activationCode => _activationCode!; - String get activationCode => _activationCode; + String get referralNumber => _referralNumber!; bool _isActivationCodeValid = false; @@ -39,22 +46,34 @@ class EReferralService extends BaseService { }, body: {}); } + Future getProjectsList(context) async { + Map request; + request = {}; + + dynamic localRes; + + await baseAppClient.post(GET_PROJECTS_LIST, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } + Future getAllCities() async { await baseAppClient.post(GET_ALL_CITIES, onSuccess: (dynamic response, int statusCode) { - _allCities.clear(); - response['ListCities'].forEach((city) { - _allCities - .add(GetAllCitiesResponseModel.fromJson(city)); - }); - }, onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }, body: {}); + _allCities.clear(); + response['ListCities'].forEach((city) { + _allCities.add(GetAllCitiesResponseModel.fromJson(city)); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: {}); } Future sendActivationCodeForEReferral( - SendActivationCodeForEReferralRequestModel sendActivationCodeForEReferralRequestModel) async { hasError = false; @@ -62,24 +81,21 @@ class EReferralService extends BaseService { onSuccess: (dynamic response, int statusCode) { _activationCode = response["VerificationCode"]; _logInTokenID = response["LogInTokenID"]; - }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; }, body: sendActivationCodeForEReferralRequestModel.toJson()); } - - Future checkActivationCodeForEReferral( CheckActivationCodeForEReferralResponseModel checkActivationCodeForEReferralRequestModel) async { checkActivationCodeForEReferralRequestModel.isDentalAllowedBackend = false; - checkActivationCodeForEReferralRequestModel.logInTokenID= _logInTokenID; - hasError =false; + checkActivationCodeForEReferralRequestModel.logInTokenID = _logInTokenID; + hasError = false; await baseAppClient.post(CHECK_ACTIVATION_CODE_FOR_E_REFERRAL, onSuccess: (dynamic response, int statusCode) { - _isActivationCodeValid = true; + _isActivationCodeValid = true; }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; @@ -87,39 +103,35 @@ class EReferralService extends BaseService { } Future createEReferral( - CreateEReferralRequestModel createEReferralRequestModel - ) async { - hasError = false; - await baseAppClient.post(CREATE_E_REFERRAL/*'Services/Patients.svc/REST/CreateEReferral'*/, + CreateEReferralRequestModel createEReferralRequestModel) async { + hasError = false; + await baseAppClient.post( + CREATE_E_REFERRAL /*'Services/Patients.svc/REST/CreateEReferral'*/, onSuccess: (dynamic response, int statusCode) { - // TODO Waiting for fix service - var asd= ("EEEEEE"); - - }, onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }, body: createEReferralRequestModel.toJson()); + // TODO Waiting for fix service + _referralNumber = response['ReferralNumber'].toString(); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: createEReferralRequestModel.toJson()); } Future getEReferrals( - SearchEReferralRequestModel searchEReferralRequestModel - ) async { + SearchEReferralRequestModel searchEReferralRequestModel) async { + _allReferral.clear(); hasError = false; + // TODO return this code when the fix the server - // await baseAppClient.post(GET_E_REFERRALS, - // onSuccess: (dynamic response, int statusCode) { - // print("EEEEEE"); - // // TODO Waiting for fix service - // // ToDo change this one when you have data - // _allReferral.clear(); - // // response['ListCities'].forEach((city) { - // // _allReferral - // // .add(SearchEReferralResponseModel.fromJson(city)); - // // }); - // - // }, onFailure: (String error, int statusCode) { - // hasError = true; - // super.error = error; - // }, body: searchEReferralRequestModel.toJson()); + await baseAppClient.post(GET_E_REFERRALS, + onSuccess: (dynamic response, int statusCode) { + _allReferral.clear(); + response['List_EReferrals'].forEach((referral) { + _allReferral + .add(SearchEReferralResponseModel.fromJson(referral)); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: searchEReferralRequestModel.toJson()); } } diff --git a/lib/core/service/AlHabibMedicalService/health-calculator/bariatrics-service.dart b/lib/core/service/AlHabibMedicalService/health-calculator/bariatrics-service.dart index b59eadac..336a632d 100644 --- a/lib/core/service/AlHabibMedicalService/health-calculator/bariatrics-service.dart +++ b/lib/core/service/AlHabibMedicalService/health-calculator/bariatrics-service.dart @@ -2,24 +2,32 @@ import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HealthCalculator/ClinicCategory.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HealthCalculator/DiseasesByClinic.dart'; +import 'package:diplomaticquarterapp/core/model/health_calcolator/get_doctor_by_time_model.dart'; +import 'package:diplomaticquarterapp/core/model/health_calcolator/get_doctor_list_calcolation_model.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; +import 'package:flutter/cupertino.dart'; + +import '../../../../uitl/app_toast.dart'; class BariatricsService extends BaseService { List clinicCategoryList = []; List diseasesList = []; + List doctorList = []; + List doctorListByTime = []; + + double? lat; + double? long; Future getClinicCategory() async { hasError = false; Map body = Map(); - var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); body['ClinicID'] = 108; // hint: it is static depend on IONIC project body['isDentalAllowedBackend'] = false; body['LanguageID'] = languageID == 'ar' ? 1 : 2; - await baseAppClient.post(GET_CLINIC_CATEGORY, - onSuccess: (dynamic response, int statusCode) { + await baseAppClient.post(GET_CLINIC_CATEGORY, onSuccess: (dynamic response, int statusCode) { clinicCategoryList.clear(); if (response['ClinicCategoryList'] != null) response['ClinicCategoryList'].forEach((city) { @@ -36,8 +44,7 @@ class BariatricsService extends BaseService { Map body = Map(); body['ClinicID'] = 108; // hint: it is static depend on IONIC project - await baseAppClient.post(GET_DISEASE_BY_CLINIC_ID, - onSuccess: (dynamic response, int statusCode) { + await baseAppClient.post(GET_DISEASE_BY_CLINIC_ID, onSuccess: (dynamic response, int statusCode) { diseasesList.clear(); if (response['DiseasesByClinicList'] != null) response['DiseasesByClinicList'].forEach((city) { @@ -51,8 +58,7 @@ class BariatricsService extends BaseService { Future searchDoctorsByTime(DiseasesByClinic disease) async { hasError = false; - var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Map body = Map(); body['ClinicID'] = 108; // hint: it is static depend on IONIC project @@ -66,11 +72,67 @@ class BariatricsService extends BaseService { body['Longitude'] = 0; body['isDentalAllowedBackend'] = false; - await baseAppClient.post(SEARCH_DOCTOR_BY_TIME, - onSuccess: (dynamic response, int statusCode) { + await baseAppClient.post(SEARCH_DOCTOR_BY_TIME, onSuccess: (dynamic response, int statusCode) {}, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } + + Future getDoctorList({required DiseasesByClinic disease}) async { + hasError = false; + var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + + Map body = Map(); + body['ClinicID'] = 108; // hint: it is static depend on IONIC project + body['ContinueDentalPlan'] = false; + body['IsGetNearAppointment'] = false; + body['IsSearchAppointmnetByClinicID'] = true; + body['LanguageID'] = languageID == 'ar' ? 1 : 2; + body['Latitude'] = 0; + body['License'] = true; + body['Longitude'] = 0; + body['PatientID'] = 0; + body['isDentalAllowedBackend'] = false; + + if (disease != null) body['DiseaseID'] = disease.diseasesID; + + await baseAppClient.post(GET_DOCTOR_LIST_BY_TIME, onSuccess: (dynamic response, int statusCode) { + doctorListByTime.clear(); + if (response['DoctorList'] != null) + response['DoctorList'].forEach((city) { + doctorListByTime.add(DoctorListByTimeModel.fromJson(city)); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } + + 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; + + await baseAppClient.post(GET_DOCTOR_LIST_CALCULATION, onSuccess: (dynamic response, int statusCode) { + localRes = response; }, onFailure: (String error, int statusCode) { + AppToast.showErrorToast(message: error); hasError = true; super.error = error; }, body: body); + return Future.value(localRes); } } diff --git a/lib/core/service/AlHabibMedicalService/home_health_care_service.dart b/lib/core/service/AlHabibMedicalService/home_health_care_service.dart index 2ec1e310..41418060 100644 --- a/lib/core/service/AlHabibMedicalService/home_health_care_service.dart +++ b/lib/core/service/AlHabibMedicalService/home_health_care_service.dart @@ -1,32 +1,32 @@ import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/core/enum/OrderService.dart'; +import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/GetCMCAllOrdersResponseModel.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/HHC_get_all_services_request_modle.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/HHC_get_all_services_response_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/get_hHC_all_pres_orders_request_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/get_hhc_all_pres_orders_response_model.dart'; -import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/get_order_detail_by_order_iD_request_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/get_order_detail_by_order_iD_response_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/patient_er_insert_pres_order_request_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/update_pres_oreder_request_model.dart'; import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/customer_addresses_service.dart'; -import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/add_new_address_Request_Model.dart'; +import 'package:diplomaticquarterapp/main.dart'; import '../base_service.dart'; class HomeHealthCareService extends BaseService { - List hhcAllServicesList = List(); - List hhcAllPresOrdersList = List(); + List hhcAllServicesList = []; + List hhcAllPresOrdersList = []; - List hhcAllOrderDetail = List(); - List addressesList = List(); + List hhcAllOrderDetail = []; + List addressesList = []; + dynamic hhcResponse; + bool? isOrderUpdated; + CustomerInfo? customerInfo; + int? requestNo; - bool isOrderUpdated; - CustomerInfo customerInfo; - Future getHHCAllServices( - HHCGetAllServicesRequestModel hHCGetAllServicesRequestModel) async { + Future getHHCAllServices(HHCGetAllServicesRequestModel hHCGetAllServicesRequestModel) async { hasError = false; - await baseAppClient.post(HHC_GET_ALL_SERVICES, - onSuccess: (dynamic response, int statusCode) { + await baseAppClient.post(HHC_GET_ALL_SERVICES, onSuccess: (dynamic response, int statusCode) { hhcAllServicesList.clear(); response['PatientER_HHC_GetAllServicesList'].forEach((data) { hhcAllServicesList.add(HHCGetAllServicesResponseModel.fromJson(data)); @@ -37,17 +37,27 @@ class HomeHealthCareService extends BaseService { }, body: hHCGetAllServicesRequestModel.toJson()); } - Future getHHCAllPresOrders() async { - GetHHCAllPresOrdersRequestModel getHHCAllPresOrdersRequestModel = - GetHHCAllPresOrdersRequestModel(); + Future getHHCAllServicesRC(HHCGetAllServicesRequestModel hHCGetAllServicesRequestModel) async { + hasError = false; + await baseAppClient.post(HHC_GET_ALL_SERVICES_RC + "?PatientID=" + user.patientID.toString(), isRCService: true, onSuccess: (dynamic response, int statusCode) { + hhcAllServicesList.clear(); + response['response'].forEach((data) { + hhcAllServicesList.add(HHCGetAllServicesResponseModel.fromJson(data)); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: hHCGetAllServicesRequestModel.toJson()); + } + + Future getHHCAllPresOrdersRC() async { + GetHHCAllPresOrdersRequestModel getHHCAllPresOrdersRequestModel = GetHHCAllPresOrdersRequestModel(); hasError = false; - await baseAppClient.post(GET_PATIENT_ALL_PRES_ORD, - onSuccess: (dynamic response, int statusCode) { + await baseAppClient.post(GET_ALL_HHC_ORDERS_RC, isRCService: true, onSuccess: (dynamic response, int statusCode) { hhcAllPresOrdersList.clear(); - response['PatientER_GetPatientAllPresOrdersList'].forEach((data) { - if (data['ServiceID'] == OrderService.HOME_HEALTH_CARE.getIdOrderService()) - hhcAllPresOrdersList - .add(GetHHCAllPresOrdersResponseModel.fromJson(data)); + hhcAllOrderDetail.clear(); + response['response'].forEach((data) { + hhcAllPresOrdersList.add(GetCMCAllOrdersResponseModel.fromJson(data)); }); }, onFailure: (String error, int statusCode) { hasError = true; @@ -55,17 +65,29 @@ class HomeHealthCareService extends BaseService { }, body: getHHCAllPresOrdersRequestModel.toJson()); } + Future getHHCAllPresOrders() async { + GetHHCAllPresOrdersRequestModel getHHCAllPresOrdersRequestModel = GetHHCAllPresOrdersRequestModel(); + hasError = false; + await baseAppClient.post(GET_PATIENT_ALL_PRES_ORD, onSuccess: (dynamic response, int statusCode) { + hhcAllPresOrdersList.clear(); + // response['PatientER_GetPatientAllPresOrdersList'].forEach((data) { + // if (data['ServiceID'] == OrderService.HOME_HEALTH_CARE.getIdOrderService()) hhcAllPresOrdersList.add(GetHHCAllPresOrdersResponseModel.fromJson(data)); + // }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: getHHCAllPresOrdersRequestModel.toJson()); + } + Future getOrderDetailByOrderID(int presOrderID) async { hasError = false; Map body = Map(); body['PresOrderID'] = presOrderID; body['isDentalAllowedBackend'] = false; - await baseAppClient.post(GET_ORDER_DETAIL_BY_ID, - onSuccess: (dynamic response, int statusCode) { + await baseAppClient.post(GET_ORDER_DETAIL_BY_ID, onSuccess: (dynamic response, int statusCode) { hhcAllOrderDetail.clear(); response['PatientER_HHC_GetTransactionsForOrderList'].forEach((data) { - hhcAllOrderDetail - .add(GetOrderDetailByOrderIDResponseModel.fromJson(data)); + hhcAllOrderDetail.add(GetOrderDetailByOrderIDResponseModel.fromJson(data)); }); }, onFailure: (String error, int statusCode) { hasError = true; @@ -75,8 +97,7 @@ class HomeHealthCareService extends BaseService { Future updateHHCPresOrder(UpdatePresOrderRequestModel updatePresOrderRequestModel) async { hasError = false; - await baseAppClient.post(PATIENT_ER_UPDATE_PRES_ORDER, - onSuccess: (dynamic response, int statusCode) { + await baseAppClient.post(PATIENT_ER_UPDATE_PRES_ORDER, onSuccess: (dynamic response, int statusCode) { isOrderUpdated = true; }, onFailure: (String error, int statusCode) { hasError = true; @@ -84,16 +105,35 @@ class HomeHealthCareService extends BaseService { }, body: updatePresOrderRequestModel.toJson()); } - Future insertPresPresOrder({PatientERInsertPresOrderRequestModel order}) async { + Future updateHHCPresOrderRC(UpdatePresOrderRequestModel updatePresOrderRequestModel) async { hasError = false; - await baseAppClient.post(INSERT_ER_INERT_PRES_ORDER, - onSuccess: (dynamic response, int statusCode) { - + await baseAppClient.post(UPDATE_HHC_ORDER_RC, isRCService: true, onSuccess: (dynamic response, int statusCode) { + isOrderUpdated = true; }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; - }, body: order.toJson()); + }, body: updatePresOrderRequestModel.toJson()); } -} + Future insertPresPresOrder({PatientERInsertPresOrderRequestModel? order}) async { + hasError = false; + await baseAppClient.post(INSERT_ER_INERT_PRES_ORDER, onSuccess: (dynamic response, int statusCode) { + hhcResponse = response; + requestNo = response['RequestNo']; + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: order!.toJson()); + } + Future insertHHCOrderRC({PatientERInsertPresOrderRequestModel? order}) async { + hasError = false; + await baseAppClient.post(ADD_HHC_ORDER_RC, isRCService: true, onSuccess: (dynamic response, int statusCode) { + hhcResponse = response; + requestNo = response["response"]; + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: order!.toJson()); + } +} diff --git a/lib/core/service/AuthenticatedUserObject.dart b/lib/core/service/AuthenticatedUserObject.dart index 8dd2583d..5f73c5e8 100644 --- a/lib/core/service/AuthenticatedUserObject.dart +++ b/lib/core/service/AuthenticatedUserObject.dart @@ -3,7 +3,7 @@ import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.da import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; class AuthenticatedUserObject { - AuthenticatedUser user; + AuthenticatedUser user = AuthenticatedUser(); AppSharedPreferences sharedPref = AppSharedPreferences(); bool isLogin = false; @@ -11,17 +11,24 @@ class AuthenticatedUserObject { getUser(); } - getUser({bool getUser = false}) async { + Future getUser({bool getUser = false}) async { if (getUser) { var userData = await sharedPref.getObject(USER_PROFILE); - if (userData != null) user = AuthenticatedUser.fromJson(userData); + if (userData != null) { + user = AuthenticatedUser.fromJson(userData); + } } else if (user == null) { var userData = await sharedPref.getObject(USER_PROFILE); - if (userData != null) user = AuthenticatedUser.fromJson(userData); + if (userData != null) { + // user = AuthenticatedUser.fromJson(userData); + user = AuthenticatedUser( + patientID: 1, + ); + } } } - logout() async { + void logout() { isLogin = false; } } diff --git a/lib/core/service/PrescriptionDeliveryService.dart b/lib/core/service/PrescriptionDeliveryService.dart index c36efe89..15825de4 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, int? projectID}) async { + hasError = false; + Map body = Map(); + body['latitude'] = latitude; + body['longitude'] = longitude; + body['AppointmentNo'] = appointmentNo.toString(); + // body['CreatedBy'] = createdBy; + body['DischargeID'] = dischargeID.toString(); + body['ProjectID'] = projectID; + await baseAppClient.post(ADD_PRESCRIPTION_ORDER_RC, isRCService: true, onSuccess: (dynamic response, int statusCode) { + }, onFailure: (String error, int statusCode) { hasError = true; print(error); super.error = error; diff --git a/lib/core/service/ancillary_orders_service.dart b/lib/core/service/ancillary_orders_service.dart index b9d14a06..99babdfd 100644 --- a/lib/core/service/ancillary_orders_service.dart +++ b/lib/core/service/ancillary_orders_service.dart @@ -4,19 +4,26 @@ import 'package:diplomaticquarterapp/models/anicllary-orders/ancillary_order_lis import 'package:diplomaticquarterapp/models/anicllary-orders/ancillary_order_proc_model.dart'; class AncillaryOrdersService extends BaseService { - List _ancillaryLists = List(); + List _ancillaryLists =[]; + List get ancillaryLists => _ancillaryLists; - List _ancillaryProcLists = List(); - List get ancillaryProcLists => - _ancillaryProcLists; + List _ancillaryProcLists =[]; + + List get ancillaryProcLists => _ancillaryProcLists; + + String _insuranceCompanyName = ""; + + String get insuranceCompanyName => _insuranceCompanyName; + String _insurancePolicyNumber = ""; + + String get insurancePolicyNumber => _insurancePolicyNumber; Future getOrders() async { Map body = Map(); hasError = false; - await baseAppClient.post(GET_ANCILLARY_ORDERS, - onSuccess: (dynamic response, int statusCode) { + await baseAppClient.post(GET_ANCILLARY_ORDERS, onSuccess: (dynamic response, int statusCode) { _ancillaryLists = []; response['AncillaryOrderList'].forEach((item) { ancillaryLists.add(AncillaryOrdersListModel.fromJson(item)); @@ -27,172 +34,38 @@ class AncillaryOrdersService extends BaseService { }, body: body); } - Future getOrdersDetails(appointmentNo, orderNo) async { + Future getOrdersMyAppo() async { Map body = Map(); hasError = false; - await baseAppClient.post(GET_ANCILLARY_ORDERS_DETAILS, - onSuccess: (dynamic response, int statusCode) { - _ancillaryProcLists = []; - response['AncillaryOrderProcList'] = [ - { - "AncillaryOrderProcList": [ - { - "ApprovalLineItemNo": 0, - "ApprovalNo": 0, - "ApprovalStatus": "", - "ApprovalStatusID": 0, - "CompanyShare": 501.3, - "CompanyShareWithTax": 576.5, - "CompanyTaxAmount": 75.19, - "DiscountAmount": 55.7, - "DiscountCategory": 1, - "DiscountType": "P", - "DiscountTypeValue": 10, - "IsApprovalCreated": false, - "IsApprovalRequired": false, - "IsCovered": false, - "OrderDate": "/Date(1601758800000+0300)/", - "OrderLineItemNo": 1, - "OrderNo": 2020000001, - "PartnerID": 0, - "PartnerShare": 0, - "PartnerShareType": "P", - "PatientShare": 0, - "PatientShareWithTax": 0, - "PatientTaxAmount": 0, - "ProcPrice": 557, - "ProcedureCategoryID": 2, - "ProcedureCategoryName": "LABORATORY", - "ProcedureID": "02013001", - "ProcedureName": "11-DESOXYCORTISOL (COMPOUND S) - S.O", - "TaxAmount": 75.19, - "TaxPct": 15 - }, - { - "ApprovalLineItemNo": 0, - "ApprovalNo": 0, - "ApprovalStatus": "", - "ApprovalStatusID": 0, - "CompanyShare": 90, - "CompanyShareWithTax": 103.5, - "CompanyTaxAmount": 13.5, - "DiscountAmount": 10, - "DiscountCategory": 1, - "DiscountType": "P", - "DiscountTypeValue": 10, - "IsApprovalCreated": false, - "IsApprovalRequired": true, - "IsCovered": false, - "OrderDate": "/Date(1601758800000+0300)/", - "OrderLineItemNo": 4, - "OrderNo": 2020000001, - "PartnerID": 0, - "PartnerShare": 0, - "PartnerShareType": "P", - "PatientShare": 0, - "PatientShareWithTax": 0, - "PatientTaxAmount": 0, - "ProcPrice": 100, - "ProcedureCategoryID": 2, - "ProcedureCategoryName": "LABORATORY", - "ProcedureID": "02014011", - "ProcedureName": "CBC (COMPLETE BLOOD COUNT PROFILE)", - "TaxAmount": 13.5, - "TaxPct": 15 - }, - { - "ApprovalLineItemNo": 0, - "ApprovalNo": 0, - "ApprovalStatus": "", - "ApprovalStatusID": 0, - "CompanyShare": 347.76, - "CompanyShareWithTax": 399.92, - "CompanyTaxAmount": 52.16, - "DiscountAmount": 38.64, - "DiscountCategory": 1, - "DiscountType": "P", - "DiscountTypeValue": 10, - "IsApprovalCreated": false, - "IsApprovalRequired": false, - "IsCovered": false, - "OrderDate": "/Date(1601758800000+0300)/", - "OrderLineItemNo": 3, - "OrderNo": 2020000001, - "PartnerID": 0, - "PartnerShare": 0, - "PartnerShareType": "P", - "PatientShare": 0, - "PatientShareWithTax": 0, - "PatientTaxAmount": 0, - "ProcPrice": 386.4, - "ProcedureCategoryID": 2, - "ProcedureCategoryName": "LABORATORY", - "ProcedureID": "02019302", - "ProcedureName": "21-HYDROXYLASE ABS - S.O", - "TaxAmount": 52.16, - "TaxPct": 15 - }, - { - "ApprovalLineItemNo": 0, - "ApprovalNo": 0, - "ApprovalStatus": "", - "ApprovalStatusID": 0, - "CompanyShare": 1323, - "CompanyShareWithTax": 1521.45, - "CompanyTaxAmount": 198.45, - "DiscountAmount": 147, - "DiscountCategory": 1, - "DiscountType": "P", - "DiscountTypeValue": 10, - "IsApprovalCreated": false, - "IsApprovalRequired": true, - "IsCovered": false, - "OrderDate": "/Date(1601758800000+0300)/", - "OrderLineItemNo": 5, - "OrderNo": 2020000001, - "PartnerID": 0, - "PartnerShare": 0, - "PartnerShareType": "P", - "PatientShare": 0, - "PatientShareWithTax": 0, - "PatientTaxAmount": 0, - "ProcPrice": 1470, - "ProcedureCategoryID": 3, - "ProcedureCategoryName": "RADIOLOGY", - "ProcedureID": "03033065", - "ProcedureName": "CT SCAN - ABDOMEN (WITH CONTRAST)", - "TaxAmount": 198.45, - "TaxPct": 15 - } - ], - "AppointmentDate": "/Date(1601499600000+0300)/", - "AppointmentNo": 2016053756, - "ClinicID": 1, - "ClinicName": "INTERNAL MEDICINE CLINIC", - "CompanyID": 0, - "CompanyName": "Blood Donation Investigation", - "DoctorID": 1485, - "DoctorName": "ANAS ABDULLAH", - "ErrCode": null, - "GroupID": 2, - "InsurancePolicyNo": "45976500", - "Message": "Success", - "PatientCardID": "232332323", - "PatientID": 3072055, - "PatientName": "MAYA KHALED SADDIQ", - "PatientType": 1, - "PolicyID": 2, - "PolicyName": "Test", - "ProjectID": 15, - "SetupID": "010266", - "StatusCode": 1, - "SubCategoryID": 2, - "SubPolicyNo": "234234" - } - ]; + dynamic localRes; + await baseAppClient.post(GET_ANCILLARY_ORDERS, onSuccess: (dynamic response, int statusCode) { + _ancillaryLists = []; + localRes = response; + response['AncillaryOrderList'].forEach((item) { + ancillaryLists.add(AncillaryOrdersListModel.fromJson(item)); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + return Future.value(localRes); + } + + Future getOrdersDetails(appointmentNo, orderNo, projectID) async { + Map body = Map(); + body['AppointmentNo_Vida'] = appointmentNo; + body['OrderNo'] = orderNo; + body['ProjectID'] = projectID; + hasError = false; + + dynamic localRes; + + await baseAppClient.post(GET_ANCILLARY_ORDERS_DETAILS, onSuccess: (dynamic response, int statusCode) { + localRes = response; + _ancillaryProcLists = []; response['AncillaryOrderProcList'].forEach((item) { ancillaryProcLists.add(AncillaryOrdersListProcListModel.fromJson(item)); }); @@ -200,5 +73,6 @@ class AncillaryOrdersService extends BaseService { hasError = true; super.error = error; }, body: body); + return Future.value(localRes); } } diff --git a/lib/core/service/appointment_rate_service.dart b/lib/core/service/appointment_rate_service.dart index a0c2b208..0f14a038 100644 --- a/lib/core/service/appointment_rate_service.dart +++ b/lib/core/service/appointment_rate_service.dart @@ -1,17 +1,18 @@ import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/core/model/rate/appointment_details.dart'; import 'package:diplomaticquarterapp/core/model/rate/appointment_rate.dart'; import 'package:diplomaticquarterapp/core/model/rate/appoitment_rated.dart'; -import 'package:diplomaticquarterapp/core/model/rate/appointment_details.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; class AppointmentRateService extends BaseService { - List appointmentRatedList = List(); - AppointmentDetails appointmentDetails; + List appointmentRatedList =[]; + AppointmentDetails? appointmentDetails; - Future getIsLastAppointmentRatedList() async { + Future getIsLastAppointmentRatedList(int languageID) async { hasError = false; - await baseAppClient.post(IS_LAST_APPOITMENT_RATED, - onSuccess: (dynamic response, int statusCode) { + Map bodyData = Map(); + bodyData['LanguageID'] = languageID; + await baseAppClient.post(IS_LAST_APPOITMENT_RATED, onSuccess: (dynamic response, int statusCode) { appointmentRatedList.clear(); response['IsLastAppoitmentRatedList'].forEach((appoint) { appointmentRatedList.add(AppoitmentRated.fromJson(appoint)); @@ -19,7 +20,7 @@ class AppointmentRateService extends BaseService { }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; - }, body: Map()); + }, body: bodyData); } Future getAppointmentDetails() async { @@ -27,19 +28,15 @@ class AppointmentRateService extends BaseService { Map bodyData = Map(); bodyData['AppointmentNumber'] = appointmentRatedList[0].appointmentNo; bodyData['ProjectID'] = appointmentRatedList[0].projectID; - await baseAppClient.post(GET_APPOINTMENT_DETAILS_BY_NO, - onSuccess: (dynamic response, int statusCode) { - if (response['AppointmentDetails'] != null) - appointmentDetails = - AppointmentDetails.fromJson(response['AppointmentDetails']); + await baseAppClient.post(GET_APPOINTMENT_DETAILS_BY_NO, onSuccess: (dynamic response, int statusCode) { + if (response['AppointmentDetails'] != null) appointmentDetails = AppointmentDetails.fromJson(response['AppointmentDetails']); }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; }, body: bodyData); } - Future sendAppointmentRate(int rate, int appointmentNo, int projectID, - int doctorID, int clinicID, String note) async { + Future sendAppointmentRate(int rate, int appointmentNo, int projectID, int doctorID, int clinicID, String note, int languageID) async { hasError = false; AppointmentRate appointmentRate = AppointmentRate(); appointmentRate.rate = rate; @@ -48,19 +45,47 @@ class AppointmentRateService extends BaseService { appointmentRate.doctorID = doctorID; appointmentRate.clinicID = clinicID; appointmentRate.note = note; + appointmentRate.createdBy = 2; + appointmentRate.editedBy = 2; + appointmentRate.languageID = languageID; - await baseAppClient.post(GET_APPOINTMENT_DETAILS_BY_NO, - onSuccess: (dynamic response, int statusCode) {}, - onFailure: (String error, int statusCode) { + await baseAppClient.post(NEW_RATE_APPOINTMENT_URL, onSuccess: (dynamic response, int statusCode) {}, onFailure: (String error, int statusCode) { hasError = true; super.error = error; }, body: appointmentRate.toJson()); } + Future sendDoctorRate(int rate, int appointmentNo, int projectID, int doctorID, int clinicID, String note, String appoDate, String docName, String projectName, String clinicName) async { + Map request; + hasError = false; + request = { + "DoctorID": doctorID, + "Rate": rate, + "ClinicID": clinicID, + "ProjectID": projectID, + "AppointmentNo": appointmentNo, + "Note": note, + "MobileNumber": authenticatedUserObject.user!.mobileNumber, + "AppointmentDate": appoDate, + "DoctorName": docName, + "ProjectName": projectName, + "COCTypeName": 1, + "PatientName": authenticatedUserObject.user!.firstName! + " " + authenticatedUserObject.user!.lastName!, + "PatientOutSA": authenticatedUserObject.user!.outSA, + "PatientTypeID": authenticatedUserObject.user!.patientType, + "ClinicName": clinicName, + "PatientIdentificationID": authenticatedUserObject.user!.patientIdentificationNo + }; + + await baseAppClient.post(NEW_RATE_DOCTOR_URL, onSuccess: (dynamic response, int statusCode) {}, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: request); + } + AppoitmentRated get lastAppointmentRated { - if (appointmentRatedList.length > 0) - return appointmentRatedList[appointmentRatedList.length - 1]; - return null; + if (appointmentRatedList.length > 0) return appointmentRatedList[appointmentRatedList.length - 1]; + return AppoitmentRated(); } deleteAppointmentRated(AppoitmentRated appointmentRated) { diff --git a/lib/core/service/base_service.dart b/lib/core/service/base_service.dart index fdb80604..2b8ec3d3 100644 --- a/lib/core/service/base_service.dart +++ b/lib/core/service/base_service.dart @@ -7,10 +7,10 @@ import 'AuthenticatedUserObject.dart'; import 'client/base_app_client.dart'; class BaseService { - String error; + String? error; bool hasError = false; BaseAppClient baseAppClient = BaseAppClient(); - AuthenticatedUser user; + AuthenticatedUser user = new AuthenticatedUser(); AuthenticatedUserObject authenticatedUserObject = locator(); @@ -23,9 +23,9 @@ class BaseService { } getUser() async { - if (user==null) { + // if (user==null) { var userData = await sharedPref.getObject(USER_PROFILE); if (userData != null) user = AuthenticatedUser.fromJson(userData); - } + // } } } diff --git a/lib/core/service/blood/blood_details_servies.dart b/lib/core/service/blood/blood_details_servies.dart index 644d96d9..eb490086 100644 --- a/lib/core/service/blood/blood_details_servies.dart +++ b/lib/core/service/blood/blood_details_servies.dart @@ -6,10 +6,10 @@ import '../base_service.dart'; class BloodDetailsService extends BaseService{ - // List CitiesModelList = List(); + // List CitiesModelList =[]; // Map body = Map(); - List BloodModelList = List(); + List BloodModelList =[]; Map body = Map(); Future getAllBloodOrders() async { hasError = false; @@ -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/service/blood/blood_donation_service.dart b/lib/core/service/blood/blood_donation_service.dart index 9fc11c04..39c776b6 100644 --- a/lib/core/service/blood/blood_donation_service.dart +++ b/lib/core/service/blood/blood_donation_service.dart @@ -1,23 +1,22 @@ import 'package:diplomaticquarterapp/config/config.dart'; -import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/blooddonation/get_all_cities.dart'; import '../base_service.dart'; class BloodDonationService extends BaseService { - //List LivechatModelList = List(); + //List LivechatModelList =[]; // Map body = Map(); - List CitiesModelList = List(); + List CitiesModelList =[]; Map body = Map(); + Future getAllCitiesOrders() async { hasError = false; body['ListCities'] = false; - await baseAppClient.post(GET_CITIES_REQUEST, - onSuccess: (dynamic response, int statusCode) { + body["IsPublicRequest"] = true; + await baseAppClient.post(GET_CITIES_REQUEST, onSuccess: (dynamic response, int statusCode) { CitiesModelList.clear(); - response['ListCities'].forEach((vital) { CitiesModelList.add(CitiesModel.fromJson(vital)); }); @@ -26,16 +25,16 @@ class BloodDonationService extends BaseService { super.error = error; }, body: body); } + Future bloodDonationSave(request) async { var localRes; try { - await baseAppClient.post(SAVE_BLOOD_REQUEST, - onSuccess: (dynamic response, int statusCode) { - localRes = response; - }, onFailure: (String error, int statusCode) { - localRes = error; - return Future.value(error); - }, body: request); + await baseAppClient.post(SAVE_BLOOD_REQUEST, onSuccess: (dynamic response, int statusCode) { + localRes = response; + }, onFailure: (String error, int statusCode) { + localRes = error; + return Future.value(error); + }, body: request); return Future.value(localRes); } catch (error) { throw error; @@ -45,33 +44,57 @@ class BloodDonationService extends BaseService { Future getAgreement() async { var localRes; try { - await baseAppClient.post(GET_BLOOD_AGREEMENT, - onSuccess: (dynamic response, int statusCode) { - localRes = response; - }, onFailure: (String error, int statusCode) { - localRes = error; - return Future.value(error); - }, body: {}); + await baseAppClient.post(GET_BLOOD_AGREEMENT, onSuccess: (dynamic response, int statusCode) { + localRes = response; + }, onFailure: (String error, int statusCode) { + localRes = error; + return Future.value(error); + }, body: {}); return Future.value(localRes); } catch (error) { throw error; } } - Future saveAgreement(request) async { var localRes; try { - await baseAppClient.post(SAVE_BLOOD_AGREEMENT, - onSuccess: (dynamic response, int statusCode) { - localRes = response; - }, onFailure: (String error, int statusCode) { - localRes = error; - return Future.value(error); - }, body: request); + await baseAppClient.post(SAVE_BLOOD_AGREEMENT, onSuccess: (dynamic response, int statusCode) { + localRes = response; + }, onFailure: (String error, int statusCode) { + localRes = error; + return Future.value(error); + }, body: request); return Future.value(localRes); } catch (error) { throw error; } } + + Future getBloodDonationProjectsList() async { + Map request; + request = {}; + dynamic localRes; + await baseAppClient.post(GET_BLOOD_DONATION_PROJECTS_LIST, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + + return Future.value(localRes); + } + + Future getBloodDonationFreeSlots(int clinicID, int projectID) async { + Map request; + request = {"ClinicID": clinicID, "ProjectID": projectID}; + dynamic localRes; + await baseAppClient.post(GET_BLOOD_DONATION_FREE_SLOTS, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + + return Future.value(localRes); + } + } diff --git a/lib/core/service/childvaccines/add_new_child_service.dart b/lib/core/service/childvaccines/add_new_child_service.dart index 5e4a4d86..98cf9638 100644 --- a/lib/core/service/childvaccines/add_new_child_service.dart +++ b/lib/core/service/childvaccines/add_new_child_service.dart @@ -1,21 +1,22 @@ import 'package:diplomaticquarterapp/config/config.dart'; -import 'package:diplomaticquarterapp/core/model/childvaccines/add_newchild_model.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/model/childvaccines/add_newchild_model.dart'; import 'package:diplomaticquarterapp/core/model/childvaccines/create_new_user_model.dart'; import 'package:diplomaticquarterapp/core/model/childvaccines/user_information_model.dart'; + import '../base_service.dart'; class CreteNewBabyService extends BaseService { - List createNewBabyModelList = List(); - List userModelList = List(); - List newUserModelList = List(); + List createNewBabyModelList =[]; + List userModelList =[]; + List newUserModelList =[]; - Future getCreateNewBabyOrders({CreateNewBaby newChild,int userID}) async { + Future getCreateNewBabyOrders({CreateNewBaby? newChild,int? userID}) async { hasError = false; await getUser(); - Map body = Map.from(newChild.toJson()); + Map body = Map.from(newChild!.toJson()); body['CreatedBy'] = 102; body['EditedBy'] = 102; body['UserID'] = userID; diff --git a/lib/core/service/childvaccines/child_vaccines_service.dart b/lib/core/service/childvaccines/child_vaccines_service.dart index 09256f47..df3934df 100644 --- a/lib/core/service/childvaccines/child_vaccines_service.dart +++ b/lib/core/service/childvaccines/child_vaccines_service.dart @@ -1,14 +1,14 @@ -import 'dart:convert'; +import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/childvaccines/List_BabyInformationModel.dart'; -import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/core/model/childvaccines/user_information_model.dart'; + import '../base_service.dart'; class ChildVaccinesService extends BaseService { - List babyInformationModelList = List(); - List userInformationModelList = List(); + List babyInformationModelList =[]; + List userInformationModelList =[]; int userID = 0; Future getAllBabyInformationOrders() async { diff --git a/lib/core/service/childvaccines/delete_baby_service.dart b/lib/core/service/childvaccines/delete_baby_service.dart index 115d13c5..494c92fc 100644 --- a/lib/core/service/childvaccines/delete_baby_service.dart +++ b/lib/core/service/childvaccines/delete_baby_service.dart @@ -1,26 +1,27 @@ import 'package:diplomaticquarterapp/config/config.dart'; -import 'package:diplomaticquarterapp/core/model/childvaccines/add_newchild_model.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/model/childvaccines/add_newchild_model.dart'; import 'package:diplomaticquarterapp/core/model/childvaccines/create_new_user_model.dart'; import 'package:diplomaticquarterapp/core/model/childvaccines/delete_baby_model.dart'; import 'package:diplomaticquarterapp/core/model/childvaccines/user_information_model.dart'; + import '../base_service.dart'; class DeleteBabyService extends BaseService{ - List createNewBabyModelList = List(); - List userModelList = List(); - List newUserModelList = List(); + List createNewBabyModelList =[]; + List userModelList =[]; + List newUserModelList =[]; - List deleteBabyModelList= List(); + List deleteBabyModelList=[]; - Future getDeleteBabyOrder({DeleteBaby deleteChild,int babyID}) async { + Future getDeleteBabyOrder({DeleteBaby? deleteChild,int? babyID}) async { hasError = false; await getUser(); - Map body = Map.from(deleteChild.toJson()); + Map body = Map.from(deleteChild!.toJson()); // body['CreatedBy'] = 102; body['EditedBy'] = 102; //body['BabyID'] = babyID; diff --git a/lib/core/service/childvaccines/get_vaccinations_item_services.dart b/lib/core/service/childvaccines/get_vaccinations_item_services.dart index 5ff936af..0cf19e9d 100644 --- a/lib/core/service/childvaccines/get_vaccinations_item_services.dart +++ b/lib/core/service/childvaccines/get_vaccinations_item_services.dart @@ -4,7 +4,7 @@ import 'package:diplomaticquarterapp/core/model/childvaccines/get_vacainations_i import '../base_service.dart'; class GetVccinationsItemsService extends BaseService { - List getVaccinationsItemModelList = List(); + List getVaccinationsItemModelList =[]; Map body = Map(); diff --git a/lib/core/service/childvaccines/user_information_service.dart b/lib/core/service/childvaccines/user_information_service.dart index 0628920c..bdb086d8 100644 --- a/lib/core/service/childvaccines/user_information_service.dart +++ b/lib/core/service/childvaccines/user_information_service.dart @@ -1,10 +1,11 @@ import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/childvaccines/user_information_model.dart'; + import '../base_service.dart'; class UserInformationService extends BaseService { - List userInformationModelList = List(); + List userInformationModelList =[]; Map body = Map(); Future getUserInformationOrders() async { diff --git a/lib/core/service/childvaccines/vaccination_table_service.dart b/lib/core/service/childvaccines/vaccination_table_service.dart index fc2b40e9..330384a9 100644 --- a/lib/core/service/childvaccines/vaccination_table_service.dart +++ b/lib/core/service/childvaccines/vaccination_table_service.dart @@ -1,19 +1,18 @@ import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/core/model/childvaccines/List_BabyInformationModel.dart'; -import 'package:diplomaticquarterapp/core/model/childvaccines/add_newchild_model.dart'; import 'package:diplomaticquarterapp/core/model/childvaccines/create_vaccination_table.dart'; -import 'package:diplomaticquarterapp/core/model/childvaccines/user_information_model.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; + import '../base_service.dart'; class VaccinationTableService extends BaseService { - List createVaccinationTableModelList = List(); + List createVaccinationTableModelList =[]; Map body = Map(); Future getCreateVaccinationTableOrders(List_BabyInformationModel babyInfo, bool sendEmail) async { - String babyBDFormatted = "${DateUtil.convertDateToString(babyInfo.dOB)}/"; + String babyBDFormatted = "${DateUtil.convertDateToString(babyInfo.dOB!)}/"; hasError = false; await getUser(); diff --git a/lib/core/service/client/base_app_client.dart b/lib/core/service/client/base_app_client.dart index 8e410819..edce26ff 100644 --- a/lib/core/service/client/base_app_client.dart +++ b/lib/core/service/client/base_app_client.dart @@ -1,17 +1,20 @@ +import 'dart:async'; import 'dart:convert'; +import 'dart:io' show Platform; +import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; 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'; +import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; -import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/navigation_service.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/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'package:provider/provider.dart'; @@ -19,7 +22,6 @@ import 'package:provider/provider.dart'; import '../../../locator.dart'; import '../../../routes.dart'; import '../AuthenticatedUserObject.dart'; -import 'dart:io' show Platform; AppSharedPreferences sharedPref = new AppSharedPreferences(); @@ -29,35 +31,42 @@ AppSharedPreferences sharedPref = new AppSharedPreferences(); /// onFailure: (String error, int statusCode) {}, /// body: Map(); /// -AuthenticatedUserObject authenticatedUserObject = - locator(); +AuthenticatedUserObject authenticatedUserObject = locator(); VitalSignService _vitalSignService = locator(); class BaseAppClient { + final _analytics = locator(); + + var sampleNHICResponse = + '{"Date":null,"LanguageID":0,"ServiceName":0,"Time":null,"AndroidLink":null,"AuthenticationTokenID":null,"Data":null,"Dataw":false,"DietType":0,"DietTypeID":0,"ErrorCode":null,"ErrorEndUserMessage":null,"ErrorEndUserMessageN":null,"ErrorMessage":null,"ErrorStatusCode":0,"ErrorType":0,"FoodCategory":0,"IOSLink":null,"IsAuthenticated":false,"MealOrderStatus":0,"MealType":0,"MessageStatus":1,"NumberOfResultRecords":0,"PatientBlodType":null,"SuccessMsg":null,"SuccessMsgN":null,"VidaUpdatedResponse":null,"AccessTokenObject":null,"Age":23,"ClientIdentifierId":null,"CreatedBy":0,"DateOfBirth":"05\/20\/2001","FirstNameAr":"عميرخان","FirstNameEn":"UMAIR KHAN","Gender":"M","GenderAr":null,"GenderEn":null,"HealthId":"30000411002276","IdNumber":"2188030163","IdType":"Iqama","IsHijri":false,"IsInstertedOrUpdated":0,"IsNull":0,"IsPatientExistNHIC":0,"IsRecordLockedByCurrentUser":false,"LastNameAr":"خان","LastNameEn":"KHAN","List_ActiveAccessToken":null,"MaritalStatus":"غير معروف","MaritalStatusCode":"U","NationalDateOfBirth":"26\/02\/1422","Nationality":"باكستان","NationalityCode":"PAK","Occupation":"-","PCDTransactionDataResultList":null,"PCD_GetVidaPatientForManualVerificationList":null,"PCD_NHIC_HMG_PatientDetailsMatchCalulationList":null,"PCD_ReturnValue":0,"PatientStatus":"-","PlaceofBirth":"-","PractitionerStatusCode":null,"PractitionerStatusDescAr":null,"PractitionerStatusDescEn":null,"RowCount":0,"SecondNameAr":"عظيم","SecondNameEn":"AZEEM","ThirdNameAr":"خان عمر","ThirdNameEn":"KHAN UMAR","YakeenDoctorData_GetSourceList":null,"YakeenVidaPatientDataStatisticsByPatientIdList":null,"YakeenVidaPatientDataStatisticsList":null,"YakeenVidaPatientDataStatisticsPrefferedList":null,"accessToken":null,"categoryCode":0,"categoryNameAr":null,"categoryNameEn":null,"constraintCode":0,"constraintNameAr":null,"constraintNameEn":null,"content":null,"errorList":null,"licenseExpiryDate":null,"licenseIssuedDate":null,"licenseStatusCode":null,"licenseStatusDescAr":null,"licenseStatusDescEn":null,"organizations":null,"registrationNumber":null,"specialtyCode":0,"specialtyNameAr":null,"specialtyNameEn":null}'; + post(String endPoint, - {Map body, - Function(dynamic response, int statusCode) onSuccess, - Function(String error, int statusCode) onFailure, + {required Map body, + required Function(dynamic response, int statusCode) onSuccess, + required Function(String error, int statusCode) onFailure, bool isAllowAny = false, - bool isExternal = false}) async { + bool isExternal = false, + bool isRCService = false, + bool bypassConnectionCheck = false}) async { String url; if (isExternal) { url = endPoint; } else { - url = BASE_URL + endPoint; + if (isRCService) + url = RC_BASE_URL + endPoint; + else + url = BASE_URL + endPoint; } try { - //Map profile = await sharedPref.getObj(DOCTOR_PROFILE); - var pharmacyToken = await sharedPref.getString(PHARMACY_AUTORZIE_TOKEN); + String? pharmacyToken = await sharedPref.getString(PHARMACY_AUTORZIE_TOKEN); var user = await sharedPref.getObject(USER_PROFILE); - Map headers = { - 'Content-Type': 'application/json', - 'Accept': 'application/json' - }; + Map headers = {'Content-Type': 'application/json', 'Accept': 'application/json'}; if (!isExternal) { - String token = await sharedPref.getString(TOKEN); - var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + String? token = await sharedPref.getString(TOKEN); + String? languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + if (endPoint == SEND_ACTIVATION_CODE) { + languageID = 'en'; + } if (body.containsKey('SetupID')) { body['SetupID'] = body.containsKey('SetupID') ? body['SetupID'] != null @@ -68,141 +77,219 @@ class BaseAppClient { body['VersionID'] = VERSION_ID; body['Channel'] = CHANNEL; - body['LanguageID'] = languageID == 'ar' ? 1 : 2; + + if (body.containsKey('LanguageID')) { + if (body['LanguageID'] != null) { + //change this line because language issue happened on dental + body['LanguageID'] = body['LanguageID'] == 'ar' + ? 1 + : body['LanguageID'] == 'en' + ? 2 + : body['LanguageID']; + } else { + body['LanguageID'] = Provider.of(AppGlobal.context, listen: false).isArabic ? 1 : 2; + } + } else { + // body['LanguageID'] = (languageID.toString().toLowerCase() == 'ar' ? 1 : 2); + body['LanguageID'] = Provider.of(AppGlobal.context, listen: false).isArabic ? 1 : 2; + } + // } else { + // // body['LanguageID'] = (languageID.toString().toLowerCase() == 'ar' ? 1 : 2); + // body['LanguageID'] = + // Provider.of(AppGlobal.context, listen: false) + // .isArabic + // ? 1 + // : 2; + // } + + // body['LanguageID'] = Provider.of(AppGlobal.context, listen: false).isArabic ? 1 : 2; body['IPAdress'] = IP_ADDRESS; body['generalid'] = GENERAL_ID; - body['PatientOutSA'] = body.containsKey('PatientOutSA') - ? body['PatientOutSA'] != null - ? body['PatientOutSA'] - : PATIENT_OUT_SA - : PATIENT_OUT_SA; + // body['isVidaPlus'] = true; + + double lat = await AppSharedPreferences().getDouble(USER_LAT) ?? 0.0; + double long = await AppSharedPreferences().getDouble(USER_LONG) ?? 0.0; + + body['Latitude'] = lat; + body['Longitude'] = long; if (body.containsKey('isDentalAllowedBackend')) { - body['isDentalAllowedBackend'] = - body.containsKey('isDentalAllowedBackend') - ? body['isDentalAllowedBackend'] != null - ? body['isDentalAllowedBackend'] - : IS_DENTAL_ALLOWED_BACKEND - : IS_DENTAL_ALLOWED_BACKEND; + body['isDentalAllowedBackend'] = body.containsKey('isDentalAllowedBackend') + ? body['isDentalAllowedBackend'] != null + ? body['isDentalAllowedBackend'] + : IS_DENTAL_ALLOWED_BACKEND + : IS_DENTAL_ALLOWED_BACKEND; } - body['DeviceTypeID'] = Platform.isAndroid ? 1: 2; + body['DeviceTypeID'] = Platform.isIOS + ? 1 + : await Utils.isGoogleServicesAvailable() + ? 2 + : 3; if (!body.containsKey('IsPublicRequest')) { - body['PatientType'] = body.containsKey('PatientType') - ? body['PatientType'] != null - ? body['PatientType'] - : user['PatientType'] != null - ? user['PatientType'] - : PATIENT_TYPE - : PATIENT_TYPE; + // if (!body.containsKey('PatientType')) { + if (user != null && user['PatientType'] != null) { + body['PatientType'] = user['PatientType']; + } else { + body['PatientType'] = PATIENT_TYPE; + } + // } + + // body['PatientType'] = body.containsKey('PatientType') + // ? body['PatientType'] != null + // ? body['PatientType'] + // : user['PatientType'] != null + // ? user['PatientType'] + // : PATIENT_TYPE + // : PATIENT_TYPE; + + // if (!body.containsKey('PatientTypeID')) { + if (user != null && user['PatientType'] != null) { + body['PatientTypeID'] = user['PatientType']; + } else { + body['PatientType'] = PATIENT_TYPE_ID; + } + // } + + // body['PatientTypeID'] = body.containsKey('PatientTypeID') + // ? body['PatientTypeID'] != null + // ? body['PatientTypeID'] + // : user['PatientType'] != null + // ? user['PatientType'] + // : PATIENT_TYPE_ID + // : PATIENT_TYPE_ID; - body['PatientTypeID'] = body.containsKey('PatientTypeID') - ? body['PatientTypeID'] != null - ? body['PatientTypeID'] - : user['PatientType'] != null - ? user['PatientType'] - : PATIENT_TYPE_ID - : PATIENT_TYPE_ID; if (user != null) { - body['TokenID'] = token; - body['PatientID'] = body['PatientID'] != null - ? body['PatientID'] - : user['PatientID']; - body['PatientOutSA'] = user['OutSA']; - body['SessionID'] = SESSION_ID; //getSe - headers = { - 'Content-Type': 'application/json', - 'Accept': 'application/json', - 'Authorization': pharmacyToken, - 'Mobilenumber': user != null - ? Utils.getPhoneNumberWithoutZero(user['MobileNumber'].toString()) - : "", - 'Statictoken': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9', - 'Username': user['PatientID'].toString(), - }; + body['TokenID'] = body['TokenID'] != null ? body['TokenID'] : token; + body['PatientID'] = body['PatientID'] != null ? body['PatientID'] : user['PatientID']; + + body['PatientOutSA'] = body.containsKey('PatientOutSA') + ? body['PatientOutSA'] != null + ? body['PatientOutSA'] + : user['OutSA'] + : user['OutSA']; + body['SessionID'] = getSessionId(body['TokenID'] != null ? body['TokenID'] : ""); //getSe + // body['SessionID'] = body['TokenID']; //getSe + + // headers = { + // 'Content-Type': 'application/json', + // 'Accept': 'application/json', + // 'Authorization': pharmacyToken, + // 'Mobilenumber': user != null ? Utils.getPhoneNumberWithoutZero(user['MobileNumber'].toString()) : "", + // 'Statictoken': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9', + // 'Username': user['PatientID'].toString(), + // }; } } } - print("URL : $url"); - print("Body : ${json.encode(body)}"); + // body['IdentificationNo'] = 1023854217; + // body['MobileNo'] = "531940021"; //0560717232 + // body['PatientID'] = 5690832; //4609100 + // body['TokenID'] = "@dm!n"; - if (await Utils.checkConnection()) { - final response = await http.post(url.trim(), - body: json.encode(body), headers: headers); + // Patient ID: 3027574 + // Mobile no.: 0502303285 + // ID: 119116817 + + body.removeWhere((key, value) => key == null || value == null); + + // if (url == 'https://uat.hmgwebservices.com/Services/NHIC.svc/REST/GetPatientInfo') { + // url = "https://hmgwebservices.com/Services/NHIC.svc/REST/GetPatientInfo"; + // body['TokenID'] = "@dm!n"; + // } + + // if (AppGlobal.isNetworkDebugEnabled) { + debugPrint("URL : $url"); + final jsonBody = json.encode(body); + debugPrint(jsonBody); + // } + + if (await Utils.checkConnection(bypassConnectionCheck: bypassConnectionCheck)) { + final response = await http.post(Uri.parse(url.trim()), body: json.encode(body), headers: headers); final int statusCode = response.statusCode; - print("statusCode :$statusCode"); if (statusCode < 200 || statusCode >= 400 || json == null) { onFailure('Error While Fetching data', statusCode); + logApiEndpointError(endPoint, 'Error While Fetching data', statusCode); } else { - // var parsed = json.decode(response.body.toString()); - var parsed = json.decode(utf8.decode(response.bodyBytes)); - if (parsed['Response_Message'] != null) { + // var decoded = utf8.decode(response.bodyBytes); + var parsed; + // if (url.contains('Services/NHIC.svc/REST/GetPatientInfo')) { + // parsed = json.decode(sampleNHICResponse); + // } else { + parsed = json.decode(utf8.decode(response.bodyBytes)); + // } + + // print("Response: $parsed"); + + if (isAllowAny) { onSuccess(parsed, statusCode); } else { - if (parsed['ErrorType'] == 4) { - navigateToAppUpdate( - AppGlobal.context, parsed['ErrorEndUserMessage']); - } - if (isAllowAny) { + if (parsed['Response_Message'] != null) { onSuccess(parsed, statusCode); - } else if (parsed['IsAuthenticated'] == null) { - if (parsed['isSMSSent'] == true) { - onSuccess(parsed, statusCode); - } else if (parsed['MessageStatus'] == 1) { - onSuccess(parsed, statusCode); - } else if (parsed['Result'] == 'OK') { + } else { + if (parsed['ErrorType'] == 4) { + navigateToAppUpdate(AppGlobal.context, parsed['ErrorEndUserMessage']); + logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); + } + if (parsed['ErrorType'] == 2) { + await logout(); + logApiEndpointError(endPoint, "session logged out", statusCode); + } + if (isAllowAny) { onSuccess(parsed, statusCode); - } else { - if (parsed != null) { + } else if (parsed['IsAuthenticated'] == null) { + if (parsed['isSMSSent'] == true) { + onSuccess(parsed, statusCode); + } else if (parsed['MessageStatus'] == 1) { + onSuccess(parsed, statusCode); + } else if (parsed['Result'] == 'OK') { onSuccess(parsed, statusCode); } else { - onFailure( - parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], - statusCode); - logout(); + // if (parsed != null) { + // onSuccess(parsed, statusCode); + // } else { + onFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); + logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); + // logout(); + // } } - } - } else if (parsed['MessageStatus'] == 1 || - parsed['SMSLoginRequired'] == true) { - onSuccess(parsed, statusCode); - } else if (parsed['MessageStatus'] == 2 && - parsed['IsAuthenticated']) { - if (parsed['SameClinicApptList'] != null) { + } else if (parsed['MessageStatus'] == 1 || parsed['SMSLoginRequired'] == true) { onSuccess(parsed, statusCode); - } else { - if (parsed['message'] == null && - parsed['ErrorEndUserMessage'] == null) { - if (parsed['ErrorSearchMsg'] == null) { - onFailure("Server Error found with no available message", - statusCode); + } else if (parsed['MessageStatus'] == 2 && parsed['IsAuthenticated']) { + if (parsed['SameClinicApptList'] != null) { + onSuccess(parsed, statusCode); + } else { + if (parsed['message'] == null && parsed['ErrorEndUserMessage'] == null) { + if (parsed['ErrorSearchMsg'] == null) { + onFailure("Server Error found with no available message", statusCode); + logApiEndpointError(endPoint, "Server Error found with no available message", statusCode); + } else { + onFailure(parsed['ErrorSearchMsg'], statusCode); + logApiEndpointError(endPoint, parsed['ErrorSearchMsg'], statusCode); + } } else { - onFailure(parsed['ErrorSearchMsg'], statusCode); + onFailure(parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); + logApiEndpointError(endPoint, parsed['message'] ?? parsed['message'], statusCode); } - } else { - onFailure( - parsed['message'] ?? - parsed['ErrorEndUserMessage'] ?? - parsed['ErrorMessage'], - statusCode); } } - } else if (!parsed['IsAuthenticated']) { - await logout(); - - //helpers.showErrorToast('Your session expired Please login agian'); - } else { - if (parsed['SameClinicApptList'] != null) { - onSuccess(parsed, statusCode); - } else { - if (parsed['message'] != null) { - onFailure(parsed['message'] ?? parsed['message'], statusCode); + // else if (!parsed['IsAuthenticated']) { + // await logout(); + // } + else { + if (parsed['SameClinicApptList'] != null) { + onSuccess(parsed, statusCode); } else { - onFailure( - parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], - statusCode); + if (parsed['message'] != null) { + onFailure(parsed['message'] ?? parsed['message'], statusCode); + logApiEndpointError(endPoint, parsed['message'] ?? parsed['message'], statusCode); + } else { + onFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); + logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); + } } } } @@ -210,19 +297,17 @@ class BaseAppClient { } } else { onFailure('Please Check The Internet Connection', -1); + _analytics.errorTracking.log("internet_connectivity", error: "no internet available"); } } catch (e) { print(e); onFailure(e.toString(), -1); + _analytics.errorTracking.log(endPoint, error: "api exception: $e - API Path: $url"); } } postPharmacy(String endPoint, - {Map body, - Function(dynamic response, int statusCode) onSuccess, - Function(String error, int statusCode) onFailure, - bool isAllowAny = false, - bool isExternal = false}) async { + {Map? body, Function(dynamic response, int statusCode)? onSuccess, Function(String error, int statusCode)? onFailure, bool isAllowAny = false, bool isExternal = false}) async { var token = await sharedPref.getString(PHARMACY_AUTORZIE_TOKEN); var user = await sharedPref.getObject(USER_PROFILE); String url; @@ -238,145 +323,127 @@ class BaseAppClient { Map headers = { 'Content-Type': 'application/json', 'Accept': 'application/json', - 'Authorization': token ?? '', - 'Mobilenumber': user != null - ? Utils.getPhoneNumberWithoutZero(user['MobileNumber'].toString()) - : "", + 'Authorization': pharmacyToken ?? '', + 'Mobilenumber': user != null ? Utils.getPhoneNumberWithoutZero(user['MobileNumber'].toString()) : "", 'Statictoken': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9', 'Username': user != null ? user['PatientID'].toString() : "", }; if (!isExternal) { String token = await sharedPref.getString(TOKEN); - var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); - if (body.containsKey('SetupID')) { - body['SetupID'] = body.containsKey('SetupID') - ? body['SetupID'] != null - ? body['SetupID'] - : SETUP_ID - : SETUP_ID; - } - - body['VersionID'] = VERSION_ID; - body['Channel'] = CHANNEL; - body['LanguageID'] = languageID == 'ar' ? 1 : 2; - - body['IPAdress'] = IP_ADDRESS; - body['generalid'] = GENERAL_ID; - body['PatientOutSA'] = body.containsKey('PatientOutSA') - ? body['PatientOutSA'] != null - ? body['PatientOutSA'] - : PATIENT_OUT_SA - : PATIENT_OUT_SA; - - if (body.containsKey('isDentalAllowedBackend')) { - body['isDentalAllowedBackend'] = - body.containsKey('isDentalAllowedBackend') - ? body['isDentalAllowedBackend'] != null - ? body['isDentalAllowedBackend'] - : IS_DENTAL_ALLOWED_BACKEND - : IS_DENTAL_ALLOWED_BACKEND; - } - - - body['DeviceTypeID'] = Platform.isAndroid ? 1: 2; - - if (!body.containsKey('IsPublicRequest')) { - body['PatientType'] = body.containsKey('PatientType') - ? body['PatientType'] != null - ? body['PatientType'] - : user['PatientType'] != null - ? user['PatientType'] - : PATIENT_TYPE - : PATIENT_TYPE; - - body['PatientTypeID'] = body.containsKey('PatientTypeID') - ? body['PatientTypeID'] != null - ? body['PatientTypeID'] - : user['PatientType'] != null - ? user['PatientType'] - : PATIENT_TYPE_ID - : PATIENT_TYPE_ID; - if (user != null) { - body['TokenID'] = token; - body['PatientID'] = body['PatientID'] != null - ? body['PatientID'] - : user['PatientID']; - body['PatientOutSA'] = user['OutSA']; - body['SessionID'] = SESSION_ID; //getSe - headers = { - 'Content-Type': 'application/json', - 'Accept': 'application/json', - 'Authorization': pharmacyToken, - 'Mobilenumber': user['MobileNumber'].toString(), - 'Statictoken': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9', - 'Username': user['PatientID'].toString(), - }; - } - } + var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + + // if (body.containsKey('SetupID')) { + // body['SetupID'] = body.containsKey('SetupID') + // ? body['SetupID'] != null + // ? body['SetupID'] + // : SETUP_ID + // : SETUP_ID; + // } + // + // body['VersionID'] = VERSION_ID; + // body['Channel'] = CHANNEL; + // body['LanguageID'] = languageID == 'ar' ? 1 : 2; + // + // body['IPAdress'] = IP_ADDRESS; + // body['generalid'] = GENERAL_ID; + // body['PatientOutSA'] = body.containsKey('PatientOutSA') + // ? body['PatientOutSA'] != null + // ? body['PatientOutSA'] + // : PATIENT_OUT_SA + // : PATIENT_OUT_SA; + // + // if (body.containsKey('isDentalAllowedBackend')) { + // body['isDentalAllowedBackend'] = body.containsKey('isDentalAllowedBackend') + // ? body['isDentalAllowedBackend'] != null + // ? body['isDentalAllowedBackend'] + // : IS_DENTAL_ALLOWED_BACKEND + // : IS_DENTAL_ALLOWED_BACKEND; + // } + // + // body['DeviceTypeID'] = Platform.isAndroid ? 1 : 2; + // + // if (!body.containsKey('IsPublicRequest')) { + // body['PatientType'] = body.containsKey('PatientType') + // ? body['PatientType'] != null + // ? body['PatientType'] + // : user['PatientType'] != null + // ? user['PatientType'] + // : PATIENT_TYPE + // : PATIENT_TYPE; + // + // body['PatientTypeID'] = body.containsKey('PatientTypeID') + // ? body['PatientTypeID'] != null + // ? body['PatientTypeID'] + // : user['PatientType'] != null + // ? user['PatientType'] + // : PATIENT_TYPE_ID + // : PATIENT_TYPE_ID; + // if (user != null) { + // body['TokenID'] = token; + // body['PatientID'] = body['PatientID'] != null ? body['PatientID'] : user['PatientID']; + // body['PatientOutSA'] = user['OutSA']; + // body['SessionID'] = SESSION_ID; //getSe + // } + // } } print("URL : $url"); print("Body : ${json.encode(body)}"); + print("Headers : ${json.encode(headers)}"); if (await Utils.checkConnection()) { - final response = await http.post(url.trim(), - body: json.encode(body), headers: headers); + final response = await http.post(Uri.parse(url.trim()), body: json.encode(body), headers: headers); final int statusCode = response.statusCode; - print("statusCode :$statusCode"); + // print("statusCode :$statusCode"); if (statusCode < 200 || statusCode >= 400 || json == null) { - onFailure('Error While Fetching data', statusCode); + onFailure!('Error While Fetching data', statusCode); + logApiEndpointError(endPoint, 'Error While Fetching data', statusCode); } else { // var parsed = json.decode(response.body.toString()); var parsed = json.decode(utf8.decode(response.bodyBytes)); if (parsed['Response_Message'] != null) { - onSuccess(parsed, statusCode); + onSuccess!(parsed, statusCode); } else { if (parsed['ErrorType'] == 4) { - navigateToAppUpdate( - AppGlobal.context, parsed['ErrorEndUserMessage']); + navigateToAppUpdate(AppGlobal.context, parsed['ErrorEndUserMessage']); + logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); } if (isAllowAny) { - onSuccess(parsed, statusCode); + onSuccess!(parsed, statusCode); } else if (parsed['IsAuthenticated'] == null) { if (parsed['isSMSSent'] == true) { - onSuccess(parsed, statusCode); + onSuccess!(parsed, statusCode); } else if (parsed['MessageStatus'] == 1) { - onSuccess(parsed, statusCode); + onSuccess!(parsed, statusCode); } else if (parsed['Result'] == 'OK') { - onSuccess(parsed, statusCode); + onSuccess!(parsed, statusCode); } else { if (parsed != null) { - onSuccess(parsed, statusCode); + onSuccess!(parsed, statusCode); } else { - onFailure( - parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], - statusCode); + onFailure!(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); + logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); + logApiEndpointError(endPoint, 'session logged out', statusCode); logout(); } } - } else if (parsed['MessageStatus'] == 1 || - parsed['SMSLoginRequired'] == true) { - onSuccess(parsed, statusCode); - } else if (parsed['MessageStatus'] == 2 && - parsed['IsAuthenticated']) { + } else if (parsed['MessageStatus'] == 1 || parsed['SMSLoginRequired'] == true) { + onSuccess!(parsed, statusCode); + } else if (parsed['MessageStatus'] == 2 && parsed['IsAuthenticated']) { if (parsed['SameClinicApptList'] != null) { - onSuccess(parsed, statusCode); + onSuccess!(parsed, statusCode); } else { - if (parsed['message'] == null && - parsed['ErrorEndUserMessage'] == null) { + if (parsed['message'] == null && parsed['ErrorEndUserMessage'] == null) { if (parsed['ErrorSearchMsg'] == null) { - onFailure("Server Error found with no available message", - statusCode); + onFailure!("Server Error found with no available message", statusCode); + logApiEndpointError(endPoint, "Server Error found with no available message", statusCode); } else { - onFailure(parsed['ErrorSearchMsg'], statusCode); + onFailure!(parsed['ErrorSearchMsg'], statusCode); + logApiEndpointError(endPoint, parsed['ErrorSearchMsg'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); } } else { - onFailure( - parsed['message'] ?? - parsed['ErrorEndUserMessage'] ?? - parsed['ErrorMessage'], - statusCode); + onFailure!(parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); + logApiEndpointError(endPoint, parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); } } } else if (!parsed['IsAuthenticated']) { @@ -385,80 +452,88 @@ class BaseAppClient { //helpers.showErrorToast('Your session expired Please login agian'); } else { if (parsed['SameClinicApptList'] != null) { - onSuccess(parsed, statusCode); + onSuccess!(parsed, statusCode); } else { if (parsed['message'] != null) { - onFailure(parsed['message'] ?? parsed['message'], statusCode); + onFailure!(parsed['message'] ?? parsed['message'], statusCode); + logApiEndpointError(endPoint, parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); } else { - onFailure( - parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], - statusCode); + onFailure!(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); + logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); } } } } } } else { - onFailure('Please Check The Internet Connection', -1); + onFailure!('Please Check The Internet Connection', -1); + _analytics.errorTracking.log("internet_connectivity", error: "no internet available"); } } catch (e) { print(e); - onFailure(e.toString(), -1); + onFailure!(e.toString(), -1); + _analytics.errorTracking.log(endPoint, error: "api exception: $e"); } } Future navigateToAppUpdate(context, String text) async { - Navigator.pushReplacement( - context, FadePage(page: AppUpdatePage(appUpdateText: text))); + Navigator.pushAndRemoveUntil( + locator().navigatorKey.currentContext!, + MaterialPageRoute(builder: (context) => AppUpdatePage(appUpdateText: text)), + (Route route) => false, + ); } get(String endPoint, - {Function(dynamic response, int statusCode) onSuccess, - Function(String error, int statusCode) onFailure, - Map queryParams, - bool isExternal = false}) async { + {required Function(dynamic response, int statusCode) onSuccess, + required Function(String error, int statusCode) onFailure, + Map? queryParams, + bool isExternal = false, + bool isRCService = false}) async { String url; if (isExternal) { url = endPoint; } else { - url = BASE_URL + endPoint; + if (isRCService) + url = RC_BASE_URL + endPoint; + else + url = BASE_URL + endPoint; } if (queryParams != null) { String queryString = Uri(queryParameters: queryParams).query; url += '?' + queryString; } - print("URL : $url"); + debugPrint("URL : $url"); + // print("Body : ${json.encode(body)}"); if (await Utils.checkConnection()) { final response = await http.get( - url.trim(), - headers: { - 'Content-Type': 'application/json', - 'Accept': 'application/json' - }, + Uri.parse(url.trim()), + headers: {'Content-Type': 'application/json', 'Accept': 'application/json'}, ); final int statusCode = response.statusCode; - print("statusCode :$statusCode"); + // print("statusCode :$statusCode"); if (statusCode < 200 || statusCode >= 400 || json == null) { - onFailure('Error While Fetching data', statusCode); + onFailure!('Error While Fetching data', statusCode); + logApiEndpointError(endPoint, 'Error While Fetching data', statusCode); } else { - // var parsed = json.decode(response.body.toString()); var parsed = json.decode(utf8.decode(response.bodyBytes)); - onSuccess(parsed, statusCode); + onSuccess!(parsed, statusCode); } } else { - onFailure('Please Check The Internet Connection', -1); + onFailure!('Please Check The Internet Connection', -1); + _analytics.errorTracking.log("internet_connectivity", error: "no internet available"); } } getPharmacy(String endPoint, - {Function(dynamic response, int statusCode) onSuccess, - Function(String error, int statusCode) onFailure, + {required Function(dynamic response, int statusCode) onSuccess, + required Function(String error, int statusCode) onFailure, bool isAllowAny = false, bool isExternal = false, - Map queryParams}) async { + Map? queryParams}) async { var token = await sharedPref.getString(PHARMACY_AUTORZIE_TOKEN); var user = await sharedPref.getObject(USER_PROFILE); @@ -474,198 +549,208 @@ class BaseAppClient { } print("URL : $url"); + var ss = json.encode(queryParams); if (await Utils.checkConnection()) { - final response = await http.get(url.trim(), headers: { + final response = await http.get(Uri.parse(url.trim()), headers: { 'Content-Type': 'text/html; charset=utf-8', 'Accept': 'application/json', 'Authorization': token ?? '', - 'Mobilenumber': user != null - ? Utils.getPhoneNumberWithoutZero(user['MobileNumber'].toString()) - : "", + 'Mobilenumber': user != null ? Utils.getPhoneNumberWithoutZero(user['MobileNumber'].toString()) : "", 'Statictoken': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9', 'Username': user != null ? user['PatientID'].toString() : "", + // 'Host': "mdlaboratories.com", }); final int statusCode = response.statusCode; - print("statusCode :$statusCode"); + // print("statusCode :$statusCode"); if (statusCode < 200 || statusCode >= 400 || json == null) { if (statusCode == 401) { - AppToast.showErrorToast( - message: TranslationBase.of(AppGlobal.context).pharmacyRelogin); + onFailure!(TranslationBase.of(AppGlobal.context).pharmacyRelogin, statusCode); + logApiEndpointError(endPoint, TranslationBase.of(AppGlobal.context).pharmacyRelogin, statusCode); Navigator.of(AppGlobal.context).pushNamed(HOME); } else { - onFailure('Error While Fetching data', statusCode); + var bodyUtf = json.decode(utf8.decode(response.bodyBytes)); + // print(bodyUtf); + onFailure!(bodyUtf['error']['ErrorEndUserMsg'], statusCode); + logApiEndpointError(endPoint, bodyUtf['error']['ErrorEndUserMsg'], statusCode); } } else { // var parsed = json.decode(response.body.toString()); var bodyUtf = json.decode(utf8.decode(response.bodyBytes)); - onSuccess(bodyUtf, statusCode); + onSuccess!(bodyUtf, statusCode); } } else { - onFailure('Please Check The Internet Connection', -1); + onFailure!('Please Check The Internet Connection', -1); + _analytics.errorTracking.log("internet_connectivity", error: "no internet available"); } } - simplePost(String fullUrl, - { Map body, - Function(dynamic response, int statusCode) onSuccess, - Function(String error, int statusCode) onFailure,}) async { + simplePost( + String fullUrl, { + required Map body, + required Map headers, + required Function(dynamic response, int statusCode) onSuccess, + required Function(String error, int statusCode) onFailure, + }) async { String url = fullUrl; - print("URL Query String: $url"); + // print("URL Query String: $url"); + // print("body: $body"); if (await Utils.checkConnection()) { + headers!.addAll({'Content-Type': 'application/json', 'Accept': 'application/json'}); final response = await http.post( - url.trim(), + Uri.parse(url.trim()), body: json.encode(body), - headers: { - 'Content-Type': 'application/json', - 'Accept': 'application/json' - }, + headers: headers, ); - final int statusCode = response.statusCode; - print("statusCode :$statusCode"); + // print("statusCode :$statusCode"); + if (await handleUnauthorized(statusCode, forUrl: fullUrl)) simplePost(fullUrl, onFailure: onFailure, onSuccess: onSuccess, body: body, headers: headers); + + // print(response.body.toString()); if (statusCode < 200 || statusCode >= 400 || json == null) { - onFailure('Error While Fetching data', statusCode); + onFailure!('Error While Fetching data', statusCode); + logApiFullUrlError(fullUrl, 'Error While Fetching data', statusCode); } else { - onSuccess(response.body.toString(), statusCode); + onSuccess!(response.body.toString(), statusCode); } } else { - onFailure('Please Check The Internet Connection', -1); + onFailure!('Please Check The Internet Connection', -1); + _analytics.errorTracking.log("internet_connectivity", error: "no internet available"); } } simpleGet(String fullUrl, - {Function(dynamic response, int statusCode) onSuccess, - Function(String error, int statusCode) onFailure, - Map queryParams}) async { - + {Function(dynamic response, int statusCode)? onSuccess, Function(String error, int statusCode)? onFailure, Map? queryParams, Map? headers}) async { + headers = headers ?? {}; String url = fullUrl; - print("URL Query String: $url"); var haveParams = (queryParams != null); if (haveParams) { String queryString = Uri(queryParameters: queryParams).query; url += '?' + queryString; - print("URL Query String: $url"); + // print("URL Query String: $url"); } 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' - }, + Uri.parse(url.trim()), + headers: headers, ); final int statusCode = response.statusCode; - print("statusCode :$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); + onFailure!('Error While Fetching data', statusCode); + logApiFullUrlError(fullUrl, 'Error While Fetching data', statusCode); } else { - onSuccess(response.body.toString(), statusCode); + onSuccess!(response.body.toString(), statusCode); } } else { - onFailure('Please Check The Internet Connection', -1); + onFailure!('Please Check The Internet Connection', -1); + _analytics.errorTracking.log("internet_connectivity", error: "no internet available"); } } - simplePut(String fullUrl, - { Map body, - Function(dynamic response, int statusCode) onSuccess, - Function(String error, int statusCode) onFailure}) async { - + {Map? body, Map? headers, Function(dynamic response, int statusCode)? onSuccess, Function(String error, int statusCode)? onFailure}) async { String url = fullUrl; - print("URL Query String: $url"); + // 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(), + Uri.parse(url.trim()), body: json.encode(body), - headers: { - 'Content-Type': 'application/json', - 'Accept': 'application/json' - }, + headers: headers, ); final int statusCode = response.statusCode; - print("statusCode :$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); + onFailure!('Error While Fetching data', statusCode); + logApiFullUrlError(fullUrl, 'Error While Fetching data', statusCode); } else { - onSuccess(response.body.toString(), statusCode); + onSuccess!(response.body.toString(), statusCode); } } else { - onFailure('Please Check The Internet Connection', -1); + onFailure!('Please Check The Internet Connection', -1); + _analytics.errorTracking.log("internet_connectivity", error: "no internet available"); } } simpleDelete(String fullUrl, - {Function(dynamic response, int statusCode) onSuccess, - Function(String error, int statusCode) onFailure, - Map queryParams}) async { - + {Function(dynamic response, int statusCode)? onSuccess, Function(String error, int statusCode)? onFailure, Map? queryParams, Map? headers}) async { String url = fullUrl; - print("URL Query String: $url"); + // print("URL Query String: $url"); var haveParams = (queryParams != null); if (haveParams) { String queryString = Uri(queryParameters: queryParams).query; url += '?' + queryString; - print("URL Query String: $url"); + // print("URL Query String: $url"); } 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' - }, + Uri.parse(url.trim()), + headers: headers, ); final int statusCode = response.statusCode; - print("statusCode :$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); + onFailure!('Error While Fetching data', statusCode); + logApiFullUrlError(fullUrl, 'Error While Fetching data', statusCode); } else { - onSuccess(response.body.toString(), statusCode); + onSuccess!(response.body.toString(), statusCode); } } else { - onFailure('Please Check The Internet Connection', -1); + onFailure!('Please Check The Internet Connection', -1); + _analytics.errorTracking.log("internet_connectivity", error: "no internet available"); + } + } + + Future handleUnauthorized(int statusCode, {required String forUrl}) async { + if (forUrl.startsWith(EXA_CART_API_BASE_URL) && statusCode == 401) { + final token = await generatePackagesToken(); + packagesAuthHeader['Authorization'] = 'Bearer $token'; + return token != null && (token is String); } + return false; } logout() async { await sharedPref.remove(LOGIN_TOKEN_ID); await sharedPref.remove(PHARMACY_CUSTOMER_ID); await authenticatedUserObject.getUser(); - Provider.of(AppGlobal.context, listen: false).isLogin = - false; - var model = - Provider.of(AppGlobal.context, listen: false); + Provider.of(AppGlobal.context, listen: false).isLogin = false; + var model = Provider.of(AppGlobal.context, listen: false); _vitalSignService.weightKg = ""; _vitalSignService.heightCm = ""; - model.setState(0, false); + model.setState(0, 0, false, null); Navigator.of(AppGlobal.context).pushReplacementNamed(HOME); } String getSessionId(String id) { ///return id.replaceAll(RegExp('/[^\w\s]/'), ''); - return id.replaceAll(RegExp('/[^a-zA-Z ]'), ''); + // if (id != null) return id.replaceAll(RegExp('/[^a-zA-Z]'), ''); + return id.replaceAll(RegExp('/[^a-zA-Z]'), ''); } static defaultHttpParameters() async { String token = await sharedPref.getString(TOKEN); - var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); var user = await sharedPref.getObject(USER_PROFILE); var params = {}; if (user != null) { @@ -685,11 +770,7 @@ class BaseAppClient { } pharmacyPost(String endPoint, - {Map body, - Function(dynamic response, int statusCode) onSuccess, - Function(String error, int statusCode) onFailure, - bool isAllowAny = false, - bool isExternal = false}) async { + {Map? body, Function(dynamic response, int statusCode)? onSuccess, Function(String error, int statusCode)? onFailure, bool isAllowAny = false, bool isExternal = false}) async { var token = await sharedPref.getString(PHARMACY_AUTORZIE_TOKEN); var user = await sharedPref.getObject(USER_PROFILE); String url; @@ -701,10 +782,9 @@ class BaseAppClient { try { if (isExternal) { String token = await sharedPref.getString(TOKEN); - var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); var user = await sharedPref.getObject(USER_PROFILE); - if (body.containsKey('SetupID')) { + if (body!.containsKey('SetupID')) { body['SetupID'] = body.containsKey('SetupID') ? body['SetupID'] != null ? body['SetupID'] @@ -721,19 +801,18 @@ class BaseAppClient { body['PatientOutSA'] = body.containsKey('PatientOutSA') ? body['PatientOutSA'] != null ? body['PatientOutSA'] - : PATIENT_OUT_SA - : PATIENT_OUT_SA; + : user['OutSA'] + : user['OutSA']; if (body.containsKey('isDentalAllowedBackend')) { - body['isDentalAllowedBackend'] = - body.containsKey('isDentalAllowedBackend') - ? body['isDentalAllowedBackend'] != null - ? body['isDentalAllowedBackend'] - : IS_DENTAL_ALLOWED_BACKEND - : IS_DENTAL_ALLOWED_BACKEND; + body['isDentalAllowedBackend'] = body.containsKey('isDentalAllowedBackend') + ? body['isDentalAllowedBackend'] != null + ? body['isDentalAllowedBackend'] + : IS_DENTAL_ALLOWED_BACKEND + : IS_DENTAL_ALLOWED_BACKEND; } - body['DeviceTypeID'] = Platform.isAndroid ? 1: 2; + body['DeviceTypeID'] = Platform.isAndroid ? 1 : 2; if (!body.containsKey('IsPublicRequest')) { body['PatientType'] = body.containsKey('PatientType') @@ -741,98 +820,85 @@ class BaseAppClient { ? body['PatientType'] : user['PatientType'] != null ? user['PatientType'] - : PATIENT_TYPE - : PATIENT_TYPE; + : user['PatientType'] + : user['PatientType']; body['PatientTypeID'] = body.containsKey('PatientTypeID') ? body['PatientTypeID'] != null ? body['PatientTypeID'] : user['PatientType'] != null ? user['PatientType'] - : PATIENT_TYPE_ID - : PATIENT_TYPE_ID; + : user['PatientType'] + : user['PatientType']; if (user != null) { body['TokenID'] = token; - body['PatientID'] = body['PatientID'] != null - ? body['PatientID'] - : user['PatientID']; + body['PatientID'] = body['PatientID'] != null ? body['PatientID'] : user['PatientID']; body['PatientOutSA'] = user['OutSA']; - body['SessionID'] = SESSION_ID; //getSessionId(token); + // body['SessionID'] = SESSION_ID; //getSessionId(token); } } } - print("URL : $url"); - print("Body : ${json.encode(body)}"); + // print("URL : $url"); + // print("Body : ${json.encode(body)}"); var ss = json.encode(body); if (await Utils.checkConnection()) { - final response = - await http.post(url.trim(), body: json.encode(body), headers: { - // 'Content-Type': 'application/json', - // 'Accept': 'application/json', - // 'Statictoken': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9', + final response = await http.post(Uri.parse(url.trim()), body: json.encode(body), headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', 'Authorization': token ?? '', - 'Mobilenumber': user != null - ? Utils.getPhoneNumberWithoutZero(user['MobileNumber'].toString()) - : "", + 'Mobilenumber': user != null ? Utils.getPhoneNumberWithoutZero(user['MobileNumber'].toString()) : "", 'Statictoken': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9', 'Username': user != null ? user['PatientID'].toString() : "", }); final int statusCode = response.statusCode; - print("statusCode :$statusCode"); + // print("statusCode :$statusCode"); if (statusCode < 200 || statusCode >= 400 || json == null) { - onFailure('Error While Fetching data', statusCode); + var parsed = json.decode(utf8.decode(response.bodyBytes)); + onFailure!(parsed['error']['ErrorEndUserMsgN'] ?? 'Error While Fetching data', statusCode); + logApiEndpointError(endPoint, parsed['error']['ErrorEndUserMsgN'] ?? 'Error While Fetching data', statusCode); } else { // var parsed = json.decode(response.body.toString()); var parsed = json.decode(utf8.decode(response.bodyBytes)); if (parsed['Response_Message'] != null) { - onSuccess(parsed, statusCode); + onSuccess!(parsed, statusCode); } else { if (parsed['ErrorType'] == 4) { - navigateToAppUpdate( - AppGlobal.context, parsed['ErrorEndUserMessage']); + navigateToAppUpdate(AppGlobal.context, parsed['ErrorEndUserMessage']); } if (isAllowAny) { - onSuccess(parsed, statusCode); + onSuccess!(parsed, statusCode); } else if (parsed['IsAuthenticated'] == null) { if (parsed['isSMSSent'] == true) { - onSuccess(parsed, statusCode); + onSuccess!(parsed, statusCode); } else if (parsed['MessageStatus'] == 1) { - onSuccess(parsed, statusCode); + onSuccess!(parsed, statusCode); } else if (parsed['Result'] == 'OK') { - onSuccess(parsed, statusCode); + onSuccess!(parsed, statusCode); } else { if (parsed != null) { - onSuccess(parsed, statusCode); + onSuccess!(parsed, statusCode); } else { - onFailure( - parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], - statusCode); + onFailure!(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); + logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); logout(); } } - } else if (parsed['MessageStatus'] == 1 || - parsed['SMSLoginRequired'] == true) { - onSuccess(parsed, statusCode); - } else if (parsed['MessageStatus'] == 2 && - parsed['IsAuthenticated']) { - if (parsed['message'] == null && - parsed['ErrorEndUserMessage'] == null) { + } else if (parsed['MessageStatus'] == 1 || parsed['SMSLoginRequired'] == true) { + onSuccess!(parsed, statusCode); + } else if (parsed['MessageStatus'] == 2 && parsed['IsAuthenticated']) { + if (parsed['message'] == null && parsed['ErrorEndUserMessage'] == null) { if (parsed['ErrorSearchMsg'] == null) { - onFailure("Server Error found with no available message", - statusCode); + onFailure!("Server Error found with no available message", statusCode); + logApiEndpointError(endPoint, "Server Error found with no available message", statusCode); } else { - onFailure(parsed['ErrorSearchMsg'], statusCode); + onFailure!(parsed['ErrorSearchMsg'], statusCode); + logApiEndpointError(endPoint, parsed['ErrorSearchMsg'], statusCode); } } else { - onFailure( - parsed['message'] ?? - parsed['ErrorEndUserMessage'] ?? - parsed['ErrorMessage'], - statusCode); + onFailure!(parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); + logApiEndpointError(endPoint, parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); } } else if (!parsed['IsAuthenticated']) { await logout(); @@ -840,25 +906,57 @@ class BaseAppClient { //helpers.showErrorToast('Your session expired Please login agian'); } else { if (parsed['SameClinicApptList'] != null) { - onSuccess(parsed, statusCode); + onSuccess!(parsed, statusCode); } else { if (parsed['message'] != null) { - onFailure(parsed['message'] ?? parsed['message'], statusCode); + onFailure!(parsed['message'] ?? parsed['message'], statusCode); + logApiEndpointError(endPoint, parsed['message'] ?? parsed['message'], statusCode); } else { - onFailure( - parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], - statusCode); + onFailure!(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); + logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); } } } } } } else { - onFailure('Please Check The Internet Connection', -1); + onFailure!('Please Check The Internet Connection', -1); + _analytics.errorTracking.log("internet_connectivity", error: "no internet available"); } } catch (e) { print(e); - onFailure(e.toString(), -1); + onFailure!(e.toString(), -1); + logApiEndpointError(endPoint, 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(); + logApiFullUrlError(url, error, statusCode); + }); + await completer.future; + return token!; + } + + logApiFullUrlError(String fullUrl, error, code) { + final endpoint = Uri.parse(fullUrl).pathSegments.last; + logApiEndpointError(endpoint, error, code); + } + + logApiEndpointError(String endPoint, error, code) { + _analytics.errorTracking.log(endPoint, error: error); + } } diff --git a/lib/core/service/contactus/finadus_service.dart b/lib/core/service/contactus/finadus_service.dart index 4086def9..4c3f5877 100644 --- a/lib/core/service/contactus/finadus_service.dart +++ b/lib/core/service/contactus/finadus_service.dart @@ -1,19 +1,25 @@ import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/contactus/get_hmg_locations.dart'; + import '../base_service.dart'; class FindusService extends BaseService { - List FindusModelList = List(); - List FindusHospitalModelList = List(); - List FindusPharmaciesModelList = List(); + List FindusModelList =[]; + List FindusHospitalModelList =[]; + List FindusPharmaciesModelList =[]; Map body = Map(); Future getAllFindUsOrders() async { hasError = false; + var lat = await sharedPref.getDouble(USER_LAT); + var long = await sharedPref.getDouble(USER_LONG); + body['Latitude'] = lat ?? 0; + body['Longitude'] = long ?? 0; + await baseAppClient.post(GET_FINDUS_REQUEST, onSuccess: (dynamic response, int statusCode) { FindusModelList.clear(); diff --git a/lib/core/service/contactus/livechat_service.dart b/lib/core/service/contactus/livechat_service.dart index 025073ca..0b8402af 100644 --- a/lib/core/service/contactus/livechat_service.dart +++ b/lib/core/service/contactus/livechat_service.dart @@ -1,11 +1,11 @@ import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; -import 'package:diplomaticquarterapp/core/model/contactus/get_hmg_locations.dart'; import 'package:diplomaticquarterapp/core/model/contactus/get_patientI_cprojects.dart'; + import '../base_service.dart'; class LiveChatService extends BaseService { - List LivechatModelList = List(); + List LivechatModelList =[]; Map body = Map(); // body['body'] @@ -13,6 +13,9 @@ class LiveChatService extends BaseService { Future getAllLiveChatOrders() async { hasError = false; body['List_PatientICProjects'] = false; + body['Latitude'] = await this.sharedPref.getDouble(USER_LAT); + body['Longitude'] = await this.sharedPref.getDouble(USER_LONG); + await baseAppClient.post(GET_LIVECHAT_REQUEST, onSuccess: (dynamic response, int statusCode) { LivechatModelList.clear(); diff --git a/lib/core/service/dashboard_service.dart b/lib/core/service/dashboard_service.dart index a15a4b39..4db1fd6a 100644 --- a/lib/core/service/dashboard_service.dart +++ b/lib/core/service/dashboard_service.dart @@ -1,5 +1,3 @@ -import 'package:diplomaticquarterapp/config/config.dart'; -import 'package:diplomaticquarterapp/core/model/rate/appoitment_rated.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; class DashboardService extends BaseService { diff --git a/lib/core/service/er/EdOnlineServices.dart b/lib/core/service/er/EdOnlineServices.dart index 2df92d8a..71beec0b 100644 --- a/lib/core/service/er/EdOnlineServices.dart +++ b/lib/core/service/er/EdOnlineServices.dart @@ -1,19 +1,21 @@ import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/er/ErPatientShareModel.dart'; import 'package:diplomaticquarterapp/core/model/er/TriageQuestionsModel.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; +import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; +import 'package:flutter/cupertino.dart'; class EdOnlineServices extends BaseService { - List triageQuestionsModelList = List(); - ErPatientShareModel erPatientShareModel; + List triageQuestionsModelList =[]; + ErPatientShareModel? erPatientShareModel; Future getQuestions() async { - hasError =false; + hasError = false; triageQuestionsModelList.clear(); Map body = Map(); body['ProjectID'] = 15; - await baseAppClient.post(ER_GET_VISUAL_TRIAGE_QUESTIONS, - onSuccess: (dynamic response, int statusCode) { + await baseAppClient.post(ER_GET_VISUAL_TRIAGE_QUESTIONS, onSuccess: (dynamic response, int statusCode) { triageQuestionsModelList.clear(); response['ER_TriageQuestionsList'].forEach((questions) { triageQuestionsModelList.add(TriageQuestionsModel.fromJson(questions)); @@ -24,56 +26,37 @@ class EdOnlineServices extends BaseService { }, body: body); } - Future getPatientPaymentInformation({var id}) async { - hasError =false; - await baseAppClient.post(ER_GetPatientPaymentInformationForERClinic, - onSuccess: (dynamic response, int statusCode) { - erPatientShareModel = - ErPatientShareModel.fromJson(response['ER_PatientShare']); + hasError = false; + await baseAppClient.post(ER_GetPatientPaymentInformationForERClinic, onSuccess: (dynamic response, int statusCode) { + erPatientShareModel = ErPatientShareModel.fromJson(response['ER_PatientShare']); }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; - }, body: Map.from({"ProjectID":15,"ClinicID":10})); + }, body: Map.from({"ProjectID": 15, "ClinicID": 10})); } - Future saveQuestionsInformation( - {String notes, - String chiefComplaint, - int projectId, - DateTime selectedTime, - List selectedQuestions}) async { - hasError =false; + Future saveQuestionsInformation({String? notes, String? chiefComplaint, int? projectId, DateTime? selectedTime, List? selectedQuestions}) async { + AppSharedPreferences sharedPref = AppSharedPreferences(); + hasError = false; Map body = Map(); - List checklist = List(); + List checklist =[]; body['ProjectID'] = 15; body['ProjectId'] = projectId; int riskScore = 0; - if (user.age > 14) { - selectedQuestions.forEach((element) { - int score = int.parse(element.adultPoints); + if (user.age! > 14) { + selectedQuestions!.forEach((element) { + int score = int.parse((element.adultPoints! != "" ? element.adultPoints! : "0")); riskScore += score; - checklist.add(Map.from({ - "IsSelected": 1, - "ParameterCode": element.parameterCode, - "ParameterGroup": element.parameterGroup, - "ParameterType": element.parameterType, - "Score": score - })); + checklist.add(Map.from({"IsSelected": 1, "ParameterCode": element.parameterCode, "ParameterGroup": element.parameterGroup, "ParameterType": element.parameterType, "Score": score})); }); } else { - selectedQuestions.forEach((element) { - int score = int.parse(element.pediaPoints); + selectedQuestions!.forEach((element) { + int score = int.parse(element.pediaPoints!); riskScore += score; - checklist.add(Map.from({ - "IsSelected": 1, - "ParameterCode": element.parameterCode, - "ParameterGroup": element.parameterGroup, - "ParameterType": element.parameterType, - "Score": score - })); + checklist.add(Map.from({"IsSelected": 1, "ParameterCode": element.parameterCode, "ParameterGroup": element.parameterGroup, "ParameterType": element.parameterType, "Score": score})); }); } @@ -81,16 +64,16 @@ class EdOnlineServices extends BaseService { "Notes": notes, "ChiefComplaint": chiefComplaint, "PatientId": user.patientID, - "ProjectId": 15, + "ProjectId": projectId, "RiskScore": riskScore, "checklist": checklist.map((e) => e).toList() }; - await baseAppClient.post(ER_SAVE_TRIAGE_INFORMATION, - onSuccess: (dynamic response, int statusCode) {}, - onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }, body: body); + sharedPref.setInt(ER_CHECKIN_RISK_SCORE, riskScore); + + await baseAppClient.post(ER_SAVE_TRIAGE_INFORMATION, onSuccess: (dynamic response, int statusCode) {}, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); } } diff --git a/lib/core/service/er/am_service.dart b/lib/core/service/er/am_service.dart index 2e9460b8..69c494d2 100644 --- a/lib/core/service/er/am_service.dart +++ b/lib/core/service/er/am_service.dart @@ -1,45 +1,49 @@ import 'package:diplomaticquarterapp/config/config.dart'; -import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/enum/OrderService.dart'; +import 'package:diplomaticquarterapp/core/model/er/AmbulanceRequestOrdersModel.dart'; import 'package:diplomaticquarterapp/core/model/er/PatientAllPresOrders.dart'; -import 'package:diplomaticquarterapp/core/model/er/PatientER.dart'; +import 'package:diplomaticquarterapp/core/model/er/PatientER_RC.dart'; import 'package:diplomaticquarterapp/core/model/er/PickUpRequestPresOrder.dart'; import 'package:diplomaticquarterapp/core/model/er/get_all_transportation_method_list_model.dart'; import 'package:flutter/cupertino.dart'; + import '../base_service.dart'; class AmService extends BaseService { - List amModelList = List(); - List patientAllPresOrdersList = List(); + List amModelList =[]; + List patientAllPresOrdersList =[]; + + List patientAmbulanceRequestOrdersList =[]; + bool hasPendingOrder = false; int pendingOrderID = 0; String pendingOrderStatus = ""; String pendingOrderStatusAR = ""; - PickUpRequestPresOrder pickUpRequestPresOrder; + PickUpRequestPresOrder? pickUpRequestPresOrder; + + AmbulanceRequestOrdersModel? pendingAmbulanceRequestOrder; Future getAllTransportationOrders() async { hasError = false; Map body = Map(); body['isDentalAllowedBackend'] = false; body['IdentificationNo'] = user.patientIdentificationNo; - await baseAppClient.post(GET_AMBULANCE_REQUEST, - onSuccess: (dynamic response, int statusCode) { + await baseAppClient.get(GET_ALL_TRANSPORTATIONS_RC + "?patientID=" + user.patientID.toString(), isRCService: true, isExternal: false, onSuccess: (dynamic response, int statusCode) { amModelList.clear(); - response['PatientER_RRT_GetAllTransportationMethodList'].forEach((item) { + response['response']['transportationservices'].forEach((item) { amModelList.add(PatientERTransportationMethod.fromJson(item)); }); }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; - }, body: body); + }); } Future getPatientAllPresOrdersList() async { hasError = false; hasPendingOrder = false; pickUpRequestPresOrder = null; - await baseAppClient.post(GET_PATIENT_ALL_PRES_ORDERS, - onSuccess: (dynamic response, int statusCode) { + await baseAppClient.post(GET_PATIENT_ALL_PRES_ORDERS, onSuccess: (dynamic response, int statusCode) { patientAllPresOrdersList.clear(); response['PatientER_GetPatientAllPresOrdersList'].forEach((item) { if (item['ServiceID'] == OrderService.AMBULANCE.getIdOrderService()) { @@ -47,9 +51,9 @@ class AmService extends BaseService { patientAllPresOrdersList.add(order); if (order.status == 1) { hasPendingOrder = true; - pendingOrderID = order.iD; - pendingOrderStatus = order.description; - pendingOrderStatusAR = order.descriptionN; + pendingOrderID = order.iD!; + pendingOrderStatus = order.description!; + pendingOrderStatusAR = order.descriptionN!; } } }); @@ -59,15 +63,44 @@ class AmService extends BaseService { }, body: Map()); } + Future getPatientAllPresOrdersListRC(dynamic patientID) async { + hasError = false; + hasPendingOrder = false; + pickUpRequestPresOrder = null; + + Map body = Map(); + body['patientId'] = patientID; + body['PatientID'] = patientID; + + await baseAppClient.post(GET_ALL_TRANSPORTATIONS_ORDERS, isRCService: true, onSuccess: (dynamic response, int statusCode) { + patientAmbulanceRequestOrdersList.clear(); + hasPendingOrder = false; + pendingOrderID = 0; + pendingAmbulanceRequestOrder = null; + + response['response'].forEach((item) { + patientAmbulanceRequestOrdersList.add(AmbulanceRequestOrdersModel.fromJson(item)); + if (item['StatusId'] == 1) { + hasPendingOrder = true; + pendingOrderID = item['orderpayment']['id']; + pendingOrderStatus = item['statusText']; + pendingOrderStatusAR = item['statusText']; + pendingAmbulanceRequestOrder = AmbulanceRequestOrdersModel.fromJson(item); + } + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } + Future getOrderDetails() async { hasError = false; Map body = Map(); body['PresOrderID'] = pendingOrderID; body['isDentalAllowedBackend'] = false; - await baseAppClient.post(GET_PICK_UP_REQUEST_BY_PRES_ORDER_ID, - onSuccess: (dynamic response, int statusCode) { - response['PatientER_RRT_GetPickUpRequestByPresOrderIDList'] - .forEach((item) { + await baseAppClient.post(GET_PICK_UP_REQUEST_BY_PRES_ORDER_ID, onSuccess: (dynamic response, int statusCode) { + response['PatientER_RRT_GetPickUpRequestByPresOrderIDList'].forEach((item) { pickUpRequestPresOrder = PickUpRequestPresOrder.fromJson(item); }); }, onFailure: (String error, int statusCode) { @@ -76,7 +109,7 @@ class AmService extends BaseService { }, body: body); } - Future updatePressOrder({@required int presOrderID}) async { + Future updatePressOrder({required int presOrderID}) async { hasError = false; Map body = Map(); body['PresOrderID'] = presOrderID; @@ -84,24 +117,31 @@ class AmService extends BaseService { body['RejectionReason'] = ''; body['PresOrderStatus'] = OrderService.AMBULANCE.getIdOrderService(); body['isDentalAllowedBackend'] = false; - await baseAppClient.post(UPDATE_PRESS_ORDER, - onSuccess: (dynamic response, int statusCode) { - - }, onFailure: (String error, int statusCode) { + await baseAppClient.post(UPDATE_PRESS_ORDER, onSuccess: (dynamic response, int statusCode) {}, onFailure: (String error, int statusCode) { hasError = true; super.error = error; }, body: body); } - Future insertERPressOrder({@required PatientER patientER}) async { + Future updatePressOrderRC({required int presOrderID, required int patientID}) async { hasError = false; + Map body = Map(); + body['Id'] = presOrderID; + body['StatusId'] = 6; + body['ClickButton'] = 14; + body['PatientID'] = patientID; + await baseAppClient.post(CANCEL_AMBULANCE_REQUEST, isRCService: true, onSuccess: (dynamic response, int statusCode) {}, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } - await baseAppClient.post(INSERT_ER_INERT_PRES_ORDER, - onSuccess: (dynamic response, int statusCode) { - - }, onFailure: (String error, int statusCode) { + Future insertERPressOrder({required PatientER_RC patientER}) async { + hasError = false; + var body = patientER.toJson(); + await baseAppClient.post(INSERT_TRANSPORTATION_ORDER_RC, isRCService: true, onSuccess: (dynamic response, int statusCode) {}, onFailure: (String error, int statusCode) { hasError = true; super.error = error; - }, body: patientER.toJson()); + }, body: body); } } diff --git a/lib/core/service/er/er_service.dart b/lib/core/service/er/er_service.dart index bd3b6116..f1aa6c3c 100644 --- a/lib/core/service/er/er_service.dart +++ b/lib/core/service/er/er_service.dart @@ -1,17 +1,15 @@ import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/er/projectavgerwaitingtime.dart'; + import '../base_service.dart'; class ErService extends BaseService { - List projectAvgERWaitingTimeModelList = List(); + List projectAvgERWaitingTimeModelList =[]; Map body = Map(); - String Latitude = ""; - String Longitude = ""; - String PhoneNumber = ""; - Future getProjectAvgERWaitingTimeOrders({int id, int projectID}) async { + Future getProjectAvgERWaitingTimeOrders({int? id, int? projectID}) async { hasError = false; if (id != null && projectID != null) { @@ -22,22 +20,17 @@ class ErService extends BaseService { var long = await sharedPref.getDouble(USER_LONG); body['Latitude'] = lat ?? 0; body['Longitude'] = long ?? 0; + body['IsForER'] = true; + + dynamic localRes; await baseAppClient.post(GET_NEAREST_HOSPITAL, onSuccess: (dynamic response, int statusCode) { - projectAvgERWaitingTimeModelList.clear(); - response['List_ProjectAvgERWaitingTime'].forEach((vital) { - projectAvgERWaitingTimeModelList - .add(ProjectAvgERWaitingTime.fromJson(vital)); - }); - projectAvgERWaitingTimeModelList.forEach((element) { - Latitude = '${element.latitude}'; - Longitude = '${element.longitude}'; - PhoneNumber = '${element.phoneNumber}'; - }); + localRes = response; }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; }, body: body); + return Future.value(localRes); } } diff --git a/lib/core/service/feedback/feedback_service.dart b/lib/core/service/feedback/feedback_service.dart index 9df5b0a6..a6ca0cb0 100644 --- a/lib/core/service/feedback/feedback_service.dart +++ b/lib/core/service/feedback/feedback_service.dart @@ -1,23 +1,19 @@ import 'dart:io'; + import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/feedback/COC_items.dart'; import 'package:diplomaticquarterapp/core/model/feedback/request_insert_coc_item.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; -import 'package:diplomaticquarterapp/pages/feedback/appointment_history.dart'; -import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; class FeedbackService extends BaseService { - List cOCItemList = List(); + List cOCItemList =[]; RequestInsertCOCItem _requestInsertCOCItem = RequestInsertCOCItem(); - List appointHistoryList = List(); + List appointHistoryList =[]; - Future sendCOCItem( - {String title, - String details, - String cOCTypeName, - String attachment, - AppointmentHistory appointHistory}) async { + Future sendCOCItem({String? title, String? details, String? cOCTypeName, String? attachment, AppoitmentAllHistoryResultList? appointHistory}) async { hasError = false; var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); @@ -26,10 +22,10 @@ class FeedbackService extends BaseService { _requestInsertCOCItem.details = details; _requestInsertCOCItem.cOCTypeName = cOCTypeName; _requestInsertCOCItem.formTypeID = cOCTypeName; - _requestInsertCOCItem.mobileNo = user.mobileNumber; + _requestInsertCOCItem.mobileNo = "966" + Utils.getPhoneNumberWithoutZero(user.mobileNumber!); _requestInsertCOCItem.isUserLoggedIn = true; _requestInsertCOCItem.projectID = user.projectID; - _requestInsertCOCItem.patientName = user.firstName + " " + user.lastName; + _requestInsertCOCItem.patientName = user.firstName! + " " + user.lastName!; _requestInsertCOCItem.fileName = ""; _requestInsertCOCItem.appVersion = VERSION_ID; _requestInsertCOCItem.uILanguage = languageID; //TODO Change it to be dynamic @@ -37,14 +33,18 @@ class FeedbackService extends BaseService { _requestInsertCOCItem.deviceInfo = Platform.localHostname; _requestInsertCOCItem.resolution = "400x847"; _requestInsertCOCItem.projectID = 0; - _requestInsertCOCItem.identificationNo = - int.parse(user.patientIdentificationNo); - + _requestInsertCOCItem.tokenID = "C0c@@dm!n?T&A&A@Barcha202029582948"; + _requestInsertCOCItem.identificationNo = int.parse(user.patientIdentificationNo!); + if (BASE_URL.contains('uat')) { + _requestInsertCOCItem.forDemo = true; + } else { + _requestInsertCOCItem.forDemo = false; + } final Map body = _requestInsertCOCItem.toJson(); if (appointHistory != null) { body['AppoinmentNo'] = appointHistory.appointmentNo; - body['AppointmentDate'] = DateUtil.convertDateToString(appointHistory.appointmentDate); + body['AppointmentDate'] = appointHistory.appointmentDate; body['ClinicID'] = appointHistory.clinicID; body['ClinicName'] = appointHistory.clinicName; body['DoctorID'] = appointHistory.doctorID; @@ -52,9 +52,7 @@ class FeedbackService extends BaseService { body['ProjectName'] = appointHistory.projectName; } - await baseAppClient - .post(SEND_FEEDBACK, onSuccess: (dynamic response, int statusCode) {}, - onFailure: (String error, int statusCode) { + await baseAppClient.post(SEND_FEEDBACK, onSuccess: (dynamic response, int statusCode) {}, onFailure: (String error, int statusCode) { hasError = true; super.error = error; }, body: body); @@ -64,15 +62,54 @@ class FeedbackService extends BaseService { hasError = false; Map body = new Map(); body['IdentificationNo'] = user.patientIdentificationNo; - body['MobileNo'] = user.mobileNumber; - body['Searching_type'] = '1'; + body['MobileNo'] = "966" + Utils.getPhoneNumberWithoutZero(user.mobileNumber!); + body['Searching_type'] = 1; + + if (BASE_URL.contains('uat')) { + body['ForDemo'] = true; + } + await baseAppClient.post(GET_STATUS_FOR_COCO, onSuccess: (dynamic response, int statusCode) { + cOCItemList = []; + response['ListCOCItems'].forEach((cOC) { + cOCItemList.add(COCItem.fromJson(cOC)); + }); + cOCItemList = cOCItemList.reversed.toList(); // Sort list in desc order + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } + + Future searchFeedback(String countryCode, String phoneNumber, int type, String idNumber) async { + hasError = false; + Map body = new Map(); + if (type == 1) { + body['IdentificationNo'] = 0; + body['PatientID'] = num.tryParse(idNumber); + body['ItemID'] = 0; + } else if (type == 2) { + body['IdentificationNo'] = idNumber; + body['PatientID'] = 0; + body['ItemID'] = 0; + } else { + body['IdentificationNo'] = 0; + body['PatientID'] = 0; + body['ItemID'] = idNumber; + } - await baseAppClient.post(GET_STATUS_FOR_COCO, - onSuccess: (dynamic response, int statusCode) { + body['PatientOutSA'] = countryCode.contains("966") ? 0 : 1; + + body['MobileNo'] = countryCode + Utils.getPhoneNumberWithoutZero(phoneNumber); + body['Searching_type'] = type; + if (BASE_URL.contains('uat')) { + body['ForDemo'] = true; + } + await baseAppClient.post(GET_STATUS_FOR_COCO, onSuccess: (dynamic response, int statusCode) { cOCItemList = []; response['ListCOCItems'].forEach((cOC) { cOCItemList.add(COCItem.fromJson(cOC)); }); + cOCItemList = cOCItemList.reversed.toList(); // Sort list in desc order }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; @@ -83,11 +120,10 @@ class FeedbackService extends BaseService { hasError = false; Map body = new Map(); body['IsComingFromCOC'] = true; - baseAppClient.post(GET_PATIENT_AppointmentHistory, - onSuccess: (dynamic response, int statusCode) { + baseAppClient.post(GET_PATIENT_AppointmentHistory, onSuccess: (dynamic response, int statusCode) { appointHistoryList = []; response['AppoimentAllHistoryResultList'].forEach((appoint) { - appointHistoryList.add(AppointmentHistory.fromJson(appoint)); + appointHistoryList.add(AppoitmentAllHistoryResultList.fromJson(appoint)); }); }, onFailure: (String error, int statusCode) { hasError = true; diff --git a/lib/core/service/geofencing/GeofencingServices.dart b/lib/core/service/geofencing/GeofencingServices.dart index 56b4f56e..ef565ac6 100644 --- a/lib/core/service/geofencing/GeofencingServices.dart +++ b/lib/core/service/geofencing/GeofencingServices.dart @@ -1,5 +1,4 @@ import 'dart:convert'; -import 'dart:developer'; import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; @@ -9,13 +8,10 @@ import 'package:diplomaticquarterapp/core/model/geofencing/responses/GeoZonesRes import 'package:diplomaticquarterapp/core/model/geofencing/responses/LogGeoZoneResponseModel.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; -import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; -import '../../../locator.dart'; - class GeofencingServices extends BaseService { - List geoZones = List(); + List geoZones =[]; bool testZones = true; Future> getAllGeoZones(GeoZonesRequestModel request) async { @@ -28,8 +24,6 @@ class GeofencingServices extends BaseService { geoZones.add(GeoZonesResponseModel().fromJson(json)); }); - if (kDebugMode || testZones) addTestingGeoZones(zones); - _zonesJsonString = json.encode(zones); }, onFailure: (String error, int statusCode) { hasError = true; @@ -38,13 +32,13 @@ class GeofencingServices extends BaseService { AppSharedPreferences pref = AppSharedPreferences(); await pref.setString(HMG_GEOFENCES, _zonesJsonString); - debugPrint("Finished Fetching GEO ZONES from HMG service..."); - debugPrint("GEO ZONES saved to AppPreferences with key '$HMG_GEOFENCES'"); - + var res = await sharedPref.getStringWithDefaultValue(HMG_GEOFENCES, "[]"); + print("-------GEO ZONES----------: $res"); return geoZones; } - LogGeoZoneResponseModel logResponse; + LogGeoZoneResponseModel? logResponse; + Future logGeoZone(LogGeoZoneRequestModel request) async { hasError = false; await baseAppClient.post(LOG_GEO_ZONES, onSuccess: (dynamic response, int statusCode) { @@ -53,14 +47,6 @@ class GeofencingServices extends BaseService { hasError = true; return Future.error(error); }, body: request.toFlatMap()); - return logResponse; - } - - addTestingGeoZones(List zones) { - // zones.add({"GEOF_ID": 12, "Description": "ZiK Home", "Latitude": "24.691136", "Longitude": "46.650116", "Radius": 100, "Type": 1}); - // zones.add({"GEOF_ID": 13, "Description": "CS Office", "Latitude": "24.7087913", "Longitude": "46.6656461", "Radius": 100, "Type": 1}); - // zones.add({"GEOF_ID": 14, "Description": "Mahmoud Shrouf Home", "Latitude": "24.777577", "Longitude": "46.652675", "Radius": 100, "Type": 1}); - // zones.add({"GEOF_ID": 14, "Description": "Panorama Mall", "Latitude": "24.692453", "Longitude": "46.669168", "Radius": 450, "Type": 1}); - // zones.add({"GEOF_ID": 16, "Description": "Saudi Architects Crossing", "Latitude": "24.698375", "Longitude": "46.668567", "Radius": 140, "Type": 1}); + return logResponse!; } } diff --git a/lib/core/service/hospital_service.dart b/lib/core/service/hospital_service.dart index 6e32d8e6..7d724e54 100644 --- a/lib/core/service/hospital_service.dart +++ b/lib/core/service/hospital_service.dart @@ -1,38 +1,66 @@ +import 'dart:io'; + import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; -import 'package:diplomaticquarterapp/core/model/hospitals/request_get_hospitals_model.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; +import 'package:diplomaticquarterapp/services/permission/permission_service.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:flutter/material.dart'; import 'package:geolocator/geolocator.dart'; class HospitalService extends BaseService { - List _hospitals = List(); + List _hospitals =[]; List get hospitals => _hospitals; - double _latitude; - double _longitude; + double? _latitude; + double? _longitude; _getCurrentLocation() async { - await Geolocator.getLastKnownPosition().then((value) { - _latitude = value.latitude; - _longitude = value.longitude; - }).catchError((e) { - _longitude = 0; - _latitude = 0; - }); + if (await PermissionService.isLocationEnabled()) { + Geolocator.getLastKnownPosition().then((value) { + _latitude = value!.latitude; + _longitude = value.longitude; + }).catchError((e) { + _longitude = 0; + _latitude = 0; + }); + } else { + if (Platform.isAndroid) { + Utils.showPermissionConsentDialog(AppGlobal.context, TranslationBase.of(AppGlobal.context).locationPermissionDialog, () { + Geolocator.getLastKnownPosition().then((value) { + _latitude = value!.latitude; + _longitude = value.longitude; + }).catchError((e) { + _longitude = 0; + _latitude = 0; + }); + }); + } else { + Geolocator.getLastKnownPosition().then((value) { + _latitude = value!.latitude; + _longitude = value.longitude; + }).catchError((e) { + _longitude = 0; + _latitude = 0; + }); + } + } } - Future getHospitals({bool isResBasedOnLoc = true}) async { - if(isResBasedOnLoc) - await _getCurrentLocation(); + Future getHospitals(int languageID, {bool isResBasedOnLoc = true, bool isAdvancePayment = false}) async { + if (isResBasedOnLoc) await _getCurrentLocation(); Map body = Map(); - body['Latitude'] = isResBasedOnLoc?_latitude:0; - body['Longitude'] = isResBasedOnLoc?_longitude:0; + body['Latitude'] = await this.sharedPref.getDouble(USER_LAT); + body['Longitude'] = await this.sharedPref.getDouble(USER_LONG); body['IsOnlineCheckIn'] = isResBasedOnLoc; - body['PatientOutSA'] = 0; + body['IsAdvancePayment'] = isAdvancePayment; + body['LanguageID'] = languageID; + body['IsForER'] = true; - await baseAppClient.post(GET_PROJECT, - onSuccess: (dynamic response, int statusCode) { + await baseAppClient.post(GET_PROJECT, onSuccess: (dynamic response, int statusCode) { _hospitals.clear(); response['ListProject'].forEach((hospital) { _hospitals.add(HospitalsModel.fromJson(hospital)); @@ -42,5 +70,4 @@ class HospitalService extends BaseService { super.error = error; }, body: body); } - } diff --git a/lib/core/service/insurance_service.dart b/lib/core/service/insurance_service.dart index 0b626342..9920f8f4 100644 --- a/lib/core/service/insurance_service.dart +++ b/lib/core/service/insurance_service.dart @@ -1,6 +1,8 @@ import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/insurance/Insurance_card_details.dart'; +import 'package:diplomaticquarterapp/core/model/insurance/ReauestInsuranceApprovalModel.dart'; +import 'package:diplomaticquarterapp/core/model/insurance/insuranceManualUpdateRequest.dart'; import 'package:diplomaticquarterapp/core/model/insurance/insurance_approval.dart'; import 'package:diplomaticquarterapp/core/model/insurance/insurance_card.dart'; import 'package:diplomaticquarterapp/core/model/insurance/insurance_card_update_model.dart'; @@ -9,11 +11,13 @@ import 'package:diplomaticquarterapp/models/FamilyFiles/GetAllSharedRecordByStat import 'package:diplomaticquarterapp/models/FamilyFiles/GetAllSharedRecordsByStatusReq.dart'; import 'package:diplomaticquarterapp/services/family_files/family_files_provider.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:flutter/material.dart'; class InsuranceCardService extends BaseService { - List _cardList = List(); - List _cardUpdated = List(); - List _insuranceApproval = List(); + List _cardList =[]; + List _cardUpdated =[]; + List _insuranceApproval =[]; List get cardList => _cardList; @@ -21,12 +25,11 @@ class InsuranceCardService extends BaseService { List get insuranceApproval => _insuranceApproval; - InsuranceCardDetailsModel insuranceCardDetails; - List insuranceCardDetailsList = List(); + InsuranceCardDetailsModel? insuranceCardDetails; + List insuranceCardDetailsList =[]; bool isHaveInsuranceCard = false; - GetAllSharedRecordsByStatusResponse getAllSharedRecordsByStatusResponse = - GetAllSharedRecordsByStatusResponse(); + GetAllSharedRecordsByStatusResponse getAllSharedRecordsByStatusResponse = GetAllSharedRecordsByStatusResponse(); clearInsuranceCard() { _cardList.clear(); @@ -36,19 +39,12 @@ class InsuranceCardService extends BaseService { _cardUpdated.clear(); } - - InsuranceApprovalModel _insuranceApprovalModel = InsuranceApprovalModel( - isDentalAllowedBackend: false, - patientTypeID: 1, - patientType: 1, - eXuldAPPNO: 0, - projectID: 0); + RequestInsuranceApprovalModel _requestInsuranceApprovalModel = RequestInsuranceApprovalModel(isDentalAllowedBackend: false, patientTypeID: 1, patientType: 1, eXuldAPPNO: 0, projectID: 0); Future getInsurance() async { hasError = false; _cardList.clear(); - await baseAppClient.post(GET_PAtIENTS_INSURANCE, - onSuccess: (dynamic response, int statusCode) { + await baseAppClient.post(GET_PAtIENTS_INSURANCE, onSuccess: (dynamic response, int statusCode) { response['List_PatientInsuranceCard'].forEach((item) { _cardList.add(InsuranceCardModel.fromJson(item)); }); @@ -60,10 +56,9 @@ class InsuranceCardService extends BaseService { Future getInsuranceUpdate() async { hasError = false; - _cardList.clear(); - await baseAppClient.post(GET_PAtIENTS_INSURANCE_UPDATED, - onSuccess: (dynamic response, int statusCode) { - _cardUpdated.clear(); + _cardList.clear(); + await baseAppClient.post(GET_PAtIENTS_INSURANCE_UPDATED, onSuccess: (dynamic response, int statusCode) { + _cardUpdated.clear(); response['List_PatientInsuranceCardHistory'].forEach((item) { _cardUpdated.add(InsuranceUpdateModel.fromJson(item)); }); @@ -73,110 +68,187 @@ class InsuranceCardService extends BaseService { }, body: Map()); } - Future getInsuranceApproval({int appointmentNo}) async { + Future getInsuranceApproval({int? appointmentNo}) async { hasError = false; - // _cardList.clear(); if (appointmentNo != null) { - _insuranceApprovalModel.appointmentNo = appointmentNo; - _insuranceApprovalModel.eXuldAPPNO = null; - _insuranceApprovalModel.projectID = null; + _requestInsuranceApprovalModel.appointmentNo = appointmentNo; + _requestInsuranceApprovalModel.eXuldAPPNO = 0; + _requestInsuranceApprovalModel.projectID = 0; } else { - _insuranceApprovalModel.appointmentNo = null; - _insuranceApprovalModel.eXuldAPPNO = 0; - _insuranceApprovalModel.projectID = 0; + _requestInsuranceApprovalModel.appointmentNo = 0; + _requestInsuranceApprovalModel.eXuldAPPNO = 0; + _requestInsuranceApprovalModel.projectID = 0; } + _insuranceApproval.clear(); + _insuranceApproval.length = 0; - await baseAppClient.post(GET_PAtIENTS_INSURANCE_APPROVALS, - onSuccess: (dynamic response, int statusCode) { - print(response['HIS_Approval_List'].length); - _insuranceApproval.clear(); - _insuranceApproval.length = 0; + await baseAppClient.post(GET_PAtIENTS_INSURANCE_APPROVALS, onSuccess: (dynamic response, int statusCode) { response['HIS_Approval_List'].forEach((item) { _insuranceApproval.add(InsuranceApprovalModel.fromJson(item)); }); }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; - }, body: _insuranceApprovalModel.toJson()); + }, body: _requestInsuranceApprovalModel.toJson()); } Future getFamilyFiles() async { var myFamily = await sharedPref.getObject(FAMILY_FILE); if (myFamily != null) { - getAllSharedRecordsByStatusResponse = - GetAllSharedRecordsByStatusResponse.fromJson(myFamily); + getAllSharedRecordsByStatusResponse = GetAllSharedRecordsByStatusResponse.fromJson(myFamily); } else { getSharedRecordByStatus(); } } Future getSharedRecordByStatus() async { - try { - dynamic localRes; - var request = GetAllSharedRecordsByStatusReq(); - request.status = 0; - await baseAppClient.post(GET_SHARED_RECORD_BY_STATUS, - onSuccess: (dynamic response, int statusCode) { - localRes = response; - }, onFailure: (String error, int statusCode) { - AppToast.showErrorToast(message: error); + var myFamily = await sharedPref.getObject(FAMILY_FILE); + if (myFamily != null) { + getAllSharedRecordsByStatusResponse = GetAllSharedRecordsByStatusResponse.fromJson(myFamily); + return Future.value(GetAllSharedRecordsByStatusResponse.fromJson(myFamily)); + } else { + try { + dynamic localRes; + var request = GetAllSharedRecordsByStatusReq(); + request.status = 0; + await baseAppClient.post(GET_SHARED_RECORD_BY_STATUS, onSuccess: (dynamic response, int statusCode) { + localRes = response; + }, onFailure: (String error, int statusCode) { + AppToast.showErrorToast(message: error); + throw error; + }, body: request.toJson()); + sharedPref.setObject(FAMILY_FILE, localRes); + getAllSharedRecordsByStatusResponse = GetAllSharedRecordsByStatusResponse.fromJson(localRes); + } catch (error) { + print("------------"+error.toString()); throw error; - }, body: request.toJson()); - sharedPref.setObject(FAMILY_FILE, localRes); - getAllSharedRecordsByStatusResponse = - GetAllSharedRecordsByStatusResponse.fromJson(localRes); - } catch (error) { - print(error); - throw error; + } } } - Future getInsuranceDetails(data) async{ + + Future getInsuranceDetails(data) async { dynamic localRes; - await baseAppClient.post(INSURANCE_DETAILS, - onSuccess: (dynamic response, int statusCode) { - localRes = response['List_InsuranceCheckList']; - }, onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }, body:{'CompanyID': data.companyID,'SubCategoryID':data.subCategoryID },); + await baseAppClient.post( + INSURANCE_DETAILS, + onSuccess: (dynamic response, int statusCode) { + localRes = response['List_InsuranceCheckList']; + }, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, + body: {'CompanyID': data.companyID, 'SubCategoryID': data.subCategoryID}, + ); return Future.value(localRes); } - Future getPatientInsuranceDetails({String setupID, int projectID, String patientIdentificationID,int patientID}) async{ + Future getPatientInsuranceDetails({String? setupID, int? projectID, String? patientIdentificationID, int? patientID, bool? isFamily, int parentID = 0}) async { error = ""; hasError = false; insuranceCardDetails = null; isHaveInsuranceCard = false; - await baseAppClient.post(GET_PATIENT_INSURANCE_DETAILS, - onSuccess: (dynamic response, int statusCode) { - insuranceCardDetailsList.clear(); - isHaveInsuranceCard = true; - response['List_PatientInsuranceDetails'].forEach((item) { - insuranceCardDetailsList.add(InsuranceCardDetailsModel.fromJson(item)); - }); - }, onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }, body:{'SetupID': setupID,'ProjectID':projectID,'PatientIdentificationID':patientIdentificationID ,'isDentalAllowedBackend':false,'PatientID':patientID},); + await baseAppClient.post( + GET_PATIENT_INSURANCE_DETAILS, + onSuccess: (dynamic response, int statusCode) { + insuranceCardDetailsList.clear(); + isHaveInsuranceCard = true; + response['List_PatientInsuranceDetails'].forEach((item) { + insuranceCardDetailsList.add(InsuranceCardDetailsModel.fromJson(item)); + }); + }, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, + body: { + 'SetupID': setupID, + 'ProjectID': projectID, + 'PatientIdentificationID': patientIdentificationID, + 'isDentalAllowedBackend': false, + 'PatientID': patientID, + 'IsFamily': isFamily, + 'ParentID': parentID + }, + ); + } + Future getInsuranceSchemes(int projectID, int companyID) async { + dynamic localRes; + await baseAppClient.post( + INSURANCE_SCHEMES, + onSuccess: (dynamic response, int statusCode) { + localRes = response['PatientER_SchemesOfAactiveCompaniesGetList']; + }, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, + body: {'CompanyID': companyID, 'ProjectID': projectID}, + ); + return Future.value(localRes); } - Future uploadInsuranceCard({ String patientIdentificationID,int patientID,String image=""}) async{ - error = ""; - Map body = Map(); - body['PatientID']=patientID; - body['PatientType']=user.patientType; - body['MobileNo']=user.mobileNumber; - body['PatientIdentificationID']=patientIdentificationID; - body['InsuranceCardImage']= image; + Future submitManualInsuranceUpdateRequest(InsuranceManualUpdateRequest insuranceManualUpdateRequest) async { + dynamic localRes; + await baseAppClient.post( + UPDATE_MANUAL_INSURANCE, + onSuccess: (dynamic response, int statusCode) { + localRes = response; + }, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, + body: insuranceManualUpdateRequest.toJson(), + ); + return Future.value(localRes); + } + + Future getInsuranceCompanies() async { + dynamic localRes; + await baseAppClient.post( + INSURANCE_COMPANIES, + onSuccess: (dynamic response, int statusCode) { + localRes = response['PatientER_InsuranceCompanyGetList']; + }, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, + body: {}, + ); + return Future.value(localRes); + } - await baseAppClient.post(UPLOAD_INSURANCE_CARD, - onSuccess: (dynamic response, int statusCode) { + Future uploadInsuranceCard(BuildContext context, {String? patientIdentificationID, int? patientID, String image = ""}) async { + error = ""; + Map body = Map(); + body['PatientID'] = patientID; + body['PatientType'] = user.patientType; + body['MobileNo'] = user.mobileNumber; + body['PatientIdentificationID'] = patientIdentificationID; + body['InsuranceCardImage'] = image; - }, onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }, body:body,); + dynamic localRes; + await baseAppClient.post( + UPLOAD_INSURANCE_CARD, + onSuccess: (dynamic response, int statusCode) { + print(response); + if (response['MessageStatus'] == 1) { + AppToast.showSuccessToast(message: TranslationBase.of(context).requestSent); + } else { + AppToast.showErrorToast(message: response['ErrorEndUserMessage']); + } + localRes = response; + }, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + throw error; + }, + body: body, + ); + return Future.value(localRes); } } diff --git a/lib/core/service/medical/ActiveMedicationsService.dart b/lib/core/service/medical/ActiveMedicationsService.dart index 070b7e5f..eac538bf 100644 --- a/lib/core/service/medical/ActiveMedicationsService.dart +++ b/lib/core/service/medical/ActiveMedicationsService.dart @@ -4,13 +4,14 @@ import 'package:diplomaticquarterapp/core/service/base_service.dart'; class ActiveMedicationsService extends BaseService{ - List activePrescriptionReport = List(); + List activePrescriptionReport =[]; getActiveMedication() async { hasError = false; super.error = ""; Map body = Map(); - body['isDentalAllowedBackend'] = false; + // body['isDentalAllowedBackend'] = false; + // body['PatientID'] = 1298851; await baseAppClient.post(ADD_ACTIVE_PRESCRIPTIONS_REPORT_BY_PATIENT_ID, onSuccess: (response, statusCode) async { activePrescriptionReport.clear(); diff --git a/lib/core/service/medical/AllergiesService.dart b/lib/core/service/medical/AllergiesService.dart index d3deae2b..698f2f48 100644 --- a/lib/core/service/medical/AllergiesService.dart +++ b/lib/core/service/medical/AllergiesService.dart @@ -3,7 +3,7 @@ import 'package:diplomaticquarterapp/core/model/Allergy/Allergy.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; class AllergiesService extends BaseService { - List allergies = List(); + List allergies =[]; getAllergies() async { hasError = false; diff --git a/lib/core/service/medical/BloodPressureService.dart b/lib/core/service/medical/BloodPressureService.dart index 82130750..33a0beeb 100644 --- a/lib/core/service/medical/BloodPressureService.dart +++ b/lib/core/service/medical/BloodPressureService.dart @@ -6,14 +6,14 @@ import 'package:diplomaticquarterapp/core/model/my_trakers/blood_pressur/YearBlo import 'package:diplomaticquarterapp/core/service/base_service.dart'; class BloodPressureService extends BaseService { - List monthDiabtectResultAverageList = List(); - List weekDiabtectResultAverageList = List(); - List yearDiabtecResultAverageList = List(); + List monthDiabtectResultAverageList =[]; + List weekDiabtectResultAverageList =[]; + List yearDiabtecResultAverageList =[]; ///Result - List monthDiabtecPatientResult = List(); - List weekDiabtecPatientResult = List(); - List yearDiabtecPatientResult = List(); + List monthDiabtecPatientResult =[]; + List weekDiabtecPatientResult =[]; + List yearDiabtecPatientResult =[]; Future getBloodSugar() async { hasError = false; @@ -24,6 +24,7 @@ class BloodPressureService extends BaseService { monthDiabtectResultAverageList.clear(); weekDiabtectResultAverageList.clear(); yearDiabtecResultAverageList.clear(); + response['List_MonthBloodPressureResultAverage'].forEach((item) { monthDiabtectResultAverageList .add(MonthBloodPressureResultAverage.fromJson(item)); @@ -73,7 +74,7 @@ class BloodPressureService extends BaseService { super.error = ""; Map body = Map(); body['isDentalAllowedBackend'] = false; - body['to'] = user.emailAddress; + body['To'] = user.emailAddress; await baseAppClient.post(SEND_AVERAGE_BLOOD_PRESSURE_REPORT, onSuccess: (response, statusCode) async {}, onFailure: (String error, int statusCode) { @@ -83,10 +84,10 @@ class BloodPressureService extends BaseService { } addDiabtecResult( - {String bloodPressureDate, - String diastolicPressure, - String systolicePressure, - int measuredArm}) async { + {String? bloodPressureDate, + String? diastolicPressure, + String? systolicePressure, + int? measuredArm}) async { hasError = false; super.error = ""; @@ -108,10 +109,11 @@ class BloodPressureService extends BaseService { } updateDiabtecResult( - {String bloodPressureDate, - String diastolicPressure, - String systolicePressure, - int measuredArm}) async { + {String? bloodPressureDate, + String? diastolicPressure, + String? systolicePressure, + int? lineItemNo, + int? measuredArm}) async { hasError = false; super.error = ""; @@ -120,6 +122,7 @@ class BloodPressureService extends BaseService { body['DiastolicPressure'] = diastolicPressure; body['SystolicePressure'] = systolicePressure; body['MeasuredArm'] ='$measuredArm'; + body['LineItemNo'] = lineItemNo; body['isDentalAllowedBackend'] = false; await baseAppClient.post(UPDATE_BLOOD_PRESSURE_RESULT, @@ -132,7 +135,7 @@ class BloodPressureService extends BaseService { }, body: body); } - Future deactivateDiabeticStatus({int lineItemNo }) async { + Future deactivateDiabeticStatus({int? lineItemNo }) async { hasError = false; super.error = ""; Map body = Map(); diff --git a/lib/core/service/medical/BloodSugarService.dart b/lib/core/service/medical/BloodSugarService.dart index e8e2fabf..2cdae441 100644 --- a/lib/core/service/medical/BloodSugarService.dart +++ b/lib/core/service/medical/BloodSugarService.dart @@ -6,42 +6,37 @@ import 'package:diplomaticquarterapp/core/model/my_trakers/blood_sugar/YearDiabt import 'package:diplomaticquarterapp/core/service/base_service.dart'; class BloodSugarService extends BaseService { - List monthDiabtectResultAverageList = List(); - List weekDiabtectResultAverageList = List(); - List yearDiabtecResultAverageList = List(); + List monthDiabtectResultAverageList =[]; + List weekDiabtectResultAverageList =[]; + List yearDiabtecResultAverageList =[]; ///Result - List monthDiabtecPatientResult = List(); - List weekDiabtecPatientResult = List(); - List yearDiabtecPatientResult = List(); + List monthDiabtecPatientResult =[]; + List weekDiabtecPatientResult =[]; + List yearDiabtecPatientResult =[]; Future getBloodSugar() async { hasError = false; Map body = Map(); + monthDiabtectResultAverageList.clear(); + weekDiabtectResultAverageList.clear(); + yearDiabtecResultAverageList.clear(); + monthDiabtecPatientResult.clear(); + weekDiabtecPatientResult.clear(); + yearDiabtecPatientResult.clear(); body['isDentalAllowedBackend'] = false; - await baseAppClient.post(GET_DIABETIC_RESULT_AVERAGE, - onSuccess: (dynamic response, int statusCode) { - monthDiabtectResultAverageList.clear(); - weekDiabtectResultAverageList.clear(); - yearDiabtecResultAverageList.clear(); - - monthDiabtecPatientResult.clear(); - weekDiabtecPatientResult.clear(); - yearDiabtecPatientResult.clear(); + await baseAppClient.post(GET_DIABETIC_RESULT_AVERAGE, onSuccess: (dynamic response, int statusCode) { response['List_MonthDiabtectResultAverage'].forEach((item) { - monthDiabtectResultAverageList - .add(MonthDiabtectResultAverage.fromJson(item)); + monthDiabtectResultAverageList.add(MonthDiabtectResultAverage.fromJson(item)); }); response['List_WeekDiabtectResultAverage'].forEach((item) { - weekDiabtectResultAverageList - .add(WeekDiabtectResultAverage.fromJson(item)); + weekDiabtectResultAverageList.add(WeekDiabtectResultAverage.fromJson(item)); }); response['List_YearDiabtecResultAverage'].forEach((item) { - yearDiabtecResultAverageList - .add(YearDiabtecResultAverage.fromJson(item)); + yearDiabtecResultAverageList.add(YearDiabtecResultAverage.fromJson(item)); }); }, onFailure: (String error, int statusCode) { hasError = true; @@ -51,11 +46,10 @@ class BloodSugarService extends BaseService { Future getDiabtecResults() async { hasError = false; - await baseAppClient.post(GET_DIABTEC_RESULT, - onSuccess: (dynamic response, int statusCode) { - monthDiabtecPatientResult.clear(); - weekDiabtecPatientResult.clear(); - yearDiabtecPatientResult.clear(); + monthDiabtecPatientResult.clear(); + weekDiabtecPatientResult.clear(); + yearDiabtecPatientResult.clear(); + await baseAppClient.post(GET_DIABTEC_RESULT, onSuccess: (dynamic response, int statusCode) { response['List_MonthDiabtecPatientResult'].forEach((item) { monthDiabtecPatientResult.add(DiabtecPatientResult.fromJson(item)); @@ -69,41 +63,36 @@ class BloodSugarService extends BaseService { yearDiabtecPatientResult.add(DiabtecPatientResult.fromJson(item)); }); }, onFailure: (String error, int statusCode) { - hasError = true; super.error = error; }, body: Map()); } - addDiabtecResult({String bloodSugerDateChart, String bloodSugerResult, String diabtecUnit, int measuredTime}) async { + addDiabtecResult({String? bloodSugerDateChart, String? bloodSugerResult, String? diabtecUnit, int? measuredTime}) async { hasError = false; super.error = ""; Map body = Map(); body['BloodSugerDateChart'] = bloodSugerDateChart; body['BloodSugerResult'] = bloodSugerResult; body['DiabtecUnit'] = diabtecUnit; - body['MeasuredTime'] = measuredTime+1; + body['MeasuredTime'] = measuredTime! + 1; body['isDentalAllowedBackend'] = false; - await baseAppClient.post(ADD_DIABTEC_RESULT, - onSuccess: (response, statusCode) async {}, - onFailure: (String error, int statusCode) { + await baseAppClient.post(ADD_DIABTEC_RESULT, onSuccess: (response, statusCode) async {}, onFailure: (String error, int statusCode) { hasError = true; super.error = error; }, body: body); } - updateDiabtecResult({DateTime month,DateTime hour,String bloodSugerResult,String diabtecUnit, int measuredTime,int lineItemNo}) async { + updateDiabtecResult({DateTime? month, DateTime? hour, String? bloodSugerResult, String? diabtecUnit, int? measuredTime, int? lineItemNo}) async { hasError = false; super.error = ""; Map body = Map(); body['BloodSugerResult'] = bloodSugerResult; body['DiabtecUnit'] = diabtecUnit; - body['BloodSugerDateChart'] = '${month.year}-${month.month}-${month.day} ${hour.hour}:${hour.minute}:00'; + body['BloodSugerDateChart'] = '${month!.year}-${month.month}-${month.day} ${hour!.hour}:${hour.minute}:00'; body['isDentalAllowedBackend'] = false; - body['MeasuredTime'] = measuredTime+1; + body['MeasuredTime'] = measuredTime! + 1; body['LineItemNo'] = lineItemNo; - await baseAppClient.post(UPDATE_DIABETIC_RESULT, - onSuccess: (response, statusCode) async {}, - onFailure: (String error, int statusCode) { + await baseAppClient.post(UPDATE_DIABETIC_RESULT, onSuccess: (response, statusCode) async {}, onFailure: (String error, int statusCode) { hasError = true; super.error = error; }, body: body); @@ -114,26 +103,22 @@ class BloodSugarService extends BaseService { super.error = ""; Map body = Map(); body['isDentalAllowedBackend'] = false; - body['to'] = user.emailAddress; - await baseAppClient.post(SEND_AVERAGE_BLOOD_SUGAR_REPORT, - onSuccess: (response, statusCode) async {}, - onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }, body: body); + body['To'] = user.emailAddress; + await baseAppClient.post(SEND_AVERAGE_BLOOD_SUGAR_REPORT, onSuccess: (response, statusCode) async {}, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); } - Future deactivateDiabeticStatus({int lineItemNo }) async { - hasError = false; + Future deactivateDiabeticStatus({int? lineItemNo}) async { + hasError = false; super.error = ""; Map body = Map(); body['isDentalAllowedBackend'] = false; - body['LineItemNo'] =lineItemNo; - await baseAppClient.post(DEACTIVATE_DIABETIC_STATUS, - onSuccess: (response, statusCode) async {}, - onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }, body: body); + body['LineItemNo'] = lineItemNo; + await baseAppClient.post(DEACTIVATE_DIABETIC_STATUS, onSuccess: (response, statusCode) async {}, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); } } diff --git a/lib/core/service/medical/EyeService.dart b/lib/core/service/medical/EyeService.dart index 937f89e3..40ae1b08 100644 --- a/lib/core/service/medical/EyeService.dart +++ b/lib/core/service/medical/EyeService.dart @@ -4,7 +4,7 @@ import 'package:diplomaticquarterapp/core/service/base_service.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; class EyeService extends BaseService { - List appoimentAllHistoryResultList = List(); + List appoimentAllHistoryResultList = []; getEyeMeasurement() async { hasError = false; @@ -12,12 +12,10 @@ class EyeService extends BaseService { Map body = Map(); body['isDentalAllowedBackend'] = false; body['IsIrisPrescription'] = true; - await baseAppClient.post(GET_PATIENT_APPOINTMENT_HISTORY, - onSuccess: (response, statusCode) async { + await baseAppClient.post(GET_PATIENT_APPOINTMENT_HISTORY, onSuccess: (response, statusCode) async { appoimentAllHistoryResultList.clear(); response['AppoimentAllHistoryResultList'].forEach((appoitment) { - appoimentAllHistoryResultList - .add(AppoimentAllHistoryResultList.fromJson(appoitment)); + appoimentAllHistoryResultList.add(AppoimentAllHistoryResultList.fromJson(appoitment)); }); }, onFailure: (String error, int statusCode) { hasError = true; @@ -25,13 +23,13 @@ class EyeService extends BaseService { }, body: body); } - sendGlassesPrescriptionEmail({int appointmentNo,String projectName,int projectID}) async { + sendGlassesPrescriptionEmail({int? appointmentNo, String? projectName, int? projectID}) async { hasError = false; super.error = ""; Map body = Map(); body['isDentalAllowedBackend'] = false; body['PatientIditificationNum'] = user.patientIdentificationNo; - body['PatientName'] = user.firstName+" "+user.lastName; + body['PatientName'] = user.firstName! + " " + user.lastName!; body['To'] = user.emailAddress; body['SetupID'] = user.setupID; body['DateofBirth'] = user.dateofBirth; @@ -39,24 +37,21 @@ class EyeService extends BaseService { body['AppointmentNo'] = appointmentNo; body['ProjectName'] = projectName; body['PatientID'] = user.patientID; - body['PatientMobileNumber'] = Utils.getPhoneNumberWithoutZero(user.mobileNumber); - await baseAppClient.post(SEND_REPORT_EYE_EMAIL, - onSuccess: (response, statusCode) async { - - }, onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }, body: body); + body['PatientMobileNumber'] = Utils.getPhoneNumberWithoutZero(user.mobileNumber!); + await baseAppClient.post(SEND_REPORT_EYE_EMAIL, onSuccess: (response, statusCode) async {}, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); } - sendContactLensPrescriptionEmail({int appointmentNo,String projectName,int projectID}) async { + sendContactLensPrescriptionEmail({int? appointmentNo, String? projectName, int? projectID}) async { hasError = false; super.error = ""; Map body = Map(); body['isDentalAllowedBackend'] = false; body['AppointmentNo'] = appointmentNo; body['PatientIditificationNum'] = user.patientIdentificationNo; - body['PatientName'] = user.firstName+" "+user.lastName; + body['PatientName'] = user.firstName! + " " + user.lastName!; body['To'] = user.emailAddress; body['SetupID'] = user.setupID; body['DateofBirth'] = user.dateofBirth; @@ -64,13 +59,10 @@ class EyeService extends BaseService { body['AppointmentNo'] = appointmentNo; body['ProjectName'] = projectName; body['PatientID'] = user.patientID; - body['PatientMobileNumber'] = Utils.getPhoneNumberWithoutZero(user.mobileNumber); - await baseAppClient.post(SEND_CONTACT_LENS_PRESCRIPTION_EMAIL, - onSuccess: (response, statusCode) async { - - }, onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }, body: body); + body['PatientMobileNumber'] = Utils.getPhoneNumberWithoutZero(user.mobileNumber!); + await baseAppClient.post(SEND_CONTACT_LENS_PRESCRIPTION_EMAIL, onSuccess: (response, statusCode) async {}, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); } } diff --git a/lib/core/service/medical/PatientSickLeaveService.dart b/lib/core/service/medical/PatientSickLeaveService.dart index bb60ee3b..0b177ec7 100644 --- a/lib/core/service/medical/PatientSickLeaveService.dart +++ b/lib/core/service/medical/PatientSickLeaveService.dart @@ -3,29 +3,27 @@ import 'package:diplomaticquarterapp/core/model/sick_leave/sick_leave.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; class PatientSickLeaveService extends BaseService { - List sickLeaveList = List(); + List sickLeaveList = []; + + String sickLeavePDF = ""; getSickLeave() async { hasError = false; super.error = ""; - await baseAppClient.post(GET_PATIENT_SICK_LEAVE, - onSuccess: (response, statusCode) async { + await baseAppClient.post(GET_PATIENT_SICK_LEAVE_STATUS, onSuccess: (response, statusCode) async { sickLeaveList.clear(); - response['List_SickLeave'].forEach((sickLeave) { - sickLeaveList.add(SickLeave.fromJson(sickLeave)); - }); + if (response['List_SickLeave'] != null && response['List_SickLeave'].length != 0) { + response['List_SickLeave'].forEach((sickLeave) { + sickLeaveList.add(SickLeave.fromJson(sickLeave)); + }); + } }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; }, body: Map()); } - sendSickLeaveEmail( - {int requestNo, - String projectName, - String doctorName, - int projectID, - String setupID}) async { + sendSickLeaveEmail({required int requestNo, required String projectName, required String doctorName, required int projectID, required String setupID, required bool isDownload}) async { hasError = false; super.error = ""; Map body = Map(); @@ -34,14 +32,17 @@ class PatientSickLeaveService extends BaseService { body['DateofBirth'] = user.dateofBirth; body['PatientIditificationNum'] = user.patientIdentificationNo; body['PatientMobileNumber'] = user.mobileNumber; - body['PatientName'] = user.firstName + " " + user.firstName; + body['PatientName'] = user.firstName! + " " + user.firstName!; body['ProjectName'] = projectName; body['DoctorName'] = doctorName; body['ProjectID'] = projectID; body['SetupID'] = setupID; - await baseAppClient - .post(SendSickLeaveEmail, onSuccess: (response, statusCode) async {}, - onFailure: (String error, int statusCode) { + body['IsDownload'] = isDownload; + await baseAppClient.post(SendSickLeaveEmail, onSuccess: (response, statusCode) async { + if(isDownload) { + sickLeavePDF = response['Base64Data']; + } + }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; }, body: body); diff --git a/lib/core/service/medical/WeightPressureService.dart b/lib/core/service/medical/WeightPressureService.dart index b48c4795..7246bfbe 100644 --- a/lib/core/service/medical/WeightPressureService.dart +++ b/lib/core/service/medical/WeightPressureService.dart @@ -7,40 +7,33 @@ import 'package:diplomaticquarterapp/core/service/base_service.dart'; class WeightService extends BaseService { ///Average - List - monthWeightMeasurementResultAverage = List(); - List weekWeightMeasurementResultAverage = - List(); - List yearWeightMeasurementResultAverage = - List(); + List monthWeightMeasurementResultAverage =[]; + List weekWeightMeasurementResultAverage =[]; + List yearWeightMeasurementResultAverage =[]; ///Result - List monthWeightMeasurementResult = List(); - List weekWeightMeasurementResult = List(); - List yearWeightMeasurementResult = List(); + List monthWeightMeasurementResult =[]; + List weekWeightMeasurementResult =[]; + List yearWeightMeasurementResult =[]; Future getWeightAverage() async { hasError = false; Map body = Map(); body['isDentalAllowedBackend'] = false; - await baseAppClient.post(GET_WEIGHT_PRESSURE_RESULT_AVERAGE, - onSuccess: (dynamic response, int statusCode) { - monthWeightMeasurementResultAverage.clear(); - weekWeightMeasurementResultAverage.clear(); - yearWeightMeasurementResultAverage.clear(); + monthWeightMeasurementResultAverage.clear(); + weekWeightMeasurementResultAverage.clear(); + yearWeightMeasurementResultAverage.clear(); + await baseAppClient.post(GET_WEIGHT_PRESSURE_RESULT_AVERAGE, onSuccess: (dynamic response, int statusCode) { response['List_MonthWeightMeasurementResultAverage'].forEach((item) { - monthWeightMeasurementResultAverage - .add(MonthWeightMeasurementResultAverage.fromJson(item)); + monthWeightMeasurementResultAverage.add(MonthWeightMeasurementResultAverage.fromJson(item)); }); response['List_WeekWeightMeasurementResultAverage'].forEach((item) { - weekWeightMeasurementResultAverage - .add(WeekWeightMeasurementResultAverage.fromJson(item)); + weekWeightMeasurementResultAverage.add(WeekWeightMeasurementResultAverage.fromJson(item)); }); response['List_YearWeightMeasurementResultAverage'].forEach((item) { - yearWeightMeasurementResultAverage - .add(YearWeightMeasurementResultAverage.fromJson(item)); + yearWeightMeasurementResultAverage.add(YearWeightMeasurementResultAverage.fromJson(item)); }); }, onFailure: (String error, int statusCode) { hasError = true; @@ -50,19 +43,17 @@ class WeightService extends BaseService { Future getWeightMeasurementResult() async { hasError = false; - await baseAppClient.post(GET_WEIGHT_PRESSURE_RESULT, - onSuccess: (dynamic response, int statusCode) { - monthWeightMeasurementResult.clear(); - weekWeightMeasurementResult.clear(); - yearWeightMeasurementResult.clear(); + monthWeightMeasurementResult.clear(); + weekWeightMeasurementResult.clear(); + yearWeightMeasurementResult.clear(); + await baseAppClient.post(GET_WEIGHT_PRESSURE_RESULT, onSuccess: (dynamic response, int statusCode) { response['List_WeekWeightMeasurementResult'].forEach((item) { weekWeightMeasurementResult.add(WeightMeasurementResult.fromJson(item)); }); response['List_MonthWeightMeasurementResult'].forEach((item) { - monthWeightMeasurementResult - .add(WeightMeasurementResult.fromJson(item)); + monthWeightMeasurementResult.add(WeightMeasurementResult.fromJson(item)); }); response['List_YearWeightMeasurementResult'].forEach((item) { @@ -74,8 +65,7 @@ class WeightService extends BaseService { }, body: Map()); } - addWeightResult( - {String weightDate, String weightMeasured, int weightUnit}) async { + addWeightResult({required String weightDate, required String weightMeasured, required int weightUnit}) async { hasError = false; super.error = ""; @@ -85,15 +75,14 @@ class WeightService extends BaseService { body['weightUnit'] = weightUnit; body['isDentalAllowedBackend'] = false; - await baseAppClient.post(ADD_WEIGHT_PRESSURE_RESULT, - onSuccess: (response, statusCode) async {}, + await baseAppClient.post(ADD_WEIGHT_PRESSURE_RESULT, onSuccess: (response, statusCode) async {}, onFailure: (String error, int statusCode) { hasError = true; super.error = error; }, body: body); } - updateWeightResult({int lineItemNo, int weightUnit,String weightMeasured,String weightDate}) async { + updateWeightResult({required int lineItemNo, required int weightUnit, required String weightMeasured, required String weightDate}) async { hasError = false; super.error = ""; Map body = Map(); @@ -103,36 +92,36 @@ class WeightService extends BaseService { body['WeightDate'] = weightDate; body['isDentalAllowedBackend'] = false; - await baseAppClient.post(UPDATE_WEIGHT_PRESSURE_RESULT, - onSuccess: (response, statusCode) async {}, + await baseAppClient.post(UPDATE_WEIGHT_PRESSURE_RESULT, onSuccess: (response, statusCode) async {}, onFailure: (String error, int statusCode) { hasError = true; super.error = error; }, body: body); } + Future sendReportByEmail() async { hasError = false; super.error = ""; Map body = Map(); body['isDentalAllowedBackend'] = false; body['to'] = user.emailAddress; - await baseAppClient.post(SEND_AVERAGE_BLOOD_WEIGHT_REPORT, - onSuccess: (response, statusCode) async {}, + await baseAppClient.post(SEND_AVERAGE_BLOOD_WEIGHT_REPORT, onSuccess: (response, statusCode) async {}, onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }, body: body); + hasError = true; + super.error = error; + }, body: body); } - deleteWeightResult({int lineItemNo, }) async { + deleteWeightResult({ + required int lineItemNo, + }) async { hasError = false; super.error = ""; Map body = Map(); body['LineItemNo'] = lineItemNo; body['isDentalAllowedBackend'] = false; - await baseAppClient.post(DEACTIVATE_WEIGHT_PRESSURE_RESULT, - onSuccess: (response, statusCode) async {}, + await baseAppClient.post(DEACTIVATE_WEIGHT_PRESSURE_RESULT, onSuccess: (response, statusCode) async {}, onFailure: (String error, int statusCode) { hasError = true; super.error = error; diff --git a/lib/core/service/medical/ask_doctor_services.dart b/lib/core/service/medical/ask_doctor_services.dart index 9a819a6e..95597955 100644 --- a/lib/core/service/medical/ask_doctor_services.dart +++ b/lib/core/service/medical/ask_doctor_services.dart @@ -1,3 +1,5 @@ +import 'dart:io'; + import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/core/model/ask_doctor/AskDoctorReqTypes.dart'; import 'package:diplomaticquarterapp/core/model/ask_doctor/DoctorResponse.dart'; @@ -6,32 +8,51 @@ import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; class AskDoctorService extends BaseService { - List askDoctorReqTypes = List(); - List doctorResponseList = List(); + List askDoctorReqTypes =[]; + List doctorResponseList =[]; + + Future getCallInfoHoursResult({int? projectId, int? doctorId}) async { + hasError = false; + Map body = Map(); + body['isDentalAllowedBackend'] = false; + body['DoctorID'] = doctorId; + body['ProjectID'] = projectId; + + dynamic localRes; + + await baseAppClient.post(GET_CALL_INFO_HOURS_RESULT, onSuccess: (dynamic response, int statusCode) { + localRes = response; + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + return Future.value(localRes); + } - Future getCallInfoHoursResult({int projectId, int doctorId}) async { + Future isDoctorAvailable({int? projectId, int? doctorId, int? clinicId}) async { hasError = false; Map body = Map(); body['isDentalAllowedBackend'] = false; body['DoctorID'] = doctorId; body['ProjectID'] = projectId; + body['ClinicID'] = clinicId; - await baseAppClient.post(GET_CALL_INFO_HOURS_RESULT, - onSuccess: (dynamic response, int statusCode) { - ///OKAY - var asd=""; + dynamic localRes; + + await baseAppClient.post(IS_DOCTOR_AVAILABLE_BY_CALENDAR_SCHEDULE, onSuccess: (dynamic response, int statusCode) { + localRes = response; }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; }, body: body); + return Future.value(localRes); } Future getCallRequestTypeLOV() async { - hasError =false; + hasError = false; Map body = Map(); body['isDentalAllowedBackend'] = false; - await baseAppClient.post(GET_CALL_REQUEST_TYPE_LOV, - onSuccess: (dynamic response, int statusCode) { + await baseAppClient.post(GET_CALL_REQUEST_TYPE_LOV, onSuccess: (dynamic response, int statusCode) { askDoctorReqTypes.clear(); response['ListReqTypes'].forEach((reqType) { askDoctorReqTypes.add(AskDoctorReqTypes.fromJson(reqType)); @@ -42,16 +63,28 @@ class AskDoctorService extends BaseService { }, body: body); } + Future getQuestionTypes() async { + hasError = false; + Map body = Map(); + body['isDentalAllowedBackend'] = false; + await baseAppClient.post(GET_QUESTION_TYPES, onSuccess: (dynamic response, int statusCode) { + askDoctorReqTypes.clear(); + response['QuestionsTypes'].forEach((reqType) { + askDoctorReqTypes.add(AskDoctorReqTypes.fromJson(reqType)); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } + Future getDoctorResponse() async { - hasError =false; + hasError = false; Map body = Map(); body['isDentalAllowedBackend'] = false; - body['from'] = - "${DateTime.now().year}-${DateTime.now().month}-${DateTime.now().day} 00:00:00"; - body['from'] = - "${DateTime.now().year}-${DateTime.now().month}-${DateTime.now().day} ${DateTime.now().hour}:${DateTime.now().minute}:00"; - await baseAppClient.post(GET_DOCTOR_RESPONSE, - onSuccess: (dynamic response, int statusCode) { + body['from'] = "${DateTime.now().year}-${DateTime.now().month}-${DateTime.now().day} 00:00:00"; + body['from'] = "${DateTime.now().year}-${DateTime.now().month}-${DateTime.now().day} ${DateTime.now().hour}:${DateTime.now().minute}:00"; + await baseAppClient.post(GET_DOCTOR_RESPONSE, onSuccess: (dynamic response, int statusCode) { doctorResponseList.clear(); response['List_DoctorResponse'].forEach((reqType) { doctorResponseList.add(DoctorResponse.fromJson(reqType)); @@ -62,13 +95,12 @@ class AskDoctorService extends BaseService { }, body: body); } - Future updateReadStatus({int transactionNo}) async { - hasError =false; + Future updateReadStatus({int? transactionNo}) async { + hasError = false; Map body = Map(); body['isDentalAllowedBackend'] = false; body['TransactionNo'] = transactionNo; - await baseAppClient.post(UPDATE_READ_STATUS, - onSuccess: (dynamic response, int statusCode) { + await baseAppClient.post(UPDATE_READ_STATUS, onSuccess: (dynamic response, int statusCode) { //TODO fix it }, onFailure: (String error, int statusCode) { hasError = true; @@ -76,31 +108,64 @@ class AskDoctorService extends BaseService { }, body: body); } - - Future sendRequestLOV({DoctorList doctorList,String requestType,String remark}) async { - hasError =false; + Future sendRequestLOV({DoctorList? doctorList, String? requestType, String? remark}) async { + hasError = false; Map body = Map(); - body['ProjectID'] = doctorList.projectID; + body['ProjectID'] = doctorList!.projectID; body['SetupID'] = doctorList.setupID; body['DoctorID'] = doctorList.doctorID; body['PatientMobileNumber'] = user.mobileNumber; body['IsMessageSent'] = false; - body['RequestDate'] = DateUtil.yearMonthDay(DateTime.now()); - body['RequestTime'] = DateUtil.time(DateTime.now()); + body['RequestDate'] = DateUtil.convertDateToString(DateTime.now()); + body['RequestTime'] = DateUtil.convertDateToString(DateTime.now()); body['Remarks'] = remark; - body['Status'] = 2;// 4 for testing only.."cancelled status insert" else should be changed to 1 in live version + body['Status'] = 2; // 4 for testing only.."cancelled status insert" else should be changed to 1 in live version body['CreatedBy'] = 102; - body['CreatedOn'] = DateUtil.yearMonthDay(DateTime.now()); + body['CreatedOn'] = DateUtil.convertDateToString(DateTime.now()); body['EditedBy'] = 102; - body['EditedOn'] = DateUtil.yearMonthDay(DateTime.now()); + body['EditedOn'] = DateUtil.convertDateToString(DateTime.now()); body['isDentalAllowedBackend'] = false; - await baseAppClient.post(INSERT_CALL_INFO, - onSuccess: (dynamic response, int statusCode) { + body['AppointmentNo'] = doctorList.appointmentNo; + body['ClinicID'] = doctorList.clinicID; + body['QuestionType'] = num.parse(requestType!); + body['RequestType'] = num.parse(requestType); + body['RequestTypeID'] = num.parse(requestType); + + await baseAppClient.post(INSERT_CALL_INFO, onSuccess: (dynamic response, int statusCode) {}, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } - }, onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }, body: body); + Future rateDoctorResponse({int? transactionNo, int? questionType, int? rate, String? notes, String? mobileNo, String? idNo, String? patientName, int? projectID, String? language}) async { + hasError = false; + dynamic localRes; + Map body = Map(); + body['MobileNo'] = mobileNo; + body['IdentificationNo'] = idNo; + body['PatientName'] = patientName; + body['IsUserLoggedIn'] = true; + body['ProjectID'] = projectID; + body['UILanguage'] = language; + body['BrowserInfo'] = Platform.localHostname; + body['COCTypeName'] = 3; + body['FormTypeID'] = 3; + body['DeviceInfo'] = Platform.localHostname; + body['Resolution'] = "400x847"; + body['AppVersion'] = VERSION_ID; + body['ForDemo'] = false; + body['isVidaPlus'] = false; + body['TransactionNo'] = transactionNo; + body['QuestionType'] = questionType; + body['Rate'] = rate; + body['Notes'] = notes; + await baseAppClient.post(RATE_DOCTOR_RESPONSE, onSuccess: (dynamic response, int statusCode) { + localRes = response; + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + return Future.value(localRes); } } diff --git a/lib/core/service/medical/labs_service.dart b/lib/core/service/medical/labs_service.dart index 11592956..3f83a493 100644 --- a/lib/core/service/medical/labs_service.dart +++ b/lib/core/service/medical/labs_service.dart @@ -3,21 +3,21 @@ import 'package:diplomaticquarterapp/core/model/labs/LabOrderResult.dart'; import 'package:diplomaticquarterapp/core/model/labs/lab_result.dart'; import 'package:diplomaticquarterapp/core/model/labs/patient_lab_orders.dart'; import 'package:diplomaticquarterapp/core/model/labs/patient_lab_special_result.dart'; -import 'package:diplomaticquarterapp/core/model/labs/request_patient_lab_orders.dart'; import 'package:diplomaticquarterapp/core/model/labs/request_patient_lab_special_result.dart'; import 'package:diplomaticquarterapp/core/model/labs/request_send_lab_report_email.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; -import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; class LabsService extends BaseService { - List patientLabOrdersList = List(); + List patientLabOrdersList = []; + + String labReportPDF = ""; Future getPatientLabOrdersList() async { hasError = false; - Map body = Map(); + Map body = Map(); body['isDentalAllowedBackend'] = false; - await baseAppClient.post(GET_Patient_LAB_ORDERS, - onSuccess: (dynamic response, int statusCode) { + await baseAppClient.post(GET_Patient_LAB_ORDERS, onSuccess: (dynamic response, int statusCode) { patientLabOrdersList.clear(); response['ListPLO'].forEach((hospital) { patientLabOrdersList.add(PatientLabOrders.fromJson(hospital)); @@ -28,26 +28,26 @@ class LabsService extends BaseService { }, body: body); } - RequestPatientLabSpecialResult _requestPatientLabSpecialResult = - RequestPatientLabSpecialResult(); + RequestPatientLabSpecialResult _requestPatientLabSpecialResult = RequestPatientLabSpecialResult(); - List patientLabSpecialResult = List(); - List labResultList = List(); - List labOrdersResultsList = List(); + List patientLabSpecialResult = []; + List labResultList = []; + List labOrdersResultsList = []; - Future getLaboratoryResult( - {String projectID, - int clinicID, - String invoiceNo, - String orderNo}) async { + Future getLaboratoryResult({String? projectID, int? clinicID, String? invoiceNo, String? invoiceType, String? orderNo, String? setupID, bool? isVidaPlus}) async { hasError = false; _requestPatientLabSpecialResult.projectID = projectID; _requestPatientLabSpecialResult.clinicID = clinicID; - _requestPatientLabSpecialResult.invoiceNo = invoiceNo; + + _requestPatientLabSpecialResult.invoiceNo = isVidaPlus! ? "0" : invoiceNo; + _requestPatientLabSpecialResult.invoiceNoVP = isVidaPlus ? invoiceNo : "0"; + + _requestPatientLabSpecialResult.invoiceType = invoiceType ?? ""; + _requestPatientLabSpecialResult.orderNo = orderNo; + _requestPatientLabSpecialResult.setupID = setupID; - await baseAppClient.post(GET_Patient_LAB_SPECIAL_RESULT, - onSuccess: (dynamic response, int statusCode) { + await baseAppClient.post(GET_Patient_LAB_SPECIAL_RESULT, onSuccess: (dynamic response, int statusCode) { patientLabSpecialResult.clear(); response['ListPLSR'].forEach((hospital) { patientLabSpecialResult.add(PatientLabSpecialResult.fromJson(hospital)); @@ -58,17 +58,18 @@ class LabsService extends BaseService { }, body: _requestPatientLabSpecialResult.toJson()); } - Future getPatientLabResult({PatientLabOrders patientLabOrder}) async { + Future getPatientLabResult({PatientLabOrders? patientLabOrder, bool? isVidaPlus}) async { hasError = false; Map body = Map(); - body['InvoiceNo'] = patientLabOrder.invoiceNo; - body['OrderNo'] = patientLabOrder.orderNo; + body['InvoiceNo_VP'] = isVidaPlus! ? patientLabOrder!.invoiceNo : "0"; + body['InvoiceNo'] = isVidaPlus ? "0" : patientLabOrder!.invoiceNo; + body['InvoiceType'] = patientLabOrder!.invoiceType; + body['OrderNo'] = patientLabOrder!.orderNo; body['isDentalAllowedBackend'] = false; body['SetupID'] = patientLabOrder.setupID; body['ProjectID'] = patientLabOrder.projectID; body['ClinicID'] = patientLabOrder.clinicID; - await baseAppClient.post(GET_Patient_LAB_RESULT, - onSuccess: (dynamic response, int statusCode) { + await baseAppClient.post(GET_Patient_LAB_RESULT, onSuccess: (dynamic response, int statusCode) { patientLabSpecialResult.clear(); labResultList.clear(); response['ListPLR'].forEach((lab) { @@ -80,19 +81,123 @@ class LabsService extends BaseService { }, body: body); } - Future getPatientLabOrdersResults({PatientLabOrders patientLabOrder,String procedure}) async { + Future generateCovidLabReport(LabResult covidLabResult, String isOutsideKSA) async { hasError = false; Map body = Map(); - body['InvoiceNo'] = patientLabOrder.invoiceNo; - body['OrderNo'] = patientLabOrder.orderNo; + + body['To'] = user.emailAddress; + body['OrderNo'] = covidLabResult.orderNo; + body['OrderLineItemNo'] = covidLabResult.orderLineItemNo; + body['LineItemNo'] = covidLabResult.resultValueBasedLineItemNo; + body['CertificateFormat'] = 5; + body['GeneratedBy'] = 102; + body['ShowPassportNumber'] = isOutsideKSA; body['isDentalAllowedBackend'] = false; - body['SetupID'] = patientLabOrder.setupID; + body['SetupID'] = covidLabResult.setupID; + body['ProjectID'] = covidLabResult.projectID; + + dynamic localRes; + + await baseAppClient.post(SEND_COVID_LAB_RESULT_EMAIL, onSuccess: (dynamic response, int statusCode) { + localRes = response; + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + return Future.value(localRes); + } + + Future updateCovidPassportNumber(String passportNumber) async { + hasError = false; + Map body = Map(); + + body['PassportNo'] = passportNumber; + + dynamic localRes; + + await baseAppClient.post(COVID_PASSPORT_UPDATE, onSuccess: (dynamic response, int statusCode) { + localRes = response; + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + return Future.value(localRes); + } + + Future updateWorkplaceName(String workplaceName, String workplaceNameAR, String occupation, String occupationAR, int requestNumber, String setupID, int projectID) async { + // Future updateWorkplaceName(String workplaceName, String workplaceNameAR, int requestNumber, String setupID, int projectID) async { + hasError = false; + Map body = Map(); + + body['Placeofwork'] = workplaceName; + body['PlaceofworkAr'] = workplaceNameAR; + body['Occupation'] = occupation; + body['OccupationAr'] = occupationAR; + body['Req_ID'] = requestNumber; + body['TargetSetupID'] = setupID; + body['ProjectID'] = projectID; + body['UserID'] = 102; + body['RequestType'] = 1; + + dynamic localRes; + + await baseAppClient.post(UPDATE_WORKPLACE_NAME, onSuccess: (dynamic response, int statusCode) { + localRes = response; + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + return Future.value(localRes); + } + + Future getCovidPassportNumber() async { + hasError = false; + Map body = Map(); + + dynamic localRes; + + await baseAppClient.post(GET_PATIENT_PASSPORT_NUMBER, onSuccess: (dynamic response, int statusCode) { + localRes = response; + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + return Future.value(localRes); + } + + Future getSickLeaveStatusByAdmissionNo(int projectID, int admissionNo) async { + hasError = false; + Map body = Map(); + + body['AdmissionNo'] = admissionNo; + body['ProjectID'] = projectID; + + dynamic localRes; + + await baseAppClient.post(GET_SICKLEAVE_STATUS_ADMISSION_NO, onSuccess: (dynamic response, int statusCode) { + localRes = response; + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + return Future.value(localRes); + } + + Future getPatientLabOrdersResults({PatientLabOrders? patientLabOrder, String? procedure, bool isVidaPlus = false}) async { + hasError = false; + Map body = Map(); + body['InvoiceNo_VP'] = isVidaPlus ? patientLabOrder!.invoiceNo : "0"; + body['InvoiceNo'] = isVidaPlus ? "0" : patientLabOrder!.invoiceNo; + body['OrderNo'] = patientLabOrder!.orderNo; + body['isDentalAllowedBackend'] = false; + body['SetupID'] = patientLabOrder!.setupID; body['ProjectID'] = patientLabOrder.projectID; body['ClinicID'] = patientLabOrder.clinicID; body['Procedure'] = procedure; - await baseAppClient.post(GET_Patient_LAB_ORDERS_RESULT, - onSuccess: (dynamic response, int statusCode) { - labOrdersResultsList.clear(); + body['Procedure'] = procedure; + body['LanguageID'] = 1; + await baseAppClient.post(GET_Patient_LAB_ORDERS_RESULT, onSuccess: (dynamic response, int statusCode) { + labOrdersResultsList.clear(); response['ListPLR'].forEach((lab) { labOrdersResultsList.add(LabOrderResult.fromJson(lab)); }); @@ -102,27 +207,34 @@ class LabsService extends BaseService { }, body: body); } - RequestSendLabReportEmail _requestSendLabReportEmail = - RequestSendLabReportEmail(); + RequestSendLabReportEmail _requestSendLabReportEmail = RequestSendLabReportEmail(); - Future sendLabReportEmail({PatientLabOrders patientLabOrder}) async { - _requestSendLabReportEmail.projectID = patientLabOrder.projectID; - _requestSendLabReportEmail.invoiceNo = patientLabOrder.invoiceNo; + Future sendLabReportEmail({PatientLabOrders? patientLabOrder, AuthenticatedUser? userObj, bool isVidaPlus = false, bool isDownload = false, int languageID = 1}) async { + _requestSendLabReportEmail.projectID = patientLabOrder!.projectID; + _requestSendLabReportEmail.invoiceNo = isVidaPlus ? "0" : patientLabOrder.invoiceNo; + _requestSendLabReportEmail.invoiceNoVP = isVidaPlus ? patientLabOrder.invoiceNo : "0"; + _requestSendLabReportEmail.invoiceType = patientLabOrder.invoiceType; _requestSendLabReportEmail.doctorName = patientLabOrder.doctorName; _requestSendLabReportEmail.clinicName = patientLabOrder.clinicDescription; - _requestSendLabReportEmail.patientName = user.firstName +" "+ user.lastName; - _requestSendLabReportEmail.patientIditificationNum = - user.patientIdentificationNo; - _requestSendLabReportEmail.dateofBirth = user.dateofBirth; - _requestSendLabReportEmail.to = user.emailAddress; - _requestSendLabReportEmail.orderDate = '${patientLabOrder.orderDate.year}-${patientLabOrder.orderDate.month}-${patientLabOrder.orderDate.day}'; - _requestSendLabReportEmail.patientMobileNumber = user.mobileNumber; + _requestSendLabReportEmail.patientName = userObj!.firstName! + " " + userObj.lastName!; + _requestSendLabReportEmail.patientIditificationNum = userObj.patientIdentificationNo; + _requestSendLabReportEmail.dateofBirth = userObj.dateofBirth; + _requestSendLabReportEmail.to = userObj.emailAddress; + _requestSendLabReportEmail.orderDate = '${patientLabOrder.orderDate!.year}-${patientLabOrder.orderDate!.month}-${patientLabOrder.orderDate!.day}'; + _requestSendLabReportEmail.patientMobileNumber = userObj.mobileNumber; _requestSendLabReportEmail.projectName = patientLabOrder.projectName; - _requestSendLabReportEmail.setupID = user.setupID; - - await baseAppClient.post(SEND_LAB_RESULT_EMAIL, - onSuccess: (dynamic response, int statusCode) { + _requestSendLabReportEmail.setupID = patientLabOrder.setupID; + _requestSendLabReportEmail.orderNo = patientLabOrder.orderNo; + _requestSendLabReportEmail.orderNo = patientLabOrder.orderNo; + _requestSendLabReportEmail.isDownload = isDownload; + _requestSendLabReportEmail.doctorID = patientLabOrder.doctorID; + _requestSendLabReportEmail.languageID = languageID; + // await baseAppClient.post(SEND_LAB_RESULT_EMAIL, onSuccess: (dynamic response, int statusCode) { + await baseAppClient.post(isVidaPlus ? SEND_LAB_RESULT_EMAIL : SEND_LAB_RESULT_EMAIL_NEW, onSuccess: (dynamic response, int statusCode) { + if (isDownload) { + labReportPDF = isVidaPlus ? response['LabReportsPDFContent'] : response['PdfContent']; + } }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; diff --git a/lib/core/service/medical/medical_service.dart b/lib/core/service/medical/medical_service.dart index f90280cf..733d9ae5 100644 --- a/lib/core/service/medical/medical_service.dart +++ b/lib/core/service/medical/medical_service.dart @@ -1,48 +1,87 @@ import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/er/PatientER.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; +import 'package:diplomaticquarterapp/pages/MyAppointments/models/DoctorScheduleResponse.dart'; import 'package:flutter/cupertino.dart'; class MedicalService extends BaseService { - List appoitmentAllHistoryResultList = List(); - - getAppointmentHistory({bool isActiveAppointment = false}) async { + List appoitmentAllHistoryResultList =[]; + List doctorScheduleResponse =[]; + List freeSlots = []; + getAppointmentHistory({bool isActiveAppointment = false, bool isForTimeLine = false}) async { hasError = false; super.error = ""; Map body = Map(); - if(isActiveAppointment) { + if (isActiveAppointment) { body['IsActiveAppointment'] = true; body['isDentalAllowedBackend'] = false; } - - await baseAppClient.post(GET_PATIENT_APPOINTMENT_HISTORY, - onSuccess: (response, statusCode) async { + body['IsForTimeLine'] = isForTimeLine; + var appoHistory = await sharedPref.getObject(APPOINTMENT_HISTORY_MEDICAL); + if (appoHistory != null) { appoitmentAllHistoryResultList.clear(); - response['AppoimentAllHistoryResultList'].forEach((appoitment) { - appoitmentAllHistoryResultList - .add(AppoitmentAllHistoryResultList.fromJson(appoitment)); + appoHistory.forEach((appoitment) { + appoitmentAllHistoryResultList.add(AppoitmentAllHistoryResultList.fromJson(appoitment)); }); - }, onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }, body: body); + } else { + await baseAppClient.post(GET_PATIENT_APPOINTMENT_HISTORY, onSuccess: (response, statusCode) async { + appoitmentAllHistoryResultList.clear(); + response['AppoimentAllHistoryResultList'].forEach((appoitment) { + appoitmentAllHistoryResultList.add(AppoitmentAllHistoryResultList.fromJson(appoitment)); + }); + sharedPref.setObject(APPOINTMENT_HISTORY_MEDICAL, response['AppoimentAllHistoryResultList']); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } } - addAmbulanceRequest({@required PatientER patientER}) async { + addAmbulanceRequest({required PatientER patientER}) async { hasError = false; super.error = ""; Map body = Map(); body['RequesterFileNo'] = user.patientID; body['RequesterMobileNo'] = user.mobileNumber; body['RequesterIsOutSA'] = user.outSA; - await baseAppClient.post(GET_PATIENT_APPOINTMENT_HISTORY, - onSuccess: (response, statusCode) async { + await baseAppClient.post(GET_PATIENT_APPOINTMENT_HISTORY, onSuccess: (response, statusCode) async {}, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } + getSchedule(DoctorList doctorRequest) async { + Map request; + request = {'DoctorID': doctorRequest.doctorID, 'ProjectID': doctorRequest.projectID, 'ClinicID': doctorRequest.clinicID, 'DoctorWorkingHoursDays': 90}; + dynamic localRes; + await baseAppClient.post(DOCTOR_SCHEDULE_URL, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + doctorScheduleResponse.clear(); + localRes['List_DoctorWorkingHoursTable'].forEach((item) => {doctorScheduleResponse.add(DoctorScheduleResponse.fromJson(item))}); + } - }, onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }, body: body); + getFreeSlot(DoctorList doctorRequest) async { + Map request; + request = {'DoctorID': doctorRequest.doctorID, 'ProjectID': doctorRequest.projectID, 'ClinicID': doctorRequest.clinicID, 'DoctorWorkingHoursDays': 90}; + dynamic localRes; + await baseAppClient.post(GET_DOCTOR_FREE_SLOTS, onSuccess: (response, statusCode) async { + localRes = response; + freeSlots.clear(); + localRes['FreeTimeSlots'].forEach((item) => freeSlots.add(item)); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + // throw error; + }, body: request); + // freeSlots.clear(); + // localRes['FreeTimeSlots'].forEach((item) => freeSlots.add(item)); + // localRes['List_DoctorWorkingHoursTable'].forEach((item) => + // {doctorScheduleResponse.add(DoctorScheduleResponse.fromJson(item))}); } } diff --git a/lib/core/service/medical/my_balance_service.dart b/lib/core/service/medical/my_balance_service.dart index e2744250..e3b44586 100644 --- a/lib/core/service/medical/my_balance_service.dart +++ b/lib/core/service/medical/my_balance_service.dart @@ -1,4 +1,3 @@ -import 'dart:convert'; import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; @@ -16,21 +15,21 @@ import 'package:diplomaticquarterapp/services/family_files/family_files_provider import 'package:diplomaticquarterapp/uitl/app_toast.dart'; class MyBalanceService extends BaseService { - List patientAdvanceBalanceAmountList = List(); - double totalAdvanceBalanceAmount; - List patientInfoList = List(); + List patientAdvanceBalanceAmountList =[]; + dynamic totalAdvanceBalanceAmount; + List patientInfoList =[]; GetAllSharedRecordsByStatusResponse getAllSharedRecordsByStatusResponse = GetAllSharedRecordsByStatusResponse(); - PatientInfoAndMobileNumber patientInfoAndMobileNumber; - String logInTokenID; - String verificationCode; + PatientInfoAndMobileNumber? patientInfoAndMobileNumber; + String? logInTokenID; + String? verificationCode; String updatedRegisterBloodMessage = ""; AuthenticatedUserObject authenticatedUserObject = locator(); - MyBalanceService() { - getFamilyFiles(); - } + // MyBalanceService() { + // // getFamilyFiles(); + // } getPatientAdvanceBalanceAmount() async { hasError = false; @@ -49,7 +48,7 @@ class MyBalanceService extends BaseService { }, body: Map()); } - getPatientInfoByPatientID({String id}) async { + getPatientInfoByPatientID({required String id}) async { hasError = false; super.error = ""; Map body = Map(); @@ -73,7 +72,7 @@ class MyBalanceService extends BaseService { Map body = Map(); body['isDentalAllowedBackend'] = false; body['MobileNo'] = advanceModel.mobileNumber; - body['ProjectID'] = advanceModel.hospitalsModel.iD; + body['ProjectID'] = advanceModel.hospitalsModel!.iD; body['PatientID'] = advanceModel.fileNumber; await baseAppClient.post(GET_PATIENT_INFO_BY_ID_AND_MOBILE_NUMBER, @@ -88,7 +87,7 @@ class MyBalanceService extends BaseService { }, body: body); } - sendActivationCodeForAdvancePayment({int patientID, int projectID}) async { + sendActivationCodeForAdvancePayment({required int patientID, required int projectID}) async { hasError = false; super.error = ""; Map body = Map(); @@ -100,7 +99,6 @@ class MyBalanceService extends BaseService { onSuccess: (response, statusCode) async { logInTokenID = response['LogInTokenID']; verificationCode = response['VerificationCode']; - print(verificationCode); }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; @@ -108,7 +106,7 @@ class MyBalanceService extends BaseService { }, body: body); } - checkActivationCodeForAdvancePayment({String activationCode}) async { + checkActivationCodeForAdvancePayment({required String activationCode}) async { hasError = false; super.error = ""; Map body = Map(); @@ -143,7 +141,7 @@ class MyBalanceService extends BaseService { } catch (error) { print(error); hasError = true; - super.error = error; + super.error = error.toString(); } } diff --git a/lib/core/service/medical/my_doctor_service.dart b/lib/core/service/medical/my_doctor_service.dart index 3d9e14b7..2f08f07c 100644 --- a/lib/core/service/medical/my_doctor_service.dart +++ b/lib/core/service/medical/my_doctor_service.dart @@ -8,9 +8,9 @@ import 'package:diplomaticquarterapp/core/service/base_service.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; class MyDoctorService extends BaseService { - List patientDoctorAppointmentList = List(); - DoctorProfile doctorProfile; - DoctorList doctorList; + List patientDoctorAppointmentList =[]; + DoctorProfile? doctorProfile; + DoctorList? doctorList; DoctorRating doctorRating = DoctorRating(); RequestPatientDoctorAppointment patientDoctorAppointmentRequest = @@ -49,7 +49,7 @@ class MyDoctorService extends BaseService { ); Future getDoctorProfileAndRating( - {int doctorId, int clinicID, int projectID}) async { + {required int doctorId, required int clinicID, required int projectID}) async { ///GET DOCTOR PROFILE _requestDoctorProfile.doctorID = doctorId; _requestDoctorProfile.clinicID = clinicID; @@ -59,10 +59,10 @@ class MyDoctorService extends BaseService { onSuccess: (dynamic response, int statusCode) { doctorProfile = DoctorProfile.fromJson(response['DoctorProfileList'][0]); doctorList = DoctorList.fromJson(response['DoctorProfileList'][0]); - doctorList.clinicName = doctorProfile.clinicDescription; - doctorList.doctorTitle = doctorProfile.doctorTitleForProfile; - doctorList.name = doctorProfile.doctorName; - doctorList.projectName = doctorProfile.projectName; + doctorList!.clinicName = doctorProfile!.clinicDescription!; + doctorList!.doctorTitle = doctorProfile!.doctorTitleForProfile!; + doctorList!.name = doctorProfile!.doctorName!; + doctorList!.projectName = doctorProfile!.projectName!; }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; diff --git a/lib/core/service/medical/prescriptions_service.dart b/lib/core/service/medical/prescriptions_service.dart index e9741a7f..8becfb7e 100644 --- a/lib/core/service/medical/prescriptions_service.dart +++ b/lib/core/service/medical/prescriptions_service.dart @@ -1,29 +1,34 @@ 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_info_rc_model.dart'; import 'package:diplomaticquarterapp/core/model/prescriptions/prescription_report.dart'; import 'package:diplomaticquarterapp/core/model/prescriptions/prescription_report_enh.dart'; +import 'package:diplomaticquarterapp/core/model/prescriptions/prescription_report_inp.dart'; import 'package:diplomaticquarterapp/core/model/prescriptions/prescriptions_order.dart'; import 'package:diplomaticquarterapp/core/model/prescriptions/request_get_list_pharmacy_for_prescriptions.dart'; import 'package:diplomaticquarterapp/core/model/prescriptions/request_prescription_report.dart'; import 'package:diplomaticquarterapp/core/model/prescriptions/request_prescription_report_enh.dart'; -import 'package:diplomaticquarterapp/core/model/prescriptions/request_prescriptions.dart'; -import 'package:diplomaticquarterapp/core/model/prescriptions/request_prescriptions_orders.dart'; import 'package:diplomaticquarterapp/core/model/prescriptions/request_send_prescription_email.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; import 'package:flutter/cupertino.dart'; class PrescriptionsService extends BaseService { - List prescriptionsList = List(); + List prescriptionsList = []; + List prescriptionReportListINP = []; + List prescriptionsOrderList = []; + List prescriptionsOrderListRC = []; + var isMedDeliveryAllowed; - List prescriptionsOrderList = List(); + String prescriptionReportPDF = ""; Future getPrescriptions() async { hasError = false; Map body = Map(); body['isDentalAllowedBackend'] = false; - await baseAppClient.post(PRESCRIPTIONS, - onSuccess: (dynamic response, int statusCode) { + await baseAppClient.post(PRESCRIPTIONS, onSuccess: (dynamic response, int statusCode) { prescriptionsList.clear(); response['PatientPrescriptionList'].forEach((prescriptions) { prescriptionsList.add(Prescriptions.fromJson(prescriptions)); @@ -35,15 +40,40 @@ class PrescriptionsService extends BaseService { } Future getPrescriptionsOrders() async { + prescriptionsOrderList.clear(); Map body = Map(); - body['isDentalAllowedBackend'] = false; - await baseAppClient.post(GET_PRESCRIPTIONS_ALL_ORDERS, - onSuccess: (dynamic response, int statusCode) { - prescriptionsOrderList.clear(); - response['PatientER_GetPatientAllPresOrdersList'] - .forEach((prescriptionsOrder) { - prescriptionsOrderList - .add(PrescriptionsOrder.fromJson(prescriptionsOrder)); + // 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)); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } + + Future getPrescriptionsInfoRC(int orderID, dynamic patientID) async { + prescriptionsOrderListRC.clear(); + Map body = Map(); + body['ID'] = orderID; + await baseAppClient.post(GET_ALL_PRESCRIPTION_INFO_RC + "?PatientId=" + patientID.toString(), isRCService: true, onSuccess: (dynamic response, int statusCode) { + response['response']['report'].forEach((prescriptionsOrder) { + prescriptionsOrderListRC.add(PrescriptionInfoRCModel.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, isRCService: true, onSuccess: (dynamic response, int statusCode) { + response['response'].forEach((prescriptionsOrder) { + prescriptionsOrderList.add(GetCMCAllOrdersResponseModel.fromJson(prescriptionsOrder)); }); }, onFailure: (String error, int statusCode) { hasError = true; @@ -51,64 +81,71 @@ class PrescriptionsService extends BaseService { }, body: body); } - RequestPrescriptionReport _requestPrescriptionReport = - RequestPrescriptionReport( - appointmentNo: 0, isDentalAllowedBackend: false); - List prescriptionReportList = List(); + RequestPrescriptionReport _requestPrescriptionReport = RequestPrescriptionReport(appointmentNo: 0, isDentalAllowedBackend: false); + List prescriptionReportList = []; - Future getPrescriptionReport( - {Prescriptions prescriptions}) async { + Future getPrescriptionReport({required Prescriptions prescriptions}) async { hasError = false; - _requestPrescriptionReport.dischargeNo = prescriptions.dischargeNo; + if (prescriptions.isInOutPatient == false) { + _requestPrescriptionReport.dischargeNo = prescriptions.dischargeNo; + } else { + _requestPrescriptionReport.dischargeNo = 0; + } _requestPrescriptionReport.projectID = prescriptions.projectID; _requestPrescriptionReport.clinicID = prescriptions.clinicID; _requestPrescriptionReport.setupID = prescriptions.setupID; _requestPrescriptionReport.episodeID = prescriptions.episodeID; _requestPrescriptionReport.appointmentNo = prescriptions.appointmentNo; - await baseAppClient.post(prescriptions.isInOutPatient? GET_PRESCRIPTION_REPORT_ENH : GET_PRESCRIPTION_REPORT, - onSuccess: (dynamic response, int statusCode) { + await baseAppClient.post(prescriptions.isInOutPatient! ? GET_PRESCRIPTION_REPORT_ENH : GET_PRESCRIPTION_REPORT, onSuccess: (dynamic response, int statusCode) { prescriptionReportList.clear(); prescriptionReportEnhList.clear(); - if(prescriptions.isInOutPatient){ + prescriptionReportListINP.clear(); + isMedDeliveryAllowed = response['IsHomeMedicineDeliverySupported']; + if (prescriptions.isInOutPatient!) { response['ListPRM'].forEach((prescriptions) { prescriptionReportList.add(PrescriptionReport.fromJson(prescriptions)); prescriptionReportEnhList.add(PrescriptionReportEnh.fromJson(prescriptions)); }); - }else{ + } else { + prescriptionReportListINP.clear(); response['INP_GetPrescriptionReport_List'].forEach((prescriptions) { - prescriptionReportList.add(PrescriptionReport.fromJson(prescriptions)); + prescriptionReportListINP.add(PrescriptionReportINP.fromJson(prescriptions)); }); } - - }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; }, body: _requestPrescriptionReport.toJson()); } - RequestSendPrescriptionEmail _requestSendPrescriptionEmail = - RequestSendPrescriptionEmail( - isDentalAllowedBackend: false,); + RequestSendPrescriptionEmail _requestSendPrescriptionEmail = RequestSendPrescriptionEmail( + isDentalAllowedBackend: false, + ); - Future sendPrescriptionEmail(String appointmentDate, int patientID, - String clinicName, String doctorName, int projectID) async { + Future sendPrescriptionEmail(String appointmentDate, int patientID, String clinicName, String doctorName, int doctorID, int projectID, bool isInOutPatient, bool isDownload) async { _requestSendPrescriptionEmail.listPrescriptions = prescriptionReportList; + _requestSendPrescriptionEmail.listPrescriptionsINP = prescriptionReportListINP; _requestSendPrescriptionEmail.appointmentDate = appointmentDate; _requestSendPrescriptionEmail.patientID = patientID; _requestSendPrescriptionEmail.clinicName = clinicName; _requestSendPrescriptionEmail.doctorName = doctorName; _requestSendPrescriptionEmail.projectID = projectID; - _requestSendPrescriptionEmail.to = user.emailAddress; - _requestSendPrescriptionEmail.dateofBirth = user.dateofBirth; - _requestSendPrescriptionEmail.patientIditificationNum = user.patientIdentificationNo; - _requestSendPrescriptionEmail.patientMobileNumber = user.mobileNumber; - _requestSendPrescriptionEmail.patientName = user.firstName +" "+ user.lastName; - _requestSendPrescriptionEmail.setupID = user.setupID; + _requestSendPrescriptionEmail.to = user.emailAddress; + _requestSendPrescriptionEmail.dateofBirth = user.dateofBirth; + _requestSendPrescriptionEmail.patientIditificationNum = user.patientIdentificationNo; + _requestSendPrescriptionEmail.patientMobileNumber = user.mobileNumber; + _requestSendPrescriptionEmail.doctorID = doctorID; + _requestSendPrescriptionEmail.patientName = user.firstName! + " " + user.lastName!; + _requestSendPrescriptionEmail.setupID = user.setupID; + _requestSendPrescriptionEmail.to = user.emailAddress; + _requestSendPrescriptionEmail.isDownload = isDownload; hasError = false; - await baseAppClient.post(SEND_PRESCRIPTION_EMAIL, onSuccess: (response, statusCode) {}, - onFailure: (String error, int statusCode) { + await baseAppClient.post(SEND_PRESCRIPTION_EMAIL, onSuccess: (response, statusCode) { + if (isDownload) { + prescriptionReportPDF = response["Base64Data"]; + } + }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; }, body: _requestSendPrescriptionEmail.toJson()); @@ -118,19 +155,24 @@ class PrescriptionsService extends BaseService { latitude: 0, longitude: 0, isDentalAllowedBackend: false, - ); - List pharmacyPrescriptionsList = List(); + List pharmacyPrescriptionsList = []; - Future getListPharmacyForPrescriptions({int itemId}) async { + Future getListPharmacyForPrescriptions({required int itemId}) async { hasError = false; requestGetListPharmacyForPrescriptions.itemID = itemId; - await baseAppClient.post(GET_PHARMACY_LIST, - onSuccess: (dynamic response, int statusCode) { + + requestGetListPharmacyForPrescriptions.latitude = await sharedPref.getDouble(USER_LAT); + requestGetListPharmacyForPrescriptions.longitude = await sharedPref.getDouble(USER_LONG); + + // requestGetListPharmacyForPrescriptions.latitude = 24.709863; + // requestGetListPharmacyForPrescriptions.longitude = 46.668348; + + pharmacyPrescriptionsList.clear(); + await baseAppClient.post(GET_PHARMACY_LIST, onSuccess: (dynamic response, int statusCode) { pharmacyPrescriptionsList.clear(); response['PharmList'].forEach((prescriptions) { - pharmacyPrescriptionsList - .add(PharmacyPrescriptions.fromJson(prescriptions)); + pharmacyPrescriptionsList.add(PharmacyPrescriptions.fromJson(prescriptions)); }); }, onFailure: (String error, int statusCode) { hasError = true; @@ -138,26 +180,24 @@ class PrescriptionsService extends BaseService { }, body: requestGetListPharmacyForPrescriptions.toJson()); } - RequestPrescriptionReportEnh _requestPrescriptionReportEnh = - RequestPrescriptionReportEnh(isDentalAllowedBackend: false,); - - List prescriptionReportEnhList = List(); + RequestPrescriptionReportEnh _requestPrescriptionReportEnh = RequestPrescriptionReportEnh( + isDentalAllowedBackend: false, + ); - Future getPrescriptionReportEnh({PrescriptionsOrder prescriptionsOrder}) async { + List prescriptionReportEnhList = []; - ///This logic copy from the old app from class [order-history.component.ts] in line 45 + Future getPrescriptionReportEnh({required PrescriptionsOrder prescriptionsOrder}) async { bool isInPatient = false; prescriptionsList.forEach((element) { if (prescriptionsOrder.appointmentNo == "0") { if (element.dischargeNo == int.parse(prescriptionsOrder.dischargeID)) { - _requestPrescriptionReportEnh.appointmentNo = element.appointmentNo; _requestPrescriptionReportEnh.clinicID = element.clinicID; _requestPrescriptionReportEnh.projectID = element.projectID; _requestPrescriptionReportEnh.episodeID = element.episodeID; _requestPrescriptionReportEnh.setupID = element.setupID; _requestPrescriptionReportEnh.dischargeNo = element.dischargeNo; - isInPatient = element.isInOutPatient; + isInPatient = element.isInOutPatient!; } } else { if (int.parse(prescriptionsOrder.appointmentNo) == element.appointmentNo) { @@ -167,42 +207,46 @@ class PrescriptionsService extends BaseService { _requestPrescriptionReportEnh.episodeID = element.episodeID; _requestPrescriptionReportEnh.setupID = element.setupID; _requestPrescriptionReportEnh.dischargeNo = element.dischargeNo; - isInPatient = element.isInOutPatient;///call inpGetPrescriptionReport + isInPatient = element.isInOutPatient!; } } }); hasError = false; - await baseAppClient.post(isInPatient? GET_PRESCRIPTION_REPORT_ENH : GET_PRESCRIPTION_REPORT, - onSuccess: (dynamic response, int statusCode) { + await baseAppClient.post(isInPatient ? GET_PRESCRIPTION_REPORT_ENH : GET_PRESCRIPTION_REPORT, onSuccess: (dynamic response, int statusCode) { prescriptionReportEnhList.clear(); - if(isInPatient){ + if (isInPatient) { response['ListPRM'].forEach((prescriptions) { prescriptionReportEnhList.add(PrescriptionReportEnh.fromJson(prescriptions)); }); - }else{ + } else { response['INP_GetPrescriptionReport_List'].forEach((prescriptions) { - - PrescriptionReportEnh reportEnh = PrescriptionReportEnh.fromJson(prescriptions); - reportEnh.itemDescription = prescriptions['ItemDescriptionN']; + PrescriptionReportEnh reportEnh = PrescriptionReportEnh.fromJson(prescriptions); + reportEnh.itemDescription = prescriptions['ItemDescriptionN']; prescriptionReportEnhList.add(reportEnh); - }); - } - - }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; }, body: _requestPrescriptionReportEnh.toJson()); + } - + Future updatePressOrderRC({required int presOrderID}) async { + hasError = false; + Map body = Map(); + body['Id'] = presOrderID; + body['StatusId'] = 6; + body['ClickButton'] = 14; + await baseAppClient.post(UPDATE_PRESCRIPTION_ORDER_RC, onSuccess: (dynamic response, int statusCode) {}, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); } - Future updatePressOrder({@required int presOrderID}) async { + Future updatePressOrder({required int presOrderID}) async { hasError = false; Map body = Map(); body['PresOrderID'] = presOrderID; @@ -210,13 +254,9 @@ class PrescriptionsService extends BaseService { body['RejectionReason'] = ''; body['PresOrderStatus'] = 4; body['isDentalAllowedBackend'] = false; - await baseAppClient.post(UPDATE_PRESS_ORDER, - onSuccess: (dynamic response, int statusCode) { - - }, onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }, body: body); + await baseAppClient.post(UPDATE_PRESS_ORDER, onSuccess: (dynamic response, int statusCode) {}, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); } - } diff --git a/lib/core/service/medical/radiology_service.dart b/lib/core/service/medical/radiology_service.dart index b0b96e71..19bedfce 100644 --- a/lib/core/service/medical/radiology_service.dart +++ b/lib/core/service/medical/radiology_service.dart @@ -2,21 +2,27 @@ import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/core/model/radiology/final_radiology.dart'; import 'package:diplomaticquarterapp/core/model/radiology/request_send_rad_report_email.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; +import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; class RadiologyService extends BaseService { - List finalRadiologyList = List(); + List finalRadiologyList = []; String url = ''; - Future getRadImageURL({int invoiceNo, int lineItem, int projectId}) async { + bool isRadiologyVIDAPlus = false; + + String radReportPDF = ""; + + Future getRadImageURL({int? invoiceNo, String? invoiceType, int? lineItem, int? projectId, bool? isVidaPlus, String? examId}) async { hasError = false; final Map body = new Map(); - body['InvoiceNo'] = invoiceNo; - body['LineIt emNo'] = lineItem; + body['InvoiceNo'] = isVidaPlus! ? "0" : invoiceNo; + body['InvoiceNo_VP'] = isVidaPlus ? invoiceNo : "0"; + body['LineItemNo'] = lineItem; body['ProjectID'] = projectId; + body['InvoiceType'] = invoiceType; + body['ExamId'] = examId; - await baseAppClient.post(GET_RAD_IMAGE_URL, - isAllowAny: true, - onSuccess: (dynamic response, int statusCode) { + await baseAppClient.post(GET_RAD_IMAGE_URL, isAllowAny: true, onSuccess: (dynamic response, int statusCode) { url = response['Data']; }, onFailure: (String error, int statusCode) { hasError = true; @@ -26,12 +32,20 @@ class RadiologyService extends BaseService { Future getPatientRadOrders() async { hasError = false; - await baseAppClient.post(GET_PATIENT_ORDERS, - onSuccess: (dynamic response, int statusCode) { + await baseAppClient.post(GET_PATIENT_ORDERS, onSuccess: (dynamic response, int statusCode) { finalRadiologyList.clear(); - response['FinalRadiologyList'].forEach((radiology) { - finalRadiologyList.add(FinalRadiology.fromJson(radiology)); - }); + // response['FinalRadiologyList'].forEach((radiology) { + if (response['FinalRadiologyList'] != null && response['FinalRadiologyList'].length != 0) { + isRadiologyVIDAPlus = false; + response['FinalRadiologyList'].forEach((radiology) { + finalRadiologyList.add(FinalRadiology.fromJson(radiology)); + }); + } else { + isRadiologyVIDAPlus = true; + response['FinalRadiologyListAPI'].forEach((radiology) { + finalRadiologyList.add(FinalRadiology.fromJson(radiology)); + }); + } }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; @@ -40,8 +54,7 @@ class RadiologyService extends BaseService { Future getPatientRadOrdersDetails() async { hasError = false; - await baseAppClient.post(GET_PATIENT_ORDERS, - onSuccess: (dynamic response, int statusCode) { + await baseAppClient.post(GET_PATIENT_ORDERS, onSuccess: (dynamic response, int statusCode) { finalRadiologyList.clear(); response['FinalRadiologyList'].forEach((radiology) { finalRadiologyList.add(FinalRadiology.fromJson(radiology)); @@ -52,29 +65,33 @@ class RadiologyService extends BaseService { }, body: Map()); } - RequestSendRadReportEmail _requestSendRadReportEmail = - RequestSendRadReportEmail(); + RequestSendRadReportEmail _requestSendRadReportEmail = RequestSendRadReportEmail(); - Future sendRadReportEmail({FinalRadiology finalRadiology}) async { - _requestSendRadReportEmail.projectID = finalRadiology.projectID; + Future sendRadReportEmail({FinalRadiology? finalRadiology, AuthenticatedUser? userObj, required bool isDownload}) async { + _requestSendRadReportEmail.projectID = finalRadiology!.projectID; _requestSendRadReportEmail.clinicName = finalRadiology.clinicDescription; _requestSendRadReportEmail.invoiceNo = finalRadiology.invoiceNo; + _requestSendRadReportEmail.invoiceNo_VP = finalRadiology.invoiceNo_VP; + _requestSendRadReportEmail.invoiceLineItemNo = finalRadiology.invoiceLineItemNo; _requestSendRadReportEmail.setupID = finalRadiology.setupID; _requestSendRadReportEmail.doctorName = finalRadiology.doctorName; - _requestSendRadReportEmail.orderDate = '${finalRadiology.orderDate.year}-${finalRadiology.orderDate.month}-${finalRadiology.orderDate.day}'; - _requestSendRadReportEmail.patientIditificationNum = user.patientIdentificationNo; - _requestSendRadReportEmail.patientMobileNumber = user.mobileNumber; - _requestSendRadReportEmail.patientName = user.firstName + " " + user.lastName; - _requestSendRadReportEmail.patientIditificationNum = user.patientIdentificationNo; + _requestSendRadReportEmail.orderDate = '${finalRadiology.orderDate!.year}-${finalRadiology.orderDate!.month}-${finalRadiology.orderDate!.day}'; + _requestSendRadReportEmail.patientIditificationNum = userObj!.patientIdentificationNo; + _requestSendRadReportEmail.patientMobileNumber = userObj.mobileNumber; + _requestSendRadReportEmail.patientName = userObj.firstName! + " " + userObj.lastName!; _requestSendRadReportEmail.projectName = finalRadiology.projectName; _requestSendRadReportEmail.radResult = finalRadiology.reportData; - _requestSendRadReportEmail.to = user.emailAddress; - _requestSendRadReportEmail.dateofBirth = user.dateofBirth; + _requestSendRadReportEmail.to = userObj.emailAddress; + _requestSendRadReportEmail.dateofBirth = userObj.dateofBirth; + _requestSendRadReportEmail.invoiceType = finalRadiology.invoiceType; + _requestSendRadReportEmail.isDownload = isDownload; hasError = false; - await baseAppClient.post(SEND_RAD_REPORT_EMAIL, - isAllowAny: true, onSuccess: (dynamic response, int statusCode) {}, - onFailure: (String error, int statusCode) { + await baseAppClient.post(SEND_RAD_REPORT_EMAIL, isAllowAny: true, onSuccess: (dynamic response, int statusCode) { + if(isDownload) { + radReportPDF = response["Base64Data"]; + } + }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; }, body: _requestSendRadReportEmail.toJson()); diff --git a/lib/core/service/medical/reports_monthly_service.dart b/lib/core/service/medical/reports_monthly_service.dart index 479360ac..280a2246 100644 --- a/lib/core/service/medical/reports_monthly_service.dart +++ b/lib/core/service/medical/reports_monthly_service.dart @@ -5,8 +5,8 @@ import 'package:diplomaticquarterapp/core/service/base_service.dart'; import 'package:diplomaticquarterapp/pages/feedback/appointment_history.dart'; class ReportsMonthlyService extends BaseService { - List reportsList = List(); - List appointHistoryList = List(); + List reportsList =[]; + List appointHistoryList =[]; RequestReports _requestReports = RequestReports( isReport: true, diff --git a/lib/core/service/medical/reports_service.dart b/lib/core/service/medical/reports_service.dart index bf340814..bd0b2027 100644 --- a/lib/core/service/medical/reports_service.dart +++ b/lib/core/service/medical/reports_service.dart @@ -1,24 +1,23 @@ import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/core/model/reports/Reports.dart'; +import 'package:diplomaticquarterapp/core/model/reports/admission_for_medical_report.dart'; import 'package:diplomaticquarterapp/core/model/reports/request_reports.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; import 'package:diplomaticquarterapp/pages/feedback/appointment_history.dart'; class ReportsService extends BaseService { - List reportsList = List(); - List appointHistoryList = List(); + List reportsList = []; + List inpatientReportsList =[]; + List appointHistoryList =[]; + + List admissionsMedicalReport = []; + String userAgreementContent = ""; - RequestReports _requestReports = RequestReports( - isReport: true, - encounterType: 1, - requestType: 1, - patientOutSA: 0, - ); + RequestReports _requestReports = RequestReports(isReport: true, encounterType: 1, requestType: 1, projectID: 0); Future getReports() async { hasError = false; - await baseAppClient.post(REPORTS, - onSuccess: (dynamic response, int statusCode) { + await baseAppClient.post(REPORTS, onSuccess: (dynamic response, int statusCode) { reportsList.clear(); response['GetPatientMedicalStatus'].forEach((reports) { reportsList.add(Reports.fromJson(reports)); @@ -29,12 +28,42 @@ class ReportsService extends BaseService { }, body: _requestReports.toJson()); } + Future getInPatientReports() async { + RequestReports _requestReportsInpatient = RequestReports(isReport: true, encounterType: 2, requestType: 1, patientOutSA: 0, projectID: 0); + hasError = false; + await baseAppClient.post(REPORTS, onSuccess: (dynamic response, int statusCode) { + inpatientReportsList.clear(); + response['GetPatientMedicalStatus'].forEach((reports) { + inpatientReportsList.add(Reports.fromJson(reports)); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: _requestReportsInpatient.toJson()); + } + + Future getInpatientAdmissionsList(int languageID) async { + Map body = new Map(); + body['IsForMedicalReport'] = true; + body['LanguageID'] = languageID; + hasError = false; + await baseAppClient.post(GET_INPATIENT_ADMISSIONS, onSuccess: (dynamic response, int statusCode) { + admissionsMedicalReport.clear(); + print(response['AdmissionsForMedicalReport']); + response['AdmissionsForMedicalReport'].forEach((reports) { + admissionsMedicalReport.add(AdmissionMedicalReport.fromJson(reports)); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } + Future getPatentAppointmentHistory() async { hasError = false; Map body = new Map(); body['IsForMedicalReport'] = true; - await baseAppClient.post(GET_PATIENT_AppointmentHistory, - onSuccess: (dynamic response, int statusCode) { + await baseAppClient.post(GET_PATIENT_AppointmentHistory, onSuccess: (dynamic response, int statusCode) { appointHistoryList = []; response['AppoimentAllHistoryResultList'].forEach((appoint) { appointHistoryList.add(AppointmentHistory.fromJson(appoint)); @@ -47,8 +76,7 @@ class ReportsService extends BaseService { Future getUserTermsAndConditions() async { hasError = false; - await baseAppClient.post(GET_USER_TERMS, - onSuccess: (dynamic response, int statusCode) { + await baseAppClient.post(GET_USER_TERMS, onSuccess: (dynamic response, int statusCode) { userAgreementContent = response['UserAgreementContent']; }, onFailure: (String error, int statusCode) { hasError = true; @@ -56,33 +84,28 @@ class ReportsService extends BaseService { }, body: Map()); } - Future updatePatientHealthSummaryReport({bool isSummary}) async { + Future updatePatientHealthSummaryReport({required bool isSummary}) async { Map body = Map(); body['RSummaryReport'] = isSummary; hasError = false; - await baseAppClient.post(UPDATE_HEALTH_TERMS, - onSuccess: (dynamic response, int statusCode) {}, - onFailure: (String error, int statusCode) { + await baseAppClient.post(UPDATE_HEALTH_TERMS, onSuccess: (dynamic response, int statusCode) {}, onFailure: (String error, int statusCode) { hasError = true; super.error = error; }, body: body); } - Future updateEmail({String email}) async { + Future updateEmail({required String email}) async { Map body = Map(); body['EmailAddress'] = email; body['isDentalAllowedBackend'] = false; hasError = false; - await baseAppClient.post(UPDATE_PATENT_EMAIL, - onSuccess: (dynamic response, int statusCode) {}, - onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }, body: body); + await baseAppClient.post(UPDATE_PATENT_EMAIL, onSuccess: (dynamic response, int statusCode) {}, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); } - Future insertRequestForMedicalReport( - AppointmentHistory appointmentHistory) async { + Future insertRequestForMedicalReport(AppointmentHistory appointmentHistory) async { Map body = new Map(); body['ClinicID'] = appointmentHistory.clinicID; body['DoctorID'] = appointmentHistory.doctorID; @@ -98,23 +121,35 @@ class ReportsService extends BaseService { body['Status'] = 1; body['CreatedBy'] = 102; hasError = false; - await baseAppClient.post(INSERT_REQUEST_FOR_MEDICAL_REPORT, - onSuccess: (dynamic response, int statusCode) {}, - onFailure: (String error, int statusCode) { + await baseAppClient.post(INSERT_REQUEST_FOR_MEDICAL_REPORT, onSuccess: (dynamic response, int statusCode) {}, onFailure: (String error, int statusCode) { hasError = true; super.error = error; }, body: body); } - Future sendEmailForMedicalReport( - String projectName, - String clinicName, - String doctorName, - String requestDate, - String invoiceNo, - int projectID, - String stamp, - String setupID) async { + Future insertRequestForInPatientMedicalReport(int clinicID, int doctorID, String setupID, int admissionNo, int projectID) async { + Map body = new Map(); + body['ClinicID'] = clinicID; + body['DoctorID'] = doctorID; + body['SetupID'] = setupID; + body['EncounterNo'] = admissionNo; + body['EncounterType'] = 2; // appointmentHistory.appointmentType; + body['IsActive'] = true; + body['ProjectID'] = projectID; + body['Remarks'] = ""; + body['ProcedureId'] = ""; + body['RequestType'] = 1; + body['Source'] = 2; + body['Status'] = 1; + body['CreatedBy'] = 102; + hasError = false; + await baseAppClient.post(INSERT_REQUEST_FOR_MEDICAL_REPORT, onSuccess: (dynamic response, int statusCode) {}, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } + + Future sendEmailForMedicalReport(String projectName, String clinicName, String doctorName, String requestDate, String invoiceNo, int projectID, String stamp, String setupID) async { Map body = new Map(); body['SetupID'] = setupID; body['PrintDate'] = requestDate; @@ -125,21 +160,50 @@ class ReportsService extends BaseService { body['DateofBirth'] = user.dateofBirth; body['PatientIditificationNum'] = user.patientIdentificationNo; body['PatientMobileNumber'] = user.mobileNumber; - body['PatientName'] = user.firstName + " " + user.lastName; + body['PatientName'] = user.firstName! + " " + user.lastName!; body['ProjectName'] = projectName; body['ClinicName'] = clinicName; body['ProjectID'] = projectID; body['InvoiceNo'] = invoiceNo; - body['PrintedByName'] = user.firstName + " " + user.lastName; + body['PrintedByName'] = user.firstName! + " " + user.lastName!; dynamic response; hasError = false; - await baseAppClient.post(SEND_MEDICAL_REPORT_EMAIL, - onSuccess: (dynamic res, int statusCode) { - response = res; - }, - onFailure: (String error, int statusCode) { + await baseAppClient.post(SEND_MEDICAL_REPORT_EMAIL, onSuccess: (dynamic res, int statusCode) { + response = res; + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + return response; + } + + Future getMedicalReportPDF(String projectName, String clinicName, String doctorName, String requestDate, String invoiceNo, int projectID, String stamp, String setupID) async { + Map body = new Map(); + body['SetupID'] = setupID; + body['PrintDate'] = requestDate; + body['ProcedureID'] = "05005009"; + body['Reporttype'] = "MEDICAL REPORT"; + body['stamp'] = stamp; + body['To'] = user.emailAddress; + body['DateofBirth'] = user.dateofBirth; + body['PatientIditificationNum'] = user.patientIdentificationNo; + body['PatientMobileNumber'] = user.mobileNumber; + body['PatientName'] = user.firstName! + " " + user.lastName!; + body['ProjectName'] = projectName; + body['ClinicName'] = clinicName; + body['ProjectID'] = projectID; + body['InvoiceNo'] = invoiceNo; + body['InvoiceNo_VP'] = invoiceNo; + body['PrintedByName'] = user.firstName! + " " + user.lastName!; + + dynamic response; + + hasError = false; + await baseAppClient.post(GET_MEDICAL_REPORT_PDF, onSuccess: (dynamic res, int statusCode) { + response = res; + }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; }, body: body); diff --git a/lib/core/service/medical/vital_sign_service.dart b/lib/core/service/medical/vital_sign_service.dart index d1fbbf1c..054843de 100644 --- a/lib/core/service/medical/vital_sign_service.dart +++ b/lib/core/service/medical/vital_sign_service.dart @@ -4,13 +4,13 @@ import 'package:diplomaticquarterapp/core/model/vital_sign/vital_sign_res_model. import '../base_service.dart'; class VitalSignService extends BaseService { - List vitalSignResModelList = List(); + List vitalSignResModelList =[]; String weightKg = ""; String heightCm = ""; String bloadType = ""; - Future getPatientRadOrders({int appointmentNo, int projectID}) async { + Future getPatientRadOrders({ int? appointmentNo, int? projectID}) async { hasError = false; Map body = Map(); if (appointmentNo != null && projectID != null) { diff --git a/lib/core/service/notifications_service.dart b/lib/core/service/notifications_service.dart index f2cac55e..ad6cbce1 100644 --- a/lib/core/service/notifications_service.dart +++ b/lib/core/service/notifications_service.dart @@ -5,7 +5,7 @@ import 'package:diplomaticquarterapp/core/model/notifications/mark_message_as_re import 'package:diplomaticquarterapp/core/service/base_service.dart'; class NotificationService extends BaseService { - List notificationsList = List(); + List notificationsList =[]; Future getAllNotifications(GetNotificationsRequestModel getNotificationsRequestModel ) async { hasError = false; diff --git a/lib/core/service/offers_service.dart b/lib/core/service/offers_service.dart index 8007007b..19b68707 100644 --- a/lib/core/service/offers_service.dart +++ b/lib/core/service/offers_service.dart @@ -5,9 +5,9 @@ import 'package:diplomaticquarterapp/core/model/pharmacy/offers_model.dart'; import 'base_service.dart'; class OffersCategoriseService extends BaseService { - List _offersList = List(); + List _offersList =[]; List get offersList => _offersList; - List _offerProducts = List(); + List _offerProducts =[]; List get offersProducts => _offerProducts; clearCategorise() { @@ -35,7 +35,7 @@ class OffersCategoriseService extends BaseService { ); } - Future getOffersProducts({String id}) async { + Future getOffersProducts({required String id}) async { hasError = false; _offerProducts.clear(); String endPoint = diff --git a/lib/core/service/packages_offers/PackagesOffersServices.dart b/lib/core/service/packages_offers/PackagesOffersServices.dart index 15811b82..5ee27ad1 100644 --- a/lib/core/service/packages_offers/PackagesOffersServices.dart +++ b/lib/core/service/packages_offers/PackagesOffersServices.dart @@ -1,80 +1,118 @@ import 'dart:convert'; import 'dart:developer'; -import 'dart:ui'; import 'package:diplomaticquarterapp/config/config.dart'; -import 'package:diplomaticquarterapp/core/enum/PaymentOptions.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/ResponseModel.dart'; +import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/requests/AddProductToCartRequestModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/requests/CreateCustomerRequestModel.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/PackagesCartItemsResponseModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCategoriesResponseModel.dart'; -import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart'; 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/offers_stores_response_model.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/service/client/base_app_client.dart'; +import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:flutter/cupertino.dart'; -import '../../../locator.dart'; +Map packagesAuthHeader = {}; class OffersAndPackagesServices extends BaseService { - List categoryList = List(); - List productList = List(); - List latestOffersList = List(); - List bestSellerList = List(); - List bannersList = List(); - List cartItemList = List(); + AuthenticatedUser? patientUser; + List categoryList = []; + List projectsList = []; + List productList = []; + List latestOffersList = []; + List tamaraPaymentOptions = []; + List bestSellerList = []; + List bannersList = []; + List ordersHistory = []; + List cartItemList = []; + List _hospitals = []; + + List get hospitals => _hospitals; String cartItemCount = ""; - PackagesCustomerResponseModel customer; + PackagesCustomerResponseModel? customer; Future> getAllCategories(OffersCategoriesRequestModel request) async { - Future errorThrow; + if (categoryList.isNotEmpty) return categoryList; 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) { categoryList.add(PackagesCategoriesResponseModel().fromJson(json)); }); } - }, onFailure: (String error, int statusCode) { - log(error); - }, queryParams: request.toFlatMap()); + }, onFailure: (String error, int statusCode) {}, queryParams: request.toFlatMap()); return categoryList; } - Future> getAllProducts({@required OffersProductsRequestModel request, @required BuildContext context, @required bool showLoading = true}) async { - Future errorThrow; + Future> getAllStores() async { + if (projectsList.isNotEmpty) return projectsList; + + var url = EXA_CART_API_BASE_URL + PACKAGES_STORES; + await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) { + if (statusCode == 200) { + var jsonResponse = json.decode(stringResponse); + final response = OfferProjectsResponseModel.fromJson(jsonResponse); + projectsList = response.project!; + } + }, onFailure: (String error, int statusCode) { + throw error; + }, queryParams: {'fields': 'id,name'}); - request.sinceId = (productList.isNotEmpty) ? productList.last.id : 0; - - productList = List(); + return projectsList; + } + + Future> getAllProducts({required OffersProductsRequestModel request, BuildContext? context, bool showLoading = true, bool byOffset = true}) async { + Future errorThrow; + productList = []; 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) { productList.add(PackagesResponseModel().fromJson(json)); }); } - }, onFailure: (String error, int statusCode) { - log(error); - }, queryParams: request.toFlatMap()); + }, onFailure: (String error, int statusCode) {}, queryParams: request.toFlatMap()); return productList; } - Future> getLatestOffers({@required OffersProductsRequestModel request, @required BuildContext context, @required bool showLoading = true}) async { + Future> getTamaraOptions({required BuildContext context, bool showLoading = true}) async { + if (tamaraPaymentOptions != null && tamaraPaymentOptions.isNotEmpty) return tamaraPaymentOptions; + tamaraPaymentOptions.clear(); + 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, 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) { + latestOffersList.clear(); if (statusCode == 200) { var jsonResponse = json.decode(stringResponse); jsonResponse['products'].forEach((json) { @@ -88,10 +126,10 @@ class OffersAndPackagesServices extends BaseService { return latestOffersList; } - Future> getBestSellers({@required OffersProductsRequestModel request, @required BuildContext context, @required bool showLoading = true}) async { - + Future> getBestSellers({required OffersProductsRequestModel request, required BuildContext context, 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) { + bestSellerList.clear(); if (statusCode == 200) { var jsonResponse = json.decode(stringResponse); jsonResponse['products'].forEach((json) { @@ -105,10 +143,9 @@ class OffersAndPackagesServices extends BaseService { return bestSellerList; } - - Future> getBanners({@required OffersProductsRequestModel request, @required BuildContext context, @required bool showLoading = true}) async { + Future> getBanners({required OffersProductsRequestModel request, required BuildContext context, 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) { @@ -122,14 +159,13 @@ class OffersAndPackagesServices extends BaseService { return bannersList; } - Future loadOffersPackagesDataForMainPage({@required BuildContext context, bool showLoading = true, Function completion }) async { + Future loadOffersPackagesDataForMainPage({required BuildContext context, bool showLoading = true, required Function completion}) async { var finished = 0; - var totalCalls = 3; - - completedAll(){ + var totalCalls = 2; + completedAll() { finished++; - if(completion != null && finished == totalCalls) { + if (completion != null && finished == totalCalls) { _hideLoading(context, showLoading); completion(); } @@ -137,209 +173,275 @@ class OffersAndPackagesServices extends BaseService { _showLoading(context, showLoading); + 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); + } + } + // Performing Parallel Request on same time // # 1 - getBestSellers(request: OffersProductsRequestModel(), context: context, showLoading: false).then((value){ - completedAll(); + getBestSellers(request: OffersProductsRequestModel(), context: context, showLoading: false).then((value) { + completedAll(); }); // # 2 - getLatestOffers(request: OffersProductsRequestModel(), context: context, showLoading: false).then((value){ + getLatestOffers(request: OffersProductsRequestModel(), context: context, showLoading: false).then((value) { completedAll(); }); // # 3 - getBanners(request: OffersProductsRequestModel(), context: context, showLoading: false).then((value){ - completedAll(); - }); - + // getBanners( + // request: OffersProductsRequestModel(), + // context: context, + // showLoading: false) + // .then((value) { + // completedAll(); + // }); } // -------------------- // Create Customer // -------------------- - Future createCustomer(PackagesCustomerRequestModel request, {@required BuildContext context, bool showLoading = true, Function(bool) completion }) async{ - if(customer != null) - return Future.value(customer); + Future createCustomer(PackagesCustomerRequestModel request, {required BuildContext context, bool showLoading = true, Function(bool)? completion}) async { + if (customer != null) return Future.value(customer); customer = null; - Future errorThrow; + Future? errorThrow; _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); + }, onFailure: (String error, int statusCode) { 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!; + } // -------------------- // 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}'; - await baseAppClient.simpleGet(url, onSuccess: (dynamic stringResponse, int statusCode) { + 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)); }); - + return jsonResponse; }, onFailure: (String error, int statusCode) { _hideLoading(context, showLoading); log(error); - errorThrow = Future.error({"error":error, "statusCode":statusCode}); - }, queryParams: null); - - return errorThrow ?? cartItemList; + errorThrow = Future.error({"error": error, "statusCode": statusCode}); + return errorThrow; + }, queryParams: Map()); } - Future> addProductToCart(AddProductToCartRequestModel request, {@required BuildContext context, bool showLoading = true}) async{ + Future?> addProductToCart(AddProductToCartRequestModel request, {required BuildContext context, bool showLoading = true}) async { Future errorThrow; ResponseModel response; - request.customer_id = customer.id; + request.customer_id = customer!.id; _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); var jsonCartItem = jsonResponse["shopping_carts"][0]; response = ResponseModel(status: true, data: PackagesCartItemsResponseModel.fromJson(jsonCartItem), error: null); - cartItemCount = response.data.quantity.toString(); - - }, onFailure: (String error, int statusCode){ + cartItemCount = (jsonResponse['count'] ?? 0).toString(); + return response; + }, onFailure: (String error, int statusCode) { _hideLoading(context, showLoading); errorThrow = Future.error(ResponseModel(status: true, data: null, error: error)); + return errorThrow; }); - - return errorThrow ?? response; } - Future updateProductToCart(int cartItemID, {UpdateProductToCartRequestModel request, @required BuildContext context, bool showLoading = true}) async{ + Future updateProductToCart(int cartItemID, {UpdateProductToCartRequestModel? request, required BuildContext context, bool showLoading = true}) async { Future errorThrow; _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); - - }, onFailure: (String error, int statusCode){ + return jsonResponse; + }, onFailure: (String error, int statusCode) { _hideLoading(context, showLoading); log(error); - errorThrow = Future.error({"error":error, "statusCode":statusCode}); + errorThrow = Future.error({"error": error, "statusCode": statusCode}); + return errorThrow; }); - - return errorThrow ?? bannersList; } - - Future deleteProductFromCart(int cartItemID, {@required BuildContext context, bool showLoading = true}) async{ + Future deleteProductFromCart(int cartItemID, {required BuildContext context, bool showLoading = true}) async { Future errorThrow; _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); - - }, onFailure: (String error, int statusCode){ + return true; + }, onFailure: (String error, int statusCode) { _hideLoading(context, showLoading); log(error); - errorThrow = Future.error({"error":error, "statusCode":statusCode}); + errorThrow = Future.error({"error": error, "statusCode": statusCode}); + return errorThrow; }); - - return errorThrow ?? true; } // -------------------- // Place Order // -------------------- - Future placeOrder({@required String paymentOption, @required BuildContext context, bool showLoading = true}) async{ + Future placeOrder({required Map paymentParams, required int projectID, required BuildContext context, bool showLoading = true}) async { Future errorThrow; - var jsonBody = { - "order": { - "customer_id" : customer.id, - "billing_address": { - "email": customer.email, - "phone_number": customer.addresses.first.phoneNumber - }, - "payment_method_system_name": "Payments.PayFort", - "payment_option": paymentOption - } + Map jsonBody = { + "customer_id": customer!.id, + "project_id": projectID, + "billing_address": {"email": patientUser!.emailAddress, "phone_number": patientUser!.mobileNumber}, }; + jsonBody.addAll(paymentParams); + jsonBody = {'order': jsonBody}; + + print(jsonBody); 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); order_id = jsonResponse['orders'][0]['id']; - - }, onFailure: (String error, int statusCode){ + return order_id; + }, onFailure: (String error, int statusCode) { _hideLoading(context, showLoading); log(error); errorThrow = Future.error(error); + return errorThrow; }); + } + + // -------------------- + // Order History + // -------------------- + Future?> orderHistory({required BuildContext context, bool showLoading = true}) async { + // if(ordersHistory.isNotEmpty) + // return ordersHistory; - return errorThrow ?? order_id; + Future errorThrow; + // https://mdlaboratories.com/offersdiscounts/api/orders/items/0535256053?fields=id,product,utilize_by_vida,valid_until_date_utc,order_id&page=1&limit=100 + Map queryParams = {}; + queryParams['fields'] = 'id,product,utilize_by_vida,valid_until_date_utc,order_id'; + queryParams['page'] = "1"; + queryParams['limit'] = "100"; + print(queryParams); + + _showLoading(context, showLoading); + var url = EXA_CART_API_BASE_URL + PACKAGES_ORDER_HISTORY + "/${user.mobileNumber}"; + + await baseAppClient.simpleGet(url, headers: packagesAuthHeader, queryParams: queryParams, onSuccess: (dynamic stringResponse, int statusCode) { + _hideLoading(context, showLoading); + var jsonResponse = json.decode(stringResponse); + final order_items = jsonResponse["order_items"] as List; + ordersHistory = order_items.map((e) => PackagesResponseModel().fromJson(e['product'])).toList(); + print(ordersHistory); + return ordersHistory; + }, onFailure: (String error, int statusCode) { + _hideLoading(context, showLoading); + log(error); + errorThrow = Future.error(error); + return errorThrow; + }); } - Future> getOrderById(int id, {@required BuildContext context, bool showLoading = true}) async{ + Future?> getOrderById(int id, {required BuildContext context, bool showLoading = true}) async { Future errorThrow; ResponseModel response; _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); var jsonOrder = jsonResponse['orders'][0]; response = ResponseModel(status: true, data: PackagesOrderResponseModel.fromJson(jsonOrder)); - + return response; }, onFailure: (String error, int statusCode) { _hideLoading(context, showLoading); - errorThrow = Future.error(ResponseModel(status: false,error: error)); - }, queryParams: null); - - return errorThrow ?? response; + errorThrow = Future.error(ResponseModel(status: false, error: error)); + return errorThrow; + }, queryParams: Map()); } + Future getHospitals({bool isResBasedOnLoc = true}) async { + Map body = Map(); + body['Latitude'] = await this.sharedPref.getDouble(USER_LAT); + body['Longitude'] = await this.sharedPref.getDouble(USER_LONG); + body['IsOnlineCheckIn'] = isResBasedOnLoc; + body['PatientOutSA'] = 0; + + await baseAppClient.post(GET_PROJECT, onSuccess: (dynamic response, int statusCode) { + _hospitals.clear(); + response['ListProject'].forEach((hospital) { + _hospitals.add(HospitalsModel.fromJson(hospital)); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } } -_showLoading(BuildContext context, bool flag){ - if(flag) - GifLoaderDialogUtils.showMyDialog(context); +_showLoading(BuildContext context, bool flag) { + if (flag) GifLoaderDialogUtils.showMyDialog(context); } -_hideLoading(BuildContext context, bool flag){ - if(flag) - GifLoaderDialogUtils.hideDialog(context); -} \ No newline at end of file +_hideLoading(BuildContext context, bool flag) { + if (flag) GifLoaderDialogUtils.hideDialog(context); +} diff --git a/lib/core/service/parmacyModule/lacum-registration-service.dart b/lib/core/service/parmacyModule/lacum-registration-service.dart index b3e64e69..8686a9e6 100644 --- a/lib/core/service/parmacyModule/lacum-registration-service.dart +++ b/lib/core/service/parmacyModule/lacum-registration-service.dart @@ -6,7 +6,7 @@ import 'lacum-service.dart'; class LacumRegistrationService extends LacumService{ - ListUserAgreement listUserAgreement; + ListUserAgreement? listUserAgreement; Future getLacumAccountInformationById(String patientIdentificationNo) async { hasError = false; diff --git a/lib/core/service/parmacyModule/lacum-service.dart b/lib/core/service/parmacyModule/lacum-service.dart index c7117303..980ed030 100644 --- a/lib/core/service/parmacyModule/lacum-service.dart +++ b/lib/core/service/parmacyModule/lacum-service.dart @@ -9,15 +9,15 @@ class LacumService extends BaseService{ String errorMsg = ''; String successMsg = ''; - LacumAccountInformation lacumInformation; - LacumAccountInformation lacumGroupInformation; + LacumAccountInformation? lacumInformation; + LacumAccountInformation? lacumGroupInformation; - Future getLacumAccountInformation() async { + Future getLacumAccountInformation(String identificationNo) async { hasError = false; super.error = ""; Map body = Map(); - body['IdentificationNo'] = user.patientIdentificationNo; + body['IdentificationNo'] = identificationNo; try { await baseAppClient.post(GET_LACUM_ACCOUNT_INFORMATION, @@ -32,13 +32,13 @@ class LacumService extends BaseService{ } } - Future getLacumGroupInformation() async { + Future getLacumGroupInformation(String identificationNo) async { hasError = false; super.error = ""; Map body = Map(); - body['IdentificationNo'] = user.patientIdentificationNo; - body['AccountNumber'] = "${lacumInformation.yahalaAccountNo}"; + body['IdentificationNo'] = identificationNo; + body['AccountNumber'] = "${lacumInformation!.yahalaAccountNo}"; body['IsDetailsRequired'] = true; try { @@ -57,7 +57,7 @@ class LacumService extends BaseService{ Future makeAccountActivate() async { hasError = false; super.error = ""; - int yahalaAccountNo = lacumInformation.yahalaAccountNo; + int? yahalaAccountNo = lacumInformation?.yahalaAccountNo; Map body = Map(); body['CreatedBy'] = 103; @@ -80,7 +80,7 @@ class LacumService extends BaseService{ Future makeAccountDeactivate() async { hasError = false; super.error = ""; - int yahalaAccountNo = lacumInformation.yahalaAccountNo; + int? yahalaAccountNo = lacumInformation?.yahalaAccountNo; Map body = Map(); body['CreatedBy'] = 103; @@ -121,7 +121,7 @@ class LacumService extends BaseService{ try { await baseAppClient.post(CREATE_LAKUM_ACCOUNT, onSuccess: (response, statusCode) async { - successMsg = LacumAccountInformation.fromJson(response).message; + successMsg = LacumAccountInformation.fromJson(response).message!; }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; diff --git a/lib/core/service/parmacyModule/lacum-transfer-service.dart b/lib/core/service/parmacyModule/lacum-transfer-service.dart index b15696f9..c66f5efe 100644 --- a/lib/core/service/parmacyModule/lacum-transfer-service.dart +++ b/lib/core/service/parmacyModule/lacum-transfer-service.dart @@ -4,7 +4,8 @@ import 'package:diplomaticquarterapp/core/model/pharmacies/LacumAccountInformati import 'lacum-service.dart'; class LacumTransferService extends LacumService{ - LacumAccountInformation lacumReceiverInformation; + + LacumAccountInformation ?lacumReceiverInformation; Future getLacumGroupDataBuAccountId(String accountId) async { hasError = false; @@ -33,14 +34,14 @@ class LacumTransferService extends LacumService{ super.error = ""; Map body = Map(); - body['MobileNo'] = lacumGroupInformation.lakumInquiryInformationObjVersion.mobileNumber; - body['UserName'] = lacumGroupInformation.lakumInquiryInformationObjVersion.memberName; - body['YaHalaSenderAccNumber'] = lacumGroupInformation.lakumInquiryInformationObjVersion.accountNumber; - body['Yahala_IdentificationNo'] = lacumGroupInformation.lakumInquiryInformationObjVersion.memberUniversalId; + body['MobileNo'] = lacumGroupInformation!.lakumInquiryInformationObjVersion!.mobileNumber; + body['UserName'] = lacumGroupInformation!.lakumInquiryInformationObjVersion!.memberName; + body['YaHalaSenderAccNumber'] = lacumGroupInformation!.lakumInquiryInformationObjVersion!.accountNumber; + body['Yahala_IdentificationNo'] = lacumGroupInformation!.lakumInquiryInformationObjVersion!.memberUniversalId; body['YaHalaPointsToTransfer'] = points; - body['YaHalaReceiverAccNumber'] = lacumReceiverInformation.lakumInquiryInformationObjVersion.accountNumber; - body['YaHalaReceiverMobileNumber'] = lacumReceiverInformation.lakumInquiryInformationObjVersion.mobileNumber; - body['YaHalaReceiverName'] = lacumReceiverInformation.lakumInquiryInformationObjVersion.memberName; + body['YaHalaReceiverAccNumber'] = lacumReceiverInformation!.lakumInquiryInformationObjVersion!.accountNumber; + body['YaHalaReceiverMobileNumber'] = lacumReceiverInformation!.lakumInquiryInformationObjVersion!.mobileNumber; + body['YaHalaReceiverName'] = lacumReceiverInformation!.lakumInquiryInformationObjVersion!.memberName; try { await baseAppClient.post(TRANSFER_YAHALA_LOYALITY_POINTS, diff --git a/lib/core/service/parmacyModule/order-preview-service.dart b/lib/core/service/parmacyModule/order-preview-service.dart index 0ada84e7..f205e61b 100644 --- a/lib/core/service/parmacyModule/order-preview-service.dart +++ b/lib/core/service/parmacyModule/order-preview-service.dart @@ -7,7 +7,6 @@ import 'package:diplomaticquarterapp/core/model/pharmacies/order_detail.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/payment-checkout-data.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/OrderPreviewViewModel.dart'; -import 'package:flutter/cupertino.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; class OrderPreviewService extends BaseService { @@ -15,18 +14,18 @@ class OrderPreviewService extends BaseService { bool hasError = false; String errorMsg = ''; - List addresses = List(); - LacumAccountInformation lacumInformation; - LacumAccountInformation lacumGroupInformation; - List orderList = List(); + List addresses = []; + LacumAccountInformation? lacumInformation; + LacumAccountInformation? lacumGroupInformation; + List orderList = []; Future getAddresses() async { var customerId = await sharedPref.getString(PHARMACY_CUSTOMER_ID); + var customerGUID = await sharedPref.getString(PHARMACY_CUSTOMER_GUID); Map queryParams = {'fields': 'addresses'}; hasError = false; try { - await baseAppClient.getPharmacy("$GET_CUSTOMERS_ADDRESSES$customerId", - onSuccess: (dynamic response, int statusCode) { + await baseAppClient.getPharmacy("$GET_CUSTOMERS_ADDRESSES$customerId/$customerGUID", onSuccess: (dynamic response, int statusCode) { addresses.clear(); response['customers'][0]['addresses'].forEach((item) { addresses.add(Addresses.fromJson(item)); @@ -46,9 +45,7 @@ class OrderPreviewService extends BaseService { dynamic localRes; hasError = false; try { - await baseAppClient - .getPharmacy("$GET_SHIPPING_OPTIONS$customerId/${selectedAddress.id}", - onSuccess: (dynamic response, int statusCode) { + await baseAppClient.getPharmacy("$GET_SHIPPING_OPTIONS$customerId/${selectedAddress.id}", onSuccess: (dynamic response, int statusCode) { localRes = response['shipping_option'][0]; }, onFailure: (String error, int statusCode) { hasError = true; @@ -62,12 +59,15 @@ class OrderPreviewService extends BaseService { Future getShoppingCart() async { var customerId = await sharedPref.getString(PHARMACY_CUSTOMER_ID); + var customerGUID = await sharedPref.getObject(PHARMACY_CUSTOMER_GUID); + + if (customerId == null) return Map(); + Map queryParams = {'shopping_cart_type': '1'}; dynamic localRes; hasError = false; try { - await baseAppClient.getPharmacy("$GET_SHOPPING_CART$customerId", - onSuccess: (dynamic response, int statusCode) { + await baseAppClient.getPharmacy("$GET_SHOPPING_CART$customerId/$customerGUID", onSuccess: (dynamic response, int statusCode) { localRes = response; }, onFailure: (String error, int statusCode) { hasError = true; @@ -79,8 +79,7 @@ class OrderPreviewService extends BaseService { return Future.value(localRes); } - Future changeProductQuantity( - String productId, ShoppingCart product) async { + Future changeProductQuantity(String productId, ShoppingCart product) async { hasError = false; super.error = ""; dynamic localRes; @@ -94,8 +93,7 @@ class OrderPreviewService extends BaseService { Map body = Map(); body["shopping_cart_item"] = choppingCartObject; - await baseAppClient.pharmacyPost("$GET_SHOPPING_CART$productId", isExternal: false, - onSuccess: (response, statusCode) async { + await baseAppClient.pharmacyPost("$GET_SHOPPING_CART$productId", isExternal: false, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { hasError = true; @@ -112,8 +110,7 @@ class OrderPreviewService extends BaseService { Map body = Map(); - await baseAppClient.pharmacyPost("$DELETE_SHOPPING_CART$productId", isExternal: false, - onSuccess: (response, statusCode) async { + await baseAppClient.pharmacyPost("$DELETE_SHOPPING_CART$productId", isExternal: false, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { hasError = true; @@ -130,9 +127,7 @@ class OrderPreviewService extends BaseService { super.error = ""; dynamic localRes; - await baseAppClient - .getPharmacy("$DELETE_SHOPPING_CART_ALL$customerId/ShoppingCart", - onSuccess: (response, statusCode) async { + await baseAppClient.getPharmacy("$DELETE_SHOPPING_CART_ALL$customerId/ShoppingCart", onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { hasError = true; @@ -142,16 +137,15 @@ class OrderPreviewService extends BaseService { return Future.value(localRes); } - Future getLacumAccountInformation() async { + Future getLacumAccountInformation(String identificationNo) async { hasError = false; super.error = ""; Map body = Map(); - body['IdentificationNo'] = user.patientIdentificationNo; + body['IdentificationNo'] = identificationNo; try { - await baseAppClient.post(GET_LACUM_ACCOUNT_INFORMATION, - onSuccess: (response, statusCode) async { + await baseAppClient.post(GET_LACUM_ACCOUNT_INFORMATION, onSuccess: (response, statusCode) async { lacumInformation = LacumAccountInformation.fromJson(response); }, onFailure: (String error, int statusCode) { hasError = true; @@ -162,17 +156,16 @@ class OrderPreviewService extends BaseService { } } - Future getLacumGroupInformation() async { + Future getLacumGroupInformation(String identificationNo) async { hasError = false; super.error = ""; Map body = Map(); - body['IdentificationNo'] = user.patientIdentificationNo; - body['AccountNumber'] = "${lacumInformation.yahalaAccountNo}"; + body['IdentificationNo'] = identificationNo; + body['AccountNumber'] = "${lacumInformation!.yahalaAccountNo}"; try { - await baseAppClient.post(GET_LACUM_GROUP_INFORMATION, - onSuccess: (response, statusCode) async { + await baseAppClient.post(GET_LACUM_GROUP_INFORMATION, onSuccess: (response, statusCode) async { lacumGroupInformation = LacumAccountInformation.fromJson(response); }, onFailure: (String error, int statusCode) { hasError = true; @@ -183,39 +176,37 @@ class OrderPreviewService extends BaseService { } } - Future makeOrder(PaymentCheckoutData paymentCheckoutData, - List shoppingCarts) async { - paymentCheckoutData.address.isChecked = true; + Future makeOrder(PaymentCheckoutData paymentCheckoutData, List shoppingCarts, bool isLakumEnabled) async { + paymentCheckoutData.address!.isChecked = true; hasError = false; super.error = ""; - var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'en'); + var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'en'); var customerId = await sharedPref.getString(PHARMACY_CUSTOMER_ID); Map orderBody = Map(); orderBody['rx_attachments'] = ""; - orderBody['customer_language_id'] = languageID == 'ar' ? 1 : 2; + orderBody['customer_language_id'] = languageID == 'ar' ? 2 : 1; orderBody['billing_address'] = paymentCheckoutData.address; orderBody['pick_up_in_store'] = false; orderBody['payment_method_system_name'] = "Payments.PayFort"; - orderBody['shipping_method'] = languageID == 'ar' - ? paymentCheckoutData.shippingOption.namen - : paymentCheckoutData.shippingOption.name; - orderBody['shipping_rate_computation_method_system_name'] = - paymentCheckoutData - .shippingOption.shippingRateComputationMethodSystemName; + + if (paymentCheckoutData.shippingOption!.shippingRateComputationMethodSystemName == "Shipping.Aramex") + orderBody['shipping_method'] = "Aramex Domestic"; + else + orderBody['shipping_method'] = "Fixed Price"; + + orderBody['shipping_rate_computation_method_system_name'] = paymentCheckoutData.shippingOption!.shippingRateComputationMethodSystemName; orderBody['customer_id'] = int.parse(customerId); - orderBody['custom_values_xml'] = - "PaymentOption:${getPaymentOptionName(paymentCheckoutData.paymentOption)}"; + orderBody['custom_values_xml'] = "PaymentOption:${getPaymentOptionName(paymentCheckoutData.paymentOption!)}"; orderBody['shippingOption'] = paymentCheckoutData.shippingOption; orderBody['shipping_address'] = paymentCheckoutData.address; - orderBody['lakum_amount'] = paymentCheckoutData.usedLakumPoints; + orderBody['lakum_amount'] = isLakumEnabled ? paymentCheckoutData.usedLakumPoints : 0; - List> itemsList = List(); + List> itemsList = []; shoppingCarts.forEach((item) { Map orderItemsBody = Map(); - orderItemsBody['product_id'] = item.product.id; + orderItemsBody['product_id'] = item.product!.id; orderItemsBody['quantity'] = item.quantity; itemsList.add(orderItemsBody); }); @@ -225,8 +216,7 @@ class OrderPreviewService extends BaseService { body['order'] = orderBody; try { - await baseAppClient.pharmacyPost(ORDER_SHOPPING_CART, isExternal: false, isAllowAny: true, - onSuccess: (response, statusCode) async { + await baseAppClient.pharmacyPost(ORDER_SHOPPING_CART, isExternal: false, isAllowAny: true, onSuccess: (response, statusCode) async { orderList.clear(); response['orders'].forEach((item) { orderList.add(OrderDetailModel.fromJson(item)); @@ -258,30 +248,32 @@ class OrderPreviewService extends BaseService { case 4: return "INSTALLMENT"; break; + case 5: + return "ApplePay"; + break; default: return ""; } } - Future getDriverLocation(dynamic driverId) async{ + Future getDriverLocation(dynamic driverId) async { Map jsonBody = Map(); jsonBody['DriverID'] = driverId; LatLng coordinates; - await baseAppClient.post(DRIVER_LOCATION, - onSuccess: (response, statusCode) async { - if(statusCode == 200){ - dynamic locationObject = response['PatientER_GetDriverLocationList'][0]; - double lat = locationObject['Latitude']; - double lon = locationObject['Longitude']; - if(lat != null && lon != null){ - coordinates = LatLng(lat,lon); - } - } - }, onFailure: (String error, int statusCode) { - - }, body: jsonBody); - - return coordinates; + await baseAppClient.post(DRIVER_LOCATION, onSuccess: (response, statusCode) async { + if (statusCode == 200) { + dynamic locationObject = response['PatientER_GetDriverLocationList'][0]; + double lat = locationObject['Latitude']; + double lon = locationObject['Longitude']; + if (lat != null && lon != null) { + coordinates = LatLng(lat, lon); + return coordinates; + } + } + }, onFailure: (String error, int statusCode) { + return LatLng(double.nan, double.nan); + //added by Amir + }, body: jsonBody); } } diff --git a/lib/core/service/parmacyModule/parmacy_module_service.dart b/lib/core/service/parmacyModule/parmacy_module_service.dart index 7fa095ca..2490f231 100644 --- a/lib/core/service/parmacyModule/parmacy_module_service.dart +++ b/lib/core/service/parmacyModule/parmacy_module_service.dart @@ -3,6 +3,7 @@ import 'package:diplomaticquarterapp/config/shared_pref_kay.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/service/AlHabibMedicalService/customer_addresses_service.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; @@ -10,27 +11,23 @@ import 'package:diplomaticquarterapp/uitl/utils.dart'; class PharmacyModuleService extends BaseService { final AppSharedPreferences sharedPref = AppSharedPreferences(); bool isFinished = true; - bool hasError = false; String errorMsg = ''; String url = ""; + CustomerInfo? customerInfo; - List bannerItems = List(); - List manufacturerList = List(); - List bestSellerProducts = List(); - List lastVisitedProducts = List(); + List bannerItems =[]; + List manufacturerList =[]; + List bestSellerProducts =[]; + List lastVisitedProducts =[]; + List mostViewedProducts =[]; Future makeVerifyCustomer(dynamic data) async { - Map queryParams = { - 'FileNumber': data['PatientID'].toString() - }; + Map queryParams = {'FileNumber': data['PatientID'].toString()}; hasError = false; try { - await baseAppClient.getPharmacy(PHARMACY_VERIFY_CUSTOMER, - onSuccess: (dynamic response, int statusCode) async { + await baseAppClient.getPharmacy(PHARMACY_VERIFY_CUSTOMER, onSuccess: (dynamic response, int statusCode) async { if (response['UserName'] != null) { - sharedPref.setString( - PHARMACY_CUSTOMER_ID, response['CustomerId'].toString()); - print(response); + sharedPref.setString(PHARMACY_CUSTOMER_ID, response['CustomerId'].toString()); } else { await createUser(); } @@ -43,26 +40,25 @@ class PharmacyModuleService extends BaseService { } } - Future createUser() async { + Future createUser() async { var data = await sharedPref.getObject(USER_PROFILE); var languageID = await sharedPref.getString(APP_LANGUAGE); Map queryParams = { - 'Phone': data['MobileNumber'], - 'Email': data['EmailAddress'], + 'Phone': Utils.getPhoneNumberWithoutZero(data['MobileNumber']), 'FileNumber': data['PatientID'].toString(), - 'Language': languageID.toString(), - 'Gender': data['Gender'].toString(), - 'FirstName': data['FirstName'], - 'LastName': data['LastName'], - 'LanguageId': languageID.toString(), - 'CountryCode': data['ZipCode'], + 'Language': languageID.toString() == 'en' ? '2' : '1', + 'Iqama': data['PatientIdentificationNo'], + 'CountryCode': data['ZipCode'] ?? '966', }; hasError = false; try { - await baseAppClient.get(PHARMACY_CREATE_CUSTOMER, - onSuccess: (dynamic response, int statusCode) async { - if (!response['IsRegistered']) {} - await generatePharmacyToken(); + await baseAppClient.getPharmacy(PHARMACY_CREATE_CUSTOMER, onSuccess: (dynamic response, int statusCode) async { + if (!response['IsRegistered']) { + } else { + customerInfo = CustomerInfo.fromJson(response); + await sharedPref.setObject(PHARMACY_CUSTOMER_ID, customerInfo!.customerId); + await sharedPref.setObject(PHARMACY_CUSTOMER_GUID, response['customerDto']['customerGuid']); + } }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; @@ -70,21 +66,20 @@ class PharmacyModuleService extends BaseService { } catch (error) { throw error; } + return Future.value(1); } Future generatePharmacyToken() async { await getUser(); Map queryParams = { 'Filenumber': user.patientID.toString(), - 'MobileNumber': Utils.getPhoneNumberWithoutZero(user.mobileNumber), + 'MobileNumber': Utils.getPhoneNumberWithoutZero(user.mobileNumber!), }; hasError = false; try { - await baseAppClient.getPharmacy(PHARMACY_AUTORZIE_CUSTOMER, - onSuccess: (dynamic response, int statusCode) async { + await baseAppClient.getPharmacy(PHARMACY_AUTORZIE_CUSTOMER, onSuccess: (dynamic response, int statusCode) async { if (response['Status'] == 200) { - await sharedPref.setString( - PHARMACY_AUTORZIE_TOKEN, response['token'].toString()); + await sharedPref.setString(PHARMACY_AUTORZIE_TOKEN, response['token'].toString()); } }, onFailure: (String error, int statusCode) { hasError = true; @@ -98,8 +93,7 @@ class PharmacyModuleService extends BaseService { Future getBannerListList() async { hasError = false; try { - await baseAppClient.getPharmacy(GET_PHARMACY_BANNER, - onSuccess: (dynamic response, int statusCode) { + await baseAppClient.getPharmacy(GET_PHARMACY_BANNER, onSuccess: (dynamic response, int statusCode) { bannerItems.clear(); response['images'].forEach((item) { bannerItems.add(PharmacyImageObject.fromJson(item)); @@ -114,17 +108,18 @@ class PharmacyModuleService extends BaseService { } Future getTopManufacturerList() async { + if (manufacturerList.isNotEmpty) return; Map queryParams = {'page': '1', 'limit': '8'}; try { - await baseAppClient.getPharmacy(GET_PHARMACY_TOP_MANUFACTURER, - onSuccess: (dynamic response, int statusCode) { + await baseAppClient.getPharmacy(GET_PHARMACY_TOP_MANUFACTURER, onSuccess: (dynamic response, int statusCode) { manufacturerList.clear(); response['manufacturer'].forEach((item) { Manufacturer manufacturer = Manufacturer.fromJson(item); - if (manufacturer.image != null) { - manufacturerList.add(Manufacturer.fromJson(item)); - } + // if (manufacturer.image != null) { + manufacturerList.add(Manufacturer.fromJson(item)); + // } }); + hasError = false; }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; @@ -135,17 +130,19 @@ class PharmacyModuleService extends BaseService { } Future getBestSellerProducts() async { + if (bestSellerProducts.isNotEmpty) return; + Map queryParams = { 'fields': - 'id,discount_ids,name,namen,localized_names,display_order,short_description,full_description,full_descriptionn,sku,order_minimum_quantity,order_maximum_quantity,price,old_price,images,is_rx,rx_message,rx_messagen,discount_name,discount_namen,approved_rating_sum,approved_total_reviews,allow_back_in_stock_subscriptions,stock_quantity,stock_availability,stock_availabilityn,discount_percentage,reviews', + 'id,discount_ids,name,namen,localized_names,display_order,short_description,full_description,full_descriptionn,sku,order_minimum_quantity,order_maximum_quantity,price,old_price,images,is_rx,rx_message,rx_messagen,discount_name,discount_namen,approved_rating_sum,approved_total_reviews,allow_back_in_stock_subscriptions,stock_quantity,stock_availability,stock_availabilityn,discount_percentage,reviews,specifications', }; try { - await baseAppClient.getPharmacy(GET_PHARMACY_BEST_SELLER_PRODUCT, - onSuccess: (dynamic response, int statusCode) { + await baseAppClient.getPharmacy(GET_PHARMACY_BEST_SELLER_PRODUCT, onSuccess: (dynamic response, int statusCode) { bestSellerProducts.clear(); response['products'].forEach((item) { bestSellerProducts.add(PharmacyProduct.fromJson(item)); }); + hasError = false; }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; @@ -157,20 +154,18 @@ class PharmacyModuleService extends BaseService { Future getLastVisitedProducts() async { String lastVisited = ""; - if (await this.sharedPref.getString(PHARMACY_LAST_VISITED_PRODUCTS) != - null) { - lastVisited = - await this.sharedPref.getString(PHARMACY_LAST_VISITED_PRODUCTS); + if (await this.sharedPref.getString(PHARMACY_LAST_VISITED_PRODUCTS) != null) { + lastVisited = await this.sharedPref.getString(PHARMACY_LAST_VISITED_PRODUCTS); + // lastVisited = "2458,4561"; try { - await baseAppClient - .getPharmacy("$GET_PHARMACY_PRODUCTs_BY_IDS$lastVisited", - onSuccess: (dynamic response, int statusCode) { + await baseAppClient.getPharmacy("$GET_PHARMACY_PRODUCTs_BY_IDS$lastVisited", onSuccess: (dynamic response, int statusCode) { lastVisitedProducts.clear(); response['products'].forEach((item) { lastVisitedProducts.add(PharmacyProduct.fromJson(item)); }); + hasError = false; }, onFailure: (String error, int statusCode) { - hasError = true; + hasError = true; // sharedPref.setString(PHARMACY_LAST_VISITED_PRODUCTS, ""); super.error = error; }); } catch (error) { @@ -178,4 +173,27 @@ class PharmacyModuleService extends BaseService { } } } + + Future getMostViewedProducts() async { + hasError = false; + Map queryParams = { + 'fields': + 'id,discount_ids,name,reviews,namen,localized_names,display_order,short_description,full_description,full_descriptionn,sku,order_minimum_quantity,order_maximum_quantity,price,old_price,images,is_rx,rx_message,rx_messagen,discount_name,discount_namen,approved_rating_sum,approved_total_reviews,allow_back_in_stock_subscriptions,stock_quantity,stock_availability,stock_availabilityn,discount_percentage,specifications', + }; + try { + await baseAppClient.getPharmacy(GET_MOST_VIEWED_PRODUCTS, onSuccess: (dynamic response, int statusCode) { + mostViewedProducts.clear(); + response['products'].forEach((item) { + mostViewedProducts.add(PharmacyProduct.fromJson(item)); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, queryParams: queryParams); + } catch (error) { + hasError = true; + super.error = error.toString(); + // throw error; + } + } } diff --git a/lib/core/service/parmacyModule/prescription_service.dart b/lib/core/service/parmacyModule/prescription_service.dart index c2312890..ecad3b77 100644 --- a/lib/core/service/parmacyModule/prescription_service.dart +++ b/lib/core/service/parmacyModule/prescription_service.dart @@ -1,52 +1,27 @@ import 'package:diplomaticquarterapp/config/config.dart'; -import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/model/prescriptions/Prescriptions.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; -import 'package:diplomaticquarterapp/core/model/pharmacies/Prescriptions.dart'; class PrescriptionService extends BaseService { final AppSharedPreferences sharedPref = AppSharedPreferences(); bool isFinished = true; bool hasError = false; String errorMsg = ''; - String url = ""; - List _prescriptionsList = List(); + List _prescriptionsList =[]; + List get prescriptionsList => _prescriptionsList; -// Future getPrescription() async { -// hasError = false; -// url = PRESCRIPTION; -// print("Print PRESCRIPTION url" + url); -// await baseAppClient.get(url, -// onSuccess: (dynamic response, int statusCode) { -// _prescriptionsList.clear(); -// response['PatientPrescriptionList'].forEach((item) { -// _prescriptionsList.add(Prescriptions.fromJson(item)); -// }); -// print(_prescriptionsList.length); -// print(response); -// }, onFailure: (String error, int statusCode) { -// hasError = true; -// super.error = error; -// }); -// } Future getPrescription() async { - url = PRESCRIPTION; - print("Print PRESCRIPTION url" + url); hasError = false; Map body = Map(); body['isDentalAllowedBackend'] = false; - print("Print PRESCRIPTION url" + url); - await baseAppClient.post(url, - onSuccess: (dynamic response, int statusCode) { + await baseAppClient.post(PRESCRIPTION, onSuccess: (dynamic response, int statusCode) { _prescriptionsList.clear(); response['PatientPrescriptionList'].forEach((prescriptions) { _prescriptionsList.add(Prescriptions.fromJson(prescriptions)); }); - print(_prescriptionsList.length); - print("response is -------------"+response); - print(response); }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; diff --git a/lib/core/service/parmacyModule/terms-condition-service.dart b/lib/core/service/parmacyModule/terms-condition-service.dart index 68fac632..7d03c5dc 100644 --- a/lib/core/service/parmacyModule/terms-condition-service.dart +++ b/lib/core/service/parmacyModule/terms-condition-service.dart @@ -9,7 +9,7 @@ class TermsConditionService extends BaseService{ String errorMsg = ''; String successMsg = ''; - ListUserAgreement listUserAgreement; + ListUserAgreement? listUserAgreement; Future getUserTermsAndConditionsForEPharmcy() async { hasError = false; diff --git a/lib/core/service/pharmacies_service.dart b/lib/core/service/pharmacies_service.dart index dbd4fae1..88235c0e 100644 --- a/lib/core/service/pharmacies_service.dart +++ b/lib/core/service/pharmacies_service.dart @@ -1,12 +1,12 @@ import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/pharmacies_list_model.dart'; -import 'package:diplomaticquarterapp/core/service/base_service.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/pharmacies_model.dart'; +import 'package:diplomaticquarterapp/core/service/base_service.dart'; import 'package:geolocator/geolocator.dart'; class PharmacyService extends BaseService { - List _medicineItem = List(); - List _pharmaciesList = List(); + List _medicineItem =[]; + List _pharmaciesList =[]; List get medicineItem => _medicineItem; List get pharmaciesList => _pharmaciesList; @@ -65,7 +65,7 @@ class PharmacyService extends BaseService { _getCurrentLocation() async { await Geolocator.getLastKnownPosition().then((value) { - _latitude = value.latitude; + _latitude = value!.latitude; _longitude = value.longitude; }).catchError((e) { _longitude = 0; @@ -73,7 +73,7 @@ class PharmacyService extends BaseService { }); } - Future getMedicineList({String drugName}) async { + Future getMedicineList({required String drugName}) async { hasError = false; await _getCurrentLocation(); Map body = Map(); @@ -97,7 +97,7 @@ class PharmacyService extends BaseService { } - Future getPharmaciesList({int itemID}) async { + Future getPharmaciesList({required int itemID}) async { await _getCurrentLocation(); Map body = Map(); diff --git a/lib/core/service/pharmacy_categorise_service.dart b/lib/core/service/pharmacy_categorise_service.dart index 58f58ddb..736c2788 100644 --- a/lib/core/service/pharmacy_categorise_service.dart +++ b/lib/core/service/pharmacy_categorise_service.dart @@ -1,57 +1,53 @@ import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; -import 'package:diplomaticquarterapp/core/model/pharmacy/brands_model.dart'; import 'package:diplomaticquarterapp/core/model/pharmacy/categorise_parent_model.dart'; import 'package:diplomaticquarterapp/core/model/pharmacy/final_products_model.dart'; -import 'package:diplomaticquarterapp/core/model/pharmacy/parent_products_model.dart'; import 'package:diplomaticquarterapp/core/model/pharmacy/pharmacy_categorise.dart'; import 'package:diplomaticquarterapp/core/model/pharmacy/scan_qr_model.dart'; -import 'package:diplomaticquarterapp/core/model/pharmacy/sub_categories_model.dart'; -import 'package:diplomaticquarterapp/core/model/pharmacy/sub_products_model.dart'; -import 'package:diplomaticquarterapp/core/model/search_products_model.dart'; +import 'package:diplomaticquarterapp/models/LiveCare/validators.dart'; import 'base_service.dart'; class PharmacyCategoriseService extends BaseService { //service one - List _categoriseList = List(); + List _categoriseList =[]; List get categoriseList => _categoriseList; //service two - List _parentCategoriseList = List(); + List _parentCategoriseList =[]; List get parentCategoriseList => _parentCategoriseList; //service three - List _parentProductsList = List(); + List _parentProductsList =[]; List get parentProductsList => _parentProductsList; //service four - List _subCategoriseList = List(); + List _subCategoriseList =[]; List get subCategoriseList => _subCategoriseList; //service five - List _subProductsList = List(); + List _subProductsList =[]; List get subProductsList => _subProductsList; //service six - List _finalProducts = List(); + List _finalProducts =[]; List get finalProducts => _finalProducts; //service 7 - List _brandsList = List(); + List _brandsList =[]; List get brandsList => _brandsList; // service 8 - List _searchList = List(); + List _searchList =[]; List get searchList => _searchList; - List _scanList = List(); + List _scanList =[]; List get scanList => _scanList; - List manufacturerProducts = List(); + List manufacturerProducts =[]; clearSearchList() { _searchList.clear(); @@ -74,7 +70,7 @@ class PharmacyCategoriseService extends BaseService { ); } - Future scanQr({String id}) async { + Future scanQr({required String id}) async { hasError = false; _scanList.clear(); String endPoint = id != null ? SCAN_QR_CODE + "$id" : SCAN_QR_CODE + ""; @@ -92,11 +88,14 @@ class PharmacyCategoriseService extends BaseService { ); } - Future searchProducts({String productName}) async { + Future searchProducts({required String productName}) async { hasError = false; _searchList.clear(); + // the language ID in pharmacy is different not same in patient app, en == 1 , ar == 2 + var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + var languageId = languageID == 'ar' ? 2 : 1; String endPoint = productName != null - ? GET_SEARCH_PRODUCTS + "$productName" + '&language_id=1' + ? GET_SEARCH_PRODUCTS + "$productName" + '&language_id=' + "$languageId" : GET_SEARCH_PRODUCTS + ""; await baseAppClient.getPharmacy( endPoint, @@ -112,7 +111,7 @@ class PharmacyCategoriseService extends BaseService { ); } - Future getBrands({String id}) async { + Future getBrands({required String id}) async { hasError = false; _brandsList.clear(); await baseAppClient.getPharmacy( @@ -129,7 +128,7 @@ class PharmacyCategoriseService extends BaseService { ); } - Future getCategoriseParent({String id}) async { + Future getCategoriseParent({required String id}) async { hasError = false; _parentCategoriseList.clear(); String endPoint = @@ -148,11 +147,14 @@ class PharmacyCategoriseService extends BaseService { ); } - Future getParentProducts({String id}) async { + Future getParentProducts( + {String? id, int? pageNumber, bool isLoading = false}) async { hasError = false; - _parentProductsList.clear(); + if (isLoading == false) { + _parentProductsList.clear(); + } String endPoint = id != null - ? GET_PARENT_PRODUCTS + "$id" + '&page=1&limit=50' + ? GET_PARENT_PRODUCTS + "$id" + '&page=' + '$pageNumber' + '&limit=24' : GET_PARENT_PRODUCTS + ""; await baseAppClient.getPharmacy( endPoint, @@ -160,6 +162,7 @@ class PharmacyCategoriseService extends BaseService { response['products'].forEach((item) { _parentProductsList.add(PharmacyProduct.fromJson(item)); }); + //pageNumber++; }, onFailure: (String error, int statusCode) { hasError = true; @@ -168,7 +171,7 @@ class PharmacyCategoriseService extends BaseService { ); } - Future getSubCategorise({String id}) async { + Future getSubCategorise({required String id}) async { hasError = false; _subCategoriseList.clear(); @@ -188,11 +191,14 @@ class PharmacyCategoriseService extends BaseService { ); } - Future getSubProducts({String id}) async { + Future getSubProducts( + {String? id, int? pageIndex, bool isLoading = false}) async { hasError = false; - _subProductsList.clear(); + if (isLoading == false) { + _subProductsList.clear(); + } String endPoint = id != null - ? GET_SUB_PRODUCTS + "$id" + '&page=1&limit=50' + ? GET_SUB_PRODUCTS + "$id" + '&page=' + '$pageIndex' + '&limit=24' : GET_SUB_PRODUCTS + ""; await baseAppClient.getPharmacy( endPoint, @@ -208,7 +214,7 @@ class PharmacyCategoriseService extends BaseService { ); } - Future getFinalProducts({String id}) async { + Future getFinalProducts({required String id}) async { hasError = false; _finalProducts.clear(); String endPoint = @@ -249,6 +255,7 @@ class PharmacyCategoriseService extends BaseService { Future getLastVisitedProducts() async { String lastVisited = ""; + _finalProducts.clear(); if (await this.sharedPref.getString(PHARMACY_LAST_VISITED_PRODUCTS) != null) { lastVisited = @@ -274,7 +281,7 @@ class PharmacyCategoriseService extends BaseService { Future getBestSellerProducts() async { Map queryParams = { 'fields': - 'id,discount_ids,name,namen,localized_names,display_order,short_description,full_description,full_descriptionn,sku,order_minimum_quantity,order_maximum_quantity,price,old_price,images,is_rx,rx_message,rx_messagen,discount_name,discount_namen,approved_rating_sum,approved_total_reviews,allow_back_in_stock_subscriptions,stock_quantity,stock_availability,stock_availabilityn,discount_percentage,reviews', + 'id,discount_ids,name,namen,localized_names,display_order,short_description,full_description,full_descriptionn,sku,order_minimum_quantity,order_maximum_quantity,price,old_price,images,is_rx,rx_message,rx_messagen,discount_name,discount_namen,approved_rating_sum,approved_total_reviews,allow_back_in_stock_subscriptions,stock_quantity,stock_availability,stock_availabilityn,discount_percentage,reviews,specifications', }; try { await baseAppClient.getPharmacy(GET_PHARMACY_BEST_SELLER_PRODUCT, @@ -293,16 +300,16 @@ class PharmacyCategoriseService extends BaseService { } Future getFilteredProducts( - {String categoryId, String brandId, String min, String max}) async { + {String? categoryId, String? brandId, String? min, String? max}) async { hasError = false; String endPoint; _parentProductsList.clear(); endPoint = FILTERED_PRODUCTS + "$categoryId" + - "&manufacturerids=$brandId" + - "&price_min=$min" + - "&price_max=$max&page=1&limit=50"; + "$brandId" + + "$min" + + "$max&page=1&limit=50"; await baseAppClient.getPharmacy( endPoint, onSuccess: (dynamic response, int statusCode) { @@ -317,47 +324,75 @@ class PharmacyCategoriseService extends BaseService { ); } + Future getFilteredSubProducts( + {String? categoryId, String? brandId, String? min, String? max}) async { + hasError = false; + String endPoint; + + _subProductsList.clear(); + endPoint = FILTERED_PRODUCTS + + "$categoryId" + + "$brandId" + + "$min" + + "$max&page=1&limit=50"; + await baseAppClient.getPharmacy( + endPoint, + onSuccess: (dynamic response, int statusCode) { + response['products'].forEach((item) { + _subProductsList.add(PharmacyProduct.fromJson(item)); + }); + }, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, + ); + } + Future getMostViewedProducts() async { + hasError = false; Map queryParams = { 'fields': - 'id,discount_ids,name,reviews,namen,localized_names,display_order,short_description,full_description,full_descriptionn,sku,order_minimum_quantity,order_maximum_quantity,price,old_price,images,is_rx,rx_message,rx_messagen,discount_name,discount_namen,approved_rating_sum,approved_total_reviews,allow_back_in_stock_subscriptions,stock_quantity,stock_availability,stock_availabilityn,discount_percentage', + 'mostview?fields=id,discount_ids,name,reviews,namen,localized_names,display_order,short_description,full_description,full_descriptionn,sku,order_minimum_quantity,order_maximum_quantity,price,old_price,images,is_rx,rx_message,rx_messagen,discount_name,discount_namen,approved_rating_sum,approved_total_reviews,allow_back_in_stock_subscriptions,stock_quantity,stock_availability,stock_availabilityn,discount_percentage,specifications', }; try { await baseAppClient.getPharmacy(GET_MOST_VIEWED_PRODUCTS, onSuccess: (dynamic response, int statusCode) { - _finalProducts.clear(); - response['products'].forEach((item) { - _finalProducts.add(PharmacyProduct.fromJson(item)); - }); - print("most viewed products ---------"); - print(response); - }, onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }, queryParams: queryParams); + _finalProducts.clear(); + response['products'].forEach((item) { + _finalProducts.add(PharmacyProduct.fromJson(item)); + }); + print("most viewed products ---------"); + print(response); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, queryParams: queryParams); } catch (error) { - throw error; + hasError = true; + super.error = error.toString(); + // throw error; } } Future getNewProducts() async { Map queryParams = { 'fields': - 'Id,name,namen,localized_names,price,images,sku,stock_availability,published', + 'Id,name,namen,localized_names,price,images,sku,stock_availability,published', }; try { await baseAppClient.getPharmacy(GET_NEW_PRODUCTS, onSuccess: (dynamic response, int statusCode) { - _finalProducts.clear(); - response['products'].forEach((item) { - _finalProducts.add(PharmacyProduct.fromJson(item)); - }); - print("new products ---------"); - print(response); - }, onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }, queryParams: queryParams); + _finalProducts.clear(); + response['products'].forEach((item) { + _finalProducts.add(PharmacyProduct.fromJson(item)); + }); + print("new products ---------"); + print(response); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, queryParams: queryParams); } catch (error) { throw error; } diff --git a/lib/core/service/privilege_service.dart b/lib/core/service/privilege_service.dart index 5beef992..b8b7b771 100644 --- a/lib/core/service/privilege_service.dart +++ b/lib/core/service/privilege_service.dart @@ -1,19 +1,43 @@ import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/core/model/privilege/HMCProjectListModel.dart'; import 'package:diplomaticquarterapp/core/model/privilege/PrivilegeModel.dart'; +import 'package:diplomaticquarterapp/core/model/privilege/ProjectDetailListModel.dart'; +import 'package:diplomaticquarterapp/core/model/privilege/VidaPlusProjectListModel.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; +import 'package:diplomaticquarterapp/main.dart'; class PrivilegeService extends BaseService { - - List privilegeModelList = List(); + List privilegeModelList = []; + List vidaPlusProjectListModel = []; + List hMCProjectListModel = []; + List projectDetailListModel = []; Future getPrivilege() async { Map body = Map(); body['PatientType'] = 4; - await baseAppClient.post(GET_PRIVILEGE, - onSuccess: (dynamic response, int statusCode) { + body['LanguageID'] = 1; + await baseAppClient.post(GET_PRIVILEGE, onSuccess: (dynamic response, int statusCode) { response['ServicePrivilegeList'].forEach((item) { privilegeModelList.add(PrivilegeModel.fromJson(item)); }); + + if (response['ProjectListVidaPlus'].length != 0) { + response['ProjectListVidaPlus'].forEach((item) { + vidaPlusProjectListModel.add(VidaPlusProjectListModel.fromJson(item)); + }); + } + + if (response['HMCProjectList'].length != 0) { + response['HMCProjectList'].forEach((item) { + hMCProjectListModel.add(HMCProjectListModel.fromJson(item)); + }); + } + + if (response['ProjectDetailList'].length != 0) { + response['ProjectDetailList'].forEach((item) { + projectDetailListModel.add(ProjectDetailListModel.fromJson(item)); + }); + } }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; diff --git a/lib/core/service/qr_service.dart b/lib/core/service/qr_service.dart index d43ed5bb..5d87a7aa 100644 --- a/lib/core/service/qr_service.dart +++ b/lib/core/service/qr_service.dart @@ -3,7 +3,7 @@ import 'package:diplomaticquarterapp/core/model/qr/qr_parking_model.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; class QrService extends BaseService { - List qRParkingList = List(); + List qRParkingList =[]; Future getQRParkingByID(int qRParkingID) async { Map body = Map(); diff --git a/lib/core/service/vaccine_service.dart b/lib/core/service/vaccine_service.dart index 297909a4..30cff48d 100644 --- a/lib/core/service/vaccine_service.dart +++ b/lib/core/service/vaccine_service.dart @@ -1,13 +1,13 @@ import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/core/model/vaccine/my_vaccine.dart'; import 'package:diplomaticquarterapp/core/model/vaccine/vaccination_item.dart'; import 'package:diplomaticquarterapp/core/model/vaccine/vaccination_on_hand.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; -import 'package:diplomaticquarterapp/core/model/vaccine/my_vaccine.dart'; class VaccineService extends BaseService { - List _vaccineList = List(); - List vaccinationItemList = List(); - List vaccinationOnHandList = List(); + List _vaccineList =[]; + List vaccinationItemList =[]; + List vaccinationOnHandList =[]; List get vaccineList => _vaccineList; @@ -15,6 +15,7 @@ class VaccineService extends BaseService { Map body = Map(); body['To'] = "0"; body['From'] = "0"; + hasError = false; _vaccineList.clear(); await baseAppClient.post(GET_VACCINES, @@ -35,7 +36,7 @@ class VaccineService extends BaseService { body['DateofBirth'] = user.dateofBirth; body['PatientIditificationNum'] = user.patientIdentificationNo; body['PatientMobileNumber'] = user.mobileNumber; - body['PatientName'] = user.firstName + " " + user.lastName; + body['PatientName'] = user.firstName! + " " + user.lastName!; hasError = false; @@ -59,7 +60,7 @@ class VaccineService extends BaseService { }, body: Map()); } - Future getMyVaccinationOnHand({String pItemCode}) async { + Future getMyVaccinationOnHand({required String pItemCode}) async { Map body = Map(); body['P_ITEM_CODE'] = pItemCode; await baseAppClient.post(GET_VACCINATION_ONHAND, diff --git a/lib/core/service/weather_service.dart b/lib/core/service/weather_service.dart index ea7d65bf..a94dd9e1 100644 --- a/lib/core/service/weather_service.dart +++ b/lib/core/service/weather_service.dart @@ -4,7 +4,7 @@ import 'package:diplomaticquarterapp/core/model/weahter/weather_model.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; class WeatherService extends BaseService { - List weatherIndicatorData = List(); + List weatherIndicatorData =[]; Map body = Map(); String Latitude = ""; @@ -24,7 +24,6 @@ class WeatherService extends BaseService { response['GetCityInfo_List'].forEach((data) { weatherIndicatorData.add(GetCityInfoList.fromJson(data)); }); - print(weatherIndicatorData); }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; diff --git a/lib/core/viewModels/AlHabibMedicalService/H2O_view_model.dart b/lib/core/viewModels/AlHabibMedicalService/H2O_view_model.dart index a89ec799..d7df4773 100644 --- a/lib/core/viewModels/AlHabibMedicalService/H2O_view_model.dart +++ b/lib/core/viewModels/AlHabibMedicalService/H2O_view_model.dart @@ -1,3 +1,6 @@ +import 'dart:math' as math; + +import 'package:flutter_charts/flutter_charts.dart' as Charts; import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/H2O/insert_user_activity_request_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/H2O/user_detail_model.dart'; @@ -6,21 +9,25 @@ import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/H2O/user_p import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/H2O/user_progress_for_week_data_model.dart'; import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/H2O_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; -import 'package:charts_flutter/flutter.dart' as charts; -import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/widgets/charts/custom_line_chart.dart'; + import '../../../locator.dart'; class H2OViewModel extends BaseViewModel { H2OService _h2OService = locator(); - List userProgressForWeekDataSeries; - List userProgressForMonthDataSeries; + // + // List userProgressForWeekDataSeries; + List? userProgressForWeekDataSeries; + List? userProgressForMonthDataSeries; + + // List userProgressForMonthDataSeries; UserDetailModel get userDetail => _h2OService.userDetailModel; UserProgressForTodayDataModel get userProgressData { if (_h2OService.userProgressForTodayDataList.length != 0) return _h2OService.userProgressForTodayDataList[0]; - return null; + return UserProgressForTodayDataModel(); } Future getUserDetail() async { @@ -28,7 +35,7 @@ class H2OViewModel extends BaseViewModel { setState(ViewState.Busy); await _h2OService.getUserDetail(); if (_h2OService.hasError) { - error = _h2OService.error; + error = _h2OService.error!; setState(ViewState.Error); } else { setState(ViewState.Idle); @@ -40,7 +47,7 @@ class H2OViewModel extends BaseViewModel { await _h2OService.updateUserDetail(userDetailModel); if (_h2OService.hasError) { - error = _h2OService.error; + error = _h2OService.error!; setState(ViewState.Error); onResponse(false); } else { @@ -55,7 +62,7 @@ class H2OViewModel extends BaseViewModel { setState(ViewState.Busy); await _h2OService.getUserProgressForTodayData(); if (_h2OService.hasError) { - error = _h2OService.error; + error = _h2OService.error!; setState(ViewState.Error); } else { setState(ViewState.Idle); @@ -66,10 +73,11 @@ class H2OViewModel extends BaseViewModel { setState(ViewState.Busy); await _h2OService.getUserProgressForWeekData(); if (_h2OService.hasError) { - error = _h2OService.error; + error = _h2OService.error!; setState(ViewState.Error); } else { - userProgressForWeekDataSeries = createUserProgressForWeekDataSeries(); + // userProgressForWeekDataSeries = createUserProgressForWeekDataSeries(); + userProgressForWeekDataSeries = createUserProgressForWeekDataSeriesNew(); setState(ViewState.Idle); } } @@ -78,52 +86,79 @@ class H2OViewModel extends BaseViewModel { setState(ViewState.Busy); await _h2OService.getUserProgressForMonthData(); if (_h2OService.hasError) { - error = _h2OService.error; + error = _h2OService.error!; setState(ViewState.Error); } else { - userProgressForMonthDataSeries = createUserProgressForMonthDataSeries(); + userProgressForMonthDataSeries = createUserProgressForMonthDataSeriesNew(); setState(ViewState.Idle); } } - List> createUserProgressForWeekDataSeries() { - List globalData = []; + // List> createUserProgressForWeekDataSeries() { + // List globalData = []; + // _h2OService.userProgressForWeekDataList.forEach((UserProgressForWeekDataModel data) { + // globalData.add(new ChartSeries(data.dayName!, data.percentageConsumed!)); + // }); + // Iterable minMaxList = globalData.map((e) => e.x).toList(); + // int maxValue = minMaxList.isEmpty ? 0 : minMaxList.reduce(math.max); + // int minValue = minMaxList.isEmpty ? 0 : minMaxList.reduce(math.min); + // + // if (maxValue == 0 && minValue == 0) { + // maxValue = 1; + // minValue = -1; + // } + // return [ + // Charts.series( + // id: 'Global Revenue', + // domainFn: (ChartSeries sales, _) => sales.y, + // measureFn: (ChartSeries sales, _) => sales.x, + // measureLowerBoundFn: (ChartSeries sales, _) => minValue, + // measureUpperBoundFn: (ChartSeries sales, _) => maxValue, + // data: globalData, + // ), + // ]; + // } + + List createUserProgressForWeekDataSeriesNew() { + List list = []; + _h2OService.userProgressForWeekDataList.forEach((UserProgressForWeekDataModel data) { - globalData.add(new ChartSeries(data.dayName, data.percentageConsumed)); + list.add(new LineChartModel(data.dayName!, data.percentageConsumed!)); }); - return [ - new charts.Series( - id: 'Global Revenue', - domainFn: (ChartSeries sales, _) => sales.y, - measureFn: (ChartSeries sales, _) => sales.x, - data: globalData, - ), - ]; + return list; } - List> createUserProgressForMonthDataSeries() { - List globalData = []; + List createUserProgressForMonthDataSeriesNew() { + List list = []; _h2OService.userProgressForMonthDataList.forEach((UserProgressForMonthDataModel data) { - globalData.add(new ChartSeries(data.monthName, data.percentageConsumed)); + list.add(new LineChartModel(data.monthName!, data.percentageConsumed!)); }); - return [ - new charts.Series( - id: 'Global Revenue', - domainFn: (ChartSeries sales, _) => sales.y, - measureFn: (ChartSeries sales, _) => sales.x, - data: globalData, - ), - ]; + return list; } + // List> createUserProgressForMonthDataSeries() { + // List globalData = []; + // _h2OService.userProgressForMonthDataList.forEach((UserProgressForMonthDataModel data) { + // globalData.add(new ChartSeries(data.monthName!, data.percentageConsumed!)); + // }); + // return [ + // new charts.Series( + // id: 'Global Revenue', + // domainFn: (ChartSeries sales, _) => sales.y, + // measureFn: (ChartSeries sales, _) => sales.x, + // data: globalData, + // ), + // ]; + // } + Future insertUserActivity(InsertUserActivityRequestModel insertUserActivityRequestModel) async { setState(ViewState.BusyLocal); - insertUserActivityRequestModel.mobileNumber = user.mobileNumber.substring(1); - insertUserActivityRequestModel.identificationNo = user.patientIdentificationNo; + insertUserActivityRequestModel.mobileNumber = user!.mobileNumber!.substring(1); + insertUserActivityRequestModel.identificationNo = user!.patientIdentificationNo; await _h2OService.insertUserActivity(insertUserActivityRequestModel); if (_h2OService.hasError) { - error = _h2OService.error; + error = _h2OService.error!; setState(ViewState.ErrorLocal); } else { setState(ViewState.Idle); @@ -134,7 +169,7 @@ class H2OViewModel extends BaseViewModel { setState(ViewState.BusyLocal); await _h2OService.undoUserActivity(); if (_h2OService.hasError) { - error = _h2OService.error; + error = _h2OService.error!; setState(ViewState.ErrorLocal); } else { setState(ViewState.Idle); diff --git a/lib/core/viewModels/AlHabibMedicalService/add_new_address_Request_Model.dart b/lib/core/viewModels/AlHabibMedicalService/add_new_address_Request_Model.dart index 23329a89..af040cb6 100644 --- a/lib/core/viewModels/AlHabibMedicalService/add_new_address_Request_Model.dart +++ b/lib/core/viewModels/AlHabibMedicalService/add_new_address_Request_Model.dart @@ -1,5 +1,5 @@ class AddNewAddressRequestModel { - Customer customer; + Customer? customer; AddNewAddressRequestModel({this.customer}); @@ -12,25 +12,25 @@ class AddNewAddressRequestModel { Map toJson() { final Map data = new Map(); if (this.customer != null) { - data['customer'] = this.customer.toJson(); + data['customer'] = this.customer!.toJson(); } return data; } } class Customer { - List addresses; - int id; - String email; - List roleIds; + List? addresses; + String? id; + String? email; + List? roleIds; Customer({this.addresses, this.id, this.email, this.roleIds}); Customer.fromJson(Map json) { if (json['addresses'] != null) { - addresses = new List(); + addresses = []; json['addresses'].forEach((v) { - addresses.add(new Addresses.fromJson(v)); + addresses!.add(new Addresses.fromJson(v)); }); } id = json['id']; @@ -41,7 +41,7 @@ class Customer { Map toJson() { final Map data = new Map(); if (this.addresses != null) { - data['addresses'] = this.addresses.map((v) => v.toJson()).toList(); + data['addresses'] = this.addresses!.map((v) => v.toJson()).toList(); } data['id'] = this.id; data['email'] = this.email; @@ -51,24 +51,24 @@ class Customer { } class Addresses { - int id; - String firstName; - String lastName; - String email; + String? id; + String? firstName; + String? lastName; + String? email; dynamic company; - int countryId; - String country; - Null stateProvinceId; - String city; - String address1; - String address2; - String zipPostalCode; - String phoneNumber; + int? countryId; + String? country; + dynamic stateProvinceId; + String? city; + String? address1; + String? address2; + String? zipPostalCode; + String? phoneNumber; dynamic faxNumber; - String customerAttributes; - String createdOnUtc; - Null province; - String latLong; + String? customerAttributes; + String? createdOnUtc; + dynamic province; + String? latLong; Addresses( {this.id, diff --git a/lib/core/viewModels/AlHabibMedicalService/cmc_view_model.dart b/lib/core/viewModels/AlHabibMedicalService/cmc_view_model.dart index 65fffe33..629f2918 100644 --- a/lib/core/viewModels/AlHabibMedicalService/cmc_view_model.dart +++ b/lib/core/viewModels/AlHabibMedicalService/cmc_view_model.dart @@ -1,5 +1,6 @@ import 'package:diplomaticquarterapp/core/enum/OrderService.dart'; import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/GetCMCAllOrdersResponseModel.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_get_items_request_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_get_items_response_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_insert_pres_order_request_model.dart'; @@ -12,70 +13,62 @@ import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/cmc_serv import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/customer_addresses_service.dart'; import 'package:diplomaticquarterapp/core/service/parmacyModule/parmacy_module_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; +import 'package:diplomaticquarterapp/main.dart'; import '../../../locator.dart'; import 'add_new_address_Request_Model.dart'; class CMCViewModel extends BaseViewModel { - CMCService _cMCService = - locator(); - CustomerAddressesService _customerAddressesService = - locator(); - List get addressesList => - _customerAddressesService.addressesList; - List get cmcAllServicesList => + CMCService _cMCService = locator(); + CustomerAddressesService _customerAddressesService = locator(); - _cMCService.cmcAllServicesList; + List get addressesList => _customerAddressesService.addressesList; - List get cmcAllPresOrders => - _cMCService.cmcAllPresOrdersList; + List get cmcAllServicesList => _cMCService.cmcAllServicesList; - List get cmcAllOrderDetail => - _cMCService.cmcAllOrderDetail; - List get checkupItems => - _cMCService.checkupItemsList; + List get cmcAllPresOrders => _cMCService.cmcAllPresOrdersList; - PharmacyModuleService _pharmacyModuleService = locator(); + List get cmcAllOrderDetail => _cMCService.cmcAllOrderDetail; - bool get isOrderUpdated => _cMCService.isOrderUpdated; + List get checkupItems => _cMCService.checkupItemsList; - Future getCMCAllServices() async { - await _cMCService - .getCMCAllServices(); - CMCGetItemsRequestModel cMCGetItemsRequestModel = new CMCGetItemsRequestModel(checkupType: cmcAllServicesList[0].iD); + PharmacyModuleService _pharmacyModuleService = locator(); + + GetCMCAllOrdersResponseModel? pendingOrder; + + bool? get isOrderUpdated => _cMCService.isOrderUpdated; - await getCheckupItems(cMCGetItemsRequestModel: cMCGetItemsRequestModel,isFirst: true); + Future getCMCAllServices() async { + await _cMCService.getCMCAllServices(); if (_cMCService.hasError) { - error = _cMCService.error; + error = _cMCService.error!; setState(ViewState.Error); } else { setState(ViewState.Idle); } } - Future getCheckupItems({CMCGetItemsRequestModel cMCGetItemsRequestModel, bool isFirst = false}) async { - if(!isFirst) - setState(ViewState.Busy); - await _cMCService.getCheckupItems(cMCGetItemsRequestModel); + + Future getCheckupItems({CMCGetItemsRequestModel? cMCGetItemsRequestModel, bool isFirst = false}) async { + if (!isFirst) setState(ViewState.Busy); + await _cMCService.getCheckupItems(cMCGetItemsRequestModel!); if (_cMCService.hasError) { - error = _cMCService.error; + error = _cMCService.error!; setState(ViewState.Error); } - if(!isFirst) - setState(ViewState.Idle); + if (!isFirst) setState(ViewState.Idle); } Future getCmcAllPresOrders() async { setState(ViewState.Busy); - await _cMCService.getCmcAllPresOrders(); + // await _cMCService.getCmcAllPresOrders(); + await _cMCService.getCmcAllPresOrdersRC(); if (_cMCService.hasError) { - error = _cMCService.error; + error = _cMCService.error!; setState(ViewState.Error); } else { - var pendingOrder = _cMCService.cmcAllPresOrdersList.firstWhere( - (element) => element.status == 1 || element.status == 2, - orElse: () => null); - if (pendingOrder != null) { - await getOrderDetailByOrderID(pendingOrder); + pendingOrder = _cMCService.cmcAllPresOrdersList.firstWhere((element) => element.statusId == 1 || element.statusId == 2, orElse: () => GetCMCAllOrdersResponseModel()); + if (pendingOrder != null && pendingOrder!.serviceText != null) { + // await getOrderDetailByOrderID(pendingOrder); setState(ViewState.Idle); } else { getCMCAllServices(); @@ -83,44 +76,56 @@ class CMCViewModel extends BaseViewModel { } } - Future updateCmcPresOrder( - UpdatePresOrderRequestModel updatePresOrderRequestModel) async { + Future updateCmcPresOrder(UpdatePresOrderRequestModel updatePresOrderRequestModel) async { setState(ViewState.BusyLocal); - await _cMCService.updateCmcPresOrder( - updatePresOrderRequestModel); + // await _cMCService.updateCmcPresOrder(updatePresOrderRequestModel); + await _cMCService.updateCmcPresOrderRC(updatePresOrderRequestModel); if (_cMCService.hasError) { - error = _cMCService.error; + error = _cMCService.error!; setState(ViewState.ErrorLocal); } else { setState(ViewState.Idle); } } - Future getOrderDetailByOrderID(GetHHCAllPresOrdersResponseModel order) async { - GetOrderDetailByOrderIDRequestModel getOrderDetailByOrderIDRequestModel = - GetOrderDetailByOrderIDRequestModel(presOrderID: order.iD); - await _cMCService - .getOrderDetailByOrderID(getOrderDetailByOrderIDRequestModel); + Future getOrderDetailByOrderID(GetCMCAllOrdersResponseModel order) async { + GetOrderDetailByOrderIDRequestModel getOrderDetailByOrderIDRequestModel = GetOrderDetailByOrderIDRequestModel(presOrderID: order.iD); + await _cMCService.getOrderDetailByOrderID(getOrderDetailByOrderIDRequestModel); + } + + Future insertPresPresOrder({required CMCInsertPresOrderRequestModel order}) async { + setState(ViewState.Busy); + order.createdBy = user.patientID; + order.orderServiceID = OrderService.Comprehensive_Medical_Checkup.getIdOrderService(); + String requestId = await _cMCService.insertPresPresOrder(order: order); + if (_cMCService.hasError) { + error = _cMCService.error!; + setState(ViewState.ErrorLocal); + } else { + getCmcAllPresOrders(); + } + return requestId; } - //TODO check it in uat - Future insertPresPresOrder({CMCInsertPresOrderRequestModel order}) async { + + Future insertCMCOrderRC({required CMCInsertPresOrderRequestModel order}) async { setState(ViewState.Busy); order.createdBy = user.patientID; order.orderServiceID = OrderService.Comprehensive_Medical_Checkup.getIdOrderService(); - await _cMCService.insertPresPresOrder(order: order); + String requestId = await _cMCService.insertCMCOrderRC(order: order); if (_cMCService.hasError) { - error = _cMCService.error; + error = _cMCService.error!; setState(ViewState.ErrorLocal); } else { getCmcAllPresOrders(); } + return requestId; } Future getCustomerAddresses() async { setState(ViewState.Busy); await _customerAddressesService.getCustomerAddresses(); if (_customerAddressesService.hasError) { - error = _customerAddressesService.error; + error = _customerAddressesService.error!; setState(ViewState.ErrorLocal); } else { setState(ViewState.Idle); @@ -129,30 +134,26 @@ class CMCViewModel extends BaseViewModel { Future getCustomerInfo() async { setState(ViewState.Busy); - await _pharmacyModuleService.generatePharmacyToken().then((value) async{ - await _customerAddressesService.getCustomerInfo(); - }); + await _pharmacyModuleService.generatePharmacyToken(); + if (_customerAddressesService.hasError) { - error = _customerAddressesService.error; + error = _customerAddressesService.error!; + await _pharmacyModuleService.createUser(); setState(ViewState.ErrorLocal); } else { + await _pharmacyModuleService.createUser(); await getCustomerAddresses(); } } - Future addAddressInfo( - {AddNewAddressRequestModel addNewAddressRequestModel}) async { - - + Future addAddressInfo({required AddNewAddressRequestModel addNewAddressRequestModel}) async { setState(ViewState.Busy); - await _customerAddressesService.addAddressInfo( - addNewAddressRequestModel: addNewAddressRequestModel - ); + await _customerAddressesService.addAddressInfo(addNewAddressRequestModel: addNewAddressRequestModel); if (_customerAddressesService.hasError) { - error = _customerAddressesService.error; + error = _customerAddressesService.error!; setState(ViewState.ErrorLocal); } else { setState(ViewState.Idle); } } -} \ No newline at end of file +} diff --git a/lib/core/viewModels/AlHabibMedicalService/health-calculator/Bariatrics-viewmodel.dart b/lib/core/viewModels/AlHabibMedicalService/health-calculator/Bariatrics-viewmodel.dart index 5853cc8f..f545caff 100644 --- a/lib/core/viewModels/AlHabibMedicalService/health-calculator/Bariatrics-viewmodel.dart +++ b/lib/core/viewModels/AlHabibMedicalService/health-calculator/Bariatrics-viewmodel.dart @@ -1,9 +1,11 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HealthCalculator/ClinicCategory.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HealthCalculator/DiseasesByClinic.dart'; -import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HealthCalculator/ClinicCategory.dart'; +import 'package:diplomaticquarterapp/core/model/health_calcolator/get_doctor_by_time_model.dart'; +import 'package:diplomaticquarterapp/core/model/health_calcolator/get_doctor_list_calcolation_model.dart'; import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/health-calculator/bariatrics-service.dart'; import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; +import 'package:flutter/cupertino.dart'; import '../../../../locator.dart'; @@ -13,12 +15,15 @@ class BariatricsViewModel extends BaseViewModel { List get clinicCategoryList => _service.clinicCategoryList; List get diseasesList => _service.diseasesList; + List get doctorList => _service.doctorList; + List get doctorListByTime => _service.doctorListByTime; + List doctorLists =[]; void getClinicCategory() async { setState(ViewState.Busy); await _service.getClinicCategory(); if (_service.hasError) { - error = _service.error; + error = _service.error!; setState(ViewState.Error); } else { getDiseaseByClinicId(); @@ -29,7 +34,7 @@ class BariatricsViewModel extends BaseViewModel { setState(ViewState.Busy); await _service.getDiseaseByClinicId(); if (_service.hasError) { - error = _service.error; + error = _service.error!; setState(ViewState.Error); } else { setState(ViewState.Idle); @@ -40,10 +45,33 @@ class BariatricsViewModel extends BaseViewModel { setState(ViewState.Busy); await _service.searchDoctorsByTime(disease); if (_service.hasError) { - error = _service.error; + error = _service.error!; setState(ViewState.ErrorLocal); } else { setState(ViewState.Idle); } } + + void getDoctorList({required DiseasesByClinic disease}) async { + setState(ViewState.Busy); + await _service.getDoctorList(disease:disease); + if (_service.hasError) { + error = _service.error!; + setState(ViewState.Error); + } else { + { + _service.doctorListByTime.forEach((element) { + List patientLabOrdersClinic = + doctorLists.where((elementClinic) => elementClinic.filterName == element.projectName).toList(); + + if (patientLabOrdersClinic.length != 0) { + doctorLists[doctorLists.indexOf(patientLabOrdersClinic[0])].doctorsByTimeList.add(element); + } else { + doctorLists.add(DoctorsListTime(filterName: element.projectName, doctor: element)); + } + }); + setState(ViewState.Idle); + } + } + } } 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 32644fd4..0d617b6a 100644 --- a/lib/core/viewModels/AlHabibMedicalService/home_health_care_view_model.dart +++ b/lib/core/viewModels/AlHabibMedicalService/home_health_care_view_model.dart @@ -1,10 +1,11 @@ +import 'dart:async'; + import 'package:diplomaticquarterapp/core/enum/OrderService.dart'; import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/GetCMCAllOrdersResponseModel.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/HHC_get_all_services_request_modle.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/HHC_get_all_services_response_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/PatientERHHCInsertServicesList.dart'; -import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/get_hhc_all_pres_orders_response_model.dart'; -import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/get_order_detail_by_order_iD_request_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/get_order_detail_by_order_iD_response_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/patient_er_insert_pres_order_request_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/update_pres_oreder_request_model.dart'; @@ -12,50 +13,40 @@ import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/customer import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/home_health_care_service.dart'; import 'package:diplomaticquarterapp/core/service/parmacyModule/parmacy_module_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; -import 'package:intl/intl.dart'; import '../../../locator.dart'; import 'add_new_address_Request_Model.dart'; class HomeHealthCareViewModel extends BaseViewModel { - HomeHealthCareService _homeHealthCareService = - locator(); - - CustomerAddressesService _customerAddressesService = - locator(); + HomeHealthCareService _homeHealthCareService = locator(); - List get hhcAllServicesList => - _homeHealthCareService.hhcAllServicesList; + CustomerAddressesService _customerAddressesService = locator(); + List get hhcAllServicesList => _homeHealthCareService.hhcAllServicesList; - List get addressesList => - _customerAddressesService.addressesList; + List get addressesList => _customerAddressesService.addressesList; - List get hhcAllPresOrders => - _homeHealthCareService.hhcAllPresOrdersList; + List get hhcAllPresOrders => _homeHealthCareService.hhcAllPresOrdersList; - List get hhcAllOrderDetail => - _homeHealthCareService.hhcAllOrderDetail; + List get hhcAllOrderDetail => _homeHealthCareService.hhcAllOrderDetail; PharmacyModuleService _pharmacyModuleService = locator(); + bool get isOrderUpdated => _homeHealthCareService.isOrderUpdated ?? false; + int get orderId => _homeHealthCareService.requestNo ?? 0; + late GetCMCAllOrdersResponseModel pendingOrder; + List patientERHHCInsertServicesList = []; - bool get isOrderUpdated => _homeHealthCareService.isOrderUpdated; - - GetHHCAllPresOrdersResponseModel pendingOrder; - - List patientERHHCInsertServicesList = List(); + dynamic get hhcResponse => _homeHealthCareService.hhcResponse; Future getHHCAllServices() async { - HHCGetAllServicesRequestModel hHCGetAllServicesRequestModel = - new HHCGetAllServicesRequestModel(); - //setState(ViewState.Busy); - await _homeHealthCareService - .getHHCAllServices(hHCGetAllServicesRequestModel); + HHCGetAllServicesRequestModel hHCGetAllServicesRequestModel = new HHCGetAllServicesRequestModel(); + // await _homeHealthCareService.getHHCAllServices(hHCGetAllServicesRequestModel); + await _homeHealthCareService.getHHCAllServicesRC(hHCGetAllServicesRequestModel); if (_homeHealthCareService.hasError) { - error = _homeHealthCareService.error; + error = _homeHealthCareService.error!; setState(ViewState.Error); } else { setState(ViewState.Idle); @@ -63,95 +54,235 @@ class HomeHealthCareViewModel extends BaseViewModel { } Future getHHCAllPresOrders() async { - pendingOrder = null; + pendingOrder = GetCMCAllOrdersResponseModel(); setState(ViewState.Busy); - await _homeHealthCareService.getHHCAllPresOrders(); + await _homeHealthCareService.getHHCAllPresOrdersRC(); if (_homeHealthCareService.hasError) { - error = _homeHealthCareService.error; + error = _homeHealthCareService.error!; setState(ViewState.Error); } else { - pendingOrder = _homeHealthCareService.hhcAllPresOrdersList - .firstWhere((element) => element.status == 1 || element.status == 2, - orElse: () => null); - if (pendingOrder != null) { - await _homeHealthCareService.getOrderDetailByOrderID(pendingOrder.iD); + pendingOrder = _homeHealthCareService.hhcAllPresOrdersList.firstWhere((element) => element.statusId == 1 || element.statusId == 2, orElse: () => GetCMCAllOrdersResponseModel()); + if (pendingOrder != null && pendingOrder.serviceText != null) { + // await _homeHealthCareService.getOrderDetailByOrderID(pendingOrder.iD); setState(ViewState.Idle); } else { getHHCAllServices(); } - } } 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; + error = _homeHealthCareService.error!; setState(ViewState.ErrorLocal); } else { setState(ViewState.Idle); } } - Future insertPresPresOrder({PatientERInsertPresOrderRequestModel order}) async { + Future insertPresPresOrder({PatientERInsertPresOrderRequestModel? order}) async { setState(ViewState.Busy); - order.createdBy = user.patientID; + order!.createdBy = user.patientID; order.orderServiceID = OrderService.HOME_HEALTH_CARE.getIdOrderService(); - await _homeHealthCareService.insertPresPresOrder(order: order); + // await _homeHealthCareService.insertPresPresOrder(order: order); + await _homeHealthCareService.insertHHCOrderRC(order: order); if (_homeHealthCareService.hasError) { - error = _homeHealthCareService.error; + error = _homeHealthCareService.error!; setState(ViewState.ErrorLocal); } else { getHHCAllPresOrders(); } } - Future getCustomerAddresses() async { setState(ViewState.Busy); - await _customerAddressesService.getCustomerAddresses( - ); + await _customerAddressesService.getCustomerAddresses(); if (_customerAddressesService.hasError) { - error = _customerAddressesService.error; + error = _customerAddressesService.error!; setState(ViewState.ErrorLocal); } else { setState(ViewState.Idle); } } - Future getCustomerInfo() async { + Future getCustomerInfo() async { setState(ViewState.Busy); - await _pharmacyModuleService.generatePharmacyToken().then((value) async{ - await _customerAddressesService.getCustomerInfo(); - }); + await _pharmacyModuleService.generatePharmacyToken(); + if (_customerAddressesService.hasError) { - error = _customerAddressesService.error; + error = _customerAddressesService.error!; + await _pharmacyModuleService.createUser(); setState(ViewState.ErrorLocal); } else { - await getCustomerAddresses(); + await _pharmacyModuleService.createUser().then((value) async { + if (!_pharmacyModuleService.hasError) await getCustomerAddresses(); + setState(ViewState.Idle); + }).catchError((err) {}); } + return Future.value(1); } - Future addAddressInfo( - {AddNewAddressRequestModel addNewAddressRequestModel}) async { - + Future addAddressInfo({AddNewAddressRequestModel? addNewAddressRequestModel}) async { setState(ViewState.Busy); - await _pharmacyModuleService.generatePharmacyToken().then((value) async{ - await _customerAddressesService.addAddressInfo( - addNewAddressRequestModel: addNewAddressRequestModel - ); - }); + // await _pharmacyModuleService.generatePharmacyToken().then((value) async { + await _customerAddressesService.addAddressInfo(addNewAddressRequestModel: addNewAddressRequestModel); + // }); if (_customerAddressesService.hasError) { - error = _customerAddressesService.error; + error = _customerAddressesService.error!; setState(ViewState.ErrorLocal); } else { setState(ViewState.Idle); } } +} - -} \ No newline at end of file +// import 'dart:async'; +// +// import 'package:diplomaticquarterapp/core/enum/OrderService.dart'; +// import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +// import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/GetCMCAllOrdersResponseModel.dart'; +// import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/HHC_get_all_services_request_modle.dart'; +// import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/HHC_get_all_services_response_model.dart'; +// import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/PatientERHHCInsertServicesList.dart'; +// import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/get_order_detail_by_order_iD_response_model.dart'; +// import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/patient_er_insert_pres_order_request_model.dart'; +// import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/update_pres_oreder_request_model.dart'; +// import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/customer_addresses_service.dart'; +// import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/home_health_care_service.dart'; +// import 'package:diplomaticquarterapp/core/service/parmacyModule/parmacy_module_service.dart'; +// import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; +// import 'package:diplomaticquarterapp/main.dart'; +// +// import '../../../locator.dart'; +// import 'add_new_address_Request_Model.dart'; +// +// class HomeHealthCareViewModel extends BaseViewModel { +// HomeHealthCareService _homeHealthCareService = locator(); +// +// CustomerAddressesService _customerAddressesService = locator(); +// +// List get hhcAllServicesList => _homeHealthCareService.hhcAllServicesList; +// +// List get addressesList => _customerAddressesService.addressesList; +// +// List get hhcAllPresOrders => _homeHealthCareService.hhcAllPresOrdersList; +// +// List get hhcAllOrderDetail => _homeHealthCareService.hhcAllOrderDetail; +// +// PharmacyModuleService _pharmacyModuleService = locator(); +// +// bool get isOrderUpdated => _homeHealthCareService.isOrderUpdated!; +// +// int get orderId => _homeHealthCareService.requestNo!; +// late GetCMCAllOrdersResponseModel pendingOrder; +// +// List patientERHHCInsertServicesList =[]; +// +// dynamic get hhcResponse => _homeHealthCareService.hhcResponse; +// +// Future getHHCAllServices() async { +// HHCGetAllServicesRequestModel hHCGetAllServicesRequestModel = new HHCGetAllServicesRequestModel(); +// // await _homeHealthCareService.getHHCAllServices(hHCGetAllServicesRequestModel); +// await _homeHealthCareService.getHHCAllServicesRC(hHCGetAllServicesRequestModel); +// +// if (_homeHealthCareService.hasError) { +// error = _homeHealthCareService.error!; +// setState(ViewState.Error); +// } else { +// setState(ViewState.Idle); +// } +// } +// +// Future getHHCAllPresOrders() async { +// pendingOrder = GetCMCAllOrdersResponseModel(); +// setState(ViewState.Busy); +// await _homeHealthCareService.getHHCAllPresOrdersRC(); +// if (_homeHealthCareService.hasError) { +// error = _homeHealthCareService.error!; +// setState(ViewState.Error); +// } else { +// pendingOrder = _homeHealthCareService.hhcAllPresOrdersList.firstWhere((element) => element.statusId == 1 || element.statusId == 2, orElse: () => GetCMCAllOrdersResponseModel()); +// if (pendingOrder != null) { +// logger.d(pendingOrder); +// // await _homeHealthCareService.getOrderDetailByOrderID(pendingOrder.iD); +// setState(ViewState.Idle); +// } else { +// getHHCAllServices(); +// } +// } +// } +// +// Future updateHHCPresOrder(UpdatePresOrderRequestModel updatePresOrderRequestModel) async { +// setState(ViewState.Busy); +// // await _homeHealthCareService.updateHHCPresOrder(updatePresOrderRequestModel); +// await _homeHealthCareService.updateHHCPresOrderRC(updatePresOrderRequestModel); +// if (_homeHealthCareService.hasError) { +// error = _homeHealthCareService.error!; +// setState(ViewState.ErrorLocal); +// } else { +// setState(ViewState.Idle); +// } +// } +// +// Future insertPresPresOrder({required PatientERInsertPresOrderRequestModel order}) async { +// setState(ViewState.Busy); +// order.createdBy = user!.patientID; +// order.orderServiceID = OrderService.HOME_HEALTH_CARE.getIdOrderService(); +// // await _homeHealthCareService.insertPresPresOrder(order: order); +// await _homeHealthCareService.insertHHCOrderRC(order: order); +// if (_homeHealthCareService.hasError) { +// error = _homeHealthCareService.error!; +// setState(ViewState.ErrorLocal); +// } else { +// getHHCAllPresOrders(); +// } +// } +// +// Future getCustomerAddresses() async { +// setState(ViewState.Busy); +// await _customerAddressesService.getCustomerAddresses(); +// if (_customerAddressesService.hasError) { +// error = _customerAddressesService.error!; +// setState(ViewState.ErrorLocal); +// } else { +// setState(ViewState.Idle); +// } +// } +// +// Future getCustomerInfo() async { +// setState(ViewState.Busy); +// await _pharmacyModuleService.generatePharmacyToken(); +// +// if (_customerAddressesService.hasError) { +// error = _customerAddressesService.error!; +// await _pharmacyModuleService.createUser(); +// setState(ViewState.ErrorLocal); +// } else { +// await _pharmacyModuleService.createUser().then((value) async { +// if (!_pharmacyModuleService.hasError) await getCustomerAddresses(); +// setState(ViewState.Idle); +// }).catchError((err) {}); +// } +// return Future.value(1); +// } +// +// Future addAddressInfo({required AddNewAddressRequestModel addNewAddressRequestModel}) async { +// setState(ViewState.Busy); +// +// // await _pharmacyModuleService.generatePharmacyToken().then((value) async { +// await _customerAddressesService.addAddressInfo(addNewAddressRequestModel: addNewAddressRequestModel); +// // }); +// +// if (_customerAddressesService.hasError) { +// error = _customerAddressesService.error!; +// setState(ViewState.ErrorLocal); +// } else { +// setState(ViewState.Idle); +// } +// } +// } diff --git a/lib/core/viewModels/PharmacyPagesViewModel.dart b/lib/core/viewModels/PharmacyPagesViewModel.dart new file mode 100644 index 00000000..7d26fbcf --- /dev/null +++ b/lib/core/viewModels/PharmacyPagesViewModel.dart @@ -0,0 +1,17 @@ +import 'package:flutter/cupertino.dart'; + +class PharmacyPagesViewModel with ChangeNotifier { + int currentTab = 0; + PageController? pageController; + + PharmacyPagesViewModel() { + pageController = PageController(keepPage: true); + } + changeCurrentTab(int tab) { + if (pageController!.hasClients) { + currentTab = tab; + pageController!.jumpToPage(tab); + notifyListeners(); + } + } +} diff --git a/lib/core/viewModels/TermsConditionsViewModel.dart b/lib/core/viewModels/TermsConditionsViewModel.dart index 0cd667cf..f458ce9f 100644 --- a/lib/core/viewModels/TermsConditionsViewModel.dart +++ b/lib/core/viewModels/TermsConditionsViewModel.dart @@ -14,7 +14,7 @@ class TermsConditionsViewModel extends BaseViewModel{ setState(ViewState.Busy); await _service.getUserTermsAndConditions(); if (_service.hasError) { - error = _service.error; + error = _service.error!; setState(ViewState.Error); } else { setState(ViewState.Idle); 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 1972e08f..5e25e3e8 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,13 +21,13 @@ 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); await _eReferralService.getRelationTypes(); if (_eReferralService.hasError) { - error = _eReferralService.error; + error = _eReferralService.error!; setState(ViewState.Error); } else{ setState(ViewState.Idle); @@ -37,18 +37,22 @@ class EReferralViewModel extends BaseViewModel { setState(ViewState.Busy); await _eReferralService.getAllCities(); if (_eReferralService.hasError) { - error = _eReferralService.error; + error = _eReferralService.error!; setState(ViewState.Error); } else{ setState(ViewState.Idle); } } - void sendActivationCodeForEReferral(SendActivationCodeForEReferralRequestModel sendActivationCodeForEReferralRequestModel) async { + void getAllProjects() async { + + } +//Changed By Aamir into Future + Future sendActivationCodeForEReferral(SendActivationCodeForEReferralRequestModel sendActivationCodeForEReferralRequestModel) async { setState(ViewState.BusyLocal); await _eReferralService.sendActivationCodeForEReferral(sendActivationCodeForEReferralRequestModel); if (_eReferralService.hasError) { - error = _eReferralService.error; + error = _eReferralService.error!; setState(ViewState.ErrorLocal); } else{ setState(ViewState.Idle); @@ -59,19 +63,19 @@ class EReferralViewModel extends BaseViewModel { setState(ViewState.BusyLocal); await _eReferralService.checkActivationCodeForEReferral(checkActivationCodeForEReferralRequestModel); if (_eReferralService.hasError) { - error = _eReferralService.error; + error = _eReferralService.error!; setState(ViewState.ErrorLocal); } else{ setState(ViewState.Idle); } } - - void createEReferral( +//Changed by Aamir to Future + Future createEReferral( CreateEReferralRequestModel createEReferralRequestModel) async { setState(ViewState.BusyLocal); await _eReferralService.createEReferral(createEReferralRequestModel); if (_eReferralService.hasError) { - error = _eReferralService.error; + error = _eReferralService.error!; setState(ViewState.ErrorLocal); } else { setState(ViewState.Idle); @@ -82,7 +86,7 @@ class EReferralViewModel extends BaseViewModel { setState(ViewState.BusyLocal); await _eReferralService.getEReferrals(searchEReferralRequestModel); if (_eReferralService.hasError) { - error = _eReferralService.error; + error = _eReferralService.error!; setState(ViewState.ErrorLocal); } else { setState(ViewState.Idle); diff --git a/lib/core/viewModels/ancillary_orders_view_model.dart b/lib/core/viewModels/ancillary_orders_view_model.dart index 77eb4237..51b12087 100644 --- a/lib/core/viewModels/ancillary_orders_view_model.dart +++ b/lib/core/viewModels/ancillary_orders_view_model.dart @@ -1,36 +1,37 @@ +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/service/ancillary_orders_service.dart'; import 'package:diplomaticquarterapp/models/anicllary-orders/ancillary_order_list_model.dart'; import 'package:diplomaticquarterapp/models/anicllary-orders/ancillary_order_proc_model.dart'; -import 'base_view_model.dart'; import '../../locator.dart'; -import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'base_view_model.dart'; class AnciallryOrdersViewModel extends BaseViewModel { bool hasError = false; AncillaryOrdersService _ancillaryService = locator(); - List get ancillaryLists => - _ancillaryService.ancillaryLists; - List get ancillaryListsDetails => - _ancillaryService.ancillaryProcLists; + + List get ancillaryLists => _ancillaryService.ancillaryLists; + + List get ancillaryListsDetails => _ancillaryService.ancillaryProcLists; + Future getOrders() async { hasError = false; setState(ViewState.Busy); await _ancillaryService.getOrders(); if (_ancillaryService.hasError) { - error = _ancillaryService.error; + error = _ancillaryService.error!; setState(ViewState.ErrorLocal); } else setState(ViewState.Idle); } - Future getOrdersDetails(appointmentNo, orderNo) async { + Future getOrdersDetails(appointmentNo, orderNo, projectID) async { hasError = false; setState(ViewState.Busy); - await _ancillaryService.getOrdersDetails(appointmentNo, orderNo); + await _ancillaryService.getOrdersDetails(appointmentNo, orderNo, projectID); if (_ancillaryService.hasError) { - error = _ancillaryService.error; + error = _ancillaryService.error!; setState(ViewState.ErrorLocal); } else setState(ViewState.Idle); diff --git a/lib/core/viewModels/appointment_rate_view_model.dart b/lib/core/viewModels/appointment_rate_view_model.dart index e1bdfc9e..b3cb666c 100644 --- a/lib/core/viewModels/appointment_rate_view_model.dart +++ b/lib/core/viewModels/appointment_rate_view_model.dart @@ -3,48 +3,55 @@ import 'package:diplomaticquarterapp/core/model/rate/appointment_details.dart'; import 'package:diplomaticquarterapp/core/model/rate/appoitment_rated.dart'; import 'package:diplomaticquarterapp/core/service/appointment_rate_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; + import '../../locator.dart'; class AppointmentRateViewModel extends BaseViewModel { - AppointmentRateService _appointmentRateService = - locator(); + AppointmentRateService _appointmentRateService = locator(); bool isHaveAppointmentNotRate = false; - AppointmentDetails get appointmentDetails => _appointmentRateService.appointmentDetails; - + AppointmentDetails get appointmentDetails => _appointmentRateService.appointmentDetails!; - Future getIsLastAppointmentRatedList() async { + Future getIsLastAppointmentRatedList(int languageID) async { isHaveAppointmentNotRate = false; setState(ViewState.Busy); - await _appointmentRateService.getIsLastAppointmentRatedList(); + await _appointmentRateService.getIsLastAppointmentRatedList(languageID); if (_appointmentRateService.hasError) { - error = _appointmentRateService.error; + error = _appointmentRateService.error!; setState(ViewState.Error); } else { - if(_appointmentRateService.appointmentRatedList.length>0) - await getAppointmentDetails(); + if (_appointmentRateService.appointmentRatedList.length > 0) await getAppointmentDetails(); } } getAppointmentDetails() async { await _appointmentRateService.getAppointmentDetails(); if (_appointmentRateService.hasError) { - error = _appointmentRateService.error; + error = _appointmentRateService.error!; setState(ViewState.Error); } else { - if (_appointmentRateService.appointmentDetails != null) - isHaveAppointmentNotRate = true; + if (_appointmentRateService.appointmentDetails != null) isHaveAppointmentNotRate = true; + setState(ViewState.Idle); + } + } + + Future sendAppointmentRate(int rate, int appointmentNo, int projectID, int doctorID, int clinicID, String note, int languageID) async { + setState(ViewState.Busy); + await _appointmentRateService.sendAppointmentRate(rate, appointmentNo, projectID, doctorID, clinicID, note, languageID); + if (_appointmentRateService.hasError) { + error = _appointmentRateService.error!; + setState(ViewState.ErrorLocal); + } else { setState(ViewState.Idle); + _appointmentRateService.deleteAllAppAppointmentRate(); } } - Future sendAppointmentRate(int rate, int appointmentNo, int projectID, - int doctorID, int clinicID, String note) async { + Future sendDoctorRate(int rate, int appointmentNo, int projectID, int doctorID, int clinicID, String note, String appoDate, String docName, String projectName, String clinicName) async { setState(ViewState.Busy); - await _appointmentRateService.sendAppointmentRate( - rate, appointmentNo, projectID, doctorID, clinicID, note); + await _appointmentRateService.sendDoctorRate(rate, appointmentNo, projectID, doctorID, clinicID, note, appoDate, docName, projectName, clinicName); if (_appointmentRateService.hasError) { - error = _appointmentRateService.error; + error = _appointmentRateService.error!; setState(ViewState.ErrorLocal); } else { setState(ViewState.Idle); @@ -52,14 +59,11 @@ class AppointmentRateViewModel extends BaseViewModel { } } - AppoitmentRated get lastAppointmentRated => - _appointmentRateService.lastAppointmentRated; + AppoitmentRated get lastAppointmentRated => _appointmentRateService.lastAppointmentRated; - deleteAppointmentRated(AppoitmentRated appointmentRated) => - _appointmentRateService.deleteAppointmentRated(appointmentRated); + deleteAppointmentRated(AppoitmentRated appointmentRated) => _appointmentRateService.deleteAppointmentRated(appointmentRated); - deleteAppAppointmentRate() => - _appointmentRateService.deleteAllAppAppointmentRate(); + deleteAppAppointmentRate() => _appointmentRateService.deleteAllAppAppointmentRate(); setIsRated(bool isRated) { this.isHaveAppointmentNotRate = isRated; diff --git a/lib/core/viewModels/base_view_model.dart b/lib/core/viewModels/base_view_model.dart index aab267e9..2efae385 100644 --- a/lib/core/viewModels/base_view_model.dart +++ b/lib/core/viewModels/base_view_model.dart @@ -15,30 +15,29 @@ class BaseViewModel extends ChangeNotifier { ViewState get state => _state; String error = ""; + String languageID = "en"; - AuthenticatedUser user; + late AuthenticatedUser user; AppSharedPreferences sharedPref = AppSharedPreferences(); AuthenticatedUserObject authenticatedUserObject = locator(); void setState(ViewState viewState) { _state = viewState; - if (viewState == ViewState.Busy || viewState == ViewState.BusyLocal) - error = ""; + if (viewState == ViewState.Busy || viewState == ViewState.BusyLocal) error = ""; if (hasListeners) notifyListeners(); } - setUser(AuthenticatedUser user){ + setUser(AuthenticatedUser user) { this.user = user; notifyListeners(); } - + BaseViewModel() { //authenticatedUserObject.getUser(); - user = authenticatedUserObject.user; + user = authenticatedUserObject.user!; this.isLogin = authenticatedUserObject.isLogin; - } _getUser() async { @@ -51,6 +50,10 @@ class BaseViewModel extends ChangeNotifier { notifyListeners(); } + Future getSavedLanguage() async { + languageID = await sharedPref.getString(APP_LANGUAGE); + } + @override void dispose() { removeListener(() {}); diff --git a/lib/core/viewModels/blooddonation/blood_details_view_model.dart b/lib/core/viewModels/blooddonation/blood_details_view_model.dart index a6b341cf..028be89a 100644 --- a/lib/core/viewModels/blooddonation/blood_details_view_model.dart +++ b/lib/core/viewModels/blooddonation/blood_details_view_model.dart @@ -1,6 +1,7 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/blooddonation/blood_groub_details.dart'; import 'package:diplomaticquarterapp/core/service/blood/blood_details_servies.dart'; + import '../../../locator.dart'; import '../base_view_model.dart'; @@ -16,7 +17,7 @@ class BloodDeatailsViewModel extends BaseViewModel{ await _bloodDetailsService .getAllBloodOrders();; if (_bloodDetailsService.hasError) { - error = _bloodDetailsService.error; + error = _bloodDetailsService.error!; setState(ViewState.Error); } else setState(ViewState.Idle); diff --git a/lib/core/viewModels/blooddonation/booddonation_view_model.dart b/lib/core/viewModels/blooddonation/booddonation_view_model.dart index b9c13c57..9c765d3e 100644 --- a/lib/core/viewModels/blooddonation/booddonation_view_model.dart +++ b/lib/core/viewModels/blooddonation/booddonation_view_model.dart @@ -16,7 +16,7 @@ class BloodDonationViewModel extends BaseViewModel{ await _bloodDonationService.getAllCitiesOrders(); // getHospitals(); if (_bloodDonationService.hasError) { - error = _bloodDonationService.error; + error = _bloodDonationService.error!; setState(ViewState.Error); } else setState(ViewState.Idle); diff --git a/lib/core/viewModels/child_vaccines/add_new_child_view_model.dart b/lib/core/viewModels/child_vaccines/add_new_child_view_model.dart index eebaca02..c8068a5d 100644 --- a/lib/core/viewModels/child_vaccines/add_new_child_view_model.dart +++ b/lib/core/viewModels/child_vaccines/add_new_child_view_model.dart @@ -1,9 +1,7 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/childvaccines/add_newchild_model.dart'; -import 'package:diplomaticquarterapp/core/model/childvaccines/delete_baby_model.dart'; import 'package:diplomaticquarterapp/core/service/childvaccines/add_new_child_service.dart'; import 'package:diplomaticquarterapp/core/service/childvaccines/child_vaccines_service.dart'; -import 'package:diplomaticquarterapp/core/service/childvaccines/delete_baby_service.dart'; import '../../../locator.dart'; import '../base_view_model.dart'; @@ -16,18 +14,18 @@ class AddNewChildViewModel extends BaseViewModel { // DeleteBabyService _deleteBabyService = locator(); bool isAdded = false; ///create new baby - createNewBabyOrders({ CreateNewBaby newChild}) async { + createNewBabyOrders({ required CreateNewBaby newChild}) async { setState(ViewState.Busy); await _creteNewBabyService.getCreateNewBabyOrders(newChild: newChild, userID: _childVaccinesService.userID); if (_creteNewBabyService.hasError) { - error = _creteNewBabyService.error; + error = _creteNewBabyService.error!; setState(ViewState.Error); } else { isAdded = true; setState(ViewState.Idle); await _childVaccinesService.getAllBabyInformationOrders(); if (_childVaccinesService.hasError) { - error = _childVaccinesService.error; + error = _childVaccinesService.error!; setState(ViewState.Error); } else{ diff --git a/lib/core/viewModels/child_vaccines/child_vaccines_view_model.dart b/lib/core/viewModels/child_vaccines/child_vaccines_view_model.dart index 7c4af285..6c9aad1b 100644 --- a/lib/core/viewModels/child_vaccines/child_vaccines_view_model.dart +++ b/lib/core/viewModels/child_vaccines/child_vaccines_view_model.dart @@ -1,8 +1,6 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/childvaccines/List_BabyInformationModel.dart'; import 'package:diplomaticquarterapp/core/model/childvaccines/delete_baby_model.dart'; - -import 'package:diplomaticquarterapp/core/service/childvaccines/child_vaccines_service.dart'; //======== import 'package:diplomaticquarterapp/core/service/childvaccines/add_new_child_service.dart'; import 'package:diplomaticquarterapp/core/service/childvaccines/child_vaccines_service.dart'; @@ -30,7 +28,7 @@ class ChildVaccinesViewModel extends BaseViewModel{ setState(ViewState.Busy); await _childVaccinesService.getNewUserOrders(); if (_childVaccinesService.hasError) { - error = _childVaccinesService.error; + error = _childVaccinesService.error!; setState(ViewState.Error); } else getBabyInformatioRequestOrders(); @@ -39,7 +37,7 @@ class ChildVaccinesViewModel extends BaseViewModel{ getBabyInformatioRequestOrders() async { await _childVaccinesService.getAllBabyInformationOrders(); if (_childVaccinesService.hasError) { - error = _childVaccinesService.error; + error = _childVaccinesService.error!; setState(ViewState.Error); } else setState(ViewState.Idle); @@ -48,21 +46,21 @@ class ChildVaccinesViewModel extends BaseViewModel{ ///delete baby - deleteBabyOrders({ DeleteBaby newChild}) async { + deleteBabyOrders({ required DeleteBaby newChild}) async { setState(ViewState.Busy); //await _creteNewBabyService.getCreateNewBabyOrders(newChild: newChild, userID: _childVaccinesService.userID); await _deleteBabyService.getDeleteBabyOrder(deleteChild: newChild,babyID: newChild.babyID); //getDeleteBabyOrder(deleteChild: newChild,); // getDeleteBabyOrder if (_creteNewBabyService.hasError) { - error = _creteNewBabyService.error; + error = _creteNewBabyService.error!; setState(ViewState.Error); } else { isDeleted = true; setState(ViewState.Idle); await _childVaccinesService.getAllBabyInformationOrders(); if (_childVaccinesService.hasError) { - error = _childVaccinesService.error; + error = _childVaccinesService.error!; setState(ViewState.Error); } else{ diff --git a/lib/core/viewModels/child_vaccines/user_information_view_model.dart b/lib/core/viewModels/child_vaccines/user_information_view_model.dart index 43269f42..43bbde60 100644 --- a/lib/core/viewModels/child_vaccines/user_information_view_model.dart +++ b/lib/core/viewModels/child_vaccines/user_information_view_model.dart @@ -1,8 +1,9 @@ +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/childvaccines/user_information_model.dart'; import 'package:diplomaticquarterapp/core/service/childvaccines/user_information_service.dart'; + import '../../../locator.dart'; import '../base_view_model.dart'; -import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; class UserInformationViewModel extends BaseViewModel { UserInformationService _userInformationService = @@ -15,7 +16,7 @@ class UserInformationViewModel extends BaseViewModel { setState(ViewState.Busy); await _userInformationService.getUserInformationOrders(); if (_userInformationService.hasError) { - error = _userInformationService.error; + error = _userInformationService.error!; setState(ViewState.Error); } else setState(ViewState.Idle); diff --git a/lib/core/viewModels/child_vaccines/vaccination_table_view_model.dart b/lib/core/viewModels/child_vaccines/vaccination_table_view_model.dart index d0ccb8a1..f1af0baf 100644 --- a/lib/core/viewModels/child_vaccines/vaccination_table_view_model.dart +++ b/lib/core/viewModels/child_vaccines/vaccination_table_view_model.dart @@ -1,8 +1,6 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/childvaccines/List_BabyInformationModel.dart'; -import 'package:diplomaticquarterapp/core/model/childvaccines/add_newchild_model.dart'; import 'package:diplomaticquarterapp/core/model/childvaccines/create_vaccination_table.dart'; -import 'package:diplomaticquarterapp/core/service/childvaccines/add_new_child_service.dart'; import 'package:diplomaticquarterapp/core/service/childvaccines/vaccination_table_service.dart'; import '../../../locator.dart'; @@ -20,7 +18,7 @@ class VaccinationTableViewModel extends BaseViewModel{ await _creteVaccinationTableService.getCreateVaccinationTableOrders(babyInfo, sendEmail);//getCreateNewBabyOrders(); if ( _creteVaccinationTableService.hasError) { - error = _creteVaccinationTableService.error; + error = _creteVaccinationTableService.error!; setState(ViewState.Error); } else setState(ViewState.Idle); diff --git a/lib/core/viewModels/contactus/findus_view_model.dart b/lib/core/viewModels/contactus/findus_view_model.dart index 800c3106..f6e1754f 100644 --- a/lib/core/viewModels/contactus/findus_view_model.dart +++ b/lib/core/viewModels/contactus/findus_view_model.dart @@ -1,8 +1,9 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/contactus/get_hmg_locations.dart'; import 'package:diplomaticquarterapp/core/service/contactus/finadus_service.dart'; -import '../base_view_model.dart'; + import '../../../locator.dart'; +import '../base_view_model.dart'; class FindusViewModel extends BaseViewModel { FindusService _findusService = locator(); @@ -22,7 +23,7 @@ class FindusViewModel extends BaseViewModel { await _findusService.getAllFindUsOrders(); if (_findusService.hasError) { - error = _findusService.error; + error = _findusService.error!; setState(ViewState.Error); } else setState(ViewState.Idle); diff --git a/lib/core/viewModels/contactus/livechat_view_model.dart b/lib/core/viewModels/contactus/livechat_view_model.dart index 8df4e801..76b70ab5 100644 --- a/lib/core/viewModels/contactus/livechat_view_model.dart +++ b/lib/core/viewModels/contactus/livechat_view_model.dart @@ -1,8 +1,9 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/contactus/get_patientI_cprojects.dart'; import 'package:diplomaticquarterapp/core/service/contactus/livechat_service.dart'; -import '../base_view_model.dart'; + import '../../../locator.dart'; +import '../base_view_model.dart'; class LiveChatViewModel extends BaseViewModel{ @@ -22,7 +23,7 @@ class LiveChatViewModel extends BaseViewModel{ await _liveChatService.getAllLiveChatOrders(); if (_liveChatService.hasError) { - error = _liveChatService.error; + error = _liveChatService.error!; setState(ViewState.Error); } else setState(ViewState.Idle); diff --git a/lib/core/viewModels/dashboard_view_model.dart b/lib/core/viewModels/dashboard_view_model.dart index e085e476..b3b85269 100644 --- a/lib/core/viewModels/dashboard_view_model.dart +++ b/lib/core/viewModels/dashboard_view_model.dart @@ -2,8 +2,7 @@ import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/service/medical/vital_sign_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; -import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; -import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; + import '../../locator.dart'; class DashboardViewModel extends BaseViewModel { @@ -14,15 +13,18 @@ class DashboardViewModel extends BaseViewModel { String get heightCm => _vitalSignService.heightCm; String booldType = "-"; - // ToDoCountProviderModel toDoProvider = - // Provider.of(AppGlobal.context); + DashboardViewModel() { + // this.getPatientRadOrders(); + } getPatientRadOrders() async { if (isLogin && _vitalSignService.weightKg.isEmpty) { setState(ViewState.Busy); await _vitalSignService.getPatientRadOrders(); + booldType = await sharedPref.getString(BLOOD_TYPE) ?? "-"; + if (_vitalSignService.hasError) { - error = _vitalSignService.error; + error = _vitalSignService.error!; setState(ViewState.ErrorLocal); } else { booldType = await sharedPref.getString(BLOOD_TYPE) ?? "-"; @@ -30,17 +32,4 @@ class DashboardViewModel extends BaseViewModel { } } } - -// getToDoCount() { -// toDoProvider.setState(0); -// ClinicListService service = new ClinicListService(); -// service.getActiveAppointmentNo(AppGlobal.context).then((res) { -// print(res['AppointmentActiveNumber']); -// if (res['MessageStatus'] == 1) { -// toDoProvider.setState(res['AppointmentActiveNumber']); -// } else {} -// }).catchError((err) { -// print(err); -// }); -// } } diff --git a/lib/core/viewModels/er/EdOnlineViewModel.dart b/lib/core/viewModels/er/EdOnlineViewModel.dart index 1970a965..015d97f4 100644 --- a/lib/core/viewModels/er/EdOnlineViewModel.dart +++ b/lib/core/viewModels/er/EdOnlineViewModel.dart @@ -15,17 +15,16 @@ class EdOnlineViewModel extends BaseViewModel { List get hospitals => _hospitalService.hospitals; - List get triageQuestionsModelList => - _edOnlineServices.triageQuestionsModelList; + List get triageQuestionsModelList => _edOnlineServices.triageQuestionsModelList; - ErPatientShareModel get erPatientShareModel => _edOnlineServices.erPatientShareModel; + ErPatientShareModel? get erPatientShareModel => _edOnlineServices.erPatientShareModel; - Future getHospitals() async { + Future getHospitals(int languageID) async { if(_hospitalService.hospitals.isEmpty){ setState(ViewState.Busy); - await _hospitalService.getHospitals(); + await _hospitalService.getHospitals(languageID); if (_hospitalService.hasError) { - error = _hospitalService.error; + error = _hospitalService.error!; setState(ViewState.Error); } else setState(ViewState.Idle); @@ -33,14 +32,14 @@ class EdOnlineViewModel extends BaseViewModel { } Future getQuestions() async { - if(_edOnlineServices.triageQuestionsModelList.isEmpty){ - setState(ViewState.Busy); - await _edOnlineServices.getQuestions(); - if (_edOnlineServices.hasError) { - error = _edOnlineServices.error; - setState(ViewState.Error); - } else - setState(ViewState.Idle); + if (_edOnlineServices.triageQuestionsModelList.isEmpty) { + setState(ViewState.Busy); + await _edOnlineServices.getQuestions(); + if (_edOnlineServices.hasError) { + error = _edOnlineServices!.error!; + setState(ViewState.Error); + } else + setState(ViewState.Idle); } } @@ -48,27 +47,17 @@ class EdOnlineViewModel extends BaseViewModel { setState(ViewState.Busy); await _edOnlineServices.getPatientPaymentInformation(); if (_edOnlineServices.hasError) { - error = _edOnlineServices.error; + error = _edOnlineServices.error!; setState(ViewState.Error); } else setState(ViewState.Idle); } - Future saveQuestionsInformation( - {String notes, - String chiefComplaint, - int projectId, - DateTime selectedTime, - List selectedQuestions}) async { + Future saveQuestionsInformation({String? notes, String? chiefComplaint, int? projectId, DateTime? selectedTime, List? selectedQuestions}) async { setState(ViewState.BusyLocal); - await _edOnlineServices.saveQuestionsInformation( - notes: notes, - projectId: projectId, - chiefComplaint: chiefComplaint, - selectedTime: selectedTime, - selectedQuestions: selectedQuestions); + await _edOnlineServices.saveQuestionsInformation(notes: notes, projectId: projectId, chiefComplaint: chiefComplaint, selectedTime: selectedTime, selectedQuestions: selectedQuestions); if (_edOnlineServices.hasError) { - error = _edOnlineServices.error; + error = _edOnlineServices.error!; setState(ViewState.ErrorLocal); } else setState(ViewState.Idle); diff --git a/lib/core/viewModels/er/am_request_view_model.dart b/lib/core/viewModels/er/am_request_view_model.dart index 5f6d40d5..aa2a01b2 100644 --- a/lib/core/viewModels/er/am_request_view_model.dart +++ b/lib/core/viewModels/er/am_request_view_model.dart @@ -1,6 +1,7 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/er/AmbulanceRequestOrdersModel.dart'; import 'package:diplomaticquarterapp/core/model/er/PatientAllPresOrders.dart'; -import 'package:diplomaticquarterapp/core/model/er/PatientER.dart'; +import 'package:diplomaticquarterapp/core/model/er/PatientER_RC.dart'; import 'package:diplomaticquarterapp/core/model/er/PickUpRequestPresOrder.dart'; import 'package:diplomaticquarterapp/core/model/er/get_all_transportation_method_list_model.dart'; import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; @@ -10,64 +11,77 @@ import 'package:diplomaticquarterapp/core/service/medical/medical_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; import 'package:flutter/cupertino.dart'; -import '../base_view_model.dart'; + import '../../../locator.dart'; +import '../base_view_model.dart'; class AmRequestViewModel extends BaseViewModel { AmService _amService = locator(); HospitalService _hospitalService = locator(); MedicalService _medicalService = locator(); - List get amRequestModeList => - _amService.amModelList; + List get amRequestModeList => _amService.amModelList; - List get patientAllPresOrdersList => - _amService.patientAllPresOrdersList; + List get patientAllPresOrdersList => _amService.patientAllPresOrdersList; - List get appoitmentAllHistoryResultList => - _medicalService.appoitmentAllHistoryResultList; + List get appoitmentAllHistoryResultList => _medicalService.appoitmentAllHistoryResultList; + + List get patientAmbulanceRequestOrdersList => _amService.patientAmbulanceRequestOrdersList; List get hospitals => _hospitalService.hospitals; - bool get hasPendingOrder =>_amService.hasPendingOrder; + bool get hasPendingOrder => _amService.hasPendingOrder; + + PickUpRequestPresOrder? get pickUpRequestPresOrder => _amService.pickUpRequestPresOrder; - PickUpRequestPresOrder get pickUpRequestPresOrder =>_amService.pickUpRequestPresOrder; + AmbulanceRequestOrdersModel? get pendingAmbulanceRequestOrder => _amService.pendingAmbulanceRequestOrder; Future getAppointmentHistory() async { setState(ViewState.BusyLocal); await _medicalService.getAppointmentHistory(isActiveAppointment: true); if (_medicalService.hasError) { - error = _medicalService.error; + error = _medicalService.error!; setState(ViewState.ErrorLocal); } else setState(ViewState.Idle); } - Future getAmRequestOrders() async { + Future getAmRequestOrders(int languageID) async { setState(ViewState.Busy); await _amService.getAllTransportationOrders(); if (_amService.hasError) { - error = _amService.error; + error = _amService.error!; + setState(ViewState.Error); + } else + getHospitals(languageID); + } + + Future getHospitals(int languageID) async { + setState(ViewState.Busy); + await _hospitalService.getHospitals(languageID, isResBasedOnLoc: false); + if (_hospitalService.hasError) { + error = _hospitalService.error!; setState(ViewState.Error); } else - getHospitals(); + // getPatientAllPresOrdersList(); + await getPatientAllPresOrdersListRC(); } - Future getHospitals() async { + Future getPatientAllPresOrdersListRC() async { setState(ViewState.Busy); - await _hospitalService.getHospitals(isResBasedOnLoc: false); + await _amService.getPatientAllPresOrdersListRC(authenticatedUserObject.user!.patientID); if (_hospitalService.hasError) { - error = _hospitalService.error; + error = _hospitalService.error!; setState(ViewState.Error); } else - getPatientAllPresOrdersList(); + setState(ViewState.Idle); } Future getPatientAllPresOrdersList() async { setState(ViewState.Busy); await _amService.getPatientAllPresOrdersList(); if (_hospitalService.hasError) { - error = _hospitalService.error; + error = _hospitalService.error!; setState(ViewState.Error); } else if (_amService.hasPendingOrder) { getOrderDetails(); @@ -79,30 +93,32 @@ class AmRequestViewModel extends BaseViewModel { setState(ViewState.Busy); await _amService.getOrderDetails(); if (_amService.hasError) { - error = _amService.error; + error = _amService.error!; setState(ViewState.Error); } else setState(ViewState.Idle); } - Future updatePressOrder({@required int presOrderID}) async { + Future updatePressOrder({required int presOrderID}) async { setState(ViewState.Busy); - await _amService.updatePressOrder(presOrderID: presOrderID); + // await _amService.updatePressOrder(presOrderID: presOrderID); + await _amService.updatePressOrderRC(presOrderID: presOrderID, patientID: authenticatedUserObject.user!.patientID!); if (_amService.hasError) { - error = _amService.error; + error = _amService.error!; setState(ViewState.Error); } else - getPatientAllPresOrdersList(); + getPatientAllPresOrdersListRC(); } - Future insertERPressOrder({@required PatientER patientER}) async { + Future insertERPressOrder({required PatientER_RC patientER}) async { setState(ViewState.Busy); await _amService.insertERPressOrder(patientER: patientER); if (_amService.hasError) { - error = _amService.error; + error = _amService.error!; setState(ViewState.ErrorLocal); } else - getAmRequestOrders(); + // getAmRequestOrders(); + await getPatientAllPresOrdersListRC(); } } diff --git a/lib/core/viewModels/er/near_hospital_view_model.dart b/lib/core/viewModels/er/near_hospital_view_model.dart index f12aa28f..2f597568 100644 --- a/lib/core/viewModels/er/near_hospital_view_model.dart +++ b/lib/core/viewModels/er/near_hospital_view_model.dart @@ -1,9 +1,7 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/er/projectavgerwaitingtime.dart'; - import 'package:diplomaticquarterapp/core/service/er/er_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; -import 'package:diplomaticquarterapp/pages/BookAppointment/widgets/BranchView.dart'; import '../../../locator.dart'; @@ -13,7 +11,7 @@ class NearHospitalViewModel extends BaseViewModel { List get ProjectAvgERWaitingTimeModeList => _erService.projectAvgERWaitingTimeModelList; - getProjectAvgERWaitingTimeOrders({int id, int projectID}) async { + getProjectAvgERWaitingTimeOrders({int? id, int? projectID}) async { setState(ViewState.Busy); if (id != null && projectID != null) { @@ -23,7 +21,7 @@ class NearHospitalViewModel extends BaseViewModel { await _erService.getProjectAvgERWaitingTimeOrders(); } if (_erService.hasError) { - error = _erService.error; + error = _erService.error!; setState(ViewState.Error); } else setState(ViewState.Idle); diff --git a/lib/core/viewModels/er/rrt-view-model.dart b/lib/core/viewModels/er/rrt-view-model.dart new file mode 100644 index 00000000..96c0436d --- /dev/null +++ b/lib/core/viewModels/er/rrt-view-model.dart @@ -0,0 +1,253 @@ +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'; +import 'package:diplomaticquarterapp/core/service/parmacyModule/parmacy_module_service.dart'; +import 'package:diplomaticquarterapp/locator.dart'; +import 'package:diplomaticquarterapp/models/rrt/RRTProcedureList.dart'; +import 'package:diplomaticquarterapp/models/rrt/service_price.dart'; +import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; +import 'package:diplomaticquarterapp/services/pharmacy_services/pharmacyAddress_service.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; + +import '../base_view_model.dart'; + +class RRTService extends BaseService {} + +class _RRTServiceData { + List pendingOrders = []; + List completedOrders = []; + ServicePrice servicePrice = ServicePrice(); + +// RRTProcedureList rrtProcedureList; +} + +class RRTViewModel extends BaseViewModel { + var _service = RRTService(); + late int createdRequestNo; + var _pharmacy_service = locator(); + var _pharmacy_address_service = locator(); + CustomerAddressesService _customerAddressesService = locator(); + List rrtProcedureList = []; + + List get addressesList => _customerAddressesService.addressesList; + + _RRTServiceData rrtServiceData = _RRTServiceData(); + + Future<_RRTServiceData> loadRequiredData(int languageID) async { + // await getServicePrice(); + // await getAllOrders(); + await getProcedureDetails(languageID); + await getAllOrdersRC(); + // getProcedureDetails(); + return rrtServiceData; + } + + Future createOrder(Map body) async { + body['IdentificationNo'] = user!.patientIdentificationNo; + body['NationalityID'] = user!.nationalityID; + body['CreatedBy'] = user!.patientIdentificationType; + body['OrderServiceID'] = 5; + var localRes; + int requestNo; + await _service.baseAppClient.post(PATIENT_ER_INSERT_PRES_ORDER, body: body, onSuccess: (response, statusCode) { + requestNo = response['RequestNo']; + return requestNo; + }, onFailure: (error, statusCode) { + AppToast.showErrorToast(message: error); + return error; + }); + } + + Future createOrderRC(Map body) async { + // body['IdentificationNo'] = user.patientIdentificationNo; + // body['NationalityID'] = user.nationalityID; + // body['CreatedBy'] = user.patientIdentificationType; + // body['OrderServiceID'] = 5; + var localRes; + + await _service.baseAppClient.post(ADD_RRT_ORDER_RC, isRCService: true, body: body, onSuccess: (response, statusCode) { + createdRequestNo = response['response']; + Future.value(createdRequestNo); + }, onFailure: (error, statusCode) { + AppToast.showErrorToast(message: error); + return error; + }); + } + + // Service ID: 4 == RRT + Future<_RRTServiceData> getAllOrders() async { + await _service.baseAppClient.post(GET_PRESCRIPTIONS_ALL_ORDERS, body: {}, onSuccess: (response, statusCode) { + var data = response["PatientER_GetPatientAllPresOrdersList"]; + rrtServiceData.completedOrders.clear(); + rrtServiceData.pendingOrders.clear(); + if (data != null && data is List) { + data.forEach((json) { + if (json["ServiceID"] == 5) { + if (json["Status"] == 1 || json["Status"] == 2) { + // Pending + rrtServiceData.pendingOrders.add(GetCMCAllOrdersResponseModel.fromJson(json)); + } + rrtServiceData.completedOrders.add(GetCMCAllOrdersResponseModel.fromJson(json)); + } + }); + } + }, onFailure: (error, statusCode) { + AppToast.showErrorToast(message: error); + }); + return rrtServiceData; + } + + Future<_RRTServiceData> getAllOrdersRC() async { + await _service.baseAppClient.post(GET_ALL_RRT_ORDERS_RC, isRCService: true, 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<_RRTServiceData> getProcedureDetails(int languageID) async { + DoctorsListService service = new DoctorsListService(); + await service.getRRTProcedures(15, languageID).then((res) { + rrtProcedureList.clear(); + var data = res["Vida_ProcedureList"]; + data.forEach((json) { + rrtProcedureList.add(VidaProcedureList.fromJson(json)); + }); + print(rrtProcedureList.length); + }).catchError((err) { + AppToast.showErrorToast(message: err); + print(err); + }); + return rrtServiceData; + } + + Future getOrderDetails() async { + return null; + } + + Future getAllQuestions() async { + dynamic response_; + await _service.baseAppClient.post(GET_ALL_RRT_QUESTIONS, body: {}, onSuccess: (response, statusCode) { + response_ = response; + }, onFailure: (error, statusCode) { + AppToast.showErrorToast(message: error); + }); + return response_; + } + + Future getServicePrice() async { + Map body = {"IdentificationNo": user!.patientIdentificationNo}; + ServicePrice servicePrice; + await _service.baseAppClient.post(GET_RRT_SERVICE_PRICE, body: body, onSuccess: (response, statusCode) { + var data = response['PatientE_RealRRT_GetServicePriceList']; + if (data != null && data is List) { + var priceData = data.first; + if (priceData != null) { + servicePrice = ServicePrice.fromJson(priceData); + rrtServiceData.servicePrice = servicePrice; + return servicePrice; + } + } + + }, onFailure: (error, statusCode) { + AppToast.showErrorToast(message: error); + return error; + }); + } + + Future cancelOrder(PrescriptionsOrder order, {String reason = ""}) async { + var body = {"PresOrderID": order.iD, "PresOrderStatus": 4, "EditedBy": 3, "RejectionReason": reason}; + var success = false; + await _service.baseAppClient.post(PATIENT_ER_UPDATE_PRES_ORDER, 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 cancelOrderRC(GetCMCAllOrdersResponseModel order, {String reason = ""}) async { + Map body = {"Id": order.iD, "ClickButton": 14}; + var success = false; + await _service.baseAppClient.post(UPDATE_RRT_ORDER_RC, isRCService: true, 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 { + var token = await sharedPref.getString(PHARMACY_AUTORZIE_TOKEN); + if (token == null) await _pharmacy_service.generatePharmacyToken(); + + await _pharmacy_service.makeVerifyCustomer({'PatientID': user!.patientID.toString()}); + await _pharmacy_address_service.getAddresses(); + return _pharmacy_address_service.addresses; + } catch (e) { + error = e; + } + Future.error(error); + } + + Future getCustomerAddresses() async { + setState(ViewState.Busy); + await _customerAddressesService.getCustomerAddresses(); + if (_customerAddressesService.hasError) { + error = _customerAddressesService.error!; + setState(ViewState.ErrorLocal); + } else { + setState(ViewState.Idle); + } + } + + Future getCustomerInfo() async { + setState(ViewState.Busy); + await _pharmacy_service.generatePharmacyToken(); + + if (_customerAddressesService.hasError) { + error = _customerAddressesService.error!; + await _pharmacy_service.createUser(); + setState(ViewState.ErrorLocal); + } else { + await _pharmacy_service.createUser(); + if (!_pharmacy_service.hasError) await getCustomerAddresses(); + } + + // setState(ViewState.Busy); + // await _pharmacy_service.generatePharmacyToken(); + // if (_customerAddressesService.hasError) { + // error = _customerAddressesService.error; + // await _pharmacy_service.createUser(); + // await getCustomerAddresses(); + // setState(ViewState.ErrorLocal); + // } else { + // await _customerAddressesService.getCustomerInfo(); + // await getCustomerAddresses(); + // } + } +} diff --git a/lib/core/viewModels/feedback/feedback_view_model.dart b/lib/core/viewModels/feedback/feedback_view_model.dart index 6793c786..a064b5ea 100644 --- a/lib/core/viewModels/feedback/feedback_view_model.dart +++ b/lib/core/viewModels/feedback/feedback_view_model.dart @@ -2,45 +2,24 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/feedback/COC_items.dart'; import 'package:diplomaticquarterapp/core/service/feedback/feedback_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; -import 'package:diplomaticquarterapp/pages/feedback/appointment_history.dart'; -import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:flutter/cupertino.dart'; +import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; import '../../../locator.dart'; -enum MessageType { - ComplaintOnAnAppointment, - ComplaintWithoutAppointment, - Question, - Compliment, - Suggestion, - NON -} +enum MessageType { ComplaintOnAnAppointment, ComplaintWithoutAppointment, Question, Compliment, Suggestion, NON } class FeedbackViewModel extends BaseViewModel { FeedbackService _feedbackService = locator(); List get cOCItemList => _feedbackService.cOCItemList; + List get appointHistoryList => _feedbackService.appointHistoryList; - List get appointHistoryList => - _feedbackService.appointHistoryList; - - Future sendCOCItem( - {String title, - String details, - String cOCTypeName, - String attachment, - AppointmentHistory appointHistory}) async { + Future sendCOCItem({String? title, String? details, String? cOCTypeName, String? attachment, AppoitmentAllHistoryResultList? appointHistory}) async { setState(ViewState.BusyLocal); - await _feedbackService.sendCOCItem( - title: title, - details: details, - cOCTypeName: cOCTypeName, - attachment: attachment, - appointHistory: appointHistory); + await _feedbackService.sendCOCItem(title: title, details: details, cOCTypeName: cOCTypeName, attachment: attachment, appointHistory: appointHistory); if (_feedbackService.hasError) { - error = _feedbackService.error; + error = _feedbackService.error!; setState(ViewState.ErrorLocal); return false; } else { @@ -53,18 +32,29 @@ class FeedbackViewModel extends BaseViewModel { setState(ViewState.Busy); await _feedbackService.getStatusCOC(); if (_feedbackService.hasError) { - error = _feedbackService.error; + error = _feedbackService.error!; + setState(ViewState.Error); + } else { + setState(ViewState.Idle); + } + } + + searchFeedback(String countryCode, String phoneNumber, int type, String idNumber) async { + setState(ViewState.Busy); + await _feedbackService.searchFeedback(countryCode, phoneNumber, type, idNumber); + if (_feedbackService.hasError) { + error = _feedbackService.error!; setState(ViewState.Error); } else { setState(ViewState.Idle); } } - Future getPatentAppointmentHistory() async { + Future getPatentAppointmentHistory() async { setState(ViewState.Busy); await _feedbackService.getPatentAppointmentHistory(); if (_feedbackService.hasError) { - error = _feedbackService.error; + error = _feedbackService.error!; setState(ViewState.Error); } else { setState(ViewState.Idle); diff --git a/lib/core/viewModels/hospital_view_model.dart b/lib/core/viewModels/hospital_view_model.dart index 66ad4b01..61957bbd 100644 --- a/lib/core/viewModels/hospital_view_model.dart +++ b/lib/core/viewModels/hospital_view_model.dart @@ -10,11 +10,11 @@ class HospitalViewModel extends BaseViewModel { List get hospitals => _hospitalService.hospitals; - Future getHospitals() async { + Future getHospitals(int languageID) async { setState(ViewState.Busy); - await _hospitalService.getHospitals(); + await _hospitalService.getHospitals(languageID); if (_hospitalService.hasError) { - error = _hospitalService.error; + error = _hospitalService.error!; setState(ViewState.Error); } else setState(ViewState.Idle); diff --git a/lib/core/viewModels/insurance_card_View_model.dart b/lib/core/viewModels/insurance_card_View_model.dart index 234db5d4..00997eb5 100644 --- a/lib/core/viewModels/insurance_card_View_model.dart +++ b/lib/core/viewModels/insurance_card_View_model.dart @@ -4,6 +4,7 @@ import 'package:diplomaticquarterapp/core/model/insurance/insurance_card.dart'; import 'package:diplomaticquarterapp/core/model/insurance/insurance_card_update_model.dart'; import 'package:diplomaticquarterapp/core/service/insurance_service.dart'; import 'package:diplomaticquarterapp/models/FamilyFiles/GetAllSharedRecordByStatusResponse.dart'; +import 'package:flutter/material.dart'; import '../../locator.dart'; import 'base_view_model.dart'; @@ -30,7 +31,7 @@ class InsuranceViewModel extends BaseViewModel { setState(ViewState.Busy); await _insuranceCardService.getInsurance(); if (_insuranceCardService.hasError) { - error = _insuranceCardService.error; + error = _insuranceCardService.error!; setState(ViewState.ErrorLocal); } else setState(ViewState.Idle); @@ -42,13 +43,13 @@ class InsuranceViewModel extends BaseViewModel { setState(ViewState.Busy); await _insuranceCardService.getInsuranceUpdate(); if (_insuranceCardService.hasError) { - error = _insuranceCardService.error; + error = _insuranceCardService.error!; setState(ViewState.ErrorLocal); } else getFamilyFiles(); } - Future getInsuranceApproval({int appointmentNo}) async { + Future getInsuranceApproval({ int? appointmentNo}) async { hasError = false; //_insuranceCardService.clearInsuranceCard(); setState(ViewState.Busy); @@ -58,7 +59,7 @@ class InsuranceViewModel extends BaseViewModel { else await _insuranceCardService.getInsuranceApproval(); if (_insuranceCardService.hasError) { - error = _insuranceCardService.error; + error = _insuranceCardService.error!; setState(ViewState.ErrorLocal); } else setState(ViewState.Idle); @@ -67,16 +68,16 @@ class InsuranceViewModel extends BaseViewModel { Future getFamilyFiles() async { await _insuranceCardService.getSharedRecordByStatus(); if (_insuranceCardService.hasError) { - error = _insuranceCardService.error; + error = _insuranceCardService.error!; setState(ViewState.Error); } else setState(ViewState.Idle); } - Future uploadInsuranceCard({String patientIdentificationID, int patientID,String image =""}) async { + Future uploadInsuranceCard(BuildContext context, {String? patientIdentificationID, int? patientID,String image =""}) async { setState(ViewState.BusyLocal); - await _insuranceCardService.uploadInsuranceCard(patientIdentificationID: patientIdentificationID,patientID: patientID,image: image); + await _insuranceCardService.uploadInsuranceCard(context, patientIdentificationID: patientIdentificationID,patientID: patientID,image: image); if (_insuranceCardService.hasError) { - error = _insuranceCardService.error; + error = _insuranceCardService.error!; setState(ViewState.ErrorLocal); } else setState(ViewState.Idle); diff --git a/lib/core/viewModels/medical/ActiveMedicationsViewModel.dart b/lib/core/viewModels/medical/ActiveMedicationsViewModel.dart index ee4f37c5..23a6a33e 100644 --- a/lib/core/viewModels/medical/ActiveMedicationsViewModel.dart +++ b/lib/core/viewModels/medical/ActiveMedicationsViewModel.dart @@ -15,7 +15,7 @@ class ActiveMedicationsViewModel extends BaseViewModel { setState(ViewState.Busy); await _activeMedicationsService.getActiveMedication(); if (_activeMedicationsService.hasError) { - error = _activeMedicationsService.error; + error = _activeMedicationsService.error!; setState(ViewState.Error); } else { setState(ViewState.Idle); diff --git a/lib/core/viewModels/medical/AllergiesViewModel.dart b/lib/core/viewModels/medical/AllergiesViewModel.dart index bc4666bc..f3b19a2c 100644 --- a/lib/core/viewModels/medical/AllergiesViewModel.dart +++ b/lib/core/viewModels/medical/AllergiesViewModel.dart @@ -13,7 +13,7 @@ class AllergiesViewModel extends BaseViewModel { setState(ViewState.Busy); await _allergiesService.getAllergies(); if (_allergiesService.hasError) { - error = _allergiesService.error; + error = _allergiesService.error!; setState(ViewState.Error); } else { setState(ViewState.Idle); diff --git a/lib/core/viewModels/medical/EyeViewModel.dart b/lib/core/viewModels/medical/EyeViewModel.dart index ab76b94f..4c5af31d 100644 --- a/lib/core/viewModels/medical/EyeViewModel.dart +++ b/lib/core/viewModels/medical/EyeViewModel.dart @@ -4,6 +4,7 @@ import 'package:diplomaticquarterapp/core/model/eye/AppointmentFilter.dart'; import 'package:diplomaticquarterapp/core/service/medical/EyeService.dart'; import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; import 'package:diplomaticquarterapp/locator.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; class EyeViewModel extends BaseViewModel { EyeService _eyeService = locator(); @@ -11,66 +12,69 @@ class EyeViewModel extends BaseViewModel { List get appoimentAllHistoryResultList => _eyeService.appoimentAllHistoryResultList; - List appointmentFilter = List(); + List appointmentFilter =[]; getEyeMeasurement() async { setState(ViewState.Busy); await _eyeService.getEyeMeasurement(); if (_eyeService.hasError) { - error = _eyeService.error; + error = _eyeService.error!; setState(ViewState.Error); } else { - _eyeService.appoimentAllHistoryResultList.forEach((element) { - List _appointmentFilter = appointmentFilter - .where( - (elementFilter) => - elementFilter.filterName == element.projectName, - ) - .toList(); - - if (_appointmentFilter.length != 0) { - appointmentFilter[appointmentFilter.indexOf(_appointmentFilter[0])] - .appointmentAllHistoryResultList - .add(element); - } else { - appointmentFilter.add(AppointmentFilter( - element, - element.projectName, - )); - } - }); + if (_eyeService.appoimentAllHistoryResultList.length == 0) { + new AppToast().backWithEmpty(); + } else { + _eyeService.appoimentAllHistoryResultList.forEach((element) { + List _appointmentFilter = appointmentFilter + .where( + (elementFilter) => + elementFilter.filterName == element.projectName, + ) + .toList(); + if (_appointmentFilter.length != 0) { + appointmentFilter[appointmentFilter.indexOf(_appointmentFilter[0])] + .appointmentAllHistoryResultList + .add(element); + } else { + appointmentFilter.add(AppointmentFilter( + element, + element.projectName!, + )); + } + }); + } setState(ViewState.Idle); } } - sendGlassesPrescriptionEmail({int appointmentNo, String projectName, int projectID}) async { + sendGlassesPrescriptionEmail( + {required int appointmentNo, required String projectName, required int projectID}) async { setState(ViewState.Busy); await _eyeService.sendGlassesPrescriptionEmail( appointmentNo: appointmentNo, projectID: projectID, projectName: projectName); if (_eyeService.hasError) { - error = _eyeService.error; + error = _eyeService.error!; setState(ViewState.Error); } else { setState(ViewState.Idle); } } - sendContactLensPrescriptionEmail({int appointmentNo, String projectName, int projectID}) async { + sendContactLensPrescriptionEmail( + {required int appointmentNo, required String projectName, required int projectID}) async { setState(ViewState.Busy); await _eyeService.sendContactLensPrescriptionEmail( appointmentNo: appointmentNo, projectID: projectID, projectName: projectName); if (_eyeService.hasError) { - error = _eyeService.error; + error = _eyeService.error!; setState(ViewState.Error); } else { setState(ViewState.Idle); } } - - } diff --git a/lib/core/viewModels/medical/PrescriptionDeliveryViewModel.dart b/lib/core/viewModels/medical/PrescriptionDeliveryViewModel.dart index 455b5934..d8b59ef7 100644 --- a/lib/core/viewModels/medical/PrescriptionDeliveryViewModel.dart +++ b/lib/core/viewModels/medical/PrescriptionDeliveryViewModel.dart @@ -7,48 +7,35 @@ 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); await _pharmacyModuleService.generatePharmacyToken().then((value) async { - await _customerAddressesService.getCustomerInfo(); + // await _customerAddressesService.getCustomerInfo(); + // await _customerAddressesService.getCustomerInfo(); + await _pharmacyModuleService.createUser().then((value) async { + await getCustomerAddresses(); + }); }); if (_customerAddressesService.hasError) { - error = _customerAddressesService.error; + error = _customerAddressesService.error!; setState(ViewState.ErrorLocal); - } else { - await getCustomerAddresses(); - } + } else {} } - 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, int? projectID}) 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, projectID: projectID); if (_prescriptionDeliveryService.hasError) { - error = _prescriptionDeliveryService.error; + error = _prescriptionDeliveryService.error!; setState(ViewState.ErrorLocal); } else { setState(ViewState.Idle); @@ -59,7 +46,7 @@ class PrescriptionDeliveryViewModel extends BaseViewModel { setState(ViewState.Busy); await _customerAddressesService.getCustomerAddresses(); if (_customerAddressesService.hasError) { - error = _customerAddressesService.error; + error = _customerAddressesService.error!; setState(ViewState.ErrorLocal); } else { setState(ViewState.Idle); diff --git a/lib/core/viewModels/medical/ask_doctor_view_model.dart b/lib/core/viewModels/medical/ask_doctor_view_model.dart index 629df0a9..f254c915 100644 --- a/lib/core/viewModels/medical/ask_doctor_view_model.dart +++ b/lib/core/viewModels/medical/ask_doctor_view_model.dart @@ -1,3 +1,4 @@ +import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/ask_doctor/AskDoctorReqTypes.dart'; import 'package:diplomaticquarterapp/core/model/ask_doctor/DoctorResponse.dart'; @@ -6,70 +7,71 @@ import 'package:diplomaticquarterapp/core/service/medical/my_doctor_service.dart import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; import 'package:diplomaticquarterapp/locator.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; -import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; class AskDoctorViewModel extends BaseViewModel { AskDoctorService _askDoctorService = locator(); MyDoctorService _myDoctorService = locator(); - List patientDoctorAppointmentListHospital = - List(); + List patientDoctorAppointmentListHospital = []; - List get askDoctorReqTypes => - _askDoctorService.askDoctorReqTypes; + List get askDoctorReqTypes => _askDoctorService.askDoctorReqTypes; - List get doctorResponseList => - _askDoctorService.doctorResponseList; + List get doctorResponseList => _askDoctorService.doctorResponseList; Future getMyDoctor() async { setState(ViewState.Busy); - await _myDoctorService.getPatientDoctorAppointmentList( - top: 25, beforeDays: 15); + await _myDoctorService.getPatientDoctorAppointmentList(top: 25, beforeDays: 15); if (_myDoctorService.hasError) { - error = _myDoctorService.error; + error = _myDoctorService.error!; setState(ViewState.Error); - } else - var asd = ""; - _myDoctorService.patientDoctorAppointmentList.forEach((element) { - List doctorByClinic = - patientDoctorAppointmentListHospital - .where((elementClinic) => - elementClinic.filterName == element.projectName) - .toList(); - - if (doctorByClinic.length != 0) { - patientDoctorAppointmentListHospital[ - patientDoctorAppointmentListHospital.indexOf(doctorByClinic[0])] - .patientDoctorAppointmentList - .add(element); - } else { - patientDoctorAppointmentListHospital.add(PatientDoctorAppointmentList( - filterName: element.projectName, - patientDoctorAppointment: element)); - } + } else if (_myDoctorService.patientDoctorAppointmentList.length != 0) { + _myDoctorService.patientDoctorAppointmentList.forEach((element) { + if (!element.isLiveCareClinic!) { + List doctorByClinic = patientDoctorAppointmentListHospital.where((elementClinic) => elementClinic.filterName == element.projectName).toList(); + if (doctorByClinic.length != 0) { + patientDoctorAppointmentListHospital[patientDoctorAppointmentListHospital.indexOf(doctorByClinic[0])].patientDoctorAppointmentList!.add(element); + } else { + patientDoctorAppointmentListHospital.add(PatientDoctorAppointmentList(filterName: element.projectName, patientDoctorAppointment: element)); + } + } + setState(ViewState.Idle); + }); + } else { setState(ViewState.Idle); - }); + // AppToast.showErrorToast(message: TranslationBase.of(AppGlobal.context).askDocEmpty); + } } Future getCallRequestTypeLOVs() async { setState(ViewState.Busy); await _askDoctorService.getCallRequestTypeLOV(); if (_askDoctorService.hasError) { - error = _askDoctorService.error; + error = _askDoctorService.error!; + setState(ViewState.ErrorLocal); + AppToast.showErrorToast(message: error); + } else + setState(ViewState.Idle); + } + + Future getQuestionTypes() async { + setState(ViewState.Busy); + await _askDoctorService.getQuestionTypes(); + if (_askDoctorService.hasError) { + error = _askDoctorService.error!; setState(ViewState.ErrorLocal); AppToast.showErrorToast(message: error); } else setState(ViewState.Idle); } - Future getCallInfoHoursResult({int projectId, int doctorId}) async { + Future getCallInfoHoursResult({required int projectId, required int doctorId}) async { setState(ViewState.Busy); - await _askDoctorService.getCallInfoHoursResult( - projectId: projectId, doctorId: doctorId); + await _askDoctorService.getCallInfoHoursResult(projectId: projectId, doctorId: doctorId); if (_askDoctorService.hasError) { - error = _askDoctorService.error; + error = _askDoctorService.error!; setState(ViewState.ErrorLocal); } else setState(ViewState.Idle); @@ -79,29 +81,27 @@ class AskDoctorViewModel extends BaseViewModel { setState(ViewState.Busy); await _askDoctorService.getDoctorResponse(); if (_askDoctorService.hasError) { - error = _askDoctorService.error; + error = _askDoctorService.error!; setState(ViewState.Error); } else setState(ViewState.Idle); } - Future updateReadStatus({int transactionNo}) async { + Future updateReadStatus({required int transactionNo}) async { setState(ViewState.Busy); await _askDoctorService.updateReadStatus(transactionNo: transactionNo); if (_askDoctorService.hasError) { - error = _askDoctorService.error; + error = _askDoctorService.error!; setState(ViewState.Error); } else setState(ViewState.Idle); } - Future sendRequestLOV( - {DoctorList doctorList, String requestType, String remark}) async { + Future sendRequestLOV({required DoctorList doctorList, required String requestType, required String remark}) async { setState(ViewState.BusyLocal); - await _askDoctorService.sendRequestLOV( - doctorList: doctorList, requestType: requestType, remark: remark); + await _askDoctorService.sendRequestLOV(doctorList: doctorList, requestType: requestType, remark: remark); if (_askDoctorService.hasError) { - error = _askDoctorService.error; + error = _askDoctorService.error!; setState(ViewState.ErrorLocal); AppToast.showErrorToast(message: error); } else diff --git a/lib/core/viewModels/medical/blood_pressure_view_model.dart b/lib/core/viewModels/medical/blood_pressure_view_model.dart index ae3abbcb..b3c0f8a9 100644 --- a/lib/core/viewModels/medical/blood_pressure_view_model.dart +++ b/lib/core/viewModels/medical/blood_pressure_view_model.dart @@ -9,14 +9,11 @@ import '../../../core/viewModels/base_view_model.dart'; class BloodPressureViewMode extends BaseViewModel { BloodPressureService bloodPressureService = locator(); - List get monthDiabtecPatientResult => - bloodPressureService.monthDiabtecPatientResult; + List get monthDiabtecPatientResult => bloodPressureService.monthDiabtecPatientResult; - List get weekDiabtecPatientResult => - bloodPressureService.weekDiabtecPatientResult; + List get weekDiabtecPatientResult => bloodPressureService.weekDiabtecPatientResult; - List get yearDiabtecPatientResult => - bloodPressureService.yearDiabtecPatientResult; + List get yearDiabtecPatientResult => bloodPressureService.yearDiabtecPatientResult; List weightWeekTimeSeriesDataTop = []; List weightWeekTimeSeriesDataLow = []; @@ -32,40 +29,35 @@ class BloodPressureViewMode extends BaseViewModel { await bloodPressureService.getBloodSugar(); await bloodPressureService.getDiabtecResults(); if (bloodPressureService.hasError) { - error = bloodPressureService.error; + error = bloodPressureService.error!; setState(ViewState.ErrorLocal); } else { clearDate(); bloodPressureService.weekDiabtectResultAverageList.forEach((element) { - weightWeekTimeSeriesDataTop.add(TimeSeriesSales2( - element.bloodPressureDate, - element.dailyDiastolicPressureAverageResult.toDouble())); - weightWeekTimeSeriesDataLow.add(TimeSeriesSales2( - element.bloodPressureDate, - element.dailySystolicePressureAverageResult.toDouble())); - - for (int index = 0; index < bloodPressureService.monthDiabtectResultAverageList.length; index++) { - - weighMonthTimeSeriesDataTop.add(TimeSeriesSales3(index, bloodPressureService.monthDiabtectResultAverageList[index].weekDiastolicPressureAverageResult.toDouble())); - - weighMonthTimeSeriesDataLow.add(TimeSeriesSales3(index, bloodPressureService.monthDiabtectResultAverageList[index].weekSystolicePressureAverageResult.toDouble())); - } + weightWeekTimeSeriesDataTop.add(TimeSeriesSales2(element.bloodPressureDate!, element.dailyDiastolicPressureAverageResult!.toDouble())); + weightWeekTimeSeriesDataLow.add(TimeSeriesSales2(element.bloodPressureDate!, element.dailySystolicePressureAverageResult!.toDouble())); + }); - bloodPressureService.yearDiabtecResultAverageList.forEach((element) { - weightYearTimeSeriesDataTop.add(TimeSeriesSales2(element.date, - element.monthSystolicePressureAverageResult.toDouble())); + for (int index = 0; index < bloodPressureService.monthDiabtectResultAverageList.length; index++) { + // weighMonthTimeSeriesDataTop.add(TimeSeriesSales3("Week " + (index + 1).toString(), bloodPressureService.monthDiabtectResultAverageList[index].weekDiastolicPressureAverageResult.toDouble())); + // weighMonthTimeSeriesDataLow.add(TimeSeriesSales3("Week " + (index + 1).toString(), bloodPressureService.monthDiabtectResultAverageList[index].weekSystolicePressureAverageResult.toDouble())); + weighMonthTimeSeriesDataTop.add(TimeSeriesSales3( + bloodPressureService.monthDiabtectResultAverageList[index].weekDesc, bloodPressureService.monthDiabtectResultAverageList[index].weekDiastolicPressureAverageResult!.toDouble())); + weighMonthTimeSeriesDataLow.add(TimeSeriesSales3( + bloodPressureService.monthDiabtectResultAverageList[index].weekDesc, bloodPressureService.monthDiabtectResultAverageList[index].weekSystolicePressureAverageResult!.toDouble())); + } - weightYearTimeSeriesDataLow.add(TimeSeriesSales2(element.date, - element.monthDiastolicPressureAverageResult.toDouble())); - }); + bloodPressureService.yearDiabtecResultAverageList.forEach((element) { + weightYearTimeSeriesDataTop.add(TimeSeriesSales2(element.date!, element.monthSystolicePressureAverageResult!.toDouble())); + weightYearTimeSeriesDataLow.add(TimeSeriesSales2(element.date!, element.monthDiastolicPressureAverageResult!.toDouble())); }); + setState(ViewState.Idle); } } - - void clearDate(){ + void clearDate() { weightWeekTimeSeriesDataTop.clear(); weightWeekTimeSeriesDataLow.clear(); weighMonthTimeSeriesDataTop.clear(); @@ -79,47 +71,35 @@ class BloodPressureViewMode extends BaseViewModel { await bloodPressureService.sendReportByEmail(); if (bloodPressureService.hasError) { - error = bloodPressureService.error; + error = bloodPressureService.error!; setState(ViewState.ErrorLocal); } else { setState(ViewState.Idle); } } - Future addORUpdateDiabtecResult( - {String bloodPressureDate, - String diastolicPressure, - String systolicePressure, - int measuredArm,bool isUpdate = false}) async { + Future addORUpdateDiabtecResult({String? bloodPressureDate, String? diastolicPressure, String? systolicePressure, int? measuredArm, int? lineItemNo, bool isUpdate = false}) async { setState(ViewState.BusyLocal); - if(!isUpdate) - await bloodPressureService.addDiabtecResult( - bloodPressureDate: bloodPressureDate, - diastolicPressure: diastolicPressure, - systolicePressure: systolicePressure, - measuredArm: measuredArm); + if (!isUpdate) + await bloodPressureService.addDiabtecResult(bloodPressureDate: bloodPressureDate, diastolicPressure: diastolicPressure, systolicePressure: systolicePressure, measuredArm: measuredArm); else await bloodPressureService.updateDiabtecResult( - bloodPressureDate: bloodPressureDate, - diastolicPressure: diastolicPressure, - systolicePressure: systolicePressure, - measuredArm: measuredArm); + bloodPressureDate: bloodPressureDate, diastolicPressure: diastolicPressure, systolicePressure: systolicePressure, measuredArm: measuredArm, lineItemNo: lineItemNo); if (bloodPressureService.hasError) { - error = bloodPressureService.error; + error = bloodPressureService.error!; setState(ViewState.ErrorLocal); } else { - await getBloodPressure(); + // await getBloodPressure(); setState(ViewState.Idle); } } - - Future deactivateDiabeticStatus({int lineItemNo}) async { + Future deactivateDiabeticStatus({required int lineItemNo}) async { setState(ViewState.BusyLocal); await bloodPressureService.deactivateDiabeticStatus(lineItemNo: lineItemNo); if (bloodPressureService.hasError) { - error = bloodPressureService.error; + error = bloodPressureService.error!; setState(ViewState.ErrorLocal); } else { await getBloodPressure(); diff --git a/lib/core/viewModels/medical/blood_sugar_view_model.dart b/lib/core/viewModels/medical/blood_sugar_view_model.dart index 8a513992..5b9c4077 100644 --- a/lib/core/viewModels/medical/blood_sugar_view_model.dart +++ b/lib/core/viewModels/medical/blood_sugar_view_model.dart @@ -1,10 +1,7 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/my_trakers/blood_sugar/DiabtecPatientResult.dart'; -import 'package:diplomaticquarterapp/core/model/my_trakers/chartData/WeekChartDate.dart'; -import 'package:diplomaticquarterapp/core/model/my_trakers/chartData/YearMonthlyChartDate.dart'; import 'package:diplomaticquarterapp/core/service/medical/BloodSugarService.dart'; import 'package:diplomaticquarterapp/locator.dart'; -import 'package:charts_flutter/flutter.dart' as charts; import 'package:diplomaticquarterapp/widgets/charts/app_time_series_chart.dart'; import '../../../core/viewModels/base_view_model.dart'; @@ -30,15 +27,18 @@ class BloodSugarViewMode extends BaseViewModel { await bloodSugarService.getBloodSugar(); await bloodSugarService.getDiabtecResults(); if (bloodSugarService.hasError) { - error = bloodSugarService.error; + error = bloodSugarService.error!; setState(ViewState.Error); } else { bloodSugarService.weekDiabtectResultAverageList.forEach((element) { bloodWeekTimeSeriesData.add(TimeSeriesSales2( - element.dateChart, + element.dateChart!, element.dailyAverageResult.toDouble(), )); }); + if (bloodWeekTimeSeriesData.isEmpty) { + bloodWeekTimeSeriesData.add(TimeSeriesSales2(DateTime.now(), 0)); + } for (int index = 0; index < bloodSugarService.monthDiabtectResultAverageList.length; @@ -53,7 +53,7 @@ class BloodSugarViewMode extends BaseViewModel { bloodSugarService.yearDiabtecResultAverageList.forEach((element) { yearTimeSeriesData.add(TimeSeriesSales2( - element.date, + element.date!, element.monthAverageResult.toDouble(), )); }); @@ -63,10 +63,10 @@ class BloodSugarViewMode extends BaseViewModel { } Future addDiabtecResult( - {String bloodSugerDateChart, - String bloodSugerResult, - String diabtecUnit, - int measuredTime}) async { + {String? bloodSugerDateChart, + String? bloodSugerResult, + String? diabtecUnit, + int? measuredTime}) async { setState(ViewState.BusyLocal); await bloodSugarService.addDiabtecResult( bloodSugerDateChart: bloodSugerDateChart, @@ -74,7 +74,7 @@ class BloodSugarViewMode extends BaseViewModel { diabtecUnit: diabtecUnit, measuredTime: measuredTime); if (bloodSugarService.hasError) { - error = bloodSugarService.error; + error = bloodSugarService.error!; setState(ViewState.Error); } else { await getBloodSugar(); @@ -83,12 +83,12 @@ class BloodSugarViewMode extends BaseViewModel { } Future updateDiabtecResult( - {DateTime month, - DateTime hour, - String bloodSugerResult, - String diabtecUnit, - int measuredTime, - int lineItemNo}) async { + {DateTime? month, + DateTime? hour, + String? bloodSugerResult, + String? diabtecUnit, + int? measuredTime, + int? lineItemNo}) async { setState(ViewState.BusyLocal); await bloodSugarService.updateDiabtecResult( @@ -99,7 +99,7 @@ class BloodSugarViewMode extends BaseViewModel { lineItemNo: lineItemNo, month: month); if (bloodSugarService.hasError) { - error = bloodSugarService.error; + error = bloodSugarService.error!; setState(ViewState.ErrorLocal); } else { await getBloodSugar(); @@ -112,19 +112,19 @@ class BloodSugarViewMode extends BaseViewModel { await bloodSugarService.sendReportByEmail(); if (bloodSugarService.hasError) { - error = bloodSugarService.error; + error = bloodSugarService.error!; setState(ViewState.ErrorLocal); } else { setState(ViewState.Idle); } } - Future deactivateDiabeticStatus({int lineItemNo}) async { + Future deactivateDiabeticStatus({required int lineItemNo}) async { setState(ViewState.BusyLocal); await bloodSugarService.deactivateDiabeticStatus(lineItemNo: lineItemNo); if (bloodSugarService.hasError) { - error = bloodSugarService.error; + error = bloodSugarService.error!; setState(ViewState.ErrorLocal); } else { await getBloodSugar(); diff --git a/lib/core/viewModels/medical/labs_view_model.dart b/lib/core/viewModels/medical/labs_view_model.dart index 9e3f09e5..ea45a312 100644 --- a/lib/core/viewModels/medical/labs_view_model.dart +++ b/lib/core/viewModels/medical/labs_view_model.dart @@ -1,3 +1,7 @@ +import 'dart:convert'; +import 'dart:io'; +import 'dart:typed_data'; + import 'package:diplomaticquarterapp/core/enum/filter_type.dart'; import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/labs/LabOrderResult.dart'; @@ -5,7 +9,12 @@ import 'package:diplomaticquarterapp/core/model/labs/lab_result.dart'; import 'package:diplomaticquarterapp/core/model/labs/patient_lab_orders.dart'; import 'package:diplomaticquarterapp/core/model/labs/patient_lab_special_result.dart'; import 'package:diplomaticquarterapp/core/service/medical/labs_service.dart'; +import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/widgets/charts/app_time_series_chart.dart'; +import 'package:open_filex/open_filex.dart'; +import 'package:path_provider/path_provider.dart'; import '../../../locator.dart'; import '../base_view_model.dart'; @@ -15,60 +24,43 @@ class LabsViewModel extends BaseViewModel { LabsService _labsService = locator(); List get labOrdersResultsList => _labsService.labOrdersResultsList; + List timeSeries = []; + String get labReportPDF => _labsService.labReportPDF; - List _patientLabOrdersListClinic = List(); - List _patientLabOrdersListHospital = List(); + List _patientLabOrdersListClinic = []; + List _patientLabOrdersListHospital = []; - List get patientLabOrdersList => - filterType == FilterType.Clinic - ? _patientLabOrdersListClinic - : _patientLabOrdersListHospital; + List get patientLabOrdersList => filterType == FilterType.Clinic ? _patientLabOrdersListClinic : _patientLabOrdersListHospital; void getLabs() async { if (authenticatedUserObject.isLogin) { setState(ViewState.Busy); await _labsService.getPatientLabOrdersList(); if (_labsService.hasError) { - error = _labsService.error; + error = _labsService.error!; setState(ViewState.Error); } else { _labsService.patientLabOrdersList.forEach((element) { - List patientLabOrdersClinic = - _patientLabOrdersListClinic - .where((elementClinic) => - elementClinic.filterName == element.clinicDescription) - .toList(); + List patientLabOrdersClinic = _patientLabOrdersListClinic.where((elementClinic) => elementClinic.filterName == element.clinicDescription).toList(); if (patientLabOrdersClinic.length != 0) { - _patientLabOrdersListClinic[_patientLabOrdersListClinic - .indexOf(patientLabOrdersClinic[0])] - .patientLabOrdersList - .add(element); + _patientLabOrdersListClinic[_patientLabOrdersListClinic.indexOf(patientLabOrdersClinic[0])].patientLabOrdersList.add(element); } else { - _patientLabOrdersListClinic.add(PatientLabOrdersList( - filterName: element.clinicDescription, - patientDoctorAppointment: element)); + _patientLabOrdersListClinic.add(PatientLabOrdersList(filterName: element.clinicDescription ?? element.projectName, patientDoctorAppointment: element)); } // doctor list sort via project - List patientLabOrdersHospital = - _patientLabOrdersListHospital - .where( - (elementClinic) => - elementClinic.filterName == element.projectName, - ) - .toList(); + List patientLabOrdersHospital = _patientLabOrdersListHospital + .where( + (elementClinic) => elementClinic.filterName == element.projectName, + ) + .toList(); if (patientLabOrdersHospital.length != 0) { - _patientLabOrdersListHospital[_patientLabOrdersListHospital - .indexOf(patientLabOrdersHospital[0])] - .patientLabOrdersList - .add(element); + _patientLabOrdersListHospital[_patientLabOrdersListHospital.indexOf(patientLabOrdersHospital[0])].patientLabOrdersList.add(element); } else { - _patientLabOrdersListHospital.add(PatientLabOrdersList( - filterName: element.projectName, - patientDoctorAppointment: element)); + _patientLabOrdersListHospital.add(PatientLabOrdersList(filterName: element.projectName ?? element.clinicDescription, patientDoctorAppointment: element)); } }); @@ -82,48 +74,42 @@ class LabsViewModel extends BaseViewModel { notifyListeners(); } - List get patientLabSpecialResult => - _labsService.patientLabSpecialResult; + List get patientLabSpecialResult => _labsService.patientLabSpecialResult; List get labResultList => _labsService.labResultList; - List labResultLists = List(); + List labResultLists = []; - getLaboratoryResult( - {String projectID, - int clinicID, - String invoiceNo, - String orderNo}) async { + getLaboratoryResult({String? projectID, int? clinicID, String? invoiceNo, String? invoiceType, String? orderNo, String? setupID, bool? isVidaPlus}) async { setState(ViewState.Busy); - await _labsService.getLaboratoryResult( - invoiceNo: invoiceNo, - orderNo: orderNo, - projectID: projectID, - clinicID: clinicID); + await _labsService.getLaboratoryResult(invoiceNo: invoiceNo, invoiceType: invoiceType, orderNo: orderNo, projectID: projectID, clinicID: clinicID, setupID: setupID, isVidaPlus: isVidaPlus); if (_labsService.hasError) { - error = _labsService.error; + error = _labsService.error!; setState(ViewState.Error); } else { setState(ViewState.Idle); } } - getPatientLabResult({PatientLabOrders patientLabOrder}) async { + getPatientLabResult({required PatientLabOrders patientLabOrder, required bool isVidaPlus}) async { setState(ViewState.Busy); - await _labsService.getPatientLabResult(patientLabOrder: patientLabOrder); + await _labsService.getPatientLabResult(patientLabOrder: patientLabOrder, isVidaPlus: isVidaPlus); if (_labsService.hasError) { - error = _labsService.error; + error = _labsService.error!; setState(ViewState.Error); } else { _labsService.labResultList.forEach((element) { List patientLabOrdersClinic = labResultLists.where((elementClinic) => elementClinic.filterName == element.testCode).toList(); if (patientLabOrdersClinic.length != 0) { - - var value= labResultLists[labResultLists.indexOf(patientLabOrdersClinic[0])].patientLabResultList - .where((e) => e.sampleCollectedOn== element.sampleCollectedOn && e.resultValue ==element.resultValue ).toList(); - if(value.isEmpty) - labResultLists[labResultLists.indexOf(patientLabOrdersClinic[0])].patientLabResultList.add(element); + // var value = labResultLists[labResultLists.indexOf(patientLabOrdersClinic[0])] + // .patientLabResultList! + // .where((e) { + // return e.sampleCollectedOn == element.sampleCollectedOn && e.resultValue == element.resultValue; + // }) + // .toList(); + // if (value.isEmpty) + labResultLists[labResultLists.indexOf(patientLabOrdersClinic[0])].patientLabResultList!.add(element); } else { labResultLists.add(LabResultList(filterName: element.testCode, lab: element)); } @@ -132,32 +118,63 @@ class LabsViewModel extends BaseViewModel { } } - - getPatientLabOrdersResults({PatientLabOrders patientLabOrder,String procedure}) async { + getPatientLabOrdersResults({PatientLabOrders? patientLabOrder, String? procedure, bool? isVidaPlus}) async { setState(ViewState.Busy); - await _labsService.getPatientLabOrdersResults(patientLabOrder: patientLabOrder,procedure: procedure); + await _labsService.getPatientLabOrdersResults( + patientLabOrder: patientLabOrder, + procedure: procedure, + isVidaPlus: isVidaPlus!, + ); if (_labsService.hasError) { - error = _labsService.error; + error = _labsService.error!; setState(ViewState.Error); } else { - bool isShouldClear = false; - if(_labsService.labOrdersResultsList.length==1) - { - labOrdersResultsList.forEach((element) { - if(element.resultValue.contains('/') ||element.resultValue.contains('*' )|| element.resultValue.isEmpty ) - isShouldClear = true; - });} - if(isShouldClear) - _labsService.labOrdersResultsList.clear(); + /// commented out based on PAP-304 + // bool isShouldClear = false; + // if (_labsService.labOrdersResultsList.length == 1) { + // labOrdersResultsList.forEach((element) { + // if (element.resultValue.contains('/') || element.resultValue.contains('*') || element.resultValue.isEmpty) + // isShouldClear = true; + // }); + // } + // if (isShouldClear) + // + // _labsService.labOrdersResultsList.clear(); + + _labsService.labOrdersResultsList.forEach((element) { + try { + timeSeries.add(new TimeSeriesSales2(DateUtil.convertStringToDate(element.verifiedOnDateTime!), double.parse(element.resultValue!))); + } catch (e) {} + }); setState(ViewState.Idle); } } - sendLabReportEmail({PatientLabOrders patientLabOrder,String mes}) async { - await _labsService.sendLabReportEmail(patientLabOrder: patientLabOrder); + sendLabReportEmail({PatientLabOrders? patientLabOrder, String? mes, AuthenticatedUser? userObj, required bool isVidaPlus, bool isDownload = false, int languageID = 1}) async { + await _labsService.sendLabReportEmail(patientLabOrder: patientLabOrder, userObj: userObj, isVidaPlus: isVidaPlus, isDownload: isDownload, languageID: languageID); if (_labsService.hasError) { - error = _labsService.error; - }else - AppToast.showSuccessToast(message: mes); + error = _labsService.error!; + } else { + if (isDownload) { + if (labReportPDF.isNotEmpty) { + String path = await _createFileFromString(labReportPDF, "pdf"); + try { + OpenFilex.open(path); + } catch (ex) { + AppToast.showErrorToast(message: "Cannot open file."); + } + } + } else { + AppToast.showSuccessToast(message: mes!); + } + } + } + + Future _createFileFromString(String encodedStr, String ext) async { + Uint8List bytes = base64.decode(encodedStr); + String dir = (await getApplicationDocumentsDirectory()).path; + File file = File("$dir/" + DateTime.now().millisecondsSinceEpoch.toString() + "." + ext); + await file.writeAsBytes(bytes); + return file.path; } } diff --git a/lib/core/viewModels/medical/medical_view_model.dart b/lib/core/viewModels/medical/medical_view_model.dart index 52fd221a..a111b6a5 100644 --- a/lib/core/viewModels/medical/medical_view_model.dart +++ b/lib/core/viewModels/medical/medical_view_model.dart @@ -1,25 +1,53 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; -import 'package:diplomaticquarterapp/core/service/AuthenticatedUserObject.dart'; import 'package:diplomaticquarterapp/core/service/medical/medical_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; import 'package:diplomaticquarterapp/locator.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; +import 'package:diplomaticquarterapp/pages/MyAppointments/models/DoctorScheduleResponse.dart'; class MedicalViewModel extends BaseViewModel { MedicalService _medicalService = locator(); - List get appoitmentAllHistoryResultList => - _medicalService.appoitmentAllHistoryResultList; + List get appoitmentAllHistoryResultList => _medicalService.appoitmentAllHistoryResultList; - getAppointmentHistory() async { - if (authenticatedUserObject.isLogin) { + List get getDoctorScheduleList => _medicalService.doctorScheduleResponse; + + List get freeSlots => _medicalService.freeSlots; + + getAppointmentHistory({bool isForTimeLine = false}) async { + if (authenticatedUserObject.isLogin) { setState(ViewState.Busy); - await _medicalService.getAppointmentHistory(); + await _medicalService.getAppointmentHistory(isForTimeLine: isForTimeLine); if (_medicalService.hasError) { - error = _medicalService.error; + error = _medicalService.error!; setState(ViewState.Error); } else setState(ViewState.Idle); } } + + getDoctorSchedule(DoctorList doctorRequest) async { + //if (authenticatedUserObject.isLogin) { + setState(ViewState.Busy); + await _medicalService.getSchedule(doctorRequest); + if (_medicalService.hasError) { + error = _medicalService.error!; + setState(ViewState.Error); + } else + setState(ViewState.Idle); + //} + } + + getFreeSlots(DoctorList doctorRequest) async { + //if (authenticatedUserObject.isLogin) { + setState(ViewState.Busy); + await _medicalService.getFreeSlot(doctorRequest); + if (_medicalService.hasError) { + error = _medicalService.error!; + setState(ViewState.Error); + } else + setState(ViewState.Idle); + } +//} } diff --git a/lib/core/viewModels/medical/my_balance_view_model.dart b/lib/core/viewModels/medical/my_balance_view_model.dart index e33bc86c..24e01d18 100644 --- a/lib/core/viewModels/medical/my_balance_view_model.dart +++ b/lib/core/viewModels/medical/my_balance_view_model.dart @@ -32,13 +32,13 @@ class MyBalanceViewModel extends BaseViewModel { _bloodDonationService.CitiesModelList; BloodDetailsService _bloodDetailsService = locator(); - List get BloodDetailsModelList => + List get bloodDetailsModelList => _bloodDetailsService .BloodModelList; //_bloodDonationService.CitiesModelList; //=========================== - double get totalAdvanceBalanceAmount => + dynamic get totalAdvanceBalanceAmount => _myBalanceService.totalAdvanceBalanceAmount; String get updatedRegisterBloodMessage => @@ -50,58 +50,63 @@ class MyBalanceViewModel extends BaseViewModel { List get patientInfoList => _myBalanceService.patientInfoList; PatientInfoAndMobileNumber get patientInfoAndMobileNumber => - _myBalanceService.patientInfoAndMobileNumber; + _myBalanceService.patientInfoAndMobileNumber!; - String get logInTokenID => _myBalanceService.logInTokenID; + List get bloodModelList => + _bloodDetailsService.BloodModelList; - String get verificationCode => _myBalanceService.verificationCode; + String get logInTokenID => _myBalanceService.logInTokenID!; + + String get verificationCode => _myBalanceService.verificationCode!; getPatientAdvanceBalanceAmount() async { setState(ViewState.Busy); await _myBalanceService.getPatientAdvanceBalanceAmount(); if (_myBalanceService.hasError) { - error = _myBalanceService.error; + error = _myBalanceService.error!; setState(ViewState.Error); } else { setState(ViewState.Idle); } } - Future getHospitals() async { + Future getHospitals(int languageID, {bool isAdvancePayment = false}) async { setState(ViewState.Busy); - await _hospitalService.getHospitals(); + await _hospitalService.getHospitals(languageID, isAdvancePayment: isAdvancePayment); if (_hospitalService.hasError) { - error = _hospitalService.error; + error = _hospitalService.error!; setState(ViewState.Error); } else setState(ViewState.Idle); } Future getCities() async { - setState(ViewState.Busy); - await _bloodDonationService.getAllCitiesOrders(); - if (_bloodDonationService.hasError) { - error = _bloodDonationService.error; - setState(ViewState.Error); - } else - setState(ViewState.Idle); + if(isLogin) { + setState(ViewState.Busy); + await _bloodDonationService.getAllCitiesOrders(); + if (_bloodDonationService.hasError) { + error = _bloodDonationService.error!; + setState(ViewState.Error); + } else + setState(ViewState.Idle); + } } Future getBlood() async { setState(ViewState.Busy); await _bloodDetailsService.getAllBloodOrders(); if (_bloodDetailsService.hasError) { - error = _bloodDetailsService.error; + error = _bloodDetailsService.error!; setState(ViewState.Error); } else setState(ViewState.Idle); } - Future getPatientInfoByPatientID({String id}) async { + Future getPatientInfoByPatientID({required String id}) async { setState(ViewState.Busy); await _myBalanceService.getPatientInfoByPatientID(id: id); if (_myBalanceService.hasError) { - error = _myBalanceService.error; + error = _myBalanceService.error!; setState(ViewState.ErrorLocal); AppToast.showErrorToast(message: error); } else { @@ -115,7 +120,7 @@ class MyBalanceViewModel extends BaseViewModel { await _myBalanceService .getPatientInfoByPatientIDAndMobileNumber(advanceModel); if (_myBalanceService.hasError) { - error = _myBalanceService.error; + error = _myBalanceService.error!; setState(ViewState.ErrorLocal); AppToast.showErrorToast(message: error); } else { @@ -124,12 +129,12 @@ class MyBalanceViewModel extends BaseViewModel { } Future sendActivationCodeForAdvancePayment( - {int patientID, int projectID}) async { + {required int patientID, required int projectID}) async { setState(ViewState.Busy); await _myBalanceService.sendActivationCodeForAdvancePayment( patientID: patientID, projectID: projectID); if (_myBalanceService.hasError) { - error = _myBalanceService.error; + error = _myBalanceService.error!; setState(ViewState.ErrorLocal); AppToast.showErrorToast(message: error); } else { @@ -138,12 +143,12 @@ class MyBalanceViewModel extends BaseViewModel { } Future checkActivationCodeForAdvancePayment( - {String activationCode, String patientMobileNumber}) async { + {required String activationCode, String? patientMobileNumber}) async { setState(ViewState.Busy); await _myBalanceService.checkActivationCodeForAdvancePayment( activationCode: activationCode); if (_myBalanceService.hasError) { - error = _myBalanceService.error; + error = _myBalanceService.error!; setState(ViewState.ErrorLocal); } else { setState(ViewState.Idle); @@ -154,7 +159,7 @@ class MyBalanceViewModel extends BaseViewModel { setState(ViewState.Busy); await _myBalanceService.getFamilyFiles(); if (_myBalanceService.hasError) { - error = _myBalanceService.error; + error = _myBalanceService.error!; setState(ViewState.ErrorLocal); AppToast.showErrorToast(message: error); } else { @@ -166,7 +171,7 @@ class MyBalanceViewModel extends BaseViewModel { setState(ViewState.Busy); await _myBalanceService.updateBloodGroup(detailsModel); if (_myBalanceService.hasError) { - error = _myBalanceService.error; + error = _myBalanceService.error!; setState(ViewState.ErrorLocal); } else { await _myBalanceService.addUserAgreementForBloodDonation(); diff --git a/lib/core/viewModels/medical/my_doctor_view_model.dart b/lib/core/viewModels/medical/my_doctor_view_model.dart index 266157ff..da070d17 100644 --- a/lib/core/viewModels/medical/my_doctor_view_model.dart +++ b/lib/core/viewModels/medical/my_doctor_view_model.dart @@ -13,26 +13,26 @@ class MyDoctorViewModel extends BaseViewModel { MyDoctorService _myDoctorService = locator(); List _patientDoctorAppointmentListClinic = - List(); + []; List _patientDoctorAppointmentListHospital = - List(); + []; List get patientDoctorAppointmentList => filterType == FilterType.Clinic ? _patientDoctorAppointmentListClinic : _patientDoctorAppointmentListHospital; - DoctorList get doctorList=> _myDoctorService.doctorList; + DoctorList get doctorList=> _myDoctorService.doctorList!; - DoctorProfile get doctorProfile => _myDoctorService.doctorProfile; + DoctorProfile get doctorProfile => _myDoctorService.doctorProfile!; DoctorRating get doctorRating => _myDoctorService.doctorRating; void getMyDoctor() async { setState(ViewState.Busy); await _myDoctorService.getPatientDoctorAppointmentList(); if (_myDoctorService.hasError) { - error = _myDoctorService.error; + error = _myDoctorService.error!; setState(ViewState.Error); } else { _myDoctorService.patientDoctorAppointmentList.forEach((element) { @@ -46,7 +46,7 @@ class MyDoctorViewModel extends BaseViewModel { _patientDoctorAppointmentListClinic[ _patientDoctorAppointmentListClinic .indexOf(doctorByClinic[0])] - .patientDoctorAppointmentList + .patientDoctorAppointmentList! .add(element); } else { _patientDoctorAppointmentListClinic.add(PatientDoctorAppointmentList( @@ -65,7 +65,7 @@ class MyDoctorViewModel extends BaseViewModel { if (doctorByHospital.length != 0) { _patientDoctorAppointmentListHospital[_patientDoctorAppointmentListHospital.indexOf(doctorByHospital[0])] - .patientDoctorAppointmentList + .patientDoctorAppointmentList! .add(element); } else { _patientDoctorAppointmentListHospital.add( @@ -84,11 +84,11 @@ class MyDoctorViewModel extends BaseViewModel { notifyListeners(); } - Future getDoctorProfileAndRating({int doctorId,int clinicID,int projectID }) async { + Future getDoctorProfileAndRating({required int doctorId,required int clinicID,required int projectID }) async { setState(ViewState.Busy); await _myDoctorService.getDoctorProfileAndRating(doctorId: doctorId,clinicID: clinicID,projectID: projectID); if (_myDoctorService.hasError) { - error = _myDoctorService.error; + error = _myDoctorService.error!; setState(ViewState.Error); } else setState(ViewState.Idle); diff --git a/lib/core/viewModels/medical/patient_sick_leave_view_model.dart b/lib/core/viewModels/medical/patient_sick_leave_view_model.dart index 6addf833..d0390f88 100644 --- a/lib/core/viewModels/medical/patient_sick_leave_view_model.dart +++ b/lib/core/viewModels/medical/patient_sick_leave_view_model.dart @@ -5,17 +5,24 @@ import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; import 'package:diplomaticquarterapp/locator.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'dart:convert'; +import 'dart:io'; +import 'dart:typed_data'; +import 'package:open_filex/open_filex.dart'; +import 'package:path_provider/path_provider.dart'; + class PatientSickLeaveViewMode extends BaseViewModel { - PatientSickLeaveService _patientSickLeaveService = - locator(); + PatientSickLeaveService _patientSickLeaveService = locator(); List get sickLeaveList => _patientSickLeaveService.sickLeaveList; + String get sickLeavePDF => _patientSickLeaveService.sickLeavePDF; + getSickLeave() async { setState(ViewState.Busy); await _patientSickLeaveService.getSickLeave(); if (_patientSickLeaveService.hasError) { - error = _patientSickLeaveService.error; + error = _patientSickLeaveService.error!; setState(ViewState.Error); } else { setState(ViewState.Idle); @@ -23,20 +30,35 @@ class PatientSickLeaveViewMode extends BaseViewModel { } Future sendSickLeaveEmail( - {String message, - int requestNo, - String projectName, - String doctorName,int projectID,String setupID}) async { + {required String message, required int requestNo, required String projectName, required String doctorName, required int projectID, required String setupID, required bool isDownload}) async { setState(ViewState.Busy); - await _patientSickLeaveService.sendSickLeaveEmail( - requestNo: requestNo, projectName: projectName, doctorName: doctorName,projectID: projectID,setupID: setupID); + await _patientSickLeaveService.sendSickLeaveEmail(requestNo: requestNo, projectName: projectName, doctorName: doctorName, projectID: projectID, setupID: setupID, isDownload: isDownload); if (_patientSickLeaveService.hasError) { - error = _patientSickLeaveService.error; + error = _patientSickLeaveService.error!; setState(ViewState.ErrorLocal); AppToast.showErrorToast(message: error); } else { - AppToast.showSuccessToast(message: message); + if (isDownload) { + if (sickLeavePDF.isNotEmpty) { + String path = await _createFileFromString(sickLeavePDF, "pdf"); + try { + OpenFilex.open(path); + } catch (ex) { + AppToast.showErrorToast(message: "Cannot open file."); + } + } + } else { + AppToast.showSuccessToast(message: message); + } setState(ViewState.Idle); } } + + Future _createFileFromString(String encodedStr, String ext) async { + Uint8List bytes = base64.decode(encodedStr); + String dir = (await getApplicationDocumentsDirectory()).path; + File file = File("$dir/" + DateTime.now().millisecondsSinceEpoch.toString() + "." + ext); + await file.writeAsBytes(bytes); + return file.path; + } } diff --git a/lib/core/viewModels/medical/prescriptions_view_model.dart b/lib/core/viewModels/medical/prescriptions_view_model.dart index 2c32a081..82c0282e 100644 --- a/lib/core/viewModels/medical/prescriptions_view_model.dart +++ b/lib/core/viewModels/medical/prescriptions_view_model.dart @@ -1,9 +1,13 @@ +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_info_rc_model.dart'; import 'package:diplomaticquarterapp/core/model/prescriptions/prescription_report.dart'; import 'package:diplomaticquarterapp/core/model/prescriptions/prescription_report_enh.dart'; +import 'package:diplomaticquarterapp/core/model/prescriptions/prescription_report_inp.dart'; import 'package:diplomaticquarterapp/core/model/prescriptions/prescriptions_order.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:flutter/cupertino.dart'; +import 'package:open_filex/open_filex.dart'; import '../../../core/enum/filter_type.dart'; import '../../../core/enum/viewstate.dart'; @@ -12,39 +16,51 @@ import '../../../core/service/medical/prescriptions_service.dart'; import '../../../locator.dart'; import '../base_view_model.dart'; +import 'dart:convert'; +import 'dart:io'; +import 'dart:typed_data'; +import 'package:path_provider/path_provider.dart'; + class PrescriptionsViewModel extends BaseViewModel { FilterType filterType = FilterType.Clinic; PrescriptionsService _prescriptionsService = locator(); - List _prescriptionsOrderListClinic = List(); - List _prescriptionsOrderListHospital = List(); + List _prescriptionsOrderListClinic = []; + List _prescriptionsOrderListHospital = []; + + List get prescriptionReportList => _prescriptionsService.prescriptionReportList; + + List get prescriptionReportListINP => _prescriptionsService.prescriptionReportListINP; + + List get prescriptionsList => _prescriptionsService.prescriptionsList; + List get prescriptionsHistory => _prescriptionsService.prescriptionsOrderList; - List get prescriptionReportList => - _prescriptionsService.prescriptionReportList; + List get pharmacyPrescriptionsList => _prescriptionsService.pharmacyPrescriptionsList; - List get prescriptionsList => - _prescriptionsService.prescriptionsList; + List get prescriptionReportEnhList => _prescriptionsService.prescriptionReportEnhList; - List get prescriptionsHistory => _prescriptionsService.prescriptionsOrderList; + List get prescriptionsOrderListRC => _prescriptionsService.prescriptionsOrderListRC; - List get pharmacyPrescriptionsList => _prescriptionsService.pharmacyPrescriptionsList ; + List get prescriptionsOrderList => filterType == FilterType.Clinic ? _prescriptionsOrderListClinic : _prescriptionsOrderListHospital; + List prescriptionsOrderListByValue(filterValue) { + return filterValue == FilterType.Clinic ? _prescriptionsOrderListClinic : _prescriptionsOrderListHospital; + } + + get isMedDeliveryAllowed => _prescriptionsService.isMedDeliveryAllowed; - List get prescriptionsOrderList => - filterType == FilterType.Clinic - ? _prescriptionsOrderListClinic - : _prescriptionsOrderListHospital; + String get prescriptionReportPDF => _prescriptionsService.prescriptionReportPDF; getPrescriptions() async { setState(ViewState.Busy); await _prescriptionsService.getPrescriptions(); if (_prescriptionsService.hasError) { - error = _prescriptionsService.error; + error = _prescriptionsService.error!; setState(ViewState.Error); } else { _filterList(); - await _getPrescriptionsOrders(); +// await getPrescriptionsOrders(); setState(ViewState.Idle); } } @@ -52,50 +68,41 @@ class PrescriptionsViewModel extends BaseViewModel { void _filterList() { _prescriptionsService.prescriptionsList.forEach((element) { /// PrescriptionsList list sort clinic - List prescriptionsByClinic = - _prescriptionsOrderListClinic - .where((elementClinic) => - elementClinic.filterName == element.clinicDescription) - .toList(); + List prescriptionsByClinic = _prescriptionsOrderListClinic.where((elementClinic) => elementClinic.filterName == element.clinicDescription).toList(); if (prescriptionsByClinic.length != 0) { - _prescriptionsOrderListClinic[ - _prescriptionsOrderListClinic.indexOf(prescriptionsByClinic[0])] - .prescriptionsList - .add(element); + _prescriptionsOrderListClinic[_prescriptionsOrderListClinic.indexOf(prescriptionsByClinic[0])].prescriptionsList!.add(element); } else { - _prescriptionsOrderListClinic.add(PrescriptionsList( - filterName: element.clinicDescription, prescriptions: element)); + _prescriptionsOrderListClinic.add(PrescriptionsList(filterName: element.clinicDescription, prescriptions: element)); } /// PrescriptionsList list sort via hospital - List prescriptionsByHospital = - _prescriptionsOrderListHospital - .where( - (elementClinic) => elementClinic.filterName == element.name, - ) - .toList(); + List prescriptionsByHospital = _prescriptionsOrderListHospital + .where( + (elementClinic) => elementClinic.filterName == element.name, + ) + .toList(); if (prescriptionsByHospital.length != 0) { - _prescriptionsOrderListHospital[_prescriptionsOrderListHospital - .indexOf(prescriptionsByHospital[0])] - .prescriptionsList - .add(element); + _prescriptionsOrderListHospital[_prescriptionsOrderListHospital.indexOf(prescriptionsByHospital[0])].prescriptionsList!.add(element); } else { - _prescriptionsOrderListHospital.add(PrescriptionsList( - filterName: element.name, prescriptions: element)); + _prescriptionsOrderListHospital.add(PrescriptionsList(filterName: element.name, prescriptions: element)); } }); } - _getPrescriptionsOrders() async { - await _prescriptionsService.getPrescriptionsOrders(); - if (_prescriptionsService.hasError) { - error = _prescriptionsService.error; - setState(ViewState.ErrorLocal); - } else { - setState(ViewState.Idle); - } + getPrescriptionsOrders({bool showLoading = false}) async { + setState(ViewState.Busy); + Future.delayed(new Duration(milliseconds: 300)).then((value) async { + // await _prescriptionsService.getPrescriptionsOrders(); + await _prescriptionsService.getPrescriptionsOrdersRC(); + if (_prescriptionsService.hasError) { + error = _prescriptionsService.error!; + setState(ViewState.ErrorLocal); + } else { + setState(ViewState.Idle); + } + }); } setFilterType(FilterType filterType) { @@ -103,11 +110,11 @@ class PrescriptionsViewModel extends BaseViewModel { notifyListeners(); } - getPrescriptionReport({Prescriptions prescriptions}) async { + getPrescriptionReport({required Prescriptions prescriptions}) async { setState(ViewState.Busy); await _prescriptionsService.getPrescriptionReport(prescriptions: prescriptions); if (_prescriptionsService.hasError) { - error = _prescriptionsService.error; + error = _prescriptionsService.error!; setState(ViewState.ErrorLocal); } else { setState(ViewState.Idle); @@ -115,60 +122,89 @@ class PrescriptionsViewModel extends BaseViewModel { } sendPrescriptionEmail( - {String appointmentDate, - int patientID, - String clinicName, - String doctorName, - String mes, - int projectID}) async { + {required String appointmentDate, + required int patientID, + required String clinicName, + required String doctorName, + required int doctorID, + required String mes, + required int projectID, + required bool isInOutPatient, + required bool isDownload}) async { setState(ViewState.BusyLocal); - await _prescriptionsService.sendPrescriptionEmail( - appointmentDate, patientID, clinicName, doctorName, projectID); + await _prescriptionsService.sendPrescriptionEmail(appointmentDate, patientID, clinicName, doctorName, doctorID, projectID, isInOutPatient, isDownload); if (_prescriptionsService.hasError) { - error = _prescriptionsService.error; + error = _prescriptionsService.error!; setState(ViewState.ErrorLocal); AppToast.showErrorToast(message: error); } else { - AppToast.showSuccessToast(message: mes); + if (isDownload) { + if (prescriptionReportPDF.isNotEmpty) { + String path = await _createFileFromString(prescriptionReportPDF, "pdf"); + try { + OpenFilex.open(path); + } catch (ex) { + AppToast.showErrorToast(message: "Cannot open file."); + } + } + } else { + AppToast.showSuccessToast(message: mes); + } + // AppToast.showSuccessToast(message: mes); setState(ViewState.Idle); } } - getListPharmacyForPrescriptions({int itemId}) async { + getListPharmacyForPrescriptions({required int itemId}) async { setState(ViewState.Busy); await _prescriptionsService.getListPharmacyForPrescriptions(itemId: itemId); if (_prescriptionsService.hasError) { - error = _prescriptionsService.error; - setState(ViewState.Error); + error = _prescriptionsService.error!; + setState(ViewState.ErrorLocal); } else { setState(ViewState.Idle); } } - - List get prescriptionReportEnhList => _prescriptionsService.prescriptionReportEnhList; - - getPrescriptionReportEnh({PrescriptionsOrder prescriptionsOrder}) async { + getPrescriptionReportEnh({required PrescriptionsOrder prescriptionsOrder}) async { setState(ViewState.Busy); await _prescriptionsService.getPrescriptionReportEnh(prescriptionsOrder: prescriptionsOrder); if (_prescriptionsService.hasError) { - error = _prescriptionsService.error; + error = _prescriptionsService.error!; setState(ViewState.Error); } else { setState(ViewState.Idle); } } - - Future updatePressOrder({@required int presOrderID}) async { + getPrescriptionReportDetailsRC(int orderID, dynamic patientID) async { setState(ViewState.Busy); - await _prescriptionsService.updatePressOrder(presOrderID: presOrderID); + await _prescriptionsService.getPrescriptionsInfoRC(orderID, patientID); if (_prescriptionsService.hasError) { - error = _prescriptionsService.error; + error = _prescriptionsService.error!; setState(ViewState.Error); } else { - await getPrescriptions(); + setState(ViewState.Idle); } } + Future _createFileFromString(String encodedStr, String ext) async { + Uint8List bytes = base64.decode(encodedStr); + String dir = (await getApplicationDocumentsDirectory()).path; + File file = File("$dir/" + DateTime.now().millisecondsSinceEpoch.toString() + "." + ext); + await file.writeAsBytes(bytes); + return file.path; + } + + Future updatePressOrder({required int presOrderID}) async { + setState(ViewState.Busy); + // await _prescriptionsService.updatePressOrder(presOrderID: presOrderID); + await _prescriptionsService.updatePressOrderRC(presOrderID: presOrderID); + if (_prescriptionsService.hasError) { + error = _prescriptionsService.error!; + setState(ViewState.Error); + } else { + await getPrescriptions(); + } + } } diff --git a/lib/core/viewModels/medical/radiology_view_model.dart b/lib/core/viewModels/medical/radiology_view_model.dart index 076707dc..6b8c4c96 100644 --- a/lib/core/viewModels/medical/radiology_view_model.dart +++ b/lib/core/viewModels/medical/radiology_view_model.dart @@ -1,66 +1,53 @@ +import "package:collection/collection.dart"; import 'package:diplomaticquarterapp/core/enum/filter_type.dart'; import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/radiology/final_radiology.dart'; import 'package:diplomaticquarterapp/core/service/medical/radiology_service.dart'; +import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import '../../../locator.dart'; import '../base_view_model.dart'; +import 'dart:convert'; +import 'dart:io'; +import 'dart:typed_data'; +import 'package:open_filex/open_filex.dart'; +import 'package:path_provider/path_provider.dart'; + class RadiologyViewModel extends BaseViewModel { FilterType filterType = FilterType.Clinic; RadiologyService _radiologyService = locator(); - List _finalRadiologyListClinic = List(); - List _finalRadiologyListHospital = List(); + List _finalRadiologyListClinic = []; + List _finalRadiologyListHospital = []; + + List get finalRadiologyList => filterType == FilterType.Clinic ? _finalRadiologyListClinic : _finalRadiologyListHospital; + + bool _isRadiologyVIDAPlus = false; - List get finalRadiologyList => - filterType == FilterType.Clinic - ? _finalRadiologyListClinic - : _finalRadiologyListHospital; + bool get isRadiologyVIDAPlus => _isRadiologyVIDAPlus; + + String get radReportPDF => _radiologyService.radReportPDF; void getPatientRadOrders() async { setState(ViewState.Busy); await _radiologyService.getPatientRadOrders(); + _isRadiologyVIDAPlus = _radiologyService.isRadiologyVIDAPlus; if (_radiologyService.hasError) { - error = _radiologyService.error; + error = _radiologyService.error!; setState(ViewState.Error); } else { - _radiologyService.finalRadiologyList.forEach((element) { - List finalRadiologyListClinic = - _finalRadiologyListClinic - .where((elementClinic) => - elementClinic.filterName == element.clinicDescription) - .toList(); - - if (finalRadiologyListClinic.length != 0) { - _finalRadiologyListClinic[ - finalRadiologyListClinic.indexOf(finalRadiologyListClinic[0])] - .finalRadiologyList - .add(element); - } else { - _finalRadiologyListClinic.add(FinalRadiologyList( - filterName: element.clinicDescription, finalRadiology: element)); - } + //Clinic Sorting + var clinicMap = groupBy(_radiologyService.finalRadiologyList, (FinalRadiology obj) => obj.clinicDescription); + clinicMap.forEach((key, value) { + _finalRadiologyListClinic.add(FinalRadiologyList(filterName: key, finalRadiologyList: value.toList())); + }); - // FinalRadiologyList list sort via project - List finalRadiologyListHospital = - _finalRadiologyListHospital - .where( - (elementClinic) => - elementClinic.filterName == element.projectName, - ) - .toList(); - - if (finalRadiologyListHospital.length != 0) { - _finalRadiologyListHospital[finalRadiologyListHospital - .indexOf(finalRadiologyListHospital[0])] - .finalRadiologyList - .add(element); - } else { - _finalRadiologyListHospital.add(FinalRadiologyList( - filterName: element.projectName, finalRadiology: element)); - } + //Hospital Sorting + var hospitalMap = groupBy(_radiologyService.finalRadiologyList, (FinalRadiology obj) => obj.projectName); + hospitalMap.forEach((key, value) { + _finalRadiologyListHospital.add(FinalRadiologyList(filterName: key, finalRadiologyList: value.toList())); }); setState(ViewState.Idle); @@ -69,31 +56,48 @@ class RadiologyViewModel extends BaseViewModel { String get radImageURL => _radiologyService.url; - getRadImageURL({int invoiceNo, int lineItem,int projectId}) async { + getRadImageURL({required int invoiceNo, String? invoiceType, required int lineItem, required int projectId, required bool isVidaPlus, required String examId}) async { setState(ViewState.Busy); - await _radiologyService.getRadImageURL(invoiceNo: invoiceNo,lineItem: lineItem,projectId: projectId); + await _radiologyService.getRadImageURL(invoiceNo: invoiceNo, invoiceType: invoiceType, lineItem: lineItem, projectId: projectId, isVidaPlus: isVidaPlus, examId: examId); if (_radiologyService.hasError) { - error = _radiologyService.error; + error = _radiologyService.error!; setState(ViewState.Error); } else setState(ViewState.Idle); } - sendRadReportEmail( - {FinalRadiology finalRadiology,String mes}) async { + sendRadReportEmail({required FinalRadiology finalRadiology, required String mes, required AuthenticatedUser userObj, required isDownload}) async { setState(ViewState.BusyLocal); - await _radiologyService.sendRadReportEmail( - finalRadiology: finalRadiology - ); + await _radiologyService.sendRadReportEmail(finalRadiology: finalRadiology, userObj: userObj, isDownload: isDownload); if (_radiologyService.hasError) { - error = _radiologyService.error; + error = _radiologyService.error!; AppToast.showErrorToast(message: error); } else { - AppToast.showSuccessToast(message: mes); + if (isDownload) { + if (radReportPDF.isNotEmpty) { + String path = await _createFileFromString(radReportPDF, "pdf"); + try { + OpenFilex.open(path); + } catch (ex) { + AppToast.showErrorToast(message: "Cannot open file."); + } + } + } else { + AppToast.showSuccessToast(message: mes); + } + // AppToast.showSuccessToast(message: mes); } setState(ViewState.Idle); } + Future _createFileFromString(String encodedStr, String ext) async { + Uint8List bytes = base64.decode(encodedStr); + String dir = (await getApplicationDocumentsDirectory()).path; + File file = File("$dir/" + DateTime.now().millisecondsSinceEpoch.toString() + "." + ext); + await file.writeAsBytes(bytes); + return file.path; + } + setFilterType(FilterType filterType) { this.filterType = filterType; notifyListeners(); diff --git a/lib/core/viewModels/medical/reports_monthly_view_model.dart b/lib/core/viewModels/medical/reports_monthly_view_model.dart index adb7223e..bbd6916e 100644 --- a/lib/core/viewModels/medical/reports_monthly_view_model.dart +++ b/lib/core/viewModels/medical/reports_monthly_view_model.dart @@ -1,9 +1,7 @@ -import 'package:diplomaticquarterapp/pages/feedback/appointment_history.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import '../../../core/enum/reportfilter_type.dart'; import '../../../core/enum/viewstate.dart'; -import '../../../core/model/reports/Reports.dart'; import '../../../core/service/medical/reports_service.dart'; import '../../../locator.dart'; import '../base_view_model.dart'; @@ -14,35 +12,34 @@ class ReportsMonthlyViewModel extends BaseViewModel { ReportsService _reportsService = locator(); String get userAgreementContent => _reportsService.userAgreementContent; + bool get receiveHealthSummaryReport => _reportsService?.user?.receiveHealthSummaryReport ?? false; + set receiveHealthSummaryReport(bool val) { + _reportsService?.user?.receiveHealthSummaryReport = val; + } getUserTermsAndConditions() async { setState(ViewState.Busy); await _reportsService.getUserTermsAndConditions(); if (_reportsService.hasError) { - error = _reportsService.error; + error = _reportsService.error!; setState(ViewState.Error); } else { setState(ViewState.Idle); } } - updatePatientHealthSummaryReport( - {String message, - bool isSummary, - bool isUpdateEmail = false, - String email}) async { + updatePatientHealthSummaryReport({required String message, required bool isSummary, bool isUpdateEmail = false, String? email}) async { setState(ViewState.BusyLocal); - await _reportsService.updatePatientHealthSummaryReport( - isSummary: isSummary); + await _reportsService.updatePatientHealthSummaryReport(isSummary: isSummary); if (_reportsService.hasError) { - error = _reportsService.error; + error = _reportsService.error!; AppToast.showErrorToast(message: error); setState(ViewState.ErrorLocal); } else { if (isUpdateEmail) { - await _reportsService.updateEmail(email: email); + await _reportsService.updateEmail(email: email!); if (_reportsService.hasError) { - error = _reportsService.error; + error = _reportsService.error!; AppToast.showErrorToast(message: error); setState(ViewState.ErrorLocal); } else { diff --git a/lib/core/viewModels/medical/reports_view_model.dart b/lib/core/viewModels/medical/reports_view_model.dart index 271b5463..04f701c5 100644 --- a/lib/core/viewModels/medical/reports_view_model.dart +++ b/lib/core/viewModels/medical/reports_view_model.dart @@ -1,3 +1,4 @@ +import 'package:diplomaticquarterapp/core/model/reports/admission_for_medical_report.dart'; import 'package:diplomaticquarterapp/pages/feedback/appointment_history.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; @@ -13,26 +14,45 @@ class ReportsViewModel extends BaseViewModel { ReportsService _reportsService = locator(); - List reportsOrderRequestList = List(); - List reportsOrderReadyList = List(); - List reportsOrderCompletedList = List(); - List reportsOrderCanceledList = List(); + List reportsOrderRequestList =[]; + List reportsOrderReadyList =[]; + List reportsOrderCanceledList =[]; - List get appointHistoryList => - _reportsService.appointHistoryList; + List reportsInPatientOrderRequestList =[]; + List reportsInPatientOrderReadyList =[]; + List reportsInPatientOrderCanceledList =[]; - getReports() async { + List get appointHistoryList => _reportsService.appointHistoryList; + + List get admissionsMedicalReportList => _reportsService.admissionsMedicalReport; + + getReports(int languageID) async { setState(ViewState.Busy); reportsOrderRequestList.clear(); reportsOrderReadyList.clear(); - reportsOrderCompletedList.clear(); reportsOrderCanceledList.clear(); await _reportsService.getReports(); if (_reportsService.hasError) { - error = _reportsService.error; + error = _reportsService.error!; setState(ViewState.Error); } else { _filterList(); + await _reportsService.getInpatientAdmissionsList(languageID); + setState(ViewState.Idle); + } + } + + getInPatientReports() async { + setState(ViewState.Busy); + reportsInPatientOrderRequestList.clear(); + reportsInPatientOrderReadyList.clear(); + reportsInPatientOrderCanceledList.clear(); + await _reportsService.getInPatientReports(); + if (_reportsService.hasError) { + error = _reportsService.error!; + setState(ViewState.Error); + } else { + _filterInPatientList(); setState(ViewState.Idle); } } @@ -41,13 +61,30 @@ class ReportsViewModel extends BaseViewModel { setState(ViewState.Busy); await _reportsService.getPatentAppointmentHistory(); if (_reportsService.hasError) { - error = _reportsService.error; + error = _reportsService.error!; setState(ViewState.Error); } else { setState(ViewState.Idle); } } + void _filterInPatientList() { + _reportsService.inpatientReportsList.forEach((report) { + switch (report.status) { + case 1: + reportsInPatientOrderRequestList.add(report); + break; + case 2: + reportsInPatientOrderReadyList.add(report); + break; + case 4: + reportsInPatientOrderCanceledList.add(report); + break; + default: + } + }); + } + void _filterList() { _reportsService.reportsList.forEach((report) { switch (report.status) { @@ -57,9 +94,6 @@ class ReportsViewModel extends BaseViewModel { case 2: reportsOrderReadyList.add(report); break; - case 3: - reportsOrderCompletedList.add(report); - break; case 4: reportsOrderCanceledList.add(report); break; @@ -68,17 +102,31 @@ class ReportsViewModel extends BaseViewModel { }); } + insertRequestForMedicalReport(AppointmentHistory appointmentHistory, String mes) async { + setState(ViewState.Busy); + await _reportsService.insertRequestForMedicalReport(appointmentHistory); + if (_reportsService.hasError) { + error = _reportsService.error!; + AppToast.showErrorToast(message: error); + setState(ViewState.ErrorLocal); + } else { + AppToast.showSuccessToast(message: mes); + getInPatientReports(); + setState(ViewState.Idle); + } + } - insertRequestForMedicalReport(AppointmentHistory appointmentHistory,String mes)async{ - setState(ViewState.Busy); - await _reportsService.insertRequestForMedicalReport(appointmentHistory); - if (_reportsService.hasError) { - error = _reportsService.error; - AppToast.showErrorToast(message: error); - setState(ViewState.ErrorLocal); - } else { - AppToast.showSuccessToast(message: mes); - setState(ViewState.Idle); - } + insertRequestForInPatientMedicalReport(int clinicID, int doctorID, String setupID, int admissionNo, int projectID, String mes) async { + setState(ViewState.Busy); + await _reportsService.insertRequestForInPatientMedicalReport(clinicID, doctorID, setupID, admissionNo, projectID); + if (_reportsService.hasError) { + error = _reportsService.error!; + AppToast.showErrorToast(message: error); + setState(ViewState.ErrorLocal); + } else { + AppToast.showSuccessToast(message: mes); + setState(ViewState.Idle); + } } + } diff --git a/lib/core/viewModels/medical/vital_sign_view_model.dart b/lib/core/viewModels/medical/vital_sign_view_model.dart index b2110187..232246d4 100644 --- a/lib/core/viewModels/medical/vital_sign_view_model.dart +++ b/lib/core/viewModels/medical/vital_sign_view_model.dart @@ -19,7 +19,7 @@ class VitalSignViewModel extends BaseViewModel { String respirationBeatPerMinute = "0"; String bloodPressure = "0 / 0"; - getPatientVitalSign({int appointmentNo, int projectID}) async { + getPatientVitalSign({int? appointmentNo, int? projectID}) async { setState(ViewState.Busy); if (appointmentNo != null && projectID != null) { @@ -29,7 +29,7 @@ class VitalSignViewModel extends BaseViewModel { await _vitalSignService.getPatientRadOrders(); } if (_vitalSignService.hasError) { - error = _vitalSignService.error; + error = _vitalSignService.error!; setState(ViewState.Error); } else { _vitalSignService.vitalSignResModelList.forEach((element) { diff --git a/lib/core/viewModels/medical/weight_pressure_view_model.dart b/lib/core/viewModels/medical/weight_pressure_view_model.dart index 42db0a58..8a689786 100644 --- a/lib/core/viewModels/medical/weight_pressure_view_model.dart +++ b/lib/core/viewModels/medical/weight_pressure_view_model.dart @@ -1,14 +1,7 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; -import 'package:diplomaticquarterapp/core/model/my_trakers/blood_pressur/BloodPressureResult.dart'; -import 'package:diplomaticquarterapp/core/model/my_trakers/blood_sugar/DiabtecPatientResult.dart'; -import 'package:diplomaticquarterapp/core/model/my_trakers/chartData/WeekChartDate.dart'; -import 'package:diplomaticquarterapp/core/model/my_trakers/chartData/YearMonthlyChartDate.dart'; import 'package:diplomaticquarterapp/core/model/my_trakers/weight/WeightMeasurementResult.dart'; -import 'package:diplomaticquarterapp/core/service/medical/BloodPressureService.dart'; -import 'package:diplomaticquarterapp/core/service/medical/BloodSugarService.dart'; import 'package:diplomaticquarterapp/core/service/medical/WeightPressureService.dart'; import 'package:diplomaticquarterapp/locator.dart'; -import 'package:charts_flutter/flutter.dart' as charts; import 'package:diplomaticquarterapp/widgets/charts/app_time_series_chart.dart'; import '../../../core/viewModels/base_view_model.dart'; @@ -16,14 +9,11 @@ import '../../../core/viewModels/base_view_model.dart'; class WeightPressureViewModel extends BaseViewModel { WeightService weightService = locator(); - List get monthWeightMeasurementResult => - weightService.monthWeightMeasurementResult; + List get monthWeightMeasurementResult => weightService.monthWeightMeasurementResult; - List get weekWeightMeasurementResult => - weightService.weekWeightMeasurementResult; + List get weekWeightMeasurementResult => weightService.weekWeightMeasurementResult; - List get yearWeightMeasurementResult => - weightService.yearWeightMeasurementResult; + List get yearWeightMeasurementResult => weightService.yearWeightMeasurementResult; List weightWeekTimeSeriesData = []; List weighMonthTimeSeriesData = []; @@ -34,30 +24,26 @@ class WeightPressureViewModel extends BaseViewModel { await weightService.getWeightAverage(); await weightService.getWeightMeasurementResult(); if (weightService.hasError) { - error = weightService.error; - setState(ViewState.Error); + error = weightService.error!; + setState(ViewState.ErrorLocal); } else { weightService.weekWeightMeasurementResultAverage.forEach((element) { weightWeekTimeSeriesData.add(TimeSeriesSales2( - element.weightDate, + element.weightDate!, element.dailyAverageResult.toDouble(), )); }); - for (int index = 0; - index < weightService.monthWeightMeasurementResultAverage.length; - index++) { + for (int index = 0; index < weightService.monthWeightMeasurementResultAverage.length; index++) { weighMonthTimeSeriesData.add(TimeSeriesSales3( index, - weightService - .monthWeightMeasurementResultAverage[index].weekAverageResult - .toDouble(), + weightService.monthWeightMeasurementResultAverage[index].weekAverageResult.toDouble(), )); } weightService.yearWeightMeasurementResultAverage.forEach((element) { weightYearTimeSeriesData.add(TimeSeriesSales2( - element.date, + element.date!, element.monthAverageResult.toDouble(), )); }); @@ -66,8 +52,7 @@ class WeightPressureViewModel extends BaseViewModel { } } - addWeightResult( - {String weightDate, String weightMeasured, int weightUnit}) async { + addWeightResult({required String weightDate, required String weightMeasured, required int weightUnit}) async { setState(ViewState.BusyLocal); await weightService.addWeightResult( weightDate: weightDate, @@ -75,35 +60,31 @@ class WeightPressureViewModel extends BaseViewModel { weightUnit: weightUnit, ); if (weightService.hasError) { - error = weightService.error; + error = weightService.error!; setState(ViewState.Error); } else { await getWeight(); setState(ViewState.Idle); } } + Future sendReportByEmail() async { setState(ViewState.BusyLocal); await weightService.sendReportByEmail(); if (weightService.hasError) { - error = weightService.error; + error = weightService.error!; setState(ViewState.ErrorLocal); } else { setState(ViewState.Idle); } } - updateWeightResult({int lineItemNo, int weightUnit, String weightMeasured,String weightDate}) async { + updateWeightResult({required int lineItemNo, required int weightUnit, required String weightMeasured, required String weightDate}) async { setState(ViewState.BusyLocal); - await weightService.updateWeightResult( - lineItemNo: lineItemNo, - weightMeasured: weightMeasured, - weightUnit: weightUnit, - weightDate: weightDate - ); + await weightService.updateWeightResult(lineItemNo: lineItemNo, weightMeasured: weightMeasured, weightUnit: weightUnit, weightDate: weightDate); if (weightService.hasError) { - error = weightService.error; + error = weightService.error!; setState(ViewState.Error); } else { await getWeight(); @@ -111,13 +92,15 @@ class WeightPressureViewModel extends BaseViewModel { } } - deleteWeightResult({int lineItemNo, }) async { + deleteWeightResult({ + required int lineItemNo, + }) async { setState(ViewState.BusyLocal); await weightService.deleteWeightResult( lineItemNo: lineItemNo, ); if (weightService.hasError) { - error = weightService.error; + error = weightService.error!; setState(ViewState.Error); } else { await getWeight(); diff --git a/lib/core/viewModels/notifications_view_model.dart b/lib/core/viewModels/notifications_view_model.dart index ac09e3b2..98077560 100644 --- a/lib/core/viewModels/notifications_view_model.dart +++ b/lib/core/viewModels/notifications_view_model.dart @@ -1,40 +1,48 @@ +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/notifications/get_notifications_request_model.dart'; import 'package:diplomaticquarterapp/core/model/notifications/get_notifications_response_model.dart'; import 'package:diplomaticquarterapp/core/model/notifications/mark_message_as_read_request_model.dart'; import 'package:diplomaticquarterapp/core/service/notifications_service.dart'; -import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart'; +import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; import '../../locator.dart'; import 'base_view_model.dart'; class NotificationViewModel extends BaseViewModel { NotificationService _notificationService = locator(); + ToDoCountProviderModel model = Provider.of(AppGlobal.context); - List get notifications => - _notificationService.notificationsList; + List get notifications => _notificationService.notificationsList; - Future getNotifications( - GetNotificationsRequestModel getNotificationsRequestModel, BuildContext context) async { - if(getNotificationsRequestModel.currentPage == 0) - setState(ViewState.Busy); + Future getNotifications(GetNotificationsRequestModel getNotificationsRequestModel, BuildContext context) async { + if (getNotificationsRequestModel.currentPage == 0) setState(ViewState.Busy); - await _notificationService - .getAllNotifications(getNotificationsRequestModel); + await _notificationService.getAllNotifications(getNotificationsRequestModel); if (_notificationService.hasError) { - error = _notificationService.error; - setState(ViewState.Error); + error = _notificationService.error!; + setState(ViewState.Error); } else { - setState(ViewState.Idle); + setState(ViewState.Idle); } } Future markAsRead(id) async { // setState(ViewState.Busy); - MarkMessageAsReadRequestModel markMessageAsReadRequestModel = - new MarkMessageAsReadRequestModel(notificationPoolID: id); + MarkMessageAsReadRequestModel markMessageAsReadRequestModel = new MarkMessageAsReadRequestModel(notificationPoolID: id); + final authService = new AuthProvider(); await _notificationService.markAsRead(markMessageAsReadRequestModel); - setState(ViewState.Idle); + await authService.getDashboard().then((value) { + var notificationCount = ''; + notificationCount = value['List_PatientDashboard'][0]['UnreadPatientNotificationCount'] > 99 ? '99+' : value['List_PatientDashboard'][0]['UnreadPatientNotificationCount'].toString(); + model.setState(model.count, 0, true, notificationCount); + sharedPref.setString(NOTIFICATION_COUNT, notificationCount); + + }); + setState(ViewState.Idle); } -} \ No newline at end of file +} diff --git a/lib/core/viewModels/offers_Categorise_view_model.dart b/lib/core/viewModels/offers_Categorise_view_model.dart index b63dd553..adfca8cd 100644 --- a/lib/core/viewModels/offers_Categorise_view_model.dart +++ b/lib/core/viewModels/offers_Categorise_view_model.dart @@ -22,19 +22,19 @@ class OffersCategoriseViewModel extends BaseViewModel { setState(ViewState.Busy); await _offersCategoriseService.getOffersCategorise(); if (_offersCategoriseService.hasError) { - error = _offersCategoriseService.error; + error = _offersCategoriseService.error!; setState(ViewState.ErrorLocal); } else await getOffersProducts(); } - Future getOffersProducts({String i}) async { + Future getOffersProducts({String? i}) async { hasError = false; setState(ViewState.Busy); - await _offersCategoriseService.getOffersProducts(id: i); + await _offersCategoriseService.getOffersProducts(id: i!); if (_offersCategoriseService.hasError) { - error = _offersCategoriseService.error; + error = _offersCategoriseService.error!; setState(ViewState.ErrorLocal); } else setState(ViewState.Idle); diff --git a/lib/core/viewModels/packages_offers/PackagesOffersViewModel.dart b/lib/core/viewModels/packages_offers/PackagesOffersViewModel.dart index 1029ed4d..64f76b68 100644 --- a/lib/core/viewModels/packages_offers/PackagesOffersViewModel.dart +++ b/lib/core/viewModels/packages_offers/PackagesOffersViewModel.dart @@ -1,13 +1,12 @@ -import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCartItemsResponseModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCategoriesResponseModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart'; -import 'package:diplomaticquarterapp/core/service/base_service.dart'; -import 'package:diplomaticquarterapp/core/service/client/base_app_client.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/tamara_payment_option.dart'; import 'package:diplomaticquarterapp/core/service/packages_offers/PackagesOffersServices.dart'; import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; -import 'package:flutter/cupertino.dart'; import 'package:diplomaticquarterapp/locator.dart'; +import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; class OfferCategoriesViewModel extends BaseViewModel{ OffersAndPackagesServices service = locator(); @@ -18,13 +17,31 @@ 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; List get bestSellerList => service.bestSellerList; List get bannersList => service.bannersList; List get cartItemList => service.cartItemList; + List get hospitals => service.hospitals; + + List get tamara_options => service.tamaraPaymentOptions; + bool allowTamara = true; + setTamaraIllegablity(double amount){ + bool illegible = true; + if(tamara_options == null || tamara_options.isEmpty) + illegible = false; + else{ + tamara_options.forEach((element) { + final ill = (amount >= element.minLimit! && amount <= element.maxLimit!); + element.enable = ill; + illegible = illegible || ill; + }); + } + allowTamara = illegible; + } String _cartItemCount = ""; diff --git a/lib/core/viewModels/pharmacies_view_model.dart b/lib/core/viewModels/pharmacies_view_model.dart index b9e162fc..f6a763b6 100644 --- a/lib/core/viewModels/pharmacies_view_model.dart +++ b/lib/core/viewModels/pharmacies_view_model.dart @@ -1,10 +1,11 @@ -import 'package:diplomaticquarterapp/core/model/pharmacies/pharmacies_list_model.dart'; -import '../../locator.dart'; -import 'base_view_model.dart'; import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/pharmacies_list_model.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/pharmacies_model.dart'; import 'package:diplomaticquarterapp/core/service/pharmacies_service.dart'; +import '../../locator.dart'; +import 'base_view_model.dart'; + class PharmacyViewModel extends BaseViewModel { bool isFinished = true; bool hasError = false; @@ -14,12 +15,12 @@ class PharmacyViewModel extends BaseViewModel { List get pharmacy => _pharmacyService.medicineItem; List get pharmacyList => _pharmacyService.pharmaciesList; - Future getPharmacies({int id}) async { + Future getPharmacies({int? id}) async { setState(ViewState.Busy); - await _pharmacyService.getPharmaciesList(itemID: id); + await _pharmacyService.getPharmaciesList(itemID: id!); if (_pharmacyService.hasError) { - error = _pharmacyService.error; + error = _pharmacyService.error!; setState(ViewState.Error); } else setState(ViewState.Idle); @@ -28,13 +29,13 @@ class PharmacyViewModel extends BaseViewModel { clearMedicineSearch(){ _pharmacyService.clearMedicineList(); } - Future getMedicine({String name}) async { + Future getMedicine({String? name}) async { hasError = false; _pharmacyService.clearMedicineList(); setState(ViewState.BusyLocal); - await _pharmacyService.getMedicineList(drugName: name); + await _pharmacyService.getMedicineList(drugName: name!); if (_pharmacyService.hasError) { - error = _pharmacyService.error; + error = _pharmacyService.error!; setState(ViewState.ErrorLocal); } else setState(ViewState.Idle); diff --git a/lib/core/viewModels/pharmacyModule/BestSellerViewModel.dart b/lib/core/viewModels/pharmacyModule/BestSellerViewModel.dart new file mode 100644 index 00000000..b03ee5b9 --- /dev/null +++ b/lib/core/viewModels/pharmacyModule/BestSellerViewModel.dart @@ -0,0 +1,26 @@ +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; +import 'package:diplomaticquarterapp/core/service/parmacyModule/parmacy_module_service.dart'; +import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; + +import '../../../locator.dart'; + +class BestSellerViewModel extends BaseViewModel { + + PharmacyModuleService _pharmacyService = locator(); + + List get bestSellerProduct => + _pharmacyService.bestSellerProducts; + + getBestSellerProducts() async { + setState(ViewState.BusyLocal); + await _pharmacyService.getBestSellerProducts(); + // if (_pharmacyService.hasError) { + // error = _pharmacyService.error; + // setState(ViewState.Error); + // } else { + setState(ViewState.Idle); + // } + } + +} \ No newline at end of file diff --git a/lib/core/viewModels/pharmacyModule/BrandViewModel.dart b/lib/core/viewModels/pharmacyModule/BrandViewModel.dart new file mode 100644 index 00000000..c1cdc8bc --- /dev/null +++ b/lib/core/viewModels/pharmacyModule/BrandViewModel.dart @@ -0,0 +1,29 @@ +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/Manufacturer.dart'; +import 'package:diplomaticquarterapp/core/service/parmacyModule/parmacy_module_service.dart'; +import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; + +import '../../../locator.dart'; + +class BrandViewModel extends BaseViewModel { + PharmacyModuleService _pharmacyService = locator(); + + List get manufacturerList => _pharmacyService.manufacturerList; + + Future getTopManufacturerList() async { + setState(ViewState.BusyLocal); + await _pharmacyService.getTopManufacturerList(); + // if (_pharmacyService.hasError) { + // error = _pharmacyService.error; + // setState(ViewState.Error); + // } else { + setState(ViewState.Idle); + // } + } + + @override + void dispose() { + + super.dispose(); + } +} diff --git a/lib/core/viewModels/pharmacyModule/LastVisitedViewModel.dart b/lib/core/viewModels/pharmacyModule/LastVisitedViewModel.dart new file mode 100644 index 00000000..568e56f8 --- /dev/null +++ b/lib/core/viewModels/pharmacyModule/LastVisitedViewModel.dart @@ -0,0 +1,25 @@ +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; +import 'package:diplomaticquarterapp/core/service/parmacyModule/parmacy_module_service.dart'; +import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; + +import '../../../locator.dart'; + +class LastVisitedViewModel extends BaseViewModel { + + PharmacyModuleService _pharmacyService = locator(); + + List get lastVisitedProducts => + _pharmacyService.lastVisitedProducts; + + getLastVisitedProducts() async { + setState(ViewState.BusyLocal); + await _pharmacyService.getLastVisitedProducts(); + // if (_pharmacyService.hasError) { + // error = _pharmacyService.error; + // setState(ViewState.Error); + // } else { + setState(ViewState.Idle); + // } + } +} \ No newline at end of file diff --git a/lib/core/viewModels/pharmacyModule/MostViewedViewModel.dart b/lib/core/viewModels/pharmacyModule/MostViewedViewModel.dart new file mode 100644 index 00000000..a0f51038 --- /dev/null +++ b/lib/core/viewModels/pharmacyModule/MostViewedViewModel.dart @@ -0,0 +1,23 @@ +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; +import 'package:diplomaticquarterapp/core/service/parmacyModule/parmacy_module_service.dart'; +import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; +import 'package:diplomaticquarterapp/locator.dart'; + +class MostViewedViewModel extends BaseViewModel { + PharmacyModuleService _pharmacyService = locator(); + + List get mostViewedProducts => + _pharmacyService.mostViewedProducts; + + getMostViewedProducts() async { + setState(ViewState.BusyLocal); + await _pharmacyService.getMostViewedProducts(); + // if (_pharmacyService.hasError) { + // error = _pharmacyService.error; + // setState(ViewState.Error); + // } else { + setState(ViewState.Idle); + // } + } +} diff --git a/lib/core/viewModels/pharmacyModule/OrderPreviewViewModel.dart b/lib/core/viewModels/pharmacyModule/OrderPreviewViewModel.dart index 1fa34ee2..cd8ae4a2 100644 --- a/lib/core/viewModels/pharmacyModule/OrderPreviewViewModel.dart +++ b/lib/core/viewModels/pharmacyModule/OrderPreviewViewModel.dart @@ -1,4 +1,5 @@ -import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'dart:convert'; + import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/Addresses.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/LacumAccountInformation.dart'; @@ -17,68 +18,82 @@ class OrderPreviewViewModel extends BaseViewModel { OrderPreviewService _orderService = locator(); List get addresses => _orderService.addresses; - LacumAccountInformation get lacumInformation => - _orderService.lacumInformation; + + LacumAccountInformation get lacumInformation => _orderService.lacumInformation!; + List get orderListModel => _orderService.orderList; - PharmacyModuleViewModel pharmacyModuleViewModel = - locator(); + PharmacyModuleViewModel pharmacyModuleViewModel = locator(); ShoppingCartResponse cartResponse = ShoppingCartResponse(); PaymentCheckoutData paymentCheckoutData = PaymentCheckoutData(); double totalAdditionalShippingCharge = 0; + setShoppingCartResponse(ShoppingCartResponse cart) { + cartResponse = cart; + notifyListeners(); + } + Future getOrderPreviewData() async { setState(ViewState.Busy); await _orderService.getAddresses(); if (_orderService.hasError) { - error = _orderService.error; + error = _orderService.error!; setState(ViewState.Error); } else { getShoppingCart(); } } + void update() { + notifyListeners(); + } + Future getShoppingCart() async { - setState(ViewState.Busy); + // setState(ViewState.Busy); + // GifLoaderDialogUtils.showMyDialog( + // locator().navigatorKey.currentContext); await _orderService.getShoppingCart().then((res) { - _handleGetShoppingCartResponse(res); + if (res != null) _handleGetShoppingCartResponse(res); }); if (_orderService.hasError) { - error = _orderService.error; - setState(ViewState.Error); + error = _orderService.error!; + // setState(ViewState.Error); } else { if (paymentCheckoutData != null) { paymentCheckoutData.cartDataVisible = true; } + // GifLoaderDialogUtils.hideDialog( + // locator().navigatorKey.currentContext); setState(ViewState.Idle); } } - Future changeProductQuantity(ShoppingCart product) async { - setState(ViewState.Busy); - await _orderService.changeProductQuantity(product.id, product).then((res) { - _handleGetShoppingCartResponse(res); - }); + Future changeProductQuantity(ShoppingCart product) async { + setState(ViewState.BusyLocal); + var resp = await _orderService.changeProductQuantity(product.id!, product); + if (_orderService.hasError) { - error = _orderService.error; + error = _orderService.error!; setState(ViewState.ErrorLocal); } else { + var object = _handleGetShoppingCartResponse(resp); setState(ViewState.Idle); } + // return object; } - Future deleteProduct(ShoppingCart product) async { - setState(ViewState.Busy); - await _orderService.deleteProduct(product.id).then((res) { - _handleGetShoppingCartResponse(res); - }); + Future deleteProduct(ShoppingCart product) async { + setState(ViewState.BusyLocal); + var resp = await _orderService.deleteProduct(product.id!); + var object = _handleGetShoppingCartResponse(resp); if (_orderService.hasError) { - error = _orderService.error; - setState(ViewState.Error); + error = _orderService.error!; + setState(ViewState.ErrorLocal); } else { setState(ViewState.Idle); } + return object; } Future deleteShoppingCart() async { @@ -87,34 +102,43 @@ class OrderPreviewViewModel extends BaseViewModel { _handleGetShoppingCartResponse(res); }); if (_orderService.hasError) { - error = _orderService.error; + error = _orderService.error!; setState(ViewState.Error); } else { setState(ViewState.Idle); } } - _handleGetShoppingCartResponse(Map res) { + ShoppingCartResponse _handleGetShoppingCartResponse(Map res) { + cartResponse.totalAmount = 0.0; totalAdditionalShippingCharge = 0; - if (res == null) { + if (res.isEmpty) { error = "response is null"; setState(ViewState.Error); - return; + return ShoppingCartResponse(); } - print(res); cartResponse.itemCount = res["item_count"]; cartResponse.quantityCount = res["quantity_count"]; cartResponse.subtotal = res["subtotal"]; cartResponse.subtotalWithVat = res["subtotal_with_vat"]; cartResponse.subtotalVatAmount = res["subtotal_vat_amount"]; cartResponse.subtotalVatRate = res["subtotal_vat_rate"]; - cartResponse.shoppingCarts = List(); + cartResponse.shoppingCarts = []; + + if (paymentCheckoutData.shippingOption != null) { + totalAdditionalShippingCharge = paymentCheckoutData.shippingOption!.rate!; + cartResponse.subtotalVatAmount = (cartResponse.subtotalVatAmount)! + (paymentCheckoutData.shippingOption!.rateVat!); + cartResponse.totalAmount = (cartResponse.totalAmount)! + (paymentCheckoutData.shippingOption!.rate! + paymentCheckoutData.shippingOption!.rateVat!); + // Changed By Aamir += into ()+() + } + res["shopping_carts"].forEach((item) { ShoppingCart shoppingCart = ShoppingCart.fromJson(item); - cartResponse.shoppingCarts.add(shoppingCart); - totalAdditionalShippingCharge += shoppingCart.product.additionalShippingCharge; + cartResponse.shoppingCarts!.add(shoppingCart); + totalAdditionalShippingCharge += shoppingCart.product!.additionalShippingCharge!; }); - cartResponse.updateShoppingCard(); + if (paymentCheckoutData.shippingOption != null) cartResponse.totalAmount = (cartResponse.subtotalWithVat! + totalAdditionalShippingCharge + paymentCheckoutData.shippingOption!.rateVat!); + return cartResponse; } String getPaymentOptionImage(PaymentOption paymentOption) { @@ -135,6 +159,8 @@ class OrderPreviewViewModel extends BaseViewModel { case 4: return "${assetFile}installment.png"; break; + case 5: + return "${assetFile}applePay.png"; default: return ""; } @@ -144,61 +170,72 @@ class OrderPreviewViewModel extends BaseViewModel { return _orderService.getPaymentOptionName(paymentOption); } - getInformationsByAddress() async { - await getLacumAccountInformation(); - await getShippingOption(); + getInformationsByAddress(String identificationNo) async { + await getShippingOption(identificationNo); } - getLacumAccountInformation() async { + getLacumAccountInformation(String identificationNo) async { setState(ViewState.Busy); - await _orderService.getLacumAccountInformation(); + await _orderService.getLacumAccountInformation(identificationNo); if (_orderService.hasError) { - error = _orderService.error; + error = _orderService.error!; setState(ViewState.Error); } else { - getLacumGroupData(); + if (_orderService.lacumInformation!.yahalaAccountNo != 0) getLacumGroupData(identificationNo); } } - Future getLacumGroupData() async { + Future getLacumGroupData(String identificationNo) async { setState(ViewState.Busy); - await _orderService.getLacumGroupInformation(); + await _orderService.getLacumGroupInformation(identificationNo); paymentCheckoutData.lacumInformation = _orderService.lacumGroupInformation; - paymentCheckoutData.usedLakumPoints = paymentCheckoutData.lacumInformation.lakumInquiryInformationObjVersion.pointsBalanceAmount; + paymentCheckoutData.usedLakumPoints = paymentCheckoutData.lacumInformation!.lakumInquiryInformationObjVersion!.pointsBalanceAmount!; if (_orderService.hasError) { - error = _orderService.error; + error = _orderService.error!; setState(ViewState.Error); } else { setState(ViewState.Idle); } } - getShippingOption() async { + Future getShippingOption(String identificationNo) async { setState(ViewState.Busy); - await _orderService.getShippingOption(paymentCheckoutData.address).then((res) { - paymentCheckoutData.shippingOption = ShippingOption.fromJson(res); - paymentCheckoutData.updateData(); + await _orderService.getShippingOption(paymentCheckoutData.address!).then((res) async { + if (_orderService.hasError) { + error = _orderService.error!; + setState(ViewState.Error); + } else { + paymentCheckoutData.shippingOption = ShippingOption.fromJson(res as Map); + //Changed By Aamir Map into Map + setState(ViewState.Idle); + await getLacumAccountInformation(identificationNo); + } }); - if (_orderService.hasError) { - error = _orderService.error; - setState(ViewState.Error); - } else { - setState(ViewState.Idle); - } } - Future makeOrder() async { + Future makeOrder(bool isLakumEnabled) async { setState(ViewState.Busy); await pharmacyModuleViewModel.generatePharmacyToken(); - await _orderService.makeOrder(paymentCheckoutData, cartResponse.shoppingCarts); + await _orderService.makeOrder(paymentCheckoutData, cartResponse.shoppingCarts!, isLakumEnabled); if (_orderService.hasError) { - error = _orderService.error; + error = _orderService.error!; setState(ViewState.ErrorLocal); } else { setState(ViewState.Idle); } } + + bool isCartItemsOutOfStock() { + bool outOfStock = false; + for (int i = 0; i < cartResponse.shoppingCarts!.length; i++) { + if (cartResponse.shoppingCarts![i].product!.stockQuantity! == 0) { + outOfStock = true; + break; + } + } + return outOfStock; + } } -enum PaymentOption { meda, sadad, visa, mastercard, installments } +enum PaymentOption { meda, sadad, visa, mastercard, installments, applepay } diff --git a/lib/core/viewModels/pharmacyModule/PharmacyAddressesViewModel.dart b/lib/core/viewModels/pharmacyModule/PharmacyAddressesViewModel.dart index 485c92fb..d920f1e3 100644 --- a/lib/core/viewModels/pharmacyModule/PharmacyAddressesViewModel.dart +++ b/lib/core/viewModels/pharmacyModule/PharmacyAddressesViewModel.dart @@ -1,23 +1,23 @@ import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; -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/core/model/pharmacies/PharmacyAddressesModel.dart'; -import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; -import 'package:google_maps_place_picker/google_maps_place_picker.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:geocoding/geocoding.dart'; +import 'package:google_maps_place_picker_mb/google_maps_place_picker.dart'; + import '../../../locator.dart'; import '../base_view_model.dart'; class PharmacyAddressesViewModel extends BaseViewModel { - PharmacyAddressService _pharmacyAddressService = - locator(); + PharmacyAddressService _pharmacyAddressService = locator(); - List get addresses => _pharmacyAddressService.addresses; + List get addresses => _pharmacyAddressService.addresses; int get selectedAddressIndex => _pharmacyAddressService.selectedAddressIndex; - CountryData get country => _pharmacyAddressService.country; + CountryData get country => _pharmacyAddressService.country!; setSelectedAddressIndex(int index) { _pharmacyAddressService.selectedAddressIndex = index; @@ -27,91 +27,92 @@ class PharmacyAddressesViewModel extends BaseViewModel { setState(ViewState.Busy); await _pharmacyAddressService.getAddresses(); if (_pharmacyAddressService.hasError) { - error = _pharmacyAddressService.error; + error = _pharmacyAddressService.error!; setState(ViewState.Error); } else { setState(ViewState.Idle); } } -/* Future getCountries(String countryName) async { - setState(ViewState.Busy); - await _pharmacyAddressService.getCountries(countryName); - if (_pharmacyAddressService.hasError) { - error = _pharmacyAddressService.error; - // setState(ViewState.Error); - } else { - // setState(ViewState.Idle); - } - }*/ - - Future addEditAddress(PickResult value, Addresses editedAddress) async { + // Future addEditAddress(PickResult value, AddressInfo editedAddress) async { + Future addEditAddress(Placemark selectedPlace, AddressInfo editedAddress, {String? latLong}) async { setState(ViewState.Busy); - Addresses sendingAddress; + AddressInfo sendingAddress; if (editedAddress == null) { - sendingAddress = Addresses(); + sendingAddress = AddressInfo(); sendingAddress.id = "0"; - sendingAddress.firstName = user.firstName; - sendingAddress.lastName = user.lastName; - sendingAddress.email = user.emailAddress; + sendingAddress.firstName = user!.firstName; + sendingAddress.lastName = user!.lastName; + sendingAddress.email = user!.emailAddress; sendingAddress.company = null; } else { sendingAddress = editedAddress; } - value.addressComponents.forEach((element) { - if (element.types.contains("country")) { - sendingAddress.country = element.longName; - } - if (element.types.contains("administrative_area_level_1")) { - sendingAddress.city = element.longName; - } - if (element.types.contains("postal_code")) { - sendingAddress.zipPostalCode = element.longName; - } - if (element.types.contains("administrative_area_level_2")) { - sendingAddress.province = element.longName; - } - }); - sendingAddress.latLong = value.geometry.location.toString(); - - await _pharmacyAddressService.getCountries(sendingAddress.country); + + sendingAddress.country = selectedPlace.country; + sendingAddress.city = selectedPlace.locality; + sendingAddress.zipPostalCode = selectedPlace.postalCode; + sendingAddress.province = selectedPlace.locality; + sendingAddress.latLong = latLong; + + // value.addressComponents.forEach((element) { + // if (element.types.contains("country")) { + // sendingAddress.country = element.longName; + // } + // if (element.types.contains("administrative_area_level_1")) { + // sendingAddress.city = element.longName; + // } + // if (element.types.contains("postal_code")) { + // sendingAddress.zipPostalCode = element.longName; + // } + // if (element.types.contains("administrative_area_level_2")) { + // sendingAddress.province = element.longName; + // } + // }); + // sendingAddress.latLong = value.geometry.location.toString(); + + await _pharmacyAddressService.getCountries(sendingAddress.country!); sendingAddress.countryId = country.id; sendingAddress.stateProvinceId = null; - sendingAddress.address1 = value.formattedAddress; - sendingAddress.address2 = ""; - sendingAddress.phoneNumber = user.mobileNumber; - sendingAddress.faxNumber = user.faxNumber; + sendingAddress.address1 = selectedPlace.name; + sendingAddress.address2 = selectedPlace.street; + sendingAddress.phoneNumber = user!.mobileNumber; + sendingAddress.faxNumber = user!.faxNumber; sendingAddress.customerAttributes = ""; sendingAddress.createdOnUtc = DateTime.now().toString(); - if (editedAddress == null) { await _pharmacyAddressService.addCustomerAddress(sendingAddress); } else { - await _pharmacyAddressService.editCustomerAddress(sendingAddress); + await _pharmacyAddressService.editCustomerAddress(sendingAddress).then((value) async {}); } if (_pharmacyAddressService.hasError) { - error = _pharmacyAddressService.error; - setState(ViewState.Error); + setState(ViewState.Idle); + await Future.delayed(Duration(milliseconds: 800)); + getAddressesList(); } else { setState(ViewState.Idle); + await Future.delayed(Duration(milliseconds: 800)); + getAddressesList(); } } - Future deleteAddresses(Addresses sendingAddress) async { + Future deleteAddresses(AddressInfo address) async { setState(ViewState.Busy); - await _pharmacyAddressService.deleteCustomerAddress(sendingAddress); + await _pharmacyAddressService.deleteCustomerAddress(address); if (_pharmacyAddressService.hasError) { - error = _pharmacyAddressService.error; + error = _pharmacyAddressService.error!; setState(ViewState.Error); } else { setState(ViewState.Idle); + await Future.delayed(Duration(milliseconds: 800)); + getAddressesList(); } } - Future saveSelectedAddressLocally(Addresses selectedAddress) async { + Future saveSelectedAddressLocally(AddressInfo selectedAddress) async { await sharedPref.setObject(PHARMACY_SELECTED_ADDRESS, selectedAddress); } } diff --git a/lib/core/viewModels/pharmacyModule/PrescriptionViewModel.dart b/lib/core/viewModels/pharmacyModule/PrescriptionViewModel.dart new file mode 100644 index 00000000..1d0cda79 --- /dev/null +++ b/lib/core/viewModels/pharmacyModule/PrescriptionViewModel.dart @@ -0,0 +1,29 @@ +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/prescriptions/Prescriptions.dart'; +import 'package:diplomaticquarterapp/core/service/parmacyModule/prescription_service.dart'; +import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; + +import '../../../locator.dart'; + +class PrescriptionViewModel extends BaseViewModel { + + PrescriptionService _prescriptionService = locator(); + + List get prescriptionsList => + _prescriptionService.prescriptionsList; + + getPrescription() async { + await getSavedLanguage(); + prescriptionsList.clear(); + if(prescriptionsList.isEmpty){ + setState(ViewState.Busy); + await _prescriptionService.getPrescription(); + if (_prescriptionService.hasError) { + error = _prescriptionService.error!; + setState(ViewState.Error); + } else { + setState(ViewState.Idle); + } + } + } +} \ No newline at end of file diff --git a/lib/core/viewModels/pharmacyModule/brand_view_model.dart b/lib/core/viewModels/pharmacyModule/brand_view_model.dart index c981b2b3..78a08ed8 100644 --- a/lib/core/viewModels/pharmacyModule/brand_view_model.dart +++ b/lib/core/viewModels/pharmacyModule/brand_view_model.dart @@ -1,3 +1,4 @@ +import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; import 'package:diplomaticquarterapp/models/pharmacy/brandModel.dart'; @@ -23,9 +24,10 @@ class BrandsViewModel extends BaseViewModel{ Future getBrandsData() async { hasError = false; setState(ViewState.Busy); + await _brandsService.getBrands(); if (_brandsService.hasError) { - error = _brandsService.error; + error = _brandsService.error!; setState(ViewState.ErrorLocal); } else setState(ViewState.Idle); @@ -36,20 +38,20 @@ class BrandsViewModel extends BaseViewModel{ setState(ViewState.Busy); await _topBrandsService.getTopBrands(); if (_topBrandsService.hasError) { - error = _topBrandsService.error; + error = _topBrandsService.error!; setState(ViewState.ErrorLocal); } else setState(ViewState.Idle); } - Future searchProducts({String productName}) async { + Future searchProducts({required String productName}) async { hasError = false; _brandsService.clearSearchList(); setState(ViewState.Busy); await _brandsService.searchProducts(productName: productName); if (_brandsService.hasError) { - error = _brandsService.error; + error = _brandsService.error!; setState(ViewState.ErrorLocal); } else setState(ViewState.Idle); diff --git a/lib/core/viewModels/pharmacyModule/lacum-registration-viewModel.dart b/lib/core/viewModels/pharmacyModule/lacum-registration-viewModel.dart index f2ed5913..d115845b 100644 --- a/lib/core/viewModels/pharmacyModule/lacum-registration-viewModel.dart +++ b/lib/core/viewModels/pharmacyModule/lacum-registration-viewModel.dart @@ -1,8 +1,6 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; -import 'package:diplomaticquarterapp/core/model/pharmacies/LacumAccountInformation.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/ListUserAgreement.dart'; import 'package:diplomaticquarterapp/core/service/parmacyModule/lacum-registration-service.dart'; -import 'package:diplomaticquarterapp/core/service/parmacyModule/lacum-transfer-service.dart'; import '../../../locator.dart'; import 'lacum-viewmodel.dart'; @@ -10,18 +8,18 @@ import 'lacum-viewmodel.dart'; class LacumRegistrationViewModel extends LacumViewModel { LacumRegistrationService _lacumService = locator(); - ListUserAgreement get listUserAgreement => _lacumService.listUserAgreement; + ListUserAgreement get listUserAgreement => _lacumService.listUserAgreement!; Future checkLacumAccountActivation(String patientIdentificationNo) async { setState(ViewState.Busy); await _lacumService.getLacumAccountInformationById(patientIdentificationNo); if (_lacumService.hasError) { - error = _lacumService.error; + error = _lacumService.error!; setState(ViewState.Error); } else { - if(_lacumService.lacumInformation != null){ - if(_lacumService.lacumInformation.yahalaAccountNo == 0){ - error = _lacumService.lacumInformation.errorEndUserMessage; + if (_lacumService.lacumInformation != null) { + if (_lacumService.lacumInformation!.yahalaAccountNo == 0) { + error = _lacumService.lacumInformation!.errorEndUserMessage!; setState(ViewState.Error); } else { setState(ViewState.Idle); @@ -34,7 +32,7 @@ class LacumRegistrationViewModel extends LacumViewModel { setState(ViewState.Busy); await _lacumService.getUserTermsAndConditionsForEPharmcy(); if (_lacumService.hasError) { - error = _lacumService.error; + error = _lacumService.error!; setState(ViewState.Error); } else { setState(ViewState.Idle); @@ -45,7 +43,7 @@ class LacumRegistrationViewModel extends LacumViewModel { setState(ViewState.Busy); await _lacumService.createLakumAccount(name, phone, 0, identificationNo, languageId); if (_lacumService.hasError) { - error = _lacumService.error; + error = _lacumService.error!; setState(ViewState.Error); return 404; } else { @@ -53,5 +51,4 @@ class LacumRegistrationViewModel extends LacumViewModel { return 200; } } - } diff --git a/lib/core/viewModels/pharmacyModule/lacum-trasnfer-viewModel.dart b/lib/core/viewModels/pharmacyModule/lacum-trasnfer-viewModel.dart index cd19a40f..84f7910b 100644 --- a/lib/core/viewModels/pharmacyModule/lacum-trasnfer-viewModel.dart +++ b/lib/core/viewModels/pharmacyModule/lacum-trasnfer-viewModel.dart @@ -8,14 +8,14 @@ import 'lacum-viewmodel.dart'; class LacumTranferViewModel extends LacumViewModel { LacumTransferService _lacumService = locator(); - LacumAccountInformation get lacumReceiverInformation => + LacumAccountInformation? get lacumReceiverInformation => _lacumService.lacumReceiverInformation; Future getLacumGroupDataBuAccountId(String accountId) async { setState(ViewState.Busy); await _lacumService.getLacumGroupDataBuAccountId(accountId); if (_lacumService.hasError) { - error = _lacumService.error; + error = _lacumService.error!; setState(ViewState.Error); } else { setState(ViewState.Idle); @@ -26,7 +26,7 @@ class LacumTranferViewModel extends LacumViewModel { setState(ViewState.Busy); await _lacumService.transferYaHalaLoyaltyPoints(points); if (_lacumService.hasError) { - error = _lacumService.error; + error = _lacumService.error!; setState(ViewState.Error); return 404; } else { diff --git a/lib/core/viewModels/pharmacyModule/lacum-viewmodel.dart b/lib/core/viewModels/pharmacyModule/lacum-viewmodel.dart index 1ee1a41c..aa6f28aa 100644 --- a/lib/core/viewModels/pharmacyModule/lacum-viewmodel.dart +++ b/lib/core/viewModels/pharmacyModule/lacum-viewmodel.dart @@ -1,11 +1,11 @@ +import 'dart:async'; +import 'dart:convert'; import 'dart:typed_data'; import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/LacumAccountInformation.dart'; import 'package:diplomaticquarterapp/core/service/parmacyModule/lacum-service.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; -import 'dart:async'; -import 'dart:convert' as convert; import '../../../locator.dart'; import '../base_view_model.dart'; @@ -13,71 +13,68 @@ import '../base_view_model.dart'; class LacumViewModel extends BaseViewModel { LacumService _lacumService = locator(); - LacumAccountInformation get lacumInformation => - _lacumService.lacumInformation; + LacumAccountInformation? get lacumInformation => _lacumService.lacumInformation; - LacumAccountInformation get lacumGroupInformation => - _lacumService.lacumGroupInformation; + LacumAccountInformation? get lacumGroupInformation => _lacumService.lacumGroupInformation; - String get successMsg => - _lacumService.successMsg; + String get successMsg => _lacumService.successMsg; - Future getLacumData() async { - await getLacumAccountData(); - getLacumGroupData(); + Future getLacumData(String identificationNo) async { + await getLacumAccountData(identificationNo); + getLacumGroupData(identificationNo); } - Future getLacumAccountData() async { + Future getLacumAccountData(String identificationNo) async { setState(ViewState.Busy); - await _lacumService.getLacumAccountInformation(); + await _lacumService.getLacumAccountInformation(identificationNo); if (_lacumService.hasError) { - error = _lacumService.error; + error = _lacumService.error!; setState(ViewState.Error); } else { setState(ViewState.Idle); } } - Future getLacumGroupData() async { + Future getLacumGroupData(String identificationNo) async { setState(ViewState.Busy); - await _lacumService.getLacumGroupInformation(); + await _lacumService.getLacumGroupInformation(identificationNo); if (_lacumService.hasError) { - error = _lacumService.error; + error = _lacumService.error!; setState(ViewState.Error); } else { setState(ViewState.Idle); } } - Future makeAccountActivate() async { + Future makeAccountActivate(String identificationNo) async { setState(ViewState.Busy); await _lacumService.makeAccountActivate(); if (_lacumService.hasError) { - error = _lacumService.error; + error = _lacumService.error!; setState(ViewState.Error); } else { - lacumGroupInformation.lakumInquiryInformationObjVersion.accountStatus = "Active"; - getLacumAccountData(); + lacumGroupInformation?.lakumInquiryInformationObjVersion?.accountStatus = "Active"; + getLacumAccountData(identificationNo); } } - Future makeAccountDeactivate() async { + Future makeAccountDeactivate(String identificationNo) async { setState(ViewState.Busy); await _lacumService.makeAccountDeactivate(); if (_lacumService.hasError) { - error = _lacumService.error; + error = _lacumService.error!; setState(ViewState.Error); } else { - lacumGroupInformation.lakumInquiryInformationObjVersion.accountStatus = "Cancelled"; - getLacumAccountData(); + lacumGroupInformation!.lakumInquiryInformationObjVersion!.accountStatus = "Cancelled"; + getLacumAccountData(identificationNo); } } Future createLakumAccount(String name, String phone) async { setState(ViewState.BusyLocal); - await _lacumService.createLakumAccount(name, phone, lacumInformation.yahalaAccountNo, lacumInformation.identificationNo, null); + await _lacumService.createLakumAccount(name, phone, lacumInformation!.yahalaAccountNo!, lacumInformation!.identificationNo!, null); if (_lacumService.hasError) { - error = _lacumService.error; + error = _lacumService.error!; setState(ViewState.ErrorLocal); } else { setState(ViewState.Idle); @@ -85,28 +82,26 @@ class LacumViewModel extends BaseViewModel { } String formatCreatedDateToString() { - DateTime createdDate = DateUtil.convertStringToDate( - lacumGroupInformation.lakumInquiryInformationObjVersion.createdDate); + DateTime createdDate = DateUtil.convertStringToDate(lacumGroupInformation!.lakumInquiryInformationObjVersion!.createdDate!); return DateUtil.getFormattedDate(createdDate, "MMM dd,yyyy"); } Uint8List convertBase64ToBarCodeImage() { try { - final _byteImage = convert.base64Decode( - lacumGroupInformation.lakumInquiryInformationObjVersion.barCode); + final _byteImage = base64Decode(lacumGroupInformation!.lakumInquiryInformationObjVersion!.barCode!.split(',').last); return _byteImage; } catch (e) { print(e); - return null; + return Uint8List(0); } } - setLakumData(LacumAccountInformation lacumInformation, LacumAccountInformation lacumGroupInformation){ + setLakumData(LacumAccountInformation lacumInformation, LacumAccountInformation lacumGroupInformation) { _lacumService.lacumInformation = lacumInformation; _lacumService.lacumGroupInformation = lacumGroupInformation; } - clearLakumGroupData(){ + clearLakumGroupData() { _lacumService.lacumGroupInformation = null; } } diff --git a/lib/core/viewModels/pharmacyModule/order_model_view_model.dart b/lib/core/viewModels/pharmacyModule/order_model_view_model.dart index 5b1c67f2..12d79b22 100644 --- a/lib/core/viewModels/pharmacyModule/order_model_view_model.dart +++ b/lib/core/viewModels/pharmacyModule/order_model_view_model.dart @@ -1,17 +1,19 @@ +import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/Addresses.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/LacumAccountInformation.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/ShoppingCartResponse.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/order_detail.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/orders_model.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/payment-checkout-data.dart'; import 'package:diplomaticquarterapp/core/service/parmacyModule/order-preview-service.dart'; import 'package:diplomaticquarterapp/services/pharmacy_services/cancelOrder_service.dart'; import 'package:diplomaticquarterapp/services/pharmacy_services/orderDetails_service.dart'; import 'package:diplomaticquarterapp/services/pharmacy_services/order_service.dart'; -import 'package:diplomaticquarterapp/core/model/pharmacies/order_model.dart'; -import 'package:diplomaticquarterapp/core/model/pharmacies/orders_model.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; + import '../../../locator.dart'; import '../base_view_model.dart'; @@ -29,19 +31,18 @@ class OrderModelViewModel extends BaseViewModel { OrderPreviewService _orderServices = locator(); List get addresses => _orderServices.addresses; LacumAccountInformation get lacumInformation => - _orderServices.lacumInformation; + _orderServices.lacumInformation!; ShoppingCartResponse cartResponse = ShoppingCartResponse(); PaymentCheckoutData paymentCheckoutData = PaymentCheckoutData(); double totalAdditionalShippingCharge = 0; - Future getOrder(customerId, pageID) async { - print("this is customer id" + customerId); + Future getOrder(customerId, customerGUID, pageID) async { setState(ViewState.Busy); - await _orderService.getOrder(customerId, pageID); + await _orderService.getOrder(customerId, customerGUID, pageID); if (_orderService.hasError) { - error = _orderService.error; + error = _orderService.error!; setState(ViewState.Error); } else { //order = _orderService.orderList; @@ -49,11 +50,11 @@ class OrderModelViewModel extends BaseViewModel { } } - Future getOrderDetails(OrderId) async { + Future getOrderDetails(OrderId, orderGUID) async { setState(ViewState.Busy); - await _orderDetailsService.getOrderDetails(OrderId); + await _orderDetailsService.getOrderDetails(OrderId, orderGUID); if (_orderDetailsService.hasError) { - error = _orderDetailsService.error; + error = _orderDetailsService.error!; setState(ViewState.Error); } else { setState(ViewState.Idle); @@ -65,7 +66,7 @@ class OrderModelViewModel extends BaseViewModel { setState(ViewState.Busy); // await _orderService.getProductReview(); if (_orderService.hasError) { - error = _orderService.error; + error = _orderService.error!; setState(ViewState.Error); } else { //order = _orderService.orderList; @@ -74,17 +75,16 @@ class OrderModelViewModel extends BaseViewModel { } Future getCanceledOrder(order, context) async { - print("this is order id" + order); setState(ViewState.Busy); dynamic res; await _cancelOrderService.getCanceledOrder(order).then((value) { res = value['success']['SuccessEndUserMsg']; - print(value['success']['SuccessEndUserMsg']); - AppToast.showSuccessToast(message: "Request Sent Successfully"); + // AppToast.showSuccessToast(message: "Request Sent Successfully"); + AppToast.showSuccessToast(message: TranslationBase.of(context).requestSent); // Navigator.pop(context); }); if (_cancelOrderService.hasError) { - error = _cancelOrderService.error; + error = _cancelOrderService.error!; setState(ViewState.Error); AppToast.showErrorToast(message: error); } else { @@ -102,13 +102,14 @@ class OrderModelViewModel extends BaseViewModel { setState(ViewState.Busy); await _orderDetailsService.makeReview(product, rating, reviewText); if (_orderDetailsService.hasError) { - error = _orderDetailsService.error; + error = _orderDetailsService.error!; setState(ViewState.Error); AppToast.showErrorToast(message: error); } else { setState(ViewState.Idle); - AppToast.showSuccessToast( - message: "Your review has been Submitted successfully"); + AppToast.showSuccessToast(message: TranslationBase.of(AppGlobal.context).submitReview); + // AppToast.showSuccessToast( + // message: "Your review has been Submitted successfully"); } } diff --git a/lib/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart b/lib/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart index 833735bb..de50b1bc 100644 --- a/lib/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart +++ b/lib/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart @@ -1,84 +1,59 @@ 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'; import '../../../locator.dart'; class PharmacyModuleViewModel extends BaseViewModel { PharmacyModuleService _pharmacyService = locator(); - PrescriptionService _prescriptionService = locator(); - - RecommendedProductService _recommendedProductService = locator(); List get bannerList => _pharmacyService.bannerItems; - List get manufacturerList => _pharmacyService.manufacturerList; - - List get bestSellerProduct => - _pharmacyService.bestSellerProducts; - - List get lastVisitedProducts => - _pharmacyService.lastVisitedProducts; - - - List get recommendedProductList => - _recommendedProductService.recommendedList; - - List get prescriptionsList => - _prescriptionService.prescriptionsList; - - bool hasError = false; -// List get pharmacyPrescriptionsList => PharmacyProduct.pharmacyPrescriptionsList ; + List get recommendedProductList => _recommendedProductService.recommendedList; - Future getPharmacyHomeData() async { - if(authenticatedUserObject.isLogin) - await generatePharmacyToken(); + Future generatePharmacyToken() async { + setState(ViewState.Busy); + await _pharmacyService.generatePharmacyToken(); + if (_pharmacyService.hasError) { + error = _pharmacyService.error!; + setState(ViewState.ErrorLocal); + } else { + setState(ViewState.Idle); + } + } + Future verifyCustomer() async { var data = await sharedPref.getObject(USER_PROFILE); var customerId = await sharedPref.getString(PHARMACY_CUSTOMER_ID); setState(ViewState.Busy); if (authenticatedUserObject.isLogin && data != null && customerId == null) { await _pharmacyService.makeVerifyCustomer(data); - if (_pharmacyService.hasError) { - error = _pharmacyService.error; - setState(ViewState.Error); - } else { - await getBannerList(); - } - } else { - await getBannerList(); } - } - - Future createUser() async { - setState(ViewState.Busy); - await _pharmacyService.createUser(); if (_pharmacyService.hasError) { - error = _pharmacyService.error; + error = _pharmacyService.error!; setState(ViewState.ErrorLocal); } else { setState(ViewState.Idle); } } - Future generatePharmacyToken() async { + + Future createUser() async { setState(ViewState.Busy); - await _pharmacyService.generatePharmacyToken(); + await _pharmacyService.createUser(); if (_pharmacyService.hasError) { - error = _pharmacyService.error; + error = _pharmacyService.error!; setState(ViewState.ErrorLocal); } else { setState(ViewState.Idle); @@ -86,64 +61,39 @@ class PharmacyModuleViewModel extends BaseViewModel { } Future getBannerList() async { - setState(ViewState.Busy); - await _pharmacyService.getBannerListList(); - if (_pharmacyService.hasError) { - error = _pharmacyService.error; - setState(ViewState.Error); - } else { - _getTopManufacturerList(); + if (bannerList.isEmpty) { + GifLoaderDialogUtils.showMyDialog(locator().navigatorKey.currentContext!); + await _pharmacyService.getBannerListList(); + GifLoaderDialogUtils.hideDialog(locator().navigatorKey.currentContext!); + if (_pharmacyService.hasError) { + error = _pharmacyService.error!; + setState(ViewState.Error); + } else + setState(ViewState.Idle); } } - List getBannerImagesUrl() { - List images = List(); + List getBannerImagesUrl(ProjectViewModel projectViewModel) { + List images =[]; 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); + images.add(element.src!); }); return images; } - _getTopManufacturerList() async { - await _pharmacyService.getTopManufacturerList(); - if (_pharmacyService.hasError) { - error = _pharmacyService.error; - setState(ViewState.Error); - } else { - setState(ViewState.Idle); - _getBestSellerProducts(); - } - } - - _getBestSellerProducts() async { - await _pharmacyService.getBestSellerProducts(); - if (_pharmacyService.hasError) { - error = _pharmacyService.error; - setState(ViewState.Error); - } else { - _getLastVisitedProducts(); - } - } - - _getLastVisitedProducts() async { - await _pharmacyService.getLastVisitedProducts(); - if (_pharmacyService.hasError) { - error = _pharmacyService.error; - setState(ViewState.Error); - } else { - setState(ViewState.Idle); - } - } - - /////////////RecommendedProducts - getRecommendedProducts(productId) async { - hasError = false; - setState(ViewState.Busy); + getRecommendedProducts(productId) async { + setState(ViewState.Busy); await _recommendedProductService.getRecommendedProducts(productId); if (_recommendedProductService.hasError) { - error = _recommendedProductService.error; + error = _recommendedProductService.error!; setState(ViewState.Error); } else { setState(ViewState.Idle); @@ -163,32 +113,4 @@ class PharmacyModuleViewModel extends BaseViewModel { return false; } } - - getPrescription() async { - print("Print PRESCRIPTION url"); - setState(ViewState.Busy); - await _prescriptionService.getPrescription(); - if (_prescriptionService.hasError) { - error = _prescriptionService.error; - setState(ViewState.Error); - } else { - setState(ViewState.Idle); - } - } - - - ///////////////////////or -// getPrescriptions() async { -// setState(ViewState.Busy); -// await _prescriptionsService.getPrescriptions(); -// if (_prescriptionsService.hasError) { -// error = _prescriptionsService.error; -// setState(ViewState.Error); -// } else { -// _filterList(); -// await _getPrescriptionsOrders(); -// setState(ViewState.Idle); -// } -// } - } diff --git a/lib/core/viewModels/pharmacyModule/product_detail_view_model.dart b/lib/core/viewModels/pharmacyModule/product_detail_view_model.dart index c7ac0a04..de48afd5 100644 --- a/lib/core/viewModels/pharmacyModule/product_detail_view_model.dart +++ b/lib/core/viewModels/pharmacyModule/product_detail_view_model.dart @@ -1,15 +1,20 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/ShoppingCart.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/ShoppingCartResponse.dart'; import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/OrderPreviewViewModel.dart'; import 'package:diplomaticquarterapp/models/pharmacy/Wishlist.dart'; import 'package:diplomaticquarterapp/models/pharmacy/locationModel.dart'; import 'package:diplomaticquarterapp/models/pharmacy/productDetailModel.dart'; -import 'package:diplomaticquarterapp/services/pharmacy_services/product_detail_service.dart'; import 'package:diplomaticquarterapp/models/pharmacy/specification.dart'; - +import 'package:diplomaticquarterapp/services/pharmacy_services/product_detail_service.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/navigation_service.dart'; +import 'package:provider/provider.dart'; import '../../../locator.dart'; -class ProductDetailViewModel extends BaseViewModel{ +class ProductDetailViewModel extends BaseViewModel { ProductDetailService _productDetailService = locator(); List get productDetailService => _productDetailService.productDetailList; @@ -22,24 +27,31 @@ class ProductDetailViewModel extends BaseViewModel{ bool hasError = false; + num get stockQuantity => _productDetailService.stockQuantity!; + + String get stockAvailability => _productDetailService.stockAvailability!; + + String get stockAvailabilityn => _productDetailService.stockAvailabilityn!; + + bool get isStockAvailable => _productDetailService.isStockAvailable!; Future getProductReviewsData(productID) async { hasError = false; setState(ViewState.Busy); await _productDetailService.getProductReviews(productID); if (_productDetailService.hasError) { - error = _productDetailService.error; + error = _productDetailService.error!; setState(ViewState.ErrorLocal); } else setState(ViewState.Idle); } - Future getProductLocationData() async { + Future getProductLocationData(String productSKU) async { hasError = false; - setState(ViewState.Busy); - await _productDetailService.getProductAvailabiltyDetail(); + setState(ViewState.BusyLocal); + await _productDetailService.getProductAvailabiltyDetail(productSKU); if (_productDetailService.hasError) { - error = _productDetailService.error; + error = _productDetailService.error!; setState(ViewState.ErrorLocal); } else setState(ViewState.Idle); @@ -47,32 +59,61 @@ class ProductDetailViewModel extends BaseViewModel{ Future notifyMe(customerId, itemID) async { hasError = false; - setState(ViewState.Busy); + setState(ViewState.BusyLocal); await _productDetailService.notifyMe(customerId, itemID); if (_productDetailService.hasError) { - error = _productDetailService.error; + error = _productDetailService.error!; setState(ViewState.ErrorLocal); } else setState(ViewState.Idle); } - Future addToCartData(quantity, itemID) async { + Future addToCartData(quantity, itemID, context) async { hasError = false; - setState(ViewState.Busy); - await _productDetailService.addToCart(quantity, itemID); + setState(ViewState.BusyLocal); + var resp = await _productDetailService.addToCart(quantity, itemID, context); + ShoppingCartResponse object = _handleGetShoppingCartResponse(resp); if (_productDetailService.hasError) { - error = _productDetailService.error; + error = _productDetailService.error!; setState(ViewState.ErrorLocal); - } else + } else { setState(ViewState.Idle); + Provider.of(locator().navigatorKey.currentContext!, listen: false).setShoppingCartResponse(object); + } } - Future addToWishlistData(itemID) async { + ShoppingCartResponse _handleGetShoppingCartResponse(Map res) { + ShoppingCartResponse cartResponse = ShoppingCartResponse(); + + if (res == null) { + error = "response is null"; + setState(ViewState.Error); + return ShoppingCartResponse(); + } + print(res); + cartResponse.itemCount = res["item_count"]; + cartResponse.quantityCount = res["quantity_count"]; + cartResponse.subtotal = res["subtotal"]; + cartResponse.subtotalWithVat = res["subtotal_with_vat"]; + cartResponse.subtotalVatAmount = res["subtotal_vat_amount"]; + cartResponse.subtotalVatRate = res["subtotal_vat_rate"]; + cartResponse.shoppingCarts =[]; + res["shopping_carts"].forEach((item) { + ShoppingCart shoppingCart = ShoppingCart.fromJson(item); + cartResponse.shoppingCarts!.add(shoppingCart); + }); + return cartResponse; + } + + Future addToWishlistData(itemID, context) async { hasError = false; - setState(ViewState.Busy); - await _productDetailService.addToWishlist(itemID); + setState(ViewState.BusyLocal); + GifLoaderDialogUtils.showMyDialog(locator().navigatorKey.currentContext!); + await _productDetailService.addToWishlist(itemID, context); + GifLoaderDialogUtils.hideDialog(locator().navigatorKey.currentContext!); + if (_productDetailService.hasError) { - error = _productDetailService.error; + error = _productDetailService.error!; setState(ViewState.ErrorLocal); } else setState(ViewState.Idle); @@ -83,34 +124,38 @@ class ProductDetailViewModel extends BaseViewModel{ setState(ViewState.Busy); await _productDetailService.getWishlistItems(); if (_productDetailService.hasError) { - error = _productDetailService.error; + error = _productDetailService.error!; setState(ViewState.ErrorLocal); } else setState(ViewState.Idle); } - - Future deletWishlistData(itemID) async { + Future deleteWishlistData(itemID, context) async { hasError = false; - setState(ViewState.Busy); - await _productDetailService.delteItemFromWishlist(itemID); + setState(ViewState.BusyLocal); + GifLoaderDialogUtils.showMyDialog(locator().navigatorKey.currentContext!); + await _productDetailService.deleteItemFromWishlist(itemID, context); + GifLoaderDialogUtils.hideDialog(locator().navigatorKey.currentContext!); + if (_productDetailService.hasError) { - error = _productDetailService.error; + error = _productDetailService.error!; setState(ViewState.ErrorLocal); } else setState(ViewState.Idle); } - Future productSpecificationData(itemID) async { hasError = false; setState(ViewState.Busy); await _productDetailService.productSpecificationData(itemID); if (_productDetailService.hasError) { - error = _productDetailService.error; + error = _productDetailService.error!; setState(ViewState.ErrorLocal); } else setState(ViewState.Idle); } -} \ No newline at end of file + clearReview() { + productDetailService.clear(); + } +} diff --git a/lib/core/viewModels/pharmacyModule/review_view_model.dart b/lib/core/viewModels/pharmacyModule/review_view_model.dart index 3661820b..00fd73fe 100644 --- a/lib/core/viewModels/pharmacyModule/review_view_model.dart +++ b/lib/core/viewModels/pharmacyModule/review_view_model.dart @@ -18,7 +18,7 @@ class ReviewViewModel extends BaseViewModel{ setState(ViewState.Busy); await _reviewService.getReview(); if (_reviewService.hasError) { - error = _reviewService.error; + error = _reviewService.error!; setState(ViewState.ErrorLocal); } else setState(ViewState.Idle); diff --git a/lib/core/viewModels/pharmacyModule/tems-condition-viewmodel.dart b/lib/core/viewModels/pharmacyModule/tems-condition-viewmodel.dart index 6a5bd476..f8684092 100644 --- a/lib/core/viewModels/pharmacyModule/tems-condition-viewmodel.dart +++ b/lib/core/viewModels/pharmacyModule/tems-condition-viewmodel.dart @@ -1,7 +1,8 @@ +import 'dart:async'; + import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/ListUserAgreement.dart'; import 'package:diplomaticquarterapp/core/service/parmacyModule/terms-condition-service.dart'; -import 'dart:async'; import '../../../locator.dart'; import '../base_view_model.dart'; @@ -9,13 +10,13 @@ import '../base_view_model.dart'; class TermsConditionViewModel extends BaseViewModel { TermsConditionService _termsConditionService = locator(); - ListUserAgreement get listUserAgreement => _termsConditionService.listUserAgreement; + ListUserAgreement get listUserAgreement => _termsConditionService.listUserAgreement!; Future getUserTermsAndConditionsForEPharmcy() async { setState(ViewState.Busy); await _termsConditionService.getUserTermsAndConditionsForEPharmcy(); if (_termsConditionService.hasError) { - error = _termsConditionService.error; + error = _termsConditionService.error!; setState(ViewState.Error); } else { setState(ViewState.Idle); diff --git a/lib/core/viewModels/pharmacyModule/wishlist_view_model.dart b/lib/core/viewModels/pharmacyModule/wishlist_view_model.dart index 788b7f3c..4f26ad79 100644 --- a/lib/core/viewModels/pharmacyModule/wishlist_view_model.dart +++ b/lib/core/viewModels/pharmacyModule/wishlist_view_model.dart @@ -12,23 +12,12 @@ class WishListViewModel extends BaseViewModel{ bool hasError = false; -// Future getWishlistData() async { -// setState(ViewState.Busy); -// await _wishlistService.getWishlist(); -// if (_wishlistService.hasError) { -// error = _wishlistService.error; -// setState(ViewState.Error); -// } else { -// setState(ViewState.Idle); -// } -// } - - Future getWishlistData() async { + Future getWishlistData({isLocalLoader = false}) async { hasError = false; - setState(ViewState.Busy); + setState(isLocalLoader ? ViewState.BusyLocal:ViewState.Busy); await _wishlistService.getWishlist(); if (_wishlistService.hasError) { - error = _wishlistService.error; + error = _wishlistService.error!; setState(ViewState.ErrorLocal); } else setState(ViewState.Idle); diff --git a/lib/core/viewModels/pharmacy_categorise_view_model.dart b/lib/core/viewModels/pharmacy_categorise_view_model.dart index e48329ba..e936ae71 100644 --- a/lib/core/viewModels/pharmacy_categorise_view_model.dart +++ b/lib/core/viewModels/pharmacy_categorise_view_model.dart @@ -1,44 +1,40 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; -import 'package:diplomaticquarterapp/core/model/pharmacy/brands_model.dart'; import 'package:diplomaticquarterapp/core/model/pharmacy/categorise_parent_model.dart'; -import 'package:diplomaticquarterapp/core/model/pharmacy/final_products_model.dart'; -import 'package:diplomaticquarterapp/core/model/pharmacy/parent_products_model.dart'; import 'package:diplomaticquarterapp/core/model/pharmacy/pharmacy_categorise.dart'; import 'package:diplomaticquarterapp/core/model/pharmacy/scan_qr_model.dart'; -import 'package:diplomaticquarterapp/core/model/pharmacy/sub_categories_model.dart'; -import 'package:diplomaticquarterapp/core/model/pharmacy/sub_products_model.dart'; -import 'package:diplomaticquarterapp/core/model/search_products_model.dart'; - import 'package:diplomaticquarterapp/core/service/pharmacy_categorise_service.dart'; import 'package:diplomaticquarterapp/locator.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:flutter/cupertino.dart'; import 'base_view_model.dart'; class PharmacyCategoriseViewModel extends BaseViewModel { bool hasError = false; - PharmacyCategoriseService _pharmacyCategoriseService = - locator(); - List get categorise => - _pharmacyCategoriseService.categoriseList; + int firstSubsetIndex = 0; + int inPatientPageSize = 20; + int lastSubsetIndex = 20; + + List filteredInPatientItems = []; + List filteredMyInPatientItems = []; + + PharmacyCategoriseService _pharmacyCategoriseService = locator(); - List get categoriseParent => - _pharmacyCategoriseService.parentCategoriseList; + List get categorise => _pharmacyCategoriseService.categoriseList; - List get parentProducts => - _pharmacyCategoriseService.parentProductsList; + List get categoriseParent => _pharmacyCategoriseService.parentCategoriseList; - List get subCategorise => - _pharmacyCategoriseService.subCategoriseList; + List get parentProducts => _pharmacyCategoriseService.parentProductsList; - List get subProducts => - _pharmacyCategoriseService.subProductsList; + List get subCategorise => _pharmacyCategoriseService.subCategoriseList; - List get finalProducts => - _pharmacyCategoriseService.finalProducts; - List get brandsList => - _pharmacyCategoriseService.brandsList; + List get subProducts => _pharmacyCategoriseService.subProductsList; + + List get finalProducts => _pharmacyCategoriseService.finalProducts; + + List get brandsList => _pharmacyCategoriseService.brandsList; List get searchList => _pharmacyCategoriseService.searchList; @@ -50,31 +46,31 @@ class PharmacyCategoriseViewModel extends BaseViewModel { setState(ViewState.Busy); await _pharmacyCategoriseService.getCategorise(); if (_pharmacyCategoriseService.hasError) { - error = _pharmacyCategoriseService.error; + error = _pharmacyCategoriseService.error!; setState(ViewState.ErrorLocal); } else setState(ViewState.Idle); } - Future getBrands({String id}) async { + Future getBrands({String? id}) async { hasError = false; // _insuranceCardService.clearInsuranceCard(); setState(ViewState.Busy); - await _pharmacyCategoriseService.getBrands(id: id); + await _pharmacyCategoriseService.getBrands(id: id!); if (_pharmacyCategoriseService.hasError) { - error = _pharmacyCategoriseService.error; + error = _pharmacyCategoriseService.error!; setState(ViewState.ErrorLocal); } else setState(ViewState.Idle); } - Future scanQr({String id}) async { + Future scanQr({String? id}) async { hasError = false; // _insuranceCardService.clearInsuranceCard(); setState(ViewState.Busy); - await _pharmacyCategoriseService.scanQr(id: id); + await _pharmacyCategoriseService.scanQr(id: id!); if (_pharmacyCategoriseService.hasError) { - error = _pharmacyCategoriseService.error; + error = _pharmacyCategoriseService.error!; setState(ViewState.ErrorLocal); } else setState(ViewState.Idle); @@ -84,88 +80,106 @@ class PharmacyCategoriseViewModel extends BaseViewModel { _pharmacyCategoriseService.clearSearchList(); } - Future searchProducts({String productName}) async { + Future searchProducts({String? productName}) async { hasError = false; _pharmacyCategoriseService.clearSearchList(); setState(ViewState.Busy); - await _pharmacyCategoriseService.searchProducts(productName: productName); + await _pharmacyCategoriseService.searchProducts(productName: productName!); if (_pharmacyCategoriseService.hasError) { - error = _pharmacyCategoriseService.error; + error = _pharmacyCategoriseService.error!; setState(ViewState.ErrorLocal); } else setState(ViewState.Idle); } - Future getCategoriseParent({String i}) async { + Future getCategoriseParent({String? i, int? pageIndex, bool? isLoading, BuildContext? context}) async { hasError = false; // _insuranceCardService.clearInsuranceCard(); setState(ViewState.Busy); - await _pharmacyCategoriseService.getCategoriseParent(id: i); + // GifLoaderDialogUtils.showMyDialog(context); + await _pharmacyCategoriseService.getCategoriseParent(id: i!); if (_pharmacyCategoriseService.hasError) { - error = _pharmacyCategoriseService.error; + error = _pharmacyCategoriseService.error!; setState(ViewState.ErrorLocal); } else - await getParentProducts(i: i); - await getBrands(id: i); + await getBrands(id: i); + await getParentProducts(i: i, pageIndex: pageIndex, isLoading: isLoading, context: context); + // GifLoaderDialogUtils.showMyDialog(context); } - Future getParentProducts({String i}) async { + Future getParentProducts({String? i, int? pageIndex, bool? isLoading, BuildContext? context}) async { hasError = false; // _insuranceCardService.clearInsuranceCard(); - setState(ViewState.Busy); - await _pharmacyCategoriseService.getParentProducts(id: i); + setState(ViewState.BusyLocal); + GifLoaderDialogUtils.showMyDialog(context!); + await _pharmacyCategoriseService.getParentProducts(id: i, pageNumber: pageIndex, isLoading: isLoading!); if (_pharmacyCategoriseService.hasError) { - error = _pharmacyCategoriseService.error; + error = _pharmacyCategoriseService.error!; setState(ViewState.ErrorLocal); } else setState(ViewState.Idle); + GifLoaderDialogUtils.hideDialog(context); } - Future getSubCategorise({String i}) async { + Future getSubCategorise({String? i, int? pageIndex, bool isLoading = false, BuildContext? context}) async { hasError = false; // _insuranceCardService.clearInsuranceCard(); setState(ViewState.Busy); - await _pharmacyCategoriseService.getSubCategorise(id: i); + await _pharmacyCategoriseService.getSubCategorise( + id: i!, + ); + if (_pharmacyCategoriseService.hasError) { + error = _pharmacyCategoriseService.error!; + setState(ViewState.ErrorLocal); + } else + getSubProducts(i: i, pageIndex: pageIndex, isLoading: isLoading, context: context); + } + + Future getSubProducts({String? i, int? pageIndex, bool isLoading = false, BuildContext? context}) async { + hasError = false; + // _insuranceCardService.clearInsuranceCard(); + setState(ViewState.BusyLocal); + GifLoaderDialogUtils.showMyDialog(context!); + await _pharmacyCategoriseService.getSubProducts(id: i, pageIndex: pageIndex, isLoading: isLoading); if (_pharmacyCategoriseService.hasError) { - error = _pharmacyCategoriseService.error; + error = _pharmacyCategoriseService.error!; setState(ViewState.ErrorLocal); } else - getSubProducts(i: i); + setState(ViewState.Idle); + GifLoaderDialogUtils.hideDialog(context!); } - Future getSubProducts({String i}) async { + Future getFinalProducts({String? i}) async { hasError = false; // _insuranceCardService.clearInsuranceCard(); setState(ViewState.Busy); - await _pharmacyCategoriseService.getSubProducts(id: i); + await _pharmacyCategoriseService.getFinalProducts(id: i!); if (_pharmacyCategoriseService.hasError) { - error = _pharmacyCategoriseService.error; + error = _pharmacyCategoriseService.error!; setState(ViewState.ErrorLocal); } else setState(ViewState.Idle); } - Future getFinalProducts({String i}) async { + Future getFilteredProducts({String? categoryId, String? brandId, String? min, String? max}) async { hasError = false; // _insuranceCardService.clearInsuranceCard(); setState(ViewState.Busy); - await _pharmacyCategoriseService.getFinalProducts(id: i); + await _pharmacyCategoriseService.getFilteredProducts(categoryId: categoryId, brandId: brandId, max: max, min: min); if (_pharmacyCategoriseService.hasError) { - error = _pharmacyCategoriseService.error; + error = _pharmacyCategoriseService.error!; setState(ViewState.ErrorLocal); } else setState(ViewState.Idle); } - Future getFilteredProducts( - {String categoryId, String brandId, String min, String max}) async { + Future getFilteredSubProducts({String? categoryId, String? brandId, String? min, String? max}) async { hasError = false; // _insuranceCardService.clearInsuranceCard(); setState(ViewState.Busy); - await _pharmacyCategoriseService.getFilteredProducts( - categoryId: categoryId, brandId: brandId, max: max, min: min); + await _pharmacyCategoriseService.getFilteredSubProducts(categoryId: categoryId, brandId: brandId, max: max, min: min); if (_pharmacyCategoriseService.hasError) { - error = _pharmacyCategoriseService.error; + error = _pharmacyCategoriseService.error!; setState(ViewState.ErrorLocal); } else setState(ViewState.Idle); @@ -175,7 +189,7 @@ class PharmacyCategoriseViewModel extends BaseViewModel { setState(ViewState.Busy); await _pharmacyCategoriseService.getManufacturerProducts(id); if (_pharmacyCategoriseService.hasError) { - error = _pharmacyCategoriseService.error; + error = _pharmacyCategoriseService.error!; setState(ViewState.Error); } else { setState(ViewState.Idle); @@ -186,7 +200,7 @@ class PharmacyCategoriseViewModel extends BaseViewModel { setState(ViewState.Busy); await _pharmacyCategoriseService.getLastVisitedProducts(); if (_pharmacyCategoriseService.hasError) { - error = _pharmacyCategoriseService.error; + error = _pharmacyCategoriseService.error!; setState(ViewState.Error); } else { setState(ViewState.Idle); @@ -197,7 +211,7 @@ class PharmacyCategoriseViewModel extends BaseViewModel { setState(ViewState.Busy); await _pharmacyCategoriseService.getBestSellerProducts(); if (_pharmacyCategoriseService.hasError) { - error = _pharmacyCategoriseService.error; + error = _pharmacyCategoriseService.error!; setState(ViewState.Error); } else { setState(ViewState.Idle); @@ -208,7 +222,7 @@ class PharmacyCategoriseViewModel extends BaseViewModel { setState(ViewState.Busy); await _pharmacyCategoriseService.getMostViewedProducts(); if (_pharmacyCategoriseService.hasError) { - error = _pharmacyCategoriseService.error; + error = _pharmacyCategoriseService.error!; setState(ViewState.Error); } else { setState(ViewState.Idle); @@ -219,10 +233,26 @@ class PharmacyCategoriseViewModel extends BaseViewModel { setState(ViewState.Busy); await _pharmacyCategoriseService.getNewProducts(); if (_pharmacyCategoriseService.hasError) { - error = _pharmacyCategoriseService.error; + error = _pharmacyCategoriseService.error!; setState(ViewState.Error); } else { setState(ViewState.Idle); } } + + addOnFilteredList() { + if (lastSubsetIndex < parentProducts.length) { + firstSubsetIndex = firstSubsetIndex + (parentProducts.length - lastSubsetIndex < inPatientPageSize - 1 ? parentProducts.length - lastSubsetIndex : inPatientPageSize - 1); + lastSubsetIndex = lastSubsetIndex + (parentProducts.length - lastSubsetIndex < inPatientPageSize - 1 ? parentProducts.length - lastSubsetIndex : inPatientPageSize - 1); + filteredInPatientItems.addAll(parentProducts.sublist(firstSubsetIndex, lastSubsetIndex)); + setState(ViewState.Idle); + } + } + + removeOnFilteredList() { + if (lastSubsetIndex - inPatientPageSize - 1 > 0) { + filteredInPatientItems.removeAt(lastSubsetIndex - inPatientPageSize - 1); + setState(ViewState.Idle); + } + } } diff --git a/lib/core/viewModels/product_categories_view_model.dart b/lib/core/viewModels/product_categories_view_model.dart new file mode 100644 index 00000000..2508f557 --- /dev/null +++ b/lib/core/viewModels/product_categories_view_model.dart @@ -0,0 +1,27 @@ +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacy/pharmacy_categorise.dart'; +import 'package:diplomaticquarterapp/core/service/pharmacy_categorise_service.dart'; +import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; +import 'package:diplomaticquarterapp/locator.dart'; + +class ProductCategoriesViewModel extends BaseViewModel { + bool hasError = false; + + PharmacyCategoriseService _pharmacyCategoriseService = + locator(); + + List get categorise => + _pharmacyCategoriseService.categoriseList; + + Future getCategorise() async { + hasError = false; + // _insuranceCardService.clearInsuranceCard(); + setState(ViewState.Busy); + await _pharmacyCategoriseService.getCategorise(); + if (_pharmacyCategoriseService.hasError) { + error = _pharmacyCategoriseService.error!; + setState(ViewState.ErrorLocal); + } else + setState(ViewState.Idle); + } +} diff --git a/lib/core/viewModels/project_view_model.dart b/lib/core/viewModels/project_view_model.dart index 2bb75305..238ee0f5 100644 --- a/lib/core/viewModels/project_view_model.dart +++ b/lib/core/viewModels/project_view_model.dart @@ -1,17 +1,30 @@ import 'dart:async'; -import 'package:connectivity/connectivity.dart'; +import 'package:connectivity_plus/connectivity_plus.dart'; +import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/model/privilege/HMCProjectListModel.dart'; import 'package:diplomaticquarterapp/core/model/privilege/PrivilegeModel.dart'; -import 'package:diplomaticquarterapp/core/service/privilege_service.dart'; +import 'package:diplomaticquarterapp/core/model/privilege/ProjectDetailListModel.dart'; +import 'package:diplomaticquarterapp/core/model/privilege/VidaPlusProjectListModel.dart'; import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; import 'package:diplomaticquarterapp/locator.dart'; +import 'package:diplomaticquarterapp/models/Appointments/laser_body_parts.dart'; +import 'package:diplomaticquarterapp/models/Authentication/register_info_response.dart'; +import 'package:diplomaticquarterapp/models/InPatientServices/get_admission_info_response_model.dart'; +import 'package:diplomaticquarterapp/models/InPatientServices/get_admission_request_info_response_model.dart'; import 'package:diplomaticquarterapp/uitl/PlatformBridge.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:flutter/cupertino.dart'; -import 'package:flutter_datetime_picker/flutter_datetime_picker.dart'; +import 'package:flutter_datetime_picker_plus/flutter_datetime_picker_plus.dart'; + +import '../../models/Appointments/DoctorListResponse.dart'; + +bool isAppArabic = false; class ProjectViewModel extends BaseViewModel { + GAnalytics get analytics => locator(); + // Platform Bridge PlatformBridge platformBridge() { return PlatformBridge.shared(); @@ -20,13 +33,51 @@ class ProjectViewModel extends BaseViewModel { AppSharedPreferences sharedPref = AppSharedPreferences(); Locale _appLocale = Locale('ar'); String currentLanguage = 'ar'; - bool _isArabic = false; + bool _isArabic = true; bool isInternetConnection = true; bool isLoading = false; bool isError = false; String error = ''; dynamic searchvalue; bool isLogin = false; + bool _isAllAppointmentsLoaded = false; + + bool get isAllAppointmentsLoaded => _isAllAppointmentsLoaded; + bool isPatientAdmitted = false; + bool patientHasAdmissionRequest = false; + int inPatientProjectID = 0; + GetAdmissionInfoResponseModel getAdmissionInfoResponseModel = GetAdmissionInfoResponseModel(); + GetAdmissionRequestInfoResponseModel getAdmissionRequestInfoResponseModel = GetAdmissionRequestInfoResponseModel(); + + bool isIndoorNavigationEnabled = true; + + int waitingAppointmentProjectID = 0; + DoctorList? waitingAppointmentDoctor; + String waitingAppointmentNFCCode = ""; + + setWaitingAppointmentDoctor(DoctorList waitingAppointmentDoctor) { + this.waitingAppointmentDoctor = waitingAppointmentDoctor; + notifyListeners(); + } + + setWaitingAppointmentNFCCode(String waitingAppointmentNFCCode) { + this.waitingAppointmentNFCCode = waitingAppointmentNFCCode; + notifyListeners(); + } + + setWaitingAppointmentProjectID(int projectID) { + this.waitingAppointmentProjectID = projectID; + notifyListeners(); + } + + void setIsAllAppointmentsLoaded(bool value) { + _isAllAppointmentsLoaded = value; + notifyListeners(); + } + + RegisterInfoResponse _registerInfo = RegisterInfoResponse(); + + RegisterInfoResponse get registerInfo => _registerInfo; dynamic get searchValue => searchvalue; @@ -36,52 +87,71 @@ class ProjectViewModel extends BaseViewModel { bool get isArabic => _isArabic; - bool isLoginChild = false; - List privilegeRootUser = List(); - List privilegeChildUser = List(); + List privilegeRootUser = []; + List privilegeChildUser = []; + List _vidaPlusProjectListModel = []; + List _hMCProjectListModel = []; + List _projectDetailListModel = []; + + List get privileges => isLoginChild ? privilegeChildUser : privilegeChildUser; + + List get vidaPlusProjectList => _vidaPlusProjectListModel; + + List get hMCProjectListModel => _hMCProjectListModel; + + List get projectDetailListModel => _projectDetailListModel; + + List selectedBodyPartList = []; + + late StreamSubscription subscription; + + late double _latitude = 0.0; + late double _longitude = 0.0; + + double get latitude => _latitude; - List get privileges => - isLoginChild ? privilegeChildUser : privilegeChildUser; + double get longitude => _longitude; - StreamSubscription subscription; + late int laserSelectionDuration = 0; ProjectViewModel() { - loadSharedPrefLanguage(); - subscription = Connectivity() - .onConnectivityChanged - .listen((ConnectivityResult result) { - switch (result) { - case ConnectivityResult.wifi: + try { + loadSharedPrefLanguage(); + subscription = Connectivity().onConnectivityChanged.listen((ConnectivityResult result) { + if (result == ConnectivityResult.mobile) { isInternetConnection = true; - break; - case ConnectivityResult.mobile: - isInternetConnection = true; - break; - case ConnectivityResult.none: + } else if (result == ConnectivityResult.wifi) { + } else if (result == ConnectivityResult.none) { isInternetConnection = false; - break; - } - notifyListeners(); - }); + } + notifyListeners(); + }); + } catch (e) { + print(e); + } } Future loadSharedPrefLanguage() async { - currentLanguage = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); - _appLocale = Locale(currentLanguage); - _isArabic = currentLanguage == 'ar'; - notifyListeners(); + try { + currentLanguage = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + _appLocale = Locale(currentLanguage); + isAppArabic = _isArabic = currentLanguage == 'ar'; + notifyListeners(); + } catch (e) { + print(e); + } } void changeLanguage(String lan) { if (lan != "en" && currentLanguage != lan) { _appLocale = Locale("ar"); - _isArabic = true; + isAppArabic = _isArabic = true; currentLanguage = 'ar'; sharedPref.setString(APP_LANGUAGE, 'ar'); } else if (lan != "ar" && currentLanguage != lan) { _appLocale = Locale("en"); - _isArabic = false; + isAppArabic = _isArabic = false; currentLanguage = 'en'; sharedPref.setString(APP_LANGUAGE, 'en'); } @@ -89,16 +159,60 @@ class ProjectViewModel extends BaseViewModel { notifyListeners(); } - setPrivilegeModelList( - {List privilege}) { + setIsPatientAdmitted(bool isAdmitted) { + this.isPatientAdmitted = isAdmitted; + notifyListeners(); + } + + setIsIndoorNavigationEnabled(bool isEnabled) { + this.isIndoorNavigationEnabled = isEnabled; + notifyListeners(); + } + + setPatientHasAdmissionRequest(bool hasAdmissionRequest) { + this.patientHasAdmissionRequest = hasAdmissionRequest; + notifyListeners(); + } + + setInPatientProjectID(int projectID) { + this.inPatientProjectID = projectID; + notifyListeners(); + } + + setInPatientAdmissionInfo(GetAdmissionInfoResponseModel _getAdmissionInfoResponseModel) { + this.getAdmissionInfoResponseModel = _getAdmissionInfoResponseModel; + notifyListeners(); + } + + setInPatientAdmissionRequest(GetAdmissionRequestInfoResponseModel _getAdmissionRequestInfoResponseModel) { + this.getAdmissionRequestInfoResponseModel = _getAdmissionRequestInfoResponseModel; + notifyListeners(); + } + + setPrivilegeModelList({List? privilege}) { this.isLoginChild = isLoginChild; - privilegeRootUser = privilege; + privilegeRootUser = privilege!; notifyListeners(); } + setVidaPlusProjectList(List vidaPlusProjectListModelInput) { + _vidaPlusProjectListModel = vidaPlusProjectListModelInput; + notifyListeners(); + } + + setProjectsDetailList(List projectDetailListModel) { + _projectDetailListModel = projectDetailListModel; + notifyListeners(); + } + + setHMCProjectList(List hMCProjectListModel) { + _hMCProjectListModel = hMCProjectListModel; + notifyListeners(); + } + setPrivilege({privilegeList, bool isLoginChild = false}) { - List privilege = List(); + List privilege = []; privilegeList['List'][0]['ListPrivilege'].forEach((item) { privilege.add(PrivilegeModel.fromJson(item)); @@ -113,21 +227,25 @@ class ProjectViewModel extends BaseViewModel { notifyListeners(); } - setIsLoginChild({@required bool isLoginChild}){ + setIsLoginChild({required bool isLoginChild}) { this.isLoginChild = isLoginChild; notifyListeners(); } bool havePrivilege(int id) { bool isHavePrivilege = false; - if(isLoginChild) - privilegeChildUser.forEach((element) { - if (element.iD == id) isHavePrivilege = element.privilege; - }); - else{ - privilegeRootUser.forEach((element) { - if (element.iD == id) isHavePrivilege = element.privilege; - }); + try { + if (isLoginChild) { + privilegeChildUser.forEach((element) { + if (element.iD == id) isHavePrivilege = element.privilege!; + }); + } else { + privilegeRootUser.forEach((element) { + if (element.iD == id) isHavePrivilege = element.privilege!; + }); + } + } catch (e) { + print(e); } return isHavePrivilege; } @@ -142,4 +260,15 @@ class ProjectViewModel extends BaseViewModel { searchvalue = data; notifyListeners(); } + + void setLatitudeLongitude(double lat, double long) { + _latitude = lat; + _longitude = long; + notifyListeners(); + } + + setRegisterData(RegisterInfoResponse data) { + _registerInfo = data; + notifyListeners(); + } } diff --git a/lib/core/viewModels/qr_view_model.dart b/lib/core/viewModels/qr_view_model.dart index 9833d6c8..7d952820 100644 --- a/lib/core/viewModels/qr_view_model.dart +++ b/lib/core/viewModels/qr_view_model.dart @@ -1,27 +1,33 @@ import 'dart:convert'; -import 'package:barcode_scan_fix/barcode_scan.dart'; +import 'dart:io'; + +import 'package:barcode_scan2/barcode_scan2.dart'; +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/qr/qr_parking_model.dart'; import 'package:diplomaticquarterapp/core/service/qr_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; +import 'package:diplomaticquarterapp/services/permission/permission_service.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; import '../../locator.dart'; class QrViewModel extends BaseViewModel { QrService _qrService = locator(); bool isSavePark = false; - QRParkingModel qrParkingModel; + QRParkingModel? qrParkingModel; readQr() async { //TODO fix the barcode scan - String result = await BarcodeScanner.scan(); + String result = await readQR(); var data = json.decode(result); var qRParkingID = data['QRParkingID']; setState(ViewState.BusyLocal); await _qrService.getQRParkingByID(qRParkingID); if (_qrService.hasError) { - error = _qrService.error; + error = _qrService.error!; setState(ViewState.ErrorLocal); } else { if (_qrService.qRParkingList.length > 0) { @@ -36,6 +42,23 @@ class QrViewModel extends BaseViewModel { } } + readQR() async { + if (await PermissionService.isCameraEnabled()) { + return (await BarcodeScanner.scan()).rawContent; + } else { + if (Platform.isAndroid) { + Utils.showPermissionConsentDialog(AppGlobal.context, TranslationBase.of(AppGlobal.context).cameraPermissionDialog, () async { + await BarcodeScanner.scan().then((value) { + return value.rawContent; + //Chnanges by Aamir + }); + }); + } else { + return (await BarcodeScanner.scan()).rawContent; + } + } + } + getIsSaveParking() async { setState(ViewState.Busy); var parking = await sharedPref.getObject(IS_GO_TO_PARKING); diff --git a/lib/core/viewModels/vaccine_view_model.dart b/lib/core/viewModels/vaccine_view_model.dart index 9f8dfecf..e5ab9b7e 100644 --- a/lib/core/viewModels/vaccine_view_model.dart +++ b/lib/core/viewModels/vaccine_view_model.dart @@ -1,11 +1,11 @@ +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/vaccine/my_vaccine.dart'; import 'package:diplomaticquarterapp/core/model/vaccine/vaccination_item.dart'; +import 'package:diplomaticquarterapp/core/service/vaccine_service.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; -import 'base_view_model.dart'; import '../../locator.dart'; -import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; -import 'package:diplomaticquarterapp/core/model/vaccine/my_vaccine.dart'; -import 'package:diplomaticquarterapp/core/service/vaccine_service.dart'; +import 'base_view_model.dart'; class VaccineViewModel extends BaseViewModel { bool hasError = false; @@ -21,8 +21,8 @@ class VaccineViewModel extends BaseViewModel { setState(ViewState.Busy); await _vaccineService.getMyVaccine(); if (_vaccineService.hasError) { - error = _vaccineService.error; - setState(ViewState.ErrorLocal); + error = _vaccineService.error!; + setState(ViewState.Error); } else setState(ViewState.Idle); } @@ -32,33 +32,33 @@ class VaccineViewModel extends BaseViewModel { setState(ViewState.Busy); await _vaccineService.getMyVaccinationItem(); if (_vaccineService.hasError) { - error = _vaccineService.error; + error = _vaccineService.error!; setState(ViewState.Error); } else setState(ViewState.Idle); } - Future getMyVaccinationOnHand({String pItemCode}) async { + Future getMyVaccinationOnHand({String? pItemCode}) async { hasError = false; setState(ViewState.Busy); - await _vaccineService.getMyVaccinationOnHand(pItemCode: pItemCode); + await _vaccineService.getMyVaccinationOnHand(pItemCode: pItemCode!); if (_vaccineService.hasError) { - error = _vaccineService.error; + error = _vaccineService.error!; setState(ViewState.ErrorLocal); } else setState(ViewState.Idle); } - Future sendEmail({String message}) async { + Future sendEmail({String? message}) async { hasError = false; setState(ViewState.BusyLocal); await _vaccineService.sendEmail(); if (_vaccineService.hasError) { - error = _vaccineService.error; + error = _vaccineService.error!; setState(ViewState.ErrorLocal); AppToast.showErrorToast(message: error); } else { - AppToast.showSuccessToast(message: message); + AppToast.showSuccessToast(message: message!); setState(ViewState.Idle); } } diff --git a/lib/core/viewModels/weather/weather_view_model.dart b/lib/core/viewModels/weather/weather_view_model.dart index bb201843..733c591d 100644 --- a/lib/core/viewModels/weather/weather_view_model.dart +++ b/lib/core/viewModels/weather/weather_view_model.dart @@ -1,11 +1,7 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; -import 'package:diplomaticquarterapp/core/model/er/projectavgerwaitingtime.dart'; import 'package:diplomaticquarterapp/core/model/weahter/weather_model.dart'; - -import 'package:diplomaticquarterapp/core/service/er/er_service.dart'; import 'package:diplomaticquarterapp/core/service/weather_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; -import 'package:diplomaticquarterapp/pages/BookAppointment/widgets/BranchView.dart'; import '../../../locator.dart'; @@ -23,7 +19,7 @@ class WeatherViewModel extends BaseViewModel { await _weatherService.getWeatherData(); // } if (_weatherService.hasError) { - error = _weatherService.error; + error = _weatherService.error!; setState(ViewState.Error); } else setState(ViewState.Idle); diff --git a/lib/d_q_icons_icons.dart b/lib/d_q_icons_icons.dart index 5d1ff3c6..83335a36 100644 --- a/lib/d_q_icons_icons.dart +++ b/lib/d_q_icons_icons.dart @@ -11,7 +11,7 @@ /// fonts: /// - asset: fonts/DQIcons.ttf /// -/// +/// /// import 'package:flutter/widgets.dart'; @@ -19,25 +19,80 @@ class DQIcons { DQIcons._(); static const _kFontFam = 'DQIcons'; - static const _kFontPkg = null; + static const dynamic _kFontPkg = null; - static const IconData blood_pressure = IconData(0xe800, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData blood = IconData(0xe801, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData bmi = IconData(0xe802, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData heart = IconData(0xe803, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData height = IconData(0xe804, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData outline = IconData(0xe805, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData thermometer = IconData(0xe806, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData weight_scale = IconData(0xe807, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData parking_icon = IconData(0xe808, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData blood_type_icon = IconData(0xe809, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData height_icon = IconData(0xe80a, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData online_payment_icon = IconData(0xe80b, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData search_medicine_icon = IconData(0xe80c, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData vital_sign_icon = IconData(0xe80d, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData weight_icon = IconData(0xe80e, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData my_medical_file = IconData(0xe80f, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData family = IconData(0xe810, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData calendar__2_ = IconData(0xe811, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData roboticon = IconData(0xe812, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData blood_pressure = + IconData(0xe800, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData blood = + IconData(0xe801, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData bmi = + IconData(0xe802, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData heart = + IconData(0xe803, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData height = + IconData(0xe804, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData outline = + IconData(0xe805, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData thermometer = + IconData(0xe806, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData weight_scale = + IconData(0xe807, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData parking_icon = + IconData(0xe808, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData blood_type_icon = + IconData(0xe809, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData height_icon = + IconData(0xe80a, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData online_payment_icon = + IconData(0xe80b, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData search_medicine_icon = + IconData(0xe80c, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData vital_sign_icon = + IconData(0xe80d, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData weight_icon = + IconData(0xe80e, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData my_medical_file = + IconData(0xe80f, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData family = + IconData(0xe810, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData calendar__2_ = + IconData(0xe811, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData roboticon = + IconData(0xe812, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData cart_menu_icon = + IconData(0xe814, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData categories_menu_icon = + IconData(0xe815, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData hmg_logo_icon = + IconData(0xe816, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData user_menu_icon = + IconData(0xe817, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData cart_menu_icon_1 = + IconData(0xe818, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData categories_menu_icon_1 = + IconData(0xe819, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData hmg_logo_icon_1 = + IconData(0xe81a, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData emo_cry = + IconData(0xe8b5, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData emo_shoot = + IconData(0xe8b6, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData emo_squint = + IconData(0xe8b7, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData emo_laugh = + IconData(0xe8b8, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData chrome = + IconData(0xe8c0, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData opera = + IconData(0xe8c1, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData ie = + IconData(0xe8c2, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData crown = + IconData(0xe8c3, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData crown_plus = + IconData(0xe8c4, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData crown_minus = + IconData(0xe8c5, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData marquee = + IconData(0xe8c6, fontFamily: _kFontFam, fontPackage: _kFontPkg); } diff --git a/lib/extensions/list_extension.dart b/lib/extensions/list_extension.dart new file mode 100644 index 00000000..eeb3d6f3 --- /dev/null +++ b/lib/extensions/list_extension.dart @@ -0,0 +1,8 @@ +extension Unique on List { + List unique([Id Function(E element)? id, bool inplace = true]) { + final ids = Set(); + var list = inplace ? this : List.from(this); + list.retainWhere((x) => ids.add(id != null ? id(x) : x as Id)); + return list; + } +} \ No newline at end of file diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart new file mode 100644 index 00000000..df9cb4f6 --- /dev/null +++ b/lib/extensions/string_extensions.dart @@ -0,0 +1,19 @@ +import 'dart:convert'; +import 'package:crypto/crypto.dart'; + +extension CapExtension on String { + String get toCamelCase => "${this[0].toUpperCase()}${this.substring(1)}"; + + String get inCaps => '${this[0].toUpperCase()}${this.substring(1)}'; + + String get allInCaps => this.toUpperCase(); + + String get capitalizeFirstofEach => this.trim().length > 0 ? this.trim().toLowerCase().split(" ").map((str) => str.isNotEmpty ? str.inCaps : str).join(" ") : ""; +} + +extension HashSha on String { + String get toSha256 { + var bytes = utf8.encode(this); + return sha256.convert(bytes).toString(); + } +} diff --git a/lib/firebase_options.dart b/lib/firebase_options.dart new file mode 100644 index 00000000..75513c06 --- /dev/null +++ b/lib/firebase_options.dart @@ -0,0 +1,72 @@ +// File generated by FlutterFire CLI. +// ignore_for_file: lines_longer_than_80_chars, avoid_classes_with_only_static_members +import 'package:firebase_core/firebase_core.dart' show FirebaseOptions; +import 'package:flutter/foundation.dart' + show defaultTargetPlatform, kIsWeb, TargetPlatform; + +/// Default [FirebaseOptions] for use with your Firebase apps. +/// +/// Example: +/// ```dart +/// import 'firebase_options.dart'; +/// // ... +/// await Firebase.initializeApp( +/// options: DefaultFirebaseOptions.currentPlatform, +/// ); +/// ``` +class DefaultFirebaseOptions { + static FirebaseOptions get currentPlatform { + if (kIsWeb) { + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for web - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + } + switch (defaultTargetPlatform) { + case TargetPlatform.android: + return android; + case TargetPlatform.iOS: + return ios; + case TargetPlatform.macOS: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for macos - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + case TargetPlatform.windows: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for windows - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + case TargetPlatform.linux: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for linux - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + default: + throw UnsupportedError( + 'DefaultFirebaseOptions are not supported for this platform.', + ); + } + } + + static const FirebaseOptions android = FirebaseOptions( + apiKey: 'AIzaSyDUfg6AKM1-00WyzpvLImUBC46wFrq9-qw', + appId: '1:815750722565:android:62281cd3e5df4063', + messagingSenderId: '815750722565', + projectId: 'api-project-815750722565', + databaseURL: 'https://api-project-815750722565.firebaseio.com', + storageBucket: 'api-project-815750722565.appspot.com', + ); + + static const FirebaseOptions ios = FirebaseOptions( + apiKey: 'AIzaSyDiXnCO00li4V7Ioa2YZ_M4ECxRsu_P9tA', + appId: '1:815750722565:ios:328ec247a81a2ca23c186c', + messagingSenderId: '815750722565', + projectId: 'api-project-815750722565', + databaseURL: 'https://api-project-815750722565.firebaseio.com', + storageBucket: 'api-project-815750722565.appspot.com', + androidClientId: '815750722565-m14h8mkosm7cnq6uh6rhqr54dn02d705.apps.googleusercontent.com', + iosClientId: '815750722565-da8p56le8bd6apsbm9eft0jjl1rtpgkt.apps.googleusercontent.com', + iosBundleId: 'com.HMG.HMG-Smartphone', + ); +} diff --git a/lib/generated/json/OfferCategoriesResponseModel_helper.dart b/lib/generated/json/OfferCategoriesResponseModel_helper.dart index 1a28d179..b6bb7d97 100644 --- a/lib/generated/json/OfferCategoriesResponseModel_helper.dart +++ b/lib/generated/json/OfferCategoriesResponseModel_helper.dart @@ -11,9 +11,9 @@ offerCategoriesResponseModelFromJson(PackagesCategoriesResponseModel data, Map(); + data.localizedNames = []; (json['localized_names'] as List).forEach((v) { - data.localizedNames.add(new OfferCategoriesResponseModelLocalizedName().fromJson(v)); + data.localizedNames!.add(new OfferCategoriesResponseModelLocalizedName().fromJson(v)); }); } if (json['description'] != null) { @@ -68,16 +68,16 @@ offerCategoriesResponseModelFromJson(PackagesCategoriesResponseModel data, Map(); - data.roleIds.addAll(json['role_ids']); + data.roleIds =[]; + data.roleIds!.addAll(json['role_ids']); } if (json['discount_ids'] != null) { - data.discountIds = new List(); - data.discountIds.addAll(json['discount_ids']); + data.discountIds = []; + data.discountIds!.addAll(json['discount_ids']); } if (json['store_ids'] != null) { - data.storeIds = new List(); - data.storeIds.addAll(json['store_ids']); + data.storeIds =[]; + data.storeIds!.addAll(json['store_ids']); } if (json['image'] != null) { data.image = new OfferCategoriesResponseModelImage().fromJson(json['image']); @@ -97,7 +97,7 @@ Map offerCategoriesResponseModelToJson(PackagesCategoriesRespon data['name'] = entity.name; data['namen'] = entity.namen; if (entity.localizedNames != null) { - data['localized_names'] = entity.localizedNames.map((v) => v.toJson()).toList(); + data['localized_names'] = entity.localizedNames!.map((v) => v.toJson()).toList(); } data['description'] = entity.description; data['category_template_id'] = entity.categoryTemplateId; @@ -126,7 +126,7 @@ Map offerCategoriesResponseModelToJson(PackagesCategoriesRespon data['store_ids'] = []; } if (entity.image != null) { - data['image'] = entity.image.toJson(); + data['image'] = entity.image!.toJson(); } data['se_name'] = entity.seName; data['is_leaf'] = entity.isLeaf; diff --git a/lib/generated/json/OfferProductsResponseModel_helper.dart b/lib/generated/json/OfferProductsResponseModel_helper.dart index d180af67..818de36a 100644 --- a/lib/generated/json/OfferProductsResponseModel_helper.dart +++ b/lib/generated/json/OfferProductsResponseModel_helper.dart @@ -14,9 +14,9 @@ offerProductsResponseModelFromJson(PackagesResponseModel data, Map(); + data.localizedNames = []; (json['localized_names'] as List).forEach((v) { - data.localizedNames.add(new OfferProductsResponseModelLocalizedName().fromJson(v)); + data.localizedNames!.add(new OfferProductsResponseModelLocalizedName().fromJson(v)); }); } if (json['short_description'] != null) { @@ -302,47 +302,53 @@ offerProductsResponseModelFromJson(PackagesResponseModel data, Map(); - data.roleIds.addAll(json['role_ids']); + data.roleIds =[]; + data.roleIds!.addAll(json['role_ids']); } if (json['discount_ids'] != null) { - data.discountIds = new List(); - data.discountIds.addAll(json['discount_ids']); + data.discountIds = []; + data.discountIds!.addAll(json['discount_ids']); } if (json['store_ids'] != null) { - data.storeIds = new List(); - data.storeIds.addAll(json['store_ids']); + data.storeIds = []; + data.storeIds!.addAll(json['store_ids']); } + + if (json['store_names'] != null) { + data.storeNames = []; + data.storeNames!.addAll(json['store_names']); + } + if (json['manufacturer_ids'] != null) { data.manufacturerIds = json['manufacturer_ids']?.map((v) => v?.toInt())?.toList()?.cast(); } if (json['reviews'] != null) { - data.reviews = new List(); - data.reviews.addAll(json['reviews']); + data.reviews =[]; + data.reviews!.addAll(json['reviews']); } if (json['images'] != null) { - data.images = new List(); + data.images = []; (json['images'] as List).forEach((v) { - data.images.add(new OfferProductsResponseModelImage().fromJson(v)); + data.images!.add(new OfferProductsResponseModelImage().fromJson(v)); }); } if (json['attributes'] != null) { - data.attributes = new List(); - data.attributes.addAll(json['attributes']); + data.attributes = []; + data.attributes!.addAll(json['attributes']); } if (json['specifications'] != null) { - data.specifications = new List(); + data.specifications = []; (json['specifications'] as List).forEach((v) { - data.specifications.add(new OfferProductsResponseModelSpecification().fromJson(v)); + data.specifications!.add(new OfferProductsResponseModelSpecification().fromJson(v)); }); } if (json['associated_product_ids'] != null) { - data.associatedProductIds = new List(); - data.associatedProductIds.addAll(json['associated_product_ids']); + data.associatedProductIds = []; + data.associatedProductIds!.addAll(json['associated_product_ids']); } if (json['tags'] != null) { - data.tags = new List(); - data.tags.addAll(json['tags']); + data.tags = []; + data.tags!.addAll(json['tags']); } if (json['vendor_id'] != null) { data.vendorId = json['vendor_id']?.toInt(); @@ -360,7 +366,7 @@ Map offerProductsResponseModelToJson(PackagesResponseModel enti data['name'] = entity.name; data['namen'] = entity.namen; if (entity.localizedNames != null) { - data['localized_names'] = entity.localizedNames.map((v) => v.toJson()).toList(); + data['localized_names'] = entity.localizedNames!.map((v) => v.toJson()).toList(); } data['short_description'] = entity.shortDescription; data['short_descriptionn'] = entity.shortDescriptionn; @@ -470,13 +476,13 @@ Map offerProductsResponseModelToJson(PackagesResponseModel enti data['reviews'] = []; } if (entity.images != null) { - data['images'] = entity.images.map((v) => v.toJson()).toList(); + data['images'] = entity.images!.map((v) => v.toJson()).toList(); } if (entity.attributes != null) { data['attributes'] = []; } if (entity.specifications != null) { - data['specifications'] = entity.specifications.map((v) => v.toJson()).toList(); + data['specifications'] = entity.specifications!.map((v) => v.toJson()).toList(); } if (entity.associatedProductIds != null) { data['associated_product_ids'] = []; diff --git a/lib/generated/json/base/json_convert_content.dart b/lib/generated/json/base/json_convert_content.dart index ae4eadeb..c4d393c3 100644 --- a/lib/generated/json/base/json_convert_content.dart +++ b/lib/generated/json/base/json_convert_content.dart @@ -2,15 +2,16 @@ // ignore_for_file: camel_case_types // ignore_for_file: prefer_single_quotes +import 'package:diplomaticquarterapp/core/model/geofencing/responses/GeoZonesResponseModel.dart'; +import 'package:diplomaticquarterapp/core/model/geofencing/responses/LogGeoZoneResponseModel.dart'; + // This file is automatically generated. DO NOT EDIT, all your changes would be lost. import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCategoriesResponseModel.dart'; -import 'package:diplomaticquarterapp/generated/json/OfferCategoriesResponseModel_helper.dart'; -import 'package:diplomaticquarterapp/core/model/geofencing/responses/LogGeoZoneResponseModel.dart'; -import 'package:diplomaticquarterapp/generated/json/log_geo_zone_response_model_entity_helper.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart'; -import 'package:diplomaticquarterapp/generated/json/OfferProductsResponseModel_helper.dart'; -import 'package:diplomaticquarterapp/core/model/geofencing/responses/GeoZonesResponseModel.dart'; import 'package:diplomaticquarterapp/generated/json/GeoZonesResponseModel_helper.dart'; +import 'package:diplomaticquarterapp/generated/json/OfferCategoriesResponseModel_helper.dart'; +import 'package:diplomaticquarterapp/generated/json/OfferProductsResponseModel_helper.dart'; +import 'package:diplomaticquarterapp/generated/json/log_geo_zone_response_model_entity_helper.dart'; class JsonConvert { T fromJson(Map json) { @@ -96,31 +97,56 @@ class JsonConvert { //list is returned by type static M _getListChildType(List data) { - if (List() is M) { - return data.map((e) => PackagesCategoriesResponseModel().fromJson(e)).toList() as M; - } else if (List() is M) { - return data.map((e) => OfferCategoriesResponseModelLocalizedName().fromJson(e)).toList() as M; - } else if (List() is M) { - return data.map((e) => OfferCategoriesResponseModelImage().fromJson(e)).toList() as M; - } else if (List() is M) { - return data.map((e) => LogGeoZoneResponseModel().fromJson(e)).toList() as M; - } else if (List() is M) { - return data.map((e) => PackagesResponseModel().fromJson(e)).toList() as M; - } else if (List() is M) { - return data.map((e) => OfferProductsResponseModelLocalizedName().fromJson(e)).toList() as M; - } else if (List() is M) { - return data.map((e) => OfferProductsResponseModelImage().fromJson(e)).toList() as M; - } else if (List() is M) { - return data.map((e) => OfferProductsResponseModelSpecification().fromJson(e)).toList() as M; - } else if (List() is M) { - return data.map((e) => GeoZonesResponseModel().fromJson(e)).toList() as M; + //Changed By Aamir + if ([] is M) { + return data.map((e) => PackagesCategoriesResponseModel().fromJson(e as Map)).toList() as M; + } else if ([] is M) { + return data.map((e) => OfferCategoriesResponseModelLocalizedName().fromJson(e as Map)).toList() as M; + } else if ([] is M) { + return data.map((e) => OfferCategoriesResponseModelImage().fromJson(e as Map)).toList() as M; + } else if ([] is M) { + return data.map((e) => LogGeoZoneResponseModel().fromJson(e as Map)).toList() as M; + } else if ([] is M) { + return data.map((e) => PackagesResponseModel().fromJson(e as Map)).toList() as M; + } else if ([] is M) { + return data.map((e) => OfferProductsResponseModelLocalizedName().fromJson(e as Map)).toList() as M; + } else if ([] is M) { + return data.map((e) => OfferProductsResponseModelImage().fromJson(e as Map)).toList() as M; + } else if ([] is M) { + return data.map((e) => OfferProductsResponseModelSpecification().fromJson(e as Map)).toList() as M; + } else if ([] is M) { + return data.map((e) => GeoZonesResponseModel().fromJson(e as Map)).toList() as M; } - return null; + return M as M; } + // static M _getListChildType(List data) { + // if (List() is M) { + // return data.map((e) => PackagesCategoriesResponseModel().fromJson(e)).toList() as M; + // } else if (List() is M) { + // return data.map((e) => OfferCategoriesResponseModelLocalizedName().fromJson(e)).toList() as M; + // } else if (List() is M) { + // return data.map((e) => OfferCategoriesResponseModelImage().fromJson(e)).toList() as M; + // } else if (List() is M) { + // return data.map((e) => LogGeoZoneResponseModel().fromJson(e)).toList() as M; + // } else if (List() is M) { + // return data.map((e) => PackagesResponseModel().fromJson(e)).toList() as M; + // } else if (List() is M) { + // return data.map((e) => OfferProductsResponseModelLocalizedName().fromJson(e)).toList() as M; + // } else if (List() is M) { + // return data.map((e) => OfferProductsResponseModelImage().fromJson(e)).toList() as M; + // } else if (List() is M) { + // return data.map((e) => OfferProductsResponseModelSpecification().fromJson(e)).toList() as M; + // } else if (List() is M) { + // return data.map((e) => GeoZonesResponseModel().fromJson(e)).toList() as M; + // } + // return null; + // } + static M fromJsonAsT(json) { if (json is List) { - return _getListChildType(json); + return _getListChildType(json as List>); + //changed by Aamir added after As keyword } else { return _fromJsonSingle(json) as M; } diff --git a/lib/generated/json/base/json_field.dart b/lib/generated/json/base/json_field.dart index bc92972b..32632862 100644 --- a/lib/generated/json/base/json_field.dart +++ b/lib/generated/json/base/json_field.dart @@ -6,16 +6,16 @@ class JSONField { //Specify the parse field name - final String name; + final String? name; //Specify the time resolution format - final String format; + final String? format; //Whether to participate in toJson - final bool serialize; + final bool? serialize; //Whether to participate in fromMap - final bool deserialize; + final bool? deserialize; const JSONField({this.name, this.format, this.serialize, this.deserialize}); } diff --git a/lib/locator.dart b/lib/locator.dart index 1acaf1af..61ed983b 100644 --- a/lib/locator.dart +++ b/lib/locator.dart @@ -1,27 +1,33 @@ import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/H2O_service.dart'; import 'package:diplomaticquarterapp/core/service/ancillary_orders_service.dart'; +import 'package:diplomaticquarterapp/core/service/client/base_app_client.dart'; import 'package:diplomaticquarterapp/core/service/parmacyModule/prescription_service.dart'; import 'package:diplomaticquarterapp/core/service/qr_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/H2O_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/home_health_care_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/ancillary_orders_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/child_vaccines/user_information_view_model.dart'; -import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/home_health_care_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/dashboard_view_model.dart'; -import 'package:diplomaticquarterapp/services/pharmacy_services/recommendedProduct_service.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/MostViewedViewModel.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/PharmacyAddressesViewModel.dart'; +import 'package:diplomaticquarterapp/core/viewModels/product_categories_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/order_model_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/weather/weather_view_model.dart'; +import 'package:diplomaticquarterapp/services/payfort_services/payfort_service.dart'; +import 'package:diplomaticquarterapp/services/payfort_services/payfort_view_model.dart'; +import 'package:diplomaticquarterapp/services/pharmacy_services/cancelOrder_service.dart'; +import 'package:diplomaticquarterapp/services/pharmacy_services/order_service.dart'; +import 'package:diplomaticquarterapp/services/pharmacy_services/recommendedProduct_service.dart'; // import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/PharmacyAddressesViewModel.dart'; // import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/order_model_view_model.dart'; // import 'package:diplomaticquarterapp/services/pharmacy_services/order_service.dart'; import 'package:diplomaticquarterapp/services/pharmacy_services/review_service.dart'; import 'package:diplomaticquarterapp/services/pharmacy_services/wishList_service.dart'; -import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/PharmacyAddressesViewModel.dart'; -import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/order_model_view_model.dart'; -import 'package:diplomaticquarterapp/services/pharmacy_services/cancelOrder_service.dart'; -import 'package:diplomaticquarterapp/services/pharmacy_services/order_service.dart'; import 'package:diplomaticquarterapp/uitl/navigation_service.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:get_it/get_it.dart'; +import 'analytics/google-analytics.dart'; import 'core/service/AlHabibMedicalService/cmc_service.dart'; import 'core/service/AlHabibMedicalService/customer_addresses_service.dart'; import 'core/service/AlHabibMedicalService/e_referral_service.dart'; @@ -46,6 +52,7 @@ import 'core/service/er/er_service.dart'; import 'core/service/feedback/feedback_service.dart'; import 'core/service/geofencing/GeofencingServices.dart'; import 'core/service/hospital_service.dart'; +import 'core/service/insurance_service.dart'; import 'core/service/medical/ActiveMedicationsService.dart'; import 'core/service/medical/AllergiesService.dart'; import 'core/service/medical/BloodPressureService.dart'; @@ -61,25 +68,25 @@ import 'core/service/medical/my_doctor_service.dart'; import 'core/service/medical/prescriptions_service.dart'; import 'core/service/medical/radiology_service.dart'; import 'core/service/medical/reports_monthly_service.dart'; +import 'core/service/medical/reports_service.dart'; import 'core/service/medical/vital_sign_service.dart'; +import 'core/service/notifications_service.dart'; +import 'core/service/offers_service.dart'; import 'core/service/packages_offers/PackagesOffersServices.dart'; import 'core/service/parmacyModule/lacum-registration-service.dart'; import 'core/service/parmacyModule/lacum-service.dart'; import 'core/service/parmacyModule/lacum-transfer-service.dart'; import 'core/service/parmacyModule/order-preview-service.dart'; -import 'core/service/notifications_service.dart'; +import 'core/service/parmacyModule/parmacy_module_service.dart'; import 'core/service/parmacyModule/terms-condition-service.dart'; +import 'core/service/pharmacies_service.dart'; +import 'core/service/pharmacy_categorise_service.dart'; import 'core/service/privilege_service.dart'; import 'core/service/termsConditionsService.dart'; +import 'core/service/vaccine_service.dart'; import 'core/service/weather_service.dart'; import 'core/viewModels/AlHabibMedicalService/cmc_view_model.dart'; -import 'core/service/parmacyModule/parmacy_module_service.dart'; - -import 'core/service/offers_service.dart'; -import 'core/service/pharmacy_categorise_service.dart'; import 'core/viewModels/AlHabibMedicalService/health-calculator/Bariatrics-viewmodel.dart'; -import 'core/viewModels/er/EdOnlineViewModel.dart'; -import 'core/viewModels/medical/PrescriptionDeliveryViewModel.dart'; import 'core/viewModels/TermsConditionsViewModel.dart'; import 'core/viewModels/all_habib_medical_services/e_referral_view_model.dart'; import 'core/viewModels/appointment_rate_view_model.dart'; @@ -90,58 +97,57 @@ import 'core/viewModels/child_vaccines/child_vaccines_view_model.dart'; import 'core/viewModels/child_vaccines/vaccination_table_view_model.dart'; import 'core/viewModels/contactus/findus_view_model.dart'; import 'core/viewModels/contactus/livechat_view_model.dart'; +import 'core/viewModels/er/EdOnlineViewModel.dart'; import 'core/viewModels/er/am_request_view_model.dart'; import 'core/viewModels/er/near_hospital_view_model.dart'; +import 'core/viewModels/er/rrt-view-model.dart'; import 'core/viewModels/feedback/feedback_view_model.dart'; -import 'core/service/medical/reports_service.dart'; import 'core/viewModels/hospital_view_model.dart'; +import 'core/viewModels/insurance_card_View_model.dart'; import 'core/viewModels/medical/ActiveMedicationsViewModel.dart'; import 'core/viewModels/medical/AllergiesViewModel.dart'; import 'core/viewModels/medical/EyeViewModel.dart'; +import 'core/viewModels/medical/PrescriptionDeliveryViewModel.dart'; import 'core/viewModels/medical/ask_doctor_view_model.dart'; import 'core/viewModels/medical/blood_pressure_view_model.dart'; +import 'core/viewModels/medical/blood_sugar_view_model.dart'; import 'core/viewModels/medical/labs_view_model.dart'; import 'core/viewModels/medical/medical_view_model.dart'; import 'core/viewModels/medical/my_balance_view_model.dart'; import 'core/viewModels/medical/my_doctor_view_model.dart'; -import 'core/viewModels/medical/blood_sugar_view_model.dart'; import 'core/viewModels/medical/patient_sick_leave_view_model.dart'; import 'core/viewModels/medical/prescriptions_view_model.dart'; import 'core/viewModels/medical/radiology_view_model.dart'; import 'core/viewModels/medical/reports_monthly_view_model.dart'; -import 'core/viewModels/medical/vital_sign_view_model.dart'; import 'core/viewModels/medical/reports_view_model.dart'; +import 'core/viewModels/medical/vital_sign_view_model.dart'; import 'core/viewModels/medical/weight_pressure_view_model.dart'; import 'core/viewModels/notifications_view_model.dart'; import 'core/viewModels/offers_Categorise_view_model.dart'; import 'core/viewModels/packages_offers/PackagesOffersViewModel.dart'; import 'core/viewModels/pharmacies_view_model.dart'; -import 'core/service/pharmacies_service.dart'; -import 'core/service/insurance_service.dart'; -import 'core/viewModels/insurance_card_View_model.dart'; -import 'core/viewModels/pharmacyModule/brand_view_model.dart'; -import 'core/viewModels/pharmacyModule/pharmacy_module_view_model.dart'; -import 'core/viewModels/pharmacyModule/product_detail_view_model.dart'; -import 'core/viewModels/pharmacyModule/review_view_model.dart'; -import 'core/viewModels/pharmacyModule/wishlist_view_model.dart'; -import 'core/viewModels/qr_view_model.dart'; -import 'core/viewModels/vaccine_view_model.dart'; -import 'core/service/vaccine_service.dart'; -import 'core/viewModels/weather/weather_view_model.dart'; -import 'services/pharmacy_services/brands_service.dart'; -import 'services/pharmacy_services/product_detail_service.dart'; import 'core/viewModels/pharmacyModule/OrderPreviewViewModel.dart'; +import 'core/viewModels/pharmacyModule/BestSellerViewModel.dart'; +import 'core/viewModels/pharmacyModule/BrandViewModel.dart'; +import 'core/viewModels/pharmacyModule/LastVisitedViewModel.dart'; +import 'core/viewModels/pharmacyModule/PrescriptionViewModel.dart'; +import 'core/viewModels/pharmacyModule/brand_view_model.dart'; import 'core/viewModels/pharmacyModule/lacum-registration-viewModel.dart'; import 'core/viewModels/pharmacyModule/lacum-trasnfer-viewModel.dart'; import 'core/viewModels/pharmacyModule/lacum-viewmodel.dart'; import 'core/viewModels/pharmacyModule/pharmacy_module_view_model.dart'; +import 'core/viewModels/pharmacyModule/product_detail_view_model.dart'; +import 'core/viewModels/pharmacyModule/review_view_model.dart'; import 'core/viewModels/pharmacyModule/tems-condition-viewmodel.dart'; +import 'core/viewModels/pharmacyModule/wishlist_view_model.dart'; import 'core/viewModels/pharmacy_categorise_view_model.dart'; import 'core/viewModels/qr_view_model.dart'; import 'core/viewModels/vaccine_view_model.dart'; -import 'core/service/vaccine_service.dart'; +import 'core/viewModels/weather/weather_view_model.dart'; +import 'services/pharmacy_services/brands_service.dart'; import 'services/pharmacy_services/orderDetails_service.dart'; import 'services/pharmacy_services/pharmacyAddress_service.dart'; +import 'services/pharmacy_services/product_detail_service.dart'; GetIt locator = GetIt.instance; @@ -198,6 +204,7 @@ void setupLocator() { locator.registerLazySingleton(() => VaccinationTableService()); locator.registerLazySingleton(() => AncillaryOrdersService()); locator.registerLazySingleton(() => EdOnlineServices()); + locator.registerLazySingleton(() => PayfortService()); //pharmacy // locator.registerLazySingleton(() => PharmacyCategoriseService()); @@ -250,6 +257,7 @@ void setupLocator() { locator.registerFactory(() => QrViewModel()); locator.registerFactory(() => ReportsMonthlyViewModel()); locator.registerFactory(() => NearHospitalViewModel()); + locator.registerFactory(() => RRTViewModel()); locator.registerFactory(() => AmRequestViewModel()); locator.registerFactory(() => PatientSickLeaveViewMode()); locator.registerFactory(() => MyBalanceViewModel()); @@ -287,21 +295,31 @@ void setupLocator() { locator.registerFactory(() => ProductDetailViewModel()); locator.registerFactory(() => WeatherViewModel()); - locator.registerFactory(() => OrderPreviewViewModel()); + // locator.registerFactory(() => OrderPreviewViewModel()); locator.registerFactory(() => LacumViewModel()); locator.registerFactory(() => LacumTranferViewModel()); locator.registerFactory(() => LacumRegistrationViewModel()); locator.registerFactory(() => EdOnlineViewModel()); + locator.registerFactory(() => ProductCategoriesViewModel()); //pharmacy locator.registerFactory(() => PharmacyCategoriseViewModel()); locator.registerFactory(() => OffersCategoriseViewModel()); locator.registerFactory(() => BariatricsViewModel()); + locator.registerFactory(() => PrescriptionViewModel()); + locator.registerFactory(() => BrandViewModel()); + locator.registerFactory(() => BestSellerViewModel()); + locator.registerFactory(() => LastVisitedViewModel()); + locator.registerFactory(() => MostViewedViewModel()); + locator.registerFactory(() => PayfortViewModel()); + // Offer And Packages //---------------------- - locator.registerLazySingleton(() => OffersAndPackagesServices()); // offerPackagesServices Service - locator.registerFactory(() => OfferCategoriesViewModel()); // Categories View Model + locator.registerLazySingleton( + () => OffersAndPackagesServices()); // offerPackagesServices Service + locator.registerFactory( + () => OfferCategoriesViewModel()); // Categories View Model locator.registerFactory(() => PackagesViewModel()); // Products View Model //pharmacy @@ -313,4 +331,11 @@ void setupLocator() { () => GeofencingServices()); // Geofencing Services locator.registerFactory(() => TermsConditionsViewModel()); locator.registerFactory(() => AnciallryOrdersViewModel()); + + + // Google/Firebase Analytics + // --------------------------- + locator.registerFactory(() => GAnalytics()); + + locator.registerLazySingleton(() => BaseAppClient()); } diff --git a/lib/main.dart b/lib/main.dart index 2412e4d1..03ac65fc 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,31 +1,48 @@ -import 'package:diplomaticquarterapp/theme/theme_notifier.dart'; +import 'dart:async'; +import 'dart:io'; + +import 'package:app_links/app_links.dart'; +import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/core/viewModels/PharmacyPagesViewModel.dart'; +import 'package:diplomaticquarterapp/core/viewModels/dashboard_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart'; import 'package:diplomaticquarterapp/routes.dart'; +import 'package:diplomaticquarterapp/services/payfort_services/payfort_view_model.dart'; import 'package:diplomaticquarterapp/services/robo_search/event_provider.dart'; import 'package:diplomaticquarterapp/services/robo_search/search_provider.dart'; +import 'package:diplomaticquarterapp/theme/theme_notifier.dart'; import 'package:diplomaticquarterapp/theme/theme_value.dart'; -import 'package:diplomaticquarterapp/uitl/HMG_Geofence.dart'; -import 'package:diplomaticquarterapp/uitl/LocalNotification.dart'; +import 'package:diplomaticquarterapp/uitl/DeepLinkHandler.dart'; import 'package:diplomaticquarterapp/uitl/PlatformBridge.dart'; -import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; +import 'package:diplomaticquarterapp/uitl/navigation_service.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; -import 'package:hexcolor/hexcolor.dart'; import 'package:provider/provider.dart'; -import 'Constants.dart'; -import 'config/shared_pref_kay.dart'; import 'config/size_config.dart'; -import 'core/model/geofencing/requests/GeoZonesRequestModel.dart'; -import 'core/service/geofencing/GeofencingServices.dart'; +import 'core/viewModels/pharmacyModule/OrderPreviewViewModel.dart'; import 'core/viewModels/project_view_model.dart'; import 'locator.dart'; import 'pages/pharmacies/compare-list.dart'; void main() async { + WidgetsFlutterBinding.ensureInitialized(); + await Firebase.initializeApp(); + + // Pass all uncaught "fatal" errors from the framework to Crashlytics + // FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterFatalError; + + // Pass all uncaught asynchronous errors that aren't handled by the Flutter framework to Crashlytics + // PlatformDispatcher.instance.onError = (error, stack) { + // if (!kDebugMode) FirebaseCrashlytics.instance.recordError(error, stack, fatal: true); + // return true; + // }; + setupLocator(); + HttpOverrides.global = MyHttpOverrides(); + runApp(MyApp()); } @@ -34,26 +51,84 @@ class MyApp extends StatefulWidget { _MyApp createState() => new _MyApp(); } +class MyHttpOverrides extends HttpOverrides { + @override + HttpClient createHttpClient(SecurityContext? context) { + return super.createHttpClient(context)..badCertificateCallback = (X509Certificate cert, String host, int port) => true; + } +} + class _MyApp extends State { + // late AppUpdateInfo _updateInfo; + StreamSubscription? _linkSubscription; + final GlobalKey navigatorKey = GlobalKey(); + + //0537503378 + //1231755 + + //0567184134 mobile + //246305493 + + // checkForUpdate() { + // // todo need to verify 'imp' + // InAppUpdate.checkForUpdate().then((info) { + // print("checkForUpdate!!!"); + // print(info.toString()); + // if (info.immediateUpdateAllowed) { + // print("Immediate567184134 Allowed!!!"); + // InAppUpdate.performImmediateUpdate().then((value) {}).catchError((e) => print(e.toString())); + // } + // }).catchError((e) { + // print(e.toString()); + // }); + // } + @override - void initState(){ - // ProjectViewModel projectProvider; + void initState() { + //ProjectViewModel projectProvider; // projectProvider = Provider.of(context); // var font = projectProvider.isArabic ? 'Cairo' : 'WorkSans'; + + // Re-enable once going live + // if (Platform.isAndroid) checkForUpdate(); + ThemeNotifier(defaultTheme()); + initDeepLinks(); super.initState(); } + void dispose() { + _linkSubscription?.cancel(); + + super.dispose(); + } + + Future initDeepLinks() async { + // Handle links + _linkSubscription = AppLinks().uriLinkStream.listen((uri) { + debugPrint('onAppLink: $uri'); + openAppLink(uri); + }); + } + + void openAppLink(Uri uri) { + print("the uri is $uri"); + DeepLinkHandler.instance.handleDeepLinkAndNavigation( + locator().navigatorKey.currentState, uri, context); + } + @override Widget build(BuildContext context) { PlatformBridge.init(context); - LocalNotification.init(onNotificationClick: (payload) { - LocalNotification.getInstance() - .showNow(title: "Payload", subtitle: payload, payload: payload); - }); + AppGlobal.context = context; + // SystemChrome.setPreferredOrientations([ + // DeviceOrientation.portraitUp, + // DeviceOrientationO.portraitDown, + // ]); // final themeNotifier = Provider.of(context); precacheImage(AssetImage('assets/images/powerd-by.jpg'), context); + return LayoutBuilder( builder: (context, constraints) { return OrientationBuilder( @@ -61,32 +136,57 @@ class _MyApp extends State { SizeConfig().init(constraints, orientation); return MultiProvider( providers: [ + ChangeNotifierProvider( + create: (context) => PharmacyPagesViewModel(), + ), ChangeNotifierProvider( create: (context) => ProjectViewModel(), ), + ChangeNotifierProvider( + create: (context) => DashboardViewModel(), + ), ChangeNotifierProvider( - create: (context) => ToDoCountProviderModel()), + create: (context) => ToDoCountProviderModel(), + ), ChangeNotifierProvider( - create: (context) => SearchProvider()), + create: (context) => SearchProvider(), + ), ChangeNotifierProvider.value( value: SearchProvider(), ), ChangeNotifierProvider( - create: (context) => ThemeNotifier( - defaultTheme() - ) + create: (context) => ThemeNotifier( + defaultTheme(), + ), ), StreamProvider.value( value: RobotProvider().intStream(), initialData: RobotProvider().setValue({}), ), ChangeNotifierProvider( - create: (context) => CompareList()), + create: (context) => CompareList(), + ), + ChangeNotifierProvider( + create: (context) => OrderPreviewViewModel(), + ), + ChangeNotifierProvider(create: (context) => PayfortViewModel()), ], child: Consumer( builder: (context, projectProvider, child) => MaterialApp( + builder: (context, mchild) { + AppGlobal.projectViewModelContext = context; + return MediaQuery( + data: MediaQuery.of(context).copyWith( + textScaler: TextScaler.linear(1.0), + ), //set desired text scale factor here + child: mchild!); + // Container( + // color: Colors.blue, + // )); + }, + navigatorKey: locator().navigatorKey, showSemanticsDebugger: false, - title: 'Diplomatic Quarter App', + title: 'Dr. AlHabib', locale: projectProvider.appLocal, localizationsDelegates: [ TranslationBaseDelegate(), @@ -99,50 +199,9 @@ class _MyApp extends State { const Locale('en', ''), // English ], theme: Provider.of(context).getTheme(), - // theme: ThemeData( - // fontFamily: projectProvider.isArabic ? 'Cairo' : 'WorkSans', - // primarySwatch: Colors.blue, - // visualDensity: VisualDensity.adaptivePlatformDensity, - // brightness: Brightness.light, - // pageTransitionsTheme: const PageTransitionsTheme( - // builders: { - // TargetPlatform.android: ZoomPageTransitionsBuilder(), - // TargetPlatform.iOS: CupertinoPageTransitionsBuilder(), - // }, - // ), - // hintColor: Colors.grey[400], - // textTheme: TextTheme( - // headline1: TextStyle( - // color: Color(0xffB8382C), - // ), - // ), - // disabledColor: Colors.grey[300], - // errorColor: Color.fromRGBO(235, 80, 60, 1.0), - // scaffoldBackgroundColor: - // Color(0xffE9E9E9), // Colors.grey[100], - // textSelectionColor: Color.fromRGBO(80, 100, 253, 0.5), - // textSelectionHandleColor: Colors.grey, - // canvasColor: Colors.white, - // backgroundColor: Color.fromRGBO(255, 255, 255, 1), - // highlightColor: Colors.grey[100].withOpacity(0.4), - // splashColor: Colors.transparent, - // primaryColor: Color(0xff515A5D), - // toggleableActiveColor: secondaryColor, - // indicatorColor: secondaryColor, - // bottomSheetTheme: BottomSheetThemeData( - // backgroundColor: HexColor('#E0E0E0')), - // cursorColor: Colors.grey, - // iconTheme: IconThemeData(), - // appBarTheme: AppBarTheme( - // color: Color(0xff515A5D), - // brightness: Brightness.light, - // elevation: 0.0, - // actionsIconTheme: IconThemeData( - // color: Colors.grey[800], - // ), - // ), - // ), initialRoute: SPLASH, + // initialRoute: CALL_PAGE, + // initialRoute: OPENTOK_CALL_PAGE, // initialRoute: PACKAGES_OFFERS, // initialRoute: PACKAGES_ORDER_COMPLETED, routes: routes, diff --git a/lib/models/Appointments/AppoimentAllHistoryResultList.dart b/lib/models/Appointments/AppoimentAllHistoryResultList.dart index 045f759e..ac37f555 100644 --- a/lib/models/Appointments/AppoimentAllHistoryResultList.dart +++ b/lib/models/Appointments/AppoimentAllHistoryResultList.dart @@ -1,25 +1,25 @@ class AppoitmentAllHistoryResultList { - String setupID; - int projectID; - int appointmentNo; - String appointmentDate; - dynamic appointmentDateN; - int appointmentType; - String bookDate; - int patientType; - int patientID; - int clinicID; - int doctorID; - String endDate; - String startTime; - String endTime; - int status; - int visitType; - int visitFor; - int patientStatusType; - int companyID; - int bookedBy; - String bookedOn; + String? setupID; + dynamic? projectID; + dynamic? appointmentNo; + String? appointmentDate; + dynamic? appointmentDateN; + dynamic? appointmentType; + String? bookDate; + dynamic? patientType; + dynamic? patientID; + dynamic? clinicID; + dynamic? doctorID; + String? endDate; + String? startTime; + String? endTime; + dynamic? status; + dynamic? visitType; + dynamic? visitFor; + dynamic? patientStatusType; + dynamic? companyID; + dynamic? bookedBy; + String? bookedOn; dynamic confirmedBy; dynamic confirmedOn; dynamic arrivalChangedBy; @@ -28,44 +28,45 @@ class AppoitmentAllHistoryResultList { dynamic editedOn; dynamic doctorName; dynamic doctorNameN; - String statusDesc; + String? statusDesc; dynamic statusDescN; - bool vitalStatus; + bool? vitalStatus; dynamic vitalSignAppointmentNo; - int episodeID; - int actualDoctorRate; - String clinicName; - bool complainExists; - String doctorImageURL; - String doctorNameObj; - int doctorRate; - List doctorSpeciality; - String doctorTitle; - int gender; - String genderDescription; - bool iSAllowOnlineCheckedIN; - bool isActiveDoctor; - bool isActiveDoctorProfile; - bool isDoctorAllowVedioCall; - bool isExecludeDoctor; - int isFollowup; - bool isLiveCareAppointment; - bool isInOutPatient; - bool isMedicalReportRequested; - bool isOnlineCheckedIN; - String latitude; + dynamic? episodeID; + dynamic? actualDoctorRate; + String? clinicName; + bool? complainExists; + String? doctorImageURL; + String? doctorNameObj; + dynamic? doctorRate; + dynamic decimalDoctorRate; + List? doctorSpeciality; + String? doctorTitle; + dynamic? gender; + String? genderDescription; + bool? iSAllowOnlineCheckedIN; + bool? isActiveDoctor; + bool? isActiveDoctorProfile; + bool? isDoctorAllowVedioCall; + bool? isExecludeDoctor; + dynamic? isFollowup; + bool? isLiveCareAppointment; + bool? isInOutPatient; + bool? isMedicalReportRequested; + bool? isOnlineCheckedIN; + String? latitude; dynamic listHISGetContactLensPerscription; dynamic listHISGetGlassPerscription; - String longitude; - int nextAction; - int noOfPatientsRate; - int originalClinicID; - int originalProjectID; - String projectName; - String qR; - int remaniningHoursTocanPay; - bool sMSButtonVisable; - int serviceID; + String? longitude; + dynamic? nextAction; + dynamic? noOfPatientsRate; + dynamic? originalClinicID; + dynamic? originalProjectID; + String? projectName; + String? qR; + int? remaniningHoursTocanPay; + bool? sMSButtonVisable; + dynamic? serviceID; AppoitmentAllHistoryResultList( {this.setupID, @@ -108,6 +109,7 @@ class AppoitmentAllHistoryResultList { this.doctorImageURL, this.doctorNameObj, this.doctorRate, + this.decimalDoctorRate, this.doctorSpeciality, this.doctorTitle, this.gender, @@ -176,6 +178,7 @@ class AppoitmentAllHistoryResultList { doctorImageURL = json['DoctorImageURL']; doctorNameObj = json['DoctorNameObj']; doctorRate = json['DoctorRate']; + decimalDoctorRate = json['DecimalDoctorRate']; doctorSpeciality = json['DoctorSpeciality'] != null ? json['DoctorSpeciality'].cast() : ["null"]; @@ -250,6 +253,7 @@ class AppoitmentAllHistoryResultList { data['DoctorImageURL'] = this.doctorImageURL; data['DoctorNameObj'] = this.doctorNameObj; data['DoctorRate'] = this.doctorRate; + data['DecimalDoctorRate'] = this.decimalDoctorRate; data['DoctorSpeciality'] = this.doctorSpeciality; data['DoctorTitle'] = this.doctorTitle; data['Gender'] = this.gender; @@ -283,12 +287,12 @@ class AppoitmentAllHistoryResultList { } class PatientAppointmentList { - String filterName = ""; - List patientDoctorAppointmentList = List(); + String? filterName = ""; + List? patientDoctorAppointmentList =[]; PatientAppointmentList( {this.filterName, - AppoitmentAllHistoryResultList patientDoctorAppointment}) { - patientDoctorAppointmentList.add(patientDoctorAppointment); + AppoitmentAllHistoryResultList? patientDoctorAppointment}) { + patientDoctorAppointmentList!.add(patientDoctorAppointment!); } } diff --git a/lib/models/Appointments/DentalChiefComplaintsModel.dart b/lib/models/Appointments/DentalChiefComplaintsModel.dart index c15b828a..8314723d 100644 --- a/lib/models/Appointments/DentalChiefComplaintsModel.dart +++ b/lib/models/Appointments/DentalChiefComplaintsModel.dart @@ -1,13 +1,13 @@ class DentalChiefComplaintsModel { - List listDentalChiefComplain; + List? listDentalChiefComplain; DentalChiefComplaintsModel({this.listDentalChiefComplain}); DentalChiefComplaintsModel.fromJson(Map json) { if (json['List_DentalChiefComplain'] != null) { - listDentalChiefComplain = new List(); + listDentalChiefComplain = []; json['List_DentalChiefComplain'].forEach((v) { - listDentalChiefComplain.add(new ListDentalChiefComplain.fromJson(v)); + listDentalChiefComplain!.add(new ListDentalChiefComplain.fromJson(v)); }); } } @@ -16,17 +16,17 @@ class DentalChiefComplaintsModel { final Map data = new Map(); if (this.listDentalChiefComplain != null) { data['List_DentalChiefComplain'] = - this.listDentalChiefComplain.map((v) => v.toJson()).toList(); + this.listDentalChiefComplain!.map((v) => v.toJson()).toList(); } return data; } } class ListDentalChiefComplain { - int projectID; - int iD; - String name; - String nameN; + int? projectID; + int? iD; + String? name; + String? nameN; ListDentalChiefComplain({this.projectID, this.iD, this.name, this.nameN}); diff --git a/lib/models/Appointments/DentalProceduresModel.dart b/lib/models/Appointments/DentalProceduresModel.dart new file mode 100644 index 00000000..ca8e5eba --- /dev/null +++ b/lib/models/Appointments/DentalProceduresModel.dart @@ -0,0 +1,76 @@ +class DentalProceduresModel { + List? listIsPatientHasOnGoingEstimation; + + DentalProceduresModel({this.listIsPatientHasOnGoingEstimation}); + + DentalProceduresModel.fromJson(Map json) { + if (json['List_IsPatientHasOnGoingEstimation'] != null) { + listIsPatientHasOnGoingEstimation = + []; + json['List_IsPatientHasOnGoingEstimation'].forEach((v) { + listIsPatientHasOnGoingEstimation! + .add(new ListIsPatientHasOnGoingEstimation.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + if (this.listIsPatientHasOnGoingEstimation != null) { + data['List_IsPatientHasOnGoingEstimation'] = this + .listIsPatientHasOnGoingEstimation! + .map((v) => v.toJson()) + .toList(); + } + return data; + } +} + +class ListIsPatientHasOnGoingEstimation { + dynamic setupID; + dynamic estimationNo; + int? projectID; + String? procedureId; + int? patientID; + int? sequenceNo; + int? neededTime; + String? procedureName; + dynamic procedureNameN; + + ListIsPatientHasOnGoingEstimation( + {this.setupID, + this.estimationNo, + this.projectID, + this.procedureId, + this.patientID, + this.sequenceNo, + this.neededTime, + this.procedureName, + this.procedureNameN}); + + ListIsPatientHasOnGoingEstimation.fromJson(Map json) { + setupID = json['SetupID']; + estimationNo = json['EstimationNo']; + projectID = json['ProjectID']; + procedureId = json['ProcedureId']; + patientID = json['PatientID']; + sequenceNo = json['sequenceNo']; + neededTime = json['NeededTime']; + procedureName = json['ProcedureName']; + procedureNameN = json['ProcedureNameN']; + } + + Map toJson() { + final Map data = new Map(); + data['SetupID'] = this.setupID; + data['EstimationNo'] = this.estimationNo; + data['ProjectID'] = this.projectID; + data['ProcedureId'] = this.procedureId; + data['PatientID'] = this.patientID; + data['sequenceNo'] = this.sequenceNo; + data['NeededTime'] = this.neededTime; + data['ProcedureName'] = this.procedureName; + data['ProcedureNameN'] = this.procedureNameN; + return data; + } +} diff --git a/lib/models/Appointments/DoctorListResponse.dart b/lib/models/Appointments/DoctorListResponse.dart index 4c7241c8..4dc65cfa 100644 --- a/lib/models/Appointments/DoctorListResponse.dart +++ b/lib/models/Appointments/DoctorListResponse.dart @@ -1,46 +1,62 @@ +import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; + class DoctorList { - int clinicID; - String clinicName; - String doctorTitle; - int iD; - String name; - int projectID; - String projectName; - int actualDoctorRate; - int clinicRoomNo; + int? clinicID; + dynamic appointmentNo; + String? clinicName; + String? doctorTitle; + num? iD; + String? name; + int? projectID; + String? projectName; + int? actualDoctorRate; + num? clinicRoomNo; dynamic date; + dynamic appointmentDate; dynamic dayName; - int doctorID; - String doctorImageURL; + int? doctorID; + String? doctorImageURL; dynamic doctorProfile; dynamic doctorProfileInfo; - int doctorRate; - int gender; - String genderDescription; - bool isAppointmentAllowed; - bool isDoctorAllowVedioCall; - bool isDoctorDummy; - bool isLiveCare; - String latitude; - String longitude; - String nationalityFlagURL; - String nationalityID; - String nationalityName; + int? doctorRate; + num? gender; + String? genderDescription; + bool? isAppointmentAllowed; + bool? isDoctorAllowVedioCall; + bool? isDoctorDummy; + bool? isLiveCare; + bool? isLiveCareClinic; + bool? isDoctorHasPrePostImages; + String? latitude; + String? longitude; + String? nationalityFlagURL; + String? nationalityID; + String? nationalityName; dynamic nearestFreeSlot; - int noOfPatientsRate; - int originalClinicID; - int personRate; + int? noOfPatientsRate; + num? originalClinicID; + num? personRate; dynamic projectDistanceInKiloMeters; - String qR; + String? qR; dynamic qRString; - int rateNumber; + num? rateNumber; dynamic serviceID; - String setupID; - List speciality; + String? setupID; + List? speciality; + List? specialityN; dynamic workingHours; + dynamic decimalDoctorRate; + String? projectBottomName; + String? projectTopName; + bool? isHMC; + String? region; + String? regionArabic; + String? regionEnglish; + String? regionID; DoctorList( {this.clinicID, + this.appointmentNo, this.clinicName, this.doctorTitle, this.iD, @@ -50,6 +66,7 @@ class DoctorList { this.actualDoctorRate, this.clinicRoomNo, this.date, + this.appointmentDate, this.dayName, this.doctorID, this.doctorImageURL, @@ -62,6 +79,8 @@ class DoctorList { this.isDoctorAllowVedioCall, this.isDoctorDummy, this.isLiveCare, + this.isLiveCareClinic, + this.isDoctorHasPrePostImages, this.latitude, this.longitude, this.nationalityFlagURL, @@ -78,19 +97,33 @@ class DoctorList { this.serviceID, this.setupID, this.speciality, - this.workingHours}); + this.specialityN, + this.workingHours, + this.decimalDoctorRate, + this.projectBottomName, + this.projectTopName, + this.isHMC, + this.region, + this.regionArabic, + this.regionEnglish, + this.regionID, + }); - DoctorList.fromJson(Map json) { + DoctorList.fromJson( + Map json, + ) { clinicID = json['ClinicID']; + appointmentNo = json['AppointmentNo']; clinicName = json['ClinicName']; doctorTitle = json['DoctorTitle']; iD = json['ID']; - name = json['DoctorName']??json['Name']; + name = json['DoctorName'] ?? json['Name']; projectID = json['ProjectID']; projectName = json['ProjectName']; actualDoctorRate = json['ActualDoctorRate']; clinicRoomNo = json['ClinicRoomNo']; date = json['Date']; + appointmentDate = json['AppointmentDate']; dayName = json['DayName']; doctorID = json['DoctorID']; doctorImageURL = json['DoctorImageURL']; @@ -103,6 +136,8 @@ class DoctorList { isDoctorAllowVedioCall = json['IsDoctorAllowVedioCall']; isDoctorDummy = json['IsDoctorDummy']; isLiveCare = json['IsLiveCare']; + isLiveCareClinic = json['IsLiveCareClinic']; + isDoctorHasPrePostImages = json['IsDoctorHasPrePostImages']; latitude = json['Latitude']; longitude = json['Longitude']; nationalityFlagURL = json['NationalityFlagURL']; @@ -118,14 +153,28 @@ class DoctorList { rateNumber = json['RateNumber']; serviceID = json['ServiceID']; setupID = json['SetupID']; - if (json.containsKey('Speciality') && json['Speciality']!=null) - speciality = json['Speciality'].cast(); + if (json.containsKey('Speciality') && json['Speciality'] != null) speciality = json['Speciality'].cast(); + if (json.containsKey('SpecialityN') && json['SpecialityN'] != null) specialityN = json['SpecialityN'].cast(); workingHours = json['WorkingHours']; + decimalDoctorRate = json['DecimalDoctorRate']; + projectBottomName = json['ProjectNameBottom']; + projectTopName = json['ProjectNameTop']; + this.isHMC = json["IsHMC"]; + this.regionArabic = json['RegionNameN']; + this.regionEnglish = json['RegionName']; + } + + String? getRegionName(bool isArabic) { + if (isArabic) { + return regionArabic; + } + return regionEnglish; } Map toJson() { final Map data = new Map(); data['ClinicID'] = this.clinicID; + data['AppointmentNo'] = this.appointmentNo; data['ClinicName'] = this.clinicName; data['DoctorTitle'] = this.doctorTitle; data['ID'] = this.iD; @@ -147,6 +196,8 @@ class DoctorList { data['IsDoctorAllowVedioCall'] = this.isDoctorAllowVedioCall; data['IsDoctorDummy'] = this.isDoctorDummy; data['IsLiveCare'] = this.isLiveCare; + data['IsLiveCareClinic'] = this.isLiveCareClinic; + data['IsDoctorHasPrePostImages'] = this.isDoctorHasPrePostImages; data['Latitude'] = this.latitude; data['Longitude'] = this.longitude; data['NationalityFlagURL'] = this.nationalityFlagURL; @@ -163,20 +214,212 @@ class DoctorList { data['ServiceID'] = this.serviceID; data['SetupID'] = this.setupID; data['Speciality'] = this.speciality; + data['SpecialityN'] = this.specialityN; data['WorkingHours'] = this.workingHours; + data['DecimalDoctorRate'] = this.decimalDoctorRate; return data; } + + String getProjectCompleteName(){ + return "${this.projectTopName} ${this.projectBottomName}"; + } + + String getProjectCompleteNameWithLocale({bool isArabic = false}) { + if (isArabic) { + return "${this.projectBottomName} ${this.projectTopName}"; + } + return "${this.projectTopName} ${this.projectBottomName}"; + } } class PatientDoctorAppointmentList { - String filterName = ""; - String distanceInKMs = ""; - List patientDoctorAppointmentList = List(); + String? filterName = ""; + String? distanceInKMs = ""; + List? patientDoctorAppointmentList = []; + String? projectTopName = ""; + String? projectBottomName = ""; + bool? isHMC; + List hospitalList = []; PatientDoctorAppointmentList( {this.filterName, this.distanceInKMs, - DoctorList patientDoctorAppointment}) { - patientDoctorAppointmentList.add(patientDoctorAppointment); + this.projectTopName, + this.projectBottomName, + DoctorList? patientDoctorAppointment, + HospitalsModel? model, + this.isHMC = false}) { + if (model != null) { + hospitalList.add(model); + } + if (patientDoctorAppointment != null) { + patientDoctorAppointmentList!.add(patientDoctorAppointment!); + } } } + +// class PatientDoctorAppointmentListByRegion { +// String? filterName = ""; +// String? distanceInKMs = ""; +// List? hmgDoctorList = []; +// List? hmcDoctorList = []; +// String? projectTopName = ""; +// String? projectBottomName = ""; +// +// PatientDoctorAppointmentListByRegion({this.filterName, this.distanceInKMs, this.projectTopName, this.projectBottomName, DoctorList? hmcPatientDoctorAppointment, DoctorList? hmgPatientDoctorAppointment}) { +// hmcDoctorList!.add(hmcPatientDoctorAppointment!); +// hmgDoctorList!.add(hmgPatientDoctorAppointment!); +// } +// } + +class PatientDoctorAppointmentListByRegion { + List? hmgDoctorList = []; + List? hmcDoctorList = []; + int hmcSize = 0; + int hmgSize = 0; + num distance = double.infinity; + num hmgDistance = double.infinity; + num hmcDistance = double.infinity; +} + +class RegionList { + Map? registeredDoctorMap = {}; +} + +/// dummy data +/// +/// + +DoctorList doctor1 = DoctorList( + clinicID: 101, + appointmentNo: 12345, + clinicName: "Downtown Clinic", + doctorTitle: "Dr.", + iD: 1, + name: "John Doe", + projectID: 301, + projectName: "HealthCare Network", + actualDoctorRate: 500, + clinicRoomNo: 2, + date: "2025-01-10", + appointmentDate: "2025-01-15T10:00:00", + dayName: "Monday", + doctorID: 11, + doctorImageURL: "https://example.com/images/johndoe.jpg", + doctorProfile: null, + doctorProfileInfo: null, + doctorRate: 4, + gender: 1, + genderDescription: "Male", + isAppointmentAllowed: true, + isDoctorAllowVedioCall: false, + isDoctorDummy: false, + isLiveCare: true, + isLiveCareClinic: false, + isDoctorHasPrePostImages: true, + latitude: "24.7136", + longitude: "46.6753", + nationalityFlagURL: "https://example.com/images/flags/sa.png", + nationalityID: "SA", + nationalityName: "Saudi Arabia", + nearestFreeSlot: "2025-01-15T10:00:00", + noOfPatientsRate: 50, + originalClinicID: 102, + personRate: 4.5, + projectDistanceInKiloMeters: 5.0, + qR: "QR123", + qRString: "abcd1234", + rateNumber: 120, + serviceID: null, + setupID: "Setup001", + speciality: ["Cardiology", "Internal Medicine"], + specialityN: ["Cardiology"], + workingHours: "8 AM - 5 PM", + decimalDoctorRate: 4.5, + projectBottomName: "HealthCare Bottom", + projectTopName: "HealthCare Top", + isHMC: false, + region: "Riyadh", +); + +DoctorList doctor2 = DoctorList( + clinicID: 102, + appointmentNo: 67890, + clinicName: "City Medical Center", + doctorTitle: "Dr.", + iD: 2, + name: "Jane Smith", + projectID: 302, + projectName: "MedicalGroup Network", + actualDoctorRate: 450, + clinicRoomNo: 5, + date: "2025-01-12", + appointmentDate: "2025-01-16T09:00:00", + dayName: "Wednesday", + doctorID: 12, + doctorImageURL: "https://example.com/images/janesmith.jpg", + doctorProfile: null, + doctorProfileInfo: null, + doctorRate: 5, + gender: 2, + genderDescription: "Female", + isAppointmentAllowed: true, + isDoctorAllowVedioCall: true, + isDoctorDummy: false, + isLiveCare: false, + isLiveCareClinic: true, + isDoctorHasPrePostImages: false, + latitude: "24.7742", + longitude: "46.7387", + nationalityFlagURL: "https://example.com/images/flags/us.png", + nationalityID: "US", + nationalityName: "United States", + nearestFreeSlot: "2025-01-16T09:00:00", + noOfPatientsRate: 70, + originalClinicID: 103, + personRate: 4.8, + projectDistanceInKiloMeters: 8.0, + qR: "QR567", + qRString: "efgh5678", + rateNumber: 200, + serviceID: null, + setupID: "Setup002", + speciality: ["Dermatology", "Cosmetic Surgery"], + specialityN: ["Dermatology"], + workingHours: "9 AM - 6 PM", + decimalDoctorRate: 4.8, + projectBottomName: "MedicalGroup Bottom", + projectTopName: "MedicalGroup Top", + isHMC: true, + region: "Riyadh", +); + +// Dummy data for PatientDoctorAppointmentList +PatientDoctorAppointmentList patientList1 = PatientDoctorAppointmentList( + filterName: "Aryan", + distanceInKMs: "0", + projectTopName: "HealthCare", + projectBottomName: "Center", + patientDoctorAppointment: doctor1, +); + +PatientDoctorAppointmentList patientList2 = PatientDoctorAppointmentList( + filterName: "Aryan", + distanceInKMs: "0", + projectTopName: "MedicalGroup", + projectBottomName: "Clinic", + patientDoctorAppointment: doctor2, +); + +// Dummy data for PatientDoctorAppointmentListByRegion +PatientDoctorAppointmentListByRegion region1 = + PatientDoctorAppointmentListByRegion() + ..hmgDoctorList = [patientList1] + ..hmcDoctorList = [patientList2]; + +// Dummy data for RegionList +RegionList regionList = RegionList() + ..registeredDoctorMap = { + "Region1": region1, + "Region2": region1, + }; \ No newline at end of file diff --git a/lib/models/Appointments/DoctorProfile.dart b/lib/models/Appointments/DoctorProfile.dart index bfc8c189..b78281a5 100644 --- a/lib/models/Appointments/DoctorProfile.dart +++ b/lib/models/Appointments/DoctorProfile.dart @@ -1,45 +1,47 @@ class DoctorProfileList { - int doctorID; - String doctorName; - Null doctorNameN; - int clinicID; - String clinicDescription; - Null clinicDescriptionN; - Null licenseExpiry; - int employmentType; - Null setupID; - int projectID; - String projectName; - String nationalityID; - String nationalityName; - Null nationalityNameN; - int gender; - String genderDescription; - Null genderDescriptionN; - Null doctorTitle; - Null projectNameN; - bool isAllowWaitList; - String titleDescription; - Null titleDescriptionN; - Null isRegistered; - Null isDoctorDummy; - bool isActive; - Null isDoctorAppointmentDisplayed; - bool doctorClinicActive; - Null isbookingAllowed; - String doctorCases; - Null doctorPicture; - String doctorProfileInfo; - List specialty; - int actualDoctorRate; - String doctorImageURL; - int doctorRate; - String doctorTitleForProfile; - bool isAppointmentAllowed; - String nationalityFlagURL; - int noOfPatientsRate; - String qR; - int serviceID; + num? doctorID; + String? doctorName; + dynamic doctorNameN; + num? clinicID; + String? clinicDescription; + dynamic clinicDescriptionN; + dynamic licenseExpiry; + num? employmentType; + dynamic setupID; + num? projectID; + String? projectName; + String? nationalityID; + String? nationalityName; + dynamic nationalityNameN; + num? gender; + String? genderDescription; + dynamic genderDescriptionN; + dynamic doctorTitle; + dynamic projectNameN; + bool? isAllowWaitList; + String? titleDescription; + dynamic titleDescriptionN; + dynamic isRegistered; + dynamic isDoctorDummy; + bool? isActive; + bool? isDoctorHasPrePostImages; + dynamic isDoctorAppointmentDisplayed; + bool? doctorClinicActive; + dynamic isbookingAllowed; + String? doctorCases; + dynamic doctorPicture; + String? doctorProfileInfo; + List? specialty; + num? actualDoctorRate; + String? doctorImageURL; + num? doctorRate; + num? decimalDoctorRate; + String? doctorTitleForProfile; + bool? isAppointmentAllowed; + String? nationalityFlagURL; + int? noOfPatientsRate; + String? qR; + num? serviceID; DoctorProfileList( {this.doctorID, @@ -67,6 +69,7 @@ class DoctorProfileList { this.isRegistered, this.isDoctorDummy, this.isActive, + this.isDoctorHasPrePostImages, this.isDoctorAppointmentDisplayed, this.doctorClinicActive, this.isbookingAllowed, @@ -77,6 +80,7 @@ class DoctorProfileList { this.actualDoctorRate, this.doctorImageURL, this.doctorRate, + this.decimalDoctorRate, this.doctorTitleForProfile, this.isAppointmentAllowed, this.nationalityFlagURL, @@ -110,16 +114,18 @@ class DoctorProfileList { isRegistered = json['IsRegistered']; isDoctorDummy = json['IsDoctorDummy']; isActive = json['IsActive']; + isDoctorHasPrePostImages = json['IsDoctorHasPrePostImages']; isDoctorAppointmentDisplayed = json['IsDoctorAppointmentDisplayed']; doctorClinicActive = json['DoctorClinicActive']; isbookingAllowed = json['IsbookingAllowed']; doctorCases = json['DoctorCases']; doctorPicture = json['DoctorPicture']; doctorProfileInfo = json['DoctorProfileInfo']; - specialty = json['Specialty'].cast(); + specialty = json['Specialty'] != null ? json['Specialty'].cast() : [""]; actualDoctorRate = json['ActualDoctorRate']; doctorImageURL = json['DoctorImageURL']; doctorRate = json['DoctorRate']; + decimalDoctorRate = json['DecimalDoctorRate']; doctorTitleForProfile = json['DoctorTitleForProfile']; isAppointmentAllowed = json['IsAppointmentAllowed']; nationalityFlagURL = json['NationalityFlagURL']; @@ -155,6 +161,7 @@ class DoctorProfileList { data['IsRegistered'] = this.isRegistered; data['IsDoctorDummy'] = this.isDoctorDummy; data['IsActive'] = this.isActive; + data['IsDoctorHasPrePostImages'] = this.isDoctorHasPrePostImages; data['IsDoctorAppointmentDisplayed'] = this.isDoctorAppointmentDisplayed; data['DoctorClinicActive'] = this.doctorClinicActive; data['IsbookingAllowed'] = this.isbookingAllowed; @@ -165,6 +172,7 @@ class DoctorProfileList { data['ActualDoctorRate'] = this.actualDoctorRate; data['DoctorImageURL'] = this.doctorImageURL; data['DoctorRate'] = this.doctorRate; + data['DecimalDoctorRate'] = this.decimalDoctorRate; data['DoctorTitleForProfile'] = this.doctorTitleForProfile; data['IsAppointmentAllowed'] = this.isAppointmentAllowed; data['NationalityFlagURL'] = this.nationalityFlagURL; diff --git a/lib/models/Appointments/DoctorRateDetails.dart b/lib/models/Appointments/DoctorRateDetails.dart index b29a5db9..58668856 100644 --- a/lib/models/Appointments/DoctorRateDetails.dart +++ b/lib/models/Appointments/DoctorRateDetails.dart @@ -4,13 +4,15 @@ class DoctorRateDetails { dynamic clinicID; dynamic rate; dynamic patientNumber; + dynamic ratio; DoctorRateDetails( {this.doctorID, this.projectID, this.clinicID, this.rate, - this.patientNumber}); + this.patientNumber, + this.ratio}); DoctorRateDetails.fromJson(Map json) { doctorID = json['DoctorID']; @@ -18,6 +20,7 @@ class DoctorRateDetails { clinicID = json['ClinicID']; rate = json['Rate']; patientNumber = json['PatientNumber']; + ratio = json['Ratio']; } Map toJson() { @@ -27,6 +30,7 @@ class DoctorRateDetails { data['ClinicID'] = this.clinicID; data['Rate'] = this.rate; data['PatientNumber'] = this.patientNumber; + data['Ratio'] = this.ratio; return data; } } diff --git a/lib/models/Appointments/InsertAppointmentRequest.dart b/lib/models/Appointments/InsertAppointmentRequest.dart index 383e2eb5..719f6ff9 100644 --- a/lib/models/Appointments/InsertAppointmentRequest.dart +++ b/lib/models/Appointments/InsertAppointmentRequest.dart @@ -1,20 +1,20 @@ import 'package:diplomaticquarterapp/models/Request.dart'; class InsertAppointmentRequest extends Request { - String AppointmentDate; // ???? "/Date(1577750400000)/" - int DoctorID; - int InitialSlotDuration; - String SelectedTime; - String StartTime; - String EndTime; - String TempValue; - int VisitFor; - int VisitType; - bool IsVirtual; - List GeneralProcedureList; - String DeviceToken; - bool IsForLiveCare; - String OriginalClinicID; - String OriginalProjectID; + String? AppointmentDate; // ???? "/Date(1577750400000)/" + int? DoctorID; + int? InitialSlotDuration; + String? SelectedTime; + String? StartTime; + String? EndTime; + String? TempValue; + int? VisitFor; + int? VisitType; + bool? IsVirtual; + List? GeneralProcedureList; + String? DeviceToken; + bool? IsForLiveCare; + String? OriginalClinicID; + String? OriginalProjectID; } diff --git a/lib/models/Appointments/OBGyneProcedureListResponse.dart b/lib/models/Appointments/OBGyneProcedureListResponse.dart new file mode 100644 index 00000000..6af282b5 --- /dev/null +++ b/lib/models/Appointments/OBGyneProcedureListResponse.dart @@ -0,0 +1,136 @@ +class OBGyneProcedureListResponse { + String? setupID; + int? projectID; + int? episodeID; + int? appointmentNo; + int? orderNo; + String? procedureId; + int? lineItemNo; + String? orderDate; + int? orderType; + int? patientType; + int? patientID; + int? price; + int? orderStatus; + bool? isApprovalRequired; + bool? isApprovalCreated; + bool? isInvoiced; + bool? isReferralInvoiced; + bool? isEROrder; + bool? isCash; + int? uniqueRowID; + int? status; + int? clinicID; + int? doctorID; + String? procedureName; + String? procedureNameN; + String? clinicDescription; + String? clinicDescriptionN; + String? doctorName; + String? doctorNameN; + String? projectDescription; + String? projectDescriptionN; + + OBGyneProcedureListResponse( + {this.setupID, + this.projectID, + this.episodeID, + this.appointmentNo, + this.orderNo, + this.procedureId, + this.lineItemNo, + this.orderDate, + this.orderType, + this.patientType, + this.patientID, + this.price, + this.orderStatus, + this.isApprovalRequired, + this.isApprovalCreated, + this.isInvoiced, + this.isReferralInvoiced, + this.isEROrder, + this.isCash, + this.uniqueRowID, + this.status, + this.clinicID, + this.doctorID, + this.procedureName, + this.procedureNameN, + this.clinicDescription, + this.clinicDescriptionN, + this.doctorName, + this.doctorNameN, + this.projectDescription, + this.projectDescriptionN}); + + OBGyneProcedureListResponse.fromJson(Map json) { + setupID = json['SetupID']; + projectID = json['ProjectID']; + episodeID = json['EpisodeID']; + appointmentNo = json['AppointmentNo']; + orderNo = json['OrderNo']; + procedureId = json['ProcedureId']; + lineItemNo = json['LineItemNo']; + orderDate = json['OrderDate']; + orderType = json['OrderType']; + patientType = json['PatientType']; + patientID = json['PatientID']; + price = json['Price']; + orderStatus = json['OrderStatus']; + isApprovalRequired = json['IsApprovalRequired']; + isApprovalCreated = json['IsApprovalCreated']; + isInvoiced = json['IsInvoiced']; + isReferralInvoiced = json['IsReferralInvoiced']; + isEROrder = json['IsEROrder']; + isCash = json['IsCash']; + uniqueRowID = json['UniqueRowID']; + status = json['Status']; + clinicID = json['ClinicID']; + doctorID = json['DoctorID']; + procedureName = json['ProcedureName']; + procedureNameN = json['ProcedureNameN']; + clinicDescription = json['ClinicDescription']; + clinicDescriptionN = json['ClinicDescriptionN']; + doctorName = json['DoctorName']; + doctorNameN = json['DoctorNameN']; + projectDescription = json['ProjectDescription']; + projectDescriptionN = json['ProjectDescriptionN']; + } + + Map toJson() { + final Map data = new Map(); + data['SetupID'] = this.setupID; + data['ProjectID'] = this.projectID; + data['EpisodeID'] = this.episodeID; + data['AppointmentNo'] = this.appointmentNo; + data['OrderNo'] = this.orderNo; + data['ProcedureId'] = this.procedureId; + data['LineItemNo'] = this.lineItemNo; + data['OrderDate'] = this.orderDate; + data['OrderType'] = this.orderType; + data['PatientType'] = this.patientType; + data['PatientID'] = this.patientID; + data['Price'] = this.price; + data['OrderStatus'] = this.orderStatus; + data['IsApprovalRequired'] = this.isApprovalRequired; + data['IsApprovalCreated'] = this.isApprovalCreated; + data['IsInvoiced'] = this.isInvoiced; + data['IsReferralInvoiced'] = this.isReferralInvoiced; + data['IsEROrder'] = this.isEROrder; + data['IsCash'] = this.isCash; + data['UniqueRowID'] = this.uniqueRowID; + data['Status'] = this.status; + data['ClinicID'] = this.clinicID; + data['DoctorID'] = this.doctorID; + data['ProcedureName'] = this.procedureName; + data['ProcedureNameN'] = this.procedureNameN; + data['ClinicDescription'] = this.clinicDescription; + data['ClinicDescriptionN'] = this.clinicDescriptionN; + data['DoctorName'] = this.doctorName; + data['DoctorNameN'] = this.doctorNameN; + data['ProjectDescription'] = this.projectDescription; + data['ProjectDescriptionN'] = this.projectDescriptionN; + return data; + } +} diff --git a/hms-plugins/flutter-hms-location/ios/Assets/.gitkeep b/lib/models/Appointments/PatientPackageComponent similarity index 100% rename from hms-plugins/flutter-hms-location/ios/Assets/.gitkeep rename to lib/models/Appointments/PatientPackageComponent diff --git a/lib/models/Appointments/PatientPackageComponent.dart b/lib/models/Appointments/PatientPackageComponent.dart new file mode 100644 index 00000000..26ce9229 --- /dev/null +++ b/lib/models/Appointments/PatientPackageComponent.dart @@ -0,0 +1,59 @@ +class PatientPackageComponent { + List? patientPackageComponents; + + PatientPackageComponent({this.patientPackageComponents}); + + PatientPackageComponent.fromJson(Map json) { + if (json['PatientPackageComponents'] != null) { + patientPackageComponents = []; + json['PatientPackageComponents'].forEach((v) { + patientPackageComponents!.add(new PatientPackageComponents.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + if (this.patientPackageComponents != null) { + data['PatientPackageComponents'] = this.patientPackageComponents!.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class PatientPackageComponents { + int? invoiceNo; + int? lineItemNo; + String? procedureID; + String? procedureName; + int? projectID; + int? sequence; + String? setupID; + num? invoiceNo_VP; + + PatientPackageComponents({this.invoiceNo, this.lineItemNo, this.procedureID, this.procedureName, this.projectID, this.sequence, this.setupID, this.invoiceNo_VP}); + + PatientPackageComponents.fromJson(Map json) { + invoiceNo = json['InvoiceNo']; + lineItemNo = json['LineItemNo']; + procedureID = json['ProcedureID']; + procedureName = json['ProcedureName']; + projectID = json['ProjectID']; + sequence = json['Sequence']; + setupID = json['SetupID']; + invoiceNo_VP = json['InvoiceNo_VP']; + } + + Map toJson() { + final Map data = new Map(); + data['InvoiceNo'] = this.invoiceNo; + data['LineItemNo'] = this.lineItemNo; + data['ProcedureID'] = this.procedureID; + data['ProcedureName'] = this.procedureName; + data['ProjectID'] = this.projectID; + data['Sequence'] = this.sequence; + data['SetupID'] = this.setupID; + data['InvoiceNo_VP'] = this.invoiceNo_VP; + return data; + } +} diff --git a/lib/models/Appointments/PatientShareResposne.dart b/lib/models/Appointments/PatientShareResposne.dart index 40670990..ef0dd7c9 100644 --- a/lib/models/Appointments/PatientShareResposne.dart +++ b/lib/models/Appointments/PatientShareResposne.dart @@ -1,54 +1,54 @@ class PatientShareResponse { - int advanceNumber; + int? advanceNumber; dynamic appointmentDate; - int appointmentNo; - int cashPrice; - int cashPriceTax; - int cashPriceWithTax; - int clinicID; + int? appointmentNo; + int? cashPrice; + int? cashPriceTax; + int? cashPriceWithTax; + int? clinicID; dynamic clinicName; - int companyId; + int? companyId; dynamic companyName; - int companyShareWithTax; + int? companyShareWithTax; dynamic doctorImageURL; dynamic doctorNameObj; - int doctorID; - List doctorSpeciality; + int? doctorID; + List? doctorSpeciality; dynamic errCode; - int groupID; - bool iSAllowOnlineCheckedIN; + int? groupID; + bool? iSAllowOnlineCheckedIN; dynamic insurancePolicyNo; - bool isExcludedForOnlineCheckin; - int isFollowup; - bool isLiveCareAppointment; - bool isOnlineCheckedIN; + bool? isExcludedForOnlineCheckin; + int? isFollowup; + bool? isLiveCareAppointment; + bool? isOnlineCheckedIN; dynamic message; - int nextAction; + int? nextAction; dynamic patientCardID; - int patientID; + int? patientID; dynamic patientShare; dynamic patientShareWithTax; - int patientStatusType; + int? patientStatusType; dynamic patientTaxAmount; dynamic patientType; - int paymentAmount; + int? paymentAmount; dynamic paymentDate; dynamic paymentMethodName; dynamic paymentReferenceNumber; - int policyId; + int? policyId; dynamic policyName; dynamic procedureName; - int projectID; + int? projectID; dynamic projectName; dynamic setupID; - int sourceType; + int? sourceType; dynamic startTime; - int status; - int statusCode; + int? status; + int? statusCode; dynamic statusDesc; dynamic subPolicyNo; - int userID; - int serviceID; + int? userID; + int? serviceID; PatientShareResponse( {this.advanceNumber, diff --git a/lib/models/Appointments/SearchInfoModel.dart b/lib/models/Appointments/SearchInfoModel.dart index f5500bca..ee1faf90 100644 --- a/lib/models/Appointments/SearchInfoModel.dart +++ b/lib/models/Appointments/SearchInfoModel.dart @@ -1,10 +1,16 @@ +import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; +import 'package:diplomaticquarterapp/models/Clinics/ClinicListResponse.dart'; + class SearchInfo { - int ProjectID; - int ClinicID; - String DoctorName; - String SelectedDate; - String SelectedTime; - String currentLat; - String currentLong; - DateTime date; + int? ProjectID; + int? ClinicID; + String? DoctorName; + String? SelectedDate; + String? SelectedTime; + String? currentLat; + String? currentLong; + DateTime? date; + + HospitalsModel? hospital; + ListClinicCentralized? clinic; } diff --git a/lib/models/Appointments/appoDetailsButtons.dart b/lib/models/Appointments/appoDetailsButtons.dart index adce8b93..faec136a 100644 --- a/lib/models/Appointments/appoDetailsButtons.dart +++ b/lib/models/Appointments/appoDetailsButtons.dart @@ -1,8 +1,8 @@ class AppoDetailsButton { - String title; - String subtitle; - String icon; - String caller; + String? title; + String? subtitle; + String? icon; + String? caller; AppoDetailsButton({this.title, this.subtitle, this.icon, this.caller}); diff --git a/lib/models/Appointments/doctor_pre_post_image.dart b/lib/models/Appointments/doctor_pre_post_image.dart new file mode 100644 index 00000000..96a738bd --- /dev/null +++ b/lib/models/Appointments/doctor_pre_post_image.dart @@ -0,0 +1,107 @@ +import 'dart:convert'; +import 'dart:typed_data'; + +import 'package:diplomaticquarterapp/uitl/utils.dart'; + +class DoctorPrePostImages { + DoctorPrePostImageModel? pre; + DoctorPrePostImageModel? post; + + Uint8List getPreBytes(){ + try{ + var b64 = pre!.imageStr!.replaceFirst('data:image/png;base64,', ''); + if(pre!.imageStr != null && isBase64(b64)) + return Utils.dataFromBase64String(b64); + }catch(e){ + + } + return Uint8List(0); + } + + Uint8List getPostBytes(){ + try{ + var b64 = post!.imageStr!.replaceFirst('data:image/png;base64,', ''); + if(post!.imageStr != null && isBase64(b64)) + return Utils.dataFromBase64String(b64); + }catch(e){ + + } + return Uint8List(0); + } + + bool isBase64(String str) { + RegExp _base64 = RegExp( + r'^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{4})$'); + return _base64.hasMatch(str); + } +} + +class DoctorPrePostImageModel { + String? setupID; + int? projectID; + int? clinicId; + int? doctorId; + int? lineItemNo; + String? imageStr; + int? imageType; + String? description; + dynamic isNewUpdated; + bool? isActive; + String? createdOn; + int? createdBy; + dynamic editedOn; + dynamic editedBy; + + DoctorPrePostImageModel({ + this.setupID, + this.projectID, + this.clinicId, + this.doctorId, + this.lineItemNo, + this.imageStr, + this.imageType, + this.description, + this.isNewUpdated, + this.isActive, + this.createdOn, + this.createdBy, + this.editedOn, + this.editedBy}); + + DoctorPrePostImageModel.fromJson(dynamic json) { + setupID = json["SetupID"]; + projectID = json["ProjectID"]; + clinicId = json["ClinicId"]; + doctorId = json["DoctorId"]; + lineItemNo = json["LineItemNo"]; + imageStr = json["ImageStr"]; + imageType = json["ImageType"]; + description = json["Description"]; + isNewUpdated = json["IsNewUpdated"]; + isActive = json["IsActive"]; + createdOn = json["CreatedOn"]; + createdBy = json["CreatedBy"]; + editedOn = json["EditedOn"]; + editedBy = json["EditedBy"]; + } + + Map toJson() { + var map = {}; + map["SetupID"] = setupID; + map["ProjectID"] = projectID; + map["ClinicId"] = clinicId; + map["DoctorId"] = doctorId; + map["LineItemNo"] = lineItemNo; + map["ImageStr"] = imageStr; + map["ImageType"] = imageType; + map["Description"] = description; + map["IsNewUpdated"] = isNewUpdated; + map["IsActive"] = isActive; + map["CreatedOn"] = createdOn; + map["CreatedBy"] = createdBy; + map["EditedOn"] = editedOn; + map["EditedBy"] = editedBy; + return map; + } + +} \ No newline at end of file diff --git a/lib/models/Appointments/laser_body_parts.dart b/lib/models/Appointments/laser_body_parts.dart new file mode 100644 index 00000000..d7d3fbd1 --- /dev/null +++ b/lib/models/Appointments/laser_body_parts.dart @@ -0,0 +1,64 @@ +class LaserBodyPart { + int? id; + int? category; + String? bodyPart; + bool? fullBoadyPart; + bool? isRetouch; + String? timeDuration; + String? bodyPartN; + bool? isActive; + String? mappingCode; + int? procedureID; + int? orderNum; + String? categoryName; + String? categoryNameN; + + LaserBodyPart( + {this.id, + this.category, + this.bodyPart, + this.fullBoadyPart, + this.isRetouch, + this.timeDuration, + this.bodyPartN, + this.isActive, + this.mappingCode, + this.procedureID, + this.orderNum, + this.categoryName, + this.categoryNameN}); + + LaserBodyPart.fromJson(Map json) { + id = json['Id']; + category = json['Category']; + bodyPart = json['BodyPart']; + fullBoadyPart = json['FullBoadyPart']; + isRetouch = json['IsRetouch']; + timeDuration = json['TimeDuration']; + bodyPartN = json['BodyPartN']; + isActive = json['IsActive']; + mappingCode = json['MappingCode']; + procedureID = json['ProcedureID']; + orderNum = json['OrderNum']; + categoryName = json['CategoryName']; + categoryNameN = json['CategoryNameN']; + } + + Map toJson() { + final Map data = new Map(); + data['Id'] = this.id; + data['Category'] = this.category; + data['BodyPart'] = this.bodyPart; + data['FullBoadyPart'] = this.fullBoadyPart; + data['IsRetouch'] = this.isRetouch; + data['TimeDuration'] = this.timeDuration; + data['BodyPartN'] = this.bodyPartN; + data['IsActive'] = this.isActive; + data['MappingCode'] = this.mappingCode; + data['ProcedureID'] = this.procedureID; + data['OrderNum'] = this.orderNum; + data['CategoryName'] = this.categoryName; + data['CategoryNameN'] = this.categoryNameN; + return data; + } +} diff --git a/lib/models/Appointments/timeSlot.dart b/lib/models/Appointments/timeSlot.dart index 58926fac..ccddc2d9 100644 --- a/lib/models/Appointments/timeSlot.dart +++ b/lib/models/Appointments/timeSlot.dart @@ -1,10 +1,10 @@ import 'package:flutter/cupertino.dart'; class TimeSlot { - String isoTime; - DateTime start; - DateTime end; - - TimeSlot({@required this.isoTime, @required this.start, @required this.end}); + String? isoTime; + DateTime? start; + DateTime? end; + String? vidaDate; + TimeSlot({@required this.isoTime, @required this.start, @required this.end, this.vidaDate}); } diff --git a/lib/models/Appointments/toDoCountProviderModel.dart b/lib/models/Appointments/toDoCountProviderModel.dart index e44a0ebb..0418424c 100644 --- a/lib/models/Appointments/toDoCountProviderModel.dart +++ b/lib/models/Appointments/toDoCountProviderModel.dart @@ -1,16 +1,25 @@ import 'package:flutter/cupertino.dart'; class ToDoCountProviderModel with ChangeNotifier { - int _count; - bool _isShowBadge = false; - int get count => _count == null ? 0 : _count; + int? _count; + int? _ancillaryCount; + String? _notificationsCount; + bool? _isShowBadge = false; - bool get isShowBadge => _isShowBadge; - void setState(int count, bool isShowBadge) { + int? get count => _count == null ? 0 : _count!; + int? get ancillaryCount => _ancillaryCount == null ? 0 : _ancillaryCount; + + String? get notificationsCount => _notificationsCount == null ? "0" : _notificationsCount; + + bool get isShowBadge => _isShowBadge!; + + void setState(int? count, int? ancillaryCount, bool? isShowBadge, String? notifCount) { _count = count; _isShowBadge = isShowBadge; + _notificationsCount = notifCount; + _ancillaryCount = ancillaryCount; notifyListeners(); } -} +} \ No newline at end of file diff --git a/lib/models/Authentication/authenticated_user.dart b/lib/models/Authentication/authenticated_user.dart index 4c7974a3..0d2b3544 100644 --- a/lib/models/Authentication/authenticated_user.dart +++ b/lib/models/Authentication/authenticated_user.dart @@ -1,131 +1,132 @@ import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; class AuthenticatedUser { - String setupID; - int patientType; - int patientID; - String firstName; - String middleName; - String lastName; - String firstNameN; - String middleNameN; - String lastNameN; - int relationshipID; - int gender; - String dateofBirth; - DateTime dateofBirthDataTime; + String? setupID; + int? patientType; + int? patientID; + String? firstName; + String? middleName; + String? lastName; + String? firstNameN; + String? middleNameN; + String? lastNameN; + int? relationshipID; + int? gender; + String? dateofBirth; + DateTime? dateofBirthDataTime; dynamic dateofBirthN; - String nationalityID; + String? nationalityID; dynamic phoneResi; dynamic phoneOffice; - String mobileNumber; + String? mobileNumber; dynamic faxNumber; - String emailAddress; + String? emailAddress; dynamic bloodGroup; dynamic rHFactor; - bool isEmailAlertRequired; - bool isSMSAlertRequired; - String preferredLanguage; - bool isPrivilegedMember; + bool? isEmailAlertRequired; + bool? isSMSAlertRequired; + String? preferredLanguage; + bool? isPrivilegedMember; dynamic memberID; dynamic expiryDate; dynamic isHmgEmployee; dynamic employeeID; dynamic emergencyContactName; dynamic emergencyContactNo; - int patientPayType; + int? patientPayType; dynamic dHCCPatientRefID; - bool isPatientDummy; - int status; + bool? isPatientDummy; + int? status; dynamic isStatusCleared; - int patientIdentificationType; - String patientIdentificationNo; - int projectID; - int infoSourceID; + int? patientIdentificationType; + String? patientIdentificationNo; + int? projectID; + int? infoSourceID; dynamic address; - int age; - String ageDesc; - int areaID; - int createdBy; - String genderDescription; + int? age; + String? ageDesc; + int? areaID; + int? createdBy; + String? genderDescription; dynamic iR; dynamic iSOCityID; dynamic iSOCountryID; - List listPrivilege; + List? listPrivilege; dynamic marital; - int outSA; + int? outSA; dynamic pOBox; - bool receiveHealthSummaryReport; - int sourceType; + bool? receiveHealthSummaryReport; + int? sourceType; dynamic strDateofBirth; dynamic tempAddress; dynamic zipCode; dynamic isFamily; + dynamic cRSVerificationStatus; // dynamic patientPayType; // dynamic patientType; // dynamic status; - AuthenticatedUser({ - this.setupID, - this.patientType, - this.patientID, - this.firstName, - this.middleName, - this.lastName, - this.firstNameN, - this.middleNameN, - this.lastNameN, - this.relationshipID, - this.gender, - this.dateofBirth, - this.dateofBirthN, - this.nationalityID, - this.phoneResi, - this.phoneOffice, - this.mobileNumber, - this.faxNumber, - this.emailAddress, - this.bloodGroup, - this.rHFactor, - this.isEmailAlertRequired, - this.isSMSAlertRequired, - this.preferredLanguage, - this.isPrivilegedMember, - this.memberID, - this.expiryDate, - this.isHmgEmployee, - this.employeeID, - this.emergencyContactName, - this.emergencyContactNo, - this.patientPayType, - this.dHCCPatientRefID, - this.isPatientDummy, - this.status, - this.isStatusCleared, - this.patientIdentificationType, - this.patientIdentificationNo, - this.projectID, - this.infoSourceID, - this.address, - this.age, - this.ageDesc, - this.areaID, - this.createdBy, - this.genderDescription, - this.iR, - this.iSOCityID, - this.iSOCountryID, - this.listPrivilege, - this.marital, - this.outSA, - this.pOBox, - this.receiveHealthSummaryReport, - this.sourceType, - this.strDateofBirth, - this.tempAddress, - this.zipCode, - this.isFamily - }); + AuthenticatedUser( + {this.setupID, + this.patientType, + this.patientID, + this.firstName, + this.middleName, + this.lastName, + this.firstNameN, + this.middleNameN, + this.lastNameN, + this.relationshipID, + this.gender, + this.dateofBirth, + this.dateofBirthN, + this.nationalityID, + this.phoneResi, + this.phoneOffice, + this.mobileNumber, + this.faxNumber, + this.emailAddress, + this.bloodGroup, + this.rHFactor, + this.isEmailAlertRequired, + this.isSMSAlertRequired, + this.preferredLanguage, + this.isPrivilegedMember, + this.memberID, + this.expiryDate, + this.isHmgEmployee, + this.employeeID, + this.emergencyContactName, + this.emergencyContactNo, + this.patientPayType, + this.dHCCPatientRefID, + this.isPatientDummy, + this.status, + this.isStatusCleared, + this.patientIdentificationType, + this.patientIdentificationNo, + this.projectID, + this.infoSourceID, + this.address, + this.age, + this.ageDesc, + this.areaID, + this.createdBy, + this.genderDescription, + this.iR, + this.iSOCityID, + this.iSOCountryID, + this.listPrivilege, + this.marital, + this.outSA, + this.pOBox, + this.receiveHealthSummaryReport, + this.sourceType, + this.strDateofBirth, + this.tempAddress, + this.zipCode, + this.isFamily, + this.cRSVerificationStatus}); AuthenticatedUser.fromJson(Map json) { setupID = json['SetupID']; @@ -179,9 +180,9 @@ class AuthenticatedUser { iSOCityID = json['ISOCityID']; iSOCountryID = json['ISOCountryID']; if (json['ListPrivilege'] != null) { - listPrivilege = new List(); + listPrivilege = []; json['ListPrivilege'].forEach((v) { - listPrivilege.add(new ListPrivilege.fromJson(v)); + listPrivilege!.add(new ListPrivilege.fromJson(v)); }); } marital = json['Marital']; @@ -193,6 +194,7 @@ class AuthenticatedUser { tempAddress = json['TempAddress']; zipCode = json['ZipCode']; isFamily = json['IsFamily']; + cRSVerificationStatus = json['CRSVerificationStatus']; } Map toJson() { @@ -248,7 +250,7 @@ class AuthenticatedUser { data['ISOCountryID'] = this.iSOCountryID; if (this.listPrivilege != null) { data['ListPrivilege'] = - this.listPrivilege.map((v) => v.toJson()).toList(); + this.listPrivilege!.map((v) => v.toJson()).toList(); } data['Marital'] = this.marital; data['OutSA'] = this.outSA; @@ -259,14 +261,15 @@ class AuthenticatedUser { data['TempAddress'] = this.tempAddress; data['ZipCode'] = this.zipCode; data['IsFamily'] = this.isFamily; + data['CRSVerificationStatus'] = this.cRSVerificationStatus; return data; } } class ListPrivilege { - int iD; - String serviceName; - bool previlege; + int? iD; + String? serviceName; + bool? previlege; dynamic region; ListPrivilege({this.iD, this.serviceName, this.previlege, this.region}); diff --git a/lib/models/Authentication/check_activation_code_request.dart b/lib/models/Authentication/check_activation_code_request.dart index af139ba5..8d2cd71e 100644 --- a/lib/models/Authentication/check_activation_code_request.dart +++ b/lib/models/Authentication/check_activation_code_request.dart @@ -1,53 +1,55 @@ class CheckActivationCodeReq { - int patientMobileNumber; - String mobileNo; - String deviceToken; - bool projectOutSA; - int loginType; - String zipCode; - bool isRegister; - String logInTokenID; - int searchType; - int patientID; - String nationalID; - String patientIdentificationID; - String activationCode; - bool isSilentLogin; - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - Null sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; - bool forRegisteration; - CheckActivationCodeReq( - {this.patientMobileNumber, - this.mobileNo, - this.deviceToken, - this.projectOutSA, - this.loginType, - this.zipCode, - this.isRegister, - this.logInTokenID, - this.searchType, - this.patientID, - this.nationalID, - this.patientIdentificationID, - this.activationCode, - this.isSilentLogin, - this.versionID, - this.channel, - this.languageID, - this.iPAdress, - this.generalid, - this.patientOutSA, - this.sessionID, - this.isDentalAllowedBackend, - this.deviceTypeID, - this.forRegisteration}); + int? patientMobileNumber; + String? mobileNo; + String? deviceToken; + bool? projectOutSA; + int? loginType; + String? zipCode; + bool? isRegister; + String? logInTokenID; + int? searchType; + int? patientID; + String? nationalID; + String? patientIdentificationID; + String? activationCode; + bool? isSilentLogin; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + dynamic sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + bool? forRegisteration; + + CheckActivationCodeReq({ + this.patientMobileNumber, + this.mobileNo, + this.deviceToken, + this.projectOutSA, + this.loginType, + this.zipCode, + this.isRegister, + this.logInTokenID, + this.searchType, + this.patientID, + this.nationalID, + this.patientIdentificationID, + this.activationCode, + this.isSilentLogin, + this.versionID, + this.channel, + // this.languageID, + this.iPAdress, + this.generalid, + this.patientOutSA, + this.sessionID, + this.isDentalAllowedBackend, + this.deviceTypeID, + this.forRegisteration, + }); CheckActivationCodeReq.fromJson(Map json) { patientMobileNumber = json['PatientMobileNumber']; @@ -66,7 +68,7 @@ class CheckActivationCodeReq { isSilentLogin = json['IsSilentLogin']; versionID = json['VersionID']; channel = json['Channel']; - languageID = json['LanguageID']; + // languageID = json['LanguageID']; iPAdress = json['IPAdress']; generalid = json['generalid']; patientOutSA = json['PatientOutSA']; @@ -94,7 +96,7 @@ class CheckActivationCodeReq { data['IsSilentLogin'] = this.isSilentLogin; data['VersionID'] = this.versionID; data['Channel'] = this.channel; - data['LanguageID'] = this.languageID; + // data['LanguageID'] = this.languageID; data['IPAdress'] = this.iPAdress; data['generalid'] = this.generalid; data['PatientOutSA'] = this.patientOutSA; @@ -102,6 +104,7 @@ class CheckActivationCodeReq { data['isDentalAllowedBackend'] = this.isDentalAllowedBackend; data['DeviceTypeID'] = this.deviceTypeID; data['ForRegisteration'] = this.forRegisteration; + return data; } } diff --git a/lib/models/Authentication/check_activation_code_request_register.dart b/lib/models/Authentication/check_activation_code_request_register.dart new file mode 100644 index 00000000..85e1f56f --- /dev/null +++ b/lib/models/Authentication/check_activation_code_request_register.dart @@ -0,0 +1,121 @@ +class CheckActivationCodeRegisterReq { + int? patientMobileNumber; + String? mobileNo; + String? deviceToken; + bool? projectOutSA; + int? loginType; + String? zipCode; + bool? isRegister; + String? logInTokenID; + int? searchType; + int? patientID; + String? nationalID; + String? patientIdentificationID; + String? activationCode; + bool? isSilentLogin; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + dynamic sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + bool? forRegisteration; + String? dob; + int? isHijri; + String? healthId; + + CheckActivationCodeRegisterReq({ + this.patientMobileNumber, + this.mobileNo, + this.deviceToken, + this.projectOutSA, + this.loginType, + this.zipCode, + this.isRegister, + this.logInTokenID, + this.searchType, + this.patientID, + this.nationalID, + this.patientIdentificationID, + this.activationCode, + this.isSilentLogin, + this.versionID, + this.channel, + this.languageID, + this.iPAdress, + this.generalid, + this.patientOutSA, + this.sessionID, + this.isDentalAllowedBackend, + this.deviceTypeID, + this.forRegisteration, + this.dob, + this.isHijri, + this.healthId, + }); + + CheckActivationCodeRegisterReq.fromJson(Map json) { + patientMobileNumber = json['PatientMobileNumber']; + mobileNo = json['MobileNo']; + deviceToken = json['DeviceToken']; + projectOutSA = json['ProjectOutSA']; + loginType = json['LoginType']; + zipCode = json['ZipCode']; + isRegister = json['isRegister']; + logInTokenID = json['LogInTokenID']; + searchType = json['SearchType']; + patientID = json['PatientID']; + nationalID = json['NationalID']; + patientIdentificationID = json['PatientIdentificationID']; + activationCode = json['activationCode']; + isSilentLogin = json['IsSilentLogin']; + versionID = json['VersionID']; + channel = json['Channel']; + languageID = json['LanguageID']; + iPAdress = json['IPAdress']; + generalid = json['generalid']; + patientOutSA = json['PatientOutSA']; + sessionID = json['SessionID']; + isDentalAllowedBackend = json['isDentalAllowedBackend']; + deviceTypeID = json['DeviceTypeID']; + forRegisteration = json['ForRegisteration']; + dob = json['DOB']; + isHijri = json['IsHijri']; + healthId = json['HealthId']; + } + + Map toJson() { + final Map data = new Map(); + data['PatientMobileNumber'] = this.patientMobileNumber; + data['MobileNo'] = this.mobileNo; + data['DeviceToken'] = this.deviceToken; + data['ProjectOutSA'] = this.projectOutSA; + data['LoginType'] = this.loginType; + data['ZipCode'] = this.zipCode; + data['isRegister'] = this.isRegister; + data['LogInTokenID'] = this.logInTokenID; + data['SearchType'] = this.searchType; + data['PatientID'] = this.patientID; + data['NationalID'] = this.nationalID; + data['PatientIdentificationID'] = this.patientIdentificationID; + data['activationCode'] = this.activationCode; + data['IsSilentLogin'] = this.isSilentLogin; + data['VersionID'] = this.versionID; + data['Channel'] = this.channel; + data['LanguageID'] = this.languageID; + data['IPAdress'] = this.iPAdress; + data['generalid'] = this.generalid; + data['PatientOutSA'] = this.patientOutSA; + data['SessionID'] = this.sessionID; + data['isDentalAllowedBackend'] = this.isDentalAllowedBackend; + data['DeviceTypeID'] = this.deviceTypeID; + data['ForRegisteration'] = this.forRegisteration; + data['DOB'] = dob; + data['IsHijri'] = isHijri; + data['HealthId'] = healthId; + return data; + } +} diff --git a/lib/models/Authentication/check_activation_code_response.dart b/lib/models/Authentication/check_activation_code_response.dart index 3a0aed65..2fa18a5e 100644 --- a/lib/models/Authentication/check_activation_code_response.dart +++ b/lib/models/Authentication/check_activation_code_response.dart @@ -2,26 +2,26 @@ import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.da class CheckActivationCode { dynamic date; - int languageID; - int serviceName; + int? languageID; + int? serviceName; dynamic time; dynamic androidLink; - String authenticationTokenID; + String? authenticationTokenID; dynamic data; - bool dataw; - int dietType; + bool? dataw; + int? dietType; dynamic errorCode; dynamic errorEndUserMessage; dynamic errorEndUserMessageN; dynamic errorMessage; - int errorType; - int foodCategory; + int? errorType; + int? foodCategory; dynamic iOSLink; - bool isAuthenticated; - int mealOrderStatus; - int mealType; - int messageStatus; - int numberOfResultRecords; + bool? isAuthenticated; + int? mealOrderStatus; + int? mealType; + int? messageStatus; + int? numberOfResultRecords; dynamic patientBlodType; dynamic successMsg; dynamic successMsgN; @@ -29,11 +29,11 @@ class CheckActivationCode { dynamic getAllPendingRecordsList; dynamic getAllSharedRecordsByStatusList; dynamic getResponseFileList; - bool isHMGPatient; - bool isLoginSuccessfully; - bool isNeedUpdateIdintificationNo; - bool kioskSendSMS; - AuthenticatedUser list; + bool? isHMGPatient; + bool? isLoginSuccessfully; + bool? isNeedUpdateIdintificationNo; + bool? kioskSendSMS; + AuthenticatedUser? list; dynamic listAskHabibMobileLoginInfo; dynamic listAskHabibPatientFile; dynamic listMergeFiles; @@ -41,29 +41,29 @@ class CheckActivationCode { dynamic listPatientCount; dynamic logInTokenID; dynamic mohemmPrivilegeList; - int pateintID; - String patientBloodType; - bool patientHasFile; + int? pateintID; + String? patientBloodType; + bool? patientHasFile; dynamic patientMergedIDs; - bool patientOutSA; - int patientShareRequestID; - int patientType; - int projectIDOut; + bool? patientOutSA; + int? patientShareRequestID; + int? patientType; + int? projectIDOut; dynamic returnMessage; - bool sMSLoginRequired; + bool? sMSLoginRequired; dynamic servicePrivilegeList; dynamic sharePatientName; dynamic verificationCode; dynamic email; dynamic errorList; - bool hasFile; - bool isActiveCode; - bool isMerged; - bool isNeedUserAgreement; - bool isSMSSent; + bool? hasFile; + bool? isActiveCode; + bool? isMerged; + bool? isNeedUserAgreement; + bool? isSMSSent; dynamic memberList; dynamic message; - int statusCode; + int? statusCode; CheckActivationCode( {this.date, @@ -271,61 +271,61 @@ class CheckActivationCode { } class List { - String setupID; - int patientType; - int patientID; - String firstName; - String middleName; - String lastName; - String firstNameN; - String middleNameN; - String lastNameN; - int relationshipID; - int gender; - String dateofBirth; + String? setupID; + int? patientType; + int? patientID; + String? firstName; + String? middleName; + String? lastName; + String? firstNameN; + String? middleNameN; + String? lastNameN; + int? relationshipID; + int? gender; + String? dateofBirth; dynamic dateofBirthN; - String nationalityID; + String? nationalityID; dynamic phoneResi; dynamic phoneOffice; - String mobileNumber; + String? mobileNumber; dynamic faxNumber; - String emailAddress; + String? emailAddress; dynamic bloodGroup; dynamic rHFactor; - bool isEmailAlertRequired; - bool isSMSAlertRequired; - String preferredLanguage; - bool isPrivilegedMember; + bool? isEmailAlertRequired; + bool? isSMSAlertRequired; + String? preferredLanguage; + bool? isPrivilegedMember; dynamic memberID; dynamic expiryDate; dynamic isHmgEmployee; dynamic employeeID; dynamic emergencyContactName; dynamic emergencyContactNo; - int patientPayType; + int? patientPayType; dynamic dHCCPatientRefID; - bool isPatientDummy; - int status; + bool? isPatientDummy; + int? status; dynamic isStatusCleared; - int patientIdentificationType; - String patientIdentificationNo; - int projectID; - int infoSourceID; + int? patientIdentificationType; + String? patientIdentificationNo; + int? projectID; + int? infoSourceID; dynamic address; - int age; - String ageDesc; - int areaID; - int createdBy; - String genderDescription; + int? age; + String? ageDesc; + int? areaID; + int? createdBy; + String? genderDescription; dynamic iR; dynamic iSOCityID; dynamic iSOCountryID; - ListPrivilege listPrivilege; + ListPrivilege? listPrivilege; dynamic marital; - int outSA; + int? outSA; dynamic pOBox; - bool receiveHealthSummaryReport; - int sourceType; + bool? receiveHealthSummaryReport; + int? sourceType; dynamic strDateofBirth; dynamic tempAddress; dynamic zipCode; @@ -522,9 +522,9 @@ class List { } class ListPrivilege { - int iD; - String serviceName; - bool previlege; + int? iD; + String? serviceName; + bool? previlege; dynamic region; ListPrivilege({this.iD, this.serviceName, this.previlege, this.region}); diff --git a/lib/models/Authentication/check_paitent_authentication_req.dart b/lib/models/Authentication/check_paitent_authentication_req.dart index 2846c1fc..8aa348c1 100644 --- a/lib/models/Authentication/check_paitent_authentication_req.dart +++ b/lib/models/Authentication/check_paitent_authentication_req.dart @@ -1,21 +1,23 @@ class CheckPatientAuthenticationReq { - int patientMobileNumber; - String zipCode; - bool isRegister; - String tokenID; - int searchType; - String patientIdentificationID; - int patientID; - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - Null sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; - + int? patientMobileNumber; + String? zipCode; + bool? isRegister; + String? tokenID; + int? searchType; + String? patientIdentificationID; + int? patientID; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + dynamic sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + String? dob; + int? isHijri; + String? healthId; CheckPatientAuthenticationReq( {this.patientMobileNumber, this.zipCode, @@ -32,7 +34,11 @@ class CheckPatientAuthenticationReq { this.patientOutSA, this.sessionID, this.isDentalAllowedBackend, - this.deviceTypeID}); + this.deviceTypeID, + this.dob, + this.isHijri, + this.healthId + }); CheckPatientAuthenticationReq.fromJson(Map json) { patientMobileNumber = json['PatientMobileNumber']; @@ -51,6 +57,9 @@ class CheckPatientAuthenticationReq { sessionID = json['SessionID']; isDentalAllowedBackend = json['isDentalAllowedBackend']; deviceTypeID = json['DeviceTypeID']; + dob = json['dob']; + isHijri = json['isHijri']; + healthId = json['HealthId']; } Map toJson() { @@ -71,6 +80,9 @@ class CheckPatientAuthenticationReq { data['SessionID'] = this.sessionID; data['isDentalAllowedBackend'] = this.isDentalAllowedBackend; data['DeviceTypeID'] = this.deviceTypeID; + data['dob'] =this.dob; + data['isHijri'] = this.isHijri; + data['HealthId'] = healthId; return data; } } diff --git a/lib/models/Authentication/check_user_status_reponse.dart b/lib/models/Authentication/check_user_status_reponse.dart index 342eaad0..0701c8b3 100644 --- a/lib/models/Authentication/check_user_status_reponse.dart +++ b/lib/models/Authentication/check_user_status_reponse.dart @@ -1,80 +1,80 @@ class CheckUserStatusResponse { - Null date; - int languageID; - int serviceName; - Null time; - Null androidLink; - Null authenticationTokenID; - Null data; - bool dataw; - int dietType; - Null errorCode; - Null errorEndUserMessage; - Null errorEndUserMessageN; - Null errorMessage; - int errorType; - int foodCategory; - Null iOSLink; - bool isAuthenticated; - int mealOrderStatus; - int mealType; - int messageStatus; - int numberOfResultRecords; - Null patientBlodType; - Null successMsg; - Null successMsgN; - Null accessTokenObject; - int age; - Null clientIdentifierId; - int createdBy; - String dateOfBirth; - String firstNameAr; - String firstNameEn; - String gender; - Null genderAr; - Null genderEn; - String healthId; - String idNumber; - String idType; - bool isHijri; - int isInstertedOrUpdated; - int isNull; - int isPatientExistNHIC; - String lastNameAr; - String lastNameEn; - Null listActiveAccessToken; - String maritalStatus; - String maritalStatusCode; - String nationality; - String nationalityCode; - String occupation; - String patientStatus; - String placeofBirth; - Null practitionerStatusCode; - Null practitionerStatusDescAr; - Null practitionerStatusDescEn; - String secondNameAr; - String secondNameEn; - String thirdNameAr; - String thirdNameEn; - Null accessToken; - int categoryCode; - Null categoryNameAr; - Null categoryNameEn; - int constraintCode; - Null constraintNameAr; - Null constraintNameEn; - Null content; - Null licenseExpiryDate; - Null licenseIssuedDate; - Null licenseStatusCode; - Null licenseStatusDescAr; - Null licenseStatusDescEn; - Null organizations; - Null registrationNumber; - int specialtyCode; - Null specialtyNameAr; - Null specialtyNameEn; + dynamic date; + int? languageID; + int? serviceName; + dynamic time; + dynamic androidLink; + dynamic authenticationTokenID; + dynamic data; + bool? dataw; + int? dietType; + dynamic errorCode; + dynamic errorEndUserMessage; + dynamic errorEndUserMessageN; + dynamic errorMessage; + int? errorType; + int? foodCategory; + dynamic iOSLink; + bool? isAuthenticated; + int? mealOrderStatus; + int? mealType; + int? messageStatus; + int? numberOfResultRecords; + dynamic patientBlodType; + dynamic successMsg; + dynamic successMsgN; + dynamic accessTokenObject; + int? age; + dynamic clientIdentifierId; + int? createdBy; + String? dateOfBirth; + String? firstNameAr; + String? firstNameEn; + String? gender; + dynamic genderAr; + dynamic genderEn; + String? healthId; + String? idNumber; + String? idType; + bool? isHijri; + int? isInstertedOrUpdated; + int? isdynamic; + int? isPatientExistNHIC; + String? lastNameAr; + String? lastNameEn; + dynamic listActiveAccessToken; + String? maritalStatus; + String? maritalStatusCode; + String? nationality; + String? nationalityCode; + String? occupation; + String? patientStatus; + String? placeofBirth; + dynamic practitionerStatusCode; + dynamic practitionerStatusDescAr; + dynamic practitionerStatusDescEn; + String? secondNameAr; + String? secondNameEn; + String? thirdNameAr; + String? thirdNameEn; + dynamic accessToken; + int? categoryCode; + dynamic categoryNameAr; + dynamic categoryNameEn; + int? constraintCode; + dynamic constraintNameAr; + dynamic constraintNameEn; + dynamic content; + dynamic licenseExpiryDate; + dynamic licenseIssuedDate; + dynamic licenseStatusCode; + dynamic licenseStatusDescAr; + dynamic licenseStatusDescEn; + dynamic organizations; + dynamic registrationNumber; + int? specialtyCode; + dynamic specialtyNameAr; + dynamic specialtyNameEn; CheckUserStatusResponse( {this.date, @@ -116,7 +116,7 @@ class CheckUserStatusResponse { this.idType, this.isHijri, this.isInstertedOrUpdated, - this.isNull, + this.isdynamic, this.isPatientExistNHIC, this.lastNameAr, this.lastNameEn, @@ -194,7 +194,7 @@ class CheckUserStatusResponse { idType = json['IdType']; isHijri = json['IsHijri']; isInstertedOrUpdated = json['IsInstertedOrUpdated']; - isNull = json['IsNull']; + isdynamic = json['Isdynamic']; isPatientExistNHIC = json['IsPatientExistNHIC']; lastNameAr = json['LastNameAr']; lastNameEn = json['LastNameEn']; @@ -274,7 +274,7 @@ class CheckUserStatusResponse { data['IdType'] = this.idType; data['IsHijri'] = this.isHijri; data['IsInstertedOrUpdated'] = this.isInstertedOrUpdated; - data['IsNull'] = this.isNull; + data['Isdynamic'] = this.isdynamic; data['IsPatientExistNHIC'] = this.isPatientExistNHIC; data['LastNameAr'] = this.lastNameAr; data['LastNameEn'] = this.lastNameEn; diff --git a/lib/models/Authentication/check_user_status_req.dart b/lib/models/Authentication/check_user_status_req.dart index 40dd8b49..69f94fd6 100644 --- a/lib/models/Authentication/check_user_status_req.dart +++ b/lib/models/Authentication/check_user_status_req.dart @@ -1,16 +1,16 @@ class CheckUserStatusRequest { - String patientIdentificationID; - String dOB; - int isHijri; - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - Null sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; + String? patientIdentificationID; + String? dOB; + int? isHijri; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + dynamic sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; CheckUserStatusRequest( {this.patientIdentificationID, diff --git a/lib/models/Authentication/checkpatient_for_registration.dart b/lib/models/Authentication/checkpatient_for_registration.dart index 420b4adb..fa23df5f 100644 --- a/lib/models/Authentication/checkpatient_for_registration.dart +++ b/lib/models/Authentication/checkpatient_for_registration.dart @@ -1,19 +1,21 @@ class CheckPatientForRegistration { - int patientIdentificationID; - int patientMobileNumber; - String zipCode; - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - Null sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; - String tokenID; - int patientID; - bool isRegister; + int? patientIdentificationID; + int? patientMobileNumber; + String? zipCode; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + dynamic sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + String? tokenID; + int? patientID; + bool? isRegister; + String? dob; + int? isHijri; CheckPatientForRegistration( {this.patientIdentificationID, @@ -30,7 +32,9 @@ class CheckPatientForRegistration { this.deviceTypeID, this.tokenID, this.patientID, - this.isRegister}); + this.isRegister, + this.dob, + this.isHijri}); CheckPatientForRegistration.fromJson(Map json) { patientIdentificationID = json['PatientIdentificationID']; @@ -48,6 +52,8 @@ class CheckPatientForRegistration { tokenID = json['TokenID']; patientID = json['PatientID']; isRegister = json['isRegister']; + dob = json['DOB']; + isHijri = json['IsHijri']; } Map toJson() { @@ -67,6 +73,8 @@ class CheckPatientForRegistration { data['TokenID'] = this.tokenID; data['PatientID'] = this.patientID; data['isRegister'] = this.isRegister; + data['DOB'] = dob; + data['IsHijri'] = isHijri; return data; } } diff --git a/lib/models/Authentication/countries_list.dart b/lib/models/Authentication/countries_list.dart new file mode 100644 index 00000000..157e9291 --- /dev/null +++ b/lib/models/Authentication/countries_list.dart @@ -0,0 +1,21 @@ +class CountriesLists { + String? iD; + String? name; + dynamic nameN; + + CountriesLists({this.iD, this.name, this.nameN}); + + CountriesLists.fromJson(Map json) { + iD = json['ID']; + name = json['Name']; + nameN = json['NameN']; + } + + Map toJson() { + final Map data = new Map(); + data['ID'] = this.iD; + data['Name'] = this.name; + data['NameN'] = this.nameN; + return data; + } +} \ No newline at end of file diff --git a/lib/models/Authentication/get_mobile_info_request.dart b/lib/models/Authentication/get_mobile_info_request.dart index 51a58d88..07025c35 100644 --- a/lib/models/Authentication/get_mobile_info_request.dart +++ b/lib/models/Authentication/get_mobile_info_request.dart @@ -1,25 +1,25 @@ class GetMobileLoginInfoRequest { - int patientMobileNumber; - String mobileNo; - String deviceToken; - int projectOutSA; - int loginType; - String zipCode; - bool isRegister; - String logInTokenID; - int searchType; - int patientID; - String nationalID; - String patientIdentificationID; - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - Null sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; + int? patientMobileNumber; + String? mobileNo; + String? deviceToken; + int? projectOutSA; + int? loginType; + String? zipCode; + bool? isRegister; + String? logInTokenID; + int? searchType; + int? patientID; + String? nationalID; + String? patientIdentificationID; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + dynamic sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; GetMobileLoginInfoRequest( {this.patientMobileNumber, diff --git a/lib/models/Authentication/get_mobile_info_response.dart b/lib/models/Authentication/get_mobile_info_response.dart index 562c82dd..3b41300a 100644 --- a/lib/models/Authentication/get_mobile_info_response.dart +++ b/lib/models/Authentication/get_mobile_info_response.dart @@ -1,67 +1,67 @@ class GetMobileLoginInfoResponse { - Null date; - int languageID; - int serviceName; - Null time; - Null androidLink; - Null authenticationTokenID; - Null data; - bool dataw; - int dietType; - Null errorCode; - Null errorEndUserMessage; - Null errorEndUserMessageN; - Null errorMessage; - int errorType; - int foodCategory; - Null iOSLink; - bool isAuthenticated; - int mealOrderStatus; - int mealType; - int messageStatus; - int numberOfResultRecords; - Null patientBlodType; - Null successMsg; - Null successMsgN; - Null doctorInformationList; - Null getAllPendingRecordsList; - Null getAllSharedRecordsByStatusList; - Null getResponseFileList; - bool isHMGPatient; - bool isLoginSuccessfully; - bool isNeedUpdateIdintificationNo; - bool kioskSendSMS; - Null list; - Null listAskHabibMobileLoginInfo; - Null listAskHabibPatientFile; - Null listMergeFiles; - List listMobileLoginInfo; - Null listPatientCount; - String logInTokenID; - Null mohemmPrivilegeList; - int pateintID; - Null patientBloodType; - bool patientHasFile; - Null patientMergedIDs; - bool patientOutSA; - int patientShareRequestID; - int patientType; - int projectIDOut; - Null returnMessage; - bool sMSLoginRequired; - Null servicePrivilegeList; - Null sharePatientName; - Null verificationCode; - Null email; - Null errorList; - bool hasFile; - bool isActiveCode; - bool isMerged; - bool isNeedUserAgreement; - bool isSMSSent; - Null memberList; - Null message; - int statusCode; + dynamic date; + int? languageID; + int? serviceName; + dynamic time; + dynamic androidLink; + dynamic authenticationTokenID; + dynamic data; + bool? dataw; + int? dietType; + dynamic errorCode; + dynamic errorEndUserMessage; + dynamic errorEndUserMessageN; + dynamic errorMessage; + int? errorType; + int? foodCategory; + dynamic iOSLink; + bool? isAuthenticated; + int? mealOrderStatus; + int? mealType; + int? messageStatus; + int? numberOfResultRecords; + dynamic patientBlodType; + dynamic successMsg; + dynamic successMsgN; + dynamic doctorInformationList; + dynamic getAllPendingRecordsList; + dynamic getAllSharedRecordsByStatusList; + dynamic getResponseFileList; + bool? isHMGPatient; + bool? isLoginSuccessfully; + bool? isNeedUpdateIdintificationNo; + bool? kioskSendSMS; + dynamic list; + dynamic listAskHabibMobileLoginInfo; + dynamic listAskHabibPatientFile; + dynamic listMergeFiles; + List? listMobileLoginInfo; + dynamic listPatientCount; + String? logInTokenID; + dynamic mohemmPrivilegeList; + int? pateintID; + dynamic patientBloodType; + bool? patientHasFile; + dynamic patientMergedIDs; + bool? patientOutSA; + int? patientShareRequestID; + int? patientType; + int? projectIDOut; + dynamic returnMessage; + bool? sMSLoginRequired; + dynamic servicePrivilegeList; + dynamic sharePatientName; + dynamic verificationCode; + dynamic email; + dynamic errorList; + bool? hasFile; + bool? isActiveCode; + bool? isMerged; + bool? isNeedUserAgreement; + bool? isSMSSent; + dynamic memberList; + dynamic message; + int? statusCode; GetMobileLoginInfoResponse( {this.date, @@ -166,9 +166,9 @@ class GetMobileLoginInfoResponse { listAskHabibPatientFile = json['List_AskHabibPatientFile']; listMergeFiles = json['List_MergeFiles']; if (json['List_MobileLoginInfo'] != null) { - listMobileLoginInfo = new List(); + listMobileLoginInfo = []; json['List_MobileLoginInfo'].forEach((v) { - listMobileLoginInfo.add(new ListMobileLoginInfo.fromJson(v)); + listMobileLoginInfo!.add(new ListMobileLoginInfo.fromJson(v)); }); } listPatientCount = json['List_PatientCount']; @@ -240,7 +240,7 @@ class GetMobileLoginInfoResponse { data['List_MergeFiles'] = this.listMergeFiles; if (this.listMobileLoginInfo != null) { data['List_MobileLoginInfo'] = - this.listMobileLoginInfo.map((v) => v.toJson()).toList(); + this.listMobileLoginInfo!.map((v) => v.toJson()).toList(); } data['List_PatientCount'] = this.listPatientCount; data['LogInTokenID'] = this.logInTokenID; @@ -273,8 +273,8 @@ class GetMobileLoginInfoResponse { } class ListMobileLoginInfo { - int iD; - int loginType; + int? iD; + int? loginType; ListMobileLoginInfo({this.iD, this.loginType}); diff --git a/lib/models/Authentication/get_patient_occupation_list_response.dart b/lib/models/Authentication/get_patient_occupation_list_response.dart new file mode 100644 index 00000000..60a21dc6 --- /dev/null +++ b/lib/models/Authentication/get_patient_occupation_list_response.dart @@ -0,0 +1,22 @@ +class GetPatientOccupationListResponse { + String? occupationID; + String? description; + String? descriptionN; + + GetPatientOccupationListResponse( + {this.occupationID, this.description, this.descriptionN}); + + GetPatientOccupationListResponse.fromJson(Map json) { + occupationID = json['OccupationID']; + description = json['Description']; + descriptionN = json['DescriptionN']; + } + + Map toJson() { + final Map data = new Map(); + data['OccupationID'] = this.occupationID; + data['Description'] = this.description; + data['DescriptionN'] = this.descriptionN; + return data; + } +} diff --git a/lib/models/Authentication/insert_device_imei_request.dart b/lib/models/Authentication/insert_device_imei_request.dart index 02e3b278..82902fe3 100644 --- a/lib/models/Authentication/insert_device_imei_request.dart +++ b/lib/models/Authentication/insert_device_imei_request.dart @@ -1,19 +1,19 @@ class INSERTDeviceIMEIRequest { - String setupID; - int patientType; - int patientID; - String firstName; - String firstNameN; - String lastNameN; - int preferredLanguage; - String patientIdentificationNo; - bool outSA; - String identificationNo; - String mobileNo; - String tokenID; - String iMEI; - bool biometricEnabled; - int logInTypeID; + String? setupID; + int? patientType; + int? patientID; + String? firstName; + String? firstNameN; + String? lastNameN; + int? preferredLanguage; + String? patientIdentificationNo; + bool? outSA; + String? identificationNo; + String? mobileNo; + String? tokenID; + String? iMEI; + bool? biometricEnabled; + int? logInTypeID; INSERTDeviceIMEIRequest( {this.setupID, diff --git a/lib/models/Authentication/register_info_response.dart b/lib/models/Authentication/register_info_response.dart index 309a8aa9..1c8973d6 100644 --- a/lib/models/Authentication/register_info_response.dart +++ b/lib/models/Authentication/register_info_response.dart @@ -1,80 +1,81 @@ class RegisterInfoResponse { - Null date; - int languageID; - int serviceName; - Null time; - Null androidLink; - Null authenticationTokenID; - Null data; - bool dataw; - int dietType; - Null errorCode; - Null errorEndUserMessage; - Null errorEndUserMessageN; - Null errorMessage; - int errorType; - int foodCategory; - Null iOSLink; - bool isAuthenticated; - int mealOrderStatus; - int mealType; - int messageStatus; - int numberOfResultRecords; - Null patientBlodType; - Null successMsg; - Null successMsgN; - Null accessTokenObject; - int age; - Null clientIdentifierId; - int createdBy; - String dateOfBirth; - String firstNameAr; - String firstNameEn; - String gender; - Null genderAr; - Null genderEn; - String healthId; - String idNumber; - String idType; - bool isHijri; - int isInstertedOrUpdated; - int isNull; - int isPatientExistNHIC; - String lastNameAr; - String lastNameEn; - Null listActiveAccessToken; - String maritalStatus; - String maritalStatusCode; - String nationality; - String nationalityCode; - String occupation; - String patientStatus; - String placeofBirth; - Null practitionerStatusCode; - Null practitionerStatusDescAr; - Null practitionerStatusDescEn; - String secondNameAr; - String secondNameEn; - String thirdNameAr; - String thirdNameEn; - Null accessToken; - int categoryCode; - Null categoryNameAr; - Null categoryNameEn; - int constraintCode; - Null constraintNameAr; - Null constraintNameEn; - Null content; - Null licenseExpiryDate; - Null licenseIssuedDate; - Null licenseStatusCode; - Null licenseStatusDescAr; - Null licenseStatusDescEn; - Null organizations; - Null registrationNumber; - int specialtyCode; - Null specialtyNameAr; - Null specialtyNameEn; + dynamic date; + int? languageID; + int? serviceName; + dynamic time; + dynamic androidLink; + dynamic authenticationTokenID; + dynamic data; + bool? dataw; + int? dietType; + dynamic errorCode; + dynamic errorEndUserMessage; + dynamic errorEndUserMessageN; + dynamic errorMessage; + int? errorType; + int? foodCategory; + dynamic iOSLink; + bool? isAuthenticated; + int? mealOrderStatus; + int? mealType; + int? messageStatus; + int? numberOfResultRecords; + dynamic patientBlodType; + dynamic successMsg; + dynamic successMsgN; + dynamic accessTokenObject; + int? age; + dynamic clientIdentifierId; + int? createdBy; + String? dateOfBirth; + String? firstNameAr; + String? firstNameEn; + String? gender; + dynamic genderAr; + dynamic genderEn; + String? healthId; + String? idNumber; + String? idType; + bool? isHijri; + int? isInstertedOrUpdated; + int? isdynamic; + int? isPatientExistNHIC; + String? lastNameAr; + String? lastNameEn; + dynamic listActiveAccessToken; + String? maritalStatus; + String? maritalStatusCode; + String? nationality; + String? nationalityCode; + String? occupation; + String? patientStatus; + String? placeofBirth; + dynamic practitionerStatusCode; + dynamic practitionerStatusDescAr; + dynamic practitionerStatusDescEn; + String? secondNameAr; + String? secondNameEn; + String? thirdNameAr; + String? thirdNameEn; + dynamic accessToken; + int? categoryCode; + dynamic categoryNameAr; + dynamic categoryNameEn; + int? constraintCode; + dynamic constraintNameAr; + dynamic constraintNameEn; + dynamic content; + dynamic licenseExpiryDate; + dynamic licenseIssuedDate; + dynamic licenseStatusCode; + dynamic licenseStatusDescAr; + dynamic licenseStatusDescEn; + dynamic organizations; + dynamic registrationNumber; + int? specialtyCode; + dynamic specialtyNameAr; + dynamic specialtyNameEn; + // String? occupationID; RegisterInfoResponse( {this.date, @@ -116,7 +117,7 @@ class RegisterInfoResponse { this.idType, this.isHijri, this.isInstertedOrUpdated, - this.isNull, + this.isdynamic, this.isPatientExistNHIC, this.lastNameAr, this.lastNameEn, @@ -152,7 +153,9 @@ class RegisterInfoResponse { this.registrationNumber, this.specialtyCode, this.specialtyNameAr, - this.specialtyNameEn}); + this.specialtyNameEn, + // this.occupationID + }); RegisterInfoResponse.fromJson(Map json) { date = json['Date']; @@ -194,7 +197,7 @@ class RegisterInfoResponse { idType = json['IdType']; isHijri = json['IsHijri']; isInstertedOrUpdated = json['IsInstertedOrUpdated']; - isNull = json['IsNull']; + isdynamic = json['Isdynamic']; isPatientExistNHIC = json['IsPatientExistNHIC']; lastNameAr = json['LastNameAr']; lastNameEn = json['LastNameEn']; @@ -231,6 +234,7 @@ class RegisterInfoResponse { specialtyCode = json['specialtyCode']; specialtyNameAr = json['specialtyNameAr']; specialtyNameEn = json['specialtyNameEn']; + // occupationID = json['OccupationID']; } Map toJson() { @@ -274,7 +278,7 @@ class RegisterInfoResponse { data['IdType'] = this.idType; data['IsHijri'] = this.isHijri; data['IsInstertedOrUpdated'] = this.isInstertedOrUpdated; - data['IsNull'] = this.isNull; + data['Isdynamic'] = this.isdynamic; data['IsPatientExistNHIC'] = this.isPatientExistNHIC; data['LastNameAr'] = this.lastNameAr; data['LastNameEn'] = this.lastNameEn; @@ -311,6 +315,7 @@ class RegisterInfoResponse { data['specialtyCode'] = this.specialtyCode; data['specialtyNameAr'] = this.specialtyNameAr; data['specialtyNameEn'] = this.specialtyNameEn; + // data['OccupationID'] = this.occupationID; return data; } } diff --git a/lib/models/Authentication/register_user_requet.dart b/lib/models/Authentication/register_user_requet.dart index 7758ce5b..e436d6ef 100644 --- a/lib/models/Authentication/register_user_requet.dart +++ b/lib/models/Authentication/register_user_requet.dart @@ -1,17 +1,22 @@ class RegisterUserRequest { - Patientobject patientobject; - String patientIdentificationID; - int patientMobileNumber; - String logInTokenID; - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - Null sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; + Patientobject? patientobject; + String? patientIdentificationID; + dynamic patientMobileNumber; + String? logInTokenID; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + dynamic sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + String? dob; + int? isHijri; + String? healthId; + String? zipCode; + // String? occupationID; RegisterUserRequest( {this.patientobject, @@ -26,12 +31,16 @@ class RegisterUserRequest { this.patientOutSA, this.sessionID, this.isDentalAllowedBackend, - this.deviceTypeID}); + this.deviceTypeID, + this.dob, + this.isHijri, + this.healthId, + this.zipCode, + // this.occupationID + }); RegisterUserRequest.fromJson(Map json) { - patientobject = json['Patientobject'] != null - ? new Patientobject.fromJson(json['Patientobject']) - : null; + patientobject = json['Patientobject'] != null ? new Patientobject.fromJson(json['Patientobject']) : null; patientIdentificationID = json['PatientIdentificationID']; patientMobileNumber = json['PatientMobileNumber']; logInTokenID = json['LogInTokenID']; @@ -44,12 +53,17 @@ class RegisterUserRequest { sessionID = json['SessionID']; isDentalAllowedBackend = json['isDentalAllowedBackend']; deviceTypeID = json['DeviceTypeID']; + dob = json['DOB']; + isHijri = json['IsHijri']; + healthId = json['HealthId']; + zipCode = json['ZipCode']; + // occupationID = json['OccupationID']; } Map toJson() { final Map data = new Map(); if (this.patientobject != null) { - data['Patientobject'] = this.patientobject.toJson(); + data['Patientobject'] = this.patientobject!.toJson(); } data['PatientIdentificationID'] = this.patientIdentificationID; data['PatientMobileNumber'] = this.patientMobileNumber; @@ -63,31 +77,38 @@ class RegisterUserRequest { data['SessionID'] = this.sessionID; data['isDentalAllowedBackend'] = this.isDentalAllowedBackend; data['DeviceTypeID'] = this.deviceTypeID; + data['DOB'] = this.dob; + data['IsHijri'] = this.isHijri; + data['HealthId'] = this.healthId; + data['ZipCode'] = this.zipCode; + // data['OccupationID'] = this.occupationID; return data; } } class Patientobject { - bool tempValue; - int patientIdentificationType; - String patientIdentificationNo; - int mobileNumber; - int patientOutSA; - String firstName; - String middleName; - String lastName; - String firstNameN; - String middleNameN; - String lastNameN; + bool? tempValue; + int? patientIdentificationType; + String? patientIdentificationNo; + dynamic mobileNumber; + int? patientOutSA; + String? firstName; + String? middleName; + String? lastName; + String? firstNameN; + String? middleNameN; + String? lastNameN; dynamic strDateofBirth; - String dateofBirth; - int gender; - String nationalityID; - String dateofBirthN; - String emailAddress; - String sourceType; - String preferredLanguage; - String marital; + String? dateofBirth; + int? gender; + String? nationalityID; + String? eHealthIDField; + String? dateofBirthN; + String? emailAddress; + String? sourceType; + String? preferredLanguage; + String? marital; + // String? occupationID; Patientobject( {this.tempValue, @@ -96,20 +117,23 @@ class Patientobject { this.mobileNumber, this.patientOutSA, this.firstName, - this.middleName, - this.lastName, - this.firstNameN, - this.middleNameN, - this.lastNameN, + this.middleName, + this.lastName, + this.firstNameN, + this.middleNameN, + this.lastNameN, this.strDateofBirth, this.dateofBirth, this.gender, this.nationalityID, + this.eHealthIDField, this.dateofBirthN, this.emailAddress, this.sourceType, this.preferredLanguage, - this.marital}); + this.marital, + // this.occupationID + }); Patientobject.fromJson(Map json) { tempValue = json['TempValue']; @@ -127,12 +151,14 @@ class Patientobject { dateofBirth = json['DateofBirth']; gender = json['Gender']; nationalityID = json['NationalityID']; + eHealthIDField = json['eHealthIDField']; dateofBirthN = json['DateofBirthN']; emailAddress = json['EmailAddress']; sourceType = json['SourceType']; preferredLanguage = json['PreferredLanguage']; marital = json['Marital']; + // occupationID = json['OccupationID'] ?? ""; } Map toJson() { @@ -152,12 +178,13 @@ class Patientobject { data['DateofBirth'] = this.dateofBirth; data['Gender'] = this.gender; data['NationalityID'] = this.nationalityID; + data['eHealthIDField'] = this.eHealthIDField; data['DateofBirthN'] = this.dateofBirthN; data['EmailAddress'] = this.emailAddress; data['SourceType'] = this.sourceType; - data['PreferredLanguage'] = this.preferredLanguage; data['Marital'] = this.marital; + // data['OccupationID'] = this.occupationID; return data; } } diff --git a/lib/models/Authentication/registered_authenticated_user_req.dart b/lib/models/Authentication/registered_authenticated_user_req.dart index c261d062..4b39ccc9 100644 --- a/lib/models/Authentication/registered_authenticated_user_req.dart +++ b/lib/models/Authentication/registered_authenticated_user_req.dart @@ -1,27 +1,27 @@ class RegisteredAuthenticatedUserRequest { - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - String sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; - int patientID; - String tokenID; - String voipToken; - int patientTypeID; - int patientType; - String deviceToken; - String deviceType; - String patientMobileNumber; - String nationalID; - int gender; - int loginType; - String mACAddress; - int latitude; - int longitude; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + String? sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + int? patientID; + String? tokenID; + String? voipToken; + int? patientTypeID; + int? patientType; + String? deviceToken; + String? deviceType; + String? patientMobileNumber; + String? nationalID; + int? gender; + int? loginType; + String? mACAddress; + int? latitude; + int? longitude; RegisteredAuthenticatedUserRequest( {this.versionID, diff --git a/lib/models/Authentication/select_device_imei_res.dart b/lib/models/Authentication/select_device_imei_res.dart index 14444279..979dfca1 100644 --- a/lib/models/Authentication/select_device_imei_res.dart +++ b/lib/models/Authentication/select_device_imei_res.dart @@ -1,18 +1,18 @@ class SelectDeviceIMEIRES { - bool biometricEnabled; - String createdOn; - String editedOn; - int iD; - String iMEI; - String identificationNo; - int logInType; - String mobile; - String name; - String nameN; - bool outSA; - int patientID; - int patientType; - int preferredLanguage; + bool? biometricEnabled; + String? createdOn; + String? editedOn; + int? iD; + String? iMEI; + String? identificationNo; + int? logInType; + String? mobile; + String? name; + String? nameN; + bool? outSA; + int? patientID; + int? patientType; + int? preferredLanguage; SelectDeviceIMEIRES( {this.biometricEnabled, @@ -32,13 +32,13 @@ class SelectDeviceIMEIRES { SelectDeviceIMEIRES.fromJson(Map json) { biometricEnabled = json['BiometricEnabled']; - createdOn = json['CreatedOn']; - editedOn = json['EditedOn']; + createdOn = json['CreatedOn'].toString(); + editedOn = json['EditedOn'].toString(); iD = json['ID']; iMEI = json['IMEI']; - identificationNo = json['IdentificationNo']; + identificationNo = json['IdentificationNo'].toString(); logInType = json['LogInType']; - mobile = json['Mobile']; + mobile = json['Mobile'].toString(); name = json['Name']; nameN = json['NameN']; outSA = json['OutSA']; @@ -48,7 +48,7 @@ class SelectDeviceIMEIRES { } Map toJson() { - final Map data = new Map(); + final Map data = Map(); data['BiometricEnabled'] = this.biometricEnabled; data['CreatedOn'] = this.createdOn; data['EditedOn'] = this.editedOn; @@ -65,4 +65,9 @@ class SelectDeviceIMEIRES { data['PreferredLanguage'] = this.preferredLanguage; return data; } + + @override + String toString() { + return 'SelectDeviceIMEIRES{biometricEnabled: $biometricEnabled, createdOn: $createdOn, editedOn: $editedOn, iD: $iD, iMEI: $iMEI, identificationNo: $identificationNo, logInType: $logInType, mobile: $mobile, name: $name, nameN: $nameN, outSA: $outSA, patientID: $patientID, patientType: $patientType, preferredLanguage: $preferredLanguage}'; + } } diff --git a/lib/models/Authentication/send_activation_request.dart b/lib/models/Authentication/send_activation_request.dart index f9b386c6..04e684e9 100644 --- a/lib/models/Authentication/send_activation_request.dart +++ b/lib/models/Authentication/send_activation_request.dart @@ -1,27 +1,34 @@ class SendActivationRequest { - int patientMobileNumber; - String mobileNo; - String deviceToken; - bool projectOutSA; - int loginType; - String zipCode; - bool isRegister; - String logInTokenID; - int searchType; - int patientID; - String nationalID; - String patientIdentificationID; - int oTPSendType; - int languageID; - double versionID; - int channel; - String iPAdress; - String generalid; - int patientOutSA; - Null sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; - String sMSSignature; + int? patientMobileNumber; + String? mobileNo; + String? deviceToken; + bool? projectOutSA; + int? loginType; + String? zipCode; + bool? isRegister; + String? logInTokenID; + int? searchType; + int? patientID; + String? nationalID; + String? patientIdentificationID; + int? oTPSendType; + int? languageID; + double? versionID; + int? channel; + String? iPAdress; + String? generalid; + int? patientOutSA; + dynamic sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + String? sMSSignature; + String? dob; + int? isHijri; + String? healthId; + int? responseID; + int? status; + int? familyRegionID; + bool? isPatientExcluded; SendActivationRequest( {this.patientMobileNumber, this.mobileNo, @@ -45,7 +52,15 @@ class SendActivationRequest { this.sessionID, this.isDentalAllowedBackend, this.deviceTypeID, - this.sMSSignature}); + this.sMSSignature, + this.dob, + this.isHijri, + this.healthId, + this.responseID, + this.status, + this.familyRegionID, + this.isPatientExcluded + }); SendActivationRequest.fromJson(Map json) { patientMobileNumber = json['PatientMobileNumber']; @@ -71,6 +86,13 @@ class SendActivationRequest { isDentalAllowedBackend = json['isDentalAllowedBackend']; deviceTypeID = json['DeviceTypeID']; sMSSignature = json['SMSSignature']; + dob = json['DOB']; + isHijri = json['IsHijri']; + healthId = json['HealthId']; + responseID = json['ReponseID']; + status = json['Status']; + familyRegionID = json['FamilyRegionID']; + isPatientExcluded = json['IsPatientExcluded']; } Map toJson() { @@ -98,6 +120,13 @@ class SendActivationRequest { data['isDentalAllowedBackend'] = this.isDentalAllowedBackend; data['DeviceTypeID'] = this.deviceTypeID; data['SMSSignature'] = sMSSignature; + data['DOB'] = dob; + data['IsHijri'] = isHijri; + data['HealthId'] = healthId; + data['ResponseID'] = responseID; + data['Status'] = status; + data['FamilyRegionID'] = familyRegionID; + data['IsPatientExcluded'] = isPatientExcluded; return data; } } diff --git a/lib/models/Clinics/ClinicListResponse.dart b/lib/models/Clinics/ClinicListResponse.dart index cabb47b2..43b78970 100644 --- a/lib/models/Clinics/ClinicListResponse.dart +++ b/lib/models/Clinics/ClinicListResponse.dart @@ -1,12 +1,12 @@ class ListClinicCentralized { - int clinicID; - String clinicDescription; - Null clinicDescriptionN; - int age; - int gender; - bool isLiveCareClinicAndOnline; - int liveCareClinicID; - int liveCareServiceID; + int? clinicID; + String? clinicDescription; + String? clinicDescriptionN; + int? age; + int? gender; + bool? isLiveCareClinicAndOnline; + int? liveCareClinicID; + int? liveCareServiceID; ListClinicCentralized( {this.clinicID, @@ -41,14 +41,20 @@ class ListClinicCentralized { data['LiveCareServiceID'] = this.liveCareServiceID; return data; } + + + @override + String toString() { + return '${clinicDescription}'.toLowerCase() + ' ${clinicDescription}'.toUpperCase(); + } } class ListGetBookScheduleConfigsList { - int iD; - String description; - Null descriptionN; - bool value; - bool isActive; + int? iD; + String? description; + dynamic descriptionN; + bool? value; + bool? isActive; ListGetBookScheduleConfigsList( {this.iD, diff --git a/lib/models/Clinics/EROnlineCheckInPaymentDetailsResponse.dart b/lib/models/Clinics/EROnlineCheckInPaymentDetailsResponse.dart new file mode 100644 index 00000000..1d6694ad --- /dev/null +++ b/lib/models/Clinics/EROnlineCheckInPaymentDetailsResponse.dart @@ -0,0 +1,108 @@ +class EROnlineCheckInPaymentDetailsResponse { + num? cashPrice; + num? cashPriceTax; + num? cashPriceWithTax; + int? companyId; + String? companyName; + num? companyShareWithTax; + dynamic errCode; + int? groupID; + String? insurancePolicyNo; + String? message; + String? patientCardID; + num? patientShare; + num? patientShareWithTax; + num? patientTaxAmount; + int? policyId; + String? policyName; + String? procedureId; + String? procedureName; + dynamic setupID; + int? statusCode; + String? subPolicyNo; + bool? isCash; + bool? isEligible; + bool? isInsured; + EROnlineCheckInPaymentDetailsResponse( + {this.cashPrice, + this.cashPriceTax, + this.cashPriceWithTax, + this.companyId, + this.companyName, + this.companyShareWithTax, + this.errCode, + this.groupID, + this.insurancePolicyNo, + this.message, + this.patientCardID, + this.patientShare, + this.patientShareWithTax, + this.patientTaxAmount, + this.policyId, + this.policyName, + this.procedureId, + this.procedureName, + this.setupID, + this.statusCode, + this.subPolicyNo, + this.isCash, + this.isEligible, + this.isInsured + }); + + EROnlineCheckInPaymentDetailsResponse.fromJson(Map json) { + cashPrice = json['CashPrice']; + cashPriceTax = json['CashPriceTax']; + cashPriceWithTax = json['CashPriceWithTax']; + companyId = json['CompanyId']; + companyName = json['CompanyName']; + companyShareWithTax = json['CompanyShareWithTax']; + errCode = json['ErrCode']; + groupID = json['GroupID']; + insurancePolicyNo = json['InsurancePolicyNo']; + message = json['Message']; + patientCardID = json['PatientCardID']; + patientShare = json['PatientShare']; + patientShareWithTax = json['PatientShareWithTax']; + patientTaxAmount = json['PatientTaxAmount']; + policyId = json['PolicyId']; + policyName = json['PolicyName']; + procedureId = json['ProcedureId']; + procedureName = json['ProcedureName']; + setupID = json['SetupID']; + statusCode = json['StatusCode']; + subPolicyNo = json['SubPolicyNo']; + isCash = json['IsCash']; + isEligible = json['IsEligible']; + isInsured = json['IsInsured']; + } + + Map toJson() { + final Map data = new Map(); + data['CashPrice'] = this.cashPrice; + data['CashPriceTax'] = this.cashPriceTax; + data['CashPriceWithTax'] = this.cashPriceWithTax; + data['CompanyId'] = this.companyId; + data['CompanyName'] = this.companyName; + data['CompanyShareWithTax'] = this.companyShareWithTax; + data['ErrCode'] = this.errCode; + data['GroupID'] = this.groupID; + data['InsurancePolicyNo'] = this.insurancePolicyNo; + data['Message'] = this.message; + data['PatientCardID'] = this.patientCardID; + data['PatientShare'] = this.patientShare; + data['PatientShareWithTax'] = this.patientShareWithTax; + data['PatientTaxAmount'] = this.patientTaxAmount; + data['PolicyId'] = this.policyId; + data['PolicyName'] = this.policyName; + data['ProcedureId'] = this.procedureId; + data['ProcedureName'] = this.procedureName; + data['SetupID'] = this.setupID; + data['StatusCode'] = this.statusCode; + data['SubPolicyNo'] = this.subPolicyNo; + data['IsCash'] = this.isCash; + data['IsEligible'] = this.isEligible; + data['IsInsured'] = this.isInsured; + return data; + } +} diff --git a/lib/models/CovidDriveThru/CovidPaymentInfoResponse.dart b/lib/models/CovidDriveThru/CovidPaymentInfoResponse.dart index a1290e4d..35342c26 100644 --- a/lib/models/CovidDriveThru/CovidPaymentInfoResponse.dart +++ b/lib/models/CovidDriveThru/CovidPaymentInfoResponse.dart @@ -4,19 +4,19 @@ class CovidPaymentInfoResponse { dynamic cashPriceTaxField; dynamic cashPriceWithTaxField; dynamic companyIdField; - String companyNameField; + String? companyNameField; dynamic companyShareWithTaxField; dynamic errCodeField; dynamic groupIDField; dynamic insurancePolicyNoField; - String messageField; + String? messageField; dynamic patientCardIDField; dynamic patientShareField; dynamic patientShareWithTaxField; dynamic patientTaxAmountField; dynamic policyIdField; dynamic policyNameField; - String procedureNameField; + String? procedureNameField; dynamic setupIDField; dynamic statusCodeField; dynamic subPolicyNoField; diff --git a/lib/models/CovidDriveThru/CovidTestProceduresResponse.dart b/lib/models/CovidDriveThru/CovidTestProceduresResponse.dart new file mode 100644 index 00000000..2c0a42c9 --- /dev/null +++ b/lib/models/CovidDriveThru/CovidTestProceduresResponse.dart @@ -0,0 +1,32 @@ +class CovidTestProceduresResponse { + String? procedureID; + String? procedureName; + String? procedureNameN; + int? projectID; + String? setupID; + + CovidTestProceduresResponse( + {this.procedureID, + this.procedureName, + this.procedureNameN, + this.projectID, + this.setupID}); + + CovidTestProceduresResponse.fromJson(Map json) { + procedureID = json['ProcedureID']; + procedureName = json['ProcedureName']; + procedureNameN = json['ProcedureNameN']; + projectID = json['ProjectID']; + setupID = json['SetupID']; + } + + Map toJson() { + final Map data = new Map(); + data['ProcedureID'] = this.procedureID; + data['ProcedureName'] = this.procedureName; + data['ProcedureNameN'] = this.procedureNameN; + data['ProjectID'] = this.projectID; + data['SetupID'] = this.setupID; + return data; + } +} diff --git a/lib/models/CovidDriveThru/DriveThroughTestingCenterModel.dart b/lib/models/CovidDriveThru/DriveThroughTestingCenterModel.dart index c85a06b3..4f528424 100644 --- a/lib/models/CovidDriveThru/DriveThroughTestingCenterModel.dart +++ b/lib/models/CovidDriveThru/DriveThroughTestingCenterModel.dart @@ -1,14 +1,16 @@ class DriveThroughTestingCenterModel { - int rowID; - int iD; - int projectID; - String setupID; - double longitude; - double latitude; - int numberOfTracks; - bool isActive; - int createdBy; - String createdOn; + int? rowID; + int? iD; + int? projectID; + String? setupID; + double? longitude; + double? latitude; + int? numberOfTracks; + bool? isActive; + int? createdBy; + String? createdOn; + int? testTypeEnum; + int? testProcedureEnum; dynamic editedBy; dynamic editedON; dynamic projectName; @@ -16,19 +18,21 @@ class DriveThroughTestingCenterModel { DriveThroughTestingCenterModel( {this.rowID, - this.iD, - this.projectID, - this.setupID, - this.longitude, - this.latitude, - this.numberOfTracks, - this.isActive, - this.createdBy, - this.createdOn, - this.editedBy, - this.editedON, - this.projectName, - this.projectNameN}); + this.iD, + this.projectID, + this.setupID, + this.longitude, + this.latitude, + this.numberOfTracks, + this.isActive, + this.createdBy, + this.createdOn, + this.testTypeEnum, + this.testProcedureEnum, + this.editedBy, + this.editedON, + this.projectName, + this.projectNameN}); DriveThroughTestingCenterModel.fromJson(Map json) { rowID = json['RowID']; @@ -41,6 +45,8 @@ class DriveThroughTestingCenterModel { isActive = json['IsActive']; createdBy = json['CreatedBy']; createdOn = json['CreatedOn']; + testTypeEnum = json['TestTypeEnum']; + testProcedureEnum = json['TestprocedureEnum']; editedBy = json['EditedBy']; editedON = json['EditedON']; projectName = json['ProjectName']; @@ -59,6 +65,8 @@ class DriveThroughTestingCenterModel { data['IsActive'] = this.isActive; data['CreatedBy'] = this.createdBy; data['CreatedOn'] = this.createdOn; + data['TestTypeEnum'] = this.testTypeEnum; + data['TestprocedureEnum'] = this.testProcedureEnum; data['EditedBy'] = this.editedBy; data['EditedON'] = this.editedON; data['ProjectName'] = this.projectName; diff --git a/lib/models/FamilyFiles/GetAllSharedRecordByStatusResponse.dart b/lib/models/FamilyFiles/GetAllSharedRecordByStatusResponse.dart index 750cf0be..def0db59 100644 --- a/lib/models/FamilyFiles/GetAllSharedRecordByStatusResponse.dart +++ b/lib/models/FamilyFiles/GetAllSharedRecordByStatusResponse.dart @@ -1,36 +1,36 @@ class GetAllSharedRecordsByStatusResponse { dynamic date; - int languageID; - int serviceName; + int? languageID; + int? serviceName; dynamic time; dynamic androidLink; dynamic authenticationTokenID; dynamic data; - bool dataw; - int dietType; + bool? dataw; + int? dietType; dynamic errorCode; dynamic errorEndUserMessage; dynamic errorEndUserMessageN; dynamic errorMessage; - int errorType; - int foodCategory; + int? errorType; + int? foodCategory; dynamic iOSLink; - bool isAuthenticated; - int mealOrderStatus; - int mealType; - int messageStatus; - int numberOfResultRecords; + bool? isAuthenticated; + int? mealOrderStatus; + int? mealType; + int? messageStatus; + int? numberOfResultRecords; dynamic patientBlodType; dynamic successMsg; dynamic successMsgN; dynamic doctorInformationList; - List getAllPendingRecordsList; - List getAllSharedRecordsByStatusList = List(); - List getResponseFileList; - bool isHMGPatient; - bool isLoginSuccessfully; - bool isNeedUpdateIdintificationNo; - bool kioskSendSMS; + List? getAllPendingRecordsList; + List? getAllSharedRecordsByStatusList ; + List? getResponseFileList; + bool? isHMGPatient; + bool? isLoginSuccessfully; + bool? isNeedUpdateIdintificationNo; + bool? kioskSendSMS; dynamic list; dynamic listAskHabibMobileLoginInfo; dynamic listAskHabibPatientFile; @@ -39,31 +39,31 @@ class GetAllSharedRecordsByStatusResponse { dynamic listPatientCount; dynamic logInTokenID; dynamic mohemmPrivilegeList; - int pateintID; + int? pateintID; dynamic patientBloodType; dynamic patientERDriverFile; dynamic patientERDriverFileList; - bool patientHasFile; + bool? patientHasFile; dynamic patientMergedIDs; - bool patientOutSA; - int patientShareRequestID; - int patientType; - int projectIDOut; + bool? patientOutSA; + int? patientShareRequestID; + int? patientType; + int? projectIDOut; dynamic returnMessage; - bool sMSLoginRequired; + bool? sMSLoginRequired; dynamic servicePrivilegeList; dynamic sharePatientName; dynamic verificationCode; dynamic email; dynamic errorList; - bool hasFile; - bool isActiveCode; - bool isMerged; - bool isNeedUserAgreement; - bool isSMSSent; + bool? hasFile; + bool? isActiveCode; + bool? isMerged; + bool? isNeedUserAgreement; + bool? isSMSSent; dynamic memberList; dynamic message; - int statusCode; + int? statusCode; GetAllSharedRecordsByStatusResponse( {this.date, @@ -92,7 +92,7 @@ class GetAllSharedRecordsByStatusResponse { this.successMsgN, this.doctorInformationList, this.getAllPendingRecordsList, - this.getAllSharedRecordsByStatusList , + this.getAllSharedRecordsByStatusList, this.getResponseFileList, this.isHMGPatient, this.isLoginSuccessfully, @@ -162,18 +162,16 @@ class GetAllSharedRecordsByStatusResponse { // getAllPendingRecordsList = json['GetAllPendingRecordsList']; if (json['GetAllPendingRecordsList'] != null) { - getAllSharedRecordsByStatusList = new List(); + getAllSharedRecordsByStatusList = []; json['GetAllPendingRecordsList'].forEach((v) { - getAllSharedRecordsByStatusList - .add(new GetAllSharedRecordsByStatusList.fromJson(v)); + getAllSharedRecordsByStatusList!.add(new GetAllSharedRecordsByStatusList.fromJson(v)); }); } if (json['GetAllSharedRecordsByStatusList'] != null) { - getAllSharedRecordsByStatusList = new List(); + getAllSharedRecordsByStatusList = []; json['GetAllSharedRecordsByStatusList'].forEach((v) { - getAllSharedRecordsByStatusList - .add(new GetAllSharedRecordsByStatusList.fromJson(v)); + getAllSharedRecordsByStatusList!.add(new GetAllSharedRecordsByStatusList.fromJson(v)); }); } getResponseFileList = json['GetResponseFileList']; @@ -214,10 +212,9 @@ class GetAllSharedRecordsByStatusResponse { memberList = json['memberList']; message = json['message']; statusCode = json['statusCode']; - }catch (e){ - var asd =""; + } catch (e) { + var asd = ""; print(e); - } } @@ -250,8 +247,7 @@ class GetAllSharedRecordsByStatusResponse { data['DoctorInformation_List'] = this.doctorInformationList; data['GetAllPendingRecordsList'] = this.getAllPendingRecordsList; if (this.getAllSharedRecordsByStatusList != null) { - data['GetAllSharedRecordsByStatusList'] = - this.getAllSharedRecordsByStatusList.map((v) => v.toJson()).toList(); + data['GetAllSharedRecordsByStatusList'] = this.getAllSharedRecordsByStatusList!.map((v) => v.toJson()).toList(); } data['GetResponseFileList'] = this.getResponseFileList; data['IsHMGPatient'] = this.isHMGPatient; @@ -296,49 +292,76 @@ class GetAllSharedRecordsByStatusResponse { } class GetAllSharedRecordsByStatusList { - int iD; - int patientID; - int responseID; - int regionID; - int status; + int? iD; + int? patientID; + int? responseID; + dynamic relationshipID; + dynamic relationship; + dynamic relationshipN; + int? regionID; + int? status; dynamic isActive; - String editedOn; - String createdOn; - String emaiLAddress; - String mobileNumber; - String patientIdenficationNumber; - String patientName; - String statusDescription; + String? editedOn; + String? createdOn; + int? age; + String? emaiLAddress; + int? gender; + String? genderDescription; + String? genderImage; + String? mobileNumber; + int? patientDataVerified; + String? patientIdenficationNumber; + String? patientName; + String? statusDescription; + int? familyRegionID; GetAllSharedRecordsByStatusList( {this.iD, this.patientID, this.responseID, + this.relationshipID, + this.relationship, + this.relationshipN, this.regionID, this.status, this.isActive, this.editedOn, this.createdOn, + this.age, this.emaiLAddress, + this.gender, + this.genderDescription, + this.genderImage, this.mobileNumber, + this.patientDataVerified, this.patientIdenficationNumber, this.patientName, - this.statusDescription}); + this.statusDescription, + this.familyRegionID}); GetAllSharedRecordsByStatusList.fromJson(Map json) { iD = json['ID']; patientID = json['PatientID']; responseID = json['ResponseID']; + relationshipID = json['RelationshipID']; + relationship = json['Relationship']; + relationshipN = json['RelationshipN']; regionID = json['RegionID']; status = json['Status']; isActive = json['IsActive']; editedOn = json['EditedOn']; createdOn = json['CreatedOn']; + age = json['Age']; emaiLAddress = json['EmaiLAddress']; + gender = json['Gender']; + genderDescription = json['GenderDescription']; + genderImage = json['GenderImage']; mobileNumber = json['MobileNumber']; + patientDataVerified = json['PatientDataVerified']; patientIdenficationNumber = json['PatientIdenficationNumber']; patientName = json['PatientName']; statusDescription = json['StatusDescription']; + familyRegionID = json['FamilyRegionID']; } Map toJson() { @@ -346,16 +369,25 @@ class GetAllSharedRecordsByStatusList { data['ID'] = this.iD; data['PatientID'] = this.patientID; data['ResponseID'] = this.responseID; + data['RelationshipID'] = this.relationshipID; + data['Relationship'] = this.relationship; + data['RelationshipN'] = this.relationshipN; data['RegionID'] = this.regionID; data['Status'] = this.status; data['IsActive'] = this.isActive; data['EditedOn'] = this.editedOn; data['CreatedOn'] = this.createdOn; + data['Age'] = this.age; data['EmaiLAddress'] = this.emaiLAddress; + data['Gender'] = this.gender; + data['GenderDescription'] = this.genderDescription; + data['GenderImage'] = this.genderImage; data['MobileNumber'] = this.mobileNumber; + data['PatientDataVerified'] = this.patientDataVerified; data['PatientIdenficationNumber'] = this.patientIdenficationNumber; data['PatientName'] = this.patientName; data['StatusDescription'] = this.statusDescription; + data['FamilyRegionID'] = this.familyRegionID; return data; } } diff --git a/lib/models/FamilyFiles/GetAllSharedRecordsByStatusReq.dart b/lib/models/FamilyFiles/GetAllSharedRecordsByStatusReq.dart index ac0adc34..61c5855e 100644 --- a/lib/models/FamilyFiles/GetAllSharedRecordsByStatusReq.dart +++ b/lib/models/FamilyFiles/GetAllSharedRecordsByStatusReq.dart @@ -1,23 +1,23 @@ class GetAllSharedRecordsByStatusReq { - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - String sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; - int patientID; - String tokenID; - int patientTypeID; - int patientType; - int status; + double? versionID; + int? channel; + //int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + String? sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + int? patientID; + String? tokenID; + int? patientTypeID; + int? patientType; + int? status; GetAllSharedRecordsByStatusReq( {this.versionID, this.channel, - this.languageID, + // this.languageID, this.iPAdress, this.generalid, this.patientOutSA, @@ -33,7 +33,7 @@ class GetAllSharedRecordsByStatusReq { GetAllSharedRecordsByStatusReq.fromJson(Map json) { versionID = json['VersionID']; channel = json['Channel']; - languageID = json['LanguageID']; + // languageID = json['LanguageID']; iPAdress = json['IPAdress']; generalid = json['generalid']; patientOutSA = json['PatientOutSA']; @@ -51,7 +51,7 @@ class GetAllSharedRecordsByStatusReq { final Map data = new Map(); data['VersionID'] = this.versionID; data['Channel'] = this.channel; - data['LanguageID'] = this.languageID; + // data['LanguageID'] = this.languageID; data['IPAdress'] = this.iPAdress; data['generalid'] = this.generalid; data['PatientOutSA'] = this.patientOutSA; diff --git a/lib/models/FamilyFiles/PatientERVirtualHistoryResponse.dart b/lib/models/FamilyFiles/PatientERVirtualHistoryResponse.dart index 11a8157c..932df25e 100644 --- a/lib/models/FamilyFiles/PatientERVirtualHistoryResponse.dart +++ b/lib/models/FamilyFiles/PatientERVirtualHistoryResponse.dart @@ -1,13 +1,13 @@ class PatientERVirtualHistoryResponse { - List erRequestHistoryList; + List? erRequestHistoryList; PatientERVirtualHistoryResponse({this.erRequestHistoryList}); PatientERVirtualHistoryResponse.fromJson(Map json) { if (json['ErRequestHistoryList'] != null) { - erRequestHistoryList = new List(); + erRequestHistoryList = []; json['ErRequestHistoryList'].forEach((v) { - erRequestHistoryList.add(new ErRequestHistoryList.fromJson(v)); + erRequestHistoryList!.add(new ErRequestHistoryList.fromJson(v)); }); } } @@ -16,7 +16,7 @@ class PatientERVirtualHistoryResponse { final Map data = new Map(); if (this.erRequestHistoryList != null) { data['ErRequestHistoryList'] = - this.erRequestHistoryList.map((v) => v.toJson()).toList(); + this.erRequestHistoryList!.map((v) => v.toJson()).toList(); } return data; } @@ -24,23 +24,23 @@ class PatientERVirtualHistoryResponse { class ErRequestHistoryList { dynamic appointmentNo; - String arrivalTime; - int callDuration; - int callStatus; - String clientRequestID; - String doctorID; - String doctorName; - String doctorNameN; - String doctorTitle; - String exWaitingTime; - bool isAppointmentHaveRating; - int patCount; - int projectID; - String sArrivalTime; - int serviceID; - String stringCallStatus; - int vCID; - int watingtimeInteger; + String? arrivalTime; + int? callDuration; + int? callStatus; + String? clientRequestID; + String? doctorID; + String? doctorName; + String? doctorNameN; + String? doctorTitle; + String? exWaitingTime; + bool? isAppointmentHaveRating; + int? patCount; + int? projectID; + String? sArrivalTime; + int? serviceID; + String? stringCallStatus; + int? vCID; + int? watingtimeInteger; ErRequestHistoryList( {this.appointmentNo, diff --git a/lib/models/InPatientServices/get_admission_info_response_model.dart b/lib/models/InPatientServices/get_admission_info_response_model.dart new file mode 100644 index 00000000..901adda8 --- /dev/null +++ b/lib/models/InPatientServices/get_admission_info_response_model.dart @@ -0,0 +1,104 @@ +class GetAdmissionInfoResponseModel { + String? setupID; + int? projectID; + int? admissionNo; + String? admissionDate; + int? admissionRequestNo; + int? admissionType; + int? patientType; + int? patientID; + int? clinicID; + int? doctorID; + int? admittingClinicID; + int? admittingDoctorID; + int? categoryID; + String? roomID; + String? bedID; + dynamic dischargeDate; + int? approvalNo; + int? status; + String? statusDesc; + String? statusDescN; + String? clinicName; + String? doctorName; + String? projectName; + + GetAdmissionInfoResponseModel( + {this.setupID, + this.projectID, + this.admissionNo, + this.admissionDate, + this.admissionRequestNo, + this.admissionType, + this.patientType, + this.patientID, + this.clinicID, + this.doctorID, + this.admittingClinicID, + this.admittingDoctorID, + this.categoryID, + this.roomID, + this.bedID, + this.dischargeDate, + this.approvalNo, + this.status, + this.statusDesc, + this.statusDescN, + this.clinicName, + this.doctorName, + this.projectName}); + + GetAdmissionInfoResponseModel.fromJson(Map json) { + setupID = json['SetupID']; + projectID = json['ProjectID']; + admissionNo = json['AdmissionNo']; + admissionDate = json['AdmissionDate']; + admissionRequestNo = json['AdmissionRequestNo']; + admissionType = json['AdmissionType']; + patientType = json['PatientType']; + patientID = json['PatientID']; + clinicID = json['ClinicID']; + doctorID = json['DoctorID']; + admittingClinicID = json['AdmittingClinicID']; + admittingDoctorID = json['AdmittingDoctorID']; + categoryID = json['CategoryID']; + roomID = json['RoomID']; + bedID = json['BedID']; + dischargeDate = json['DischargeDate']; + approvalNo = json['ApprovalNo']; + status = json['Status']; + statusDesc = json['StatusDesc']; + statusDescN = json['StatusDescN']; + clinicName = json['ClinicName']; + doctorName = json['DoctorName']; + projectName = json['ProjectName']; + } + + Map toJson() { + final Map data = new Map(); + data['SetupID'] = this.setupID; + data['ProjectID'] = this.projectID; + data['AdmissionNo'] = this.admissionNo; + data['AdmissionDate'] = this.admissionDate; + data['AdmissionRequestNo'] = this.admissionRequestNo; + data['AdmissionType'] = this.admissionType; + data['PatientType'] = this.patientType; + data['PatientID'] = this.patientID; + data['ClinicID'] = this.clinicID; + data['DoctorID'] = this.doctorID; + data['AdmittingClinicID'] = this.admittingClinicID; + data['AdmittingDoctorID'] = this.admittingDoctorID; + data['CategoryID'] = this.categoryID; + data['RoomID'] = this.roomID; + data['BedID'] = this.bedID; + data['DischargeDate'] = this.dischargeDate; + data['ApprovalNo'] = this.approvalNo; + data['Status'] = this.status; + data['StatusDesc'] = this.statusDesc; + data['StatusDescN'] = this.statusDescN; + data['ClinicName'] = this.clinicName; + data['DoctorName'] = this.doctorName; + data['ProjectName'] = this.projectName; + return data; + } +} diff --git a/lib/models/InPatientServices/get_admission_request_info_response_model.dart b/lib/models/InPatientServices/get_admission_request_info_response_model.dart new file mode 100644 index 00000000..73de052b --- /dev/null +++ b/lib/models/InPatientServices/get_admission_request_info_response_model.dart @@ -0,0 +1,86 @@ +class GetAdmissionRequestInfoResponseModel { + int? admissionRequestNo; + String? clinicName; + String? doctorName; + String? expectedAdmissionDate; + List ?medicalInstructions; + dynamic medicalInstructionsXML; + String? medicalRemarks; + int? projectId; + String? projectName; + String? setupId; + int? clinicId; + int? doctorId; + + GetAdmissionRequestInfoResponseModel( + {this.admissionRequestNo, + this.clinicName, + this.doctorName, + this.expectedAdmissionDate, + this.medicalInstructions, + this.medicalInstructionsXML, + this.medicalRemarks, + this.projectId, + this.projectName, + this.setupId, + this.clinicId, + this.doctorId}); + + GetAdmissionRequestInfoResponseModel.fromJson(Map json) { + admissionRequestNo = json['admissionRequestNo']; + clinicName = json['clinicName']; + doctorName = json['doctorName']; + clinicId = json['ClinicID']; + doctorId = json['DoctorID']; + expectedAdmissionDate = json['expectedAdmissionDate']; + if (json['medicaLInstructions'] != null) { + medicalInstructions = []; + json['medicaLInstructions'].forEach((v) { + medicalInstructions!.add(new MedicaLInstructions.fromJson(v)); + }); + } + medicalInstructionsXML = json['medicalInstructionsXML']; + medicalRemarks = json['medicalRemarks']; + projectId = json['projectId']; + projectName = json['projectName']; + setupId = json['setupId']; + } + + Map toJson() { + final Map data = new Map(); + data['admissionRequestNo'] = this.admissionRequestNo; + data['clinicName'] = this.clinicName; + data['doctorName'] = this.doctorName; + data['clinicId'] = this.clinicId; + data['doctorId'] = this.doctorId; + data['expectedAdmissionDate'] = this.expectedAdmissionDate; + if (this.medicalInstructions != null) { + data['medicaLInstructions'] = this.medicalInstructions!.map((v) => v.toJson()).toList(); + } + data['medicalInstructionsXML'] = this.medicalInstructionsXML; + data['medicalRemarks'] = this.medicalRemarks; + data['projectId'] = this.projectId; + data['projectName'] = this.projectName; + data['setupId'] = this.setupId; + return data; + } +} + +class MedicaLInstructions { + String? description; + int? parameterCode; + + MedicaLInstructions({this.description, this.parameterCode}); + + MedicaLInstructions.fromJson(Map json) { + description = json['description']; + parameterCode = json['parameterCode']; + } + + Map toJson() { + final Map data = new Map(); + data['description'] = this.description; + data['parameterCode'] = this.parameterCode; + return data; + } +} diff --git a/lib/models/InPatientServices/get_admitted_patient_response_model.dart b/lib/models/InPatientServices/get_admitted_patient_response_model.dart new file mode 100644 index 00000000..6bc55ae9 --- /dev/null +++ b/lib/models/InPatientServices/get_admitted_patient_response_model.dart @@ -0,0 +1,220 @@ +class GetAdmittedPatientsResponseModel { + String? setupID; + int? projectID; + int? admissionNo; + String? admissionDate; + int? patientType; + int? patientID; + int? clinicID; + int? doctorID; + String? roomID; + String? bedID; + int? status; + int? admissionStatus; + String? createdOn; + String? firstName; + String? middleName; + String? lastName; + String? firstNameN; + String? middleNameN; + String? lastNameN; + int? gender; + String? dateofBirth; + dynamic companionFirstName; + dynamic companionMiddleName; + dynamic companionLastName; + dynamic companionFirstNameN; + dynamic companionMiddleNameN; + dynamic companionLastNameN; + dynamic companionID; + dynamic companionGender; + bool? isHasCompanion; + int? buildingID; + int? floorID; + int? nursingStationID; + int? dietType; + String? dietTypeDateCahnged; + String? dietTypeDescription; + String? dietTypeDescriptionN; + dynamic allergyDiseaseDateCahnged; + dynamic allergyDiseaseChecked; + dynamic doctorRemarks; + dynamic allergyRemarks; + String? age; + dynamic allergies; + String? companionFullName; + bool? dietTypeChanged; + String? dietTypeDateCahngedDate; + String? genderDescription; + dynamic genderImageUrl; + bool? hasAllergy; + bool? isNewAdmitted; + String? patientFullName; + dynamic allergyRemark; + + GetAdmittedPatientsResponseModel( + {this.setupID, + this.projectID, + this.admissionNo, + this.admissionDate, + this.patientType, + this.patientID, + this.clinicID, + this.doctorID, + this.roomID, + this.bedID, + this.status, + this.admissionStatus, + this.createdOn, + this.firstName, + this.middleName, + this.lastName, + this.firstNameN, + this.middleNameN, + this.lastNameN, + this.gender, + this.dateofBirth, + this.companionFirstName, + this.companionMiddleName, + this.companionLastName, + this.companionFirstNameN, + this.companionMiddleNameN, + this.companionLastNameN, + this.companionID, + this.companionGender, + this.isHasCompanion, + this.buildingID, + this.floorID, + this.nursingStationID, + this.dietType, + this.dietTypeDateCahnged, + this.dietTypeDescription, + this.dietTypeDescriptionN, + this.allergyDiseaseDateCahnged, + this.allergyDiseaseChecked, + this.doctorRemarks, + this.allergyRemarks, + this.age, + this.allergies, + this.companionFullName, + this.dietTypeChanged, + this.dietTypeDateCahngedDate, + this.genderDescription, + this.genderImageUrl, + this.hasAllergy, + this.isNewAdmitted, + this.patientFullName, + this.allergyRemark}); + + GetAdmittedPatientsResponseModel.fromJson(Map json) { + setupID = json['SetupID']; + projectID = json['ProjectID']; + admissionNo = json['AdmissionNo']; + admissionDate = json['AdmissionDate']; + patientType = json['PatientType']; + patientID = json['PatientID']; + clinicID = json['ClinicID']; + doctorID = json['DoctorID']; + roomID = json['RoomID']; + bedID = json['BedID']; + status = json['Status']; + admissionStatus = json['AdmissionStatus']; + createdOn = json['CreatedOn']; + firstName = json['FirstName']; + middleName = json['MiddleName']; + lastName = json['LastName']; + firstNameN = json['FirstNameN']; + middleNameN = json['MiddleNameN']; + lastNameN = json['LastNameN']; + gender = json['Gender']; + dateofBirth = json['DateofBirth']; + companionFirstName = json['CompanionFirstName']; + companionMiddleName = json['CompanionMiddleName']; + companionLastName = json['CompanionLastName']; + companionFirstNameN = json['CompanionFirstNameN']; + companionMiddleNameN = json['CompanionMiddleNameN']; + companionLastNameN = json['CompanionLastNameN']; + companionID = json['CompanionID']; + companionGender = json['CompanionGender']; + isHasCompanion = json['IsHasCompanion']; + buildingID = json['BuildingID']; + floorID = json['FloorID']; + nursingStationID = json['NursingStationID']; + dietType = json['DietType']; + dietTypeDateCahnged = json['DietTypeDateCahnged']; + dietTypeDescription = json['DietTypeDescription']; + dietTypeDescriptionN = json['DietTypeDescriptionN']; + allergyDiseaseDateCahnged = json['AllergyDiseaseDateCahnged']; + allergyDiseaseChecked = json['AllergyDiseaseChecked']; + doctorRemarks = json['DoctorRemarks']; + allergyRemarks = json['AllergyRemarks']; + age = json['Age']; + allergies = json['Allergies']; + companionFullName = json['CompanionFullName']; + dietTypeChanged = json['DietTypeChanged']; + dietTypeDateCahngedDate = json['DietTypeDateCahnged_Date']; + genderDescription = json['GenderDescription']; + genderImageUrl = json['GenderImageUrl']; + hasAllergy = json['HasAllergy']; + isNewAdmitted = json['IsNewAdmitted']; + patientFullName = json['PatientFullName']; + allergyRemark = json['allergyRemark']; + } + + Map toJson() { + final Map data = new Map(); + data['SetupID'] = this.setupID; + data['ProjectID'] = this.projectID; + data['AdmissionNo'] = this.admissionNo; + data['AdmissionDate'] = this.admissionDate; + data['PatientType'] = this.patientType; + data['PatientID'] = this.patientID; + data['ClinicID'] = this.clinicID; + data['DoctorID'] = this.doctorID; + data['RoomID'] = this.roomID; + data['BedID'] = this.bedID; + data['Status'] = this.status; + data['AdmissionStatus'] = this.admissionStatus; + data['CreatedOn'] = this.createdOn; + data['FirstName'] = this.firstName; + data['MiddleName'] = this.middleName; + data['LastName'] = this.lastName; + data['FirstNameN'] = this.firstNameN; + data['MiddleNameN'] = this.middleNameN; + data['LastNameN'] = this.lastNameN; + data['Gender'] = this.gender; + data['DateofBirth'] = this.dateofBirth; + data['CompanionFirstName'] = this.companionFirstName; + data['CompanionMiddleName'] = this.companionMiddleName; + data['CompanionLastName'] = this.companionLastName; + data['CompanionFirstNameN'] = this.companionFirstNameN; + data['CompanionMiddleNameN'] = this.companionMiddleNameN; + data['CompanionLastNameN'] = this.companionLastNameN; + data['CompanionID'] = this.companionID; + data['CompanionGender'] = this.companionGender; + data['IsHasCompanion'] = this.isHasCompanion; + data['BuildingID'] = this.buildingID; + data['FloorID'] = this.floorID; + data['NursingStationID'] = this.nursingStationID; + data['DietType'] = this.dietType; + data['DietTypeDateCahnged'] = this.dietTypeDateCahnged; + data['DietTypeDescription'] = this.dietTypeDescription; + data['DietTypeDescriptionN'] = this.dietTypeDescriptionN; + data['AllergyDiseaseDateCahnged'] = this.allergyDiseaseDateCahnged; + data['AllergyDiseaseChecked'] = this.allergyDiseaseChecked; + data['DoctorRemarks'] = this.doctorRemarks; + data['AllergyRemarks'] = this.allergyRemarks; + data['Age'] = this.age; + data['Allergies'] = this.allergies; + data['CompanionFullName'] = this.companionFullName; + data['DietTypeChanged'] = this.dietTypeChanged; + data['DietTypeDateCahnged_Date'] = this.dietTypeDateCahngedDate; + data['GenderDescription'] = this.genderDescription; + data['GenderImageUrl'] = this.genderImageUrl; + data['HasAllergy'] = this.hasAllergy; + data['IsNewAdmitted'] = this.isNewAdmitted; + data['PatientFullName'] = this.patientFullName; + data['allergyRemark'] = this.allergyRemark; + return data; + } +} diff --git a/lib/models/InPatientServices/get_general_instructions_response_model.dart b/lib/models/InPatientServices/get_general_instructions_response_model.dart new file mode 100644 index 00000000..7869a40e --- /dev/null +++ b/lib/models/InPatientServices/get_general_instructions_response_model.dart @@ -0,0 +1,52 @@ +class GetGeneralInstructions { + int? rowID; + int? iD; + int? projectID; + String? text; + String? textN; + bool? isActive; + int? createdBy; + String? createdOn; + dynamic editedBy; + dynamic editedOn; + + GetGeneralInstructions( + {this.rowID, + this.iD, + this.projectID, + this.text, + this.textN, + this.isActive, + this.createdBy, + this.createdOn, + this.editedBy, + this.editedOn}); + + GetGeneralInstructions.fromJson(Map json) { + rowID = json['RowID']; + iD = json['ID']; + projectID = json['ProjectID']; + text = json['Text']; + textN = json['TextN']; + isActive = json['IsActive']; + createdBy = json['CreatedBy']; + createdOn = json['CreatedOn']; + editedBy = json['EditedBy']; + editedOn = json['EditedOn']; + } + + Map toJson() { + final Map data = new Map(); + data['RowID'] = this.rowID; + data['ID'] = this.iD; + data['ProjectID'] = this.projectID; + data['Text'] = this.text; + data['TextN'] = this.textN; + data['IsActive'] = this.isActive; + data['CreatedBy'] = this.createdBy; + data['CreatedOn'] = this.createdOn; + data['EditedBy'] = this.editedBy; + data['EditedOn'] = this.editedOn; + return data; + } +} diff --git a/lib/models/InPatientServices/get_inpatient_advance_history_response_model.dart b/lib/models/InPatientServices/get_inpatient_advance_history_response_model.dart new file mode 100644 index 00000000..d6753707 --- /dev/null +++ b/lib/models/InPatientServices/get_inpatient_advance_history_response_model.dart @@ -0,0 +1,71 @@ +class InPatientAdvanceHistoryResponseModel { + int? advanceNumber; + int? errorCode; + String? message; + List? responseInpatientAdvanceInfo; + int? statusCode; + + InPatientAdvanceHistoryResponseModel({this.advanceNumber, this.errorCode, this.message, this.responseInpatientAdvanceInfo, this.statusCode}); + + InPatientAdvanceHistoryResponseModel.fromJson(Map json) { + advanceNumber = json['advanceNumber']; + errorCode = json['errorCode']; + message = json['message']; + if (json['responseInpatientAdvanceInfo'] != null) { + responseInpatientAdvanceInfo = []; + json['responseInpatientAdvanceInfo'].forEach((v) { + responseInpatientAdvanceInfo!.add(new ResponseInpatientAdvanceInfo.fromJson(v)); + }); + } + statusCode = json['statusCode']; + } + + Map toJson() { + final Map data = new Map(); + data['advanceNumber'] = this.advanceNumber; + data['errorCode'] = this.errorCode; + data['message'] = this.message; + if (this.responseInpatientAdvanceInfo != null) { + data['responseInpatientAdvanceInfo'] = this.responseInpatientAdvanceInfo!.map((v) => v.toJson()).toList(); + } + data['statusCode'] = this.statusCode; + return data; + } +} + +class ResponseInpatientAdvanceInfo { + int? admissionNo; + int? admissionReqNo; + String? createdOn; + int? patientId; + int? projectId; + num? requestedAmount; + String? setupId; + int? status; + + ResponseInpatientAdvanceInfo({this.admissionNo, this.admissionReqNo, this.createdOn, this.patientId, this.projectId, this.requestedAmount, this.setupId, this.status}); + + ResponseInpatientAdvanceInfo.fromJson(Map json) { + admissionNo = json['admissionNo']; + admissionReqNo = json['admissionReqNo']; + createdOn = json['createdOn']; + patientId = json['patientId']; + projectId = json['projectId']; + requestedAmount = json['requestedAmount']; + setupId = json['setupId']; + status = json['status']; + } + + Map toJson() { + final Map data = new Map(); + data['admissionNo'] = this.admissionNo; + data['admissionReqNo'] = this.admissionReqNo; + data['createdOn'] = this.createdOn; + data['patientId'] = this.patientId; + data['projectId'] = this.projectId; + data['requestedAmount'] = this.requestedAmount; + data['setupId'] = this.setupId; + data['status'] = this.status; + return data; + } +} diff --git a/lib/models/InPatientServices/get_inpatient_advance_requests_response_model.dart b/lib/models/InPatientServices/get_inpatient_advance_requests_response_model.dart new file mode 100644 index 00000000..658cbfa3 --- /dev/null +++ b/lib/models/InPatientServices/get_inpatient_advance_requests_response_model.dart @@ -0,0 +1,74 @@ +class InPatientAdvanceResponseModel { + int? advanceNumber; + Null errorCode; + String? message; + List? responseInpatientAdvanceInfo; + int? statusCode; + + InPatientAdvanceResponseModel({this.advanceNumber, this.errorCode, this.message, this.responseInpatientAdvanceInfo, this.statusCode}); + + InPatientAdvanceResponseModel.fromJson(Map json) { + advanceNumber = json['advanceNumber']; + errorCode = json['errorCode']; + message = json['message']; + if (json['responseInpatientAdvanceInfo'] != null) { + responseInpatientAdvanceInfo = []; + json['responseInpatientAdvanceInfo'].forEach((v) { + responseInpatientAdvanceInfo!.add(new ResponseInpatientAdvanceInfo.fromJson(v)); + }); + } + statusCode = json['statusCode']; + } + + Map toJson() { + final Map data = new Map(); + data['advanceNumber'] = this.advanceNumber; + data['errorCode'] = this.errorCode; + data['message'] = this.message; + if (this.responseInpatientAdvanceInfo != null) { + data['responseInpatientAdvanceInfo'] = this.responseInpatientAdvanceInfo!.map((v) => v.toJson()).toList(); + } + data['statusCode'] = this.statusCode; + return data; + } +} + +class ResponseInpatientAdvanceInfo { + int? admissionNo; + int? admissionReqNo; + String? createdOn; + int? patientId; + int? projectId; + num? requestedAmount; + String? setupId; + int? status; + int? paymentRequestID; + + ResponseInpatientAdvanceInfo({this.admissionNo, this.admissionReqNo, this.createdOn, this.patientId, this.projectId, this.requestedAmount, this.setupId, this.status, this.paymentRequestID}); + + ResponseInpatientAdvanceInfo.fromJson(Map json) { + admissionNo = json['admissionNo']; + admissionReqNo = json['admissionReqNo']; + createdOn = json['createdOn']; + patientId = json['patientId']; + projectId = json['projectId']; + requestedAmount = json['requestedAmount']; + setupId = json['setupId']; + status = json['status']; + paymentRequestID = json['PaymentRequestId']; + } + + Map toJson() { + final Map data = new Map(); + data['admissionNo'] = this.admissionNo; + data['admissionReqNo'] = this.admissionReqNo; + data['createdOn'] = this.createdOn; + data['patientId'] = this.patientId; + data['projectId'] = this.projectId; + data['requestedAmount'] = this.requestedAmount; + data['setupId'] = this.setupId; + data['status'] = this.status; + data['PaymentRequestId'] = this.paymentRequestID; + return data; + } +} diff --git a/lib/models/InPatientServices/get_meal_items_schedule_response_model.dart b/lib/models/InPatientServices/get_meal_items_schedule_response_model.dart new file mode 100644 index 00000000..5d3f7ddb --- /dev/null +++ b/lib/models/InPatientServices/get_meal_items_schedule_response_model.dart @@ -0,0 +1,74 @@ +import 'package:flutter/material.dart'; + +class GetMealItemsScheduleResponseModel { + int? itemID; + String? description; + String? descriptionN; + dynamic comment; + dynamic commentN; + String? imageURL; + bool? isDefault; + int? categoryID; + String? categoryDescription; + String? categoryDescriptionN; + int? scheduleID; + int? cal; + + GetMealItemsScheduleResponseModel( + {this.itemID, + this.description, + this.descriptionN, + this.comment, + this.commentN, + this.imageURL, + this.isDefault, + this.categoryID, + this.categoryDescription, + this.categoryDescriptionN, + this.scheduleID, + this.cal}); + + GetMealItemsScheduleResponseModel.fromJson(Map json) { + itemID = json['ItemID']; + description = json['Description']; + descriptionN = json['DescriptionN']; + comment = json['Comment']; + commentN = json['CommentN']; + imageURL = json['ImageURL']; + isDefault = json['IsDefault']; + categoryID = json['CategoryID']; + categoryDescription = json['CategoryDescription']; + categoryDescriptionN = json['CategoryDescriptionN']; + scheduleID = json['ScheduleID']; + cal = json['cal']; + } + + Map toJson() { + final Map data = new Map(); + data['ItemID'] = this.itemID; + data['Description'] = this.description; + data['DescriptionN'] = this.descriptionN; + data['Comment'] = this.comment; + data['CommentN'] = this.commentN; + data['ImageURL'] = this.imageURL; + data['IsDefault'] = this.isDefault; + data['CategoryID'] = this.categoryID; + data['CategoryDescription'] = this.categoryDescription; + data['CategoryDescriptionN'] = this.categoryDescriptionN; + data['ScheduleID'] = this.scheduleID; + data['cal'] = this.cal; + return data; + } +} + +class GetMealItemsScheduleResponseModelList { + String? filterName; + List getMealItemsScheduleResponseModelList = []; + + // int selectedItemID = 0; + final ValueNotifier selectedItemID = ValueNotifier(0); + + GetMealItemsScheduleResponseModelList({this.filterName, GetMealItemsScheduleResponseModel? getMealItemsScheduleResponseModel}) { + getMealItemsScheduleResponseModelList.add(getMealItemsScheduleResponseModel!); + } +} diff --git a/lib/models/InPatientServices/get_meals_schedule_response_model.dart b/lib/models/InPatientServices/get_meals_schedule_response_model.dart new file mode 100644 index 00000000..c691ee84 --- /dev/null +++ b/lib/models/InPatientServices/get_meals_schedule_response_model.dart @@ -0,0 +1,60 @@ +class GetMealsScheduleResponseModel { + int? scheduleID; + int? mealID; + String? description; + String? descriptionN; + int? weekID; + String? weekDescription; + String? weekDescriptionN; + String? tAT; + int? dietTypeID; + int? dayID; + bool? isShow; + String? tATTime; + + GetMealsScheduleResponseModel( + {this.scheduleID, + this.mealID, + this.description, + this.descriptionN, + this.weekID, + this.weekDescription, + this.weekDescriptionN, + this.tAT, + this.dietTypeID, + this.dayID, + this.isShow, + this.tATTime}); + + GetMealsScheduleResponseModel.fromJson(Map json) { + scheduleID = json['ScheduleID']; + mealID = json['MealID']; + description = json['Description']; + descriptionN = json['DescriptionN']; + weekID = json['WeekID']; + weekDescription = json['WeekDescription']; + weekDescriptionN = json['WeekDescriptionN']; + tAT = json['TAT']; + dietTypeID = json['DietTypeID']; + dayID = json['DayID']; + isShow = json['IsShow']; + tATTime = json['TATTime']; + } + + Map toJson() { + final Map data = new Map(); + data['ScheduleID'] = this.scheduleID; + data['MealID'] = this.mealID; + data['Description'] = this.description; + data['DescriptionN'] = this.descriptionN; + data['WeekID'] = this.weekID; + data['WeekDescription'] = this.weekDescription; + data['WeekDescriptionN'] = this.weekDescriptionN; + data['TAT'] = this.tAT; + data['DietTypeID'] = this.dietTypeID; + data['DayID'] = this.dayID; + data['IsShow'] = this.isShow; + data['TATTime'] = this.tATTime; + return data; + } +} diff --git a/lib/models/InPatientServices/get_medical_instructions_response_model.dart b/lib/models/InPatientServices/get_medical_instructions_response_model.dart new file mode 100644 index 00000000..110975ba --- /dev/null +++ b/lib/models/InPatientServices/get_medical_instructions_response_model.dart @@ -0,0 +1,85 @@ +class GetMedicalInstructions { + dynamic propertyChanged; + int? admissionRequestNoField; + String? clinicNameField; + String? doctorNameField; + String? expectedAdmissionDateField; + List? medicaLInstructionsField; + dynamic medicalInstructionsXMLField; + String? medicalRemarksField; + int? projectIdField; + String? projectNameField; + String? setupIdField; + + GetMedicalInstructions( + {this.propertyChanged, + this.admissionRequestNoField, + this.clinicNameField, + this.doctorNameField, + this.expectedAdmissionDateField, + this.medicaLInstructionsField, + this.medicalInstructionsXMLField, + this.medicalRemarksField, + this.projectIdField, + this.projectNameField, + this.setupIdField}); + + GetMedicalInstructions.fromJson(Map json) { + propertyChanged = json['PropertyChanged']; + admissionRequestNoField = json['admissionRequestNoField']; + clinicNameField = json['clinicNameField']; + doctorNameField = json['doctorNameField']; + expectedAdmissionDateField = json['expectedAdmissionDateField']; + if (json['medicaLInstructions'] != null) { + medicaLInstructionsField = []; + json['medicaLInstructions'].forEach((v) { + medicaLInstructionsField!.add(new MedicaLInstructionsField.fromJson(v)); + }); + } + medicalInstructionsXMLField = json['medicalInstructionsXMLField']; + medicalRemarksField = json['medicalRemarksField']; + projectIdField = json['projectIdField']; + projectNameField = json['projectNameField']; + setupIdField = json['setupIdField']; + } + + Map toJson() { + final Map data = new Map(); + data['PropertyChanged'] = this.propertyChanged; + data['admissionRequestNoField'] = this.admissionRequestNoField; + data['clinicNameField'] = this.clinicNameField; + data['doctorNameField'] = this.doctorNameField; + data['expectedAdmissionDateField'] = this.expectedAdmissionDateField; + if (this.medicaLInstructionsField != null) { + data['medicaLInstructionsField'] = this.medicaLInstructionsField!.map((v) => v.toJson()).toList(); + } + data['medicalInstructionsXMLField'] = this.medicalInstructionsXMLField; + data['medicalRemarksField'] = this.medicalRemarksField; + data['projectIdField'] = this.projectIdField; + data['projectNameField'] = this.projectNameField; + data['setupIdField'] = this.setupIdField; + return data; + } +} + +class MedicaLInstructionsField { + Null propertyChanged; + String? descriptionField; + int? parameterCodeField; + + MedicaLInstructionsField({this.propertyChanged, this.descriptionField, this.parameterCodeField}); + + MedicaLInstructionsField.fromJson(Map json) { + propertyChanged = json['PropertyChanged']; + descriptionField = json['description']; + parameterCodeField = json['parameterCodeField']; + } + + Map toJson() { + final Map data = new Map(); + data['PropertyChanged'] = this.propertyChanged; + data['descriptionField'] = this.descriptionField; + data['parameterCodeField'] = this.parameterCodeField; + return data; + } +} diff --git a/lib/models/LiveCare/ApplePayInsertRequest.dart b/lib/models/LiveCare/ApplePayInsertRequest.dart new file mode 100644 index 00000000..6a7f1ac6 --- /dev/null +++ b/lib/models/LiveCare/ApplePayInsertRequest.dart @@ -0,0 +1,187 @@ +class ApplePayInsertRequest { + String? clientRequestID; + int? clinicID; + String? currency; + String? customerEmail; + dynamic customerID; + String? customerName; + String? deviceToken; + String? voipToken; + int? doctorID; + String? projectID; + String? serviceID; + int? channelID; + dynamic patientID; + int? patientTypeID; + int? patientOutSA; + dynamic appointmentDate; + int? appointmentNo; + String? orderDescription; + String? liveServiceID; + String? latitude; + String? longitude; + String? amount; + String? isSchedule; + String? language; + int? userName; + String? responseContinueURL; + String? backClickUrl; + String? paymentOption; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + String? sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + bool? isMobSDK; + String? merchantReference; + String? merchantIdentifier; + String? commandType; + String? signature; + String? accessCode; + String? shaRequestPhrase; + String? shaResponsePhrase; + String? returnURL; + + ApplePayInsertRequest( + {this.clientRequestID, + this.clinicID, + this.currency, + this.customerEmail, + this.customerID, + this.customerName, + this.deviceToken, + this.voipToken, + this.doctorID, + this.projectID, + this.serviceID, + this.channelID, + this.patientID, + this.patientTypeID, + this.patientOutSA, + this.appointmentDate, + this.appointmentNo, + this.orderDescription, + this.liveServiceID, + this.latitude, + this.longitude, + this.amount, + this.isSchedule, + this.language, + this.userName, + this.responseContinueURL, + this.backClickUrl, + this.paymentOption, + this.versionID, + this.channel, + this.languageID, + this.iPAdress, + this.generalid, + this.sessionID, + this.isDentalAllowedBackend, + this.deviceTypeID, + this.isMobSDK, + this.merchantReference, + this.merchantIdentifier, + this.commandType, + this.signature, + this.accessCode, + this.shaRequestPhrase, + this.shaResponsePhrase, + this.returnURL, + }); + + ApplePayInsertRequest.fromJson(Map json) { + clientRequestID = json['ClientRequestID']; + clinicID = json['ClinicID']; + currency = json['Currency']; + customerEmail = json['CustomerEmail']; + customerID = json['CustomerID']; + customerName = json['CustomerName']; + deviceToken = json['DeviceToken']; + voipToken = json['VoipToken']; + doctorID = json['DoctorID']; + projectID = json['ProjectID']; + serviceID = json['Service_ID']; + channelID = json['Channel_ID']; + patientID = json['PatientID']; + patientTypeID = json['PatientTypeID']; + patientOutSA = json['PatientOutSA']; + appointmentDate = json['AppointmentDate']; + appointmentNo = json['AppointmentNo']; + orderDescription = json['OrderDescription']; + liveServiceID = json['Live_ServiceID']; + latitude = json['Latitude']; + longitude = json['Longitude']; + amount = json['Amount']; + isSchedule = json['IsSchedule']; + language = json['Language']; + userName = json['userName']; + responseContinueURL = json['ResponseContinueURL']; + backClickUrl = json['BackClickUrl']; + paymentOption = json['PaymentOption']; + versionID = json['VersionID']; + channel = json['Channel']; + languageID = json['LanguageID']; + iPAdress = json['IPAdress']; + generalid = json['generalid']; + sessionID = json['SessionID']; + isDentalAllowedBackend = json['isDentalAllowedBackend']; + deviceTypeID = json['DeviceTypeID']; + } + + Map toJson() { + final Map data = new Map(); + data['ClientRequestID'] = this.clientRequestID; + data['ClinicID'] = this.clinicID; + data['Currency'] = this.currency; + data['CustomerEmail'] = this.customerEmail; + data['CustomerID'] = this.customerID; + data['CustomerName'] = this.customerName; + data['DeviceToken'] = this.deviceToken; + data['VoipToken'] = this.voipToken; + data['DoctorID'] = this.doctorID; + data['ProjectID'] = this.projectID; + data['Service_ID'] = this.serviceID; + data['Channel_ID'] = this.channelID; + data['PatientID'] = this.patientID; + data['PatientId'] = this.patientID; + data['PatientTypeID'] = this.patientTypeID; + data['PatientOutSA'] = this.patientOutSA; + data['AppointmentDate'] = this.appointmentDate; + data['AppointmentNo'] = this.appointmentNo; + data['OrderDescription'] = this.orderDescription; + data['Live_ServiceID'] = this.liveServiceID; + data['Latitude'] = this.latitude; + data['Longitude'] = this.longitude; + data['Amount'] = this.amount; + data['IsSchedule'] = this.isSchedule; + data['Language'] = this.language; + data['userName'] = this.userName; + data['ResponseContinueURL'] = this.responseContinueURL; + data['BackClickUrl'] = this.backClickUrl; + data['PaymentOption'] = this.paymentOption; + data['VersionID'] = this.versionID; + data['Channel'] = this.channel; + data['LanguageID'] = this.languageID; + data['IPAdress'] = this.iPAdress; + data['generalid'] = this.generalid; + data['SessionID'] = this.sessionID; + data['isDentalAllowedBackend'] = this.isDentalAllowedBackend; + data['DeviceTypeID'] = this.deviceTypeID; + + data['IsMobSDK'] = this.isMobSDK; + data['Merchant_Reference'] = this.merchantReference; + data['Merchant_Identifier'] = this.merchantIdentifier; + data['CommandType'] = this.commandType; + data['Signature'] = this.signature; + data['Access_code'] = this.accessCode; + data['SHA_RequestPhase'] = this.shaRequestPhrase; + data['SHA_ResponsePhase'] = this.shaResponsePhrase; + data['ReturnURL'] = this.returnURL; + + return data; + } +} diff --git a/lib/models/LiveCare/ClinicsServiceTimingsResponse.dart b/lib/models/LiveCare/ClinicsServiceTimingsResponse.dart index 223b633f..a7f5c12b 100644 --- a/lib/models/LiveCare/ClinicsServiceTimingsResponse.dart +++ b/lib/models/LiveCare/ClinicsServiceTimingsResponse.dart @@ -1,16 +1,13 @@ class ClinicsServiceTimingsResponse { - List - patientERGetClinicsServiceTimingsList; + List? patientERGetClinicsServiceTimingsList; ClinicsServiceTimingsResponse({this.patientERGetClinicsServiceTimingsList}); ClinicsServiceTimingsResponse.fromJson(Map json) { if (json['PatientER_GetClinicsServiceTimingsList'] != null) { - patientERGetClinicsServiceTimingsList = - new List(); + patientERGetClinicsServiceTimingsList = []; json['PatientER_GetClinicsServiceTimingsList'].forEach((v) { - patientERGetClinicsServiceTimingsList - .add(new PatientERGetClinicsServiceTimingsList.fromJson(v)); + patientERGetClinicsServiceTimingsList!.add(new PatientERGetClinicsServiceTimingsList.fromJson(v)); }); } } @@ -18,44 +15,41 @@ class ClinicsServiceTimingsResponse { Map toJson() { final Map data = new Map(); if (this.patientERGetClinicsServiceTimingsList != null) { - data['PatientER_GetClinicsServiceTimingsList'] = this - .patientERGetClinicsServiceTimingsList - .map((v) => v.toJson()) - .toList(); + data['PatientER_GetClinicsServiceTimingsList'] = this.patientERGetClinicsServiceTimingsList!.map((v) => v.toJson()).toList(); } return data; } } class PatientERGetClinicsServiceTimingsList { - int iD; - int serviceID; - Null shiftID; - int dayOfWeek; - String dayOfWeekStr; - Null startTime; - Null endTime; - bool isActive; - String createdOn; - String createdBy; - bool projectOutSA; - String dayOfWeekStrN; - List shiftTimings; + int? iD; + int? serviceID; + dynamic shiftID; + int? dayOfWeek; + String? dayOfWeekStr; + dynamic startTime; + dynamic endTime; + bool? isActive; + String? createdOn; + String? createdBy; + bool? projectOutSA; + String? dayOfWeekStrN; + List? shiftTimings; PatientERGetClinicsServiceTimingsList( {this.iD, - this.serviceID, - this.shiftID, - this.dayOfWeek, - this.dayOfWeekStr, - this.startTime, - this.endTime, - this.isActive, - this.createdOn, - this.createdBy, - this.projectOutSA, - this.dayOfWeekStrN, - this.shiftTimings}); + this.serviceID, + this.shiftID, + this.dayOfWeek, + this.dayOfWeekStr, + this.startTime, + this.endTime, + this.isActive, + this.createdOn, + this.createdBy, + this.projectOutSA, + this.dayOfWeekStrN, + this.shiftTimings}); PatientERGetClinicsServiceTimingsList.fromJson(Map json) { iD = json['ID']; @@ -71,9 +65,9 @@ class PatientERGetClinicsServiceTimingsList { projectOutSA = json['ProjectOutSA']; dayOfWeekStrN = json['DayOfWeekStrN']; if (json['ShiftTimings'] != null) { - shiftTimings = new List(); + shiftTimings = []; json['ShiftTimings'].forEach((v) { - shiftTimings.add(new ShiftTimings.fromJson(v)); + shiftTimings!.add(new ShiftTimings.fromJson(v)); }); } } @@ -93,16 +87,16 @@ class PatientERGetClinicsServiceTimingsList { data['ProjectOutSA'] = this.projectOutSA; data['DayOfWeekStrN'] = this.dayOfWeekStrN; if (this.shiftTimings != null) { - data['ShiftTimings'] = this.shiftTimings.map((v) => v.toJson()).toList(); + data['ShiftTimings'] = this.shiftTimings!.map((v) => v.toJson()).toList(); } return data; } } class ShiftTimings { - String endTime; - int shiftID; - String startTime; + String? endTime; + int? shiftID; + String? startTime; ShiftTimings({this.endTime, this.shiftID, this.startTime}); diff --git a/lib/models/LiveCare/ERAppointmentFeesResponse.dart b/lib/models/LiveCare/ERAppointmentFeesResponse.dart index a6cc061a..3deaa05b 100644 --- a/lib/models/LiveCare/ERAppointmentFeesResponse.dart +++ b/lib/models/LiveCare/ERAppointmentFeesResponse.dart @@ -1,5 +1,5 @@ class ERAppointmentFeesResponse { - GetERAppointmentFeesList getERAppointmentFeesList; + GetERAppointmentFeesList? getERAppointmentFeesList; ERAppointmentFeesResponse({this.getERAppointmentFeesList}); @@ -13,20 +13,22 @@ class ERAppointmentFeesResponse { Map toJson() { final Map data = new Map(); if (this.getERAppointmentFeesList != null) { - data['GetERAppointmentFeesList'] = this.getERAppointmentFeesList.toJson(); + data['GetERAppointmentFeesList'] = this.getERAppointmentFeesList!.toJson(); } return data; } } class GetERAppointmentFeesList { - String amount; - String companyName; - bool isInsured; - bool isShowInsuranceUpdateModule; - String tax; - String total; - String currency; + String? amount; + String? companyName; + bool? isInsured; + bool? isShowInsuranceUpdateModule; + bool? isCash; + bool? isEligible; + String? tax; + String? total; + String? currency; GetERAppointmentFeesList( {this.amount, @@ -41,6 +43,8 @@ class GetERAppointmentFeesList { amount = json['Amount']; companyName = json['CompanyName']; isInsured = json['IsInsured']; + isCash = json['IsCash']; + isEligible = json['IsEligible']; isShowInsuranceUpdateModule = json['IsShowInsuranceUpdateModule']; tax = json['Tax']; total = json['Total']; diff --git a/lib/models/LiveCare/IncomingCallData.dart b/lib/models/LiveCare/IncomingCallData.dart index 9234c876..e357a5df 100644 --- a/lib/models/LiveCare/IncomingCallData.dart +++ b/lib/models/LiveCare/IncomingCallData.dart @@ -1,27 +1,32 @@ class IncomingCallData { - String msgID; - String notfID; - String notificationForeground; - String count; - String message; - String appointmentNo; - String title; - String projectID; - String notificationType; - String background; - String doctorname; - String clinicname; - String speciality; - String appointmentdate; - String appointmenttime; - String type; - String sessionId; - String identity; - String name; - String videoUrl; - String picture; - String isCall; - String sound; + String? callerID; + String? receiverID; + String? msgID; + String? notfID; + String? notificationForeground; + String? count; + String? message; + String? appointmentNo; // 1 for Video call, 2 for Audio call + String? title; + String? projectID; + String? notificationType; + String? background; // 0 for Zoom, 1 for OpenTok + String? doctorname; + String? clinicname; + String? speciality; + String? appointmentdate; + String? appointmenttime; + String? type; + String? sessionId; + String? identity; + String? name; + String? videoUrl; + String? picture; + String? token; + String? isCall; + String? sound; + String? server; + String? isWebRTC; IncomingCallData( {this.msgID, @@ -49,6 +54,8 @@ class IncomingCallData { this.sound}); IncomingCallData.fromJson(Map json) { + callerID = json['callerID']; + receiverID = json['PatientID']; msgID = json['msgID']; notfID = json['notfID']; notificationForeground = json['notification_foreground']; @@ -66,12 +73,15 @@ class IncomingCallData { appointmenttime = json['appointmenttime']; type = json['type']; sessionId = json['session_id']; + token = json['token']; identity = json['identity']; name = json['name']; videoUrl = json['videoUrl']; picture = json['picture']; isCall = json['is_call']; sound = json['sound']; + server = json['server']; + isWebRTC = json['isWebRTC'] ?? "false"; } Map toJson() { @@ -93,12 +103,15 @@ class IncomingCallData { data['appointmenttime'] = this.appointmenttime; data['type'] = this.type; data['session_id'] = this.sessionId; + data['token'] = this.token; data['identity'] = this.identity; data['name'] = this.name; data['videoUrl'] = this.videoUrl; data['picture'] = this.picture; data['is_call'] = this.isCall; data['sound'] = this.sound; + data['server'] = this.server; + data['isWebRTC'] = this.isWebRTC; return data; } } diff --git a/lib/models/LiveCare/LiveCareClinicsListResponse.dart b/lib/models/LiveCare/LiveCareClinicsListResponse.dart index 094fb1a5..687b3763 100644 --- a/lib/models/LiveCare/LiveCareClinicsListResponse.dart +++ b/lib/models/LiveCare/LiveCareClinicsListResponse.dart @@ -1,13 +1,13 @@ class LiveCareClinicsListResponse { - List patientERGetClinicsList; + List? patientERGetClinicsList; LiveCareClinicsListResponse({this.patientERGetClinicsList}); LiveCareClinicsListResponse.fromJson(Map json) { if (json['PatientER_GetClinicsList'] != null) { - patientERGetClinicsList = new List(); + patientERGetClinicsList = []; json['PatientER_GetClinicsList'].forEach((v) { - patientERGetClinicsList.add(new PatientERGetClinicsList.fromJson(v)); + patientERGetClinicsList!.add(new PatientERGetClinicsList.fromJson(v)); }); } } @@ -15,48 +15,47 @@ class LiveCareClinicsListResponse { Map toJson() { final Map data = new Map(); if (this.patientERGetClinicsList != null) { - data['PatientER_GetClinicsList'] = - this.patientERGetClinicsList.map((v) => v.toJson()).toList(); + data['PatientER_GetClinicsList'] = this.patientERGetClinicsList!.map((v) => v.toJson()).toList(); } return data; } } class PatientERGetClinicsList { - int iD; - int serviceID; - String serviceName; - String serviceNameN; - int clinicID; - int age; - bool isCheckAgeBelow; - int gender; - bool isActive; - String createdOn; - String createdBy; - int isOnline; - Null endTime; - bool projectOutSA; - List shiftTimings; - Null startTime; + int? iD; + int? serviceID; + String? serviceName; + String? serviceNameN; + int? clinicID; + int? age; + bool? isCheckAgeBelow; + int? gender; + bool? isActive; + String? createdOn; + String? createdBy; + int? isOnline; + dynamic endTime; + bool? projectOutSA; + List? shiftTimings; + dynamic startTime; PatientERGetClinicsList( {this.iD, - this.serviceID, - this.serviceName, - this.serviceNameN, - this.clinicID, - this.age, - this.isCheckAgeBelow, - this.gender, - this.isActive, - this.createdOn, - this.createdBy, - this.isOnline, - this.endTime, - this.projectOutSA, - this.shiftTimings, - this.startTime}); + this.serviceID, + this.serviceName, + this.serviceNameN, + this.clinicID, + this.age, + this.isCheckAgeBelow, + this.gender, + this.isActive, + this.createdOn, + this.createdBy, + this.isOnline, + this.endTime, + this.projectOutSA, + this.shiftTimings, + this.startTime}); PatientERGetClinicsList.fromJson(Map json) { iD = json['ID']; @@ -74,9 +73,9 @@ class PatientERGetClinicsList { endTime = json['EndTime']; projectOutSA = json['ProjectOutSA']; if (json['ShiftTimings'] != null) { - shiftTimings = new List(); + shiftTimings = []; json['ShiftTimings'].forEach((v) { - shiftTimings.add(new ShiftTimings.fromJson(v)); + shiftTimings!.add(new ShiftTimings.fromJson(v)); }); } startTime = json['StartTime']; @@ -99,7 +98,7 @@ class PatientERGetClinicsList { data['EndTime'] = this.endTime; data['ProjectOutSA'] = this.projectOutSA; if (this.shiftTimings != null) { - data['ShiftTimings'] = this.shiftTimings.map((v) => v.toJson()).toList(); + data['ShiftTimings'] = this.shiftTimings!.map((v) => v.toJson()).toList(); } data['StartTime'] = this.startTime; return data; @@ -107,9 +106,9 @@ class PatientERGetClinicsList { } class ShiftTimings { - String endTime; - int shiftID; - String startTime; + String? endTime; + int? shiftID; + String? startTime; ShiftTimings({this.endTime, this.shiftID, this.startTime}); diff --git a/lib/models/LiveCare/LiveCareScheduleClinicsListResponse.dart b/lib/models/LiveCare/LiveCareScheduleClinicsListResponse.dart index 8951370c..c915cfe7 100644 --- a/lib/models/LiveCare/LiveCareScheduleClinicsListResponse.dart +++ b/lib/models/LiveCare/LiveCareScheduleClinicsListResponse.dart @@ -1,13 +1,13 @@ class LiveCareScheduleClinicsListResponse { - List clinicsHaveScheduleList; + List? clinicsHaveScheduleList; LiveCareScheduleClinicsListResponse({this.clinicsHaveScheduleList}); LiveCareScheduleClinicsListResponse.fromJson(Map json) { if (json['ClinicsHaveScheduleList'] != null) { - clinicsHaveScheduleList = new List(); + clinicsHaveScheduleList = []; json['ClinicsHaveScheduleList'].forEach((v) { - clinicsHaveScheduleList.add(new ClinicsHaveScheduleList.fromJson(v)); + clinicsHaveScheduleList!.add(new ClinicsHaveScheduleList.fromJson(v)); }); } } @@ -16,20 +16,20 @@ class LiveCareScheduleClinicsListResponse { final Map data = new Map(); if (this.clinicsHaveScheduleList != null) { data['ClinicsHaveScheduleList'] = - this.clinicsHaveScheduleList.map((v) => v.toJson()).toList(); + this.clinicsHaveScheduleList!.map((v) => v.toJson()).toList(); } return data; } } class ClinicsHaveScheduleList { - int clinicID; - int serviceID; - int projectID; - String clinicDesc; - String clinicDescN; - String projectDesc; - String projectDescN; + int? clinicID; + int? serviceID; + int? projectID; + String? clinicDesc; + String? clinicDescN; + String? projectDesc; + String? projectDescN; ClinicsHaveScheduleList( {this.clinicID, diff --git a/lib/models/LiveCare/insertVIDARequest.dart b/lib/models/LiveCare/insertVIDARequest.dart index 938ca102..b6037d29 100644 --- a/lib/models/LiveCare/insertVIDARequest.dart +++ b/lib/models/LiveCare/insertVIDARequest.dart @@ -1,24 +1,24 @@ class insertVIDARequest { - int patientID; - int acceptedBy; - int appointmentNo; - String deviceToken; - double latitude; - double longitude; - int serviceID; - int projectID; - int clinicID; - String deviceType; - String voipToken; - double versionID; - int channel; - int languageID; - String iPAdress; - String generalid; - int patientOutSA; - String sessionID; - bool isDentalAllowedBackend; - int deviceTypeID; + int? patientID; + int? acceptedBy; + int? appointmentNo; + String? deviceToken; + double? latitude; + double? longitude; + int? serviceID; + int? projectID; + int? clinicID; + String? deviceType; + String? voipToken; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + String? sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; insertVIDARequest( {this.patientID, diff --git a/lib/models/LiveCare/room_model.dart b/lib/models/LiveCare/room_model.dart index 6ab64d1d..7e365a0f 100644 --- a/lib/models/LiveCare/room_model.dart +++ b/lib/models/LiveCare/room_model.dart @@ -2,11 +2,11 @@ import 'package:diplomaticquarterapp/models/LiveCare/room_validators.dart'; import 'package:diplomaticquarterapp/models/LiveCare/twilio_enums.dart'; class RoomModel with RoomValidators { - final String name; - final bool isLoading; + final String? name; + final bool? isLoading; final bool isSubmitted; - final String token; - final String identity; + final String? token; + final String? identity; final TwilioRoomType type; RoomModel({ @@ -34,7 +34,7 @@ class RoomModel with RoomValidators { } String get nameErrorText { - return isSubmitted && !nameValidator.isValid(name) ? invalidNameErrorText : null; + return isSubmitted && !nameValidator.isValid(name!) ? invalidNameErrorText : ""; } String get typeText { @@ -42,16 +42,16 @@ class RoomModel with RoomValidators { } bool get canSubmit { - return nameValidator.isValid(name); + return nameValidator.isValid(name!); } RoomModel copyWith({ - String name, - bool isLoading, - bool isSubmitted, - String token, - String identity, - TwilioRoomType type, + String? name, + bool? isLoading, + bool? isSubmitted, + String? token, + String? identity, + TwilioRoomType? type, }) { return RoomModel( name: name ?? this.name, diff --git a/lib/models/MyInvoices/DentalInvoiceDetailResponse.dart b/lib/models/MyInvoices/DentalInvoiceDetailResponse.dart new file mode 100644 index 00000000..3d095be0 --- /dev/null +++ b/lib/models/MyInvoices/DentalInvoiceDetailResponse.dart @@ -0,0 +1,487 @@ +class DentalInvoiceDetailResponse { + List? listEInvoiceForDental; + + DentalInvoiceDetailResponse({this.listEInvoiceForDental}); + + DentalInvoiceDetailResponse.fromJson(Map json) { + if (json['List_eInvoiceForDental'] != null) { + listEInvoiceForDental = []; + json['List_eInvoiceForDental'].forEach((v) { + listEInvoiceForDental!.add(new ListEInvoiceForDental.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + if (this.listEInvoiceForDental != null) { + data['List_eInvoiceForDental'] = this.listEInvoiceForDental!.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class ListEInvoiceForDental { + int? projectID; + int? doctorID; + dynamic grandTotal; + dynamic quantity; + dynamic total; + dynamic discount; + dynamic subTotal; + int? invoiceNo; + String? createdOn; + dynamic procedureID; + dynamic procedureName; + dynamic procedureNameN; + dynamic procedurePrice; + dynamic patientShare; + dynamic companyShare; + dynamic totalPatientShare; + dynamic totalCompanyShare; + dynamic totalShare; + dynamic discountAmount; + dynamic vATPercentage; + dynamic patientVATAmount; + dynamic companyVATAmount; + dynamic totalVATAmount; + dynamic price; + int? patientID; + String? patientName; + dynamic patientNameN; + String? nationalityID; + String? doctorName; + dynamic doctorNameN; + int? clinicID; + String? clinicDescription; + dynamic clinicDescriptionN; + String? appointmentDate; + int? appointmentNo; + String? insuranceID; + int? companyID; + String? companyName; + dynamic companyNameN; + String? companyAddress; + dynamic companyAddressN; + String? companyGroupAddress; + String? groupName; + dynamic groupNameN; + String? patientAddress; + String? vATNo; + String? paymentDate; + String? projectName; + dynamic totalDiscount; + dynamic totalPatientShareWithQuantity; + String? legalName; + dynamic legalNameN; + dynamic advanceAdjustment; + String? doctorImageURL; + List? listConsultation; + + ListEInvoiceForDental( + {this.projectID, + this.doctorID, + this.grandTotal, + this.quantity, + this.total, + this.discount, + this.subTotal, + this.invoiceNo, + this.createdOn, + this.procedureID, + this.procedureName, + this.procedureNameN, + this.procedurePrice, + this.patientShare, + this.companyShare, + this.totalPatientShare, + this.totalCompanyShare, + this.totalShare, + this.discountAmount, + this.vATPercentage, + this.patientVATAmount, + this.companyVATAmount, + this.totalVATAmount, + this.price, + this.patientID, + this.patientName, + this.patientNameN, + this.nationalityID, + this.doctorName, + this.doctorNameN, + this.clinicID, + this.clinicDescription, + this.clinicDescriptionN, + this.appointmentDate, + this.appointmentNo, + this.insuranceID, + this.companyID, + this.companyName, + this.companyNameN, + this.companyAddress, + this.companyAddressN, + this.companyGroupAddress, + this.groupName, + this.groupNameN, + this.patientAddress, + this.vATNo, + this.paymentDate, + this.projectName, + this.totalDiscount, + this.totalPatientShareWithQuantity, + this.legalName, + this.legalNameN, + this.advanceAdjustment, + this.doctorImageURL, + this.listConsultation}); + + ListEInvoiceForDental.fromJson(Map json) { + projectID = json['ProjectID']; + doctorID = json['DoctorID']; + grandTotal = json['GrandTotal']; + quantity = json['Quantity']; + total = json['Total']; + discount = json['Discount']; + subTotal = json['SubTotal']; + invoiceNo = json['InvoiceNo']; + createdOn = json['CreatedOn']; + procedureID = json['ProcedureID']; + procedureName = json['ProcedureName']; + procedureNameN = json['ProcedureNameN']; + procedurePrice = json['ProcedurePrice']; + patientShare = json['PatientShare']; + companyShare = json['CompanyShare']; + totalPatientShare = json['TotalPatientShare']; + totalCompanyShare = json['TotalCompanyShare']; + totalShare = json['TotalShare']; + discountAmount = json['DiscountAmount']; + vATPercentage = json['VATPercentage']; + patientVATAmount = json['PatientVATAmount']; + companyVATAmount = json['CompanyVATAmount']; + totalVATAmount = json['TotalVATAmount']; + price = json['Price']; + patientID = json['PatientID']; + patientName = json['PatientName']; + patientNameN = json['PatientNameN']; + nationalityID = json['NationalityID']; + doctorName = json['DoctorName']; + doctorNameN = json['DoctorNameN']; + clinicID = json['ClinicID']; + clinicDescription = json['ClinicDescription']; + clinicDescriptionN = json['ClinicDescriptionN']; + appointmentDate = json['AppointmentDate']; + appointmentNo = json['AppointmentNo']; + insuranceID = json['InsuranceID']; + companyID = json['CompanyID']; + companyName = json['CompanyName']; + companyNameN = json['CompanyNameN']; + companyAddress = json['CompanyAddress']; + companyAddressN = json['CompanyAddressN']; + companyGroupAddress = json['CompanyGroupAddress']; + groupName = json['GroupName']; + groupNameN = json['GroupNameN']; + patientAddress = json['PatientAddress']; + vATNo = json['VATNo']; + paymentDate = json['PaymentDate']; + projectName = json['ProjectName']; + totalDiscount = json['TotalDiscount']; + totalPatientShareWithQuantity = json['TotalPatientShareWithQuantity']; + legalName = json['LegalName']; + legalNameN = json['LegalNameN']; + advanceAdjustment = json['AdvanceAdjustment']; + doctorImageURL = json['DoctorImageURL']; + if (json['listConsultation'] != null) { + listConsultation =[]; + json['listConsultation'].forEach((v) { + listConsultation!.add(new ListConsultation.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + data['ProjectID'] = this.projectID; + data['DoctorID'] = this.doctorID; + data['GrandTotal'] = this.grandTotal; + data['Quantity'] = this.quantity; + data['Total'] = this.total; + data['Discount'] = this.discount; + data['SubTotal'] = this.subTotal; + data['InvoiceNo'] = this.invoiceNo; + data['CreatedOn'] = this.createdOn; + data['ProcedureID'] = this.procedureID; + data['ProcedureName'] = this.procedureName; + data['ProcedureNameN'] = this.procedureNameN; + data['ProcedurePrice'] = this.procedurePrice; + data['PatientShare'] = this.patientShare; + data['CompanyShare'] = this.companyShare; + data['TotalPatientShare'] = this.totalPatientShare; + data['TotalCompanyShare'] = this.totalCompanyShare; + data['TotalShare'] = this.totalShare; + data['DiscountAmount'] = this.discountAmount; + data['VATPercentage'] = this.vATPercentage; + data['PatientVATAmount'] = this.patientVATAmount; + data['CompanyVATAmount'] = this.companyVATAmount; + data['TotalVATAmount'] = this.totalVATAmount; + data['Price'] = this.price; + data['PatientID'] = this.patientID; + data['PatientName'] = this.patientName; + data['PatientNameN'] = this.patientNameN; + data['NationalityID'] = this.nationalityID; + data['DoctorName'] = this.doctorName; + data['DoctorNameN'] = this.doctorNameN; + data['ClinicID'] = this.clinicID; + data['ClinicDescription'] = this.clinicDescription; + data['ClinicDescriptionN'] = this.clinicDescriptionN; + data['AppointmentDate'] = this.appointmentDate; + data['AppointmentNo'] = this.appointmentNo; + data['InsuranceID'] = this.insuranceID; + data['CompanyID'] = this.companyID; + data['CompanyName'] = this.companyName; + data['CompanyNameN'] = this.companyNameN; + data['CompanyAddress'] = this.companyAddress; + data['CompanyAddressN'] = this.companyAddressN; + data['CompanyGroupAddress'] = this.companyGroupAddress; + data['GroupName'] = this.groupName; + data['GroupNameN'] = this.groupNameN; + data['PatientAddress'] = this.patientAddress; + data['VATNo'] = this.vATNo; + data['PaymentDate'] = this.paymentDate; + data['ProjectName'] = this.projectName; + data['TotalDiscount'] = this.totalDiscount; + data['TotalPatientShareWithQuantity'] = this.totalPatientShareWithQuantity; + data['LegalName'] = this.legalName; + data['LegalNameN'] = this.legalNameN; + data['AdvanceAdjustment'] = this.advanceAdjustment; + data['DoctorImageURL'] = this.doctorImageURL; + if (this.listConsultation != null) { + data['listConsultation'] = this.listConsultation!.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class ListConsultation { + dynamic projectID; + dynamic doctorID; + dynamic grandTotal; + dynamic quantity; + dynamic total; + dynamic discount; + dynamic subTotal; + dynamic invoiceNo; + dynamic createdOn; + String? procedureID; + String? procedureName; + dynamic procedureNameN; + dynamic procedurePrice; + dynamic patientShare; + dynamic companyShare; + dynamic totalPatientShare; + dynamic totalCompanyShare; + dynamic totalShare; + dynamic discountAmount; + dynamic vATPercentage; + dynamic patientVATAmount; + dynamic companyVATAmount; + dynamic totalVATAmount; + dynamic price; + dynamic patientID; + dynamic patientName; + dynamic patientNameN; + dynamic nationalityID; + dynamic doctorName; + dynamic doctorNameN; + dynamic clinicID; + dynamic clinicDescription; + dynamic clinicDescriptionN; + dynamic appointmentDate; + dynamic appointmentNo; + dynamic insuranceID; + dynamic companyID; + dynamic companyName; + dynamic companyNameN; + dynamic companyAddress; + dynamic companyAddressN; + dynamic companyGroupAddress; + dynamic groupName; + dynamic groupNameN; + dynamic patientAddress; + String? vATNo; + dynamic paymentDate; + dynamic projectName; + dynamic totalDiscount; + dynamic totalPatientShareWithQuantity; + dynamic legalName; + dynamic legalNameN; + dynamic advanceAdjustment; + + ListConsultation( + {this.projectID, + this.doctorID, + this.grandTotal, + this.quantity, + this.total, + this.discount, + this.subTotal, + this.invoiceNo, + this.createdOn, + this.procedureID, + this.procedureName, + this.procedureNameN, + this.procedurePrice, + this.patientShare, + this.companyShare, + this.totalPatientShare, + this.totalCompanyShare, + this.totalShare, + this.discountAmount, + this.vATPercentage, + this.patientVATAmount, + this.companyVATAmount, + this.totalVATAmount, + this.price, + this.patientID, + this.patientName, + this.patientNameN, + this.nationalityID, + this.doctorName, + this.doctorNameN, + this.clinicID, + this.clinicDescription, + this.clinicDescriptionN, + this.appointmentDate, + this.appointmentNo, + this.insuranceID, + this.companyID, + this.companyName, + this.companyNameN, + this.companyAddress, + this.companyAddressN, + this.companyGroupAddress, + this.groupName, + this.groupNameN, + this.patientAddress, + this.vATNo, + this.paymentDate, + this.projectName, + this.totalDiscount, + this.totalPatientShareWithQuantity, + this.legalName, + this.legalNameN, + this.advanceAdjustment}); + + ListConsultation.fromJson(Map json) { + projectID = json['ProjectID']; + doctorID = json['DoctorID']; + grandTotal = json['GrandTotal']; + quantity = json['Quantity']; + total = json['Total']; + discount = json['Discount']; + subTotal = json['SubTotal']; + invoiceNo = json['InvoiceNo']; + createdOn = json['CreatedOn']; + procedureID = json['ProcedureID']; + procedureName = json['ProcedureName']; + procedureNameN = json['ProcedureNameN']; + procedurePrice = json['ProcedurePrice']; + patientShare = json['PatientShare']; + companyShare = json['CompanyShare']; + totalPatientShare = json['TotalPatientShare']; + totalCompanyShare = json['TotalCompanyShare']; + totalShare = json['TotalShare']; + discountAmount = json['DiscountAmount']; + vATPercentage = json['VATPercentage']; + patientVATAmount = json['PatientVATAmount']; + companyVATAmount = json['CompanyVATAmount']; + totalVATAmount = json['TotalVATAmount']; + price = json['Price']; + patientID = json['PatientID']; + patientName = json['PatientName']; + patientNameN = json['PatientNameN']; + nationalityID = json['NationalityID']; + doctorName = json['DoctorName']; + doctorNameN = json['DoctorNameN']; + clinicID = json['ClinicID']; + clinicDescription = json['ClinicDescription']; + clinicDescriptionN = json['ClinicDescriptionN']; + appointmentDate = json['AppointmentDate']; + appointmentNo = json['AppointmentNo']; + insuranceID = json['InsuranceID']; + companyID = json['CompanyID']; + companyName = json['CompanyName']; + companyNameN = json['CompanyNameN']; + companyAddress = json['CompanyAddress']; + companyAddressN = json['CompanyAddressN']; + companyGroupAddress = json['CompanyGroupAddress']; + groupName = json['GroupName']; + groupNameN = json['GroupNameN']; + patientAddress = json['PatientAddress']; + vATNo = json['VATNo']; + paymentDate = json['PaymentDate']; + projectName = json['ProjectName']; + totalDiscount = json['TotalDiscount']; + totalPatientShareWithQuantity = json['TotalPatientShareWithQuantity']; + legalName = json['LegalName']; + legalNameN = json['LegalNameN']; + advanceAdjustment = json['AdvanceAdjustment']; + } + + Map toJson() { + final Map data = new Map(); + data['ProjectID'] = this.projectID; + data['DoctorID'] = this.doctorID; + data['GrandTotal'] = this.grandTotal; + data['Quantity'] = this.quantity; + data['Total'] = this.total; + data['Discount'] = this.discount; + data['SubTotal'] = this.subTotal; + data['InvoiceNo'] = this.invoiceNo; + data['CreatedOn'] = this.createdOn; + data['ProcedureID'] = this.procedureID; + data['ProcedureName'] = this.procedureName; + data['ProcedureNameN'] = this.procedureNameN; + data['ProcedurePrice'] = this.procedurePrice; + data['PatientShare'] = this.patientShare; + data['CompanyShare'] = this.companyShare; + data['TotalPatientShare'] = this.totalPatientShare; + data['TotalCompanyShare'] = this.totalCompanyShare; + data['TotalShare'] = this.totalShare; + data['DiscountAmount'] = this.discountAmount; + data['VATPercentage'] = this.vATPercentage; + data['PatientVATAmount'] = this.patientVATAmount; + data['CompanyVATAmount'] = this.companyVATAmount; + data['TotalVATAmount'] = this.totalVATAmount; + data['Price'] = this.price; + data['PatientID'] = this.patientID; + data['PatientName'] = this.patientName; + data['PatientNameN'] = this.patientNameN; + data['NationalityID'] = this.nationalityID; + data['DoctorName'] = this.doctorName; + data['DoctorNameN'] = this.doctorNameN; + data['ClinicID'] = this.clinicID; + data['ClinicDescription'] = this.clinicDescription; + data['ClinicDescriptionN'] = this.clinicDescriptionN; + data['AppointmentDate'] = this.appointmentDate; + data['AppointmentNo'] = this.appointmentNo; + data['InsuranceID'] = this.insuranceID; + data['CompanyID'] = this.companyID; + data['CompanyName'] = this.companyName; + data['CompanyNameN'] = this.companyNameN; + data['CompanyAddress'] = this.companyAddress; + data['CompanyAddressN'] = this.companyAddressN; + data['CompanyGroupAddress'] = this.companyGroupAddress; + data['GroupName'] = this.groupName; + data['GroupNameN'] = this.groupNameN; + data['PatientAddress'] = this.patientAddress; + data['VATNo'] = this.vATNo; + data['PaymentDate'] = this.paymentDate; + data['ProjectName'] = this.projectName; + data['TotalDiscount'] = this.totalDiscount; + data['TotalPatientShareWithQuantity'] = this.totalPatientShareWithQuantity; + data['LegalName'] = this.legalName; + data['LegalNameN'] = this.legalNameN; + data['AdvanceAdjustment'] = this.advanceAdjustment; + return data; + } +} diff --git a/lib/models/MyInvoices/GetDentalAppointmentsResponse.dart b/lib/models/MyInvoices/GetDentalAppointmentsResponse.dart new file mode 100644 index 00000000..e0f39619 --- /dev/null +++ b/lib/models/MyInvoices/GetDentalAppointmentsResponse.dart @@ -0,0 +1,113 @@ +class GetDentalAppointmentsResponse { + List? listDentalAppointments; + + GetDentalAppointmentsResponse({this.listDentalAppointments}); + + GetDentalAppointmentsResponse.fromJson(Map json) { + if (json['List_DentalAppointments'] != null) { + listDentalAppointments = []; + json['List_DentalAppointments'].forEach((v) { + listDentalAppointments!.add(new ListDentalAppointments.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + if (this.listDentalAppointments != null) { + data['List_DentalAppointments'] = + this.listDentalAppointments!.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class ListDentalAppointments { + String? setupId; + int? projectID; + int? patientID; + int? appointmentNo; + String? appointmentDate; + dynamic appointmentDateN; + int? clinicID; + int? doctorID; + int? invoiceNo; + int? status; + String? arrivedOn; + dynamic doctorName; + String? doctorNameN; + String? clinicName; + dynamic decimalDoctorRate; + String? doctorImageURL; + dynamic doctorRate; + int? patientNumber; + String? projectName; + + ListDentalAppointments( + {this.setupId, + this.projectID, + this.patientID, + this.appointmentNo, + this.appointmentDate, + this.appointmentDateN, + this.clinicID, + this.doctorID, + this.invoiceNo, + this.status, + this.arrivedOn, + this.doctorName, + this.doctorNameN, + this.clinicName, + this.decimalDoctorRate, + this.doctorImageURL, + this.doctorRate, + this.patientNumber, + this.projectName}); + + ListDentalAppointments.fromJson(Map json) { + setupId = json['SetupId']; + projectID = json['ProjectID']; + patientID = json['PatientID']; + appointmentNo = json['AppointmentNo']; + appointmentDate = json['AppointmentDate']; + appointmentDateN = json['AppointmentDateN']; + clinicID = json['ClinicID']; + doctorID = json['DoctorID']; + invoiceNo = json['InvoiceNo']; + status = json['Status']; + arrivedOn = json['ArrivedOn']; + doctorName = json['DoctorName']; + doctorNameN = json['DoctorNameN']; + clinicName = json['ClinicName']; + decimalDoctorRate = json['DecimalDoctorRate']; + doctorImageURL = json['DoctorImageURL']; + doctorRate = json['DoctorRate']; + patientNumber = json['PatientNumber']; + projectName = json['ProjectName']; + } + + Map toJson() { + final Map data = new Map(); + data['SetupId'] = this.setupId; + data['ProjectID'] = this.projectID; + data['PatientID'] = this.patientID; + data['AppointmentNo'] = this.appointmentNo; + data['AppointmentDate'] = this.appointmentDate; + data['AppointmentDateN'] = this.appointmentDateN; + data['ClinicID'] = this.clinicID; + data['DoctorID'] = this.doctorID; + data['InvoiceNo'] = this.invoiceNo; + data['Status'] = this.status; + data['ArrivedOn'] = this.arrivedOn; + data['DoctorName'] = this.doctorName; + data['DoctorNameN'] = this.doctorNameN; + data['ClinicName'] = this.clinicName; + data['DecimalDoctorRate'] = this.decimalDoctorRate; + data['DoctorImageURL'] = this.doctorImageURL; + data['DoctorRate'] = this.doctorRate; + data['PatientNumber'] = this.patientNumber; + data['ProjectName'] = this.projectName; + return data; + } +} + diff --git a/lib/models/SmartWatch/HealthData.dart b/lib/models/SmartWatch/HealthData.dart index f01c3bf8..90a7e23d 100644 --- a/lib/models/SmartWatch/HealthData.dart +++ b/lib/models/SmartWatch/HealthData.dart @@ -1,8 +1,33 @@ class healthData { - int MedCategoryID; - int MedSubCategoryID; - String Value; - String Notes; - String MachineDate; - int TransactionsListID; -} + int? MedCategoryID; + int? MedSubCategoryID; + String? MachineDate; + double? Value; + int? TransactionsListID; + + healthData({ + this.MedCategoryID, + this.MedSubCategoryID, + this.MachineDate, + this.Value, + this.TransactionsListID + }); + + healthData.fromJson(Map json) { + MedCategoryID = json['MedCategoryID']; + MedSubCategoryID = json['MedSubCategoryID']; + MachineDate = json['MachineDate']; + Value = json['Value']; + TransactionsListID = json['TransactionsListID']; + } + + 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; + return data; + } +} \ No newline at end of file diff --git a/lib/models/SmartWatch/WeeklyHeartRateResModel.dart b/lib/models/SmartWatch/WeeklyHeartRateResModel.dart new file mode 100644 index 00000000..26341ee0 --- /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'] != null ? json['ValueAvg'] : 0.0; + 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 new file mode 100644 index 00000000..e2af2dbd --- /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 = json['Value'] != null ? num.tryParse(json['Value'])!.toInt() : 0; + 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/YearlyHeartRateResModel.dart b/lib/models/SmartWatch/YearlyHeartRateResModel.dart new file mode 100644 index 00000000..3d81ff2c --- /dev/null +++ b/lib/models/SmartWatch/YearlyHeartRateResModel.dart @@ -0,0 +1,37 @@ +class YearlyHeartRateResModel { + dynamic? 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'] != null ? json['ValueAvg'] : 0.0; + 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/models/SmartWatch/YearlyStepsResModel.dart b/lib/models/SmartWatch/YearlyStepsResModel.dart index 728633d9..13392105 100644 --- a/lib/models/SmartWatch/YearlyStepsResModel.dart +++ b/lib/models/SmartWatch/YearlyStepsResModel.dart @@ -1,10 +1,10 @@ class YearlyStepsResModel { - double valueSum; - int medCategoryID; - int month; - String monthName; - int patientID; - int year; + num? valueSum; + int? medCategoryID; + int? month; + String? monthName; + int? patientID; + int? year; YearlyStepsResModel( {this.valueSum, @@ -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/models/ambulanceRequest/locationDetails.dart b/lib/models/ambulanceRequest/locationDetails.dart new file mode 100644 index 00000000..6971da33 --- /dev/null +++ b/lib/models/ambulanceRequest/locationDetails.dart @@ -0,0 +1,23 @@ +class LocationDetails { + double? _lat; + double? _long; + String? _formattedAddress; + + double get lat => _lat!; + + set lat(double lat) { + _lat = lat; + } + + double get long => _long!; + + set long(double long) { + _long = long; + } + + String? get formattedAddress => _formattedAddress; + + set formattedAddress(String? formattedAddress) { + _formattedAddress = formattedAddress; + } +} diff --git a/lib/models/anicllary-orders/ancillary_order_list_model.dart b/lib/models/anicllary-orders/ancillary_order_list_model.dart index 76ef3a7d..9aefe844 100644 --- a/lib/models/anicllary-orders/ancillary_order_list_model.dart +++ b/lib/models/anicllary-orders/ancillary_order_list_model.dart @@ -1,14 +1,14 @@ class AncillaryOrdersListModel { - List ancillaryOrderList; - Null errCode; - String message; - int patientID; - String patientName; - int patientType; - int projectID; - String projectName; - String setupID; - int statusCode; + List? ancillaryOrderList; + dynamic errCode; + String? message; + int? patientID; + String? patientName; + int? patientType; + int? projectID; + String? projectName; + String? setupID; + int? statusCode; AncillaryOrdersListModel( {this.ancillaryOrderList, @@ -24,15 +24,15 @@ class AncillaryOrdersListModel { AncillaryOrdersListModel.fromJson(Map json) { if (json['AncillaryOrderList'] != null) { - ancillaryOrderList = new List(); + ancillaryOrderList =[]; json['AncillaryOrderList'].forEach((v) { - ancillaryOrderList.add(new AncillaryOrderList.fromJson(v)); + ancillaryOrderList!.add(new AncillaryOrderList.fromJson(v)); }); } errCode = json['ErrCode']; message = json['Message']; patientID = json['PatientID']; - patientName = json['PatientName']; + patientName = json['PatientName'] != null ? json['PatientName'] : ""; patientType = json['PatientType']; projectID = json['ProjectID']; projectName = json['ProjectName']; @@ -44,7 +44,7 @@ class AncillaryOrdersListModel { final Map data = new Map(); if (this.ancillaryOrderList != null) { data['AncillaryOrderList'] = - this.ancillaryOrderList.map((v) => v.toJson()).toList(); + this.ancillaryOrderList!.map((v) => v.toJson()).toList(); } data['ErrCode'] = this.errCode; data['Message'] = this.message; @@ -60,14 +60,14 @@ class AncillaryOrdersListModel { } class AncillaryOrderList { - String appointmentDate; - int appointmentNo; - int clinicID; - String clinicName; - int doctorID; - String doctorName; - String orderDate; - int orderNo; + String? appointmentDate; + int? appointmentNo; + int? clinicID; + String? clinicName; + int? doctorID; + String? doctorName; + String? orderDate; + int? orderNo; AncillaryOrderList( {this.appointmentDate, @@ -83,7 +83,7 @@ class AncillaryOrderList { appointmentDate = json['AppointmentDate']; appointmentNo = json['AppointmentNo']; clinicID = json['ClinicID']; - clinicName = json['ClinicName']; + clinicName = json['ClinicName'] != null ? json['ClinicName'] : ""; doctorID = json['DoctorID']; doctorName = json['DoctorName']; orderDate = json['OrderDate']; diff --git a/lib/models/anicllary-orders/ancillary_order_proc_model.dart b/lib/models/anicllary-orders/ancillary_order_proc_model.dart index 7322d11a..451d775e 100644 --- a/lib/models/anicllary-orders/ancillary_order_proc_model.dart +++ b/lib/models/anicllary-orders/ancillary_order_proc_model.dart @@ -1,60 +1,61 @@ class AncillaryOrdersListProcListModel { - List ancillaryOrderProcList; - String appointmentDate; - dynamic appointmentNo; - dynamic clinicID; - String clinicName; - dynamic companyID; - String companyName; - dynamic doctorID; - String doctorName; - Null errCode; - dynamic groupID; - String insurancePolicyNo; - String message; - String patientCardID; - dynamic patientID; - String patientName; - dynamic patientType; - dynamic policyID; - String policyName; - dynamic projectID; - String setupID; - dynamic statusCode; - dynamic subCategoryID; - String subPolicyNo; + List? ancillaryOrderProcDetailsList; + String? appointmentDate; + int? appointmentNo; + int? clinicID; + String? clinicName; + int? companyID; + String? companyName; + int? doctorID; + String? doctorName; + dynamic errCode; + int? groupID; + String? insurancePolicyNo; + String? message; + String? patientCardID; + int? patientID; + String? patientName; + int? patientType; + int? policyID; + String? policyName; + int? projectID; + String? setupID; + int? statusCode; + int? subCategoryID; + String? subPolicyNo; AncillaryOrdersListProcListModel( - {this.ancillaryOrderProcList, - this.appointmentDate, - this.appointmentNo, - this.clinicID, - this.clinicName, - this.companyID, - this.companyName, - this.doctorID, - this.doctorName, - this.errCode, - this.groupID, - this.insurancePolicyNo, - this.message, - this.patientCardID, - this.patientID, - this.patientName, - this.patientType, - this.policyID, - this.policyName, - this.projectID, - this.setupID, - this.statusCode, - this.subCategoryID, - this.subPolicyNo}); + {this.ancillaryOrderProcDetailsList, + this.appointmentDate, + this.appointmentNo, + this.clinicID, + this.clinicName, + this.companyID, + this.companyName, + this.doctorID, + this.doctorName, + this.errCode, + this.groupID, + this.insurancePolicyNo, + this.message, + this.patientCardID, + this.patientID, + this.patientName, + this.patientType, + this.policyID, + this.policyName, + this.projectID, + this.setupID, + this.statusCode, + this.subCategoryID, + this.subPolicyNo}); AncillaryOrdersListProcListModel.fromJson(Map json) { - if (json['AncillaryOrderProcList'] != null) { - ancillaryOrderProcList = new List(); - json['AncillaryOrderProcList'].forEach((v) { - ancillaryOrderProcList.add(new AncillaryOrderProcList.fromJson(v)); + if (json['AncillaryOrderProcDetailsList'] != null) { + ancillaryOrderProcDetailsList = []; + json['AncillaryOrderProcDetailsList'].forEach((v) { + ancillaryOrderProcDetailsList! + .add(new AncillaryOrderProcDetailsList.fromJson(v)); }); } appointmentDate = json['AppointmentDate']; @@ -84,9 +85,9 @@ class AncillaryOrdersListProcListModel { Map toJson() { final Map data = new Map(); - if (this.ancillaryOrderProcList != null) { - data['AncillaryOrderProcList'] = - this.ancillaryOrderProcList.map((v) => v.toJson()).toList(); + if (this.ancillaryOrderProcDetailsList != null) { + data['AncillaryOrderProcDetailsList'] = + this.ancillaryOrderProcDetailsList!.map((v) => v.toJson()).toList(); } data['AppointmentDate'] = this.appointmentDate; data['AppointmentNo'] = this.appointmentNo; @@ -115,71 +116,71 @@ class AncillaryOrdersListProcListModel { } } -class AncillaryOrderProcList { +class AncillaryOrderProcDetailsList { dynamic approvalLineItemNo; dynamic approvalNo; - String approvalStatus; + String? approvalStatus; dynamic approvalStatusID; dynamic companyShare; dynamic companyShareWithTax; dynamic companyTaxAmount; dynamic discountAmount; dynamic discountCategory; - String discountType; + String? discountType; dynamic discountTypeValue; - bool isApprovalCreated; - bool isApprovalRequired; - bool isCovered; - String orderDate; + bool? isApprovalCreated; + bool? isApprovalRequired; + bool? isCovered; + String? orderDate; dynamic orderLineItemNo; dynamic orderNo; dynamic partnerID; dynamic partnerShare; - String partnerShareType; + String? partnerShareType; dynamic patientShare; dynamic patientShareWithTax; dynamic patientTaxAmount; dynamic procPrice; dynamic procedureCategoryID; - String procedureCategoryName; - String procedureID; - String procedureName; + String? procedureCategoryName; + String? procedureID; + String? procedureName; dynamic taxAmount; dynamic taxPct; - AncillaryOrderProcList( + AncillaryOrderProcDetailsList( {this.approvalLineItemNo, - this.approvalNo, - this.approvalStatus, - this.approvalStatusID, - this.companyShare, - this.companyShareWithTax, - this.companyTaxAmount, - this.discountAmount, - this.discountCategory, - this.discountType, - this.discountTypeValue, - this.isApprovalCreated, - this.isApprovalRequired, - this.isCovered, - this.orderDate, - this.orderLineItemNo, - this.orderNo, - this.partnerID, - this.partnerShare, - this.partnerShareType, - this.patientShare, - this.patientShareWithTax, - this.patientTaxAmount, - this.procPrice, - this.procedureCategoryID, - this.procedureCategoryName, - this.procedureID, - this.procedureName, - this.taxAmount, - this.taxPct}); + this.approvalNo, + this.approvalStatus, + this.approvalStatusID, + this.companyShare, + this.companyShareWithTax, + this.companyTaxAmount, + this.discountAmount, + this.discountCategory, + this.discountType, + this.discountTypeValue, + this.isApprovalCreated, + this.isApprovalRequired, + this.isCovered, + this.orderDate, + this.orderLineItemNo, + this.orderNo, + this.partnerID, + this.partnerShare, + this.partnerShareType, + this.patientShare, + this.patientShareWithTax, + this.patientTaxAmount, + this.procPrice, + this.procedureCategoryID, + this.procedureCategoryName, + this.procedureID, + this.procedureName, + this.taxAmount, + this.taxPct}); - AncillaryOrderProcList.fromJson(Map json) { + AncillaryOrderProcDetailsList.fromJson(Map json) { approvalLineItemNo = json['ApprovalLineItemNo']; approvalNo = json['ApprovalNo']; approvalStatus = json['ApprovalStatus']; diff --git a/lib/models/anicllary-orders/ancillary_orders_proc_list.dart b/lib/models/anicllary-orders/ancillary_orders_proc_list.dart new file mode 100644 index 00000000..57a9f3bb --- /dev/null +++ b/lib/models/anicllary-orders/ancillary_orders_proc_list.dart @@ -0,0 +1,18 @@ +class AncillaryOrdersProcedureList { + int? procedureID; + String? procedureDescription; + + AncillaryOrdersProcedureList({this.procedureID, this.procedureDescription}); + + AncillaryOrdersProcedureList.fromJson(Map json) { + procedureID = json['ProcedureID']; + procedureDescription = json['ProcedureDescription']; + } + + Map toJson() { + final Map data = new Map(); + data['ProcedureID'] = this.procedureID; + data['ProcedureDescription'] = this.procedureDescription; + return data; + } +} diff --git a/lib/models/apple_pay_request.dart b/lib/models/apple_pay_request.dart new file mode 100644 index 00000000..f4880544 --- /dev/null +++ b/lib/models/apple_pay_request.dart @@ -0,0 +1,135 @@ +class ApplePayRequest { + String? currency; + String? language; + String? customername; + dynamic customerEmail; + String? orderdescription; + String? liveServiceid; + dynamic longitude; + dynamic latitude; + String? devicetoken; + String? clientrequestid; + String? projectid; + String? serviceid; + String? patientid; + String? amount; + String? appleData; + String? appleSignature; + AppleHeader? appleHeader; + ApplePaymentMethod? applePaymentMethod; + + ApplePayRequest( + {this.currency, + this.language, + this.customername, + this.customerEmail, + this.orderdescription, + this.liveServiceid, + this.longitude, + this.latitude, + this.devicetoken, + this.clientrequestid, + this.projectid, + this.serviceid, + this.patientid, + this.amount, + this.appleData, + this.appleSignature, + this.appleHeader, + this.applePaymentMethod}); + + ApplePayRequest.fromJson(Map json) { + currency = json['currency']; + language = json['language']; + customername = json['customername']; + customerEmail = json['customer_email']; + orderdescription = json['orderdescription']; + liveServiceid = json['live_serviceid']; + longitude = json['longitude']; + latitude = json['latitude']; + devicetoken = json['devicetoken']; + clientrequestid = json['clientrequestid']; + projectid = json['projectid']; + serviceid = json['serviceid']; + patientid = json['patientid']; + amount = json['Amount']; + appleData = json['apple_data']; + appleSignature = json['apple_signature']; + appleHeader = json['apple_header'] != null ? new AppleHeader.fromJson(json['apple_header']) : null; + applePaymentMethod = json['apple_paymentMethod'] != null ? new ApplePaymentMethod.fromJson(json['apple_paymentMethod']) : null; + } + + Map toJson() { + final Map data = new Map(); + data['currency'] = this.currency; + data['language'] = this.language; + data['customername'] = this.customername; + data['customer_email'] = this.customerEmail; + data['orderdescription'] = this.orderdescription; + data['live_serviceid'] = this.liveServiceid; + data['longitude'] = this.longitude; + data['latitude'] = this.latitude; + data['devicetoken'] = this.devicetoken; + data['clientrequestid'] = this.clientrequestid; + data['projectid'] = this.projectid; + data['serviceid'] = this.serviceid; + data['patientid'] = this.patientid; + data['Amount'] = this.amount; + data['apple_data'] = this.appleData; + data['apple_signature'] = this.appleSignature; + if (this.appleHeader != null) { + data['apple_header'] = this.appleHeader!.toJson(); + } + if (this.applePaymentMethod != null) { + data['apple_paymentMethod'] = this.applePaymentMethod!.toJson(); + } + return data; + } +} + +class AppleHeader { + String? appleApplicationData; + String? appleEphemeralPublicKey; + String? applePublicKeyHash; + String? appleTransactionId; + + AppleHeader({this.appleApplicationData, this.appleEphemeralPublicKey, this.applePublicKeyHash, this.appleTransactionId}); + + AppleHeader.fromJson(Map json) { + appleApplicationData = json['apple_applicationData']; + appleEphemeralPublicKey = json['apple_ephemeralPublicKey']; + applePublicKeyHash = json['apple_publicKeyHash']; + appleTransactionId = json['apple_transactionId']; + } + + Map toJson() { + final Map data = new Map(); + data['apple_applicationData'] = this.appleApplicationData; + data['apple_ephemeralPublicKey'] = this.appleEphemeralPublicKey; + data['apple_publicKeyHash'] = this.applePublicKeyHash; + data['apple_transactionId'] = this.appleTransactionId; + return data; + } +} + +class ApplePaymentMethod { + String? appleDisplayName; + String? appleNetwork; + String? appleType; + + ApplePaymentMethod({this.appleDisplayName, this.appleNetwork, this.appleType}); + + ApplePaymentMethod.fromJson(Map json) { + appleDisplayName = json['apple_displayName']; + appleNetwork = json['apple_network']; + appleType = json['apple_type']; + } + + Map toJson() { + final Map data = new Map(); + data['apple_displayName'] = this.appleDisplayName; + data['apple_network'] = this.appleNetwork; + data['apple_type'] = this.appleType; + return data; + } +} diff --git a/lib/models/apple_pay_response.dart b/lib/models/apple_pay_response.dart new file mode 100644 index 00000000..7628873e --- /dev/null +++ b/lib/models/apple_pay_response.dart @@ -0,0 +1,112 @@ +import 'dart:convert'; + +class ApplePayResponse { + PaymentMethod? paymentMethod; + dynamic billingContact; + dynamic shippingMethod; + dynamic shippingContact; + Token? token; + + ApplePayResponse( + {this.paymentMethod, + this.billingContact, + this.shippingMethod, + this.shippingContact, + this.token}); + + ApplePayResponse.fromJson(Map jsonValue) { + paymentMethod = jsonValue['paymentMethod'] != null + ? new PaymentMethod.fromJson(jsonValue['paymentMethod']) + : null; + // billingContact = json['billingContact'] != null ? json['billingContact'] : ""; + // shippingMethod = json['shippingMethod'] != null ? json['shippingMethod'] : ""; + // shippingContact = json['shippingContact'] != null ? json['shippingContact'] : ""; + token = jsonValue['token'] != null ? new Token.fromJson(json.decode(jsonValue['token'])) : null; + } + + Map toJson() { + final Map data = new Map(); + if (this.paymentMethod != null) { + data['paymentMethod'] = this.paymentMethod!.toJson(); + } + data['billingContact'] = this.billingContact; + data['shippingMethod'] = this.shippingMethod; + data['shippingContact'] = this.shippingContact; + if (this.token != null) { + data['token'] = this.token!.toJson(); + } + return data; + } +} + +class PaymentMethod { + dynamic network; + dynamic displayName; + dynamic type; + + PaymentMethod({this.network, this.displayName, this.type}); + + PaymentMethod.fromJson(Map json) { + network = json['network']; + displayName = json['displayName']; + type = json['type']; + } + + Map toJson() { + final Map data = new Map(); + data['network'] = this.network; + data['displayName'] = this.displayName; + data['type'] = this.type; + return data; + } +} + +class Token { + String? version; + String? data; + String? signature; + Header? header; + + Token({this.version, this.data, this.signature, this.header}); + + Token.fromJson(Map json) { + version = json['version']; + data = json['data']; + signature = json['signature']; + header = + json['header'] != null ? new Header.fromJson(json['header']) : null; + } + + Map toJson() { + final Map data = new Map(); + data['version'] = this.version; + data['data'] = this.data; + data['signature'] = this.signature; + if (this.header != null) { + data['header'] = this.header!.toJson(); + } + return data; + } +} + +class Header { + String? ephemeralPublicKey; + String? publicKeyHash; + String? transactionId; + + Header({this.ephemeralPublicKey, this.publicKeyHash, this.transactionId}); + + Header.fromJson(Map json) { + ephemeralPublicKey = json['ephemeralPublicKey']; + publicKeyHash = json['publicKeyHash']; + transactionId = json['transactionId']; + } + + Map toJson() { + final Map data = new Map(); + data['ephemeralPublicKey'] = this.ephemeralPublicKey; + data['publicKeyHash'] = this.publicKeyHash; + data['transactionId'] = this.transactionId; + return data; + } +} diff --git a/lib/models/get_dental_instructions_response_model.dart b/lib/models/get_dental_instructions_response_model.dart new file mode 100644 index 00000000..97ed424c --- /dev/null +++ b/lib/models/get_dental_instructions_response_model.dart @@ -0,0 +1,77 @@ +class GetDentalInstructionsResponseModel { + List? data; + dynamic message; + int? status; + + GetDentalInstructionsResponseModel({this.data, this.message, this.status}); + + GetDentalInstructionsResponseModel.fromJson(Map json) { + if (json['Data'] != null) { + data = []; + json['Data'].forEach((v) { + data!.add(new Data.fromJson(v)); + }); + } + message = json['message']; + status = json['status']; + } + + Map toJson() { + final Map data = new Map(); + if (this.data != null) { + data['Data'] = this.data!.map((v) => v.toJson()).toList(); + } + data['message'] = this.message; + data['status'] = this.status; + return data; + } +} + +class Data { + String? createdOn; + String? mobileNo; + int? patientId; + int? procedureId; + int? projectId; + String? setupId; + String? smsContent; + int? sourceReferenceNo; + String? sourceType; + + Data( + {this.createdOn, + this.mobileNo, + this.patientId, + this.procedureId, + this.projectId, + this.setupId, + this.smsContent, + this.sourceReferenceNo, + this.sourceType}); + + Data.fromJson(Map json) { + createdOn = json['createdOn']; + mobileNo = json['mobileNo']; + patientId = json['patientId']; + procedureId = json['procedureId']; + projectId = json['projectId']; + setupId = json['setupId']; + smsContent = json['smsContent']; + sourceReferenceNo = json['sourceReferenceNo']; + sourceType = json['sourceType']; + } + + Map toJson() { + final Map data = new Map(); + data['createdOn'] = this.createdOn; + data['mobileNo'] = this.mobileNo; + data['patientId'] = this.patientId; + data['procedureId'] = this.procedureId; + data['projectId'] = this.projectId; + data['setupId'] = this.setupId; + data['smsContent'] = this.smsContent; + data['sourceReferenceNo'] = this.sourceReferenceNo; + data['sourceType'] = this.sourceType; + return data; + } +} diff --git a/lib/models/gradient_color.dart b/lib/models/gradient_color.dart new file mode 100644 index 00000000..b2114b97 --- /dev/null +++ b/lib/models/gradient_color.dart @@ -0,0 +1,35 @@ +import 'package:flutter/material.dart'; + +class GradientColor { + Color darkColor; + Color lightColor; + + GradientColor(this.darkColor, this.lightColor); +} + +List bannerColor = [ + new GradientColor(Color(0xFFF2B353E), Color(0xFFF71787E)), + new GradientColor(Color(0xFFFD02127), Color(0xFFFEE6161)), + new GradientColor(Colors.blue[700]!, Colors.blue[400]!), + new GradientColor(Colors.yellow[700]!, Colors.yellow), + new GradientColor(Colors.orange[800]!, Colors.orange), + new GradientColor(Colors.green[800]!, Colors.green[500]!), + new GradientColor(Colors.brown[700]!, Colors.brown), + new GradientColor(Colors.brown[700]!, Colors.brown), + new GradientColor(Colors.brown[700]!, Colors.brown), + new GradientColor(Colors.brown[700]!, Colors.brown), + new GradientColor(Colors.brown[700]!, Colors.brown), + new GradientColor(Colors.brown[700]!, Colors.brown), + new GradientColor(Colors.brown[700]!, Colors.brown), + new GradientColor(Colors.brown[700]!, Colors.brown), + new GradientColor(Colors.brown[700]!, Colors.brown), + new GradientColor(Colors.brown[700]!, Colors.brown), + new GradientColor(Colors.brown[700]!, Colors.brown), + new GradientColor(Colors.brown[700]!, Colors.brown), + new GradientColor(Colors.brown[700]!, Colors.brown), + new GradientColor(Colors.brown[700]!, Colors.brown), + new GradientColor(Colors.brown[700]!, Colors.brown), + new GradientColor(Colors.brown[700]!, Colors.brown), + new GradientColor(Colors.brown[700]!, Colors.brown), + new GradientColor(Colors.brown[700]!, Colors.brown), +]; diff --git a/lib/models/header_model.dart b/lib/models/header_model.dart new file mode 100644 index 00000000..adfc8f8f --- /dev/null +++ b/lib/models/header_model.dart @@ -0,0 +1,19 @@ +class HeaderModel { + String doctorName; + int doctorId; + String doctorImageURL; + List speciality; + String invoiceNo; + String projectName; + DateTime? date; + String? time; + String nationalityFlagURL; + int? doctorRate; + int? actualDoctorRate; + int? totalReviews; + String decimalDoctorRate; + String email; + + HeaderModel(this.doctorName, this.doctorId, this.doctorImageURL, this.speciality, this.invoiceNo, this.projectName, this.date, this.time, this.nationalityFlagURL, this.doctorRate, + this.actualDoctorRate, this.totalReviews, this.email, {this.decimalDoctorRate = ""}); +} diff --git a/lib/models/hmg_services.dart b/lib/models/hmg_services.dart new file mode 100644 index 00000000..793800fa --- /dev/null +++ b/lib/models/hmg_services.dart @@ -0,0 +1,10 @@ +class HmgServices { + int action; + String title; + String subTitle; + String icon; + bool isLogin; + bool isLocked; + + HmgServices(this.action, this.title, this.subTitle, this.icon, this.isLogin, {this.isLocked = false}); +} diff --git a/lib/models/insurance/getInsuranceCompaniesModel.dart b/lib/models/insurance/getInsuranceCompaniesModel.dart new file mode 100644 index 00000000..2aaef58e --- /dev/null +++ b/lib/models/insurance/getInsuranceCompaniesModel.dart @@ -0,0 +1,64 @@ +class InsuranceCompaniesGetModel { + String? setupID; + int? projectID; + int? companyID; + String? companyName; + String? companyNameN; + String? alias; + String? aliasN; + String? insurancePolicyNo; + String? phoneOffice1; + String? phoneOffice2; + String? faxNumber; + int? status; + String? contractExpiry; + + InsuranceCompaniesGetModel( + {this.setupID, + this.projectID, + this.companyID, + this.companyName, + this.companyNameN, + this.alias, + this.aliasN, + this.insurancePolicyNo, + this.phoneOffice1, + this.phoneOffice2, + this.faxNumber, + this.status, + this.contractExpiry}); + + InsuranceCompaniesGetModel.fromJson(Map json) { + setupID = json['SetupID']; + projectID = json['ProjectID']; + companyID = json['CompanyID']; + companyName = json['CompanyName']; + companyNameN = json['CompanyNameN']; + alias = json['Alias']; + aliasN = json['AliasN']; + insurancePolicyNo = json['InsurancePolicyNo']; + phoneOffice1 = json['PhoneOffice1']; + phoneOffice2 = json['PhoneOffice2']; + faxNumber = json['FaxNumber']; + status = json['Status']; + contractExpiry = json['ContractExpiry']; + } + + Map toJson() { + final Map data = new Map(); + data['SetupID'] = this.setupID; + data['ProjectID'] = this.projectID; + data['CompanyID'] = this.companyID; + data['CompanyName'] = this.companyName; + data['CompanyNameN'] = this.companyNameN; + data['Alias'] = this.alias; + data['AliasN'] = this.aliasN; + data['InsurancePolicyNo'] = this.insurancePolicyNo; + data['PhoneOffice1'] = this.phoneOffice1; + data['PhoneOffice2'] = this.phoneOffice2; + data['FaxNumber'] = this.faxNumber; + data['Status'] = this.status; + data['ContractExpiry'] = this.contractExpiry; + return data; + } +} diff --git a/lib/models/insurance/insuranceCompaniesSchemeModel.dart b/lib/models/insurance/insuranceCompaniesSchemeModel.dart new file mode 100644 index 00000000..a8ad8b3a --- /dev/null +++ b/lib/models/insurance/insuranceCompaniesSchemeModel.dart @@ -0,0 +1,72 @@ +class InsuranceCompaniesSchemeModel { + String? setupID; + int? projectID; + int? companyID; + int? subCategoryID; + String? subCategoryDesc; + String? subCategoryDescN; + String? validFrom; + String? validTo; + var isInpatient; + int? roomCategory; + bool? isActive; + int? createdBy; + String? createdOn; + int? editedBy; + String? editedOn; + + InsuranceCompaniesSchemeModel( + {this.setupID, + this.projectID, + this.companyID, + this.subCategoryID, + this.subCategoryDesc, + this.subCategoryDescN, + this.validFrom, + this.validTo, + this.isInpatient, + this.roomCategory, + this.isActive, + this.createdBy, + this.createdOn, + this.editedBy, + this.editedOn}); + + InsuranceCompaniesSchemeModel.fromJson(Map json) { + setupID = json['SetupID']; + projectID = json['ProjectID']; + companyID = json['CompanyID']; + subCategoryID = json['SubCategoryID']; + subCategoryDesc = json['SubCategoryDesc']; + subCategoryDescN = json['SubCategoryDescN']; + validFrom = json['ValidFrom']; + validTo = json['ValidTo']; + isInpatient = json['IsInpatient']; + roomCategory = json['RoomCategory']; + isActive = json['IsActive']; + createdBy = json['CreatedBy']; + createdOn = json['CreatedOn']; + editedBy = json['EditedBy']; + editedOn = json['EditedOn']; + } + + Map toJson() { + final Map data = new Map(); + data['SetupID'] = this.setupID; + data['ProjectID'] = this.projectID; + data['CompanyID'] = this.companyID; + data['SubCategoryID'] = this.subCategoryID; + data['SubCategoryDesc'] = this.subCategoryDesc; + data['SubCategoryDescN'] = this.subCategoryDescN; + data['ValidFrom'] = this.validFrom; + data['ValidTo'] = this.validTo; + data['IsInpatient'] = this.isInpatient; + data['RoomCategory'] = this.roomCategory; + data['IsActive'] = this.isActive; + data['CreatedBy'] = this.createdBy; + data['CreatedOn'] = this.createdOn; + data['EditedBy'] = this.editedBy; + data['EditedOn'] = this.editedOn; + return data; + } +} diff --git a/lib/models/mobile_number.dart b/lib/models/mobile_number.dart new file mode 100644 index 00000000..f973aad9 --- /dev/null +++ b/lib/models/mobile_number.dart @@ -0,0 +1,1087 @@ +// final List countries = [ +// new Countries( +// name: "Saudi Arabia", name_ar: "المملكة العربية السعودية", code: '966'), +// new Countries( +// name: "United Arab Emirates", +// name_ar: "الإمارات العربية المتحدة", +// code: '971'), +// ]; + +// class Countries { +// final String name; +// final String name_ar; +// final String code; + +// Countries({this.name, this.name_ar, this.code}); +// } + +class Countries { + String? name; + String? nameAr; + String? code; + String? countryCode; + + Countries({this.name, this.nameAr, this.code, this.countryCode}); + + Countries.fromJson(Map json) { + name = json['name']; + nameAr = json['name_ar']; + code = json['code']; + countryCode = json['countryCode']; + } + + Map toJson() { + final Map data = new Map(); + data['name'] = this.name; + data['name_ar'] = this.nameAr; + data['code'] = this.code; + data['countryCode'] = this.countryCode; + return data; + } +} + +List> countriesData = [ + { + "name": "Saudi Arabia", + "name_ar": "المملكة العربية السعودية", + "code": "966", + "countryCode": "SA", + "pattern": "5xxxxxxxx", + "maxLength": 9 + }, + { + "name": "United Arab Emirates", + "name_ar": "الإمارات العربية المتحدة", + "code": "971", + "countryCode": "AE", + "pattern": "5xxxxxxxx", + "maxLength": 9 + }, + // { + // "name": "Bahrain", + // "name_ar": "البحرين", + // "code": "+973", + // "countryCode": "BH", + // "maxLength": 8 + // }, + // {"name": "Kuwait", "name_ar": "الكويت", "code": "+965", "countryCode": "KW"}, + // { + // "name": "Afghanistan", + // "name_ar": "أفغانستان", + // "code": "+93", + // "countryCode": "AF" + // }, + // { + // "name": "Aland Islands", + // "name_ar": "جزر آلاند", + // "code": "+358", + // "countryCode": "AX" + // }, + // { + // "name": "Albania", + // "name_ar": "ألبانيا", + // "code": "+355", + // "countryCode": "AL" + // }, + // { + // "name": "Algeria", + // "name_ar": "الجزائر", + // "code": "+213", + // "countryCode": "DZ" + // }, + // { + // "name": "AmericanSamoa", + // "name_ar": "ساموا الأمريكية", + // "code": "+1 684", + // "countryCode": "AS" + // }, + // {"name": "Andorra", "name_ar": "أندورا", "code": "+376", "countryCode": "AD"}, + // {"name": "Angola", "name_ar": "أنغولا", "code": "+244", "countryCode": "AO"}, + // { + // "name": "Anguilla", + // "name_ar": "أنغيلا", + // "code": "+1 264", + // "countryCode": "AI" + // }, + // { + // "name": "Antarctica", + // "name_ar": "القارة القطبية الجنوبية", + // "code": "+672", + // "countryCode": "AQ" + // }, + // { + // "name": "Antigua and Barbuda", + // "name_ar": "أنتيغوا وبربودا", + // "code": "+1268", + // "countryCode": "AG" + // }, + // { + // "name": "Argentina", + // "name_ar": "الأرجنتين", + // "code": "+54", + // "countryCode": "AR" + // }, + // { + // "name": "Armenia", + // "name_ar": "أرمينيا", + // "code": "+374", + // "countryCode": "AM" + // }, + // {"name": "Aruba", "name_ar": "أروبا", "code": "+297", "countryCode": "AW"}, + // { + // "name": "Australia", + // "name_ar": "أستراليا", + // "code": "+61", + // "countryCode": "AU" + // }, + // {"name": "Austria", "name_ar": "النمسا", "code": "+43", "countryCode": "AT"}, + // { + // "name": "Azerbaijan", + // "name_ar": "أذربيجان", + // "code": "+994", + // "countryCode": "AZ" + // }, + // { + // "name": "Bahamas", + // "name_ar": "الباهاما", + // "code": "+1 242", + // "countryCode": "BS" + // }, + // { + // "name": "Bangladesh", + // "name_ar": "بنغلاديش", + // "code": "+880", + // "countryCode": "BD" + // }, + // { + // "name": "Barbados", + // "name_ar": "بربادوس", + // "code": "+1 246", + // "countryCode": "BB" + // }, + // { + // "name": "Belarus", + // "name_ar": "روسيا البيضاء", + // "code": "+375", + // "countryCode": "BY" + // }, + // {"name": "Belgium", "name_ar": "بلجيكا", "code": "+32", "countryCode": "BE"}, + // {"name": "Belize", "name_ar": "بليز", "code": "+501", "countryCode": "BZ"}, + // {"name": "Benin", "name_ar": "بنين", "code": "+229", "countryCode": "BJ"}, + // { + // "name": "Bermuda", + // "name_ar": "برمودا", + // "code": "+1 441", + // "countryCode": "BM" + // }, + // {"name": "Bhutan", "name_ar": "بوتان", "code": "+975", "countryCode": "BT"}, + // { + // "name": "Bolivia, Plurinational State of", + // "name_ar": "دولة بوليفيا المتعددة القوميات", + // "code": "+591", + // "countryCode": "BO" + // }, + // { + // "name": "Bosnia and Herzegovina", + // "name_ar": "البوسنة والهرسك", + // "code": "+387", + // "countryCode": "BA" + // }, + // { + // "name": "Botswana", + // "name_ar": "بوتسوانا", + // "code": "+267", + // "countryCode": "BW" + // }, + // {"name": "Brazil", "name_ar": "البرازيل", "code": "+55", "countryCode": "BR"}, + // { + // "name": "British Indian Ocean Territory", + // "name_ar": "إقليم المحيط البريطاني الهندي", + // "code": "+246", + // "countryCode": "IO" + // }, + // { + // "name": "Brunei Darussalam", + // "name_ar": "بروناي دار السلام", + // "code": "+673", + // "countryCode": "BN" + // }, + // { + // "name": "Bulgaria", + // "name_ar": "بلغاريا", + // "code": "+359", + // "countryCode": "BG" + // }, + // { + // "name": "Burkina Faso", + // "name_ar": "بوركينا فاسو", + // "code": "+226", + // "countryCode": "BF" + // }, + // { + // "name": "Burundi", + // "name_ar": "بوروندي", + // "code": "+257", + // "countryCode": "BI" + // }, + // { + // "name": "Cambodia", + // "name_ar": "كمبوديا", + // "code": "+855", + // "countryCode": "KH" + // }, + // { + // "name": "Cameroon", + // "name_ar": "الكاميرون", + // "code": "+237", + // "countryCode": "CM" + // }, + // {"name": "Canada", "name_ar": "كندا", "code": "+1", "countryCode": "CA"}, + // { + // "name": "Cape Verde", + // "name_ar": "الرأس الأخضر", + // "code": "+238", + // "countryCode": "CV" + // }, + // { + // "name": "Cayman Islands", + // "name_ar": "جزر كايمان", + // "code": "+345", + // "countryCode": "KY" + // }, + // { + // "name": "Central African Republic", + // "name_ar": "جمهورية افريقيا الوسطى", + // "code": "+236", + // "countryCode": "CF" + // }, + // {"name": "Chad", "name_ar": "تشاد", "code": "+235", "countryCode": "TD"}, + // {"name": "Chile", "name_ar": "تشيلي", "code": "+56", "countryCode": "CL"}, + // {"name": "China", "name_ar": "الصين", "code": "+86", "countryCode": "CN"}, + // { + // "name": "Christmas Island", + // "name_ar": "جزيرة الكريسماس", + // "code": "+61", + // "countryCode": "CX" + // }, + // { + // "name": "Cocos (Keeling) Islands", + // "name_ar": "جزر كوكوس كيلينغ", + // "code": "+61", + // "countryCode": "CC" + // }, + // { + // "name": "Colombia", + // "name_ar": "كولومبيا", + // "code": "+57", + // "countryCode": "CO" + // }, + // { + // "name": "Comoros", + // "name_ar": "جزر القمر", + // "code": "+269", + // "countryCode": "KM" + // }, + // {"name": "Congo", "name_ar": "الكونغو", "code": "+242", "countryCode": "CG"}, + // { + // "name": "Congo, The Democratic Republic of the Congo", + // "name_ar": "الكونغو ، جمهورية الكونغو الديمقراطية", + // "code": "+243", + // "countryCode": "CD" + // }, + // { + // "name": "Cook Islands", + // "name_ar": "جزر كوك", + // "code": "+682", + // "countryCode": "CK" + // }, + // { + // "name": "Costa Rica", + // "name_ar": "كوستا ريكا", + // "code": "+506", + // "countryCode": "CR" + // }, + // { + // "name": "Cote d'Ivoire", + // "name_ar": "ساحل العاج", + // "code": "+225", + // "countryCode": "CI" + // }, + // { + // "name": "Croatia", + // "name_ar": "كرواتيا", + // "code": "+385", + // "countryCode": "HR" + // }, + // {"name": "Cuba", "name_ar": "كوبا", "code": "+53", "countryCode": "CU"}, + // {"name": "Cyprus", "name_ar": "قبرص", "code": "+357", "countryCode": "CY"}, + // { + // "name": "Czech Republic", + // "name_ar": "جمهورية التشيك", + // "code": "+420", + // "countryCode": "CZ" + // }, + // { + // "name": "Denmark", + // "name_ar": "الدنمارك", + // "code": "+45", + // "countryCode": "DK" + // }, + // { + // "name": "Djibouti", + // "name_ar": "جيبوتي", + // "code": "+253", + // "countryCode": "DJ" + // }, + // { + // "name": "Dominica", + // "name_ar": "دومينيكا", + // "code": "+1 767", + // "countryCode": "DM" + // }, + // { + // "name": "Dominican Republic", + // "name_ar": "جمهورية الدومنيكان", + // "code": "+1 849", + // "countryCode": "DO" + // }, + // { + // "name": "Ecuador", + // "name_ar": "الإكوادور", + // "code": "+593", + // "countryCode": "EC" + // }, + // {"name": "Egypt", "name_ar": "مصر", "code": "+20", "countryCode": "EG"}, + // { + // "name": "El Salvador", + // "name_ar": "السلفادور", + // "code": "+503", + // "countryCode": "SV" + // }, + // { + // "name": "Equatorial Guinea", + // "name_ar": "غينيا الإستوائية", + // "code": "+240", + // "countryCode": "GQ" + // }, + // { + // "name": "Eritrea", + // "name_ar": "إريتريا", + // "code": "+291", + // "countryCode": "ER" + // }, + // { + // "name": "Estonia", + // "name_ar": "استونيا", + // "code": "+372", + // "countryCode": "EE" + // }, + // { + // "name": "Ethiopia", + // "name_ar": "أثيوبيا", + // "code": "+251", + // "countryCode": "ET" + // }, + // { + // "name": "Falkland Islands (Malvinas)", + // "name_ar": "جزر فوكلاند مالفيناس", + // "code": "+500", + // "countryCode": "FK" + // }, + // { + // "name": "Faroe Islands", + // "name_ar": "جزر صناعية", + // "code": "+298", + // "countryCode": "FO" + // }, + // {"name": "Fiji", "name_ar": "فيجي", "code": "+679", "countryCode": "FJ"}, + // {"name": "Finland", "name_ar": "فنلندا", "code": "+358", "countryCode": "FI"}, + // {"name": "France", "name_ar": "فرنسا", "code": "+33", "countryCode": "FR"}, + // { + // "name": "French Guiana", + // "name_ar": "غيانا الفرنسية", + // "code": "+594", + // "countryCode": "GF" + // }, + // { + // "name": "French Polynesia", + // "name_ar": "بولينيزيا الفرنسية", + // "code": "+689", + // "countryCode": "PF" + // }, + // {"name": "Gabon", "name_ar": "الغابون", "code": "+241", "countryCode": "GA"}, + // {"name": "Gambia", "name_ar": "غامبيا", "code": "+220", "countryCode": "GM"}, + // {"name": "Georgia", "name_ar": "جورجيا", "code": "+995", "countryCode": "GE"}, + // {"name": "Germany", "name_ar": "ألمانيا", "code": "+49", "countryCode": "DE"}, + // {"name": "Ghana", "name_ar": "غانا", "code": "+233", "countryCode": "GH"}, + // { + // "name": "Gibraltar", + // "name_ar": "جبل طارق", + // "code": "+350", + // "countryCode": "GI" + // }, + // {"name": "Greece", "name_ar": "اليونان", "code": "+30", "countryCode": "GR"}, + // { + // "name": "Greenland", + // "name_ar": "الأرض الخضراء", + // "code": "+299", + // "countryCode": "GL" + // }, + // { + // "name": "Grenada", + // "name_ar": "غرينادا", + // "code": "+1 473", + // "countryCode": "GD" + // }, + // { + // "name": "Guadeloupe", + // "name_ar": "جوادلوب", + // "code": "+590", + // "countryCode": "GP" + // }, + // {"name": "Guam", "name_ar": "غوام", "code": "+1 671", "countryCode": "GU"}, + // { + // "name": "Guatemala", + // "name_ar": "غواتيمالا", + // "code": "+502", + // "countryCode": "GT" + // }, + // {"name": "Guernsey", "name_ar": "غيرنسي", "code": "+44", "countryCode": "GG"}, + // {"name": "Guinea", "name_ar": "غينيا", "code": "+224", "countryCode": "GN"}, + // { + // "name": "Guinea-Bissau", + // "name_ar": "غينيا بيساو", + // "code": "+245", + // "countryCode": "GW" + // }, + // {"name": "Guyana", "name_ar": "غيانا", "code": "+595", "countryCode": "GY"}, + // {"name": "Haiti", "name_ar": "هايتي", "code": "+509", "countryCode": "HT"}, + // { + // "name": "Holy See (Vatican City State)", + // "name_ar": "الكرسي الرسولي دولة الفاتيكان", + // "code": "+379", + // "countryCode": "VA" + // }, + // { + // "name": "Honduras", + // "name_ar": "هندوراس", + // "code": "+504", + // "countryCode": "HN" + // }, + // { + // "name": "Hong Kong", + // "name_ar": "هونج كونج", + // "code": "+852", + // "countryCode": "HK" + // }, + // {"name": "Hungary", "name_ar": "اليونان", "code": "+36", "countryCode": "HU"}, + // { + // "name": "Iceland", + // "name_ar": "أيسلندا", + // "code": "+354", + // "countryCode": "IS" + // }, + // {"name": "India", "name_ar": "الهند", "code": "+91", "countryCode": "IN"}, + // { + // "name": "Indonesia", + // "name_ar": "أندونيسيا", + // "code": "+62", + // "countryCode": "ID" + // }, + // { + // "name": "Iran, Islamic Republic of Persian Gulf", + // "name_ar": "جمهورية إيران الإسلامية الخليج الفارسي", + // "code": "+98", + // "countryCode": "IR" + // }, + // {"name": "Iraq", "name_ar": "العراق", "code": "+964", "countryCode": "IQ"}, + // { + // "name": "Ireland", + // "name_ar": "أيرلندا", + // "code": "+353", + // "countryCode": "IE" + // }, + // { + // "name": "Isle of Man", + // "name_ar": "جزيرة آيل أوف مان", + // "code": "+44", + // "countryCode": "IM" + // }, + // {"name": "Israel", "name_ar": "إسرائيل", "code": "+972", "countryCode": "IL"}, + // {"name": "Italy", "name_ar": "إيطاليا", "code": "+39", "countryCode": "IT"}, + // { + // "name": "Jamaica", + // "name_ar": "جامايكا", + // "code": "+1 876", + // "countryCode": "JM" + // }, + // {"name": "Japan", "name_ar": "اليابان", "code": "+81", "countryCode": "JP"}, + // {"name": "Jersey", "name_ar": "جيرسي", "code": "+44", "countryCode": "JE"}, + // {"name": "Jordan", "name_ar": "الأردن", "code": "+962", "countryCode": "JO"}, + // { + // "name": "Kazakhstan", + // "name_ar": "كازاخستان", + // "code": "+77", + // "countryCode": "KZ" + // }, + // {"name": "Kenya", "name_ar": "كينيا", "code": "+254", "countryCode": "KE"}, + // { + // "name": "Kiribati", + // "name_ar": "كيريباس", + // "code": "+686", + // "countryCode": "KI" + // }, + // { + // "name": "Korea, Democratic People's Republic of Korea", + // "name_ar": "جمهورية كوريا الديمقراطية الشعبية", + // "code": "+850", + // "countryCode": "KP" + // }, + // { + // "name": "Korea, Republic of South Korea", + // "name_ar": "جمهورية كوريا الديمقراطية الشعبية", + // "code": "+82", + // "countryCode": "KR" + // }, + // { + // "name": "Kyrgyzstan", + // "name_ar": "قرغيزستان", + // "code": "+996", + // "countryCode": "KG" + // }, + // {"name": "Laos", "name_ar": "لاوس", "code": "+856", "countryCode": "LA"}, + // {"name": "Latvia", "name_ar": "لاتفيا", "code": "+371", "countryCode": "LV"}, + // {"name": "Lebanon", "name_ar": "لبنان", "code": "+961", "countryCode": "LB"}, + // {"name": "Lesotho", "name_ar": "ليسوتو", "code": "+266", "countryCode": "LS"}, + // { + // "name": "Liberia", + // "name_ar": "ليبيريا", + // "code": "+231", + // "countryCode": "LR" + // }, + // { + // "name": "Libyan Arab Jamahiriya", + // "name_ar": "الجماهيرية العربية الليبية", + // "code": "+218", + // "countryCode": "LY" + // }, + // { + // "name": "Liechtenstein", + // "name_ar": "ليختنشتاين", + // "code": "+423", + // "countryCode": "LI" + // }, + // { + // "name": "Lithuania", + // "name_ar": "ليتوانيا", + // "code": "+370", + // "countryCode": "LT" + // }, + // { + // "name": "Luxembourg", + // "name_ar": "لوكسمبورغ", + // "code": "+352", + // "countryCode": "LU" + // }, + // {"name": "Macao", "name_ar": "ماكاو", "code": "+853", "countryCode": "MO"}, + // { + // "name": "Macedonia", + // "name_ar": "مقدونيا", + // "code": "+389", + // "countryCode": "MK" + // }, + // { + // "name": "Madagascar", + // "name_ar": "مدغشقر", + // "code": "+261", + // "countryCode": "MG" + // }, + // {"name": "Malawi", "name_ar": "مالاوي", "code": "+265", "countryCode": "MW"}, + // { + // "name": "Malaysia", + // "name_ar": "ماليزيا", + // "code": "+60", + // "countryCode": "MY" + // }, + // { + // "name": "Maldives", + // "name_ar": "جزر المالديف", + // "code": "+960", + // "countryCode": "MV" + // }, + // {"name": "Mali", "name_ar": "مالي", "code": "+223", "countryCode": "ML"}, + // {"name": "Malta", "name_ar": "مالطا", "code": "+356", "countryCode": "MT"}, + // { + // "name": "Marshall Islands", + // "name_ar": "جزر مارشال", + // "code": "+692", + // "countryCode": "MH" + // }, + // { + // "name": "Martinique", + // "name_ar": "مارتينيك", + // "code": "+596", + // "countryCode": "MQ" + // }, + // { + // "name": "Mauritania", + // "name_ar": "موريتانيا", + // "code": "+222", + // "countryCode": "MR" + // }, + // { + // "name": "Mauritius", + // "name_ar": "موريشيوس", + // "code": "+230", + // "countryCode": "MU" + // }, + // {"name": "Mayotte", "name_ar": "مايوت", "code": "+262", "countryCode": "YT"}, + // {"name": "Mexico", "name_ar": "المكسيك", "code": "+52", "countryCode": "MX"}, + // { + // "name": "Micronesia, Federated States of Micronesia", + // "name_ar": "ميكرونيزيا ، ولايات ميكرونيزيا الموحدة", + // "code": "+691", + // "countryCode": "FM" + // }, + // { + // "name": "Moldova", + // "name_ar": "مولدوفا", + // "code": "+373", + // "countryCode": "MD" + // }, + // {"name": "Monaco", "name_ar": "موناكو", "code": "+377", "countryCode": "MC"}, + // { + // "name": "Mongolia", + // "name_ar": "منغوليا", + // "code": "+976", + // "countryCode": "MN" + // }, + // { + // "name": "Montenegro", + // "name_ar": "الجبل الأسود", + // "code": "+382", + // "countryCode": "ME" + // }, + // { + // "name": "Montserrat", + // "name_ar": "مونتسيرات", + // "code": "+1664", + // "countryCode": "MS" + // }, + // {"name": "Morocco", "name_ar": "المغرب", "code": "+212", "countryCode": "MA"}, + // { + // "name": "Mozambique", + // "name_ar": "موزمبيق", + // "code": "+258", + // "countryCode": "MZ" + // }, + // {"name": "Myanmar", "name_ar": "ميانمار", "code": "+95", "countryCode": "MM"}, + // { + // "name": "Namibia", + // "name_ar": "ناميبيا", + // "code": "+264", + // "countryCode": "NA" + // }, + // {"name": "Nauru", "name_ar": "ناورو", "code": "+674", "countryCode": "NR"}, + // {"name": "Nepal", "name_ar": "نيبال", "code": "+977", "countryCode": "NP"}, + // { + // "name": "Netherlands", + // "name_ar": "هولندا", + // "code": "+31", + // "countryCode": "NL" + // }, + // { + // "name": "Netherlands Antilles", + // "name_ar": "جزر الأنتيل الهولندية", + // "code": "+599", + // "countryCode": "AN" + // }, + // { + // "name": "New Caledonia", + // "name_ar": "كاليدونيا الجديدة", + // "code": "+687", + // "countryCode": "NC" + // }, + // { + // "name": "New Zealand", + // "name_ar": "نيوزيلندا", + // "code": "+64", + // "countryCode": "NZ" + // }, + // { + // "name": "Nicaragua", + // "name_ar": "نيكاراغوا", + // "code": "+505", + // "countryCode": "NI" + // }, + // {"name": "Niger", "name_ar": "النيجر", "code": "+227", "countryCode": "NE"}, + // { + // "name": "Nigeria", + // "name_ar": "نيجيريا", + // "code": "+234", + // "countryCode": "NG" + // }, + // {"name": "Niue", "name_ar": "نيوي", "code": "+683", "countryCode": "NU"}, + // { + // "name": "Norfolk Island", + // "name_ar": "جزيرة نورفولك", + // "code": "+672", + // "countryCode": "NF" + // }, + // { + // "name": "Northern Mariana Islands", + // "name_ar": "جزر مريانا الشمالية", + // "code": "+1 670", + // "countryCode": "MP" + // }, + // {"name": "Norway", "name_ar": "النرويج", "code": "+47", "countryCode": "NO"}, + // { + // "name": "Oman", + // "name_ar": "سلطنة عمان", + // "code": "+968", + // "countryCode": "OM" + // }, + // { + // "name": "Pakistan", + // "name_ar": "باكستان", + // "code": "+92", + // "countryCode": "PK" + // }, + // {"name": "Palau", "name_ar": "بالاو", "code": "+680", "countryCode": "PW"}, + // { + // "name": "Palestinian Territory, Occupied", + // "name_ar": "الأراضي الفلسطينية المحتلة", + // "code": "+970", + // "countryCode": "PS" + // }, + // {"name": "Panama", "name_ar": "بناما", "code": "+507", "countryCode": "PA"}, + // { + // "name": "Papua New Guinea", + // "name_ar": "بابوا غينيا الجديدة", + // "code": "+675", + // "countryCode": "PG" + // }, + // { + // "name": "Paraguay", + // "name_ar": "باراغواي", + // "code": "+595", + // "countryCode": "PY" + // }, + // {"name": "Peru", "name_ar": "بيرو", "code": "+51", "countryCode": "PE"}, + // { + // "name": "Philippines", + // "name_ar": "الفلبين", + // "code": "+63", + // "countryCode": "PH" + // }, + // { + // "name": "Pitcairn", + // "name_ar": "بيتكيرن", + // "code": "+872", + // "countryCode": "PN" + // }, + // {"name": "Poland", "name_ar": "بولندا", "code": "+48", "countryCode": "PL"}, + // { + // "name": "Portugal", + // "name_ar": "البرتغال", + // "code": "+351", + // "countryCode": "PT" + // }, + // { + // "name": "Puerto Rico", + // "name_ar": "بورتوريكو", + // "code": "+1 939", + // "countryCode": "PR" + // }, + // {"name": "Qatar", "name_ar": "دولة قطر", "code": "+974", "countryCode": "QA"}, + // {"name": "Romania", "name_ar": "رومانيا", "code": "+40", "countryCode": "RO"}, + // {"name": "Russia", "name_ar": "روسيا", "code": "+7", "countryCode": "RU"}, + // {"name": "Rwanda", "name_ar": "رواندا", "code": "+250", "countryCode": "RW"}, + // { + // "name": "Reunion", + // "name_ar": "جمع شمل", + // "code": "+262", + // "countryCode": "RE" + // }, + // { + // "name": "Saint Barthelemy", + // "name_ar": "سانت بارتيليمي", + // "code": "+590", + // "countryCode": "BL" + // }, + // { + // "name": "Saint Helena, Ascension and Tristan Da Cunha", + // "name_ar": "سانت هيلانة ، أسنشن وتريستان دا كونها", + // "code": "+290", + // "countryCode": "SH" + // }, + // { + // "name": "Saint Kitts and Nevis", + // "name_ar": "سانت كيتس ونيفيس", + // "code": "+1 869", + // "countryCode": "KN" + // }, + // { + // "name": "Saint Lucia", + // "name_ar": "القديسة لوسيا", + // "code": "+1 758", + // "countryCode": "LC" + // }, + // { + // "name": "Saint Martin", + // "name_ar": "القديس مارتن", + // "code": "+590", + // "countryCode": "MF" + // }, + // { + // "name": "Saint Pierre and Miquelon", + // "name_ar": "سانت بيير وميكلون", + // "code": "+508", + // "countryCode": "PM" + // }, + // { + // "name": "Saint Vincent and the Grenadines", + // "name_ar": "سانت فنسنت وجزر غرينادين", + // "code": "+1 784", + // "countryCode": "VC" + // }, + // {"name": "Samoa", "name_ar": "ساموا", "code": "+685", "countryCode": "WS"}, + // { + // "name": "San Marino", + // "name_ar": "سان مارينو", + // "code": "+378", + // "countryCode": "SM" + // }, + // { + // "name": "Sao Tome and Principe", + // "name_ar": "ساو تومي وبرينسيبي", + // "code": "+239", + // "countryCode": "ST" + // }, + // { + // "name": "Senegal", + // "name_ar": "السنغال", + // "code": "+221", + // "countryCode": "SN" + // }, + // {"name": "Serbia", "name_ar": "صربيا", "code": "+381", "countryCode": "RS"}, + // { + // "name": "Seychelles", + // "name_ar": "سيشيل", + // "code": "+248", + // "countryCode": "SC" + // }, + // { + // "name": "Sierra Leone", + // "name_ar": "سيرا ليون", + // "code": "+232", + // "countryCode": "SL" + // }, + // { + // "name": "Singapore", + // "name_ar": "سنغافورة", + // "code": "+65", + // "countryCode": "SG" + // }, + // { + // "name": "Slovakia", + // "name_ar": "سلوفاكيا", + // "code": "+421", + // "countryCode": "SK" + // }, + // { + // "name": "Slovenia", + // "name_ar": "سلوفينيا", + // "code": "+386", + // "countryCode": "SI" + // }, + // { + // "name": "Solomon Islands", + // "name_ar": "جزر سليمان", + // "code": "+677", + // "countryCode": "SB" + // }, + // { + // "name": "Somalia", + // "name_ar": "الصومال", + // "code": "+252", + // "countryCode": "SO" + // }, + // { + // "name": "South Africa", + // "name_ar": "جنوب أفريقيا", + // "code": "+27", + // "countryCode": "ZA" + // }, + // { + // "name": "South Georgia and the South Sandwich Islands", + // "name_ar": "جورجيا الجنوبية وجزر ساندويتش الجنوبية", + // "code": "+500", + // "countryCode": "GS" + // }, + // {"name": "Spain", "name_ar": "إسبانيا", "code": "+34", "countryCode": "ES"}, + // { + // "name": "Sri Lanka", + // "name_ar": "سيريلانكا", + // "code": "+94", + // "countryCode": "LK" + // }, + // {"name": "Sudan", "name_ar": "سودان", "code": "+249", "countryCode": "SD"}, + // { + // "name": "Suriname", + // "name_ar": "سورينام", + // "code": "+597", + // "countryCode": "SR" + // }, + // { + // "name": "Svalbard and Jan Mayen", + // "name_ar": "سفالبارد وجان ماين", + // "code": "+47", + // "countryCode": "SJ" + // }, + // { + // "name": "Swaziland", + // "name_ar": "سوازيلاند", + // "code": "+268", + // "countryCode": "SZ" + // }, + // {"name": "Sweden", "name_ar": "السويد", "code": "+46", "countryCode": "SE"}, + // { + // "name": "Switzerland", + // "name_ar": "سويسرا", + // "code": "+41", + // "countryCode": "CH" + // }, + // { + // "name": "Syrian Arab Republic", + // "name_ar": "الجمهورية العربية السورية", + // "code": "+963", + // "countryCode": "SY" + // }, + // {"name": "Taiwan", "name_ar": "تايوان", "code": "+886", "countryCode": "TW"}, + // { + // "name": "Tajikistan", + // "name_ar": "طاجيكستان", + // "code": "+992", + // "countryCode": "TJ" + // }, + // { + // "name": "Tanzania, United Republic of Tanzania", + // "name_ar": "تنزانيا ، جمهورية تنزانيا المتحدة", + // "code": "+255", + // "countryCode": "TZ" + // }, + // { + // "name": "Thailand", + // "name_ar": "تايلاند", + // "code": "+66", + // "countryCode": "TH" + // }, + // { + // "name": "Timor-Leste", + // "name_ar": "تيمور الشرقية", + // "code": "+670", + // "countryCode": "TL" + // }, + // {"name": "Togo", "name_ar": "ليذهب", "code": "+228", "countryCode": "TG"}, + // { + // "name": "Tokelau", + // "name_ar": "توكيلاو", + // "code": "+690", + // "countryCode": "TK" + // }, + // {"name": "Tonga", "name_ar": "تونغا", "code": "+676", "countryCode": "TO"}, + // { + // "name": "Trinidad and Tobago", + // "name_ar": "ترينداد وتوباغو", + // "code": "+1 868", + // "countryCode": "TT" + // }, + // {"name": "Tunisia", "name_ar": "تونس", "code": "+216", "countryCode": "TN"}, + // {"name": "Turkey", "name_ar": "ديك رومي", "code": "+90", "countryCode": "TR"}, + // { + // "name": "Turkmenistan", + // "name_ar": "تركمانستان", + // "code": "+993", + // "countryCode": "TM" + // }, + // { + // "name": "Turks and Caicos Islands", + // "name_ar": "جزر تركس وكايكوس", + // "code": "+1 649", + // "countryCode": "TC" + // }, + // {"name": "Tuvalu", "name_ar": "توفالو", "code": "+688", "countryCode": "TV"}, + // {"name": "Uganda", "name_ar": "أوغندا", "code": "+256", "countryCode": "UG"}, + // { + // "name": "Ukraine", + // "name_ar": "أوكرانيا", + // "code": "+380", + // "countryCode": "UA" + // }, + // { + // "name": "United Kingdom", + // "name_ar": "المملكة المتحدة", + // "code": "+44", + // "countryCode": "GB" + // }, + // { + // "name": "United States", + // "name_ar": "الولايات المتحدة الامريكانية", + // "code": "+1", + // "countryCode": "US" + // }, + // { + // "name": "Uruguay", + // "name_ar": "أوروغواي", + // "code": "+598", + // "countryCode": "UY" + // }, + // { + // "name": "Uzbekistan", + // "name_ar": "أوزبكستان", + // "code": "+998", + // "countryCode": "UZ" + // }, + // { + // "name": "Vanuatu", + // "name_ar": "فانواتو", + // "code": "+678", + // "countryCode": "VU" + // }, + // { + // "name": "Venezuela, Bolivarian Republic of Venezuela", + // "name_ar": "فنزويلا ، جمهورية فنزويلا البوليفارية", + // "code": "+58", + // "countryCode": "VE" + // }, + // {"name": "Vietnam", "name_ar": "فيتنام", "code": "+84", "countryCode": "VN"}, + // { + // "name": "Virgin Islands, British", + // "name_ar": "جزر العذراء البريطانية", + // "code": "+1 284", + // "countryCode": "VG" + // }, + // { + // "name": "Virgin Islands, U.S.", + // "name_ar": "جزر فيرجن ، الولايات المتحدة", + // "code": "+1 340", + // "countryCode": "VI" + // }, + // { + // "name": "Wallis and Futuna", + // "name_ar": "واليس وفوتونا", + // "code": "+681", + // "countryCode": "WF" + // }, + // {"name": "Yemen", "name_ar": "اليمن", "code": "+967", "countryCode": "YE"}, + // {"name": "Zambia", "name_ar": "زامبيا", "code": "+260", "countryCode": "ZM"}, + // { + // "name": "Zimbabwe", + // "name_ar": "زيمبابوي", + // "code": "+263", + // "countryCode": "ZW" + // } +]; +// }); +// List countryList =[]; diff --git a/lib/models/pharmacy/Wishlist.dart b/lib/models/pharmacy/Wishlist.dart index 41704ede..0e1eb1b1 100644 --- a/lib/models/pharmacy/Wishlist.dart +++ b/lib/models/pharmacy/Wishlist.dart @@ -35,7 +35,7 @@ class Wishlist { dynamic languageId; dynamic id; - List productAttributes; + List? productAttributes; dynamic customerEnteredPrice; dynamic quantity; dynamic discountAmountInclTax; @@ -53,7 +53,7 @@ class Wishlist { dynamic productId; dynamic product; dynamic customerId; - Customer customer; + Customer? customer; factory Wishlist.fromJson(Map json) => Wishlist( languageId: json["language_id"], @@ -61,15 +61,15 @@ class Wishlist { productAttributes: List.from(json["product_attributes"].map((x) => x)), customerEnteredPrice: json["customer_entered_price"], quantity: json["quantity"], - discountAmountInclTax: json["discount_amount_incl_tax"], + discountAmountInclTax: json["discount_amount_incl_tax"] != null ? json["discount_amount_incl_tax"] :0.0, subtotal: json["subtotal"], subtotalWithVat: json["subtotal_with_vat"], subtotalVatAmount: json["subtotal_vat_amount"], subtotalVatRate: json["subtotal_vat_rate"], currency: json["currency"], currencyn: json["currencyn"], - rentalStartDateUtc: json["rental_start_date_utc"], - rentalEndDateUtc: json["rental_end_date_utc"], + rentalStartDateUtc: json["rental_start_date_utc"] != null ? DateTime.parse(json["rental_start_date_utc"]) : DateTime.now(), + rentalEndDateUtc: json["rental_end_date_utc"] != null ? DateTime.parse(json["rental_end_date_utc"]) : DateTime.now(), createdOnUtc: DateTime.parse(json["created_on_utc"]), updatedOnUtc: DateTime.parse(json["updated_on_utc"]), shoppingCartType: json["shopping_cart_type"], @@ -82,7 +82,7 @@ class Wishlist { Map toJson() => { "language_id": languageId, "id": id, - "product_attributes": List.from(productAttributes.map((x) => x)), + "product_attributes": List.from(productAttributes!.map((x) => x)), "customer_entered_price": customerEnteredPrice, "quantity": quantity, "discount_amount_incl_tax": discountAmountInclTax, @@ -100,7 +100,7 @@ class Wishlist { "product_id": productId, "product": product.toJson(), "customer_id": customerId, - "customer": customer.toJson(), + "customer": customer!.toJson(), }; } @@ -130,28 +130,28 @@ class Customer { this.roleIds, }); - Address billingAddress; - Address shippingAddress; - List
addresses; - String id; - String username; - String email; + Address? billingAddress; + Address? shippingAddress; + List
? addresses; + String? id; + String? username; + String? email; dynamic firstName; dynamic lastName; dynamic languageId; dynamic adminComment; - bool isTaxExempt; - bool hasShoppingCartItems; - bool active; - bool deleted; - bool isSystemAccount; + bool? isTaxExempt; + bool? hasShoppingCartItems; + bool? active; + bool? deleted; + bool? isSystemAccount; dynamic systemName; - String lastIpAddress; - DateTime createdOnUtc; - DateTime lastLoginDateUtc; - DateTime lastActivityDateUtc; + String? lastIpAddress; + DateTime? createdOnUtc; + DateTime? lastLoginDateUtc; + DateTime? lastActivityDateUtc; dynamic registeredInStoreId; - List roleIds; + List? roleIds; factory Customer.fromJson(Map json) => Customer( billingAddress: Address.fromJson(json["billing_address"]), @@ -172,16 +172,16 @@ class Customer { systemName: json["system_name"], lastIpAddress: json["last_ip_address"], createdOnUtc: DateTime.parse(json["created_on_utc"]), - lastLoginDateUtc: DateTime.parse(json["last_login_date_utc"]), + lastLoginDateUtc: json["last_login_date_utc"] != null ? DateTime.parse(json["last_login_date_utc"]) : DateTime.now(), lastActivityDateUtc: DateTime.parse(json["last_activity_date_utc"]), registeredInStoreId: json["registered_in_store_id"], roleIds: List.from(json["role_ids"].map((x) => x)), ); Map toJson() => { - "billing_address": billingAddress.toJson(), - "shipping_address": shippingAddress.toJson(), - "addresses": List.from(addresses.map((x) => x.toJson())), + "billing_address": billingAddress!.toJson(), + "shipping_address": shippingAddress!.toJson(), + "addresses": List.from(addresses!.map((x) => x.toJson())), "id": id, "username": username, "email": email, @@ -196,11 +196,11 @@ class Customer { "is_system_account": isSystemAccount, "system_name": systemName, "last_ip_address": lastIpAddress, - "created_on_utc": createdOnUtc.toIso8601String(), - "last_login_date_utc": lastLoginDateUtc.toIso8601String(), - "last_activity_date_utc": lastActivityDateUtc.toIso8601String(), + "created_on_utc": createdOnUtc!.toIso8601String(), + "last_login_date_utc": lastLoginDateUtc!.toIso8601String(), + "last_activity_date_utc": lastActivityDateUtc!.toIso8601String(), "registered_in_store_id": registeredInStoreId, - "role_ids": List.from(roleIds.map((x) => x)), + "role_ids": List.from(roleIds!.map((x) => x)), }; } @@ -226,35 +226,35 @@ class Address { this.latLong, }); - String id; - FirstName firstName; - LastName lastName; - Email email; + String? id; + FirstName? firstName; + LastName? lastName; + Email? email; dynamic company; dynamic countryId; - Country country; + Country? country; dynamic stateProvinceId; - City city; - String address1; - String address2; - String zipPostalCode; - String phoneNumber; + City? city; + String? address1; + String? address2; + String? zipPostalCode; + String? phoneNumber; dynamic faxNumber; - String customerAttributes; - DateTime createdOnUtc; + String? customerAttributes; + DateTime? createdOnUtc; dynamic province; - String latLong; + String? latLong; factory Address.fromJson(Map json) => Address( id: json["id"], - firstName: firstNameValues.map[json["first_name"]], - lastName: lastNameValues.map[json["last_name"]], - email: emailValues.map[json["email"]], + firstName: firstNameValues.map![json["first_name"]], + lastName: lastNameValues.map![json["last_name"]], + email: emailValues.map![json["email"]], company: json["company"], countryId: json["country_id"], - country: countryValues.map[json["country"]], + country: countryValues.map![json["country"]], stateProvinceId: json["state_province_id"], - city: cityValues.map[json["city"]], + city: cityValues.map![json["city"]], address1: json["address1"], address2: json["address2"], zipPostalCode: json["zip_postal_code"], @@ -282,7 +282,7 @@ class Address { "phone_number": phoneNumber, "fax_number": faxNumber, "customer_attributes": customerAttributes, - "created_on_utc": createdOnUtc.toIso8601String(), + "created_on_utc": createdOnUtc!.toIso8601String(), "province": province, "lat_long": latLong, }; @@ -335,9 +335,9 @@ class Product { this.fullDescriptionn, this.markasNew, this.showOnHomePage, - this.metaKeywords, - this.metaDescription, - this.metaTitle, +// this.metaKeywords, +// this.metaDescription, +// this.metaTitle, this.allowCustomerReviews, this.approvedRatingSum, this.notApprovedRatingSum, @@ -348,15 +348,15 @@ class Product { this.prescriptionRequired, this.rxMessage, this.rxMessagen, - this.manufacturerPartNumber, - this.gtin, +// this.manufacturerPartNumber, +// this.gtin, this.isGiftCard, this.requireOtherProducts, this.automaticallyAddRequiredProducts, this.isDownload, this.unlimitedDownloads, this.maxNumberOfDownloads, - this.downloadExpirationDays, +// this.downloadExpirationDays, this.hasSampleDownload, this.hasUserAgreement, this.isRecurring, @@ -382,7 +382,7 @@ class Product { this.allowBackInStockSubscriptions, this.orderMinimumQuantity, this.orderMaximumQuantity, - this.allowedQuantities, +// this.allowedQuantities, this.allowAddingOnlyExistingAttributeCombinations, this.disableBuyButton, this.disableWishlistButton, @@ -437,117 +437,117 @@ class Product { this.seName, }); - String id; - bool visibleIndividually; - String name; - String namen; - List localizedNames; - String shortDescription; - String shortDescriptionn; - String fullDescription; - String fullDescriptionn; - bool markasNew; - bool showOnHomePage; - dynamic metaKeywords; - dynamic metaDescription; - dynamic metaTitle; - bool allowCustomerReviews; + String? id; + bool? visibleIndividually; + String? name; + String? namen; + List? localizedNames; + String? shortDescription; + String? shortDescriptionn; + String? fullDescription; + String? fullDescriptionn; + bool? markasNew; + bool? showOnHomePage; +// dynamic metaKeywords; +// dynamic metaDescription; +// dynamic metaTitle; + bool? allowCustomerReviews; dynamic approvedRatingSum; dynamic notApprovedRatingSum; dynamic approvedTotalReviews; dynamic notApprovedTotalReviews; - String sku; - bool isRx; - bool prescriptionRequired; + String? sku; + bool? isRx; + bool? prescriptionRequired; dynamic rxMessage; dynamic rxMessagen; - dynamic manufacturerPartNumber; - dynamic gtin; - bool isGiftCard; - bool requireOtherProducts; - bool automaticallyAddRequiredProducts; - bool isDownload; - bool unlimitedDownloads; +// dynamic manufacturerPartNumber; +// dynamic gtin; + bool? isGiftCard; + bool? requireOtherProducts; + bool? automaticallyAddRequiredProducts; + bool? isDownload; + bool? unlimitedDownloads; dynamic maxNumberOfDownloads; - dynamic downloadExpirationDays; - bool hasSampleDownload; - bool hasUserAgreement; - bool isRecurring; +// dynamic downloadExpirationDays; + bool? hasSampleDownload; + bool? hasUserAgreement; + bool? isRecurring; dynamic recurringCycleLength; dynamic recurringTotalCycles; - bool isRental; + bool? isRental; dynamic rentalPriceLength; - bool isShipEnabled; - bool isFreeShipping; - bool shipSeparately; + bool? isShipEnabled; + bool? isFreeShipping; + bool? shipSeparately; dynamic additionalShippingCharge; - bool isTaxExempt; - bool isTelecommunicationsOrBroadcastingOrElectronicServices; - bool useMultipleWarehouses; + bool? isTaxExempt; + bool? isTelecommunicationsOrBroadcastingOrElectronicServices; + bool? useMultipleWarehouses; dynamic manageInventoryMethodId; dynamic stockQuantity; - String stockAvailability; - String stockAvailabilityn; - bool displayStockAvailability; - bool displayStockQuantity; + String? stockAvailability; + String? stockAvailabilityn; + bool? displayStockAvailability; + bool? displayStockQuantity; dynamic minStockQuantity; dynamic notifyAdminForQuantityBelow; - bool allowBackInStockSubscriptions; + bool? allowBackInStockSubscriptions; dynamic orderMinimumQuantity; dynamic orderMaximumQuantity; - dynamic allowedQuantities; - bool allowAddingOnlyExistingAttributeCombinations; - bool disableBuyButton; - bool disableWishlistButton; - bool availableForPreOrder; +// dynamic allowedQuantities; + bool? allowAddingOnlyExistingAttributeCombinations; + bool? disableBuyButton; + bool? disableWishlistButton; + bool? availableForPreOrder; dynamic preOrderAvailabilityStartDateTimeUtc; - bool callForPrice; - double price; + bool? callForPrice; + double? price; dynamic oldPrice; - double productCost; + double? productCost; dynamic specialPrice; dynamic specialPriceStartDateTimeUtc; dynamic specialPriceEndDateTimeUtc; - bool customerEntersPrice; + bool? customerEntersPrice; dynamic minimumCustomerEnteredPrice; dynamic maximumCustomerEnteredPrice; - bool basepriceEnabled; + bool? basepriceEnabled; dynamic basepriceAmount; dynamic basepriceBaseAmount; - bool hasTierPrices; - bool hasDiscountsApplied; + bool? hasTierPrices; + bool? hasDiscountsApplied; dynamic discountName; dynamic discountNamen; dynamic discountDescription; dynamic discountDescriptionn; dynamic discountPercentage; - String currency; - String currencyn; - double weight; + String? currency; + String? currencyn; + double? weight; dynamic length; dynamic width; dynamic height; dynamic availableStartDateTimeUtc; dynamic availableEndDateTimeUtc; dynamic displayOrder; - bool published; - bool deleted; - DateTime createdOnUtc; - DateTime updatedOnUtc; - String productType; + bool? published; + bool? deleted; + DateTime? createdOnUtc; + DateTime? updatedOnUtc; + String? productType; dynamic parentGroupedProductId; - List roleIds; - List discountIds; - List storeIds; - List manufacturerIds; - List reviews; - List images; - List attributes; - List specifications; - List associatedProductIds; - List tags; + List? roleIds; + List? discountIds; + List? storeIds; + List? manufacturerIds; + List? reviews; + List? images; + List? attributes; + List? specifications; + List? associatedProductIds; + List? tags; dynamic vendorId; - String seName; + String? seName; factory Product.fromJson(Map json) => Product( id: json["id"], @@ -561,9 +561,9 @@ class Product { fullDescriptionn: json["full_descriptionn"], markasNew: json["markas_new"], showOnHomePage: json["show_on_home_page"], - metaKeywords: json["meta_keywords"], - metaDescription: json["meta_description"], - metaTitle: json["meta_title"], +// metaKeywords: json["meta_keywords"], +// metaDescription: json["meta_description"], +// metaTitle: json["meta_title"], allowCustomerReviews: json["allow_customer_reviews"], approvedRatingSum: json["approved_rating_sum"], notApprovedRatingSum: json["not_approved_rating_sum"], @@ -572,17 +572,17 @@ class Product { sku: json["sku"], isRx: json["is_rx"], prescriptionRequired: json["prescription_required"], - rxMessage: json["rx_message"], - rxMessagen: json["rx_messagen"], - manufacturerPartNumber: json["manufacturer_part_number"], - gtin: json["gtin"], + rxMessage: json["rx_message"] != null ? json["rx_message"] : "" , + rxMessagen: json["rx_messagen"] != null ? json["rx_messagen"] : "", +// manufacturerPartNumber: json["manufacturer_part_number"], +// gtin: json["gtin"], isGiftCard: json["is_gift_card"], requireOtherProducts: json["require_other_products"], automaticallyAddRequiredProducts: json["automatically_add_required_products"], isDownload: json["is_download"], unlimitedDownloads: json["unlimited_downloads"], maxNumberOfDownloads: json["max_number_of_downloads"], - downloadExpirationDays: json["download_expiration_days"], +// downloadExpirationDays: json["download_expiration_days"], hasSampleDownload: json["has_sample_download"], hasUserAgreement: json["has_user_agreement"], isRecurring: json["is_recurring"], @@ -608,19 +608,19 @@ class Product { allowBackInStockSubscriptions: json["allow_back_in_stock_subscriptions"], orderMinimumQuantity: json["order_minimum_quantity"], orderMaximumQuantity: json["order_maximum_quantity"], - allowedQuantities: json["allowed_quantities"], +// allowedQuantities: json["allowed_quantities"], allowAddingOnlyExistingAttributeCombinations: json["allow_adding_only_existing_attribute_combinations"], disableBuyButton: json["disable_buy_button"], disableWishlistButton: json["disable_wishlist_button"], availableForPreOrder: json["available_for_pre_order"], - preOrderAvailabilityStartDateTimeUtc: json["pre_order_availability_start_date_time_utc"], + preOrderAvailabilityStartDateTimeUtc: json["pre_order_availability_start_date_time_utc"] != null ? DateTime.parse(json["pre_order_availability_start_date_time_utc"]) : DateTime.now(), callForPrice: json["call_for_price"], price: json["price"].toDouble(), oldPrice: json["old_price"], productCost: json["product_cost"].toDouble(), - specialPrice: json["special_price"], - specialPriceStartDateTimeUtc: json["special_price_start_date_time_utc"], - specialPriceEndDateTimeUtc: json["special_price_end_date_time_utc"], + specialPrice: json["special_price"] != null ? json["special_price"] : 0.0 , + specialPriceStartDateTimeUtc: json["special_price_start_date_time_utc"] != null ? DateTime.parse(json["special_price_start_date_time_utc"]) : DateTime.now(), + specialPriceEndDateTimeUtc: json["special_price_end_date_time_utc"] != null ? DateTime.parse(json["special_price_end_date_time_utc"]) : DateTime.now(), customerEntersPrice: json["customer_enters_price"], minimumCustomerEnteredPrice: json["minimum_customer_entered_price"], maximumCustomerEnteredPrice: json["maximum_customer_entered_price"], @@ -668,16 +668,16 @@ class Product { "visible_individually": visibleIndividually, "name": name, "namen": namen, - "localized_names": List.from(localizedNames.map((x) => x.toJson())), + "localized_names": List.from(localizedNames!.map((x) => x.toJson())), "short_description": shortDescription, "short_descriptionn": shortDescriptionn, "full_description": fullDescription, "full_descriptionn": fullDescriptionn, "markas_new": markasNew, "show_on_home_page": showOnHomePage, - "meta_keywords": metaKeywords, - "meta_description": metaDescription, - "meta_title": metaTitle, +// "meta_keywords": metaKeywords, +// "meta_description": metaDescription, +// "meta_title": metaTitle, "allow_customer_reviews": allowCustomerReviews, "approved_rating_sum": approvedRatingSum, "not_approved_rating_sum": notApprovedRatingSum, @@ -688,15 +688,15 @@ class Product { "prescription_required": prescriptionRequired, "rx_message": rxMessage, "rx_messagen": rxMessagen, - "manufacturer_part_number": manufacturerPartNumber, - "gtin": gtin, +// "manufacturer_part_number": manufacturerPartNumber, +// "gtin": gtin, "is_gift_card": isGiftCard, "require_other_products": requireOtherProducts, "automatically_add_required_products": automaticallyAddRequiredProducts, "is_download": isDownload, "unlimited_downloads": unlimitedDownloads, "max_number_of_downloads": maxNumberOfDownloads, - "download_expiration_days": downloadExpirationDays, +// "download_expiration_days": downloadExpirationDays, "has_sample_download": hasSampleDownload, "has_user_agreement": hasUserAgreement, "is_recurring": isRecurring, @@ -722,7 +722,7 @@ class Product { "allow_back_in_stock_subscriptions": allowBackInStockSubscriptions, "order_minimum_quantity": orderMinimumQuantity, "order_maximum_quantity": orderMaximumQuantity, - "allowed_quantities": allowedQuantities, +// "allowed_quantities": allowedQuantities, "allow_adding_only_existing_attribute_combinations": allowAddingOnlyExistingAttributeCombinations, "disable_buy_button": disableBuyButton, "disable_wishlist_button": disableWishlistButton, @@ -759,20 +759,20 @@ class Product { "display_order": displayOrder, "published": published, "deleted": deleted, - "created_on_utc": createdOnUtc.toIso8601String(), - "updated_on_utc": updatedOnUtc.toIso8601String(), + "created_on_utc": createdOnUtc!.toIso8601String(), + "updated_on_utc": updatedOnUtc!.toIso8601String(), "product_type": productType, "parent_grouped_product_id": parentGroupedProductId, - "role_ids": List.from(roleIds.map((x) => x)), - "discount_ids": List.from(discountIds.map((x) => x)), - "store_ids": List.from(storeIds.map((x) => x)), - "manufacturer_ids": List.from(manufacturerIds.map((x) => x)), - "reviews": List.from(reviews.map((x) => x)), - "images": List.from(images.map((x) => x.toJson())), - "attributes": List.from(attributes.map((x) => x)), - "specifications": List.from(specifications.map((x) => x.toJson())), - "associated_product_ids": List.from(associatedProductIds.map((x) => x)), - "tags": List.from(tags.map((x) => x)), + "role_ids": List.from(roleIds!.map((x) => x)), + "discount_ids": List.from(discountIds!.map((x) => x)), + "store_ids": List.from(storeIds!.map((x) => x)), + "manufacturer_ids": List.from(manufacturerIds!.map((x) => x)), + "reviews": List.from(reviews!.map((x) => x)), + "images": List.from(images!.map((x) => x.toJson())), + "attributes": List.from(attributes!.map((x) => x)), + "specifications": List.from(specifications!.map((x) => x.toJson())), + "associated_product_ids": List.from(associatedProductIds!.map((x) => x)), + "tags": List.from(tags!.map((x) => x)), "vendor_id": vendorId, "se_name": seName, }; @@ -789,9 +789,9 @@ class Image { dynamic id; dynamic position; - String src; - String thumb; - String attachment; + String? src; + String? thumb; + String? attachment; factory Image.fromJson(Map json) => Image( id: json["id"], @@ -817,7 +817,7 @@ class LocalizedName { }); dynamic languageId; - String localizedName; + String? localizedName; factory LocalizedName.fromJson(Map json) => LocalizedName( languageId: json["language_id"], @@ -842,10 +842,10 @@ class Specification { dynamic id; dynamic displayOrder; - String defaultValue; - String defaultValuen; - String name; - String nameN; + String? defaultValue; + String? defaultValuen; + String? name; + String? nameN; factory Specification.fromJson(Map json) => Specification( id: json["id"], @@ -867,15 +867,15 @@ class Specification { } class EnumValues { - Map map; - Map reverseMap; + Map? map; + Map? reverseMap; EnumValues(this.map); Map get reverse { if (reverseMap == null) { - reverseMap = map.map((k, v) => new MapEntry(v, k)); + reverseMap = map!.map((k, v) => new MapEntry(v, k)); } - return reverseMap; + return reverseMap!; } } diff --git a/lib/models/pharmacy/addToCartModel.dart b/lib/models/pharmacy/addToCartModel.dart index 3253e6f7..d9fac131 100644 --- a/lib/models/pharmacy/addToCartModel.dart +++ b/lib/models/pharmacy/addToCartModel.dart @@ -19,13 +19,13 @@ class ShoppingCart { this.shoppingCarts, }); - int itemCount; - int quantityCount; - double subtotal; - double subtotalWithVat; - double subtotalVatAmount; - int subtotalVatRate; - List shoppingCarts; + int? itemCount; + int? quantityCount; + double? subtotal; + double? subtotalWithVat; + double? subtotalVatAmount; + int? subtotalVatRate; + List? shoppingCarts; factory ShoppingCart.fromJson(Map json) => ShoppingCart( itemCount: json["item_count"], @@ -44,7 +44,7 @@ class ShoppingCart { "subtotal_with_vat": subtotalWithVat, "subtotal_vat_amount": subtotalVatAmount, "subtotal_vat_rate": subtotalVatRate, - "shopping_carts": List.from(shoppingCarts.map((x) => x.toJson())), + "shopping_carts": List.from(shoppingCarts!.map((x) => x.toJson())), }; } @@ -73,27 +73,27 @@ class ShoppingCartElement { this.customer, }); - int languageId; - String id; - List productAttributes; - int customerEnteredPrice; - int quantity; + int? languageId; + String ?id; + List? productAttributes; + int? customerEnteredPrice; + int? quantity; dynamic discountAmountInclTax; - String subtotal; - String subtotalWithVat; - String subtotalVatAmount; - String subtotalVatRate; - String currency; - String currencyn; + String? subtotal; + String? subtotalWithVat; + String? subtotalVatAmount; + String? subtotalVatRate; + String? currency; + String? currencyn; dynamic rentalStartDateUtc; dynamic rentalEndDateUtc; - DateTime createdOnUtc; - DateTime updatedOnUtc; - String shoppingCartType; - int productId; - Product product; - int customerId; - Customer customer; + DateTime? createdOnUtc; + DateTime? updatedOnUtc; + String? shoppingCartType; + int? productId; + Product? product; + int? customerId; + Customer? customer; factory ShoppingCartElement.fromJson(Map json) => ShoppingCartElement( languageId: json["language_id"], @@ -122,7 +122,7 @@ class ShoppingCartElement { Map toJson() => { "language_id": languageId, "id": id, - "product_attributes": List.from(productAttributes.map((x) => x)), + "product_attributes": List.from(productAttributes!.map((x) => x)), "customer_entered_price": customerEnteredPrice, "quantity": quantity, "discount_amount_incl_tax": discountAmountInclTax, @@ -134,13 +134,13 @@ class ShoppingCartElement { "currencyn": currencyn, "rental_start_date_utc": rentalStartDateUtc, "rental_end_date_utc": rentalEndDateUtc, - "created_on_utc": createdOnUtc.toIso8601String(), - "updated_on_utc": updatedOnUtc.toIso8601String(), + "created_on_utc": createdOnUtc!.toIso8601String(), + "updated_on_utc": updatedOnUtc!.toIso8601String(), "shopping_cart_type": shoppingCartType, "product_id": productId, - "product": product.toJson(), + "product": product!.toJson(), "customer_id": customerId, - "customer": customer.toJson(), + "customer": customer!.toJson(), }; } @@ -170,28 +170,28 @@ class Customer { this.roleIds, }); - Address billingAddress; - Address shippingAddress; - List
addresses; - String id; - String username; - String email; + Address? billingAddress; + Address? shippingAddress; + List
? addresses; + String? id; + String? username; + String? email; dynamic firstName; dynamic lastName; dynamic languageId; dynamic adminComment; - bool isTaxExempt; - bool hasShoppingCartItems; - bool active; - bool deleted; - bool isSystemAccount; + bool? isTaxExempt; + bool? hasShoppingCartItems; + bool? active; + bool? deleted; + bool? isSystemAccount; dynamic systemName; - String lastIpAddress; - DateTime createdOnUtc; - DateTime lastLoginDateUtc; - DateTime lastActivityDateUtc; - int registeredInStoreId; - List roleIds; + String?lastIpAddress; + DateTime? createdOnUtc; + DateTime? lastLoginDateUtc; + DateTime? lastActivityDateUtc; + int? registeredInStoreId; + List? roleIds; factory Customer.fromJson(Map json) => Customer( billingAddress: Address.fromJson(json["billing_address"]), @@ -219,9 +219,9 @@ class Customer { ); Map toJson() => { - "billing_address": billingAddress.toJson(), - "shipping_address": shippingAddress.toJson(), - "addresses": List.from(addresses.map((x) => x.toJson())), + "billing_address": billingAddress!.toJson(), + "shipping_address": shippingAddress!.toJson(), + "addresses": List.from(addresses!.map((x) => x.toJson())), "id": id, "username": username, "email": email, @@ -236,11 +236,11 @@ class Customer { "is_system_account": isSystemAccount, "system_name": systemName, "last_ip_address": lastIpAddress, - "created_on_utc": createdOnUtc.toIso8601String(), - "last_login_date_utc": lastLoginDateUtc.toIso8601String(), - "last_activity_date_utc": lastActivityDateUtc.toIso8601String(), + "created_on_utc": createdOnUtc!.toIso8601String(), + "last_login_date_utc": lastLoginDateUtc!.toIso8601String(), + "last_activity_date_utc": lastActivityDateUtc!.toIso8601String(), "registered_in_store_id": registeredInStoreId, - "role_ids": List.from(roleIds.map((x) => x)), + "role_ids": List.from(roleIds!.map((x) => x)), }; } @@ -266,35 +266,35 @@ class Address { this.latLong, }); - String id; - FirstName firstName; - LastName lastName; - Email email; + String? id; + FirstName? firstName; + LastName? lastName; + Email? email; dynamic company; - int countryId; - Country country; + int? countryId; + Country? country; dynamic stateProvinceId; - City city; - String address1; - String address2; - String zipPostalCode; - String phoneNumber; + City? city; + String? address1; + String? address2; + String? zipPostalCode; + String? phoneNumber; dynamic faxNumber; - String customerAttributes; - DateTime createdOnUtc; + String? customerAttributes; + DateTime? createdOnUtc; dynamic province; - String latLong; + String? latLong; factory Address.fromJson(Map json) => Address( id: json["id"], - firstName: firstNameValues.map[json["first_name"]], - lastName: lastNameValues.map[json["last_name"]], - email: emailValues.map[json["email"]], + firstName: firstNameValues.map![json["first_name"]], + lastName: lastNameValues.map![json["last_name"]], + email: emailValues.map![json["email"]], company: json["company"], countryId: json["country_id"], - country: countryValues.map[json["country"]], + country: countryValues.map![json["country"]], stateProvinceId: json["state_province_id"], - city: cityValues.map[json["city"]], + city: cityValues.map![json["city"]], address1: json["address1"], address2: json["address2"], zipPostalCode: json["zip_postal_code"], @@ -322,7 +322,7 @@ class Address { "phone_number": phoneNumber, "fax_number": faxNumber, "customer_attributes": customerAttributes, - "created_on_utc": createdOnUtc.toIso8601String(), + "created_on_utc": createdOnUtc!.toIso8601String(), "province": province, "lat_long": latLong, }; @@ -480,117 +480,117 @@ class Product { this.seName, }); - String id; - bool visibleIndividually; - String name; - String namen; - List localizedNames; - String shortDescription; - String shortDescriptionn; - String fullDescription; - String fullDescriptionn; - bool markasNew; - bool showOnHomePage; - String metaKeywords; - String metaDescription; - String metaTitle; - bool allowCustomerReviews; - int approvedRatingSum; - int notApprovedRatingSum; - int approvedTotalReviews; - int notApprovedTotalReviews; - String sku; - bool isRx; - bool prescriptionRequired; + String? id; + bool? visibleIndividually; + String? name; + String? namen; + List? localizedNames; + String? shortDescription; + String? shortDescriptionn; + String? fullDescription; + String? fullDescriptionn; + bool? markasNew; + bool? showOnHomePage; + String? metaKeywords; + String? metaDescription; + String? metaTitle; + bool? allowCustomerReviews; + int? approvedRatingSum; + int? notApprovedRatingSum; + int? approvedTotalReviews; + int? notApprovedTotalReviews; + String? sku; + bool? isRx; + bool? prescriptionRequired; dynamic rxMessage; dynamic rxMessagen; dynamic manufacturerPartNumber; dynamic gtin; - bool isGiftCard; - bool requireOtherProducts; - bool automaticallyAddRequiredProducts; - bool isDownload; - bool unlimitedDownloads; - int maxNumberOfDownloads; + bool? isGiftCard; + bool? requireOtherProducts; + bool? automaticallyAddRequiredProducts; + bool? isDownload; + bool? unlimitedDownloads; + int? maxNumberOfDownloads; dynamic downloadExpirationDays; - bool hasSampleDownload; - bool hasUserAgreement; - bool isRecurring; - int recurringCycleLength; - int recurringTotalCycles; - bool isRental; - int rentalPriceLength; - bool isShipEnabled; - bool isFreeShipping; - bool shipSeparately; - int additionalShippingCharge; - bool isTaxExempt; - bool isTelecommunicationsOrBroadcastingOrElectronicServices; - bool useMultipleWarehouses; - int manageInventoryMethodId; - int stockQuantity; - String stockAvailability; - String stockAvailabilityn; - bool displayStockAvailability; - bool displayStockQuantity; - int minStockQuantity; - int notifyAdminForQuantityBelow; - bool allowBackInStockSubscriptions; - int orderMinimumQuantity; - int orderMaximumQuantity; + bool? hasSampleDownload; + bool? hasUserAgreement; + bool? isRecurring; + int? recurringCycleLength; + int? recurringTotalCycles; + bool? isRental; + int? rentalPriceLength; + bool? isShipEnabled; + bool? isFreeShipping; + bool? shipSeparately; + int? additionalShippingCharge; + bool? isTaxExempt; + bool? isTelecommunicationsOrBroadcastingOrElectronicServices; + bool? useMultipleWarehouses; + int? manageInventoryMethodId; + int? stockQuantity; + String? stockAvailability; + String? stockAvailabilityn; + bool? displayStockAvailability; + bool? displayStockQuantity; + int? minStockQuantity; + int? notifyAdminForQuantityBelow; + bool? allowBackInStockSubscriptions; + int? orderMinimumQuantity; + int? orderMaximumQuantity; dynamic allowedQuantities; - bool allowAddingOnlyExistingAttributeCombinations; - bool disableBuyButton; - bool disableWishlistButton; - bool availableForPreOrder; + bool? allowAddingOnlyExistingAttributeCombinations; + bool? disableBuyButton; + bool? disableWishlistButton; + bool? availableForPreOrder; dynamic preOrderAvailabilityStartDateTimeUtc; - bool callForPrice; - double price; - int oldPrice; - double productCost; + bool? callForPrice; + double? price; + int? oldPrice; + double? productCost; dynamic specialPrice; dynamic specialPriceStartDateTimeUtc; dynamic specialPriceEndDateTimeUtc; - bool customerEntersPrice; - int minimumCustomerEnteredPrice; - int maximumCustomerEnteredPrice; - bool basepriceEnabled; - int basepriceAmount; - int basepriceBaseAmount; - bool hasTierPrices; - bool hasDiscountsApplied; + bool? customerEntersPrice; + int? minimumCustomerEnteredPrice; + int? maximumCustomerEnteredPrice; + bool? basepriceEnabled; + int? basepriceAmount; + int? basepriceBaseAmount; + bool? hasTierPrices; + bool? hasDiscountsApplied; dynamic discountName; dynamic discountNamen; dynamic discountDescription; dynamic discountDescriptionn; dynamic discountPercentage; - String currency; - String currencyn; - double weight; - int length; - int width; - int height; + String? currency; + String? currencyn; + double? weight; + int? length; + int? width; + int? height; dynamic availableStartDateTimeUtc; dynamic availableEndDateTimeUtc; - int displayOrder; - bool published; - bool deleted; - DateTime createdOnUtc; - DateTime updatedOnUtc; - String productType; - int parentGroupedProductId; - List roleIds; - List discountIds; - List storeIds; - List manufacturerIds; - List reviews; - List images; - List attributes; - List specifications; - List associatedProductIds; - List tags; - int vendorId; - String seName; + int? displayOrder; + bool? published; + bool? deleted; + DateTime? createdOnUtc; + DateTime? updatedOnUtc; + String? productType; + int? parentGroupedProductId; + List? roleIds; + List? discountIds; + List? storeIds; + List? manufacturerIds; + List? reviews; + List? images; + List? attributes; + List? specifications; + List? associatedProductIds; + List? tags; + int? vendorId; + String? seName; factory Product.fromJson(Map json) => Product( id: json["id"], @@ -711,7 +711,7 @@ class Product { "visible_individually": visibleIndividually, "name": name, "namen": namen, - "localized_names": List.from(localizedNames.map((x) => x.toJson())), + "localized_names": List.from(localizedNames!.map((x) => x.toJson())), "short_description": shortDescription, "short_descriptionn": shortDescriptionn, "full_description": fullDescription, @@ -802,20 +802,20 @@ class Product { "display_order": displayOrder, "published": published, "deleted": deleted, - "created_on_utc": createdOnUtc.toIso8601String(), - "updated_on_utc": updatedOnUtc.toIso8601String(), + "created_on_utc": createdOnUtc!.toIso8601String(), + "updated_on_utc": updatedOnUtc!.toIso8601String(), "product_type": productType, "parent_grouped_product_id": parentGroupedProductId, - "role_ids": List.from(roleIds.map((x) => x)), - "discount_ids": List.from(discountIds.map((x) => x)), - "store_ids": List.from(storeIds.map((x) => x)), - "manufacturer_ids": List.from(manufacturerIds.map((x) => x)), - "reviews": List.from(reviews.map((x) => x)), - "images": List.from(images.map((x) => x.toJson())), - "attributes": List.from(attributes.map((x) => x)), - "specifications": List.from(specifications.map((x) => x.toJson())), - "associated_product_ids": List.from(associatedProductIds.map((x) => x)), - "tags": List.from(tags.map((x) => x)), + "role_ids": List.from(roleIds!.map((x) => x)), + "discount_ids": List.from(discountIds!.map((x) => x)), + "store_ids": List.from(storeIds!.map((x) => x)), + "manufacturer_ids": List.from(manufacturerIds!.map((x) => x)), + "reviews": List.from(reviews!.map((x) => x)), + "images": List.from(images!.map((x) => x.toJson())), + "attributes": List.from(attributes!.map((x) => x)), + "specifications": List.from(specifications!.map((x) => x.toJson())), + "associated_product_ids": List.from(associatedProductIds!.map((x) => x)), + "tags": List.from(tags!.map((x) => x)), "vendor_id": vendorId, "se_name": seName, }; @@ -830,11 +830,11 @@ class Image { this.attachment, }); - int id; - int position; - String src; - String thumb; - String attachment; + int? id; + int? position; + String? src; + String? thumb; + String? attachment; factory Image.fromJson(Map json) => Image( id: json["id"], @@ -859,8 +859,8 @@ class LocalizedName { this.localizedName, }); - int languageId; - String localizedName; + int? languageId; + String? localizedName; factory LocalizedName.fromJson(Map json) => LocalizedName( languageId: json["language_id"], @@ -883,12 +883,12 @@ class Specification { this.nameN, }); - int id; - int displayOrder; - String defaultValue; - String defaultValuen; - String name; - String nameN; + int? id; + int? displayOrder; + String? defaultValue; + String? defaultValuen; + String? name; + String? nameN; factory Specification.fromJson(Map json) => Specification( id: json["id"], @@ -910,15 +910,15 @@ class Specification { } class EnumValues { - Map map; - Map reverseMap; + Map? map; + Map? reverseMap; EnumValues(this.map); Map get reverse { if (reverseMap == null) { - reverseMap = map.map((k, v) => new MapEntry(v, k)); + reverseMap = map!.map((k, v) => new MapEntry(v, k)); } - return reverseMap; + return reverseMap!; } } diff --git a/lib/models/pharmacy/brandModel.dart b/lib/models/pharmacy/brandModel.dart index 2855d492..c1a64c2f 100644 --- a/lib/models/pharmacy/brandModel.dart +++ b/lib/models/pharmacy/brandModel.dart @@ -30,24 +30,24 @@ class Brand { this.image, }); - String id; - String name; - String namen; - List localizedNames; - String description; - int manufacturerTemplateId; - String metaKeywords; + String? id; + String? name; + String? namen; + List? localizedNames; + String? description; + int? manufacturerTemplateId; + String? metaKeywords; dynamic metaDescription; dynamic metaTitle; - int pageSize; - String pageSizeOptions; + int? pageSize; + String? pageSizeOptions; dynamic priceRanges; - bool published; - bool deleted; - int displayOrder; - DateTime createdOnUtc; - DateTime updatedOnUtc; - Image image; + bool? published; + bool? deleted; + int? displayOrder; + DateTime? createdOnUtc; + DateTime? updatedOnUtc; + Image? image; factory Brand.fromJson(Map json) => Brand( id: json["id"], @@ -74,7 +74,7 @@ class Brand { "id": id, "name": name, "namen": namen, - "localized_names": List.from(localizedNames.map((x) => x.toJson())), + "localized_names": List.from(localizedNames!.map((x) => x.toJson())), "description": description == null ? null : description, "manufacturer_template_id": manufacturerTemplateId, "meta_keywords": metaKeywords, @@ -86,9 +86,9 @@ class Brand { "published": published, "deleted": deleted, "display_order": displayOrder, - "created_on_utc": createdOnUtc.toIso8601String(), - "updated_on_utc": updatedOnUtc.toIso8601String(), - "image": image == null ? null : image.toJson(), + "created_on_utc": createdOnUtc!.toIso8601String(), + "updated_on_utc": updatedOnUtc!.toIso8601String(), + "image": image == null ? null : image!.toJson(), }; } @@ -99,7 +99,7 @@ class Image { this.attachment, }); - String src; + String? src; dynamic thumb; dynamic attachment; @@ -122,8 +122,8 @@ class LocalizedName { this.localizedName, }); - int languageId; - String localizedName; + int? languageId; + String? localizedName; factory LocalizedName.fromJson(Map json) => LocalizedName( languageId: json["language_id"], diff --git a/lib/models/pharmacy/locationModel.dart b/lib/models/pharmacy/locationModel.dart index 36ee7350..ee80ecde 100644 --- a/lib/models/pharmacy/locationModel.dart +++ b/lib/models/pharmacy/locationModel.dart @@ -36,33 +36,33 @@ class LocationModel { this.sortOrder, }); - ExpiryDate expiryDate; - double sellingPrice; - int quantity; - int itemId; - int locationId; - int projectId; - String setupId; - String locationDescription; + ExpiryDate? expiryDate; + double? sellingPrice; + int? quantity; + int? itemId; + int? locationId; + int? projectId; + String? setupId; + String? locationDescription; dynamic locationDescriptionN; - ItemDescription itemDescription; + ItemDescription? itemDescription; dynamic itemDescriptionN; - Alias alias; - int locationTypeId; - int barcode; + Alias? alias; + int? locationTypeId; + int? barcode; dynamic companybarcode; - int cityId; - CityName cityName; - int distanceInKilometers; - String latitude; - int locationType; - String longitude; - String phoneNumber; - String projectImageUrl; - int sortOrder; + int? cityId; + String? cityName; + int? distanceInKilometers; + String? latitude; + int? locationType; + String? longitude; + String? phoneNumber; + String? projectImageUrl; + int? sortOrder; factory LocationModel.fromJson(Map json) => LocationModel( - expiryDate: expiryDateValues.map[json["ExpiryDate"]], + expiryDate: expiryDateValues.map![json["ExpiryDate"]], sellingPrice: json["SellingPrice"].toDouble(), quantity: json["Quantity"], itemId: json["ItemID"], @@ -71,14 +71,14 @@ class LocationModel { setupId: json["SetupID"], locationDescription: json["LocationDescription"], locationDescriptionN: json["LocationDescriptionN"], - itemDescription: itemDescriptionValues.map[json["ItemDescription"]], + itemDescription: itemDescriptionValues.map![json["ItemDescription"]], itemDescriptionN: json["ItemDescriptionN"], - alias: aliasValues.map[json["Alias"]], + alias: aliasValues.map![json["Alias"]], locationTypeId: json["LocationTypeID"], barcode: json["Barcode"], companybarcode: json["Companybarcode"], cityId: json["CityID"], - cityName: cityNameValues.map[json["CityName"]], + cityName: json["CityName"], distanceInKilometers: json["DistanceInKilometers"], latitude: json["Latitude"], locationType: json["LocationType"], @@ -105,7 +105,7 @@ class LocationModel { "Barcode": barcode, "Companybarcode": companybarcode, "CityID": cityId, - "CityName": cityNameValues.reverse[cityName], + "CityName": cityName, "DistanceInKilometers": distanceInKilometers, "Latitude": latitude, "LocationType": locationType, @@ -145,15 +145,15 @@ final itemDescriptionValues = EnumValues({ }); class EnumValues { - Map map; - Map reverseMap; + Map? map; + Map? reverseMap; EnumValues(this.map); Map get reverse { if (reverseMap == null) { - reverseMap = map.map((k, v) => new MapEntry(v, k)); + reverseMap = map!.map((k, v) => new MapEntry(v, k)); } - return reverseMap; + return reverseMap!; } } diff --git a/lib/models/pharmacy/productDetailModel.dart b/lib/models/pharmacy/productDetailModel.dart index d2e8f010..0d09130f 100644 --- a/lib/models/pharmacy/productDetailModel.dart +++ b/lib/models/pharmacy/productDetailModel.dart @@ -1,7 +1,3 @@ -// To parse this JSON data, do -// -// final productDetail = productDetailFromJson(jsonString); - import 'dart:convert'; List productDetailFromJson(String str) => List.from(json.decode(str).map((x) => ProductDetail.fromJson(x))); @@ -13,15 +9,15 @@ class ProductDetail { this.reviews, }); - List reviews; + List? reviews; factory ProductDetail.fromJson(Map json) => ProductDetail( - reviews: List.from(json["reviews"].map((x) => Review.fromJson(x))), - ); + reviews: List.from(json["reviews"].map((x) => Review.fromJson(x))), + ); Map toJson() => { - "reviews": List.from(reviews.map((x) => x.toJson())), - }; + "reviews": List.from(reviews!.map((x) => x.toJson())), + }; } class Review { @@ -44,60 +40,60 @@ class Review { this.product, }); - int id; - int position; - int reviewId; - int customerId; - int productId; - int storeId; - bool isApproved; - String title; - String reviewText; + int? id; + int? position; + int? reviewId; + int? customerId; + int? productId; + int? storeId; + bool? isApproved; + String? title; + String? reviewText; dynamic replyText; - int rating; - int helpfulYesTotal; - int helpfulNoTotal; - DateTime createdOnUtc; - Customer customer; + int? rating; + int? helpfulYesTotal; + int? helpfulNoTotal; + DateTime? createdOnUtc; + Customer? customer; dynamic product; factory Review.fromJson(Map json) => Review( - id: json["id"], - position: json["position"], - reviewId: json["review_id"], - customerId: json["customer_id"], - productId: json["product_id"], - storeId: json["store_id"], - isApproved: json["is_approved"], - title: json["title"], - reviewText: json["review_text"], - replyText: json["reply_text"], - rating: json["rating"], - helpfulYesTotal: json["helpful_yes_total"], - helpfulNoTotal: json["helpful_no_total"], - createdOnUtc: DateTime.parse(json["created_on_utc"]), - customer: Customer.fromJson(json["customer"]), - product: json["product"], - ); + id: json["id"], + position: json["position"], + reviewId: json["review_id"], + customerId: json["customer_id"], + productId: json["product_id"], + storeId: json["store_id"], + isApproved: json["is_approved"], + title: json["title"], + reviewText: json["review_text"], + replyText: json["reply_text"], + rating: json["rating"], + helpfulYesTotal: json["helpful_yes_total"], + helpfulNoTotal: json["helpful_no_total"], + createdOnUtc: DateTime.parse(json["created_on_utc"]), + customer: Customer.fromJson(json["customer"]), + product: json["product"], + ); Map toJson() => { - "id": id, - "position": position, - "review_id": reviewId, - "customer_id": customerId, - "product_id": productId, - "store_id": storeId, - "is_approved": isApproved, - "title": title, - "review_text": reviewText, - "reply_text": replyText, - "rating": rating, - "helpful_yes_total": helpfulYesTotal, - "helpful_no_total": helpfulNoTotal, - "created_on_utc": createdOnUtc.toIso8601String(), - "customer": customer.toJson(), - "product": product, - }; + "id": id, + "position": position, + "review_id": reviewId, + "customer_id": customerId, + "product_id": productId, + "store_id": storeId, + "is_approved": isApproved, + "title": title, + "review_text": reviewText, + "reply_text": replyText, + "rating": rating, + "helpful_yes_total": helpfulYesTotal, + "helpful_no_total": helpfulNoTotal, + "created_on_utc": createdOnUtc!.toIso8601String(), + "customer": customer!.toJson(), + "product": product, + }; } class Customer { @@ -135,18 +131,18 @@ class Customer { dynamic fileNumber; dynamic iqamaNumber; - int isOutSa; - int patientType; + int? isOutSa; + int? patientType; dynamic gender; - DateTime birthDate; + DateTime? birthDate; dynamic phone; dynamic countryCode; dynamic yahalaAccountno; dynamic billingAddress; dynamic shippingAddress; - String id; - Email username; - Email email; + String? id; + Email? username; + Email? email; dynamic firstName; dynamic lastName; dynamic languageId; @@ -164,86 +160,84 @@ class Customer { dynamic registeredInStoreId; factory Customer.fromJson(Map json) => Customer( - fileNumber: json["file_number"], - iqamaNumber: json["iqama_number"], - isOutSa: json["is_out_sa"], - patientType: json["patient_type"], - gender: json["gender"], - birthDate: DateTime.parse(json["birth_date"]), - phone: json["phone"], - countryCode: json["country_code"], - yahalaAccountno: json["yahala_accountno"], - billingAddress: json["billing_address"], - shippingAddress: json["shipping_address"], - id: json["id"], - username: emailValues.map[json["username"]], - email: emailValues.map[json["email"]], - firstName: json["first_name"], - lastName: json["last_name"], - languageId: json["language_id"], - adminComment: json["admin_comment"], - isTaxExempt: json["is_tax_exempt"], - hasShoppingCartItems: json["has_shopping_cart_items"], - active: json["active"], - deleted: json["deleted"], - isSystemAccount: json["is_system_account"], - systemName: json["system_name"], - lastIpAddress: json["last_ip_address"], - createdOnUtc: json["created_on_utc"], - lastLoginDateUtc: json["last_login_date_utc"], - lastActivityDateUtc: json["last_activity_date_utc"], - registeredInStoreId: json["registered_in_store_id"], - ); + fileNumber: json["file_number"], + iqamaNumber: json["iqama_number"], + isOutSa: json["is_out_sa"], + patientType: json["patient_type"], + gender: json["gender"], + birthDate: DateTime.parse(json["birth_date"]), + phone: json["phone"], + countryCode: json["country_code"], + yahalaAccountno: json["yahala_accountno"], + billingAddress: json["billing_address"], + shippingAddress: json["shipping_address"], + id: json["id"], + username: emailValues.map![json["username"]], + email: emailValues.map![json["email"]], + firstName: json["first_name"], + lastName: json["last_name"], + languageId: json["language_id"], + adminComment: json["admin_comment"], + isTaxExempt: json["is_tax_exempt"], + hasShoppingCartItems: json["has_shopping_cart_items"], + active: json["active"], + deleted: json["deleted"], + isSystemAccount: json["is_system_account"], + systemName: json["system_name"], + lastIpAddress: json["last_ip_address"], + createdOnUtc: json["created_on_utc"], + lastLoginDateUtc: json["last_login_date_utc"], + lastActivityDateUtc: json["last_activity_date_utc"], + registeredInStoreId: json["registered_in_store_id"], + ); Map toJson() => { - "file_number": fileNumber, - "iqama_number": iqamaNumber, - "is_out_sa": isOutSa, - "patient_type": patientType, - "gender": gender, - "birth_date": birthDate.toIso8601String(), - "phone": phone, - "country_code": countryCode, - "yahala_accountno": yahalaAccountno, - "billing_address": billingAddress, - "shipping_address": shippingAddress, - "id": id, - "username": emailValues.reverse[username], - "email": emailValues.reverse[email], - "first_name": firstName, - "last_name": lastName, - "language_id": languageId, - "admin_comment": adminComment, - "is_tax_exempt": isTaxExempt, - "has_shopping_cart_items": hasShoppingCartItems, - "active": active, - "deleted": deleted, - "is_system_account": isSystemAccount, - "system_name": systemName, - "last_ip_address": lastIpAddress, - "created_on_utc": createdOnUtc, - "last_login_date_utc": lastLoginDateUtc, - "last_activity_date_utc": lastActivityDateUtc, - "registered_in_store_id": registeredInStoreId, - }; + "file_number": fileNumber, + "iqama_number": iqamaNumber, + "is_out_sa": isOutSa, + "patient_type": patientType, + "gender": gender, + "birth_date": birthDate!.toIso8601String(), + "phone": phone, + "country_code": countryCode, + "yahala_accountno": yahalaAccountno, + "billing_address": billingAddress, + "shipping_address": shippingAddress, + "id": id, + "username": emailValues.reverse[username], + "email": emailValues.reverse[email], + "first_name": firstName, + "last_name": lastName, + "language_id": languageId, + "admin_comment": adminComment, + "is_tax_exempt": isTaxExempt, + "has_shopping_cart_items": hasShoppingCartItems, + "active": active, + "deleted": deleted, + "is_system_account": isSystemAccount, + "system_name": systemName, + "last_ip_address": lastIpAddress, + "created_on_utc": createdOnUtc, + "last_login_date_utc": lastLoginDateUtc, + "last_activity_date_utc": lastActivityDateUtc, + "registered_in_store_id": registeredInStoreId, + }; } enum Email { STEVE_GATES_NOP_COMMERCE_COM } -final emailValues = EnumValues({ - "steve_gates@nopCommerce.com": Email.STEVE_GATES_NOP_COMMERCE_COM -}); +final emailValues = EnumValues({"steve_gates@nopCommerce.com": Email.STEVE_GATES_NOP_COMMERCE_COM}); class EnumValues { - Map map; - Map reverseMap; + Map? map; + Map? reverseMap; EnumValues(this.map); Map get reverse { if (reverseMap == null) { - reverseMap = map.map((k, v) => new MapEntry(v, k)); + reverseMap = map!.map((k, v) => new MapEntry(v, k)); } - return reverseMap; + return reverseMap!; } } diff --git a/lib/models/pharmacy/products.dart b/lib/models/pharmacy/products.dart index b4833c64..b792399d 100644 --- a/lib/models/pharmacy/products.dart +++ b/lib/models/pharmacy/products.dart @@ -15,17 +15,17 @@ class Products { }); dynamic messageStatus; - List products; + List? products; factory Products.fromJson(Map json) => Products( - messageStatus: json["MessageStatus"], - products: List.from(json["products"].map((x) => Product.fromJson(x))), - ); + messageStatus: json["MessageStatus"], + products: List.from(json["products"].map((x) => Product.fromJson(x))), + ); Map toJson() => { - "MessageStatus": messageStatus, - "products": List.from(products.map((x) => x.toJson())), - }; + "MessageStatus": messageStatus, + "products": List.from(products!.map((x) => x.toJson())), + }; } class Product { @@ -143,345 +143,345 @@ class Product { this.seName, }); - String id; - bool visibleIndividually; - String name; - String namen; - List localizedNames; - String shortDescription; - String shortDescriptionn; - String fullDescription; - String fullDescriptionn; - bool markasNew; - bool showOnHomePage; - String metaKeywords; - String metaDescription; - String metaTitle; - bool allowCustomerReviews; - int approvedRatingSum; - int notApprovedRatingSum; - int approvedTotalReviews; - int notApprovedTotalReviews; - String sku; - bool isRx; - bool prescriptionRequired; - String rxMessage; - String rxMessagen; + String? id; + bool? visibleIndividually; + String? name; + String? namen; + List? localizedNames; + String? shortDescription; + String? shortDescriptionn; + String? fullDescription; + String? fullDescriptionn; + bool? markasNew; + bool? showOnHomePage; + String? metaKeywords; + String? metaDescription; + String? metaTitle; + bool? allowCustomerReviews; + int? approvedRatingSum; + int? notApprovedRatingSum; + int? approvedTotalReviews; + int? notApprovedTotalReviews; + String? sku; + bool? isRx; + bool? prescriptionRequired; + String? rxMessage; + String? rxMessagen; dynamic manufacturerPartNumber; dynamic gtin; - bool isGiftCard; - bool requireOtherProducts; - bool automaticallyAddRequiredProducts; - bool isDownload; - bool unlimitedDownloads; - int maxNumberOfDownloads; + bool? isGiftCard; + bool? requireOtherProducts; + bool? automaticallyAddRequiredProducts; + bool? isDownload; + bool? unlimitedDownloads; + int? maxNumberOfDownloads; dynamic downloadExpirationDays; - bool hasSampleDownload; - bool hasUserAgreement; - bool isRecurring; - int recurringCycleLength; - int recurringTotalCycles; - bool isRental; - int rentalPriceLength; - bool isShipEnabled; - bool isFreeShipping; - bool shipSeparately; - int additionalShippingCharge; - bool isTaxExempt; - bool isTelecommunicationsOrBroadcastingOrElectronicServices; - bool useMultipleWarehouses; - int manageInventoryMethodId; - int stockQuantity; - String stockAvailability; - String stockAvailabilityn; - bool displayStockAvailability; - bool displayStockQuantity; - int minStockQuantity; - int notifyAdminForQuantityBelow; - bool allowBackInStockSubscriptions; - int orderMinimumQuantity; - int orderMaximumQuantity; + bool? hasSampleDownload; + bool? hasUserAgreement; + bool? isRecurring; + int? recurringCycleLength; + int? recurringTotalCycles; + bool? isRental; + int? rentalPriceLength; + bool? isShipEnabled; + bool? isFreeShipping; + bool? shipSeparately; + int? additionalShippingCharge; + bool? isTaxExempt; + bool? isTelecommunicationsOrBroadcastingOrElectronicServices; + bool? useMultipleWarehouses; + int? manageInventoryMethodId; + int? stockQuantity; + String? stockAvailability; + String? stockAvailabilityn; + bool? displayStockAvailability; + bool? displayStockQuantity; + int? minStockQuantity; + int? notifyAdminForQuantityBelow; + bool? allowBackInStockSubscriptions; + int? orderMinimumQuantity; + int? orderMaximumQuantity; dynamic allowedQuantities; - bool allowAddingOnlyExistingAttributeCombinations; - bool disableBuyButton; - bool disableWishlistButton; - bool availableForPreOrder; + bool? allowAddingOnlyExistingAttributeCombinations; + bool? disableBuyButton; + bool? disableWishlistButton; + bool? availableForPreOrder; dynamic preOrderAvailabilityStartDateTimeUtc; - bool callForPrice; - double price; - int oldPrice; - double productCost; + bool? callForPrice; + double? price; + int? oldPrice; + double? productCost; dynamic specialPrice; dynamic specialPriceStartDateTimeUtc; dynamic specialPriceEndDateTimeUtc; - bool customerEntersPrice; - int minimumCustomerEnteredPrice; - int maximumCustomerEnteredPrice; - bool basepriceEnabled; - int basepriceAmount; - int basepriceBaseAmount; - bool hasTierPrices; - bool hasDiscountsApplied; - String discountName; - String discountNamen; - String discountDescription; - String discountDescriptionn; - String discountPercentage; - String currency; - String currencyn; - double weight; - int length; - int width; - int height; + bool? customerEntersPrice; + int? minimumCustomerEnteredPrice; + int? maximumCustomerEnteredPrice; + bool? basepriceEnabled; + int? basepriceAmount; + int? basepriceBaseAmount; + bool? hasTierPrices; + bool? hasDiscountsApplied; + String? discountName; + String? discountNamen; + String? discountDescription; + String? discountDescriptionn; + String? discountPercentage; + String? currency; + String? currencyn; + double? weight; + int? length; + int? width; + int? height; dynamic availableStartDateTimeUtc; dynamic availableEndDateTimeUtc; - int displayOrder; - bool published; - bool deleted; - DateTime createdOnUtc; - DateTime updatedOnUtc; - String productType; - int parentGroupedProductId; - List roleIds; - List discountIds; - List storeIds; - List manufacturerIds; - List reviews; - List images; - List attributes; - List specifications; - List associatedProductIds; - List tags; - int vendorId; - String seName; + int? displayOrder; + bool? published; + bool? deleted; + DateTime? createdOnUtc; + DateTime? updatedOnUtc; + String? productType; + int? parentGroupedProductId; + List? roleIds; + List? discountIds; + List? storeIds; + List? manufacturerIds; + List? reviews; + List? images; + List? attributes; + List? specifications; + List? associatedProductIds; + List? tags; + int? vendorId; + String? seName; factory Product.fromJson(Map json) => Product( - id: json["id"], - visibleIndividually: json["visible_individually"], - name: json["name"], - namen: json["namen"], - localizedNames: List.from(json["localized_names"].map((x) => LocalizedName.fromJson(x))), - shortDescription: json["short_description"] == null ? null : json["short_description"], - shortDescriptionn: json["short_descriptionn"] == null ? null : json["short_descriptionn"], - fullDescription: json["full_description"], - fullDescriptionn: json["full_descriptionn"], - markasNew: json["markas_new"], - showOnHomePage: json["show_on_home_page"], - metaKeywords: json["meta_keywords"] == null ? null : json["meta_keywords"], - metaDescription: json["meta_description"] == null ? null : json["meta_description"], - metaTitle: json["meta_title"] == null ? null : json["meta_title"], - allowCustomerReviews: json["allow_customer_reviews"], - approvedRatingSum: json["approved_rating_sum"], - notApprovedRatingSum: json["not_approved_rating_sum"], - approvedTotalReviews: json["approved_total_reviews"], - notApprovedTotalReviews: json["not_approved_total_reviews"], - sku: json["sku"], - isRx: json["is_rx"], - prescriptionRequired: json["prescription_required"], - rxMessage: json["rx_message"] == null ? null : json["rx_message"], - rxMessagen: json["rx_messagen"] == null ? null : json["rx_messagen"], - manufacturerPartNumber: json["manufacturer_part_number"], - gtin: json["gtin"], - isGiftCard: json["is_gift_card"], - requireOtherProducts: json["require_other_products"], - automaticallyAddRequiredProducts: json["automatically_add_required_products"], - isDownload: json["is_download"], - unlimitedDownloads: json["unlimited_downloads"], - maxNumberOfDownloads: json["max_number_of_downloads"], - downloadExpirationDays: json["download_expiration_days"], - hasSampleDownload: json["has_sample_download"], - hasUserAgreement: json["has_user_agreement"], - isRecurring: json["is_recurring"], - recurringCycleLength: json["recurring_cycle_length"], - recurringTotalCycles: json["recurring_total_cycles"], - isRental: json["is_rental"], - rentalPriceLength: json["rental_price_length"], - isShipEnabled: json["is_ship_enabled"], - isFreeShipping: json["is_free_shipping"], - shipSeparately: json["ship_separately"], - additionalShippingCharge: json["additional_shipping_charge"], - isTaxExempt: json["is_tax_exempt"], - isTelecommunicationsOrBroadcastingOrElectronicServices: json["is_telecommunications_or_broadcasting_or_electronic_services"], - useMultipleWarehouses: json["use_multiple_warehouses"], - manageInventoryMethodId: json["manage_inventory_method_id"], - stockQuantity: json["stock_quantity"], - stockAvailability: json["stock_availability"], - stockAvailabilityn: json["stock_availabilityn"], - displayStockAvailability: json["display_stock_availability"], - displayStockQuantity: json["display_stock_quantity"], - minStockQuantity: json["min_stock_quantity"], - notifyAdminForQuantityBelow: json["notify_admin_for_quantity_below"], - allowBackInStockSubscriptions: json["allow_back_in_stock_subscriptions"], - orderMinimumQuantity: json["order_minimum_quantity"], - orderMaximumQuantity: json["order_maximum_quantity"], - allowedQuantities: json["allowed_quantities"], - allowAddingOnlyExistingAttributeCombinations: json["allow_adding_only_existing_attribute_combinations"], - disableBuyButton: json["disable_buy_button"], - disableWishlistButton: json["disable_wishlist_button"], - availableForPreOrder: json["available_for_pre_order"], - preOrderAvailabilityStartDateTimeUtc: json["pre_order_availability_start_date_time_utc"], - callForPrice: json["call_for_price"], - price: json["price"].toDouble(), - oldPrice: json["old_price"], - productCost: json["product_cost"].toDouble(), - specialPrice: json["special_price"], - specialPriceStartDateTimeUtc: json["special_price_start_date_time_utc"], - specialPriceEndDateTimeUtc: json["special_price_end_date_time_utc"], - customerEntersPrice: json["customer_enters_price"], - minimumCustomerEnteredPrice: json["minimum_customer_entered_price"], - maximumCustomerEnteredPrice: json["maximum_customer_entered_price"], - basepriceEnabled: json["baseprice_enabled"], - basepriceAmount: json["baseprice_amount"], - basepriceBaseAmount: json["baseprice_base_amount"], - hasTierPrices: json["has_tier_prices"], - hasDiscountsApplied: json["has_discounts_applied"], - discountName: json["discount_name"] == null ? null : json["discount_name"], - discountNamen: json["discount_namen"] == null ? null : json["discount_namen"], - discountDescription: json["discount_description"] == null ? null : json["discount_description"], - discountDescriptionn: json["discount_Descriptionn"] == null ? null : json["discount_Descriptionn"], - discountPercentage: json["discount_percentage"] == null ? null : json["discount_percentage"], - currency: json["currency"], - currencyn: json["currencyn"], - weight: json["weight"].toDouble(), - length: json["length"], - width: json["width"], - height: json["height"], - availableStartDateTimeUtc: json["available_start_date_time_utc"], - availableEndDateTimeUtc: json["available_end_date_time_utc"], - displayOrder: json["display_order"], - published: json["published"], - deleted: json["deleted"], - createdOnUtc: DateTime.parse(json["created_on_utc"]), - updatedOnUtc: DateTime.parse(json["updated_on_utc"]), - productType: json["product_type"], - parentGroupedProductId: json["parent_grouped_product_id"], - roleIds: List.from(json["role_ids"].map((x) => x)), - discountIds: List.from(json["discount_ids"].map((x) => x)), - storeIds: List.from(json["store_ids"].map((x) => x)), - manufacturerIds: List.from(json["manufacturer_ids"].map((x) => x)), - reviews: List.from(json["reviews"].map((x) => Review.fromJson(x))), - images: List.from(json["images"].map((x) => Image.fromJson(x))), - attributes: List.from(json["attributes"].map((x) => x)), - specifications: List.from(json["specifications"].map((x) => Specification.fromJson(x))), - associatedProductIds: List.from(json["associated_product_ids"].map((x) => x)), - tags: List.from(json["tags"].map((x) => x)), - vendorId: json["vendor_id"], - seName: json["se_name"], - ); + id: json["id"], + visibleIndividually: json["visible_individually"], + name: json["name"], + namen: json["namen"], + localizedNames: List.from(json["localized_names"].map((x) => LocalizedName.fromJson(x))), + shortDescription: json["short_description"] == null ? null : json["short_description"], + shortDescriptionn: json["short_descriptionn"] == null ? null : json["short_descriptionn"], + fullDescription: json["full_description"], + fullDescriptionn: json["full_descriptionn"], + markasNew: json["markas_new"], + showOnHomePage: json["show_on_home_page"], + metaKeywords: json["meta_keywords"] == null ? null : json["meta_keywords"], + metaDescription: json["meta_description"] == null ? null : json["meta_description"], + metaTitle: json["meta_title"] == null ? null : json["meta_title"], + allowCustomerReviews: json["allow_customer_reviews"], + approvedRatingSum: json["approved_rating_sum"], + notApprovedRatingSum: json["not_approved_rating_sum"], + approvedTotalReviews: json["approved_total_reviews"], + notApprovedTotalReviews: json["not_approved_total_reviews"], + sku: json["sku"], + isRx: json["is_rx"], + prescriptionRequired: json["prescription_required"], + rxMessage: json["rx_message"] == null ? null : json["rx_message"], + rxMessagen: json["rx_messagen"] == null ? null : json["rx_messagen"], + manufacturerPartNumber: json["manufacturer_part_number"], + gtin: json["gtin"], + isGiftCard: json["is_gift_card"], + requireOtherProducts: json["require_other_products"], + automaticallyAddRequiredProducts: json["automatically_add_required_products"], + isDownload: json["is_download"], + unlimitedDownloads: json["unlimited_downloads"], + maxNumberOfDownloads: json["max_number_of_downloads"], + downloadExpirationDays: json["download_expiration_days"], + hasSampleDownload: json["has_sample_download"], + hasUserAgreement: json["has_user_agreement"], + isRecurring: json["is_recurring"], + recurringCycleLength: json["recurring_cycle_length"], + recurringTotalCycles: json["recurring_total_cycles"], + isRental: json["is_rental"], + rentalPriceLength: json["rental_price_length"], + isShipEnabled: json["is_ship_enabled"], + isFreeShipping: json["is_free_shipping"], + shipSeparately: json["ship_separately"], + additionalShippingCharge: json["additional_shipping_charge"], + isTaxExempt: json["is_tax_exempt"], + isTelecommunicationsOrBroadcastingOrElectronicServices: json["is_telecommunications_or_broadcasting_or_electronic_services"], + useMultipleWarehouses: json["use_multiple_warehouses"], + manageInventoryMethodId: json["manage_inventory_method_id"], + stockQuantity: json["stock_quantity"], + stockAvailability: json["stock_availability"], + stockAvailabilityn: json["stock_availabilityn"], + displayStockAvailability: json["display_stock_availability"], + displayStockQuantity: json["display_stock_quantity"], + minStockQuantity: json["min_stock_quantity"], + notifyAdminForQuantityBelow: json["notify_admin_for_quantity_below"], + allowBackInStockSubscriptions: json["allow_back_in_stock_subscriptions"], + orderMinimumQuantity: json["order_minimum_quantity"], + orderMaximumQuantity: json["order_maximum_quantity"], + allowedQuantities: json["allowed_quantities"], + allowAddingOnlyExistingAttributeCombinations: json["allow_adding_only_existing_attribute_combinations"], + disableBuyButton: json["disable_buy_button"], + disableWishlistButton: json["disable_wishlist_button"], + availableForPreOrder: json["available_for_pre_order"], + preOrderAvailabilityStartDateTimeUtc: json["pre_order_availability_start_date_time_utc"], + callForPrice: json["call_for_price"], + price: json["price"].toDouble(), + oldPrice: json["old_price"], + productCost: json["product_cost"].toDouble(), + specialPrice: json["special_price"], + specialPriceStartDateTimeUtc: json["special_price_start_date_time_utc"], + specialPriceEndDateTimeUtc: json["special_price_end_date_time_utc"], + customerEntersPrice: json["customer_enters_price"], + minimumCustomerEnteredPrice: json["minimum_customer_entered_price"], + maximumCustomerEnteredPrice: json["maximum_customer_entered_price"], + basepriceEnabled: json["baseprice_enabled"], + basepriceAmount: json["baseprice_amount"], + basepriceBaseAmount: json["baseprice_base_amount"], + hasTierPrices: json["has_tier_prices"], + hasDiscountsApplied: json["has_discounts_applied"], + discountName: json["discount_name"] == null ? null : json["discount_name"], + discountNamen: json["discount_namen"] == null ? null : json["discount_namen"], + discountDescription: json["discount_description"] == null ? null : json["discount_description"], + discountDescriptionn: json["discount_Descriptionn"] == null ? null : json["discount_Descriptionn"], + discountPercentage: json["discount_percentage"] == null ? null : json["discount_percentage"], + currency: json["currency"], + currencyn: json["currencyn"], + weight: json["weight"].toDouble(), + length: json["length"], + width: json["width"], + height: json["height"], + availableStartDateTimeUtc: json["available_start_date_time_utc"], + availableEndDateTimeUtc: json["available_end_date_time_utc"], + displayOrder: json["display_order"], + published: json["published"], + deleted: json["deleted"], + createdOnUtc: DateTime.parse(json["created_on_utc"]), + updatedOnUtc: DateTime.parse(json["updated_on_utc"]), + productType: json["product_type"], + parentGroupedProductId: json["parent_grouped_product_id"], + roleIds: List.from(json["role_ids"].map((x) => x)), + discountIds: List.from(json["discount_ids"].map((x) => x)), + storeIds: List.from(json["store_ids"].map((x) => x)), + manufacturerIds: List.from(json["manufacturer_ids"].map((x) => x)), + reviews: List.from(json["reviews"].map((x) => Review.fromJson(x))), + images: List.from(json["images"].map((x) => Image.fromJson(x))), + attributes: List.from(json["attributes"].map((x) => x)), + specifications: List.from(json["specifications"].map((x) => Specification.fromJson(x))), + associatedProductIds: List.from(json["associated_product_ids"].map((x) => x)), + tags: List.from(json["tags"].map((x) => x)), + vendorId: json["vendor_id"], + seName: json["se_name"], + ); Map toJson() => { - "id": id, - "visible_individually": visibleIndividually, - "name": name, - "namen": namen, - "localized_names": List.from(localizedNames.map((x) => x.toJson())), - "short_description": shortDescription == null ? null : shortDescription, - "short_descriptionn": shortDescriptionn == null ? null : shortDescriptionn, - "full_description": fullDescription, - "full_descriptionn": fullDescriptionn, - "markas_new": markasNew, - "show_on_home_page": showOnHomePage, - "meta_keywords": metaKeywords == null ? null : metaKeywords, - "meta_description": metaDescription == null ? null : metaDescription, - "meta_title": metaTitle == null ? null : metaTitle, - "allow_customer_reviews": allowCustomerReviews, - "approved_rating_sum": approvedRatingSum, - "not_approved_rating_sum": notApprovedRatingSum, - "approved_total_reviews": approvedTotalReviews, - "not_approved_total_reviews": notApprovedTotalReviews, - "sku": sku, - "is_rx": isRx, - "prescription_required": prescriptionRequired, - "rx_message": rxMessage == null ? null : rxMessage, - "rx_messagen": rxMessagen == null ? null : rxMessagen, - "manufacturer_part_number": manufacturerPartNumber, - "gtin": gtin, - "is_gift_card": isGiftCard, - "require_other_products": requireOtherProducts, - "automatically_add_required_products": automaticallyAddRequiredProducts, - "is_download": isDownload, - "unlimited_downloads": unlimitedDownloads, - "max_number_of_downloads": maxNumberOfDownloads, - "download_expiration_days": downloadExpirationDays, - "has_sample_download": hasSampleDownload, - "has_user_agreement": hasUserAgreement, - "is_recurring": isRecurring, - "recurring_cycle_length": recurringCycleLength, - "recurring_total_cycles": recurringTotalCycles, - "is_rental": isRental, - "rental_price_length": rentalPriceLength, - "is_ship_enabled": isShipEnabled, - "is_free_shipping": isFreeShipping, - "ship_separately": shipSeparately, - "additional_shipping_charge": additionalShippingCharge, - "is_tax_exempt": isTaxExempt, - "is_telecommunications_or_broadcasting_or_electronic_services": isTelecommunicationsOrBroadcastingOrElectronicServices, - "use_multiple_warehouses": useMultipleWarehouses, - "manage_inventory_method_id": manageInventoryMethodId, - "stock_quantity": stockQuantity, - "stock_availability": stockAvailability, - "stock_availabilityn": stockAvailabilityn, - "display_stock_availability": displayStockAvailability, - "display_stock_quantity": displayStockQuantity, - "min_stock_quantity": minStockQuantity, - "notify_admin_for_quantity_below": notifyAdminForQuantityBelow, - "allow_back_in_stock_subscriptions": allowBackInStockSubscriptions, - "order_minimum_quantity": orderMinimumQuantity, - "order_maximum_quantity": orderMaximumQuantity, - "allowed_quantities": allowedQuantities, - "allow_adding_only_existing_attribute_combinations": allowAddingOnlyExistingAttributeCombinations, - "disable_buy_button": disableBuyButton, - "disable_wishlist_button": disableWishlistButton, - "available_for_pre_order": availableForPreOrder, - "pre_order_availability_start_date_time_utc": preOrderAvailabilityStartDateTimeUtc, - "call_for_price": callForPrice, - "price": price, - "old_price": oldPrice, - "product_cost": productCost, - "special_price": specialPrice, - "special_price_start_date_time_utc": specialPriceStartDateTimeUtc, - "special_price_end_date_time_utc": specialPriceEndDateTimeUtc, - "customer_enters_price": customerEntersPrice, - "minimum_customer_entered_price": minimumCustomerEnteredPrice, - "maximum_customer_entered_price": maximumCustomerEnteredPrice, - "baseprice_enabled": basepriceEnabled, - "baseprice_amount": basepriceAmount, - "baseprice_base_amount": basepriceBaseAmount, - "has_tier_prices": hasTierPrices, - "has_discounts_applied": hasDiscountsApplied, - "discount_name": discountName == null ? null : discountName, - "discount_namen": discountNamen == null ? null : discountNamen, - "discount_description": discountDescription == null ? null : discountDescription, - "discount_Descriptionn": discountDescriptionn == null ? null : discountDescriptionn, - "discount_percentage": discountPercentage == null ? null : discountPercentage, - "currency": currency, - "currencyn": currencyn, - "weight": weight, - "length": length, - "width": width, - "height": height, - "available_start_date_time_utc": availableStartDateTimeUtc, - "available_end_date_time_utc": availableEndDateTimeUtc, - "display_order": displayOrder, - "published": published, - "deleted": deleted, - "created_on_utc": createdOnUtc.toIso8601String(), - "updated_on_utc": updatedOnUtc.toIso8601String(), - "product_type": productType, - "parent_grouped_product_id": parentGroupedProductId, - "role_ids": List.from(roleIds.map((x) => x)), - "discount_ids": List.from(discountIds.map((x) => x)), - "store_ids": List.from(storeIds.map((x) => x)), - "manufacturer_ids": List.from(manufacturerIds.map((x) => x)), - "reviews": List.from(reviews.map((x) => x.toJson())), - "images": List.from(images.map((x) => x.toJson())), - "attributes": List.from(attributes.map((x) => x)), - "specifications": List.from(specifications.map((x) => x.toJson())), - "associated_product_ids": List.from(associatedProductIds.map((x) => x)), - "tags": List.from(tags.map((x) => x)), - "vendor_id": vendorId, - "se_name": seName, - }; + "id": id, + "visible_individually": visibleIndividually, + "name": name, + "namen": namen, + "localized_names": List.from(localizedNames!.map((x) => x.toJson())), + "short_description": shortDescription == null ? null : shortDescription, + "short_descriptionn": shortDescriptionn == null ? null : shortDescriptionn, + "full_description": fullDescription, + "full_descriptionn": fullDescriptionn, + "markas_new": markasNew, + "show_on_home_page": showOnHomePage, + "meta_keywords": metaKeywords == null ? null : metaKeywords, + "meta_description": metaDescription == null ? null : metaDescription, + "meta_title": metaTitle == null ? null : metaTitle, + "allow_customer_reviews": allowCustomerReviews, + "approved_rating_sum": approvedRatingSum, + "not_approved_rating_sum": notApprovedRatingSum, + "approved_total_reviews": approvedTotalReviews, + "not_approved_total_reviews": notApprovedTotalReviews, + "sku": sku, + "is_rx": isRx, + "prescription_required": prescriptionRequired, + "rx_message": rxMessage == null ? null : rxMessage, + "rx_messagen": rxMessagen == null ? null : rxMessagen, + "manufacturer_part_number": manufacturerPartNumber, + "gtin": gtin, + "is_gift_card": isGiftCard, + "require_other_products": requireOtherProducts, + "automatically_add_required_products": automaticallyAddRequiredProducts, + "is_download": isDownload, + "unlimited_downloads": unlimitedDownloads, + "max_number_of_downloads": maxNumberOfDownloads, + "download_expiration_days": downloadExpirationDays, + "has_sample_download": hasSampleDownload, + "has_user_agreement": hasUserAgreement, + "is_recurring": isRecurring, + "recurring_cycle_length": recurringCycleLength, + "recurring_total_cycles": recurringTotalCycles, + "is_rental": isRental, + "rental_price_length": rentalPriceLength, + "is_ship_enabled": isShipEnabled, + "is_free_shipping": isFreeShipping, + "ship_separately": shipSeparately, + "additional_shipping_charge": additionalShippingCharge, + "is_tax_exempt": isTaxExempt, + "is_telecommunications_or_broadcasting_or_electronic_services": isTelecommunicationsOrBroadcastingOrElectronicServices, + "use_multiple_warehouses": useMultipleWarehouses, + "manage_inventory_method_id": manageInventoryMethodId, + "stock_quantity": stockQuantity, + "stock_availability": stockAvailability, + "stock_availabilityn": stockAvailabilityn, + "display_stock_availability": displayStockAvailability, + "display_stock_quantity": displayStockQuantity, + "min_stock_quantity": minStockQuantity, + "notify_admin_for_quantity_below": notifyAdminForQuantityBelow, + "allow_back_in_stock_subscriptions": allowBackInStockSubscriptions, + "order_minimum_quantity": orderMinimumQuantity, + "order_maximum_quantity": orderMaximumQuantity, + "allowed_quantities": allowedQuantities, + "allow_adding_only_existing_attribute_combinations": allowAddingOnlyExistingAttributeCombinations, + "disable_buy_button": disableBuyButton, + "disable_wishlist_button": disableWishlistButton, + "available_for_pre_order": availableForPreOrder, + "pre_order_availability_start_date_time_utc": preOrderAvailabilityStartDateTimeUtc, + "call_for_price": callForPrice, + "price": price, + "old_price": oldPrice, + "product_cost": productCost, + "special_price": specialPrice, + "special_price_start_date_time_utc": specialPriceStartDateTimeUtc, + "special_price_end_date_time_utc": specialPriceEndDateTimeUtc, + "customer_enters_price": customerEntersPrice, + "minimum_customer_entered_price": minimumCustomerEnteredPrice, + "maximum_customer_entered_price": maximumCustomerEnteredPrice, + "baseprice_enabled": basepriceEnabled, + "baseprice_amount": basepriceAmount, + "baseprice_base_amount": basepriceBaseAmount, + "has_tier_prices": hasTierPrices, + "has_discounts_applied": hasDiscountsApplied, + "discount_name": discountName == null ? null : discountName, + "discount_namen": discountNamen == null ? null : discountNamen, + "discount_description": discountDescription == null ? null : discountDescription, + "discount_Descriptionn": discountDescriptionn == null ? null : discountDescriptionn, + "discount_percentage": discountPercentage == null ? null : discountPercentage, + "currency": currency, + "currencyn": currencyn, + "weight": weight, + "length": length, + "width": width, + "height": height, + "available_start_date_time_utc": availableStartDateTimeUtc, + "available_end_date_time_utc": availableEndDateTimeUtc, + "display_order": displayOrder, + "published": published, + "deleted": deleted, + "created_on_utc": createdOnUtc!.toIso8601String(), + "updated_on_utc": updatedOnUtc!.toIso8601String(), + "product_type": productType, + "parent_grouped_product_id": parentGroupedProductId, + "role_ids": List.from(roleIds!.map((x) => x)), + "discount_ids": List.from(discountIds!.map((x) => x)), + "store_ids": List.from(storeIds!.map((x) => x)), + "manufacturer_ids": List.from(manufacturerIds!.map((x) => x)), + "reviews": List.from(reviews!.map((x) => x.toJson())), + "images": List.from(images!.map((x) => x.toJson())), + "attributes": List.from(attributes!.map((x) => x)), + "specifications": List.from(specifications!.map((x) => x.toJson())), + "associated_product_ids": List.from(associatedProductIds!.map((x) => x)), + "tags": List.from(tags!.map((x) => x)), + "vendor_id": vendorId, + "se_name": seName, + }; } class Image { @@ -493,27 +493,27 @@ class Image { this.attachment, }); - int id; - int position; - String src; - String thumb; - String attachment; + int? id; + int? position; + String? src; + String? thumb; + String? attachment; factory Image.fromJson(Map json) => Image( - id: json["id"], - position: json["position"], - src: json["src"], - thumb: json["thumb"], - attachment: json["attachment"], - ); + id: json["id"], + position: json["position"], + src: json["src"], + thumb: json["thumb"], + attachment: json["attachment"], + ); Map toJson() => { - "id": id, - "position": position, - "src": src, - "thumb": thumb, - "attachment": attachment, - }; + "id": id, + "position": position, + "src": src, + "thumb": thumb, + "attachment": attachment, + }; } class LocalizedName { @@ -522,18 +522,18 @@ class LocalizedName { this.localizedName, }); - int languageId; - String localizedName; + int? languageId; + String? localizedName; factory LocalizedName.fromJson(Map json) => LocalizedName( - languageId: json["language_id"], - localizedName: json["localized_name"], - ); + languageId: json["language_id"], + localizedName: json["localized_name"], + ); Map toJson() => { - "language_id": languageId, - "localized_name": localizedName, - }; + "language_id": languageId, + "localized_name": localizedName, + }; } class Review { @@ -556,60 +556,60 @@ class Review { this.product, }); - int id; - int position; - int reviewId; - int customerId; - int productId; - int storeId; - bool isApproved; - String title; - String reviewText; + int? id; + int? position; + int? reviewId; + int? customerId; + int? productId; + int? storeId; + bool? isApproved; + String? title; + String? reviewText; dynamic replyText; - int rating; - int helpfulYesTotal; - int helpfulNoTotal; - DateTime createdOnUtc; - Customer customer; + int? rating; + int? helpfulYesTotal; + int? helpfulNoTotal; + DateTime? createdOnUtc; + Customer? customer; dynamic product; factory Review.fromJson(Map json) => Review( - id: json["id"], - position: json["position"], - reviewId: json["review_id"], - customerId: json["customer_id"], - productId: json["product_id"], - storeId: json["store_id"], - isApproved: json["is_approved"], - title: json["title"], - reviewText: json["review_text"], - replyText: json["reply_text"], - rating: json["rating"], - helpfulYesTotal: json["helpful_yes_total"], - helpfulNoTotal: json["helpful_no_total"], - createdOnUtc: DateTime.parse(json["created_on_utc"]), - customer: Customer.fromJson(json["customer"]), - product: json["product"], - ); + id: json["id"], + position: json["position"], + reviewId: json["review_id"], + customerId: json["customer_id"], + productId: json["product_id"], + storeId: json["store_id"], + isApproved: json["is_approved"], + title: json["title"], + reviewText: json["review_text"], + replyText: json["reply_text"], + rating: json["rating"], + helpfulYesTotal: json["helpful_yes_total"], + helpfulNoTotal: json["helpful_no_total"], + createdOnUtc: DateTime.parse(json["created_on_utc"]), + customer: Customer.fromJson(json["customer"]), + product: json["product"], + ); Map toJson() => { - "id": id, - "position": position, - "review_id": reviewId, - "customer_id": customerId, - "product_id": productId, - "store_id": storeId, - "is_approved": isApproved, - "title": title, - "review_text": reviewText, - "reply_text": replyText, - "rating": rating, - "helpful_yes_total": helpfulYesTotal, - "helpful_no_total": helpfulNoTotal, - "created_on_utc": createdOnUtc.toIso8601String(), - "customer": customer.toJson(), - "product": product, - }; + "id": id, + "position": position, + "review_id": reviewId, + "customer_id": customerId, + "product_id": productId, + "store_id": storeId, + "is_approved": isApproved, + "title": title, + "review_text": reviewText, + "reply_text": replyText, + "rating": rating, + "helpful_yes_total": helpfulYesTotal, + "helpful_no_total": helpfulNoTotal, + "created_on_utc": createdOnUtc!.toIso8601String(), + "customer": customer!.toJson(), + "product": product, + }; } class Customer { @@ -649,19 +649,19 @@ class Customer { dynamic fileNumber; dynamic iqamaNumber; - int isOutSa; - int patientType; + int? isOutSa; + int? patientType; dynamic gender; - DateTime birthDate; + DateTime? birthDate; dynamic phone; dynamic countryCode; dynamic yahalaAccountno; dynamic billingAddress; dynamic shippingAddress; - List addresses; - String id; - Username username; - Email email; + List? addresses; + String? id; + Username? username; + Email? email; dynamic firstName; dynamic lastName; dynamic languageId; @@ -677,90 +677,84 @@ class Customer { dynamic lastLoginDateUtc; dynamic lastActivityDateUtc; dynamic registeredInStoreId; - List roleIds; + List? roleIds; factory Customer.fromJson(Map json) => Customer( - fileNumber: json["file_number"], - iqamaNumber: json["iqama_number"], - isOutSa: json["is_out_sa"], - patientType: json["patient_type"], - gender: json["gender"], - birthDate: DateTime.parse(json["birth_date"]), - phone: json["phone"], - countryCode: json["country_code"], - yahalaAccountno: json["yahala_accountno"], - billingAddress: json["billing_address"], - shippingAddress: json["shipping_address"], - addresses: List.from(json["addresses"].map((x) => x)), - id: json["id"], - username: usernameValues.map[json["username"]], - email: emailValues.map[json["email"]], - firstName: json["first_name"], - lastName: json["last_name"], - languageId: json["language_id"], - adminComment: json["admin_comment"], - isTaxExempt: json["is_tax_exempt"], - hasShoppingCartItems: json["has_shopping_cart_items"], - active: json["active"], - deleted: json["deleted"], - isSystemAccount: json["is_system_account"], - systemName: json["system_name"], - lastIpAddress: json["last_ip_address"], - createdOnUtc: json["created_on_utc"], - lastLoginDateUtc: json["last_login_date_utc"], - lastActivityDateUtc: json["last_activity_date_utc"], - registeredInStoreId: json["registered_in_store_id"], - roleIds: List.from(json["role_ids"].map((x) => x)), - ); + fileNumber: json["file_number"], + iqamaNumber: json["iqama_number"], + isOutSa: json["is_out_sa"], + patientType: json["patient_type"], + gender: json["gender"], + birthDate: DateTime.parse(json["birth_date"]), + phone: json["phone"], + countryCode: json["country_code"], + yahalaAccountno: json["yahala_accountno"], + billingAddress: json["billing_address"], + shippingAddress: json["shipping_address"], + addresses: List.from(json["addresses"].map((x) => x)), + id: json["id"], + username: usernameValues.map![json["username"]], + email: emailValues.map![json["email"]], + firstName: json["first_name"], + lastName: json["last_name"], + languageId: json["language_id"], + adminComment: json["admin_comment"], + isTaxExempt: json["is_tax_exempt"], + hasShoppingCartItems: json["has_shopping_cart_items"], + active: json["active"], + deleted: json["deleted"], + isSystemAccount: json["is_system_account"], + systemName: json["system_name"], + lastIpAddress: json["last_ip_address"], + createdOnUtc: json["created_on_utc"], + lastLoginDateUtc: json["last_login_date_utc"], + lastActivityDateUtc: json["last_activity_date_utc"], + registeredInStoreId: json["registered_in_store_id"], + roleIds: List.from(json["role_ids"].map((x) => x)), + ); Map toJson() => { - "file_number": fileNumber, - "iqama_number": iqamaNumber, - "is_out_sa": isOutSa, - "patient_type": patientType, - "gender": gender, - "birth_date": birthDate.toIso8601String(), - "phone": phone, - "country_code": countryCode, - "yahala_accountno": yahalaAccountno, - "billing_address": billingAddress, - "shipping_address": shippingAddress, - "addresses": List.from(addresses.map((x) => x)), - "id": id, - "username": usernameValues.reverse[username], - "email": emailValues.reverse[email], - "first_name": firstName, - "last_name": lastName, - "language_id": languageId, - "admin_comment": adminComment, - "is_tax_exempt": isTaxExempt, - "has_shopping_cart_items": hasShoppingCartItems, - "active": active, - "deleted": deleted, - "is_system_account": isSystemAccount, - "system_name": systemName, - "last_ip_address": lastIpAddress, - "created_on_utc": createdOnUtc, - "last_login_date_utc": lastLoginDateUtc, - "last_activity_date_utc": lastActivityDateUtc, - "registered_in_store_id": registeredInStoreId, - "role_ids": List.from(roleIds.map((x) => x)), - }; + "file_number": fileNumber, + "iqama_number": iqamaNumber, + "is_out_sa": isOutSa, + "patient_type": patientType, + "gender": gender, + "birth_date": birthDate!.toIso8601String(), + "phone": phone, + "country_code": countryCode, + "yahala_accountno": yahalaAccountno, + "billing_address": billingAddress, + "shipping_address": shippingAddress, + "addresses": List.from(addresses!.map((x) => x)), + "id": id, + "username": usernameValues.reverse[username], + "email": emailValues.reverse[email], + "first_name": firstName, + "last_name": lastName, + "language_id": languageId, + "admin_comment": adminComment, + "is_tax_exempt": isTaxExempt, + "has_shopping_cart_items": hasShoppingCartItems, + "active": active, + "deleted": deleted, + "is_system_account": isSystemAccount, + "system_name": systemName, + "last_ip_address": lastIpAddress, + "created_on_utc": createdOnUtc, + "last_login_date_utc": lastLoginDateUtc, + "last_activity_date_utc": lastActivityDateUtc, + "registered_in_store_id": registeredInStoreId, + "role_ids": List.from(roleIds!.map((x) => x)), + }; } enum Email { MEMO17299_GMAIL_COM, STEVE_GATES_NOP_COMMERCE_COM } -final emailValues = EnumValues({ - "Memo17299@gmail.com": Email.MEMO17299_GMAIL_COM, - "steve_gates@nopCommerce.com": Email.STEVE_GATES_NOP_COMMERCE_COM -}); +final emailValues = EnumValues({"Memo17299@gmail.com": Email.MEMO17299_GMAIL_COM, "steve_gates@nopCommerce.com": Email.STEVE_GATES_NOP_COMMERCE_COM}); enum Username { AMAL_26, STEVE_GATES_NOP_COMMERCE_COM } -final usernameValues = EnumValues({ - "amal_26": Username.AMAL_26, - "steve_gates@nopCommerce.com": Username.STEVE_GATES_NOP_COMMERCE_COM -}); +final usernameValues = EnumValues({"amal_26": Username.AMAL_26, "steve_gates@nopCommerce.com": Username.STEVE_GATES_NOP_COMMERCE_COM}); class Specification { Specification({ @@ -772,30 +766,30 @@ class Specification { this.nameN, }); - int id; - int displayOrder; - String defaultValue; - String defaultValuen; - Name name; - NameN nameN; + int? id; + int? displayOrder; + String? defaultValue; + String? defaultValuen; + Name? name; + NameN? nameN; factory Specification.fromJson(Map json) => Specification( - id: json["id"], - displayOrder: json["display_order"], - defaultValue: json["default_value"], - defaultValuen: json["default_valuen"], - name: nameValues.map[json["name"]], - nameN: nameNValues.map[json["nameN"]], - ); + id: json["id"], + displayOrder: json["display_order"], + defaultValue: json["default_value"], + defaultValuen: json["default_valuen"], + name: nameValues.map![json["name"]], + nameN: nameNValues.map![json["nameN"]], + ); Map toJson() => { - "id": id, - "display_order": displayOrder, - "default_value": defaultValue, - "default_valuen": defaultValuen, - "name": nameValues.reverse[name], - "nameN": nameNValues.reverse[nameN], - }; + "id": id, + "display_order": displayOrder, + "default_value": defaultValue, + "default_valuen": defaultValuen, + "name": nameValues.reverse[name], + "nameN": nameNValues.reverse[nameN], + }; } enum Name { PRIMARY_UNIT_OF_MEASURE, BRAND, MANUFACTURER_COUNTRY_NAME, STORAGE, COMPOSITION, SPF } @@ -811,25 +805,19 @@ final nameValues = EnumValues({ enum NameN { EMPTY, NAME_N, PURPLE, FLUFFY, TENTACLED, SPF } -final nameNValues = EnumValues({ - "وحدة القياس الأولية": NameN.EMPTY, - "تخزين": NameN.FLUFFY, - "علامة تجارية": NameN.NAME_N, - "اسم البلد المصنع": NameN.PURPLE, - "SPF": NameN.SPF, - "المكونات": NameN.TENTACLED -}); +final nameNValues = + EnumValues({"وحدة القياس الأولية": NameN.EMPTY, "تخزين": NameN.FLUFFY, "علامة تجارية": NameN.NAME_N, "اسم البلد المصنع": NameN.PURPLE, "SPF": NameN.SPF, "المكونات": NameN.TENTACLED}); class EnumValues { - Map map; - Map reverseMap; + Map? map; + Map? reverseMap; EnumValues(this.map); Map get reverse { if (reverseMap == null) { - reverseMap = map.map((k, v) => new MapEntry(v, k)); + reverseMap = map!.map((k, v) => new MapEntry(v, k)); } - return reverseMap; + return reverseMap!; } } diff --git a/lib/models/pharmacy/reviewModel.dart b/lib/models/pharmacy/reviewModel.dart index da30212c..dacf6c6f 100644 --- a/lib/models/pharmacy/reviewModel.dart +++ b/lib/models/pharmacy/reviewModel.dart @@ -123,117 +123,117 @@ class Product { this.seName, }); - String id; - bool visibleIndividually; - String name; - String namen; - List localizedNames; - String shortDescription; - String shortDescriptionn; - String fullDescription; - String fullDescriptionn; - bool markasNew; - bool showOnHomePage; - String metaKeywords; - String metaDescription; - String metaTitle; - bool allowCustomerReviews; + String? id; + bool? visibleIndividually; + String? name; + String? namen; + List? localizedNames; + String? shortDescription; + String? shortDescriptionn; + String? fullDescription; + String? fullDescriptionn; + bool? markasNew; + bool? showOnHomePage; + String? metaKeywords; + String? metaDescription; + String? metaTitle; + bool? allowCustomerReviews; dynamic approvedRatingSum; dynamic notApprovedRatingSum; dynamic approvedTotalReviews; dynamic notApprovedTotalReviews; - String sku; - bool isRx; - bool prescriptionRequired; + String? sku; + bool? isRx; + bool? prescriptionRequired; dynamic rxMessage; dynamic rxMessagen; dynamic manufacturerPartNumber; dynamic gtin; - bool isGiftCard; - bool requireOtherProducts; - bool automaticallyAddRequiredProducts; - bool isDownload; - bool unlimitedDownloads; + bool? isGiftCard; + bool? requireOtherProducts; + bool? automaticallyAddRequiredProducts; + bool? isDownload; + bool? unlimitedDownloads; dynamic maxNumberOfDownloads; dynamic downloadExpirationDays; - bool hasSampleDownload; - bool hasUserAgreement; - bool isRecurring; + bool? hasSampleDownload; + bool? hasUserAgreement; + bool? isRecurring; dynamic recurringCycleLength; dynamic recurringTotalCycles; - bool isRental; + bool? isRental; dynamic rentalPriceLength; - bool isShipEnabled; - bool isFreeShipping; - bool shipSeparately; + bool? isShipEnabled; + bool? isFreeShipping; + bool? shipSeparately; dynamic additionalShippingCharge; - bool isTaxExempt; - bool isTelecommunicationsOrBroadcastingOrElectronicServices; - bool useMultipleWarehouses; + bool? isTaxExempt; + bool? isTelecommunicationsOrBroadcastingOrElectronicServices; + bool? useMultipleWarehouses; dynamic manageInventoryMethodId; dynamic stockQuantity; - String stockAvailability; - String stockAvailabilityn; - bool displayStockAvailability; - bool displayStockQuantity; + String? stockAvailability; + String? stockAvailabilityn; + bool? displayStockAvailability; + bool? displayStockQuantity; dynamic minStockQuantity; dynamic notifyAdminForQuantityBelow; - bool allowBackInStockSubscriptions; + bool? allowBackInStockSubscriptions; dynamic orderMinimumQuantity; dynamic orderMaximumQuantity; dynamic allowedQuantities; - bool allowAddingOnlyExistingAttributeCombinations; - bool disableBuyButton; - bool disableWishlistButton; - bool availableForPreOrder; + bool? allowAddingOnlyExistingAttributeCombinations; + bool? disableBuyButton; + bool? disableWishlistButton; + bool? availableForPreOrder; dynamic preOrderAvailabilityStartDateTimeUtc; - bool callForPrice; + bool? callForPrice; dynamic price; dynamic oldPrice; dynamic productCost; dynamic specialPrice; dynamic specialPriceStartDateTimeUtc; dynamic specialPriceEndDateTimeUtc; - bool customerEntersPrice; + bool? customerEntersPrice; dynamic minimumCustomerEnteredPrice; dynamic maximumCustomerEnteredPrice; - bool basepriceEnabled; + bool? basepriceEnabled; dynamic basepriceAmount; dynamic basepriceBaseAmount; - bool hasTierPrices; - bool hasDiscountsApplied; + bool? hasTierPrices; + bool? hasDiscountsApplied; dynamic discountName; dynamic discountNamen; dynamic discountDescription; dynamic discountDescriptionn; dynamic discountPercentage; - String currency; - String currencyn; - double weight; + String? currency; + String? currencyn; + double? weight; dynamic length; dynamic width; dynamic height; dynamic availableStartDateTimeUtc; dynamic availableEndDateTimeUtc; dynamic displayOrder; - bool published; - bool deleted; - DateTime createdOnUtc; - DateTime updatedOnUtc; - String productType; + bool? published; + bool? deleted; + DateTime? createdOnUtc; + DateTime? updatedOnUtc; + String? productType; dynamic parentGroupedProductId; - List roleIds; - List discountIds; - List storeIds; - List manufacturerIds; - List reviews; - List images; - List attributes; - List specifications; - List associatedProductIds; - List tags; + List? roleIds; + List? discountIds; + List? storeIds; + List? manufacturerIds; + List? reviews; + List? images; + List? attributes; + List? specifications; + List? associatedProductIds; + List? tags; dynamic vendorId; - String seName; + String? seName; factory Product.fromJson(Map json) => Product( id: json["id"], @@ -354,7 +354,7 @@ class Product { "visible_individually": visibleIndividually, "name": name, "namen": namen, - "localized_names": List.from(localizedNames.map((x) => x.toJson())), + "localized_names": List.from(localizedNames!.map((x) => x.toJson())), "short_description": shortDescription, "short_descriptionn": shortDescriptionn, "full_description": fullDescription, @@ -445,20 +445,20 @@ class Product { "display_order": displayOrder, "published": published, "deleted": deleted, - "created_on_utc": createdOnUtc.toIso8601String(), - "updated_on_utc": updatedOnUtc.toIso8601String(), + "created_on_utc": createdOnUtc!.toIso8601String(), + "updated_on_utc": updatedOnUtc!.toIso8601String(), "product_type": productType, "parent_grouped_product_id": parentGroupedProductId, - "role_ids": List.from(roleIds.map((x) => x)), - "discount_ids": List.from(discountIds.map((x) => x)), - "store_ids": List.from(storeIds.map((x) => x)), - "manufacturer_ids": List.from(manufacturerIds.map((x) => x)), - "reviews": List.from(reviews.map((x) => x.toJson())), - "images": List.from(images.map((x) => x.toJson())), - "attributes": List.from(attributes.map((x) => x)), - "specifications": List.from(specifications.map((x) => x.toJson())), - "associated_product_ids": List.from(associatedProductIds.map((x) => x)), - "tags": List.from(tags.map((x) => x)), + "role_ids": List.from(roleIds!.map((x) => x)), + "discount_ids": List.from(discountIds!.map((x) => x)), + "store_ids": List.from(storeIds!.map((x) => x)), + "manufacturer_ids": List.from(manufacturerIds!.map((x) => x)), + "reviews": List.from(reviews!.map((x) => x.toJson())), + "images": List.from(images!.map((x) => x.toJson())), + "attributes": List.from(attributes!.map((x) => x)), + "specifications": List.from(specifications!.map((x) => x.toJson())), + "associated_product_ids": List.from(associatedProductIds!.map((x) => x)), + "tags": List.from(tags!.map((x) => x)), "vendor_id": vendorId, "se_name": seName, }; @@ -490,16 +490,16 @@ class Review { dynamic customerId; dynamic productId; dynamic storeId; - bool isApproved; - String title; - ReviewText reviewText; + bool? isApproved; + String? title; + ReviewText? reviewText; dynamic replyText; dynamic rating; dynamic helpfulYesTotal; dynamic helpfulNoTotal; - DateTime createdOnUtc; - Customer customer; - Product product; + DateTime? createdOnUtc; + Customer? customer; + Product? product; factory Review.fromJson(Map json) => Review( id: json["id"], @@ -510,7 +510,7 @@ class Review { storeId: json["store_id"], isApproved: json["is_approved"], title: json["title"], - reviewText: reviewTextValues.map[json["review_text"]], + reviewText: reviewTextValues.map![json["review_text"]], replyText: json["reply_text"], rating: json["rating"], helpfulYesTotal: json["helpful_yes_total"], @@ -534,9 +534,9 @@ class Review { "rating": rating, "helpful_yes_total": helpfulYesTotal, "helpful_no_total": helpfulNoTotal, - "created_on_utc": createdOnUtc.toIso8601String(), - "customer": customer.toJson(), - "product": product == null ? null : product.toJson(), + "created_on_utc": createdOnUtc!.toIso8601String(), + "customer": customer!.toJson(), + "product": product == null ? null : product!.toJson(), }; } @@ -551,9 +551,9 @@ class Image { dynamic id; dynamic position; - String src; - String thumb; - String attachment; + String? src; + String? thumb; + String? attachment; factory Image.fromJson(Map json) => Image( id: json["id"], @@ -579,7 +579,7 @@ class LocalizedName { }); dynamic languageId; - String localizedName; + String? localizedName; factory LocalizedName.fromJson(Map json) => LocalizedName( languageId: json["language_id"], @@ -604,10 +604,10 @@ class Specification { dynamic id; dynamic displayOrder; - String defaultValue; - String defaultValuen; - String name; - String nameN; + String? defaultValue; + String? defaultValuen; + String? name; + String? nameN; factory Specification.fromJson(Map json) => Specification( id: json["id"], @@ -668,16 +668,16 @@ class Customer { dynamic isOutSa; dynamic patientType; dynamic gender; - DateTime birthDate; + DateTime? birthDate; dynamic phone; dynamic countryCode; dynamic yahalaAccountno; dynamic billingAddress; dynamic shippingAddress; - List addresses; - String id; - Username username; - Email email; + List? addresses; + String? id; + Username? username; + Email? email; dynamic firstName; dynamic lastName; dynamic languageId; @@ -693,7 +693,7 @@ class Customer { dynamic lastLoginDateUtc; dynamic lastActivityDateUtc; dynamic registeredInStoreId; - List roleIds; + List? roleIds; factory Customer.fromJson(Map json) => Customer( fileNumber: json["file_number"], @@ -709,8 +709,8 @@ class Customer { shippingAddress: json["shipping_address"], addresses: List.from(json["addresses"].map((x) => x)), id: json["id"], - username: usernameValues.map[json["username"]], - email: emailValues.map[json["email"]], + username: usernameValues.map![json["username"]], + email: emailValues.map![json["email"]], firstName: json["first_name"], lastName: json["last_name"], languageId: json["language_id"], @@ -735,13 +735,13 @@ class Customer { "is_out_sa": isOutSa, "patient_type": patientType, "gender": gender, - "birth_date": birthDate.toIso8601String(), + "birth_date": birthDate!.toIso8601String(), "phone": phone, "country_code": countryCode, "yahala_accountno": yahalaAccountno, "billing_address": billingAddress, "shipping_address": shippingAddress, - "addresses": List.from(addresses.map((x) => x)), + "addresses": List.from(addresses!.map((x) => x)), "id": id, "username": usernameValues.reverse[username], "email": emailValues.reverse[email], @@ -760,7 +760,7 @@ class Customer { "last_login_date_utc": lastLoginDateUtc, "last_activity_date_utc": lastActivityDateUtc, "registered_in_store_id": registeredInStoreId, - "role_ids": List.from(roleIds.map((x) => x)), + "role_ids": List.from(roleIds!.map((x) => x)), }; } @@ -789,15 +789,15 @@ final reviewTextValues = EnumValues({ }); class EnumValues { - Map map; - Map reverseMap; + Map? map; + Map? reverseMap; EnumValues(this.map); Map get reverse { if (reverseMap == null) { - reverseMap = map.map((k, v) => new MapEntry(v, k)); + reverseMap = map!.map((k, v) => new MapEntry(v, k)); } - return reverseMap; + return reverseMap!; } } diff --git a/lib/models/pharmacy/specification.dart b/lib/models/pharmacy/specification.dart index 6ef69191..9fd50f01 100644 --- a/lib/models/pharmacy/specification.dart +++ b/lib/models/pharmacy/specification.dart @@ -13,14 +13,14 @@ class SpecificationModel { this.specification, }); - List specification; + List? specification; factory SpecificationModel.fromJson(Map json) => SpecificationModel( specification: List.from(json["specification"].map((x) => Specification.fromJson(x))), ); Map toJson() => { - "specification": List.from(specification.map((x) => x.toJson())), + "specification": List.from(specification!.map((x) => x.toJson())), }; } @@ -34,12 +34,12 @@ class Specification { this.nameN, }); - int id; - int displayOrder; - String defaultValue; - String defaultValuen; - String name; - String nameN; + int? id; + int? displayOrder; + String? defaultValue; + String? defaultValuen; + String? name; + String? nameN; factory Specification.fromJson(Map json) => Specification( id: json["id"], diff --git a/lib/models/pharmacy/topBrandsModel.dart b/lib/models/pharmacy/topBrandsModel.dart index 0cd833b7..57ac2fed 100644 --- a/lib/models/pharmacy/topBrandsModel.dart +++ b/lib/models/pharmacy/topBrandsModel.dart @@ -30,24 +30,24 @@ class TopBrand { this.image, }); - String id; - String name; - String namen; - List localizedNames; - String description; - int manufacturerTemplateId; - String metaKeywords; + String? id; + String? name; + String? namen; + List? localizedNames; + String? description; + int? manufacturerTemplateId; + String? metaKeywords; dynamic metaDescription; dynamic metaTitle; - int pageSize; - String pageSizeOptions; + int? pageSize; + String? pageSizeOptions; dynamic priceRanges; - bool published; - bool deleted; - int displayOrder; - DateTime createdOnUtc; - DateTime updatedOnUtc; - Image image; + bool? published; + bool? deleted; + int? displayOrder; + DateTime? createdOnUtc; + DateTime? updatedOnUtc; + Image? image; factory TopBrand.fromJson(Map json) => TopBrand( id: json["id"], @@ -74,7 +74,7 @@ class TopBrand { "id": id, "name": name, "namen": namen, - "localized_names": List.from(localizedNames.map((x) => x.toJson())), + "localized_names": List.from(localizedNames!.map((x) => x.toJson())), "description": description == null ? null : description, "manufacturer_template_id": manufacturerTemplateId, "meta_keywords": metaKeywords, @@ -86,9 +86,9 @@ class TopBrand { "published": published, "deleted": deleted, "display_order": displayOrder, - "created_on_utc": createdOnUtc.toIso8601String(), - "updated_on_utc": updatedOnUtc.toIso8601String(), - "image": image == null ? null : image.toJson(), + "created_on_utc": createdOnUtc!.toIso8601String(), + "updated_on_utc": updatedOnUtc!.toIso8601String(), + "image": image == null ? null : image!.toJson(), }; } @@ -99,7 +99,7 @@ class Image { this.attachment, }); - String src; + String? src; dynamic thumb; dynamic attachment; @@ -122,8 +122,8 @@ class LocalizedName { this.localizedName, }); - int languageId; - String localizedName; + int? languageId; + String? localizedName; factory LocalizedName.fromJson(Map json) => LocalizedName( languageId: json["language_id"], diff --git a/lib/models/rrt/RRTProcedureList.dart b/lib/models/rrt/RRTProcedureList.dart new file mode 100644 index 00000000..ff68b047 --- /dev/null +++ b/lib/models/rrt/RRTProcedureList.dart @@ -0,0 +1,50 @@ +class RRTProcedureList { + List? vidaProcedureList; + + RRTProcedureList({this.vidaProcedureList}); + + RRTProcedureList.fromJson(Map json) { + if (json['Vida_ProcedureList'] != null) { + vidaProcedureList = []; + json['Vida_ProcedureList'].forEach((v) { + vidaProcedureList!.add(new VidaProcedureList.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + if (this.vidaProcedureList != null) { + data['Vida_ProcedureList'] = this.vidaProcedureList!.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class VidaProcedureList { + num? patientShare; + num? patientShareWithTax; + num? patientTaxAmount; + String? procedureID; + String? procedureName; + + VidaProcedureList({this.patientShare, this.patientShareWithTax, this.patientTaxAmount, this.procedureID, this.procedureName}); + + VidaProcedureList.fromJson(Map json) { + patientShare = json['PatientShare']; + patientShareWithTax = json['PatientShareWithTax']; + patientTaxAmount = json['PatientTaxAmount']; + procedureID = json['ProcedureID']; + procedureName = json['ProcedureName']; + } + + Map toJson() { + final Map data = new Map(); + data['PatientShare'] = this.patientShare; + data['PatientShareWithTax'] = this.patientShareWithTax; + data['PatientTaxAmount'] = this.patientTaxAmount; + data['ProcedureID'] = this.procedureID; + data['ProcedureName'] = this.procedureName; + return data; + } +} diff --git a/lib/models/rrt/RRTRequestModel.dart b/lib/models/rrt/RRTRequestModel.dart new file mode 100644 index 00000000..dfb5b1b2 --- /dev/null +++ b/lib/models/rrt/RRTRequestModel.dart @@ -0,0 +1,75 @@ +class RRTRequestModel { + num? patientId; + int? patientOutSa; + bool? isOutPatient; + int? nearestProjectId; + num? longitude; + num? latitude; + String? additionalDetails; + String? nationality; + num? paymentAmount; + List? procedures; + + RRTRequestModel( + {this.patientId, + this.patientOutSa, + this.isOutPatient, + this.nearestProjectId, + this.longitude, + this.latitude, + this.additionalDetails, + this.nationality, + this.paymentAmount, + this.procedures}); + + RRTRequestModel.fromJson(Map json) { + patientId = json['patientId']; + patientOutSa = json['patientOutSa']; + isOutPatient = json['isOutPatient']; + nearestProjectId = json['nearestProjectId']; + longitude = json['longitude']; + latitude = json['latitude']; + additionalDetails = json['additionalDetails']; + nationality = json['nationality']; + paymentAmount = json['paymentAmount']; + if (json['procedures'] != null) { + procedures = []; + json['procedures'].forEach((v) { + procedures!.add(new Procedures.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + data['patientId'] = this.patientId; + data['patientOutSa'] = this.patientOutSa; + data['isOutPatient'] = this.isOutPatient; + data['nearestProjectId'] = this.nearestProjectId; + data['longitude'] = this.longitude; + data['latitude'] = this.latitude; + data['additionalDetails'] = this.additionalDetails; + data['nationality'] = this.nationality; + data['paymentAmount'] = this.paymentAmount; + if (this.procedures != null) { + data['procedures'] = this.procedures!.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class Procedures { + String? serviceID; + + Procedures({this.serviceID}); + + Procedures.fromJson(Map json) { + serviceID = json['ServiceID']; + } + + Map toJson() { + final Map data = new Map(); + data['ServiceID'] = this.serviceID; + return data; + } +} diff --git a/lib/models/rrt/service_price.dart b/lib/models/rrt/service_price.dart new file mode 100644 index 00000000..abb57be6 --- /dev/null +++ b/lib/models/rrt/service_price.dart @@ -0,0 +1,53 @@ +class ServicePrice { + String? currency; + dynamic maxPrice; + dynamic maxTotalPrice; + dynamic maxVAT; + dynamic minPrice; + dynamic minTotalPrice; + dynamic minVAT; + dynamic price; + dynamic totalPrice; + dynamic vat; + + ServicePrice({ + this.currency, + this.maxPrice, + this.maxTotalPrice, + this.maxVAT, + this.minPrice, + this.minTotalPrice, + this.minVAT, + this.price, + this.totalPrice, + this.vat}); + + ServicePrice.fromJson(dynamic json) { + currency = json["Currency"]; + maxPrice = json["MaxPrice"]; + maxTotalPrice = json["MaxTotalPrice"]; + maxVAT = json["MaxVAT"]; + minPrice = json["MinPrice"]; + minTotalPrice = json["MinTotalPrice"]; + minVAT = json["MinVAT"]; + price = json["Price"]; + totalPrice = json["TotalPrice"]; + vat = json["VAT"]; + } + + Map toJson() { + var map = {}; + map["Currency"] = currency; + map["MaxPrice"] = maxPrice; + map["MaxTotalPrice"] = maxTotalPrice; + map["MaxVAT"] = maxVAT; + map["MinPrice"] = minPrice; + map["MinTotalPrice"] = minTotalPrice; + map["MinVAT"] = minVAT; + map["Price"] = price; + map["TotalPrice"] = totalPrice; + map["VAT"] = vat; + return map; + } + +} \ No newline at end of file diff --git a/lib/models/slider_data.dart b/lib/models/slider_data.dart new file mode 100644 index 00000000..6d72fc4f --- /dev/null +++ b/lib/models/slider_data.dart @@ -0,0 +1,11 @@ +import 'package:flutter/material.dart'; + +class SliderData{ + String pateintId; + String pateintName; + String dof; + Color darkColor; + Color lightColor; + + SliderData(this.pateintId, this.pateintName, this.dof,this.darkColor,this.lightColor); +} \ No newline at end of file diff --git a/lib/models/tamara_request_model.dart b/lib/models/tamara_request_model.dart new file mode 100644 index 00000000..4fe24426 --- /dev/null +++ b/lib/models/tamara_request_model.dart @@ -0,0 +1,120 @@ +class TamaraRequestModel { + String? merchantReference; + String? merchantIdentifier; + String? clientRequestID; + num? amount; + String? currency; + String? language; + String? commandType; + String? signature; + String? customerEmail; + String? orderDescription; + bool? isInstallment; + num? projectID; + String? accessCode; + String? sHARequestPhase; + String? sHAResponsePhase; + String? customerName; + String? fileNumber; + bool? patientOutSA; + String? deviceToken; + String? longitude; + String? latitude; + String? appointmentNo; + var serviceID; + var liveServiceID; + String? doctorID; + var appointmentDate; + bool? isSchedule; + + TamaraRequestModel( + {this.merchantReference, + this.merchantIdentifier, + this.clientRequestID, + this.amount, + this.currency, + this.language, + this.commandType, + this.signature, + this.customerEmail, + this.orderDescription, + this.isInstallment, + this.projectID, + this.accessCode, + this.sHARequestPhase, + this.sHAResponsePhase, + this.customerName, + this.fileNumber, + this.patientOutSA, + this.deviceToken, + this.longitude, + this.latitude, + this.appointmentNo, + this.serviceID, + this.liveServiceID, + this.appointmentDate, + this.doctorID, + this.isSchedule}); + + TamaraRequestModel.fromJson(Map json) { + merchantReference = json['Merchant_Reference']; + merchantIdentifier = json['Merchant_Identifier']; + clientRequestID = json['ClientRequestID']; + amount = json['Amount']; + currency = json['Currency']; + language = json['Language']; + commandType = json['CommandType']; + signature = json['Signature']; + customerEmail = json['CustomerEmail']; + orderDescription = json['OrderDescription']; + isInstallment = json['IsInstallment']; + projectID = json['ProjectID']; + accessCode = json['Access_code']; + sHARequestPhase = json['SHA_RequestPhase']; + sHAResponsePhase = json['SHA_ResponsePhase']; + customerName = json['CustomerName']; + fileNumber = json['FileNumber']; + patientOutSA = json['PatientOutSA']; + deviceToken = json['DeviceToken']; + longitude = json['Longitude']; + latitude = json['Latitude']; + appointmentNo = json['AppointmentNo']; + serviceID = json['Service_ID']; + liveServiceID = json['Live_ServiceID']; + doctorID = json['DoctorID']; + appointmentDate = json['AppointmentDate']; + isSchedule = json['IsSchedule']; + } + + Map toJson() { + final Map data = new Map(); + data['Merchant_Reference'] = this.merchantReference; + data['Merchant_Identifier'] = this.merchantIdentifier; + data['ClientRequestID'] = this.clientRequestID; + data['Amount'] = this.amount; + data['Currency'] = this.currency; + data['Language'] = this.language; + data['CommandType'] = this.commandType; + data['Signature'] = this.signature; + data['CustomerEmail'] = this.customerEmail; + data['OrderDescription'] = this.orderDescription; + data['IsInstallment'] = this.isInstallment; + data['ProjectID'] = this.projectID; + data['Access_code'] = this.accessCode; + data['SHA_RequestPhase'] = this.sHARequestPhase; + data['SHA_ResponsePhase'] = this.sHAResponsePhase; + data['CustomerName'] = this.customerName; + data['FileNumber'] = this.fileNumber; + data['PatientOutSA'] = this.patientOutSA; + data['DeviceToken'] = this.deviceToken; + data['Longitude'] = this.longitude; + data['Latitude'] = this.latitude; + data['AppointmentNo'] = this.appointmentNo; + data['Service_ID'] = this.serviceID; + data['Live_ServiceID'] = this.liveServiceID; + data['DoctorID'] = this.doctorID; + data['AppointmentDate'] = this.appointmentDate; + data['IsSchedule'] = this.isSchedule; + return data; + } +} diff --git a/lib/models/vital_sign.dart b/lib/models/vital_sign.dart new file mode 100644 index 00000000..f9587d31 --- /dev/null +++ b/lib/models/vital_sign.dart @@ -0,0 +1,8 @@ +class VitalSign { + final String des; + final String lastVal; + final String unit; + final String icon; + + VitalSign(this.des, this.lastVal, this.unit, this.icon); +} diff --git a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/Dialog/confirm_cancel_order_dialog.dart b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/Dialog/confirm_cancel_order_dialog.dart index 549f90b8..4ea8c4ee 100644 --- a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/Dialog/confirm_cancel_order_dialog.dart +++ b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/Dialog/confirm_cancel_order_dialog.dart @@ -1,18 +1,14 @@ import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/cmc_view_model.dart'; -import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/home_health_care_view_model.dart'; import 'package:diplomaticquarterapp/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 ConfirmCancelOrderDialog extends StatefulWidget { - final CMCViewModel model; + final CMCViewModel model; final Function onTap; - - ConfirmCancelOrderDialog( - {Key key, this.model, this.onTap}); + ConfirmCancelOrderDialog({Key? key, required this.model, required this.onTap}); @override _ConfirmCancelOrderDialogState createState() => _ConfirmCancelOrderDialogState(); @@ -27,11 +23,13 @@ class _ConfirmCancelOrderDialogState extends State { @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, + contentPadding: EdgeInsets.fromLTRB(28.0, 2.0, 28.0, 0.0), + title: Text( + TranslationBase.of(context).confirm, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + letterSpacing: -0.46, ), ), children: [ @@ -39,13 +37,13 @@ class _ConfirmCancelOrderDialogState extends State { children: [ Divider(), Center( - child: Texts( - TranslationBase.of(context).cancelOrderMsg , - color: Colors.grey, + child: Text( + TranslationBase.of(context).cancelOrderMsg, + style: TextStyle(fontSize: 14, fontWeight: FontWeight.w500, letterSpacing: -0.46, color: Colors.grey[600]), ), ), SizedBox( - height: 5.0, + height: 12.0, ), Row( // mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -60,9 +58,14 @@ class _ConfirmCancelOrderDialogState extends State { padding: const EdgeInsets.all(8.0), child: Container( child: Center( - child: Texts( + child: Text( TranslationBase.of(context).cancel.toUpperCase(), - color: Colors.red, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w700, + letterSpacing: -0.46, + color: Colors.red, + ), ), ), ), @@ -77,28 +80,32 @@ class _ConfirmCancelOrderDialogState extends State { Expanded( flex: 1, child: InkWell( - onTap: () async{ + onTap: () async { widget.onTap(); Navigator.pop(context); }, child: Padding( padding: const EdgeInsets.all(8.0), child: Center( - child: Texts( - TranslationBase.of(context).ok, - fontWeight: FontWeight.w400, - )), + child: Text( + TranslationBase.of(context).ok.toUpperCase(), + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w700, + letterSpacing: -0.46, + ), + )), ), ), ), ], - ) + ), + SizedBox( + height: 5.0, + ), ], ) ], ); } } - - - diff --git a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/Dialog/confirm_dialog.dart b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/Dialog/confirm_dialog.dart new file mode 100644 index 00000000..94379af8 --- /dev/null +++ b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/Dialog/confirm_dialog.dart @@ -0,0 +1,109 @@ +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; +import 'package:flutter/material.dart'; + +Future showCMCConfirmDialog(BuildContext context, String requestId, {required Function onClick}) async { + return showDialog( + context: context, + barrierDismissible: false, // user must tap button! + builder: (BuildContext context) { + return Dialog( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + ConfirmDialog( + requestId, + onClick: onClick, + ), + ], + ), + ); + }, + ); +} + +class ConfirmDialog extends StatelessWidget { + String requestId; + Function onClick; + + ConfirmDialog(this.requestId, {required this.onClick}); + + @override + Widget build(BuildContext context) { + return Container( + width: double.infinity, + padding: EdgeInsets.all(20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Container( + width: 40, + height: 40, + margin: EdgeInsets.only(top: 20), + decoration: containerRadius(CustomColors.green, 200,), + child: Icon(Icons.done,color: Colors.white,), + ), + mFlex(1), + IconButton( + icon: Icon( + Icons.close, + ), + onPressed: () { + onClick(); + Navigator.pop(context); + }, + ), + ], + ), + mHeight(12), + Text( + TranslationBase.of(context).RRTRequestSuccess, + textAlign: TextAlign.start, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.bold, + letterSpacing: -0.46, + ), + ), + mHeight(20), + Text( + TranslationBase.of(context).reqId, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.bold, + color: Colors.grey[600], + letterSpacing: -0.46, + ), + ), + Text( + requestId ?? "", + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: Colors.black, + letterSpacing: -0.46, + ), + ), + mHeight(20), + Container( + width: MediaQuery.of(context).size.width * 0.9, + child: SecondaryButton( + label: TranslationBase.of(context).ok.toUpperCase(), + color: CustomColors.accentColor, + onTap: () async { + onClick(); + Navigator.pop(context); + }, + textColor: CustomColors.white), + ), + ], + ), + ); + } +} diff --git a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/cmc_location_page.dart b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/cmc_location_page.dart index 72aa40dc..d0dd1094 100644 --- a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/cmc_location_page.dart +++ b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/cmc_location_page.dart @@ -1,30 +1,41 @@ +import 'dart:io'; + 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/ImagesInfo.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/add_new_address_Request_Model.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/cmc_view_model.dart'; -import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/home_health_care_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/services/permission/permission_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/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/widgets/app_map/google_huawei_map.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:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:google_maps_flutter/google_maps_flutter.dart'; -import 'package:google_maps_place_picker/google_maps_place_picker.dart'; + +// import 'package:flutter_hms_gms_availability/flutter_hms_gms_availability.dart'; +import 'package:geocoding/geocoding.dart'; +import 'package:geolocator/geolocator.dart'; +import 'package:google_maps_flutter/google_maps_flutter.dart' as gmaps; +import 'package:google_maps_place_picker_mb/google_maps_place_picker.dart'; +import 'package:huawei_hmsavailability/huawei_hmsavailability.dart'; import 'package:provider/provider.dart'; class CMCLocationPage extends StatefulWidget { - final Function(PickResult) onPick; + final Function onPick; final double latitude; final double longitude; final dynamic model; - const CMCLocationPage( - {Key key, this.onPick, this.latitude, this.longitude, this.model}) - : super(key: key); + const CMCLocationPage({Key? key, required this.onPick, required this.latitude, required this.longitude, this.model}) : super(key: key); @override _CMCLocationPageState createState() => _CMCLocationPageState(); @@ -33,24 +44,133 @@ class CMCLocationPage extends StatefulWidget { class _CMCLocationPageState extends State { double latitude = 0; double longitude = 0; + bool showCurrentLocation = false; + late Function onPick; + bool isHuawei = false; + late Placemark selectedPlace; + late AppMap appMap; + static gmaps.CameraPosition _kGooglePlex = gmaps.CameraPosition( + target: gmaps.LatLng(37.42796133580664, -122.085749655962), + zoom: 14.4746, + ); + late gmaps.LatLng currentPostion; + AppSharedPreferences sharedPref = AppSharedPreferences(); + late HmsApiAvailability hmsApiAvailability; @override void initState() { + hmsApiAvailability = HmsApiAvailability(); + checkIsHuawei(); + + appMap = AppMap( + _kGooglePlex.toMap() as Map, + // changed by Aamir + onCameraMove: () { + _updatePosition(_kGooglePlex); + // changed by Aamir Huawei & Google Issue may Be + }, + onMapCreated: () { + currentPostion = gmaps.LatLng(widget.latitude, widget.longitude); + latitude = widget.latitude; + longitude = widget.longitude; + _getUserLocation(); + setState(() {}); + }, + onCameraIdle: () async { + List placemarks = await placemarkFromCoordinates(latitude, longitude); + selectedPlace = placemarks[0]; + print(selectedPlace); + }, + ); + + onPick = widget.onPick; latitude = widget.latitude; longitude = widget.longitude; + if (latitude == 0.0 && longitude == 0.0) { + showCurrentLocation = true; + } super.initState(); } + checkIsHuawei() async { + await hmsApiAvailability!.isHMSAvailable().then((value) { + isHuawei = value == 0 ? true : false; + }); + print(isHuawei); + setState(() {}); + } + @override Widget build(BuildContext context) { ProjectViewModel projectViewModel = Provider.of(context); + return BaseView( - onModelReady: (model) {}, - builder: (_, model, widget) => AppScaffold( - isShowDecPage: false, - isShowAppBar: true, - baseViewModel: model, - body: PlacePicker( + onModelReady: (model) {}, + builder: (_, model, widget) => AppScaffold( + isShowDecPage: false, + isShowAppBar: true, + baseViewModel: model, + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: CustomColors.appBackgroudGreyColor, + description: TranslationBase.of(context).infoCMC, + 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).addNewAddress, + body: isHuawei + ? Column( + children: [ + Expanded( + child: Stack( + alignment: Alignment.center, + children: [ + if (appMap != null) appMap, + Container( + margin: EdgeInsets.only(bottom: 50.0), + child: Icon( + Icons.place, + color: CustomColors.accentColor, + size: 50, + ), + ), + ], + ), + ), + Container( + padding: const EdgeInsets.only(left: 20, right: 20, top: 14, bottom: 14), + child: DefaultButton(TranslationBase.of(context).addNewAddress, () async { + AddNewAddressRequestModel addNewAddressRequestModel = new AddNewAddressRequestModel( + customer: Customer(addresses: [ + Addresses( + address1: selectedPlace.street, + address2: selectedPlace.street, + customerAttributes: "", + city: selectedPlace.administrativeArea, + createdOnUtc: "", + id: "0", + faxNumber: "", + phoneNumber: projectViewModel.user!.mobileNumber, + province: selectedPlace.administrativeArea, + countryId: 69, + latLong: latitude.toStringAsFixed(6) + "," + longitude.toStringAsFixed(6), + country: selectedPlace.country, + zipPostalCode: selectedPlace.postalCode, + email: projectViewModel.user!.emailAddress) + ]), + ); + await model.addAddressInfo(addNewAddressRequestModel: addNewAddressRequestModel); + if (model.state == ViewState.ErrorLocal) { + Utils.showErrorToast(model.error); + } else { + AppToast.showSuccessToast(message: "Address Added Successfully"); + } + Navigator.of(context).pop(addNewAddressRequestModel); + }), + ), + ], + ) + : PlacePicker( apiKey: GOOGLE_API_KEY, enableMyLocationButton: true, automaticallyImplyAppBarLeading: false, @@ -62,10 +182,9 @@ class _CMCLocationPageState extends State { onPlacePicked: (PickResult result) { print(result.adrAddress); }, - selectedPlaceWidgetBuilder: - (_, selectedPlace, state, isSearchBarFocused) { - print( - "state: $state, isSearchBarFocused: $isSearchBarFocused"); + selectedPlaceWidgetBuilder: (_, selectedPlace, state, isSearchBarFocused) { + print("state: $state, isSearchBarFocused: $isSearchBarFocused"); + return isSearchBarFocused ? Container() : FloatingCard( @@ -81,76 +200,112 @@ class _CMCLocationPageState extends State { child: Column( children: [ SecondaryButton( - color: Colors.grey[800], + color: CustomColors.accentColor, textColor: Colors.white, onTap: () async { print(selectedPlace); - AddNewAddressRequestModel - addNewAddressRequestModel = - new AddNewAddressRequestModel( - customer: Customer(addresses: [ - Addresses( - address1: selectedPlace - .formattedAddress, - address2: selectedPlace - .formattedAddress, + AddNewAddressRequestModel addNewAddressRequestModel = new AddNewAddressRequestModel( + customer: Customer( + addresses: [ + Addresses( + address1: selectedPlace!.formattedAddress, + address2: selectedPlace.formattedAddress, customerAttributes: "", city: "", createdOnUtc: "", - id: 0, - latLong: - "$latitude,$longitude", - email: "") - ]), + id: "0", + latLong: selectedPlace.geometry!.location.lat.toString() + "," + selectedPlace.geometry!.location.lng.toString(), + email: "", + ) + ], + ), ); - selectedPlace.addressComponents - .forEach((e) { + selectedPlace.addressComponents!.forEach((e) { if (e.types.contains("country")) { - addNewAddressRequestModel - .customer - .addresses[0] - .country = e.longName; + addNewAddressRequestModel.customer!.addresses![0].country = e.longName; } - if (e.types - .contains("postal_code")) { - addNewAddressRequestModel - .customer - .addresses[0] - .zipPostalCode = e.longName; + if (e.types.contains("postal_code")) { + addNewAddressRequestModel.customer!.addresses![0].zipPostalCode = e.longName; } if (e.types.contains("locality")) { - addNewAddressRequestModel - .customer - .addresses[0] - .city = e.longName; + addNewAddressRequestModel.customer!.addresses![0].city = e.longName; } }); - await model.addAddressInfo( - addNewAddressRequestModel: - addNewAddressRequestModel); - if (model.state == - ViewState.ErrorLocal) { + await model.addAddressInfo(addNewAddressRequestModel: addNewAddressRequestModel); + if (model.state == ViewState.ErrorLocal) { Utils.showErrorToast(model.error); } else { - AppToast.showSuccessToast( - message: - "Address Added Successfully"); + onPick(); + AppToast.showSuccessToast(message: "Address Added Successfully"); } Navigator.of(context).pop(); }, - label: TranslationBase.of(context) - .addNewAddress, + label: TranslationBase.of(context).addNewAddress, ), ], ), ), ); }, - initialPosition: LatLng(latitude, longitude), - useCurrentLocation: false, + initialPosition: gmaps.LatLng(latitude, longitude), + useCurrentLocation: showCurrentLocation, ), - )); + ), + ); + } + + void _getUserLocation() async { + if (await this.sharedPref.getDouble(USER_LAT) != null && await this.sharedPref.getDouble(USER_LONG) != null) { + var lat = await this.sharedPref.getDouble(USER_LAT); + var long = await this.sharedPref.getDouble(USER_LONG); + latitude = lat; + longitude = long; + currentPostion = gmaps.LatLng(lat, long); + setMap(); + } else { + if (await PermissionService.isLocationEnabled()) { + Geolocator.getLastKnownPosition().then((value) { + latitude = value!.latitude; + longitude = value.longitude; + currentPostion = gmaps.LatLng(latitude, longitude); + setMap(); + }); + } else { + if (Platform.isAndroid) { + Utils.showPermissionConsentDialog(context, TranslationBase.of(context).locationPermissionDialog, () { + Geolocator.getLastKnownPosition().then((value) { + latitude = value!.latitude; + longitude = value.longitude; + currentPostion = gmaps.LatLng(latitude, longitude); + setMap(); + }); + }); + } else { + Geolocator.getLastKnownPosition().then((value) { + latitude = value!.latitude; + longitude = value.longitude; + setMap(); + }); + } + } + } + } + + setMap() { + setState(() { + _kGooglePlex = gmaps.CameraPosition( + target: currentPostion, + zoom: 14.4746, + ); + appMap.moveTo(cameraPostion: _kGooglePlex); + }); + } + + void _updatePosition(gmaps.CameraPosition _position) { + print(_position); + latitude = _position.target.latitude; + longitude = _position.target.longitude; } } diff --git a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/new_cmc_page.dart b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/new_cmc_page.dart index f314a9bf..1b467242 100644 --- a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/new_cmc_page.dart +++ b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/new_cmc_page.dart @@ -1,27 +1,25 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/GetCMCAllOrdersResponseModel.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_insert_pres_order_request_model.dart'; -import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/get_order_detail_by_order_iD_response_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/update_pres_oreder_request_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/cmc_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; -import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/Dialog/confirm_cancel_order_dialog.dart'; -import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/HomeHealthCare/StepsWidget.dart'; +import 'package:diplomaticquarterapp/main.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/ConfirmWithMessageDialog.dart'; import 'package:flutter/material.dart'; import 'package:geolocator/geolocator.dart'; import 'package:provider/provider.dart'; import 'new_cmc_step_one_page.dart'; -import 'new_cmc_step_three_page.dart'; -import 'new_cmc_step_tow_page.dart'; class NewCMCPage extends StatefulWidget { - NewCMCPage({this.model}); + NewCMCPage({required this.model}); final CMCViewModel model; @@ -30,45 +28,42 @@ class NewCMCPage extends StatefulWidget { } class _NewCMCPageState extends State with TickerProviderStateMixin { - PageController _controller; + late PageController _controller; int _currentIndex = 1; - double _latitude; - double _longitude; + double _latitude = 0; + double _longitude = 0; - CMCInsertPresOrderRequestModel cMCInsertPresOrderRequestModel; + late CMCInsertPresOrderRequestModel cMCInsertPresOrderRequestModel; + + late BuildContext _context; @override void initState() { super.initState(); PatientERCMCInsertServicesList patientERCMCInsertServicesList; if (widget.model.cmcAllServicesList.length > 0) { - patientERCMCInsertServicesList = new PatientERCMCInsertServicesList( - price: widget.model.cmcAllServicesList[0].price, - serviceID: widget.model.cmcAllServicesList[0].serviceID.toString(), - selectedServiceName: widget.model.cmcAllServicesList[0].description, - selectedServiceNameAR: - widget.model.cmcAllServicesList[0].descriptionN, - recordID: 1, - totalPrice: widget.model.cmcAllServicesList[0].totalPrice, - vAT: widget.model.cmcAllServicesList[0].vAT); - cMCInsertPresOrderRequestModel = new CMCInsertPresOrderRequestModel( - patientERCMCInsertServicesList: [patientERCMCInsertServicesList]); + patientERCMCInsertServicesList = PatientERCMCInsertServicesList( + price: widget.model.cmcAllServicesList[0].price, + serviceID: widget.model.cmcAllServicesList[0].serviceID.toString(), + selectedServiceName: widget.model.cmcAllServicesList[0].text, + selectedServiceNameAR: widget.model.cmcAllServicesList[0].textN, + recordID: 1, + totalPrice: widget.model.cmcAllServicesList[0].priceTotal, + vAT: widget.model.cmcAllServicesList[0].priceVAT, + ); + cMCInsertPresOrderRequestModel = CMCInsertPresOrderRequestModel(patientERCMCInsertServicesList: [patientERCMCInsertServicesList]); + } else { + cMCInsertPresOrderRequestModel = CMCInsertPresOrderRequestModel(patientERCMCInsertServicesList: []); + //changed By Aamir } - - cMCInsertPresOrderRequestModel = new CMCInsertPresOrderRequestModel( - patientERCMCInsertServicesList: patientERCMCInsertServicesList != null - ? [patientERCMCInsertServicesList] - : []); - _controller = new PageController(); - - _getCurrentLocation(); + // _getCurrentLocation(); } _getCurrentLocation() async { - await getLastKnownPosition().then((value) { - _latitude = value.latitude; + await Geolocator.getLastKnownPosition().then((value) { + _latitude = value!.latitude; _longitude = value.longitude; }).catchError((e) { _longitude = 0; @@ -87,321 +82,171 @@ class _NewCMCPageState extends State with TickerProviderStateMixin { @override Widget build(BuildContext context) { + _context = context; ProjectViewModel projectViewModel = Provider.of(context); - - void showConfirmMessage( - CMCViewModel model, GetOrderDetailByOrderIDResponseModel order) { + void showConfirmMessage(CMCViewModel model, GetCMCAllOrdersResponseModel order) { showDialog( context: context, - child: ConfirmCancelOrderDialog( - model: model, - onTap: () async { - UpdatePresOrderRequestModel updatePresOrderRequestModel = - UpdatePresOrderRequestModel( - presOrderID: order.presOrderID, - rejectionReason: "", - presOrderStatus: 4, - editedBy: 3); - await model.updateCmcPresOrder(updatePresOrderRequestModel); - if (model.state == ViewState.ErrorLocal) { - Utils.showErrorToast(model.error); - } else { - AppToast.showSuccessToast( - message: - TranslationBase.of(context).processDoneSuccessfully); - await model.getCmcAllPresOrders(); - } - }, - )); + builder: (cxt) => ConfirmWithMessageDialog( + message: TranslationBase.of(context).cancelOrderMsg, + 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); + } + }); + }, + )); + } + + int status = widget.model.pendingOrder != null && widget.model.pendingOrder!.statusId != null ? widget.model.pendingOrder!.statusId! : 0; + String _statusDisp = widget.model.pendingOrder != null && widget.model.pendingOrder!.statusText != null ? widget.model.pendingOrder!.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 Scaffold( body: SafeArea( - child: SingleChildScrollView( - child: Container( - height: MediaQuery.of(context).size.height * 0.8, - child: Column( - children: [ - if (widget.model.cmcAllOrderDetail.length == 0) - Container( - margin: EdgeInsets.only( - left: MediaQuery.of(context).size.width * 0.05, - right: MediaQuery.of(context).size.width * 0.05), - child: StepsWidget( - index: _currentIndex, - changeCurrentTab: changePageViewIndex, - ), - ), - Expanded( - child: PageView( - physics: NeverScrollableScrollPhysics(), - controller: _controller, - onPageChanged: (index) { - setState(() { - _currentIndex = index; - }); - }, - scrollDirection: Axis.horizontal, - children: [ - widget.model.cmcAllOrderDetail.length != 0 - ? FractionallySizedBox( - widthFactor: 0.9, - child: SingleChildScrollView( + child: Container( + child: widget.model.pendingOrder != null && widget.model.pendingOrder!.serviceText != null + ? Column( + children: [ + Container( + width: double.infinity, + padding: EdgeInsets.only(left: 12, right: 12, top: 12), + child: Container( + decoration: cardRadius(12), + margin: EdgeInsets.zero, + clipBehavior: Clip.antiAlias, + child: Container( + 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: [ - Container( - width: double.infinity, - margin: EdgeInsets.only(top: 15), - decoration: BoxDecoration( - border: Border.all( - color: Colors.grey, width: 1), - borderRadius: - BorderRadius.circular(12), - color: - Theme.of(context).primaryColor), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - SizedBox( - height: 12, - ), - Container( - width: double.infinity, - padding: EdgeInsets.only( - left: 15, - bottom: 15, - top: 15, - right: 15), - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Colors.grey, - width: 1.0, - ), - ), - // borderRadius: BorderRadius.circular(12), - color: Theme.of(context) - .primaryColor), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Texts( - TranslationBase.of(context) - .requestID, - bold: false, - fontSize: 13, - ), - SizedBox( - height: 4, - ), - Texts( - widget.model - .cmcAllOrderDetail[0].iD - .toString(), - fontSize: 22, - ), - ], - ), - ), - Container( - width: double.infinity, - padding: EdgeInsets.only( - left: 15, - bottom: 15, - top: 15, - right: 15), - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Colors.grey, - width: 1.0, - ), - ), - // borderRadius: BorderRadius.circular(12), - color: Theme.of(context) - .primaryColor), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Texts( - TranslationBase.of(context) - .OrderStatus, - bold: false, - fontSize: 13, - ), - SizedBox( - height: 4, - ), - Texts( - projectViewModel.isArabic - ? widget - .model - .cmcAllOrderDetail[0] - .descriptionN - : widget - .model - .cmcAllOrderDetail[0] - .description, - fontSize: 22, - ), - ], - ), - ), - Container( - width: double.infinity, - padding: EdgeInsets.only( - left: 15, - bottom: 15, - top: 15, - right: 15), - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Colors.grey, - width: 1.0, - ), - ), - // borderRadius: BorderRadius.circular(12), - color: Theme.of(context) - .primaryColor), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Texts( - TranslationBase.of(context) - .pickupDate, - bold: false, - fontSize: 13, - ), - SizedBox( - height: 4, - ), - Texts( - DateUtil.getDayMonthYearDateFormatted( - DateUtil.convertStringToDate( - widget - .model - .cmcAllOrderDetail[ - 0] - .createdOn)), - fontSize: 22, - ), - ], - ), - ), - Container( - width: double.infinity, - padding: EdgeInsets.only( - left: 15, bottom: 15, top: 15), - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Colors.grey, - width: 1.0, - ), - ), - // borderRadius: BorderRadius.circular(12), - color: Theme.of(context) - .primaryColor), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Texts( - TranslationBase.of(context) - .serviceName, - bold: false, - fontSize: 13, - ), - SizedBox( - height: 4, - ), - Texts( - !projectViewModel.isArabic - ? widget - .model - .cmcAllOrderDetail[0] - .description - .toString() - : widget - .model - .cmcAllOrderDetail[0] - .descriptionN - .toString(), - fontSize: 22, - ), - ], - ), - ), - SizedBox( - height: 12, - ), - Center( - child: Container( - width: MediaQuery.of(context) - .size - .width * - 0.85, - child: SecondaryButton( - label: TranslationBase.of( - context) - .cancel - .toUpperCase(), - onTap: () { - showConfirmMessage( - widget.model, - widget.model - .cmcAllOrderDetail[0]); - }, - color: Colors.red[800], - disabled: false, - textColor: Theme.of(context) - .backgroundColor), - ), - ), - SizedBox( - height: 22, + Text( + _statusDisp, + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: _color, letterSpacing: -0.4, height: 16 / 10), + ), + SizedBox(height: 6), + Text( + '${TranslationBase.of(context).requestID}: ${widget.model.pendingOrder!.iD}', + 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).hospital + ": ", + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff575757), letterSpacing: -0.4, height: 16 / 10), + ), + Expanded( + child: Text( + widget.model.pendingOrder!.projectName != null ? widget.model.pendingOrder!.projectName!.trim().toString() : "", + style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.56), ), - ], - ), + ), + ], ), - SizedBox( - height: 22, + 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), + ), + Expanded( + child: Text( + widget.model.pendingOrder!.serviceText!.trim().toString(), + style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.56), + ), + ), + ], ), ], ), ), - ) - : NewCMCStepOnePage( - changePageViewIndex: changePageViewIndex, - cMCInsertPresOrderRequestModel: - cMCInsertPresOrderRequestModel, - model: widget.model, - ), - NewCMCStepTowPage( - longitude: _longitude, - latitude: _latitude, - changePageViewIndex: changePageViewIndex, - cmcInsertPresOrderRequestModel: - cMCInsertPresOrderRequestModel, - model: widget.model, - ), - NewCMCStepThreePage( - changePageViewIndex: changePageViewIndex, - cmcInsertPresOrderRequestModel: - cMCInsertPresOrderRequestModel, - model: widget.model, + Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text( + 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), + if (widget.model.pendingOrder!.statusId == 1 || widget.model.pendingOrder!.statusId == 2) + InkWell( + onTap: () { + showConfirmMessage(widget.model, widget.model.pendingOrder!); + }, + 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), + ), + ), + ), + ], + ), + ], + ), + ), ), - ], + ) + ], + ) + : Container( + color: Colors.red, + child: NewCMCStepOnePage( + changePageViewIndex: changePageViewIndex, + cMCInsertPresOrderRequestModel: cMCInsertPresOrderRequestModel, + model: widget.model, + latitude: _latitude, + longitude: _longitude, ), ), - ], - ), - ), ), ), ); diff --git a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/new_cmc_step_one_page.dart b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/new_cmc_step_one_page.dart index c07b8345..43350f2d 100644 --- a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/new_cmc_step_one_page.dart +++ b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/new_cmc_step_one_page.dart @@ -1,27 +1,31 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; -import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_get_items_request_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_insert_pres_order_request_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/cmc_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/new_cmc_step_three_page.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:diplomaticquarterapp/widgets/dragable_sheet.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/photo_view_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; import 'package:provider/provider.dart'; +import 'new_cmc_step_tow_page.dart'; + class NewCMCStepOnePage extends StatefulWidget { final CMCInsertPresOrderRequestModel cMCInsertPresOrderRequestModel; final Function changePageViewIndex; final CMCViewModel model; - const NewCMCStepOnePage( - {Key key, - this.cMCInsertPresOrderRequestModel, - this.model, - this.changePageViewIndex}) + final double latitude; + final double longitude; + + const NewCMCStepOnePage({Key? key, required this.cMCInsertPresOrderRequestModel, required this.model, required this.changePageViewIndex, required this.latitude, required this.longitude}) : super(key: key); @override @@ -29,6 +33,8 @@ class NewCMCStepOnePage extends StatefulWidget { } class _NewCMCStepOnePageState extends State { + int selectedItem = 0; + @override void initState() { super.initState(); @@ -41,236 +47,148 @@ class _NewCMCStepOnePageState extends State { return AppScaffold( isShowAppBar: false, baseViewModel: widget.model, - body: SingleChildScrollView( - physics: ScrollPhysics(), - child: Container( - margin: EdgeInsets.all(12), - child: Center( - child: Column( - children: [ - FractionallySizedBox( - widthFactor: 0.94, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 20, - ), - Texts( - TranslationBase.of(context).selectService, - textAlign: TextAlign.center, - ), - Column( - children: - widget.model.cmcAllServicesList.map((service) { - return Container( - margin: EdgeInsets.only(top: 15), - decoration: BoxDecoration( - border: - Border.all(color: Colors.grey, width: 1), - borderRadius: BorderRadius.circular(12), - color: Theme.of(context).primaryColor), - child: Column( - children: [ - Row( - children: [ - Radio( - value: service.serviceID, - activeColor: Colors.red[800], - onChanged: (newValue) async { - PatientERCMCInsertServicesList - patientERCMCInsertServicesList = - new PatientERCMCInsertServicesList( - price: service.price, - serviceID: service.serviceID - .toString(), - selectedServiceName: - service.description, - selectedServiceNameAR: - service.descriptionN, - recordID: 1, - totalPrice: - service.totalPrice, - vAT: service.vAT); - setState(() { - widget - .cMCInsertPresOrderRequestModel - .patientERCMCInsertServicesList = [ - patientERCMCInsertServicesList - ]; - }); - CMCGetItemsRequestModel - cMCGetItemsRequestModel = - new CMCGetItemsRequestModel( - checkupType: newValue); - await widget.model.getCheckupItems( - cMCGetItemsRequestModel: - cMCGetItemsRequestModel); - }, - groupValue: widget - .cMCInsertPresOrderRequestModel - .patientERCMCInsertServicesList - .length > - 0 - ? int.parse(widget - .cMCInsertPresOrderRequestModel - .patientERCMCInsertServicesList[ - 0] - .serviceID) - : 1), - Expanded( - child: Padding( - padding: const EdgeInsets.all(20.0), - child: Texts( - projectViewModel.isArabic - ? service.descriptionN - : service.description, - fontSize: 15, - ), - ), - ), - ], + body: Column( + children: [ + Expanded( + child: SingleChildScrollView( + physics: BouncingScrollPhysics(), + padding: EdgeInsets.all(21), + child: Column( + children: [ + ListView.separated( + physics: NeverScrollableScrollPhysics(), + shrinkWrap: true, + itemBuilder: (context, index) { + return Row( + children: [ + Radio( + value: num.tryParse(widget.model.cmcAllServicesList[index].serviceID!), + activeColor: Colors.red[800], + onChanged: (newValue) async { + selectedItem = index; + PatientERCMCInsertServicesList patientERCMCInsertServicesList = PatientERCMCInsertServicesList( + price: widget.model.cmcAllServicesList[index].price, + serviceID: widget.model.cmcAllServicesList[index].serviceID, + selectedServiceName: widget.model.cmcAllServicesList[index].text, + selectedServiceNameAR: widget.model.cmcAllServicesList[index].textN, + recordID: 1, + totalPrice: widget.model.cmcAllServicesList[index].priceTotal, + vAT: widget.model.cmcAllServicesList[index].priceVAT); + setState(() { + widget.cMCInsertPresOrderRequestModel.patientERCMCInsertServicesList = [patientERCMCInsertServicesList]; + }); + // CMCGetItemsRequestModel cMCGetItemsRequestModel = new CMCGetItemsRequestModel(checkupType: newValue); + // await widget.model.getCheckupItems(cMCGetItemsRequestModel: cMCGetItemsRequestModel); + }, + groupValue: widget.cMCInsertPresOrderRequestModel.patientERCMCInsertServicesList!.length > 0 + ? int.parse(widget.cMCInsertPresOrderRequestModel.patientERCMCInsertServicesList![0].serviceID!) + : 1), + Expanded( + child: Padding( + padding: const EdgeInsets.only( + left: 10, + right: 10, + top: 20, + bottom: 20, ), - ], - ), - ); - }).toList(), - ), - ], - ), - ), - SizedBox( - height: 30, - ), - Container( - color: Theme.of(context).primaryColor, - width: double.infinity, - child: Column( - children: [ - Row( - children: [ - Container( - margin: EdgeInsets.only(right: 10, left: 10), - child: Texts( - TranslationBase.of(context).coveredService, - fontWeight: FontWeight.bold, - )) - ], - ), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: widget.model.checkupItems.map((item) { - return Center( - child: FractionallySizedBox( - widthFactor: 1, - child: Container( - margin: EdgeInsets.only(top: 15), - decoration: BoxDecoration( - color: Theme.of(context).primaryColor), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - SizedBox( - height: 12, - ), - Container( - width: double.infinity, - padding: EdgeInsets.only( - left: 15, bottom: 5, top: 5), - decoration: BoxDecoration( - border: BorderDirectional( - bottom: BorderSide( - style: BorderStyle.solid, - width: 0.5, - color: Colors.grey)), - //borderRadius: , - color: - Theme.of(context).primaryColor), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Container( - margin: EdgeInsets.only( - right: 10, left: 10), - child: Texts(item.itemName, - fontSize: 15, - fontWeight: FontWeight.bold), - ), - ], - ), - ), - SizedBox( - height: 12, - ), - ], + child: Text( + projectViewModel.isArabic ? widget.model.cmcAllServicesList[index].textN! : widget.model.cmcAllServicesList[index].text!, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + letterSpacing: -0.45, ), ), ), - ); - }).toList()), + ), + ], + ); + }, + separatorBuilder: (context, index) { + return mDivider(Colors.grey); + }, + itemCount: widget.model.cmcAllServicesList.length), + Stack( + children: [ + Image.asset( + projectViewModel.isArabic ? "assets/images/cc_ar.png" : "assets/images/cc_en.png", + width: double.infinity, + ), + Align( + alignment: Alignment.topRight, + child: Container( + decoration: containerColorRadiusBorder( + Colors.black.withOpacity(0.2), + 1000, + Colors.white, + ), + margin: EdgeInsets.all(12), + child: IconButton( + icon: SvgPicture.asset( + "assets/images/new/ic_zoom.svg", + color: Colors.white, + ), + padding: EdgeInsets.all(12), + onPressed: () { + showDraggableDialog(context, PhotoViewPage(projectViewModel.isArabic ? "assets/images/cc_ar.png" : "assets/images/cc_en.png")); + }, + ), + ), + ), ], ), - ) - ], + ], + ), ), ), - ), - ), - bottomSheet: Container( - height: MediaQuery.of(context).size.height * 0.10, - width: double.infinity, - child: Column( - children: [ - Container( - width: MediaQuery.of(context).size.width * 0.9, - child: SecondaryButton( - label: TranslationBase.of(context).next, - textColor: Theme.of(context).backgroundColor, - color: Colors.grey[800], - onTap: () async { - if (widget.cMCInsertPresOrderRequestModel - .patientERCMCInsertServicesList.length != - 0 || - widget.cMCInsertPresOrderRequestModel - .patientERCMCInsertServicesList == - null) { - int index = widget.model.cmcAllServicesList.length; - PatientERCMCInsertServicesList - patientERCMCInsertServicesList = - new PatientERCMCInsertServicesList( - price: widget - .model.cmcAllServicesList[index - 1].price, - serviceID: widget - .model.cmcAllServicesList[index - 1].serviceID - .toString(), - selectedServiceName: widget.model - .cmcAllServicesList[index - 1].description, - selectedServiceNameAR: widget.model - .cmcAllServicesList[index - 1].descriptionN, - recordID: 1, - totalPrice: widget - .model.cmcAllServicesList[index - 1].totalPrice, - vAT: - widget.model.cmcAllServicesList[index - 1].vAT); + Container( + color: Colors.white, + padding: EdgeInsets.only(top: 16, bottom: 16, right: 21, left: 21), + child: DefaultButton( + TranslationBase.of(context).next, + () async { + if (widget.cMCInsertPresOrderRequestModel.patientERCMCInsertServicesList!.length != 0 || widget.cMCInsertPresOrderRequestModel.patientERCMCInsertServicesList == null) { + // int index = widget.model.cmcAllServicesList.length; + PatientERCMCInsertServicesList patientERCMCInsertServicesList = new PatientERCMCInsertServicesList( + price: widget.model.cmcAllServicesList[selectedItem].price, + serviceID: widget.model.cmcAllServicesList[selectedItem].serviceID.toString(), + selectedServiceName: widget.model.cmcAllServicesList[selectedItem].text, + selectedServiceNameAR: widget.model.cmcAllServicesList[selectedItem].textN, + recordID: 1, + totalPrice: widget.model.cmcAllServicesList[selectedItem].priceTotal, + vAT: widget.model.cmcAllServicesList[selectedItem].priceVAT, + ); + + widget.cMCInsertPresOrderRequestModel.patientID = projectViewModel.user!.patientID; + widget.cMCInsertPresOrderRequestModel.patientOutSA = projectViewModel.user!.outSA; - widget.cMCInsertPresOrderRequestModel - .patientERCMCInsertServicesList = [ - patientERCMCInsertServicesList - ]; - await widget.model.getCustomerInfo(); - if (widget.model.state == ViewState.ErrorLocal) { - Utils.showErrorToast(); - } else { - widget.changePageViewIndex(1); - } + widget.cMCInsertPresOrderRequestModel.patientERCMCInsertServicesList = [patientERCMCInsertServicesList]; + navigateTo( + context, + NewCMCStepThreePage( + cmcInsertPresOrderRequestModel: widget.cMCInsertPresOrderRequestModel, + model: widget.model, + ), + ); + // await widget.model.getCustomerInfo(); + if (widget.model.state == ViewState.ErrorLocal) { + Utils.showErrorToast(); + } else { + // navigateTo( + // context, + // NewCMCStepTowPage( + // longitude: widget.longitude, + // latitude: widget.latitude, + // cmcInsertPresOrderRequestModel: widget.cMCInsertPresOrderRequestModel, + // model: widget.model, + // ), + // ); } - }, - ), + } + }, ), - ], - ), + ), + ], ), ); } diff --git a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/new_cmc_step_three_page.dart b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/new_cmc_step_three_page.dart index 75699a5c..20d4f9f5 100644 --- a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/new_cmc_step_three_page.dart +++ b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/new_cmc_step_three_page.dart @@ -2,27 +2,35 @@ import 'dart:async'; import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_insert_pres_order_request_model.dart'; +import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; +import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/cmc_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/Dialog/confirm_dialog.dart'; +import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.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/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; +import 'package:maps_launcher/maps_launcher.dart'; import 'package:provider/provider.dart'; class NewCMCStepThreePage extends StatefulWidget { final CMCInsertPresOrderRequestModel cmcInsertPresOrderRequestModel; - final Function changePageViewIndex; final CMCViewModel model; NewCMCStepThreePage( - {Key key, - this.changePageViewIndex, - this.model, - this.cmcInsertPresOrderRequestModel}); + {Key? key, + required this.model, + required this.cmcInsertPresOrderRequestModel}); @override _NewCMCStepThreePageState createState() => _NewCMCStepThreePageState(); @@ -31,6 +39,13 @@ class NewCMCStepThreePage extends StatefulWidget { class _NewCMCStepThreePageState extends State { Completer _controller = Completer(); + String? projectDropdownValue; + late List projectsList = []; + HospitalsModel? selectedHospital; + final GlobalKey projectDropdownKey = GlobalKey(); + bool isLocationSelected = false; + ProjectViewModel? projectViewModel; + static CameraPosition _kGooglePlex = CameraPosition( target: LatLng(37.42796133580664, -122.085749655962), zoom: 14.4746, @@ -47,23 +62,39 @@ class _NewCMCStepThreePageState extends State { widget.cmcInsertPresOrderRequestModel.latitude.hashCode .toString(), ), - position: LatLng(widget.cmcInsertPresOrderRequestModel.latitude, - widget.cmcInsertPresOrderRequestModel.longitude)), + position: LatLng(widget.cmcInsertPresOrderRequestModel.latitude!, + widget.cmcInsertPresOrderRequestModel.longitude!)), ); _kGooglePlex = CameraPosition( - target: LatLng(widget.cmcInsertPresOrderRequestModel.latitude, - widget.cmcInsertPresOrderRequestModel.longitude), + target: LatLng(widget.cmcInsertPresOrderRequestModel.latitude!, + widget.cmcInsertPresOrderRequestModel.longitude!), zoom: 14.4746, ); } + WidgetsBinding.instance.addPostFrameCallback((_) { + // if (projectViewModel.isLogin) { + getProjectsList(); + // } + }); super.initState(); } @override Widget build(BuildContext context) { - ProjectViewModel projectViewModel = Provider.of(context); + projectViewModel = Provider.of(context); return AppScaffold( - isShowDecPage: false, + isShowAppBar: true, + description: TranslationBase.of(context).infoCMC, + 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).comprehensiveMedicalCheckup, + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: CustomColors.appBackgroudGreyColor, baseViewModel: widget.model, body: SingleChildScrollView( physics: BouncingScrollPhysics(), @@ -74,79 +105,221 @@ class _NewCMCStepThreePageState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Texts( - TranslationBase.of(context).orderDetails, - fontWeight: FontWeight.bold, + SizedBox( + height: 12, + ), + Text( + TranslationBase.of(context).orderSummary, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + letterSpacing: -0.46, + ), ), SizedBox( height: 12, ), Container( - decoration: BoxDecoration( - color: Theme.of(context).primaryColor, - borderRadius: BorderRadius.circular(12)), - padding: EdgeInsets.all(8), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts( - TranslationBase.of(context).orderLocation + " : ", - fontWeight: FontWeight.bold, - ), - SizedBox( - height: 12, - ), - Padding( - padding: const EdgeInsets.all(8.0), - child: Container( - height: 200, - child: GoogleMap( - mapType: MapType.normal, - markers: markers, - initialCameraPosition: _kGooglePlex, - onMapCreated: (GoogleMapController controller) { - _controller.complete(controller); - }, - ), - ), - ), - SizedBox( - height: 12, - ), - Texts(TranslationBase.of(context).selectedService), - ...List.generate( - widget.cmcInsertPresOrderRequestModel - .patientERCMCInsertServicesList.length, - (index) => Container( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + decoration: cardRadius(12), + child: Container( + padding: EdgeInsets.all(8), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: double.infinity, + decoration: containerRadius(Colors.white, 12), + margin: EdgeInsets.only(top: 12), + padding: EdgeInsets.only( + left: 0, right: 0, top: 0, bottom: 12), + child: Row( children: [ - Texts( - TranslationBase.of(context).serviceName, - fontSize: 12, - fontWeight: FontWeight.bold, - ), - SizedBox( - height: 5, - ), - Texts( - projectViewModel.isArabic - ? widget - .cmcInsertPresOrderRequestModel - .patientERCMCInsertServicesList[index] - .selectedServiceNameAR - : widget - .cmcInsertPresOrderRequestModel - .patientERCMCInsertServicesList[index] - .selectedServiceName, - fontSize: 15, - bold: true, + Flexible( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).selectLocation, + style: TextStyle( + fontSize: 11, + letterSpacing: -0.44, + fontWeight: FontWeight.w600, + ), + ), + Container( + height: 18, + child: DropdownButtonHideUnderline( + child: DropdownButton( + key: projectDropdownKey, + hint: new Text( + TranslationBase.of(context) + .selectHospital), + value: selectedHospital, + iconSize: 0, + isExpanded: true, + style: TextStyle( + fontSize: 14, + letterSpacing: -0.56, + color: Colors.black), + items: projectsList.map((item) { + return new DropdownMenuItem< + HospitalsModel>( + value: item, + child: new Text(item.name!), + ); + }).toList(), + onChanged: + (HospitalsModel? newValue) async { + setState(() { + selectedHospital = newValue!; + projectDropdownValue = newValue + .mainProjectID + .toString(); + isLocationSelected = true; + widget.cmcInsertPresOrderRequestModel + .projectID = + newValue.mainProjectID; + // getDoctorsList(context); + }); + }, + ), + ), + ), + ], + ), ), + Icon(Icons.keyboard_arrow_down), ], ), ), - ) - ], + SizedBox( + height: 6, + ), + isLocationSelected + ? Padding( + padding: const EdgeInsets.all(8.0), + child: Stack( + children: [ + Container( + height: 200, + decoration: containerColorRadiusBorder( + Colors.white, 12, Colors.grey), + clipBehavior: Clip.antiAlias, + child: Container( + decoration: cardRadius(12), + clipBehavior: Clip.antiAlias, + margin: const EdgeInsets.all(0), + child: Image.network( + "https://maps.googleapis.com/maps/api/staticmap?center=" + + selectedHospital!.latitude + .toString() + + "," + + selectedHospital!.longitude + .toString() + + "&zoom=16&size=600x300&maptype=roadmap&markers=color:red%7C" + + selectedHospital!.latitude + .toString() + + "," + + selectedHospital!.longitude + .toString() + + "&key=AIzaSyCyDbWUM9d_sBUGIE8PcuShzPaqO08NSC8", + width: double.infinity, + height: double.infinity, + fit: BoxFit.cover, + ), + ), + ), + Row( + mainAxisAlignment: MainAxisAlignment.end, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + InkWell( + onTap: () { + getDirections(); + }, + child: Container( + decoration: cardRadius(1000), + margin: EdgeInsets.all(12), + child: Padding( + padding: const EdgeInsets.only( + left: 12, + right: 12, + top: 6, + bottom: 6), + child: Row( + children: [ + Padding( + padding: + const EdgeInsets.all(3.0), + child: SvgPicture.asset( + "assets/images/new/direction.svg", + width: 13, + height: 13, + ), + ), + mWidth(6), + Text( + TranslationBase.of(context) + .getDirections, + style: TextStyle( + color: Colors.black, + fontSize: 11, + letterSpacing: -0.44, + fontWeight: FontWeight.w600, + ), + ) + ], + ), + ), + ), + ), + ], + ), + ], + ), + ) + : Container(), + SizedBox( + height: 12, + ), + Text( + TranslationBase.of(context).selectedService, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.bold, + letterSpacing: -0.46, + color: CustomColors.grey, + ), + ), + ...List.generate( + widget.cmcInsertPresOrderRequestModel + .patientERCMCInsertServicesList!.length, + (index) => Container( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + projectViewModel!.isArabic + ? widget + .cmcInsertPresOrderRequestModel + .patientERCMCInsertServicesList![index] + .selectedServiceNameAR! + : widget + .cmcInsertPresOrderRequestModel + .patientERCMCInsertServicesList![index] + .selectedServiceName!, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.bold, + letterSpacing: -0.46, + ), + ), + ], + ), + ), + ) + ], + ), ), ) ], @@ -156,25 +329,99 @@ class _NewCMCStepThreePageState extends State { bottomSheet: Container( height: MediaQuery.of(context).size.height * 0.10, width: double.infinity, + color: Colors.white, child: Column( + mainAxisAlignment: MainAxisAlignment.center, children: [ Container( width: MediaQuery.of(context).size.width * 0.9, - child: SecondaryButton( - label: TranslationBase.of(context).confirm, - color: Colors.grey[800], - onTap: () async { - await widget.model.insertPresPresOrder( - order: widget.cmcInsertPresOrderRequestModel); - if (widget.model.state != ViewState.ErrorLocal) { - widget.changePageViewIndex(0); - } - }, - textColor: Theme.of(context).backgroundColor), + child: DefaultButton( + TranslationBase.of(context).confirm, + !isLocationSelected + ? null + : () async { + GifLoaderDialogUtils.showMyDialog(context); + String requestId = await widget.model.insertCMCOrderRC( + order: widget.cmcInsertPresOrderRequestModel); + GifLoaderDialogUtils.hideDialog(context); + if (widget.model.state != ViewState.ErrorLocal) { + showCMCConfirmDialog( + context, + requestId, + onClick: () { + Navigator.pop(context); + Navigator.pop(context); + }, + ); + } else { + AppToast.showErrorToast(message: widget.model.error); + } + }, + color: CustomColors.green, + disabledColor: CustomColors.grey, + ), + // SecondaryButton( + // label: TranslationBase.of(context).confirm, + // color: CustomColors.green, + // onTap: () async { + // if(isLocationSelected) { + // GifLoaderDialogUtils.showMyDialog(context); + // String requestId = await widget.model.insertCMCOrderRC(order: widget.cmcInsertPresOrderRequestModel); + // GifLoaderDialogUtils.hideDialog(context); + // if (widget.model.state != ViewState.ErrorLocal) { + // showCMCConfirmDialog( + // context, + // requestId, + // onClick: () { + // Navigator.pop(context); + // Navigator.pop(context); + // }, + // ); + // } else { + // AppToast.showErrorToast(message: widget.model.error); + // } + // } else { + // Utils.showErrorToast("Please select hospital from the dropdown menu to continue"); + // } + // }, + // textColor: Theme.of(context).backgroundColor), ), ], ), ), ); } + + getDirections() { + if (isLocationSelected) { + MapsLauncher.launchCoordinates(double.parse(selectedHospital!.latitude!), + double.parse(selectedHospital!.longitude!), selectedHospital!.name); + } else { + Utils.showErrorToast( + "Please select address from the dropdown menu to get directions"); + } + } + + getProjectsList() { + int languageID = projectViewModel!.isArabic ? 1 : 2; + ClinicListService service = new ClinicListService(); + GifLoaderDialogUtils.showMyDialog(context); + List projectsListLocal = []; + service.getProjectsList(languageID, context).then((res) { + if (res['MessageStatus'] == 1) { + setState(() { + res['ListProject'].forEach((v) { + projectsListLocal.add(new HospitalsModel.fromJson(v)); + }); + projectsList = projectsListLocal; + }); + } + GifLoaderDialogUtils.hideDialog(context); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } } diff --git a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/new_cmc_step_tow_page.dart b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/new_cmc_step_tow_page.dart index 3d969d9e..d75aecaa 100644 --- a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/new_cmc_step_tow_page.dart +++ b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/new_cmc_step_tow_page.dart @@ -1,40 +1,39 @@ -import 'package:diplomaticquarterapp/config/config.dart'; +import 'dart:async'; +import 'dart:io'; + +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_insert_pres_order_request_model.dart'; +import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/customer_addresses_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/cmc_view_model.dart'; -import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; -import 'package:diplomaticquarterapp/widgets/dialogs/select_location_dialog.dart'; -import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/location_page.dart'; +import 'package:diplomaticquarterapp/services/permission/permission_service.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/uitl/utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/app_map/google_huawei_map.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/select_location_dialog.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:google_maps_flutter/google_maps_flutter.dart'; -import 'package:google_maps_place_picker/google_maps_place_picker.dart'; -import 'package:provider/provider.dart'; +import 'package:geolocator/geolocator.dart'; +import 'package:google_maps_flutter/google_maps_flutter.dart' as gmaps; +import 'package:google_maps_place_picker_mb/google_maps_place_picker.dart'; +import 'package:permission_handler/permission_handler.dart'; import 'cmc_location_page.dart'; +import 'new_cmc_step_three_page.dart'; class NewCMCStepTowPage extends StatefulWidget { final Function(PickResult) onPick; final double latitude; final double longitude; final CMCInsertPresOrderRequestModel cmcInsertPresOrderRequestModel; - final Function changePageViewIndex; final CMCViewModel model; - const NewCMCStepTowPage( - {Key key, - this.onPick, - this.latitude, - this.longitude, - this.cmcInsertPresOrderRequestModel, - this.changePageViewIndex, - this.model}) - : super(key: key); + const NewCMCStepTowPage({Key? key, required this.onPick, required this.latitude, required this.longitude, required this.cmcInsertPresOrderRequestModel, required this.model}) : super(key: key); @override _NewCMCStepTowPageState createState() => _NewCMCStepTowPageState(); @@ -43,151 +42,264 @@ class NewCMCStepTowPage extends StatefulWidget { class _NewCMCStepTowPageState extends State { double latitude = 0; double longitude = 0; - AddressInfo _selectedAddress; + late AddressInfo _selectedAddress; + bool showCurrentLocation = false; + AppSharedPreferences sharedPref = AppSharedPreferences(); - @override - void initState() { - if (widget.cmcInsertPresOrderRequestModel.latitude == null) { - setLatitudeAndLongitude(); + static gmaps.CameraPosition cameraPosition = gmaps.CameraPosition( + target: gmaps.LatLng(37.42796133580664, -122.085749655962), + zoom: 14.4746, + ); + + late gmaps.LatLng currentPostion; + + void _getUserLocation() async { + if (await this.sharedPref.getDouble(USER_LAT) != null && await this.sharedPref.getDouble(USER_LONG) != null) { + var lat = await this.sharedPref.getDouble(USER_LAT); + var long = await this.sharedPref.getDouble(USER_LONG); + latitude = lat; + longitude = long; + currentPostion = gmaps.LatLng(lat, long); + setMap(); } else { - latitude = widget.cmcInsertPresOrderRequestModel.latitude; - longitude = widget.cmcInsertPresOrderRequestModel.longitude; + if (await PermissionService.isLocationEnabled()) { + Geolocator.getLastKnownPosition().then((value) { + latitude = value!.latitude; + longitude = value.longitude; + currentPostion = gmaps.LatLng(latitude, longitude); + setMap(); + }); + } else { + if (Platform.isAndroid) { + Utils.showPermissionConsentDialog(context, TranslationBase.of(context).locationPermissionDialog, () { + Geolocator.getLastKnownPosition().then((value) { + latitude = value!.latitude; + longitude = value.longitude; + currentPostion = gmaps.LatLng(latitude, longitude); + setMap(); + }); + }); + } else { + Geolocator.getLastKnownPosition().then((value) { + latitude = value!.latitude; + longitude = value.longitude; + currentPostion = gmaps.LatLng(latitude, longitude); + setMap(); + }); + } + } } + } + + @override + void initState() { super.initState(); + appMap = AppMap( + cameraPosition.toMap() as Map, + // Changed by Aamir + onCameraMove: () { + // setState(() {}); + // Changed by Aamir + _updatePosition(cameraPosition); + }, + onMapCreated: () { + print("_getUserLocation"); + _getUserLocation(); + }, + ); + } + + setMap() { + setState(() { + cameraPosition = gmaps.CameraPosition( + target: currentPostion, + zoom: 14.4746, + ); + if (appMap != null) appMap.moveTo(cameraPostion: cameraPosition); + }); } - setLatitudeAndLongitude({bool isSetState = false, String latLong}) { - if (latLong == null) - latLong = widget - .model.addressesList[widget.model.addressesList.length - 1].latLong; - List latLongArr = latLong.split(','); + Future> requestPermissions() async { + var permissionResults = [ + Permission.location, + Permission.locationAlways, + ].request(); + + return permissionResults; + } + + setLatitudeAndLongitude({bool isSetState = false, String? latLong}) async { + print("latLong " + latLong.toString()); + if (latLong == null) { + if (widget.model.addressesList.isEmpty) { + setState(() { + showCurrentLocation = true; + }); + } else { + latLong = widget.model.addressesList[widget.model.addressesList.length - 1].latLong; + } + } + + if (!showCurrentLocation) { + List latLongArr = latLong!.split(','); - latitude = double.parse(latLongArr[0]); - longitude = double.parse(latLongArr[1]); + latitude = double.parse(latLongArr[0]); + longitude = double.parse(latLongArr[1]); + print("sssss1 " + latitude.toString()); + print("sssss2 " + longitude.toString()); + currentPostion = gmaps.LatLng(latitude, longitude); + setMap(); + } } + late AppMap appMap; + @override Widget build(BuildContext context) { - ProjectViewModel projectViewModel = Provider.of(context); return AppScaffold( - isShowDecPage: false, - body: Stack( + isShowAppBar: true, + description: TranslationBase.of(context).infoCMC, + 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).comprehensiveMedicalCheckup, + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: CustomColors.appBackgroudGreyColor, + baseViewModel: widget.model, + body: Column( children: [ - PlacePicker( - apiKey: GOOGLE_API_KEY, - enableMyLocationButton: true, - automaticallyImplyAppBarLeading: false, - autocompleteOnTrailingWhitespace: true, - selectInitialPosition: true, - autocompleteLanguage: projectViewModel.currentLanguage, - enableMapTypeButton: true, - searchForInitialValue: false, - onPlacePicked: (PickResult result) { - print(result.adrAddress); - widget.changePageViewIndex(3); - }, - selectedPlaceWidgetBuilder: - (_, selectedPlace, state, isSearchBarFocused) { - print("state: $state, isSearchBarFocused: $isSearchBarFocused"); - return isSearchBarFocused - ? Container() - : FloatingCard( - bottomPosition: 0.0, - leftPosition: 0.0, - rightPosition: 0.0, - width: 500, - borderRadius: BorderRadius.circular(12.0), - child: state == SearchingState.Searching - ? Center(child: CircularProgressIndicator()) - : Container( - margin: EdgeInsets.all(12), - child: Column( - children: [ - SecondaryButton( - color: Colors.grey[800], - textColor: Colors.white, - onTap: () { - Navigator.push( - context, - FadePage( - page: CMCLocationPage( - latitude: latitude, - longitude: longitude, - ), - ), - ); - }, - label: TranslationBase.of(context) - .addNewAddress, - ), - SizedBox( - height: 10, - ), - SecondaryButton( - color: Colors.red[800], - textColor: Colors.white, - onTap: () { - setState(() { - widget.cmcInsertPresOrderRequestModel - .latitude = - selectedPlace.geometry.location.lat; - widget.cmcInsertPresOrderRequestModel - .longitude = - selectedPlace.geometry.location.lng; - }); - widget.changePageViewIndex(3); - }, - label: TranslationBase.of(context).confirm, - ), - ], - )), - ); - }, - initialPosition: LatLng(latitude, longitude), - useCurrentLocation: false, - ), - Container( - child: InkWell( - onTap: () => - confirmSelectLocationDialog(widget.model.addressesList), + if (widget.model.addressesList.isNotEmpty) + Container( + margin: EdgeInsets.only(left: 12, right: 12, bottom: 12, top: 12), + decoration: cardRadius(12), child: Container( - padding: EdgeInsets.all(10), - width: double.infinity, - // height: 65, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - color: Theme.of(context).primaryColor), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Texts( - getAddressName(), - fontSize: 14, - ), + child: InkWell( + onTap: () => confirmSelectLocationDialog(widget.model.addressesList), + child: Container( + padding: EdgeInsets.all(8), + width: double.infinity, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: Colors.white, ), - Icon(Icons.arrow_drop_down) - ], + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Text( + getAddressName(), + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 12, + letterSpacing: -0.45, + ), + ), + ), + Icon(Icons.arrow_drop_down) + ], + ), + ), ), + height: 50, + width: double.infinity, ), ), - height: 56, - width: double.infinity, - color: Theme.of(context).scaffoldBackgroundColor, - ) + InkWell( + onTap: () async { + bool isNeedToUpdate = false; + await Navigator.of(context).push(new MaterialPageRoute( + builder: (BuildContext context) { + return CMCLocationPage( + latitude: latitude, + longitude: longitude, + onPick: () { + isNeedToUpdate = true; + }, + ); + }, + )); + if (isNeedToUpdate) { + _selectedAddress = new AddressInfo(); + _selectedAddress.address1 = widget.model.addressesList.last.address1; + showCurrentLocation = false; + setLatitudeAndLongitude(); + setState(() {}); + } + }, + child: Padding( + padding: EdgeInsets.only(left: 12, right: 12, bottom: 16, top: 8), + child: Row( + children: [ + Icon(Icons.add_circle_outline_sharp), + mWidth(12), + Text( + TranslationBase.of(context).addNewAddress, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + letterSpacing: -0.46, + ), + ), + ], + ), + ), + ), + Expanded( + child: Stack( + alignment: Alignment.center, + children: [ + if (appMap != null) appMap, + Icon( + Icons.place, + color: CustomColors.accentColor, + size: 50, + ), + ], + ), + ), + Padding( + padding: const EdgeInsets.only(left: 20, right: 20, top: 14, bottom: 14), + child: SecondaryButton( + color: Colors.red[800], + textColor: Colors.white, + onTap: () { + setState(() { + widget.cmcInsertPresOrderRequestModel.latitude = latitude; + widget.cmcInsertPresOrderRequestModel.longitude = longitude; + }); + // widget.changePageViewIndex(3); + navigateTo( + context, + NewCMCStepThreePage( + cmcInsertPresOrderRequestModel: widget.cmcInsertPresOrderRequestModel, + model: widget.model, + ), + ); + }, + label: TranslationBase.of(context).continues, + ), + ), ], ), ); } + void _updatePosition(gmaps.CameraPosition _position) { + latitude = _position.target.latitude; + longitude = _position.target.longitude; + } + void confirmSelectLocationDialog(List addresses) { showDialog( context: context, - child: SelectLocationDialog( + builder: (cxt) => SelectLocationDialog( addresses: addresses, selectedAddress: _selectedAddress, onValueSelected: (value) { + showCurrentLocation = false; setLatitudeAndLongitude(latLong: value.latLong); + setState(() { _selectedAddress = value; }); @@ -198,7 +310,7 @@ class _NewCMCStepTowPageState extends State { String getAddressName() { if (_selectedAddress != null) - return _selectedAddress.address1; + return _selectedAddress.address1!; else return TranslationBase.of(context).selectAddress; } diff --git a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_page.dart b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_page.dart index f1d3e72f..162c67a2 100644 --- a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_page.dart +++ b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_page.dart @@ -2,12 +2,14 @@ import 'dart:ui'; import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/cmc_view_model.dart'; +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/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; import 'NewCMC/new_cmc_page.dart'; import 'orders_log_details_page.dart'; @@ -18,7 +20,7 @@ class CMCPage extends StatefulWidget { } class _CMCPageState extends State with SingleTickerProviderStateMixin { - TabController _tabController; + late TabController _tabController; @override void initState() { @@ -34,6 +36,7 @@ class _CMCPageState extends State with SingleTickerProviderStateMixin { @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); return BaseView( onModelReady: (model) async { await model.getCmcAllPresOrders(); @@ -42,94 +45,43 @@ class _CMCPageState extends State with SingleTickerProviderStateMixin { isShowAppBar: true, description: TranslationBase.of(context).infoCMC, imagesInfo: [ - ImagesInfo( - imageAr: 'assets/images/Wifi-AR.png', - imageEn: 'assets/images/wifi-EN.png', - isAsset: true) + 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).comprehensiveMedicalCheckup, - body: Scaffold( - extendBodyBehindAppBar: true, - appBar: PreferredSize( - preferredSize: Size.fromHeight(65.0), - child: Stack( - children: [ - Positioned( - bottom: 1, - left: 0, - right: 0, - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10), - child: Container( - color: Theme.of(context).primaryColor.withOpacity(0.8), - height: 70.0, - ), - ), - ), - Center( - child: Container( - height: 60.0, - margin: EdgeInsets.only(top: 10.0), - width: MediaQuery.of(context).size.width * 0.9, - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Theme.of(context).dividerColor, - width: 0.7), - ), - color: Theme.of(context).primaryColor), - child: Center( - child: TabBar( - isScrollable: true, - controller: _tabController, - indicatorWeight: 5.0, - indicatorSize: TabBarIndicatorSize.tab, - indicatorColor: Colors.red[800], - labelColor: Theme.of(context).primaryColor, - labelPadding: - EdgeInsets.only(top: 4.0, left: 18.0, right: 18.0), - unselectedLabelColor: Colors.grey[800], - tabs: [ - Container( - width: MediaQuery.of(context).size.width * 0.37, - child: Center( - child: Texts(TranslationBase.of(context) - .comprehensiveMedicalCheckup), - ), - ), - Container( - width: MediaQuery.of(context).size.width * 0.37, - child: Center( - child: - Texts(TranslationBase.of(context).orderLog), - ), - ), - ], - ), - ), - ), - ), - ], + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: CustomColors.appBackgroudGrey2Color, + body: Column( + children: [ + TabBar( + controller: _tabController, + indicatorWeight: 3.0, + indicatorSize: TabBarIndicatorSize.tab, + labelColor: Color(0xff2B353E), + unselectedLabelColor: Color(0xff575757), + labelPadding: EdgeInsets.only(top: 15, bottom: 13, 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: [Text(TranslationBase.of(context).cmcHeading), Text(TranslationBase.of(context).orderLog)], ), - ), - body: Column( - children: [ - Expanded( - child: TabBarView( - physics: BouncingScrollPhysics(), - controller: _tabController, - children: [ - NewCMCPage( - model: model, - ), - OrdersLogDetailsPage( - model: model, - ) - ], - ), - ) - ], - ), + Expanded( + child: TabBarView( + physics: BouncingScrollPhysics(), + controller: _tabController, + children: [NewCMCPage(model: model), OrdersLogDetailsPage(model: model)], + ), + ) + ], ), ), ); diff --git a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/orders_log_details_page.dart b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/orders_log_details_page.dart index ec686e70..10a15d8d 100644 --- a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/orders_log_details_page.dart +++ b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/orders_log_details_page.dart @@ -1,14 +1,19 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/GetCMCAllOrdersResponseModel.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/get_hhc_all_pres_orders_response_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/update_pres_oreder_request_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/cmc_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/ConfirmWithMessageDialog.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -18,243 +23,161 @@ import 'Dialog/confirm_cancel_order_dialog.dart'; class OrdersLogDetailsPage extends StatelessWidget { final CMCViewModel model; - const OrdersLogDetailsPage({Key key, this.model}) : super(key: key); + const OrdersLogDetailsPage({Key ?key, required this.model}) : super(key: key); @override Widget build(BuildContext context) { - ProjectViewModel projectViewModel = Provider.of(context); - void showConfirmMessage( - CMCViewModel model, GetHHCAllPresOrdersResponseModel order) { + void showConfirmMessage(CMCViewModel model, GetCMCAllOrdersResponseModel order) { showDialog( context: context, - child: ConfirmCancelOrderDialog( - model: model, - onTap: () async { - UpdatePresOrderRequestModel updatePresOrderRequestModel = - UpdatePresOrderRequestModel( - presOrderID: order.iD, - rejectionReason: "", - presOrderStatus: 4, editedBy: 3); - await model.updateCmcPresOrder(updatePresOrderRequestModel); - if(model.state == ViewState.ErrorLocal) { - Utils.showErrorToast(model.error); - } else { - AppToast.showSuccessToast(message:TranslationBase.of(context).processDoneSuccessfully ); - await model.getCmcAllPresOrders(); - } + builder: (cxt) => ConfirmWithMessageDialog( + message: TranslationBase.of(context).cancelOrderMsg, + onTap: () { + 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); + } + }); }, )); + return; } return AppScaffold( - isShowAppBar: false, - baseViewModel: model, - body: SingleChildScrollView( - physics: ScrollPhysics(), - child: Container( - margin: EdgeInsets.all(12), - child: Center( - child: FractionallySizedBox( - widthFactor: 0.94, - child: Column( + isShowAppBar: false, + baseViewModel: model, + body: model.cmcAllPresOrders.length > 0 ? ListView.separated( + padding: EdgeInsets.all(21), + physics: BouncingScrollPhysics(), + itemBuilder: (context, index) { + GetCMCAllOrdersResponseModel order = model.cmcAllPresOrders.reversed.toList()[index]; + + int status = order.statusId!; + String _statusDisp = order.statusText!; + late 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 Container( + decoration: BoxDecoration( + color: _color, + borderRadius: BorderRadius.all( + Radius.circular(10.0), + ), + 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: 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: [ - SizedBox( - height: 50, - ), - Column( + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, - children: model.cmcAllPresOrders.map((order) { - return Container( - width: double.infinity, - margin: EdgeInsets.only(top: 15), - decoration: BoxDecoration( - border: - Border.all(color: Colors.grey, width: 1), - borderRadius: BorderRadius.circular(12), - color: Colors.white), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 12, - ), - Container( - width: double.infinity, - padding: EdgeInsets.only( - left: 15, bottom: 15, top: 15,right: 15), - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Colors.grey, - width: 1.0, - ), - ), - // borderRadius: BorderRadius.circular(12), - color: Colors.white), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts( - TranslationBase - .of(context) - .requestID, - bold: false, - fontSize: 13, - ), - SizedBox( - height: 4, - ), - Texts( - order.iD.toString(), - fontSize: 22, - ), - ], - ), - ), - Container( - width: double.infinity, - padding: EdgeInsets.only( - left: 15, bottom: 15, top: 15,right: 15), - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Colors.grey, - width: 1.0, - ), - ), - // borderRadius: BorderRadius.circular(12), - color: Colors.white), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts( - TranslationBase - .of(context) - .OrderStatus, - bold: false, - fontSize: 13, - ), - SizedBox( - height: 4, - ), - Texts( - - projectViewModel.isArabic ? order - .descriptionN : order.description, - fontSize: 22, - ), - ], - ), + children: [ + Text( + _statusDisp, + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: _color, letterSpacing: -0.4, height: 16 / 10), + ), + SizedBox(height: 6), + Text( + '${TranslationBase.of(context).requestID}: ${order.iD}', + 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).hospital + ": ", + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff575757), letterSpacing: -0.4, height: 16 / 10), + ), + Expanded( + child: Text( + // !projectViewModel.isArabic ? order.nearestProjectDescription.trim().toString() : order.nearestProjectDescriptionN.toString(), + order.projectName != null ? order.projectName!.trim().toString() : "", + style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.56), ), - Container( - width: double.infinity, - padding: EdgeInsets.only( - left: 15, bottom: 15, top: 15,right: 15), - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Colors.grey, - width: 1.0, - ), - ), - // borderRadius: BorderRadius.circular(12), - color: Colors.white), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts( - TranslationBase.of(context).pickupDate, - bold: false, - fontSize: 13, - ), - SizedBox( - height: 4, - ), - Texts( - DateUtil.getDayMonthYearDateFormatted( - DateUtil.convertStringToDate(order.createdOn)), - fontSize: 22, - ), - ], - ), - ), - Container( - width: double.infinity, - padding: EdgeInsets.only( - left: 15, bottom: 15, top: 15,right: 15), - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Colors.grey, - width: 1.0, - ), - ), - // borderRadius: BorderRadius.circular(12), - color: Colors.white), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Texts( - TranslationBase.of(context).orderLocation, - bold: false, - fontSize: 13, - ), - SizedBox( - height: 4, - ), - Texts( - !projectViewModel.isArabic?order. - projectDescription.toString() : - order - .projectDescriptionN - .toString(), - fontSize: 22, - ), - ], - ), - ), - SizedBox( - height: 12, - ), - if (order.status == 1 ||order.status == 2 ) - Center( - child: Container( - width: MediaQuery - .of(context) - .size - .width * - 0.85, - child: SecondaryButton( - label: TranslationBase.of(context).cancel.toUpperCase(), - onTap: () { - showConfirmMessage(model, - order); - } - , - color: Colors.red[800], - disabled: false, - textColor: Theme - .of(context) - .backgroundColor), - ), - ), - SizedBox( - height: 22, - ), - ], + ), + ], + ) + ], + ), + ), + Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text( + DateUtil.getDayMonthYearDateFormatted(DateTime.tryParse(order.created!)!), + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.4, height: 16 / 10), + ), + SizedBox(height: 12), + if (order.statusId == 1 || order.statusId == 2) + InkWell( + onTap: () { + showConfirmMessage(model, order); + }, + 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), + ), ), - ); - }).toList()) - ], + ), + ], + ), + ], + ), ), - ), - ), - ), - ), + ); + }, + separatorBuilder: (context, index) => SizedBox(height: 12), + itemCount: model.cmcAllPresOrders.length) : getNoDataWidget(context), ); } } diff --git a/lib/pages/AlHabibMedicalService/E-Referral/New_E_Referral/new_e_referral_index_page.dart b/lib/pages/AlHabibMedicalService/E-Referral/New_E_Referral/new_e_referral_index_page.dart index fb2b94c6..543f320b 100644 --- a/lib/pages/AlHabibMedicalService/E-Referral/New_E_Referral/new_e_referral_index_page.dart +++ b/lib/pages/AlHabibMedicalService/E-Referral/New_E_Referral/new_e_referral_index_page.dart @@ -1,5 +1,8 @@ import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/EReferral/create_e_referral_request_model.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/E-Referral/New_E_Referral/new_e_referral_step_one_page.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:flutter/material.dart'; import 'new_e_referral_step_three_page.dart'; @@ -9,18 +12,15 @@ class StartIndexForNewEReferral extends StatefulWidget { StartIndexForNewEReferral(); @override - _StartIndexForNewEReferralState createState() => - _StartIndexForNewEReferralState(); + _StartIndexForNewEReferralState createState() => _StartIndexForNewEReferralState(); } -class _StartIndexForNewEReferralState extends State - with TickerProviderStateMixin { - PageController _controller; - int _currentIndex = 1; +class _StartIndexForNewEReferralState extends State with TickerProviderStateMixin { + late PageController _controller; + int _currentIndex = 0; int pageSelected = 2; - CreateEReferralRequestModel createEReferralRequestModel = - new CreateEReferralRequestModel(); + CreateEReferralRequestModel createEReferralRequestModel = new CreateEReferralRequestModel(); @override void initState() { @@ -40,37 +40,139 @@ class _StartIndexForNewEReferralState extends State @override Widget build(BuildContext context) { return Scaffold( - body: SafeArea( - child: SingleChildScrollView( - child: Container( - height: MediaQuery.of(context).size.height * 0.9, - child: PageView( - physics: NeverScrollableScrollPhysics(), - controller: _controller, - onPageChanged: (index) { - setState(() { - _currentIndex = index; - }); - }, - scrollDirection: Axis.horizontal, - children: [ - NewEReferralStepOnePage( - changePageViewIndex: changePageViewIndex, - createEReferralRequestModel: createEReferralRequestModel, - ), - NewEReferralStepTowPage( - changePageViewIndex: changePageViewIndex, - createEReferralRequestModel: createEReferralRequestModel, - ), - NewEReferralStepThreePage( - changePageViewIndex: changePageViewIndex, - createEReferralRequestModel: createEReferralRequestModel, - ), - ], + body: Container( + height: double.infinity, + child: Column( + children: [ + Container( + width: double.infinity, + padding: EdgeInsets.only(left: 12,right: 12,top: 12), + child: Row( + children: [ + Expanded( + child: showProgress( + title: TranslationBase.of(context).RequesterInfo, + status: _currentIndex == 0 + ? TranslationBase.of(context).inPrgress + : _currentIndex > 0 + ? TranslationBase.of(context).completed + : TranslationBase.of(context).locked, + color: _currentIndex == 0 ? CustomColors.orange : CustomColors.green, + ), + ), + Expanded( + child: showProgress( + title: TranslationBase.of(context).patientInfo, + status: _currentIndex == 1 + ? TranslationBase.of(context).inPrgress + : _currentIndex > 1 + ? TranslationBase.of(context).completed + : TranslationBase.of(context).locked, + color: _currentIndex == 1 + ? CustomColors.orange + : _currentIndex > 1 + ? CustomColors.green + : CustomColors.grey2, + ), + ), + showProgress( + title: TranslationBase.of(context).otherInfo, + status: _currentIndex == 2 ? TranslationBase.of(context).inPrgress : TranslationBase.of(context).locked, + color: _currentIndex == 2 + ? CustomColors.orange + : _currentIndex > 3 + ? CustomColors.green + : CustomColors.grey2, + isNeedBorder: false, + ), + ], + ), ), - ), + Expanded( + child: PageView( + physics: NeverScrollableScrollPhysics(), + controller: _controller, + onPageChanged: (index) { + setState(() { + _currentIndex = index; + }); + }, + scrollDirection: Axis.horizontal, + children: [ + NewEReferralStepOnePage( + changePageViewIndex: changePageViewIndex, + createEReferralRequestModel: createEReferralRequestModel, + ), + NewEReferralStepTowPage( + changePageViewIndex: changePageViewIndex, + createEReferralRequestModel: createEReferralRequestModel, + ), + NewEReferralStepThreePage( + changePageViewIndex: changePageViewIndex, + createEReferralRequestModel: createEReferralRequestModel, + ), + ], + ), + ), + ], ), ), ); } + + Widget showProgress({required String title, required String status, required Color color, bool isNeedBorder = true}) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Container( + width: 26, + height: 26, + decoration: containerRadius(color, 200), + child: Icon( + Icons.done, + color: Colors.white, + size: 16, + ), + ), + if (isNeedBorder) + Expanded( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: mDivider(Colors.grey), + )), + ], + ), + mHeight(8), + Text( + title, + style: TextStyle( + fontSize: 11, + fontWeight: FontWeight.w600, + letterSpacing: -0.44, + ), + ), + mHeight(2), + Container( + padding: EdgeInsets.all(5), + decoration: containerRadius(color.withOpacity(0.2), 4), + child: Text( + status, + style: TextStyle( + fontSize: 8, + fontWeight: FontWeight.w600, + letterSpacing: -0.32, + color: color, + ), + ), + ), + ], + ) + ], + ); + } } 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 62799c6d..72d28f60 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 @@ -1,30 +1,34 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/EReferral/check_activation_code_for_e_referral_request_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/EReferral/create_e_referral_request_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/EReferral/get_all_relationship_types_response_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/EReferral/send_activation_code_for_e_referral_request_model.dart'; import 'package:diplomaticquarterapp/core/model/my_balance/AdvanceModel.dart'; 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/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/models/FamilyFiles/GetAllSharedRecordByStatusResponse.dart'; -import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/E-Referral/e_referral_confirm_sms_dialog.dart'; -import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/E-Referral/dialogs/select_country_ingo_Dialog.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/E-Referral/dialogs/select_relation_type_dialog.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; -import 'package:diplomaticquarterapp/pages/medical/balance/new_text_Field.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/widgets/buttons/secondary_button.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/mobile-no/mobile_no.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/otp/sms-popup.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; - +import 'package:provider/provider.dart'; class NewEReferralStepOnePage extends StatefulWidget { final CreateEReferralRequestModel createEReferralRequestModel; final Function changePageViewIndex; - const NewEReferralStepOnePage({Key key, this.createEReferralRequestModel, this.changePageViewIndex}) : super(key: key); + const NewEReferralStepOnePage({Key? key, required this.createEReferralRequestModel, required this.changePageViewIndex}) : super(key: key); @override _NewEReferralStepOnePageState createState() => _NewEReferralStepOnePageState(); @@ -32,194 +36,209 @@ class NewEReferralStepOnePage extends StatefulWidget { class _NewEReferralStepOnePageState extends State { TextEditingController _nameTextController = TextEditingController(); - TextEditingController _mobileTextController = TextEditingController(); - GetAllRelationshipTypeResponseModel _selectedRelation; - String email; - AuthenticatedUser authenticatedUser; - GetAllSharedRecordsByStatusList selectedPatientFamily; + TextEditingController _requesterRelationTextController = TextEditingController(); + + GetAllRelationshipTypeResponseModel _selectedRelation = GetAllRelationshipTypeResponseModel(); + String? email; + AuthenticatedUser authenticatedUser = AuthenticatedUser(); + GetAllSharedRecordsByStatusList selectedPatientFamily = GetAllSharedRecordsByStatusList(); AdvanceModel advanceModel = AdvanceModel(); + late ProjectViewModel projectViewModel; + String mobileNo = ""; // todo create a model for Country // todo use country from the json - dynamic _selectedCountry = { - "name": "Saudi Arabia", - "name_ar": "المملكة العربية السعودية", - "code": "+966", - "countryCode": "SA", - "pattern": "5xxxxxxxx", - "maxLength": 9 - }; + dynamic _selectedCountry = {"name": "Saudi Arabia", "name_ar": "المملكة العربية السعودية", "code": "966", "countryCode": "SA", "pattern": "5xxxxxxxx", "maxLength": 9}; AppSharedPreferences sharedPref = AppSharedPreferences(); - AuthenticatedUser authUser; + late AuthenticatedUser authUser; @override void initState() { super.initState(); } + void showSMSDialog(EReferralViewModel model) { + SMSOTP( + context, + 1, + _selectedCountry['code'] + mobileNo, + (value) { + submit(model, value); + }, + () => { + Navigator.pop(context), + }, + ).displayDialog(context); + } + @override Widget build(BuildContext context) { - void showSMSDialog() { - showDialog( - context: context, - barrierDismissible: false, - child: EReferralConfirmSMSDialog( - phoneNumber: _selectedCountry['code']+_mobileTextController.text, - onSucces: (){ - Navigator.of(context).pop(); - widget.changePageViewIndex(1); - widget.createEReferralRequestModel.requesterName=_nameTextController.text; - widget.createEReferralRequestModel.requesterContactNo = _selectedCountry['code'].toString().substring(1)+_mobileTextController.text; - widget.createEReferralRequestModel.requesterRelationship=_selectedRelation.iD; + projectViewModel = Provider.of(context); - - } - - - ), - ).then((value) { - print("dialog dismissed"); - print(value); - if (value != null && value) { - - } - }); - } return BaseView( - onModelReady: (model) => model.getRelationTypes(), - builder: (_, model, widget) => AppScaffold( - isShowAppBar: false, - body: SingleChildScrollView( - physics: ScrollPhysics(), - child: Container( - margin: EdgeInsets.all(12), - child: Center( - child: FractionallySizedBox( - widthFactor: 0.9, + onModelReady: (model) => model.getRelationTypes(), + builder: (_, model, widget) => AppScaffold( + isShowAppBar: false, + backgroundColor: CustomColors.appBackgroudGrey2Color, + body: Container( + child: Column( + children: [ + Expanded( + child: SingleChildScrollView( + physics: ScrollPhysics(), + child: Container( + margin: EdgeInsets.all(12), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( height: 20, ), - Center( - child: Texts( -// TranslationBase.of(context).advancePaymentLabel, - "Referral requester information", - textAlign: TextAlign.center, + Text( + TranslationBase.of(context).referralRequesterInformation, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.64, ), ), SizedBox( height: 12, ), - NewTextFields( - hintText: "Enter Referral Requester Name*", - controller: _nameTextController, - ), - SizedBox( - height: 12, - ), - InkWell( - onTap: () => confirmSelectCountryTypeDialog(), - 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(getCountryName()), - Icon(Icons.arrow_drop_down) - ], - ), - ), - ), + inputWidget(TranslationBase.of(context).enterReferralRequesterName, "", _nameTextController, isInputTypeNum: false), SizedBox( height: 12, ), - MobileNumberTextFiled( - controller: _mobileTextController, - code: _selectedCountry == null - ? "11" - : _selectedCountry["code"], - ), + PhoneNumberSelectorWidget(onNumberChange: (value) { + setState(() { + mobileNo = value; + }); + }, onCountryChange: (value) { + setState(() { + _selectedCountry = value; + }); + }), SizedBox( height: 12, ), - Center( - child: Texts( -// TranslationBase.of(context).advancePaymentLabel, - "Requester Relationship", - textAlign: TextAlign.center, + 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, + ), ), - ), - SizedBox( - height: 12, - ), - InkWell( - onTap: () => confirmSelectRelationTypeDialog( - model.relationTypes), - child: Container( - padding: EdgeInsets.all(12), - width: double.infinity, - height: 65, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - color: Colors.white), + child: InkWell( + onTap: () => confirmSelectRelationTypeDialog(model.relationTypes), child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Texts(getRelationName()), - Icon(Icons.arrow_drop_down) + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).selectRelationship, + style: TextStyle( + fontSize: 11, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.44, + ), + ), + Text( + getRelationName(), + style: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: Color(0xff2B353E), + letterSpacing: -0.44, + ), + ), + ], + ), + ), + Icon(Icons.arrow_drop_down), ], ), ), ), + SizedBox( + height: 12, + ), + if (_selectedRelation != null && _selectedRelation.iD == 5) + inputWidget(TranslationBase.of(context).requesterRelationship, "", _requesterRelationTextController, isInputTypeNum: false), ], ), ), ), ), - ), - bottomSheet: Container( - height: MediaQuery - .of(context) - .size - .height * 0.1, - width: double.infinity, - padding: EdgeInsets.all(9), - child: SecondaryButton( - textColor: Colors.white, - label: "Next", - onTap: () async { - SendActivationCodeForEReferralRequestModel sendActivationCodeForEReferralRequestModel = - SendActivationCodeForEReferralRequestModel( - zipCode: _selectedCountry['code'], - patientMobileNumber: int.parse( - _mobileTextController.text),); - await model.sendActivationCodeForEReferral(sendActivationCodeForEReferralRequestModel); - - showSMSDialog(); - }, - loading: model.state == ViewState.BusyLocal, - disabled: - _nameTextController.text.isEmpty || - _selectedRelation == null || - _mobileTextController.text.isEmpty, + Container( + margin: EdgeInsets.zero, + decoration: cardRadius(0), + child: Container( + // color: Theme.of(context).scaffoldBackgroundColor, + padding: EdgeInsets.all(12), + width: double.infinity, + child: DefaultButton( + TranslationBase.of(context).next, + (_nameTextController.text.isEmpty || _selectedRelation == null || mobileNo.isEmpty || (_selectedRelation.iD == 5 && _requesterRelationTextController.text.isEmpty)) + ? null + : () async { + Future.delayed(new Duration(milliseconds: 300)).then((value) async { + GifLoaderDialogUtils.showMyDialog(context); + SendActivationCodeForEReferralRequestModel sendActivationCodeForEReferralRequestModel = SendActivationCodeForEReferralRequestModel( + zipCode: _selectedCountry['code'], + patientMobileNumber: int.parse(mobileNo), + ); + await model.sendActivationCodeForEReferral(sendActivationCodeForEReferralRequestModel); + GifLoaderDialogUtils.hideDialog(context); + showSMSDialog(model); + }); + }, + disabledColor: Colors.grey, + ), + ), ), - ))); - + ], + ), + ), + ), + ); + } + void submit(EReferralViewModel model, code) async { + final activationCode = code; + Future.delayed(new Duration(milliseconds: 300)).then((value) async { + GifLoaderDialogUtils.showMyDialog(context); + CheckActivationCodeForEReferralResponseModel checkActivationCodeForEReferralRequestModel = new CheckActivationCodeForEReferralResponseModel(activationCode: activationCode); + await model.checkActivationCodeForEReferral(checkActivationCodeForEReferralRequestModel); + if (model.state == ViewState.ErrorLocal) { + GifLoaderDialogUtils.hideDialog(context); + Future.delayed(Duration(seconds: 1), () { + AppToast.showErrorToast(message: model.error); + showSMSDialog(model); + }); + } else { + GifLoaderDialogUtils.hideDialog(context); + Navigator.of(context).pop(); + widget.changePageViewIndex(1); + widget.createEReferralRequestModel.requesterName = _nameTextController.text; + widget.createEReferralRequestModel.requesterContactNo = _selectedCountry['code'].toString() + mobileNo; + widget.createEReferralRequestModel.otherRelationship = _requesterRelationTextController.text; + widget.createEReferralRequestModel.requesterRelationship = _selectedRelation.iD; + } + }); } - void confirmSelectRelationTypeDialog( - List relations) { + void confirmSelectRelationTypeDialog(List relations) { showDialog( context: context, - child: SelectRelationTypeDialog( + builder: (cxt) => SelectRelationTypeDialog( relationTypes: relations, selectedRelation: _selectedRelation, onValueSelected: (value) { @@ -231,53 +250,127 @@ class _NewEReferralStepOnePageState extends State { ); } - void confirmSelectCountryTypeDialog() { - showDialog( - context: context, - child: SelectCountryDialog( - selectedCountry: _selectedCountry, - onValueSelected: (value) { - setState(() { - _selectedCountry = 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, + ), + ), + 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), + ], + ), ), ); } + // void confirmSelectCountryTypeDialog() { + // showDialog( + // context: context, + // child: SelectCountryDialog( + // selectedCountry: _selectedCountry, + // onValueSelected: (value) { + // setState(() { + // _selectedCountry = value; + // }); + // }, + // ), + // ); + // } + String getRelationName() { - if (_selectedRelation != null) - return _selectedRelation.text; - else - return "Select Relationship" /*TranslationBase.of(context).selectHospital*/; + if (_selectedRelation !=null && _selectedRelation.textAr != null) { + if (projectViewModel.isArabic) { + return _selectedRelation.textAr!; + } + return _selectedRelation.textEn!; + } else + return ""; } String getCountryName() { - if (_selectedCountry != null) + if (_selectedCountry != null) { + if (projectViewModel.isArabic) { + return _selectedCountry["name_ar"]; + } return _selectedCountry["name"]; - else + } else return "Country"; } } class MobileNumberTextFiled extends StatelessWidget { - const MobileNumberTextFiled({ - Key key, - this.controller, - this.code - }) : super(key: key); - + const MobileNumberTextFiled({Key? key, required this.controller, required this.code, required this.onChange}) : super(key: key); final TextEditingController controller; final String code; + final Function onChange; @override Widget build(BuildContext context) { return Container( padding: EdgeInsets.all(5), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(15), color: Colors.white), - child: Row(children: [ + decoration: BoxDecoration(borderRadius: BorderRadius.circular(15), color: Colors.white), + child: Row(textDirection: TextDirection.ltr, children: [ Expanded( flex: 1, child: Icon( @@ -296,9 +389,9 @@ class MobileNumberTextFiled extends StatelessWidget { margin: EdgeInsets.all(5), child: TextField( controller: controller, + onChanged: onChange(), keyboardType: TextInputType.phone, - decoration: InputDecoration( - border: InputBorder.none, hintText: '5xxxxxxxx'), + decoration: InputDecoration(border: InputBorder.none, hintText: '5xxxxxxxx'), ), ), ) 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 a823c154..ec2a54d8 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 @@ -1,46 +1,59 @@ +import 'dart:io'; + import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/EReferral/create_e_referral_request_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/EReferral/get_all_cities_response_model.dart'; +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/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/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/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/bottom_options/BottomSheet.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.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:font_awesome_flutter/font_awesome_flutter.dart'; +import 'package:provider/provider.dart'; import '../dialogs/select_city_dialog.dart'; -import 'dart:io'; + class NewEReferralStepThreePage extends StatefulWidget { final CreateEReferralRequestModel createEReferralRequestModel; final Function changePageViewIndex; - const NewEReferralStepThreePage( - {Key key, this.createEReferralRequestModel, this.changePageViewIndex}) - : super(key: key); + const NewEReferralStepThreePage({Key? key, required this.createEReferralRequestModel, required this.changePageViewIndex}) : super(key: key); @override - _NewEReferralStepThreePageState createState() => - _NewEReferralStepThreePageState(); + _NewEReferralStepThreePageState createState() => _NewEReferralStepThreePageState(); } class _NewEReferralStepThreePageState extends State { TextEditingController _nameTextController = TextEditingController(); TextEditingController _mobileTextController = TextEditingController(); - GetAllCitiesResponseModel _selectedCity; + late GetAllCitiesResponseModel _selectedCity; - GetAllSharedRecordsByStatusList selectedPatientFamily; + late GetAllSharedRecordsByStatusList selectedPatientFamily; List medicalReportImages = []; List insuredPatientImages = []; + List projectsList = []; + bool isPatientInsured = false; AppSharedPreferences sharedPref = AppSharedPreferences(); - AuthenticatedUser authUser; + late AuthenticatedUser authUser; + + final GlobalKey projectDropdownKey = GlobalKey(); + String? projectDropdownValue; @override void initState() { @@ -50,386 +63,405 @@ class _NewEReferralStepThreePageState extends State { @override Widget build(BuildContext context) { return BaseView( + onModelReady: (model) { + getAllProjects(); + }, builder: (_, model, widget) => AppScaffold( isShowAppBar: false, + backgroundColor: CustomColors.appBackgroudGrey2Color, body: SingleChildScrollView( physics: ScrollPhysics(), child: Container( margin: EdgeInsets.all(12), - child: Center( - child: FractionallySizedBox( - widthFactor: 0.94, - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 20, - ), - Center( - child: Texts( -// TranslationBase.of(context).advancePaymentLabel, - "Other details", - textAlign: TextAlign.center, - ), - ), - SizedBox( - height: 12, - ), - Container( - padding: EdgeInsets.only(top: 10), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - color: Colors.white, - ), - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 9), - child: Texts( - "Medical Report", - color: Colors.grey, - fontSize: 17, - ), - ), - ], - ), - InkWell( - onTap: () { - ImageOptions.showImageOptions(context, - (String image,File file) { - setState(() { - EReferralAttachment eReferralAttachment = - new EReferralAttachment( - fileName: - 'image ${medicalReportImages.length + 1}.png', - base64String: image); - medicalReportImages - .add(eReferralAttachment); - }); - }, ); - }, - child: Container( - margin: EdgeInsets.only( - left: 10, right: 10, top: 15), - height: 50, - decoration: BoxDecoration( - border: Border.all(color: Colors.grey), - borderRadius: BorderRadius.circular(7), - color: Colors.white, - shape: BoxShape.rectangle, - ), - child: Center( - child: Row( - crossAxisAlignment: - CrossAxisAlignment.center, - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - Icon(Icons.attach_file), - Texts( - 'selected attachment', - variant: 'bodyText', - textAlign: TextAlign.center, - ), - ], - ), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: 20, + ), + Text( + TranslationBase.of(context).otherInfo, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.64, + ), + ), + SizedBox( + height: 12, + ), + Container( + padding: EdgeInsets.all(12), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + color: Colors.white, + ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).medicalReport, + style: TextStyle( + fontSize: 12, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, ), ), - ), - SizedBox( - height: 12, - ), - ...List.generate( + ...List.generate( medicalReportImages.length, (index) => Container( - margin: EdgeInsets.all(10), - padding: EdgeInsets.all(8.0), - child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, + padding: EdgeInsets.only(top: 6, bottom: 6), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Row( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Icon( - FontAwesomeIcons.paperclip), - SizedBox( - width: 8, - ), - Texts( - medicalReportImages[index] - .fileName, - ), - ], + Texts( + medicalReportImages[index].fileName, ), - InkWell( - onTap: () { - setState(() { - medicalReportImages.remove( - medicalReportImages[ - index]); - }); - }, - child: Icon( - FontAwesomeIcons.trashAlt, - color: Colors.red[300], - )) ], ), - )), - ], - ), - ), - SizedBox( - height: 12, - ), - Container( - padding: EdgeInsets.only(top: 10), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - color: Colors.white), - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 9), - child: Texts( - "Preferred Branch", - color: Colors.grey, - fontSize: 17, + InkWell( + onTap: () { + setState(() { + medicalReportImages.remove(medicalReportImages[index]); + }); + }, + child: Icon( + Icons.close, + color: Colors.red[300], + )) + ], ), ), - ], - ), - InkWell( - onTap: () => - confirmSelectCityDialog(model.allCities), - 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(getRelationName()), - Icon(Icons.arrow_drop_down) - ], + ), + InkWell( + onTap: () { + ImageOptions.showImageOptions( + context, + (String image, File file) { + setState(() { + EReferralAttachment eReferralAttachment = new EReferralAttachment(fileName: 'image ${medicalReportImages.length + 1}.png', base64String: image); + medicalReportImages.add(eReferralAttachment); + }); + }, + ); + }, + child: Padding( + padding: EdgeInsets.only(top: 12, bottom: 12), + child: Text( + TranslationBase.of(context).selectAttachment, + style: TextStyle( + fontSize: 14, + letterSpacing: -0.56, + decoration: TextDecoration.underline, + color: CustomColors.accentColor, + ), + ), ), ), - ), - ], + ], + ), ), - ), - SizedBox( - height: 12, - ), - Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - color: Colors.white), - child: Column( + Icon(Icons.attach_file), + ], + ), + ), + SizedBox( + height: 12, + ), + Container( + padding: EdgeInsets.only(top: 10), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), color: Colors.white), + child: Column( + children: [ + Container( + width: double.infinity, + decoration: containerRadius(Colors.white, 12), + margin: EdgeInsets.only(left: 20, right: 20), + padding: EdgeInsets.only(left: 10, right: 10, top: 12, bottom: 12), + child: Row( + children: [ + Flexible( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).preferredBranch, + style: TextStyle( + fontSize: 11, + letterSpacing: -0.44, + fontWeight: FontWeight.w600, + ), + ), + Container( + height: 18, + child: DropdownButtonHideUnderline( + child: DropdownButton( + key: projectDropdownKey, + hint: Text(TranslationBase.of(context).selectPreferredBranch), + value: projectDropdownValue, + iconSize: 0, + isExpanded: true, + style: TextStyle(fontSize: 14, letterSpacing: -0.56, color: Colors.black), + items: projectsList.map((item) { + return new DropdownMenuItem( + value: item.mainProjectID.toString() + "," + item.name.toString(), + child: new Text(item.name!), + ); + }).toList(), + onChanged: (newValue) { + setState(() { + projectDropdownValue = newValue!; + print(projectDropdownValue); + }); + }, + ), + ), + ), + ], + ), + ), + Icon(Icons.keyboard_arrow_down), + ], + )), + ], + ), + ), + SizedBox( + height: 12, + ), + Container( + // decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), color: Colors.white), + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, children: [ Row( - mainAxisAlignment: MainAxisAlignment.start, children: [ - Row( - children: [ - Checkbox( - value: isPatientInsured, - activeColor: Colors.black38, - onChanged: (bool newValue) { - setState(() { - isPatientInsured = newValue; - }); - }), - Padding( - padding: const EdgeInsets.all(20.0), - child: Texts( - "Insured Patient", - fontSize: 17, - ), - ), - ], + Checkbox( + value: isPatientInsured, + activeColor: CustomColors.accentColor, + onChanged: (bool? newValue) { + setState(() { + isPatientInsured = newValue!; + }); + }), + Padding( + padding: const EdgeInsets.all(5.0), + child: Text( + TranslationBase.of(context).insuredPatientReferral, + style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600), + ), ), ], ), ], ), + ], + ), + ), + if (isPatientInsured) + SizedBox( + height: 12, + ), + Opacity( + opacity: isPatientInsured ? 1 : 0, + child: Container( + padding: EdgeInsets.all(10), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + color: Colors.white, ), - if (isPatientInsured) - SizedBox( - height: 12, - ), - Opacity( - opacity: isPatientInsured ? 1 : 0, - child: Container( - padding: EdgeInsets.only(top: 10), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - color: Colors.white, - ), - child: Column( - children: [ - InkWell( - onTap: () { - ImageOptions.showImageOptions(context, - (String image,File file) { - setState(() { - EReferralAttachment - eReferralAttachment = - new EReferralAttachment( - fileName: - 'image ${medicalReportImages.length + 1}.png', - base64String: image); - - insuredPatientImages = [ - eReferralAttachment - ]; - }); - }); - }, - child: Container( - margin: EdgeInsets.only( - left: 10, right: 10, top: 15), - height: 50, - decoration: BoxDecoration( - border: Border.all(color: Colors.grey), - borderRadius: BorderRadius.circular(7), - color: Colors.white, - shape: BoxShape.rectangle, - ), - child: Center( - child: Row( - crossAxisAlignment: - CrossAxisAlignment.center, - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - Icon(Icons.attach_file), - Texts( - 'selected attachment', - variant: 'bodyText', - textAlign: TextAlign.center, - ), - ], - ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).medicalReport, + style: TextStyle( + fontSize: 12, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, ), ), - ), - SizedBox( - height: 12, - ), - ...List.generate( + ...List.generate( insuredPatientImages.length, (index) => Container( - margin: EdgeInsets.all(10), - padding: EdgeInsets.all(8.0), - child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, + padding: EdgeInsets.only(top: 6, bottom: 6), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Row( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Icon(FontAwesomeIcons - .paperclip), - SizedBox( - width: 8, - ), - Texts( - 'image ${index + 1}.png', - ), - ], + Texts( + 'image ${index + 1}.png', ), - InkWell( - onTap: () { - setState(() { - insuredPatientImages.remove( - insuredPatientImages[ - index]); - }); - }, - child: Icon( - FontAwesomeIcons.trashAlt, - color: Colors.red[300], - )) ], ), - )), - ], + InkWell( + onTap: () { + setState(() { + insuredPatientImages.remove(insuredPatientImages[index]); + }); + }, + child: Icon( + Icons.close, + color: Colors.red[300], + ), + ) + ], + ), + ), + ), + InkWell( + onTap: () { + ImageOptions.showImageOptions(context, (String image, File file) { + setState(() { + EReferralAttachment eReferralAttachment = new EReferralAttachment(fileName: 'image ${medicalReportImages.length + 1}.png', base64String: image); + insuredPatientImages = [eReferralAttachment]; + }); + }); + }, + child: Padding( + padding: const EdgeInsets.only(top: 12, bottom: 12), + child: Text( + TranslationBase.of(context).selectAttachment, + style: TextStyle( + fontSize: 14, + letterSpacing: -0.56, + decoration: TextDecoration.underline, + color: CustomColors.accentColor, + ), + ), + ), + ), + ], + ), ), - ), + Icon(Icons.attach_file), + ], ), - SizedBox( - height: 12, - ), - ], + ), ), - ), + ], ), ), ), bottomSheet: Container( - height: MediaQuery.of(context).size.height * 0.1, + color: Theme.of(context).scaffoldBackgroundColor, width: double.infinity, padding: EdgeInsets.all(9), - child: SecondaryButton( - textColor: Colors.white, - label: "Submit", - onTap: () async { - this - .widget - .createEReferralRequestModel - .medicalReportAttachment = medicalReportImages; - 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 = - 15; - this.widget.createEReferralRequestModel.preferredBranchName = - "Arryan Hospital"; - - // this.widget.createEReferralRequestModel.fullName= ""; - this.widget.createEReferralRequestModel.otherRelationship = - ""; - // this.widget.createEReferralRequestModel.; - // this.widget.createEReferralRequestModel. preferredBranchName= "Arryan Hospital"; - // this.widget.createEReferralRequestModel. preferredBranchName= "Arryan Hospital"; - - await model - .createEReferral(this.widget.createEReferralRequestModel); - }, - loading: model.state == ViewState.BusyLocal, - disabled: medicalReportImages.length == 0, + child: DefaultButton( + TranslationBase.of(context).submit, + medicalReportImages.length == 0 + ? null + : () async { + Future.delayed(new Duration(milliseconds: 300)).then((value) async { + GifLoaderDialogUtils.showMyDialog(context); + this.widget.createEReferralRequestModel.medicalReportAttachment = medicalReportImages; + 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 = projectDropdownValue != null && projectDropdownValue!.isNotEmpty ? int.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); + showCMCConfirmDialog( + context, + model.referralNumber, + onClick: () { + Navigator.pop(context); + }, + ); + } + }); + }, + disabledColor: Colors.grey, + color: Color(0xff359846), ), + + // SecondaryButton( + // textColor: Colors.white, + // label: "Submit", + // onTap: () async { + // this + // .widget + // .createEReferralRequestModel + // .medicalReportAttachment = medicalReportImages; + // 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 = + // 15; + // this.widget.createEReferralRequestModel.preferredBranchName = + // "Arryan Hospital"; + // this.widget.createEReferralRequestModel.otherRelationship = + // ""; + // + // await model + // .createEReferral(this.widget.createEReferralRequestModel); + // if(model.state == ViewState.ErrorLocal) { + // Utils.showErrorToast(model.error); + // } else{ + // AppToast.showSuccessToast(message: "Referral sent successfully"); + // } + // }, + // loading: model.state == ViewState.BusyLocal, + // disabled: medicalReportImages.length == 0, + // ), ))); } + void getAllProjects() { + int languageID = Provider.of(context, listen: false).isArabic ? 1 : 2; + ClinicListService service = new ClinicListService(); + List projectsListLocal = []; + service.getProjectsList(languageID, context).then((res) { + if (res['MessageStatus'] == 1) { + setState(() { + res['ListProject'].forEach((v) { + projectsListLocal.add(new HospitalsModel.fromJson(v)); + }); + projectsList = projectsListLocal; + }); + // isProjectLoaded = true; + } else { + // isProjectLoaded = false; + } + }).catchError((err) { + print(err); + }); + } + void confirmSelectCityDialog(List cities) { showDialog( context: context, - child: SelectCityDialog( + builder: (cxt) => SelectCityDialog( cities: cities, selectedCity: _selectedCity, onValueSelected: (value) { @@ -443,7 +475,7 @@ class _NewEReferralStepThreePageState extends State { String getRelationName() { if (_selectedCity != null) - return _selectedCity.description; + return _selectedCity.description!; else return "Select Relationship" /*TranslationBase.of(context).selectHospital*/; } 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 5f85fe12..daf11a8f 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 @@ -7,23 +7,25 @@ import 'package:diplomaticquarterapp/models/FamilyFiles/GetAllSharedRecordByStat import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/E-Referral/dialogs/select_country_ingo_Dialog.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/medical/balance/new_text_Field.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; -import 'package:diplomaticquarterapp/widgets/bottom_options/BottomSheet.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/mobile-no/mobile_no.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'; - class NewEReferralStepTowPage extends StatefulWidget { final CreateEReferralRequestModel createEReferralRequestModel; final Function changePageViewIndex; - const NewEReferralStepTowPage({Key key, this.createEReferralRequestModel, this.changePageViewIndex}) : super(key: key); + const NewEReferralStepTowPage({Key? key, required this.createEReferralRequestModel, required this.changePageViewIndex}) : super(key: key); @override _NewEReferralStepTowPageState createState() => _NewEReferralStepTowPageState(); @@ -32,22 +34,16 @@ class NewEReferralStepTowPage extends StatefulWidget { class _NewEReferralStepTowPageState extends State { TextEditingController _patientNameTextController = TextEditingController(); TextEditingController _patientIdentificationTextController = TextEditingController(); - TextEditingController _mobileTextController = TextEditingController(); - GetAllCitiesResponseModel _selectedCity ; - GetAllSharedRecordsByStatusList selectedPatientFamily; + String mobileNo = ""; + GetAllCitiesResponseModel _selectedCity =GetAllCitiesResponseModel(); + + late GetAllSharedRecordsByStatusList selectedPatientFamily; // todo create a model for Country // todo use country from the json - dynamic _selectedCountry = { - "name": "Saudi Arabia", - "name_ar": "المملكة العربية السعودية", - "code": "+966", - "countryCode": "SA", - "pattern": "5xxxxxxxx", - "maxLength": 9 - }; + dynamic _selectedCountry = {"name": "Saudi Arabia", "name_ar": "المملكة العربية السعودية", "code": "966", "countryCode": "SA", "pattern": "5xxxxxxxx", "maxLength": 9}; AppSharedPreferences sharedPref = AppSharedPreferences(); - AuthenticatedUser authUser; + late AuthenticatedUser authUser; @override void initState() { @@ -57,155 +53,224 @@ class _NewEReferralStepTowPageState extends State { @override Widget build(BuildContext context) { return BaseView( - onModelReady: (model) => model.getAllCities(), - builder: (_, model, widget) => AppScaffold( - isShowAppBar: false, - 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: 30, - ), - Center( - child: Texts( -// TranslationBase.of(context).advancePaymentLabel, - "Patient information", - textAlign: TextAlign.center, - ), - ), - SizedBox( - height: 12, + onModelReady: (model) => model.getAllCities(), + builder: (_, model, widget) => AppScaffold( + isShowAppBar: false, + backgroundColor: CustomColors.appBackgroudGrey2Color, + body: Column( + children: [ + Expanded( + child: SingleChildScrollView( + physics: ScrollPhysics(), + child: Container( + margin: EdgeInsets.all(12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: 20, + ), + Text( + TranslationBase.of(context).patientInfo, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.64, ), - NewTextFields( - hintText: "Enter Identification Number", - controller: _patientIdentificationTextController, - keyboardType:TextInputType.number , + ), + SizedBox( + height: 12, + ), + inputWidget(TranslationBase.of(context).enterIdentificationNumber, "", _patientIdentificationTextController, isInputTypeNum: true), + SizedBox( + height: 12, + ), + inputWidget(TranslationBase.of(context).patientName, "", _patientNameTextController, isInputTypeNum: false), + SizedBox( + height: 12, + ), + PhoneNumberSelectorWidget(onNumberChange: (value) { + setState(() { + mobileNo = value; + }); + }, onCountryChange: (value) { + setState(() { + _selectedCountry = value; + }); + }), + SizedBox( + height: 12, + ), + Text( + TranslationBase.of(context).patientLocated, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.64, ), - SizedBox( - height: 12, - ), - NewTextFields( - hintText: "Enter Patient Name", - controller: _patientNameTextController, - ), - SizedBox( - height: 12, - ), - InkWell( - onTap: () => confirmSelectCountryTypeDialog(), - 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(getCountryName()), - Icon(Icons.arrow_drop_down) - ], - ), + ), + SizedBox( + height: 12, + ), + 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, ), ), - SizedBox( - height: 12, - ), - MobileNumberTextFiled( - controller: _mobileTextController, - code: _selectedCountry == null - ? "11" - : _selectedCountry["code"], - ), - SizedBox( - height: 12, - ), - Center( - child: Texts( -// TranslationBase.of(context).advancePaymentLabel, - "Where the patient located", - textAlign: TextAlign.center, + child: InkWell( + onTap: () => confirmSelectCityDialog(model.allCities), + child: Row( + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).selectCity, + style: TextStyle( + fontSize: 11, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.44, + ), + ), + Text( + getRelationName(), + style: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: Color(0xff2B353E), + letterSpacing: -0.44, + ), + ), + ], + ), + ), + Icon(Icons.arrow_drop_down), + ], ), ), - SizedBox( - height: 12, - ), - InkWell( - onTap: () => confirmSelectCityDialog( - model.allCities), - 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(getRelationName()), - Icon(Icons.arrow_drop_down) - ], - ), - ), - ), - SizedBox( - height: 12, - ), - - SizedBox( - height: 12, - ), - ], - ), + ), + SizedBox( + height: 12, + ), + ], ), ), ), ), - bottomSheet: Container( - height: MediaQuery - .of(context) - .size - .height * 0.1, - width: double.infinity, - padding: EdgeInsets.all(9), - child: SecondaryButton( - textColor: Colors.white, - label: "Next", - onTap: () async { - 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)+_mobileTextController.text; - this.widget.createEReferralRequestModel.cityCode = _selectedCity.iD.toString(); - this.widget.createEReferralRequestModel.cityName = _selectedCity.description; - - - }, - loading: model.state == ViewState.BusyLocal, - disabled: - _patientNameTextController.text.isEmpty || _patientIdentificationTextController.text.isEmpty|| - _selectedCity == null || - _mobileTextController.text.isEmpty, + Container( + margin: EdgeInsets.zero, + decoration: cardRadius(0), + child: Container( + width: double.infinity, + padding: EdgeInsets.all(12), + child: DefaultButton( + TranslationBase.of(context).next, + (_patientNameTextController.text.isEmpty || _patientIdentificationTextController.text.isEmpty || _selectedCity == null || mobileNo.isEmpty) + ? null + : () { + 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() + mobileNo; + this.widget.createEReferralRequestModel.cityCode = _selectedCity.iD.toString(); + this.widget.createEReferralRequestModel.cityName = _selectedCity.description; + }, + disabledColor: Colors.grey, + ), ), - ))); - + ) + ], + ), + ), + ); + } + 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), + ], + ), + ), + ); } - void confirmSelectCityDialog( - List cities) { + void confirmSelectCityDialog(List cities) { showDialog( context: context, - child: SelectCityDialog( + builder: (cxt) => SelectCityDialog( cities: cities, selectedCity: _selectedCity, onValueSelected: (value) { @@ -220,7 +285,7 @@ class _NewEReferralStepTowPageState extends State { void confirmSelectCountryTypeDialog() { showDialog( context: context, - child: SelectCountryDialog( + builder: (cxt) => SelectCountryDialog( selectedCountry: _selectedCountry, onValueSelected: (value) { setState(() { @@ -232,10 +297,10 @@ class _NewEReferralStepTowPageState extends State { } String getRelationName() { - if (_selectedCity != null) - return _selectedCity.description; + if (_selectedCity?.description != null) + return _selectedCity.description!; else - return "Select City" /*TranslationBase.of(context).selectHospital*/; + return TranslationBase.of(context).selectCity /*TranslationBase.of(context).selectHospital*/; } String getCountryName() { @@ -247,12 +312,7 @@ class _NewEReferralStepTowPageState extends State { } class MobileNumberTextFiled extends StatelessWidget { - const MobileNumberTextFiled({ - Key key, - this.controller, - this.code - }) : super(key: key); - + const MobileNumberTextFiled({Key? key, required this.controller, required this.code}) : super(key: key); final TextEditingController controller; final String code; @@ -261,8 +321,7 @@ class MobileNumberTextFiled extends StatelessWidget { Widget build(BuildContext context) { return Container( padding: EdgeInsets.all(5), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(15), color: Colors.white), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(15), color: Colors.white), child: Row(children: [ Expanded( flex: 1, @@ -283,8 +342,7 @@ class MobileNumberTextFiled extends StatelessWidget { child: TextField( controller: controller, keyboardType: TextInputType.phone, - decoration: InputDecoration( - border: InputBorder.none, hintText: 'Mobile No'), + decoration: InputDecoration(border: InputBorder.none, hintText: TranslationBase.of(context).mobileNumber), ), ), ) diff --git a/lib/pages/AlHabibMedicalService/E-Referral/dialogs/select_city_dialog.dart b/lib/pages/AlHabibMedicalService/E-Referral/dialogs/select_city_dialog.dart index 2fb7e41a..e07f01bf 100644 --- a/lib/pages/AlHabibMedicalService/E-Referral/dialogs/select_city_dialog.dart +++ b/lib/pages/AlHabibMedicalService/E-Referral/dialogs/select_city_dialog.dart @@ -10,8 +10,7 @@ class SelectCityDialog extends StatefulWidget { final Function(GetAllCitiesResponseModel) onValueSelected; GetAllCitiesResponseModel selectedCity; - SelectCityDialog( - {Key key, this.cities, this.onValueSelected, this.selectedCity}); + SelectCityDialog({Key? key, required this.cities, required this.onValueSelected, required this.selectedCity}); @override _SelectCityDialogState createState() => _SelectCityDialogState(); @@ -26,104 +25,109 @@ class _SelectCityDialogState extends State { @override Widget build(BuildContext context) { - return SimpleDialog( - children: [ - Column( - children: [ - Divider(), - ...List.generate( - widget.cities.length, - (index) => Column( - crossAxisAlignment: CrossAxisAlignment.start, + return Dialog( + child: Column( + children: [ + Expanded( + child: SingleChildScrollView( + child: Column( children: [ - SizedBox( - height: 2, - ), - Row( - children: [ - Expanded( - flex: 1, - child: InkWell( - onTap: () { - setState(() { - widget.selectedCity = widget.cities[index]; - }); - }, - child: ListTile( - title: Text(widget.cities[index].description), - leading: Radio( - value: widget.cities[index], - groupValue: widget.selectedCity, - activeColor: Colors.red[800], - onChanged: (value) { - setState(() { - widget.selectedCity = value; - }); - }, - ), - ), + ...List.generate( + widget.cities.length, + (index) => Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: 2, ), - ) - ], - ), - SizedBox( - height: 5.0, + Row( + children: [ + Expanded( + flex: 1, + child: InkWell( + onTap: () { + setState(() { + widget.selectedCity = widget.cities[index]; + }); + }, + child: ListTile( + title: Text(widget.cities[index].description!), + leading: Radio( + value: widget.cities[index], + groupValue: widget.selectedCity, + activeColor: Colors.red[800], + onChanged: (value) { + setState(() { + widget.selectedCity = 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, - ), + ), + 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.selectedCity); - Navigator.pop(context); - }, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Center( - child: Texts( - TranslationBase.of(context).ok, - fontWeight: FontWeight.w400, - )), - ), + ), + Container( + width: 1, + height: 30, + color: Colors.grey[500], + ), + Expanded( + flex: 1, + child: InkWell( + onTap: () { + widget.onValueSelected(widget.selectedCity); + 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/dialogs/select_country_ingo_Dialog.dart b/lib/pages/AlHabibMedicalService/E-Referral/dialogs/select_country_ingo_Dialog.dart index d58fd29f..e1db9d5c 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,12 +4,14 @@ 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; SelectCountryDialog( - {Key key, /*this.relationTypes,*/ this.onValueSelected, this.selectedCountry}); + {Key? key, /*this.relationTypes,*/ required this.onValueSelected, this.selectedCountry}); @override _SelectCountryDialogState createState() => _SelectCountryDialogState(); diff --git a/lib/pages/AlHabibMedicalService/E-Referral/dialogs/select_relation_type_dialog.dart b/lib/pages/AlHabibMedicalService/E-Referral/dialogs/select_relation_type_dialog.dart index e8d4bb7d..d5323f4c 100644 --- a/lib/pages/AlHabibMedicalService/E-Referral/dialogs/select_relation_type_dialog.dart +++ b/lib/pages/AlHabibMedicalService/E-Referral/dialogs/select_relation_type_dialog.dart @@ -11,7 +11,7 @@ class SelectRelationTypeDialog extends StatefulWidget { GetAllRelationshipTypeResponseModel selectedRelation; SelectRelationTypeDialog( - {Key key, this.relationTypes, this.onValueSelected, this.selectedRelation}); + {Key? key, required this.relationTypes, required this.onValueSelected, required this.selectedRelation}); @override _SelectRelationTypeDialogState createState() => _SelectRelationTypeDialogState(); @@ -50,14 +50,14 @@ class _SelectRelationTypeDialogState extends State { }); }, child: ListTile( - title: Text(widget.relationTypes[index].text), + title: Text(widget.relationTypes[index].text!), leading: Radio( value: widget.relationTypes[index], groupValue: widget.selectedRelation, activeColor: Colors.red[800], onChanged: (value) { setState(() { - widget.selectedRelation = value; + widget.selectedRelation = value!; }); }, ), 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 f4c8d989..00000000 --- a/lib/pages/AlHabibMedicalService/E-Referral/dialogs/select_search_criteria_dialog.dart +++ /dev/null @@ -1,137 +0,0 @@ -import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/EReferral/search_criteria_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; - - SelectSearchCriteriaDialog( - {Key key, this.onValueSelected, this.selectedCriteria}); - - @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: [ - Texts(" Select Search Criteria", fontSize: 20,), - 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.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/e_referral_confirm_sms_dialog.dart b/lib/pages/AlHabibMedicalService/E-Referral/e_referral_confirm_sms_dialog.dart index ba9a123d..3b5d585e 100644 --- a/lib/pages/AlHabibMedicalService/E-Referral/e_referral_confirm_sms_dialog.dart +++ b/lib/pages/AlHabibMedicalService/E-Referral/e_referral_confirm_sms_dialog.dart @@ -6,6 +6,7 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/EReferral/check_activation_code_for_e_referral_request_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/all_habib_medical_services/e_referral_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; @@ -20,9 +21,9 @@ class EReferralConfirmSMSDialog extends StatefulWidget { // final String selectedPaymentMethod; const EReferralConfirmSMSDialog( - {Key key, - this.phoneNumber, - this.onSucces + {Key? key, + required this.phoneNumber, + required this.onSucces // this.advanceModel, // this.selectedPaymentMethod, // this.patientInfoAndMobileNumber @@ -50,7 +51,7 @@ class _EReferralConfirmSMSDialogState extends State { String timerText = (TIMER_MIN - 1).toString() + ':59'; int min = TIMER_MIN - 1; int sec = 59; - Timer _timer; + late Timer _timer; resendCode() { min = TIMER_MIN - 1; @@ -75,10 +76,10 @@ class _EReferralConfirmSMSDialogState extends State { }); } - FocusNode focusD1; - FocusNode focusD2; - FocusNode focusD3; - FocusNode focusD4; + late FocusNode focusD1; + late FocusNode focusD2; + late FocusNode focusD3; + late FocusNode focusD4; @override void initState() { @@ -158,7 +159,7 @@ class _EReferralConfirmSMSDialogState extends State { Form( key: verifyAccountForm, child: Container( - width: SizeConfig.realScreenWidth * 0.90, + width: SizeConfig.realScreenWidth! * 0.90, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -173,7 +174,7 @@ class _EReferralConfirmSMSDialogState extends State { child: TextFormField( textInputAction: TextInputAction.next, style: TextStyle( - fontSize: SizeConfig.textMultiplier * 3, + fontSize: SizeConfig.textMultiplier! * 3, ), focusNode: focusD1, maxLength: 1, @@ -204,7 +205,7 @@ class _EReferralConfirmSMSDialogState extends State { maxLength: 1, textAlign: TextAlign.center, style: TextStyle( - fontSize: SizeConfig.textMultiplier * 3, + fontSize: SizeConfig.textMultiplier! * 3, ), keyboardType: TextInputType.number, decoration: buildInputDecoration(context), @@ -231,7 +232,7 @@ class _EReferralConfirmSMSDialogState extends State { maxLength: 1, textAlign: TextAlign.center, style: TextStyle( - fontSize: SizeConfig.textMultiplier * 3, + fontSize: SizeConfig.textMultiplier! * 3, ), keyboardType: TextInputType.number, decoration: buildInputDecoration(context), @@ -257,7 +258,7 @@ class _EReferralConfirmSMSDialogState extends State { maxLength: 1, textAlign: TextAlign.center, style: TextStyle( - fontSize: SizeConfig.textMultiplier * 3, + fontSize: SizeConfig.textMultiplier! * 3, ), keyboardType: TextInputType.number, decoration: buildInputDecoration(context), @@ -330,11 +331,9 @@ class _EReferralConfirmSMSDialogState extends State { } void submit(EReferralViewModel model) async { - if (verifyAccountForm.currentState.validate()) { + if (verifyAccountForm.currentState!.validate()) { final activationCode = digit1.text + digit2.text + digit3.text + digit4.text; - - // ToDo call service CheckActivationCodeForEReferralResponseModel checkActivationCodeForEReferralRequestModel= new CheckActivationCodeForEReferralResponseModel(activationCode: activationCode); await model.checkActivationCodeForEReferral(checkActivationCodeForEReferralRequestModel); @@ -348,7 +347,7 @@ class _EReferralConfirmSMSDialogState extends State { } } - String validateCodeDigit(value) { + String? validateCodeDigit(value) { if (value.isEmpty) { return ''; } @@ -369,11 +368,11 @@ class _EReferralConfirmSMSDialogState extends State { ), errorBorder: OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(5.0)), - borderSide: BorderSide(color: Theme.of(context).errorColor), + borderSide: BorderSide(color: CustomColors.accentColor), ), focusedErrorBorder: OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(5.0)), - borderSide: BorderSide(color: Theme.of(context).errorColor), + borderSide: BorderSide(color: CustomColors.accentColor), ), ); } diff --git a/lib/pages/AlHabibMedicalService/E-Referral/e_referral_page.dart b/lib/pages/AlHabibMedicalService/E-Referral/e_referral_page.dart index 590d1cf1..f216c5ea 100644 --- a/lib/pages/AlHabibMedicalService/E-Referral/e_referral_page.dart +++ b/lib/pages/AlHabibMedicalService/E-Referral/e_referral_page.dart @@ -2,18 +2,16 @@ import 'dart:ui'; import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; import 'package:diplomaticquarterapp/core/viewModels/all_habib_medical_services/e_referral_view_model.dart'; -import 'package:diplomaticquarterapp/core/viewModels/medical/prescriptions_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/E-Referral/New_E_Referral/new_e_referral_index_page.dart'; -import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/E-Referral/New_E_Referral/new_e_referral_step_one_page.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/E-Referral/search_for_referrals_page.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; -import 'package:diplomaticquarterapp/pages/medical/prescriptions/prescriptions_history_page.dart'; -import 'package:diplomaticquarterapp/pages/medical/prescriptions/prescriptions_page.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:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; class EReferralPage extends StatefulWidget { @override @@ -22,7 +20,7 @@ class EReferralPage extends StatefulWidget { class _EReferralPageState extends State with SingleTickerProviderStateMixin { - TabController _tabController; + late TabController _tabController; @override void initState() { @@ -38,98 +36,63 @@ class _EReferralPageState extends State @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); return BaseView( - builder: (_, model, widget) => - AppScaffold( - isShowAppBar: true, - appBarTitle: "E-Referral", - description: "This service allows you to submit a Referral request from any health care providers either inside or outside the kingdom of Saudi Arabia to any of HMG Hospitals, By filling some of the patient's data and attaching the medical reports, moreover you can track the request status (Under process, Accepted or Rejected)", - imagesInfo: [ - ImagesInfo( - imageAr: 'assets/images/Wifi-AR.png', - imageEn: 'assets/images/wifi-EN.png', - isAsset: true) - ], - body: Scaffold( - extendBodyBehindAppBar: true, - appBar: PreferredSize( - preferredSize: Size.fromHeight(65.0), - child: Stack( - children: [ - Positioned( - bottom: 1, - left: 0, - right: 0, - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10), - child: Container( - color: Theme.of(context) - .scaffoldBackgroundColor - .withOpacity(0.8), - height: 70.0, - ), - ), - ), - Center( - child: Container( - height: 60.0, - margin: EdgeInsets.only(top: 10.0), - width: MediaQuery.of(context).size.width * 0.9, - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Theme.of(context).dividerColor, - width: 0.7), - ), - color: Colors.white), - child: Center( - child: TabBar( - isScrollable: true, - controller: _tabController, - indicatorWeight: 5.0, - indicatorSize: TabBarIndicatorSize.tab, - indicatorColor: Colors.red[800], - labelColor: Theme.of(context).primaryColor, - labelPadding: - EdgeInsets.only(top: 4.0, left: 18.0, right: 18.0), - unselectedLabelColor: Colors.grey[800], - tabs: [ - Container( - width: MediaQuery.of(context).size.width * 0.37, - child: Center( - child: Texts("New Referral"), - ), - ), - Container( - width: MediaQuery.of(context).size.width * 0.37, - child: Center( - child: Texts("Search for Referrals"), - ), - ), - ], - ), - ), - ), - ), + onModelReady: (model) => model.getAllCities(), + builder: (_, model, widget) => AppScaffold( + isShowAppBar: true, + showNewAppBar: true, + showNewAppBarTitle: true, + appBarTitle: TranslationBase.of(context).ereferral, + description: TranslationBase.of(context).eReferralInfo, + imagesInfo: [ + ImagesInfo( + imageAr: + 'https://hmgwebservices.com/Images/MobileApp/images-info-home/referal/ar/1.png', + imageEn: + 'https://hmgwebservices.com/Images/MobileApp/images-info-home/referal/en/1.png', + ) + ], + body: Column( + children: [ + TabBar( + isScrollable: false, + controller: _tabController, + indicatorWeight: 3.0, + indicatorSize: TabBarIndicatorSize.tab, + labelColor: Color(0xff2B353E), + unselectedLabelColor: Color(0xff575757), + labelPadding: + EdgeInsets.only(top: 15, bottom: 13, 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: [ + Text(TranslationBase.of(context).newReferral), + Text(TranslationBase.of(context).searchForReferrals), ], ), - ), - body: Column( - children: [ - Expanded( - child: TabBarView( - physics: BouncingScrollPhysics(), - controller: _tabController, - children: [ - StartIndexForNewEReferral( - ), - SearchForReferralsPage( - ) - ], - ), - ) - ], - ), + Expanded( + child: TabBarView( + physics: BouncingScrollPhysics(), + + controller: _tabController, + children: [ + StartIndexForNewEReferral(), + SearchForReferralsPage() + ], + ), + ) + ], ), ), ); diff --git a/lib/pages/AlHabibMedicalService/E-Referral/referral_details.dart b/lib/pages/AlHabibMedicalService/E-Referral/referral_details.dart new file mode 100644 index 00000000..d92ff50b --- /dev/null +++ b/lib/pages/AlHabibMedicalService/E-Referral/referral_details.dart @@ -0,0 +1,138 @@ +import 'package:diplomaticquarterapp/Constants.dart'; +import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/EReferral/search_e_referral_response_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.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/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class ReferralDetails extends StatefulWidget { + final SearchEReferralResponseModel referral; + + const ReferralDetails({Key? key, required this.referral}) : super(key: key); + + @override + _ReferralDetailsState createState() => _ReferralDetailsState(); +} + +class _ReferralDetailsState extends State { + @override + Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + return AppScaffold( + isShowAppBar: true, + showNewAppBar: true, + showNewAppBarTitle: true, + appBarTitle: TranslationBase.of(context).ereferral, + body: Column( + children: [ + Container( + width: double.infinity, + child: Container( + decoration: cardRadius(12), + margin: EdgeInsets.only(left: 16, top: 8, right: 16, bottom: 16), + child: Padding( + padding: const EdgeInsets.all(15.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + 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)), + ), + Container( + width: double.infinity, + padding: EdgeInsets.only(top: 10, bottom: 5), + child: Row( + children: [ + Expanded( + child: _getNormalText(TranslationBase.of(context).referralStatus), + ), + Expanded( + child: _getNormalText(projectViewModel.isArabic ? widget.referral.statusAr : widget.referral.status, isBold: true), + ) + ], + ), + ), + mDivider(dividerColor!), + Container( + width: double.infinity, + padding: EdgeInsets.only(top: 10, bottom: 5), + child: Row( + children: [ + Expanded( + child: _getNormalText(TranslationBase.of(context).patientName), + ), + Expanded( + child: _getNormalText(widget.referral.patientName, isBold: true), + ) + ], + ), + ), + mDivider(dividerColor!), + Container( + width: double.infinity, + padding: EdgeInsets.only(top: 10, bottom: 5), + child: Row( + children: [ + Expanded( + child: _getNormalText(TranslationBase.of(context).referralNumber), + ), + Expanded( + child: _getNormalText(widget.referral.referralNumber.toString(), isBold: true), + ) + ], + ), + ), + mDivider(dividerColor!), + Container( + width: double.infinity, + padding: EdgeInsets.only(top: 10, bottom: 5), + child: Row( + children: [ + Expanded( + child: _getNormalText(TranslationBase.of(context).referralDate), + ), + Expanded( + child: _getNormalText(DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDateNoTimeZone(widget.referral.referralDate!)), isBold: true), + ) + ], + ), + ), + mDivider(dividerColor!), + Container( + width: double.infinity, + padding: EdgeInsets.only(top: 10, bottom: 5), + child: Row( + children: [ + Expanded( + child: _getNormalText(TranslationBase.of(context).hospital), + ), + Expanded( + child: _getNormalText(widget.referral.preferredBranchName ?? "", isBold: true), + ) + ], + ), + ), + ], + ), + ), + )), + ], + )); + } + + _getNormalText(text, {bool isBold = false}) { + return Text( + text, + style: TextStyle( + fontSize: isBold ? 14 : 12, + letterSpacing: -0.5, + color: isBold ? Colors.black : Colors.grey[700], + fontWeight: FontWeight.w600, + ), + ); + } +} 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 0b75705d..106dc6e0 100644 --- a/lib/pages/AlHabibMedicalService/E-Referral/search_for_referrals_page.dart +++ b/lib/pages/AlHabibMedicalService/E-Referral/search_for_referrals_page.dart @@ -2,22 +2,30 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/EReferral/search_criteria_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/EReferral/search_e_referral_request_model.dart'; 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/pages/medical/balance/new_text_Field.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.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/dialogs/radio_selection_dialog.dart'; import 'package:diplomaticquarterapp/widgets/errors/app_embedded_error.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'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; -import 'New_E_Referral/new_e_referral_step_one_page.dart'; import 'dialogs/select_country_ingo_Dialog.dart'; -import 'dialogs/select_search_criteria_dialog.dart'; class SearchForReferralsPage extends StatefulWidget { - SearchForReferralsPage({Key key}); + SearchForReferralsPage({Key? key}); @override _SearchForReferralsPageState createState() => _SearchForReferralsPageState(); @@ -26,162 +34,194 @@ class SearchForReferralsPage extends StatefulWidget { class _SearchForReferralsPageState extends State { TextEditingController _searchTextController = TextEditingController(); - TextEditingController _mobileTextController = TextEditingController(); + String mobileNo = ""; bool _isSubmitted = false; - dynamic _selectedCountry = { - "name": "Saudi Arabia", - "name_ar": "المملكة العربية السعودية", - "code": "+966", - "countryCode": "SA", - "pattern": "5xxxxxxxx", - "maxLength": 9 - }; + dynamic _selectedCountry = {"name": "Saudi Arabia", "name_ar": "المملكة العربية السعودية", "code": "966", "countryCode": "SA", "pattern": "5xxxxxxxx", "maxLength": 9}; - SearchCriteriaModel selectedCriteria = SearchCriteriaModel( - name: "Identification Number", nameAr: "رقم المحول", value: 1); + SearchCriteriaModel selectedCriteria = SearchCriteriaModel(name: "Identification Number", nameAr: "رقم الهوية", value: 1); @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); return BaseView( - onModelReady: (model) => model.getAllCities(), + onModelReady: (model) async { + if (projectViewModel.isLogin) { + Future.delayed(new Duration(milliseconds: 300)).then((value) async { + GifLoaderDialogUtils.showMyDialog(context); + SearchEReferralRequestModel searchEReferralRequestModel = new SearchEReferralRequestModel( + patientMobileNumber: (projectViewModel.user!.outSA == 0 ? "966" : "971") + projectViewModel.user!.mobileNumber!.substring(1, projectViewModel.user!.mobileNumber!.length), + ); + if (selectedCriteria.value == 1) { + searchEReferralRequestModel.identificationNo = _searchTextController.text; + searchEReferralRequestModel.referralNumber = 0; + } else { + searchEReferralRequestModel.referralNumber = int.parse(_searchTextController.text); + searchEReferralRequestModel.identificationNo = projectViewModel.user!.patientIdentificationNo; + } + await model.getEReferrals(searchEReferralRequestModel); + GifLoaderDialogUtils.hideDialog(context); + }); + } + }, builder: (_, model, widget) => AppScaffold( isShowAppBar: false, + baseViewModel: model, body: SingleChildScrollView( physics: ScrollPhysics(), child: Container( margin: EdgeInsets.all(12), child: Center( - child: FractionallySizedBox( - widthFactor: 0.94, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 77, - ), - 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) - ], - ), - ), - ), - SizedBox( - height: 12, - ), - NewTextFields( - hintText: selectedCriteria.value == 1 - ? "Enter Patient Identification No" - : "Enter Referral Number", - controller: _searchTextController, - ), - SizedBox( - height: 12, - ), - InkWell( - onTap: () => confirmSelectCountryTypeDialog(), - 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(getCountryName()), - Icon(Icons.arrow_drop_down) - ], - ), - ), - ), - SizedBox( - height: 12, - ), - MobileNumberTextFiled( - controller: _mobileTextController, - code: _selectedCountry == null - ? "11" - : _selectedCountry["code"], - ), - SizedBox( - height: 12, - ), - if ((model.state == ViewState.Idle && - model.allReferral.length == 0)) - Text("There's No Referral To deliver"), - if (( - model.state == ViewState.ErrorLocal)) - AppEmbeddedError( error:model.error), - NetworkBaseView( - baseViewModel: model, - child: ListView.builder( - shrinkWrap: true, - scrollDirection: Axis.vertical, - itemCount: model.allReferral == null - ? 0 - : model.allReferral.length < 3 - ? model.allReferral.length - : 3, - itemBuilder: (BuildContext context, int index) { - return Padding( - padding: EdgeInsets.symmetric(horizontal: 0.2), - child: Container( - child: Texts("TODO add referral info"), - ), - ); + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: 10, + ), + 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, + builder: (cxt) => RadioSelectionDialog( + listData: list, + selectedIndex: selectedCriteria.value, + onValueSelected: (index) { + selectedCriteria = searchCriteria[index - 1]; + setState(() {}); }, ), - ), - ], - ), + ); + }).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; + }); + }, onCountryChange: (value) { + setState(() { + _selectedCountry = value; + }); + }), + // InkWell( + // onTap: () => confirmSelectCountryTypeDialog(), + // 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(getCountryName()), Icon(Icons.arrow_drop_down)], + // ), + // ), + // ), + // SizedBox( + // height: 12, + // ), + // MobileNumberTextFiled( + // controller: _mobileTextController, + // onChange: (_) { + // setState(() {}); + // }, + // code: _selectedCountry == null ? "11" : _selectedCountry["code"], + // ), + 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 + ? NetworkBaseView( + baseViewModel: model, + child: ListView.separated( + separatorBuilder: (context, index) => SizedBox(height: 0), + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + itemCount: model.allReferral == null ? 0 : model.allReferral.length, + itemBuilder: (BuildContext context, int index) { + return Container( + width: double.infinity, + child: InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: ReferralDetails(referral: model.allReferral[index]), + ), + ); + }, + child: Container( + decoration: cardRadius(12), + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(projectViewModel.isArabic ? model.allReferral[index].statusAr! : model.allReferral[index].status!, + style: TextStyle(fontSize: 14.0, letterSpacing: -0.56, fontWeight: FontWeight.bold)), + Container( + margin: EdgeInsets.only(top: 5.0), + child: MyRichText(TranslationBase.of(context).patientName + ": ", model.allReferral[index].patientName!, projectViewModel.isArabic)), + MyRichText(TranslationBase.of(context).hospital + ": ", model.allReferral[index].preferredBranchName!, projectViewModel.isArabic), + MyRichText(TranslationBase.of(context).referralDate + ": ", + DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDateNoTimeZone(model.allReferral[index].referralDate!)), projectViewModel.isArabic), + ], + ), + Icon(projectViewModel.isArabic ? Icons.arrow_back_ios_outlined : Icons.arrow_forward_outlined), + ], + ), + ), + ), + ), + ); + }, + ), + ) + : Container(), + SizedBox( + height: 80.0, + ) + ], ), ), ), ), bottomSheet: Container( - height: MediaQuery.of(context).size.height * 0.1, + color: Theme.of(context).scaffoldBackgroundColor, width: double.infinity, - padding: EdgeInsets.all(9), - child: SecondaryButton( - textColor: Colors.white, - label: "Search", - onTap: () async { - SearchEReferralRequestModel searchEReferralRequestModel = - new SearchEReferralRequestModel( - patientMobileNumber: - _selectedCountry['code'] + _mobileTextController.text, - ); - if (selectedCriteria.value == 1) { - searchEReferralRequestModel.identificationNo = - _searchTextController.text; - searchEReferralRequestModel.referralNumber = 0; - } else { - searchEReferralRequestModel.referralNumber = - int.parse(_searchTextController.text); - searchEReferralRequestModel.identificationNo = ''; - } - await model.getEReferrals(searchEReferralRequestModel); - setState(() { - _isSubmitted = true; - }); - }, - loading: model.state == ViewState.BusyLocal, - disabled: _searchTextController.text.isEmpty || - _mobileTextController.text.isEmpty, + padding: EdgeInsets.all(14), + child: DefaultButton( + TranslationBase.of(context).search, + (_searchTextController.text.isEmpty || mobileNo.isEmpty) + ? null + : () async { + SearchEReferralRequestModel searchEReferralRequestModel = new SearchEReferralRequestModel( + patientMobileNumber: _selectedCountry['code'] + mobileNo, + ); + if (selectedCriteria.value == 1) { + searchEReferralRequestModel.identificationNo = _searchTextController.text; + searchEReferralRequestModel.referralNumber = 0; + } else { + searchEReferralRequestModel.referralNumber = int.parse(_searchTextController.text); + searchEReferralRequestModel.identificationNo = ''; + } + await model.getEReferrals(searchEReferralRequestModel); + setState(() { + _isSubmitted = true; + }); + }, + disabledColor: Colors.grey, ), ))); } @@ -189,7 +229,7 @@ class _SearchForReferralsPageState extends State { void confirmSelectCountryTypeDialog() { showDialog( context: context, - child: SelectCountryDialog( + builder: (cxt) => SelectCountryDialog( selectedCountry: _selectedCountry, onValueSelected: (value) { setState(() { @@ -207,21 +247,68 @@ class _SearchForReferralsPageState extends State { return "Country"; } - void selectSearchCriteriaDialog() { - showDialog( - context: context, - child: SelectSearchCriteriaDialog( - selectedCriteria: selectedCriteria, - 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 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), + ], ), - ); + ).withBorderedContainer; } - String getSearchCriteriaName() { - return selectedCriteria.name; + String getSearchCriteriaName(ProjectViewModel projectViewModel) { + return projectViewModel.isArabic ? selectedCriteria.nameAr! : selectedCriteria.name!; } } diff --git a/lib/pages/AlHabibMedicalService/HomeHealthCare/Dialog/confirm_cancel_order_dialog.dart b/lib/pages/AlHabibMedicalService/HomeHealthCare/Dialog/confirm_cancel_order_dialog.dart index bfab0324..a0de3275 100644 --- a/lib/pages/AlHabibMedicalService/HomeHealthCare/Dialog/confirm_cancel_order_dialog.dart +++ b/lib/pages/AlHabibMedicalService/HomeHealthCare/Dialog/confirm_cancel_order_dialog.dart @@ -7,11 +7,9 @@ import 'package:flutter/material.dart'; // ignore: must_be_immutable class ConfirmCancelOrderDialog extends StatefulWidget { final HomeHealthCareViewModel model; - final Function onTap; + final Function? onTap; - - ConfirmCancelOrderDialog( - {Key key, this.model, this.onTap}); + ConfirmCancelOrderDialog({Key? key, required this.model, this.onTap}); @override _ConfirmCancelOrderDialogState createState() => _ConfirmCancelOrderDialogState(); @@ -26,7 +24,7 @@ class _ConfirmCancelOrderDialogState extends State { @override Widget build(BuildContext context) { return SimpleDialog( - contentPadding: EdgeInsets.fromLTRB(28.0, 24.0, 28.0, 0.0), + contentPadding: EdgeInsets.all(20), title: Center( child: Texts( TranslationBase.of(context).confirm, @@ -37,14 +35,16 @@ class _ConfirmCancelOrderDialogState extends State { Column( children: [ Divider(), + SizedBox( + height: 10.0, + ), Center( child: Texts( - TranslationBase.of(context).cancelOrderMsg , - color: Colors.grey, + TranslationBase.of(context).cancelOrderMsg, ), ), SizedBox( - height: 5.0, + height: 10, ), Row( // mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -76,17 +76,17 @@ class _ConfirmCancelOrderDialogState extends State { Expanded( flex: 1, child: InkWell( - onTap: () async{ - widget.onTap(); + onTap: () async { + widget.onTap!(); Navigator.pop(context); }, child: Padding( padding: const EdgeInsets.all(8.0), child: Center( child: Texts( - TranslationBase.of(context).ok, - fontWeight: FontWeight.w400, - )), + TranslationBase.of(context).ok, + fontWeight: FontWeight.w400, + )), ), ), ), @@ -98,6 +98,3 @@ class _ConfirmCancelOrderDialogState extends State { ); } } - - - diff --git a/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/location_page.dart b/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/location_page.dart index c87a3eb5..1ac2f90d 100644 --- a/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/location_page.dart +++ b/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/location_page.dart @@ -1,148 +1,299 @@ +import 'dart:io'; + 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/viewModels/AlHabibMedicalService/add_new_address_Request_Model.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/home_health_care_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/services/permission/permission_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/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; +import 'package:diplomaticquarterapp/widgets/app_map/google_huawei_map.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_hms_gms_availability/flutter_hms_gms_availability.dart'; +import 'package:geocoding/geocoding.dart'; +import 'package:geolocator/geolocator.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; -import 'package:google_maps_place_picker/google_maps_place_picker.dart'; +import 'package:google_maps_place_picker_mb/google_maps_place_picker.dart'; +import 'package:huawei_hmsavailability/huawei_hmsavailability.dart'; import 'package:provider/provider.dart'; class LocationPage extends StatefulWidget { - final Function(PickResult) onPick; - final double latitude; - final double longitude; + final Function(PickResult)? onPick; + + // final double latitude; + // final double longitude; final dynamic model; - const LocationPage({Key key, this.onPick, this.latitude, this.longitude, this.model}) - : super(key: key); + const LocationPage({Key? key, this.onPick, this.model}) : super(key: key); @override - _LocationPageState createState() => - _LocationPageState(); + _LocationPageState createState() => _LocationPageState(); } -class _LocationPageState - extends State { +class _LocationPageState extends State { double latitude = 0; double longitude = 0; + bool showCurrentLocation = false; + + GoogleMapController? mapController; + + bool isHuawei = false; + + late AppMap appMap; + AppSharedPreferences sharedPref = AppSharedPreferences(); + static CameraPosition _kGooglePlex = CameraPosition( + target: LatLng(37.42796133580664, -122.085749655962), + zoom: 14.4746, + ); + late LatLng currentPostion; + + // Completer mapController = Completer(); + late Placemark selectedPlace; + late HmsApiAvailability hmsApiAvailability; + late ProjectViewModel projectViewModel; @override void initState() { + hmsApiAvailability = HmsApiAvailability(); + if (latitude == 0.0 && longitude == 0.0) { + showCurrentLocation = true; + } + if (Platform.isAndroid) checkIsHuawei(); - latitude = widget.latitude; - longitude = widget.longitude; + WidgetsBinding.instance.addPostFrameCallback((_) { + latitude = projectViewModel.latitude; + longitude = projectViewModel.longitude; + appMap = AppMap( + //Changed By Aamir + _kGooglePlex.toMap() as Map, + onCameraMove: (camera) { + print("Changed By Aamir"); + _updatePosition(camera); + }, + onMapCreated: () { + currentPostion = LatLng(projectViewModel.latitude, projectViewModel.longitude); + latitude = projectViewModel.latitude; + longitude = projectViewModel.longitude; + _getUserLocation(); + setState(() {}); + }, + onCameraIdle: () async { + List placemarks = await placemarkFromCoordinates(latitude, longitude); + selectedPlace = placemarks[0]; + print(selectedPlace); + }, + ); + }); super.initState(); } - @override Widget build(BuildContext context) { - ProjectViewModel projectViewModel = Provider.of(context); + projectViewModel = Provider.of(context); return BaseView( - onModelReady: (model) {}, - builder: (_, model, widget) => AppScaffold( - appBarTitle: TranslationBase.of(context).addAddress, - isShowDecPage: false, - isShowAppBar: true, - baseViewModel: model, - body: PlacePicker( - apiKey: GOOGLE_API_KEY, - enableMyLocationButton: true, - automaticallyImplyAppBarLeading: false, - autocompleteOnTrailingWhitespace: true, - selectInitialPosition: true, - autocompleteLanguage: projectViewModel.currentLanguage, - enableMapTypeButton: true, - searchForInitialValue: false, - onPlacePicked: (PickResult result) { - print(result.adrAddress); - - }, - selectedPlaceWidgetBuilder: - (_, selectedPlace, state, isSearchBarFocused) { - print("state: $state, isSearchBarFocused: $isSearchBarFocused"); - return isSearchBarFocused - ? Container() - : FloatingCard( - bottomPosition: 0.0, - leftPosition: 0.0, - rightPosition: 0.0, - width: 500, - borderRadius: BorderRadius.circular(12.0), - child: state == SearchingState.Searching - ? Center(child: CircularProgressIndicator()) - : Container( - margin: EdgeInsets.all(12), - child: Column( - children: [ - SecondaryButton( - color: Colors.grey[800], - textColor: Colors.white, - onTap: () async { - AddNewAddressRequestModel - addNewAddressRequestModel = - new AddNewAddressRequestModel( - customer: Customer(addresses: [ - Addresses( - address1: - selectedPlace.formattedAddress, - address2: selectedPlace - .formattedAddress, - customerAttributes: "", - city: "", - createdOnUtc: "", - id: 0, - latLong: "$latitude,$longitude", - email: "") - ]), - ); - - selectedPlace.addressComponents.forEach((e) { - if (e.types.contains("country")) { - addNewAddressRequestModel.customer - .addresses[0].country = e.longName; - } - if (e.types.contains("postal_code")) { - addNewAddressRequestModel.customer - .addresses[0].zipPostalCode = - e.longName; - } - if (e.types.contains("locality")) { - addNewAddressRequestModel.customer - .addresses[0].city = - e.longName; - } - }); - - - await model.addAddressInfo( - addNewAddressRequestModel: addNewAddressRequestModel); - if (model.state == ViewState.ErrorLocal) { - Utils.showErrorToast(model.error); - } else { - AppToast.showSuccessToast( - message: "Address Added Successfully"); - } - Navigator.of(context).pop(addNewAddressRequestModel); - }, - label: TranslationBase.of(context).addNewAddress, - ), - ], + onModelReady: (model) {}, + builder: (_, model, widget) => AppScaffold( + appBarTitle: TranslationBase.of(context).addAddress, + isShowDecPage: false, + isShowAppBar: true, + baseViewModel: model, + showNewAppBarTitle: true, + showNewAppBar: true, + body: isHuawei + ? Column( + children: [ + Expanded( + child: Stack( + alignment: Alignment.center, + children: [ + if (appMap != null) appMap, + Container( + margin: EdgeInsets.only(bottom: 50.0), + child: Icon( + Icons.place, + color: CustomColors.accentColor, + size: 50, + ), + ), + ], + ), ), - ), - ); - }, - initialPosition: LatLng(latitude, longitude), - useCurrentLocation: false, - ), - )); + Container( + padding: const EdgeInsets.only(left: 20, right: 20, top: 14, bottom: 14), + child: DefaultButton(TranslationBase.of(context).addNewAddress, () async { + AddNewAddressRequestModel addNewAddressRequestModel = new AddNewAddressRequestModel( + customer: Customer(addresses: [ + Addresses( + address1: selectedPlace.street, + address2: selectedPlace.street, + customerAttributes: "", + city: selectedPlace.administrativeArea, + createdOnUtc: "", + id: "0", + faxNumber: "", + phoneNumber: projectViewModel.user!.mobileNumber, + province: selectedPlace.administrativeArea, + countryId: 69, + latLong: latitude.toStringAsFixed(6) + "," + longitude.toStringAsFixed(6), + country: selectedPlace.country, + zipPostalCode: selectedPlace.postalCode, + email: projectViewModel.user!.emailAddress) + ]), + ); + await model.addAddressInfo(addNewAddressRequestModel: addNewAddressRequestModel); + if (model.state == ViewState.ErrorLocal) { + Utils.showErrorToast(model.error); + } else { + AppToast.showSuccessToast(message: "Address Added Successfully"); + } + Navigator.of(context).pop(addNewAddressRequestModel); + }), + ), + ], + ) + : PlacePicker( + apiKey: GOOGLE_API_KEY, + enableMyLocationButton: true, + automaticallyImplyAppBarLeading: false, + autocompleteOnTrailingWhitespace: true, + selectInitialPosition: true, + autocompleteLanguage: projectViewModel.currentLanguage, + enableMapTypeButton: true, + searchForInitialValue: false, + onMapCreated: (GoogleMapController controller) { + mapController = controller; + }, + onPlacePicked: (PickResult result) { + print(result.adrAddress); + }, + selectedPlaceWidgetBuilder: (_, selectedPlace, state, isSearchBarFocused) { + print("state: $state, isSearchBarFocused: $isSearchBarFocused"); + return isSearchBarFocused + ? Container() + : FloatingCard( + bottomPosition: 0.0, + leftPosition: 0.0, + rightPosition: 0.0, + width: 500, + borderRadius: BorderRadius.circular(0.0), + child: state == SearchingState.Searching + ? SizedBox(height: 43, child: Center(child: CircularProgressIndicator())).insideContainer + : DefaultButton(TranslationBase.of(context).addNewAddress, () async { + AddNewAddressRequestModel addNewAddressRequestModel = new AddNewAddressRequestModel( + customer: Customer(addresses: [ + Addresses( + address1: selectedPlace!.formattedAddress, + address2: selectedPlace!.formattedAddress, + customerAttributes: "", + createdOnUtc: "", + id: "0", + faxNumber: "", + phoneNumber: projectViewModel.user!.mobileNumber, + countryId: 69, + latLong: selectedPlace.geometry!.location.lat.toString() + "," + selectedPlace.geometry!.location.lng.toString(), + email: projectViewModel.user!.emailAddress) + ]), + ); + + selectedPlace.addressComponents!.forEach((e) { + if (e.types.contains("country")) { + addNewAddressRequestModel.customer!.addresses![0].country = e.longName; + } + if (e.types.contains("postal_code")) { + addNewAddressRequestModel.customer!.addresses![0].zipPostalCode = e.longName; + } + if (e.types.contains("locality")) { + addNewAddressRequestModel.customer!.addresses![0].city = e.longName; + } + }); + + await model.addAddressInfo(addNewAddressRequestModel: addNewAddressRequestModel); + if (model.state == ViewState.ErrorLocal) { + Utils.showErrorToast(model.error); + } else { + AppToast.showSuccessToast(message: "Address Added Successfully"); + } + Navigator.of(context).pop(addNewAddressRequestModel); + }).insideContainer); + }, + initialPosition: LatLng(latitude, longitude), + useCurrentLocation: showCurrentLocation, + ), + ), + ); + } + + checkIsHuawei() async { + // isHuawei = await FlutterHmsGmsAvailability.isHmsAvailable; + // print(isHuawei); + // setState(() {}); + await hmsApiAvailability.isHMSAvailable().then((value) { + isHuawei = value == 0 ? true : false; + }); + print(isHuawei); + setState(() {}); + } + + void _getUserLocation() async { + if (await this.sharedPref.getDouble(USER_LAT) != null && await this.sharedPref.getDouble(USER_LONG) != null) { + var lat = await this.sharedPref.getDouble(USER_LAT); + var long = await this.sharedPref.getDouble(USER_LONG); + latitude = lat; + longitude = long; + currentPostion = LatLng(lat, long); + setMap(); + } else { + if (await PermissionService.isLocationEnabled()) { + Geolocator.getLastKnownPosition().then((value) { + latitude = value!.latitude; + longitude = value!.longitude; + currentPostion = LatLng(latitude, longitude); + setMap(); + }); + } else { + if (Platform.isAndroid) { + Utils.showPermissionConsentDialog(context, TranslationBase.of(context).locationPermissionDialog, () { + Geolocator.getLastKnownPosition().then((value) { + latitude = value!.latitude; + longitude = value.longitude; + currentPostion = LatLng(latitude, longitude); + setMap(); + }); + }); + } else { + Geolocator.getLastKnownPosition().then((value) { + latitude = value!.latitude; + longitude = value.longitude; + setMap(); + }); + } + } + } + } + + setMap() { + setState(() { + _kGooglePlex = CameraPosition( + target: currentPostion, + zoom: 14.4746, + ); + appMap.moveTo(cameraPostion: _kGooglePlex); + }); + } + + void _updatePosition(CameraPosition _position) { + print(_position); + latitude = _position.target.latitude; + longitude = _position.target.longitude; } } 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 86ee791b..14085fd9 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 @@ -1,175 +1,129 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/HHC_get_all_services_response_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/PatientERHHCInsertServicesList.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/patient_er_insert_pres_order_request_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/home_health_care_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/main.dart'; +import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_Home_health_care_step_tow_page.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/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'; import 'package:flutter/material.dart'; -import 'package:google_maps_place_picker/google_maps_place_picker.dart'; +import 'package:google_maps_place_picker_mb/google_maps_place_picker.dart'; import 'package:provider/provider.dart'; class NewHomeHealthCareStepOnePage extends StatefulWidget { - final PatientERInsertPresOrderRequestModel - patientERInsertPresOrderRequestModel; - final Function changePageViewIndex; + final PatientERInsertPresOrderRequestModel patientERInsertPresOrderRequestModel; + final Function? changePageViewIndex; final HomeHealthCareViewModel model; - const NewHomeHealthCareStepOnePage( - {Key key, - this.patientERInsertPresOrderRequestModel, - this.model, - this.changePageViewIndex}) - : super(key: key); + const NewHomeHealthCareStepOnePage({Key? key, required this.patientERInsertPresOrderRequestModel, required this.model, this.changePageViewIndex}) : super(key: key); @override - _NewHomeHealthCareStepOnePageState createState() => - _NewHomeHealthCareStepOnePageState(); + _NewHomeHealthCareStepOnePageState createState() => _NewHomeHealthCareStepOnePageState(); } -class _NewHomeHealthCareStepOnePageState - extends State { - PickResult _result; +class _NewHomeHealthCareStepOnePageState extends State { + late PickResult _result; @override void initState() { - if (widget.patientERInsertPresOrderRequestModel - .patientERHHCInsertServicesList == - null) - widget.patientERInsertPresOrderRequestModel - .patientERHHCInsertServicesList = []; + if (widget.patientERInsertPresOrderRequestModel.patientERHHCInsertServicesList == null) widget.patientERInsertPresOrderRequestModel.patientERHHCInsertServicesList = []; super.initState(); } - + + @override Widget build(BuildContext context) { ProjectViewModel projectViewModel = Provider.of(context); - return AppScaffold( isShowAppBar: false, baseViewModel: widget.model, - body: SingleChildScrollView( - physics: ScrollPhysics(), - child: Container( - margin: EdgeInsets.only( - left: MediaQuery.of(context).size.width * 0.05, - right: MediaQuery.of(context).size.width * 0.05), - child: Center( - child: FractionallySizedBox( - widthFactor: 1, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 12, - ), - Texts( - TranslationBase.of(context).selectHomeHealthCareServices, - textAlign: TextAlign.center, - ), - Column( - children: widget.model.hhcAllServicesList.map((service) { - return Container( - margin: EdgeInsets.only(top: 15), - decoration: BoxDecoration( - border: Border.all(color: Colors.grey, width: 1), - borderRadius: BorderRadius.circular(12), - color: Theme.of(context).primaryColor), - child: Column( - children: [ - Row( - children: [ - Checkbox( - value: isServiceSelected(service.serviceID), - activeColor: Colors.red[800], - onChanged: (bool newValue) { - setState(() { - if (!isServiceSelected( - service.serviceID)) - widget - .patientERInsertPresOrderRequestModel - .patientERHHCInsertServicesList - .add(PatientERHHCInsertServicesList( - recordID: widget - .patientERInsertPresOrderRequestModel - .patientERHHCInsertServicesList - .length, - serviceID: service.serviceID, - serviceName: - service.description)); - else - removeSelected(service.serviceID); - // widget.patientERInsertPresOrderRequestModel - // isPatientInsured = newValue; - }); - }), - Expanded( - child: Padding( - padding: const EdgeInsets.all(20.0), - child: Texts( - projectViewModel.isArabic - ? service.descriptionN - : service.description, - fontSize: 15, - ), - ), - ), - ], - ), - ], + body: Column( + children: [ + Expanded( + flex: 1, + child: ListView.separated( + physics: BouncingScrollPhysics(), + shrinkWrap: true, + padding: EdgeInsets.only(left: 21, right: 21, top: 12, bottom: 12), + itemBuilder: (context, index) { + HHCGetAllServicesResponseModel service = widget.model.hhcAllServicesList[index]; + return Padding( + padding: const EdgeInsets.only(top: 4, bottom: 4), + child: Row( + children: [ + Checkbox( + value: isServiceSelected(int.parse(service.serviceID!)), + activeColor: Color(0xffD02127), + tristate: false, + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + onChanged: (bool? newValue) { + setState(() { + if (!isServiceSelected(int.parse(service.serviceID!))) + widget.patientERInsertPresOrderRequestModel.patientERHHCInsertServicesList!.add(PatientERHHCInsertServicesList( + recordID: widget.patientERInsertPresOrderRequestModel.patientERHHCInsertServicesList!.length, + serviceID: int.parse(service.serviceID!), + serviceName: projectViewModel.isArabic ? service.textN : service.text)); + else + removeSelected(int.parse(service.serviceID!)); + }); + }), + SizedBox(width: 6), + Expanded( + child: Text( + projectViewModel.isArabic ? service.textN! : service.text!.toLowerCase().capitalize(), + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.64), + ), ), - ); - }).toList(), - ) - ], - ), - ), + ], + ), + ); + }, + separatorBuilder: (context, index) => Divider( + height: 1, + color: Color(0xffE5E5E5), + ), + itemCount: widget.model.hhcAllServicesList.length), ), - ), - ), - bottomSheet: Container( - height: MediaQuery.of(context).size.height * 0.10, - width: double.infinity, - child: Column( - children: [ - Container( - width: MediaQuery.of(context).size.width * 0.9, - child: SecondaryButton( - label: TranslationBase.of(context).next, - disabled: this - .widget - .patientERInsertPresOrderRequestModel - .patientERHHCInsertServicesList - .length == - 0 || - widget.model.state == ViewState.BusyLocal, - color: Colors.grey[800], - loading: widget.model.state == ViewState.BusyLocal, - onTap: () async { - await widget.model.getCustomerInfo(); - if (widget.model.state == ViewState.ErrorLocal) { - Utils.showErrorToast(); - } else { - widget.changePageViewIndex(1); - } - }, - textColor: Theme.of(context).backgroundColor), + Container( + color: Colors.white, + 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) + ? null + : () async { + widget.model.setState(ViewState.Busy); + await widget.model.getCustomerInfo(); + Navigator.push( + context, + FadePage( + page: NewHomeHealthCareStepTowPage( + patientERInsertPresOrderRequestModel: widget.patientERInsertPresOrderRequestModel, + model: widget.model, + ), + ), + ); + // } + }, + disabledColor: Color(0xff575757), ), - ], - ), + ), + ], ), ); } isServiceSelected(int serviceId) { Iterable patientERHHCInsertServicesList = - widget - .patientERInsertPresOrderRequestModel.patientERHHCInsertServicesList - .where((element) => serviceId == element.serviceID); + widget.patientERInsertPresOrderRequestModel.patientERHHCInsertServicesList!.where((element) => serviceId == element.serviceID); if (patientERHHCInsertServicesList.length > 0) { return true; } @@ -178,15 +132,11 @@ class _NewHomeHealthCareStepOnePageState removeSelected(int serviceId) { Iterable patientERHHCInsertServicesList = - widget - .patientERInsertPresOrderRequestModel.patientERHHCInsertServicesList - .where((element) => serviceId == element.serviceID); + widget.patientERInsertPresOrderRequestModel.patientERHHCInsertServicesList!.where((element) => serviceId == element.serviceID); if (patientERHHCInsertServicesList.length > 0) setState(() { - widget - .patientERInsertPresOrderRequestModel.patientERHHCInsertServicesList - .remove(patientERHHCInsertServicesList.first); + widget.patientERInsertPresOrderRequestModel.patientERHHCInsertServicesList!.remove(patientERHHCInsertServicesList.first); }); } } diff --git a/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_Home_health_care_step_three_page.dart b/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_Home_health_care_step_three_page.dart index 5e9bd04d..3ff391ca 100644 --- a/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_Home_health_care_step_three_page.dart +++ b/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_Home_health_care_step_three_page.dart @@ -4,34 +4,34 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/patient_er_insert_pres_order_request_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/home_health_care_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/Dialog/confirm_dialog.dart'; +import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/HomeHealthCare/home_health_care_page.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/widgets/buttons/secondary_button.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/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:provider/provider.dart'; class NewHomeHealthCareStepThreePage extends StatefulWidget { - final PatientERInsertPresOrderRequestModel - patientERInsertPresOrderRequestModel; - final Function changePageViewIndex; + final PatientERInsertPresOrderRequestModel? patientERInsertPresOrderRequestModel; + final Function? changePageViewIndex; final HomeHealthCareViewModel model; - NewHomeHealthCareStepThreePage( - {Key key, - this.patientERInsertPresOrderRequestModel, - this.changePageViewIndex, - this.model}); + NewHomeHealthCareStepThreePage({Key? key, this.patientERInsertPresOrderRequestModel, this.changePageViewIndex, required this.model}); @override - _NewHomeHealthCareStepThreePageState createState() => - _NewHomeHealthCareStepThreePageState(); + _NewHomeHealthCareStepThreePageState createState() => _NewHomeHealthCareStepThreePageState(); } -class _NewHomeHealthCareStepThreePageState - extends State { +class _NewHomeHealthCareStepThreePageState extends State { Completer _controller = Completer(); static CameraPosition _kGooglePlex = CameraPosition( @@ -42,22 +42,17 @@ class _NewHomeHealthCareStepThreePageState @override void initState() { - - if (widget.patientERInsertPresOrderRequestModel.latitude != null) { + if (widget.patientERInsertPresOrderRequestModel!.latitude != null) { markers.clear(); markers.add( Marker( markerId: MarkerId( - widget.patientERInsertPresOrderRequestModel.latitude.hashCode - .toString(), + widget.patientERInsertPresOrderRequestModel!.latitude.hashCode.toString(), ), - position: LatLng( - widget.patientERInsertPresOrderRequestModel.latitude, - widget.patientERInsertPresOrderRequestModel.longitude)), + position: LatLng(widget.patientERInsertPresOrderRequestModel!.latitude!, widget.patientERInsertPresOrderRequestModel!.longitude!)), ); _kGooglePlex = CameraPosition( - target: LatLng(widget.patientERInsertPresOrderRequestModel.latitude, - widget.patientERInsertPresOrderRequestModel.longitude), + target: LatLng(widget.patientERInsertPresOrderRequestModel!.latitude!, widget.patientERInsertPresOrderRequestModel!.longitude!), zoom: 14.4746, ); } @@ -71,6 +66,9 @@ class _NewHomeHealthCareStepThreePageState return AppScaffold( isShowDecPage: false, baseViewModel: widget.model, + showNewAppBar: true, + showNewAppBarTitle: true, + appBarTitle: TranslationBase.of(context).homeHealthCare, body: SingleChildScrollView( physics: BouncingScrollPhysics(), child: Container( @@ -79,62 +77,96 @@ class _NewHomeHealthCareStepThreePageState child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Texts(TranslationBase.of(context).orderDetails, fontWeight: FontWeight.bold,), - SizedBox( - height: 12, - ), Container( - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(12)), - padding: EdgeInsets.all(8), + padding: EdgeInsets.only(top: 12.0, bottom: 12.0), + child: Texts( + TranslationBase.of(context).RRTSummary, + fontWeight: FontWeight.bold, + fontSize: 22, + )), + Container( + decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(12)), + padding: EdgeInsets.all(12), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Texts(TranslationBase.of(context).orderLocation, fontWeight: FontWeight.bold), + Text( + TranslationBase.of(context).selectedLocation, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + color: CustomColors.textColor, + letterSpacing: -0.56, + ), + ), SizedBox( height: 12, ), - Padding( - padding: const EdgeInsets.all(8.0), - child: Container( + Container( height: 200, - child: GoogleMap( - mapType: MapType.normal, - markers: markers, - initialCameraPosition: _kGooglePlex, - onMapCreated: (GoogleMapController controller) { - _controller.complete(controller); - }, - ), - ), - ), + decoration: containerColorRadiusBorderWidth(Colors.transparent, 12,Colors.transparent,0.5), + clipBehavior: Clip.antiAlias, + child: Image.network( + "https://maps.googleapis.com/maps/api/staticmap?center=" + + widget.patientERInsertPresOrderRequestModel!.latitude.toString() + + "," + + widget.patientERInsertPresOrderRequestModel!.longitude.toString() + + "&zoom=16&size=600x300&maptype=roadmap&markers=color:red%7C" + + widget.patientERInsertPresOrderRequestModel!.latitude.toString() + + "," + + widget.patientERInsertPresOrderRequestModel!.longitude.toString() + + "&key=AIzaSyCyDbWUM9d_sBUGIE8PcuShzPaqO08NSC8", + width: double.infinity, + height: double.infinity, + fit: BoxFit.cover, + )), SizedBox( height: 12, ), - Texts(TranslationBase.of(context).selectedService + " : ", fontWeight: FontWeight.bold), + Text( + TranslationBase.of(context).selectedService, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + color: CustomColors.textColor, + letterSpacing: -0.56, + ), + ), ...List.generate( - widget.patientERInsertPresOrderRequestModel - .patientERHHCInsertServicesList.length, + widget.patientERInsertPresOrderRequestModel!.patientERHHCInsertServicesList!.length, (index) => Container( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Texts( - TranslationBase.of(context).serviceName, - fontSize: 12, - ), + // Texts( + // TranslationBase.of(context).serviceName, + // fontSize: 12, + // ), SizedBox( height: 5, ), - Texts( - widget - .patientERInsertPresOrderRequestModel - .patientERHHCInsertServicesList[index] - .serviceName, - fontSize: 15, - bold: true, - ), + Row( + children: [ + Text( + (index + 1).toString() + '. ', + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + color: CustomColors.black, + letterSpacing: -0.48, + ), + ), + Text( + widget.patientERInsertPresOrderRequestModel!.patientERHHCInsertServicesList![index].serviceName!, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + color: CustomColors.black, + letterSpacing: -0.48, + ), + ), + ], + ) ], ), ), @@ -150,29 +182,53 @@ class _NewHomeHealthCareStepThreePageState ), ), bottomSheet: Container( - height: MediaQuery.of(context).size.height * 0.10, + color: Theme.of(context).scaffoldBackgroundColor, width: double.infinity, - child: Column( - children: [ - Container( - width: MediaQuery.of(context).size.width * 0.9, - child: SecondaryButton( - label: TranslationBase.of(context).confirm, - disabled: widget.patientERInsertPresOrderRequestModel - .patientERHHCInsertServicesList.length == - 0, - color: Colors.grey[800], - onTap: () async { - await widget.model.insertPresPresOrder( - order: widget.patientERInsertPresOrderRequestModel); - if (widget.model.state != ViewState.ErrorLocal) { - widget.changePageViewIndex(0); - } - }, - textColor: Theme.of(context).backgroundColor), - ), - ], + child: Padding( + padding: const EdgeInsets.all(12.0), + child: DefaultButton( + TranslationBase.of(context).confirm, + () { + widget.model.setState(ViewState.Busy); + widget.model.insertPresPresOrder(order: widget.patientERInsertPresOrderRequestModel!).then((value) { + widget.model.setState(ViewState.Idle); + if (widget.model.state != ViewState.ErrorLocal) { + if (widget.model.orderId != null) { + showCMCConfirmDialog( + context, + widget.model.orderId.toString(), + onClick: () { + Navigator.popUntil(context, (route) => Utils.route(route, equalsTo: HomeHealthCarePage)); + Navigator.push(context, FadePage(page: HomeHealthCarePage())); + }, + ); + } + } else { + AppToast.showErrorToast(message: widget.model.error); + } + }); + }, + color: CustomColors.green, + ), ), + + // SecondaryButton( + // label: TranslationBase.of(context).confirm, + // disabled: widget.patientERInsertPresOrderRequestModel.patientERHHCInsertServicesList.length == 0, + // color: Colors.grey[800], + // onTap: () async { + // widget.model.setState(ViewState.Busy); + // widget.model.insertPresPresOrder(order: widget.patientERInsertPresOrderRequestModel).then((value) => { + // widget.model.setState(ViewState.Idle), + // Navigator.push( + // context, + // FadePage( + // page: HomeHealthCarePage(), + // ), + // ) + // }); + // }, + // textColor: Theme.of(context).backgroundColor), ), ); } diff --git a/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_Home_health_care_step_tow_page.dart b/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_Home_health_care_step_tow_page.dart index e9ddd2d1..ee8f5b92 100644 --- a/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_Home_health_care_step_tow_page.dart +++ b/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_Home_health_care_step_tow_page.dart @@ -1,193 +1,286 @@ -import 'package:diplomaticquarterapp/config/config.dart'; +import 'dart:async'; +import 'dart:io'; + +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/patient_er_insert_pres_order_request_model.dart'; import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/customer_addresses_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/home_health_care_view_model.dart'; -import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_Home_health_care_step_three_page.dart'; +import 'package:diplomaticquarterapp/services/permission/permission_service.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; +import 'package:diplomaticquarterapp/uitl/location_util.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/app_map/google_huawei_map.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/select_location_dialog.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:geolocator/geolocator.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; -import 'package:google_maps_place_picker/google_maps_place_picker.dart'; -import 'package:provider/provider.dart'; +import 'package:google_maps_place_picker_mb/google_maps_place_picker.dart'; import 'location_page.dart'; class NewHomeHealthCareStepTowPage extends StatefulWidget { - final Function(PickResult) onPick; - final double latitude; - final double longitude; - final PatientERInsertPresOrderRequestModel - patientERInsertPresOrderRequestModel; - final Function changePageViewIndex; + final Function(PickResult)? onPick; + final double? latitude; + final double? longitude; + final PatientERInsertPresOrderRequestModel? patientERInsertPresOrderRequestModel; + final Function? changePageViewIndex; final HomeHealthCareViewModel model; - const NewHomeHealthCareStepTowPage( - {Key key, - this.onPick, - this.latitude, - this.longitude, - this.patientERInsertPresOrderRequestModel, - this.changePageViewIndex, - this.model}) + const NewHomeHealthCareStepTowPage({Key? key, this.onPick, this.latitude, this.longitude, this.patientERInsertPresOrderRequestModel, this.changePageViewIndex, required this.model}) : super(key: key); @override - _NewHomeHealthCareStepTowPageState createState() => - _NewHomeHealthCareStepTowPageState(); + _NewHomeHealthCareStepTowPageState createState() => _NewHomeHealthCareStepTowPageState(); } -class _NewHomeHealthCareStepTowPageState - extends State { +class _NewHomeHealthCareStepTowPageState extends State { double latitude = 0; double longitude = 0; - AddressInfo _selectedAddress; + AddressInfo? _selectedAddress; + + bool showCurrentLocation = false; + final Set markers = new Set(); + late AppMap appMap; + AppSharedPreferences sharedPref = AppSharedPreferences(); + static CameraPosition _kGooglePlex = CameraPosition( + target: LatLng(37.42796133580664, -122.085749655962), + zoom: 14.4746, + ); + late LatLng currentPostion; + Completer mapController = Completer(); + late LocationUtils locationUtils; @override void initState() { - if (widget.patientERInsertPresOrderRequestModel.latitude == null) { - setLatitudeAndLongitude(); + appMap = AppMap( + //Changed by Aamir + _kGooglePlex.toMap() as Map, + onCameraMove: (camera) { + _updatePosition(camera as CameraPosition); + }, + onMapCreated: () { + _getUserLocation(); + setState(() {}); + }, + onCameraIdle: () { + print("onCameraIdle"); + }, + ); + super.initState(); + } + + void _getUserLocation() async { + if (await this.sharedPref.getDouble(USER_LAT) != null && await this.sharedPref.getDouble(USER_LONG) != null) { + var lat = await this.sharedPref.getDouble(USER_LAT); + var long = await this.sharedPref.getDouble(USER_LONG); + latitude = lat; + longitude = long; + currentPostion = LatLng(lat, long); + setMap(); } else { - latitude = widget.patientERInsertPresOrderRequestModel.latitude; - longitude = widget.patientERInsertPresOrderRequestModel.longitude; + locationUtils = new LocationUtils(isShowConfirmDialog: true, context: context); + locationUtils.getCurrentLocation(callBack: (value) { + print(value); + setMap(); + }); + // if (await PermissionService.isLocationEnabled()) { + // Geolocator.getLastKnownPosition().then((value) { + // latitude = value.latitude; + // longitude = value.longitude; + // currentPostion = LatLng(latitude, longitude); + // setMap(); + // }); + // } else { + // if (Platform.isAndroid) { + // Utils.showPermissionConsentDialog(context, TranslationBase.of(context).locationPermissionDialog, () { + // Geolocator.getLastKnownPosition().then((value) { + // latitude = value.latitude; + // longitude = value.longitude; + // currentPostion = LatLng(latitude, longitude); + // setMap(); + // }); + // }); + // } else { + // Geolocator.getLastKnownPosition().then((value) { + // latitude = value.latitude; + // longitude = value.longitude; + // setMap(); + // }); + // } + // } } - - super.initState(); } - setLatitudeAndLongitude({bool isSetState = false, String latLong}) { - if (latLong == null) - latLong = widget.model.addressesList[widget.model.addressesList - .length - 1].latLong; - List latLongArr = latLong.split(','); + setLatitudeAndLongitude({bool isSetState = false, String? latLong}) { + if (latLong == null) { + if (widget.model.addressesList.isEmpty) { + setState(() { + showCurrentLocation = true; + }); + } else { + latLong = widget.model.addressesList[widget.model.addressesList.length - 1].latLong; + } + } + + if (!showCurrentLocation) { + List latLongArr = latLong!.split(','); - latitude = double.parse(latLongArr[0]); - longitude = double.parse(latLongArr[1]); + latitude = double.parse(latLongArr[0]); + longitude = double.parse(latLongArr[1]); + currentPostion = LatLng(latitude, longitude); + setMap(); + } + } + + setMap() { + setState(() { + _kGooglePlex = CameraPosition( + target: currentPostion, + zoom: 14.4746, + ); + appMap.moveTo(cameraPostion: _kGooglePlex); + }); } @override Widget build(BuildContext context) { - ProjectViewModel projectViewModel = Provider.of(context); return AppScaffold( isShowDecPage: false, - body: Stack( + showNewAppBarTitle: true, + showNewAppBar: true, + appBarTitle: TranslationBase.of(context).homeHealthCare, + body: Column( children: [ - PlacePicker( - apiKey: GOOGLE_API_KEY, - enableMyLocationButton: true, - automaticallyImplyAppBarLeading: false, - autocompleteOnTrailingWhitespace: true, - selectInitialPosition: true, - autocompleteLanguage: projectViewModel.currentLanguage, - enableMapTypeButton: true, - searchForInitialValue: false, - - onPlacePicked: (PickResult result) { - print(result.adrAddress); - widget.changePageViewIndex(3); - }, - selectedPlaceWidgetBuilder: - (_, selectedPlace, state, isSearchBarFocused) { - print("state: $state, isSearchBarFocused: $isSearchBarFocused"); - return isSearchBarFocused - ? Container() - : FloatingCard( - bottomPosition: 0.0, - leftPosition: 0.0, - rightPosition: 0.0, - width: 500, - borderRadius: BorderRadius.circular(12.0), - child: state == SearchingState.Searching - ? Center(child: CircularProgressIndicator()) - : Container( - margin: EdgeInsets.all(12), - child: Column( - children: [ - SecondaryButton( - color: Colors.grey[800], - textColor: Colors.white, - onTap: () { - Navigator.push( - context, - FadePage( - page: - LocationPage( - latitude: latitude, - longitude: longitude, - ), - ), - ); - }, - label: TranslationBase.of(context).addNewAddress, - ), - SizedBox(height: 10,), - SecondaryButton( - color: Colors.red[800], - textColor: Colors.white, - onTap: () { - setState(() { - widget.patientERInsertPresOrderRequestModel - .latitude = - selectedPlace.geometry.location.lat; - widget.patientERInsertPresOrderRequestModel - .longitude = - selectedPlace.geometry.location.lng; - }); - widget.changePageViewIndex(3); - }, - label: TranslationBase.of(context).confirm, - ), - ], + if (widget.model.addressesList.isNotEmpty) + Container( + margin: EdgeInsets.only(left: 12, right: 12, bottom: 12, top: 12), + decoration: cardRadius(12), + child: Container( + child: InkWell( + onTap: () => confirmSelectLocationDialog(widget.model.addressesList), + child: Container( + padding: EdgeInsets.all(8), + width: double.infinity, + // height: 65, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: Colors.white, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Text( + getAddressName(), + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 12, + letterSpacing: -0.45, + ), + ), + ), + Icon(Icons.arrow_drop_down) + ], + ), ), ), - ); + height: 50, + width: double.infinity, + ), + ), + InkWell( + onTap: () { + // Navigator.push( + // context, + // FadePage( + // page: LocationPage( + // // latitude: latitude, + // // longitude: longitude, + // ), + // ), + // ).then((value) async { + // print(value); + // await widget.model.getCustomerAddresses(); + // setState(() {}); + // }); }, - initialPosition: LatLng(latitude, longitude), - useCurrentLocation: false, + child: Padding( + padding: EdgeInsets.only(left: 12, right: 12, bottom: 16, top: 16), + child: Row( + children: [ + Icon(Icons.location_on_outlined), + mWidth(12), + Text( + TranslationBase.of(context).selectLocation, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + letterSpacing: -0.46, + ), + ), + ], + ), + ), ), - Container( - child: InkWell( - onTap: () => - confirmSelectLocationDialog(widget.model.addressesList), - child: Container( - padding: EdgeInsets.all(10), - width: double.infinity, - // height: 65, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - color: Colors.white), - child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Expanded(child: Texts(getAddressName(), fontSize: 14,),), - Icon(Icons.arrow_drop_down) - ], + Expanded( + child: Stack( + alignment: Alignment.center, + children: [ + if (appMap != null) appMap, + Container( + margin: EdgeInsets.only(bottom: 50.0), + child: Icon( + Icons.place, + color: CustomColors.accentColor, + size: 50, + ), ), - ), + ], ), - height: 56, width: double.infinity, color: Theme - .of(context) - .scaffoldBackgroundColor, - - ) + ), + Padding( + padding: const EdgeInsets.only(left: 20, right: 20, top: 14, bottom: 14), + child: DefaultButton( + TranslationBase.of(context).continues, + () { + setState(() { + widget.patientERInsertPresOrderRequestModel!.latitude = latitude; + widget.patientERInsertPresOrderRequestModel!.longitude = longitude; + }); + navigateTo( + context, + NewHomeHealthCareStepThreePage( + patientERInsertPresOrderRequestModel: widget.patientERInsertPresOrderRequestModel, + model: widget.model, + ), + ); + }, + ), + ), ], ), ); } + void _updatePosition(CameraPosition _position) { + latitude = _position.target.latitude; + longitude = _position.target.longitude; + } void confirmSelectLocationDialog(List addresses) { showDialog( context: context, - child: SelectLocationDialog( + builder: (cxt) => SelectLocationDialog( addresses: addresses, - selectedAddress: _selectedAddress - , + selectedAddress: _selectedAddress, onValueSelected: (value) { setLatitudeAndLongitude(latLong: value.latLong); setState(() { @@ -199,9 +292,32 @@ class _NewHomeHealthCareStepTowPageState } String getAddressName() { - if (_selectedAddress != null) - return _selectedAddress.address1; + if (_selectedAddress != null && _selectedAddress!.address1 != null) + return _selectedAddress!.address1.toString(); else return TranslationBase.of(context).selectAddress; } + + goToCurrentLocation() { + Geolocator.getCurrentPosition().then((value) { + _selectedAddress = AddressInfo(latLong: '${value.latitude},${value.longitude}'); + moveToLocation(LatLng(value.latitude, value.longitude)); + }); + } + + moveToLocation(LatLng location, {bool animate = true}) async { + await Future.delayed(Duration(milliseconds: 200)); + _kGooglePlex = CameraPosition( + target: location, + zoom: 16.4746, + ); + if (animate) + (await mapController.future).animateCamera( + CameraUpdate.newCameraPosition(_kGooglePlex), + ); + else + (await mapController.future).moveCamera( + CameraUpdate.newCameraPosition(_kGooglePlex), + ); + } } 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 ab564cb7..42ced9eb 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,42 +1,39 @@ +import 'dart:io'; + 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/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_Home_health_care_step_three_page.dart'; -import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_Home_health_care_step_tow_page.dart'; +import 'package:diplomaticquarterapp/services/permission/permission_service.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/ConfirmWithMessageDialog.dart'; import 'package:flutter/material.dart'; import 'package:geolocator/geolocator.dart'; import 'package:provider/provider.dart'; -import '../StepsWidget.dart'; import 'new_Home_health_care_step_one_page.dart'; class NewHomeHealthCarePage extends StatefulWidget { - NewHomeHealthCarePage({this.model}); + NewHomeHealthCarePage({required this.model}); final HomeHealthCareViewModel model; + @override _NewHomeHealthCarePageState createState() => _NewHomeHealthCarePageState(); } -class _NewHomeHealthCarePageState extends State - with TickerProviderStateMixin { - PageController _controller; +class _NewHomeHealthCarePageState extends State with TickerProviderStateMixin { + late PageController _controller; int _currentIndex = 1; - double _latitude; - double _longitude; + late double _latitude; + late double _longitude; - PatientERInsertPresOrderRequestModel patientERInsertPresOrderRequestModel = - new PatientERInsertPresOrderRequestModel(); + PatientERInsertPresOrderRequestModel patientERInsertPresOrderRequestModel = PatientERInsertPresOrderRequestModel(); @override void initState() { @@ -46,13 +43,43 @@ class _NewHomeHealthCarePageState extends State } _getCurrentLocation() async { - await getLastKnownPosition().then((value) { - _latitude = value.latitude; - _longitude = value.longitude; - }).catchError((e) { - _longitude = 0; - _latitude = 0; - }); + if (await PermissionService.isLocationEnabled()) { + Geolocator.getLastKnownPosition().then((value) { + _latitude = value!.latitude; + _longitude = value.longitude; + }).catchError((e) { + _longitude = 0; + _latitude = 0; + }); + } else { + if (Platform.isAndroid) { + Utils.showPermissionConsentDialog(context, TranslationBase.of(context).locationPermissionDialog, () { + Geolocator.getLastKnownPosition().then((value) { + _latitude = value!.latitude; + _longitude = value.longitude; + }).catchError((e) { + _longitude = 0; + _latitude = 0; + }); + }); + } else { + Geolocator.getLastKnownPosition().then((value) { + _latitude = value!.latitude; + _longitude = value.longitude; + }).catchError((e) { + _longitude = 0; + _latitude = 0; + }); + } + } + + // await Geolocator.getLastKnownPosition().then((value) { + // _latitude = value.latitude; + // _longitude = value.longitude; + // }).catchError((e) { + // _longitude = 0; + // _latitude = 0; + // }); } @override @@ -64,322 +91,242 @@ class _NewHomeHealthCarePageState extends State setState(() { _currentIndex = tab; }); - _controller.animateToPage(tab, - duration: Duration(milliseconds: 800), curve: Curves.easeOutQuart); + _controller.animateToPage(tab, duration: Duration(milliseconds: 800), curve: Curves.easeOutQuart); } @override Widget build(BuildContext context) { - void showConfirmMessage(HomeHealthCareViewModel model, - GetOrderDetailByOrderIDResponseModel order) { + void showConfirmMessage(HomeHealthCareViewModel model, GetCMCAllOrdersResponseModel order) { showDialog( context: context, - child: ConfirmCancelOrderDialog( - model: model, - onTap: () async { - UpdatePresOrderRequestModel updatePresOrderRequestModel = - UpdatePresOrderRequestModel( - presOrderID: order.presOrderID, - rejectionReason: "", - presOrderStatus: 4, - editedBy: 3); - 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(); - } - }, - )); + builder: (cxt) => ConfirmWithMessageDialog( + message: TranslationBase.of(context).cancelOrderMsg, + onTap: () async { + model.setState(ViewState.Busy); + UpdatePresOrderRequestModel updatePresOrderRequestModel = UpdatePresOrderRequestModel(presOrderID: order.iD, rejectionReason: "", presOrderStatus: 4, editedBy: 3); + + 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(); + } + }, + )); } ProjectViewModel projectViewModel = Provider.of(context); - return Scaffold( - body: SafeArea( - child: SingleChildScrollView( - child: Container( - height: MediaQuery.of(context).size.height * 0.8, - child: Column( - children: [ - Container( - margin: EdgeInsets.only( - left: MediaQuery.of(context).size.width * 0.05, - right: MediaQuery.of(context).size.width * 0.05), - child: StepsWidget( - index: _currentIndex, - changeCurrentTab: _changeCurrentTab, - ), - ), - Expanded( - child: PageView( - physics: NeverScrollableScrollPhysics(), - controller: _controller, - onPageChanged: (index) { - setState(() { - _currentIndex = index; - }); - }, - scrollDirection: Axis.horizontal, - children: [ - widget.model.pendingOrder != null - ? FractionallySizedBox( - widthFactor: 0.9, - child: SingleChildScrollView( - child: Container( - width: double.infinity, - margin: EdgeInsets.only(top: 15), - decoration: BoxDecoration( - border: Border.all( - color: Colors.grey, width: 1), - borderRadius: BorderRadius.circular(12), - color: Theme.of(context).primaryColor), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - SizedBox( - height: 12, - ), - Container( - width: double.infinity, - padding: EdgeInsets.only( - left: 15, - bottom: 15, - top: 15, - right: 15), - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Colors.grey, - width: 1.0, - ), - ), - // borderRadius: BorderRadius.circular(12), - color: - Theme.of(context).primaryColor), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Texts( - TranslationBase.of(context) - .requestID, - bold: false, - fontSize: 13, - ), - SizedBox( - height: 4, - ), - Texts( - widget.model.pendingOrder.iD - .toString(), - fontSize: 22, - ), - ], - ), - ), - Container( - width: double.infinity, - padding: EdgeInsets.only( - left: 15, - bottom: 15, - top: 15, - right: 15), - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Colors.grey, - width: 1.0, - ), - ), - // borderRadius: BorderRadius.circular(12), - color: - Theme.of(context).primaryColor), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Texts( - TranslationBase.of(context) - .OrderStatus, - bold: false, - fontSize: 13, - ), - SizedBox( - height: 4, - ), - Texts( - projectViewModel.isArabic - ? widget.model.pendingOrder - .descriptionN - : widget.model.pendingOrder - .description, - fontSize: 22, - ), - ], - ), - ), - Container( - width: double.infinity, - padding: EdgeInsets.only( - left: 15, - bottom: 15, - top: 15, - right: 15), - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Colors.grey, - width: 1.0, - ), - ), - // borderRadius: BorderRadius.circular(12), - color: - Theme.of(context).primaryColor), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Texts( - TranslationBase.of(context) - .pickupDate, - bold: false, - fontSize: 13, - ), - SizedBox( - height: 4, - ), - Texts( - DateUtil - .getDayMonthYearDateFormatted( - DateUtil - .convertStringToDate( - widget - .model - .pendingOrder - .createdOn)), - fontSize: 22, - ), - ], - ), - ), - ...List.generate( - widget.model.hhcAllOrderDetail.length, - (index) => Container( - width: double.infinity, - padding: EdgeInsets.only( - left: 15, - bottom: 15, - top: 15, - right: 15), - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Colors.grey, - width: 1.0, - ), - ), - // borderRadius: BorderRadius.circular(12), - color: Theme.of(context) - .primaryColor), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Texts( - TranslationBase.of(context) - .serviceName, - bold: false, - fontSize: 13, - ), - SizedBox( - height: 4, - ), - Texts( - projectViewModel.isArabic - ? widget - .model - .hhcAllOrderDetail[ - index] - .descriptionN - : widget - .model - .hhcAllOrderDetail[ - index] - .description, - fontSize: 22, - bold: true, - ), - ], - ), - ), - ), - SizedBox( - height: 12, - ), - Center( - child: Container( - width: MediaQuery.of(context) - .size - .width * - 0.85, - child: SecondaryButton( - label: TranslationBase.of(context) - .cancel - .toUpperCase(), - onTap: () { - showConfirmMessage( - widget.model, - widget.model - .hhcAllOrderDetail[0]); - }, - color: Colors.red[800], - disabled: false, - textColor: Theme.of(context) - .backgroundColor), - ), - ), - SizedBox( - height: 12, + return PageView( + physics: NeverScrollableScrollPhysics(), + controller: _controller, + onPageChanged: (index) { + setState(() { + _currentIndex = index; + }); + }, + scrollDirection: Axis.horizontal, + children: [ + widget.model.pendingOrder != null && widget.model.pendingOrder.serviceText != 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( + widget.model.pendingOrder.statusText ?? "", + 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}', + 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).hospital + ": ", + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff575757), letterSpacing: -0.4, height: 16 / 10), + ), + Expanded( + child: Text( + widget.model.pendingOrder.nearestProjectName ?? "", + style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.56), ), - ], + ), + ], + ) + ], + ), + ), + Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text( + DateUtil.getDayMonthYearDateFormatted(DateTime.tryParse(widget.model.pendingOrder.created.toString()) ?? DateTime.now()), + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.4, height: 16 / 10), + ), + SizedBox(height: 12), + if (widget.model.pendingOrder.statusId == 1 || widget.model.pendingOrder.statusId == 2) + InkWell( + onTap: () { + showConfirmMessage(widget.model, widget.model.pendingOrder); + }, + 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), + ), ), ), - ), - ) - : NewHomeHealthCareStepOnePage( - changePageViewIndex: _changeCurrentTab, - patientERInsertPresOrderRequestModel: - patientERInsertPresOrderRequestModel, - model: widget.model, - ), - NewHomeHealthCareStepTowPage( - latitude: _latitude, - longitude: _longitude, - changePageViewIndex: _changeCurrentTab, - patientERInsertPresOrderRequestModel: - patientERInsertPresOrderRequestModel, - model: widget.model, + ], + ), + ], ), - NewHomeHealthCareStepThreePage( - 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/StepsWidget.dart b/lib/pages/AlHabibMedicalService/HomeHealthCare/StepsWidget.dart index 370544d0..29403efd 100644 --- a/lib/pages/AlHabibMedicalService/HomeHealthCare/StepsWidget.dart +++ b/lib/pages/AlHabibMedicalService/HomeHealthCare/StepsWidget.dart @@ -1,181 +1,97 @@ -import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; class StepsWidget extends StatelessWidget { - final int index; - final Function changeCurrentTab; + final int? index; + final Function? changeCurrentTab; - StepsWidget({Key key, this.index, this.changeCurrentTab}); + StepsWidget({Key? key, this.index, this.changeCurrentTab}); @override Widget build(BuildContext context) { - ProjectViewModel projectViewModel = Provider.of(context); - return !projectViewModel.isArabic? Stack( - children: [ - Container( - height: 50, - width: MediaQuery.of(context).size.width, - color: Colors.transparent, - child: Center( - child: Divider( - color: Colors.grey, - height: 0.75, - thickness: 0.75, - ), - ), - ), - Positioned( - top: 10, - left: 0, - child: InkWell( - onTap: () => changeCurrentTab(0), - child: Container( - width: 35, - height: 35, - decoration: BoxDecoration( - border: index > 0 ? null:Border.all(color: Colors.black,width: 0.75), - shape: BoxShape.circle, - color: index == 0 ? Colors.grey[800] : index > 0 ?Colors.green: Colors.white, - ), - child: Center( - child: Texts( - '1', - color: index == 0 ? Colors.white : index > 0 ?Colors.white: Colors.grey[800], - ), - ), - ), - ), - ), - Positioned( - top: 10, - left: MediaQuery.of(context).size.width * 0.42, - child: InkWell( - onTap: () => index >= 2 ? changeCurrentTab(1) : null, - child: Container( - width: 35, - height: 35, - decoration: BoxDecoration( - border: index > 1 ? null:Border.all(color: Colors.black,width: 0.75), - shape: BoxShape.circle, - color: index == 1 ? Colors.grey[800] : index > 1 ?Colors.green: Colors.white, - ), - child: Center( - child: Texts( - '2', - color: index == 1? Colors.white : index > 1 ?Colors.white: Colors.grey[800], - ), - ), - ), - ), - ), - Positioned( - top: 10, - right: 0, - child: InkWell( - onTap: () => index == 2 ?changeCurrentTab(3) : null, - child: Container( - width: 35, - height: 35, - decoration: BoxDecoration( - shape: BoxShape.circle, - border: Border.all(color: Colors.black,width: 0.75), - color: index == 2 ? Colors.grey[800] : Colors.white, - ), - child: Center( - child: Texts( - '3', - color: index == 2 ? Colors.white : Colors.grey[800], - ), - ), - ), - ), - ), + return showRow(); + } - ], - ):Stack( - children: [ - Container( - height: 50, - width: MediaQuery.of(context).size.width, - color: Colors.transparent, - child: Center( - child: Divider( - color: Colors.grey, - height: 0.75, - thickness: 0.75, - ), - ), - ), - Positioned( - top: 10, - right: 0, - child: InkWell( - onTap: () => changeCurrentTab(0), + Widget showRow() { + return Container( + width: double.infinity, + child: Row( + children: [ + InkWell( + onTap: () => changeCurrentTab!(0), child: Container( width: 35, height: 35, - decoration: BoxDecoration( - border: index > 0 ? null:Border.all(color: Colors.black,width: 0.75), - shape: BoxShape.circle, - color: index == 0 ? Colors.grey[800] : index > 0 ?Colors.green: Colors.white, - ), + decoration: containerColorRadiusBorder( + index == 0 + ? CustomColors.accentColor + : index! > 0 + ? Colors.green[700]! + : Colors.white, + 2000, + Colors.black), child: Center( - child: Texts( - '1', - color: index == 0 ? Colors.white : index > 0 ?Colors.white: Colors.grey[800], + child: Text( + "1", + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.bold, + ), ), ), ), ), - ), - Positioned( - top: 10, - left: MediaQuery.of(context).size.width * 0.42, - child: InkWell( - onTap: () => index >= 2 ? changeCurrentTab(1) : null, + Expanded(child: mDivider(Colors.grey)), + InkWell( + onTap: () => index! >= 2 ? changeCurrentTab!(1) : null, child: Container( width: 35, height: 35, - decoration: BoxDecoration( - border: index > 1 ? null:Border.all(color: Colors.black,width: 0.75), - shape: BoxShape.circle, - color: index == 1 ? Colors.grey[800] : index > 1 ?Colors.green: Colors.white, - ), + decoration: containerColorRadiusBorder( + index == 1 + ? CustomColors.accentColor + : index! > 1 + ? Colors.green[700]! + : Colors.white, + 2000, + Colors.black), child: Center( - child: Texts( - '2', - color: index == 1? Colors.white : index > 1 ?Colors.white: Colors.grey[800], + child: Text( + "2", + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.bold, + ), ), ), ), ), - ), - Positioned( - top: 10, - left: 0, - child: InkWell( - onTap: () => index == 2 ?changeCurrentTab(3) : null, + Expanded(child: mDivider(Colors.grey)), + InkWell( + onTap: () => index == 2 ? changeCurrentTab!(3) : null, child: Container( width: 35, height: 35, - decoration: BoxDecoration( - shape: BoxShape.circle, - border: Border.all(color: Colors.black,width: 0.75), - color: index == 2 ? Colors.grey[800] : Colors.white, + decoration: containerColorRadiusBorder( + index == 2 ? CustomColors.accentColor : Colors.white, + 2000, + Colors.black, ), child: Center( - child: Texts( - '3', - color: index == 2 ? Colors.white : Colors.grey[800], + child: Text( + "3", + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.bold, + ), ), ), ), ), - ), - ], + ], + ), ); } } diff --git a/lib/pages/AlHabibMedicalService/HomeHealthCare/home_health_care_index_page.dart b/lib/pages/AlHabibMedicalService/HomeHealthCare/home_health_care_index_page.dart index fa0799f9..05b0d753 100644 --- a/lib/pages/AlHabibMedicalService/HomeHealthCare/home_health_care_index_page.dart +++ b/lib/pages/AlHabibMedicalService/HomeHealthCare/home_health_care_index_page.dart @@ -1,3 +1,4 @@ +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; @@ -5,7 +6,6 @@ import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:hexcolor/hexcolor.dart'; import 'home_health_care_page.dart'; @@ -37,9 +37,7 @@ class HomeHealthCareIndexPage extends StatelessWidget { SizedBox( height: 22, ), - Center( - child: Image.asset( - 'assets/images/AlHabibMedicalService/Wifi-AR.png')), + Center(child: Image.asset('assets/images/AlHabibMedicalService/Wifi-AR.png')), SizedBox( height: 77, ), @@ -54,13 +52,13 @@ class HomeHealthCareIndexPage extends StatelessWidget { width: MediaQuery.of(context).size.width * 0.9, child: SecondaryButton( onTap: () => Navigator.push( - context, - FadePage( - page: HomeHealthCarePage(), - ), - ), + context, + FadePage( + page: HomeHealthCarePage(), + ), + ), label: TranslationBase.of(context).loginRegister, - textColor: Theme.of(context).backgroundColor), + textColor: CustomColors.white), ), ], ), diff --git a/lib/pages/AlHabibMedicalService/HomeHealthCare/home_health_care_page.dart b/lib/pages/AlHabibMedicalService/HomeHealthCare/home_health_care_page.dart index b39c918f..7308154f 100644 --- a/lib/pages/AlHabibMedicalService/HomeHealthCare/home_health_care_page.dart +++ b/lib/pages/AlHabibMedicalService/HomeHealthCare/home_health_care_page.dart @@ -2,13 +2,14 @@ import 'dart:ui'; import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/home_health_care_view_model.dart'; -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/base/base_view.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:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; import 'NewHomeHealthCare/new_home_health_care_page.dart'; import 'orders_log_details_page.dart'; @@ -18,9 +19,8 @@ class HomeHealthCarePage extends StatefulWidget { _HomeHealthCarePageState createState() => _HomeHealthCarePageState(); } -class _HomeHealthCarePageState extends State - with SingleTickerProviderStateMixin { - TabController _tabController; +class _HomeHealthCarePageState extends State with SingleTickerProviderStateMixin { + late TabController _tabController; @override void initState() { @@ -36,6 +36,7 @@ class _HomeHealthCarePageState extends State @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); return BaseView( onModelReady: (model) { model.getHHCAllPresOrders(); @@ -44,100 +45,47 @@ class _HomeHealthCarePageState extends State isShowAppBar: true, description: TranslationBase.of(context).HHCNotAuthMsg, appBarTitle: TranslationBase.of(context).homeHealthCare, - imagesInfo: [ - ImagesInfo( - imageAr: 'assets/images/Wifi-AR.png', - imageEn: 'assets/images/wifi-EN.png', - isAsset: true) - ], - body: Scaffold( - extendBodyBehindAppBar: true, - appBar: PreferredSize( - preferredSize: Size.fromHeight(65.0), - child: Stack( - children: [ - Positioned( - bottom: 1, - left: 0, - right: 0, - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10), - child: Container( - color: Theme.of(context) - .scaffoldBackgroundColor - .withOpacity(0.8), - height: 70.0, - ), - ), - ), - Center( - child: Container( - height: 60.0, - margin: EdgeInsets.only(top: 10.0), - width: MediaQuery.of(context).size.width * 0.9, - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Theme.of(context).dividerColor, - width: 0.7), - ), - color: Theme.of(context).primaryColor), - child: Center( - child: TabBar( - isScrollable: true, - controller: _tabController, - indicatorWeight: 5.0, - indicatorSize: TabBarIndicatorSize.tab, - indicatorColor: Colors.red[800], - labelColor: Theme.of(context).primaryColor, - labelPadding: - EdgeInsets.only(top: 4.0, left: 18.0, right: 18.0), - unselectedLabelColor: Colors.grey[800], - tabs: [ - Container( - width: MediaQuery.of(context).size.width * 0.37, - child: Center( - child: Texts( - TranslationBase.of(context).homeHealthCare, - color: Colors.black, - ), - ), - ), - Container( - width: MediaQuery.of(context).size.width * 0.37, - child: Center( - child: Texts( - TranslationBase.of(context).orderLog, - color: Colors.black, - ), - ), - ), - ], - ), - ), - ), - ), - ], + showNewAppBar: true, + showNewAppBarTitle: true, + imagesInfo: [ImagesInfo(imageAr: 'https://hmgwebservices.com/Images/MobileApp/HHC/ar/0.png', imageEn: 'https://hmgwebservices.com/Images/MobileApp/HHC/en/0.png')], + body: Column( + children: [ + TabBar( + controller: _tabController, + indicatorWeight: 3.0, + indicatorSize: TabBarIndicatorSize.tab, + labelColor: Color(0xff2B353E), + unselectedLabelColor: Color(0xff575757), + labelPadding: EdgeInsets.only(top: 15, bottom: 13, 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: [Text(TranslationBase.of(context).homeHealthCare), Text(TranslationBase.of(context).orderLog)], ), - ), - body: Column( - children: [ - Expanded( - child: TabBarView( - physics: BouncingScrollPhysics(), - controller: _tabController, - children: [ - NewHomeHealthCarePage( - model: model, - ), - OrdersLogDetailsPage( - model: model, - ) - ], - ), - ) - ], - ), + Expanded( + child: TabBarView( + physics: BouncingScrollPhysics(), + controller: _tabController, + children: [ + NewHomeHealthCarePage( + model: model, + ), + OrdersLogDetailsPage( + model: model, + ) + ], + ), + ) + ], ), ), ); diff --git a/lib/pages/AlHabibMedicalService/HomeHealthCare/orders_log_details_page.dart b/lib/pages/AlHabibMedicalService/HomeHealthCare/orders_log_details_page.dart index f0ca5fe4..71c40181 100644 --- a/lib/pages/AlHabibMedicalService/HomeHealthCare/orders_log_details_page.dart +++ b/lib/pages/AlHabibMedicalService/HomeHealthCare/orders_log_details_page.dart @@ -1,4 +1,5 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/GetCMCAllOrdersResponseModel.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/get_hhc_all_pres_orders_response_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/update_pres_oreder_request_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/home_health_care_view_model.dart'; @@ -7,8 +8,8 @@ import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/ConfirmWithMessageDialog.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -16,248 +17,163 @@ import 'package:provider/provider.dart'; import 'Dialog/confirm_cancel_order_dialog.dart'; class OrdersLogDetailsPage extends StatelessWidget { - final HomeHealthCareViewModel model; + final HomeHealthCareViewModel? model; - const OrdersLogDetailsPage({Key key, this.model}) : super(key: key); + const OrdersLogDetailsPage({Key? key, this.model}) : super(key: key); @override Widget build(BuildContext context) { ProjectViewModel projectViewModel = Provider.of(context); - void showConfirmMessage( - HomeHealthCareViewModel model, GetHHCAllPresOrdersResponseModel order) { + void showConfirmMessage(HomeHealthCareViewModel model, GetCMCAllOrdersResponseModel order) { showDialog( - context: context, - child: ConfirmCancelOrderDialog( - model: model, - onTap: () async { - UpdatePresOrderRequestModel updatePresOrderRequestModel = - UpdatePresOrderRequestModel( - presOrderID: order.iD, - rejectionReason: "", - presOrderStatus: 4, editedBy: 3); - 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(); - } - }, - )); + context: context, + builder: (cxt) => ConfirmWithMessageDialog( + message: TranslationBase.of(context).cancelOrderMsg, + 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; } return AppScaffold( isShowAppBar: false, baseViewModel: model, - body: SingleChildScrollView( - physics: ScrollPhysics(), - child: Container( - margin: EdgeInsets.all(12), - child: Center( - child: FractionallySizedBox( - widthFactor: 0.94, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 50, + body: model!.hhcAllPresOrders.length > 0 + ? ListView.separated( + padding: EdgeInsets.all(21), + physics: BouncingScrollPhysics(), + itemBuilder: (context, index) { + GetCMCAllOrdersResponseModel order = model!.hhcAllPresOrders.reversed.toList()[index]; + + int status = order.statusId!; + String _statusDisp = order.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 Container( + decoration: BoxDecoration( + color: _color, + borderRadius: BorderRadius.all( + Radius.circular(10.0), + ), + boxShadow: [ + BoxShadow( + color: Color(0xff000000).withOpacity(.05), + blurRadius: 27, + offset: Offset(0, -3), + ), + ], ), - Column( + 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: model.hhcAllPresOrders.map((order) { - return Container( - width: double.infinity, - margin: EdgeInsets.only(top: 15), - decoration: BoxDecoration( - border: - Border.all(color: Colors.grey, width: 1), - borderRadius: BorderRadius.circular(12), - color: Colors.white), + children: [ + Expanded( child: Column( + mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ - SizedBox( - height: 12, + Text( + _statusDisp, + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: _color, letterSpacing: -0.4, height: 16 / 10), ), - Container( - width: double.infinity, - padding: EdgeInsets.only( - left: 15, bottom: 15, top: 15, right: 15), - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Colors.grey, - width: 1.0, - ), - ), - // borderRadius: BorderRadius.circular(12), - color: Colors.white), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts( - TranslationBase - .of(context) - .requestID, - bold: false, - fontSize: 13, - ), - SizedBox( - height: 4, - ), - Texts( - order.iD.toString(), - fontSize: 22, - ), - ], - ), + SizedBox(height: 6), + Text( + '${TranslationBase.of(context).requestID}: ${order.iD}', + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.64, height: 25 / 16), ), - Container( - width: double.infinity, - padding: EdgeInsets.only( - left: 15, bottom: 15, top: 15, right: 15), - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Colors.grey, - width: 1.0, - ), - ), - // borderRadius: BorderRadius.circular(12), - color: Colors.white), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts( - TranslationBase - .of(context) - .OrderStatus, - bold: false, - fontSize: 13, - ), - SizedBox( - height: 4, - ), - Texts( - - projectViewModel.isArabic ? order.descriptionN : order.description, - fontSize: 22, - ), - ], - ), - ), - Container( - width: double.infinity, - padding: EdgeInsets.only( - left: 15, bottom: 15, top: 15, right: 15), - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Colors.grey, - width: 1.0, - ), - ), - // borderRadius: BorderRadius.circular(12), - color: Colors.white), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts( - TranslationBase - .of(context) - .pickupDate, - bold: false, - fontSize: 13, - ), - SizedBox( - height: 4, - ), - Texts( - DateUtil.getDayMonthYearDateFormatted( - DateUtil.convertStringToDate(order.createdOn)), - fontSize: 22, - ), - ], - ), - ), - - SizedBox( - height: 12, - ), - Container( - width: double.infinity, - padding: EdgeInsets.only( - left: 15, bottom: 15, top: 15, right: 15), - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Colors.grey, - width: 1.0, - ), - ), - // borderRadius: BorderRadius.circular(12), - color: Colors.white), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Texts( - TranslationBase.of(context).orderLocation, - bold: false, - fontSize: 13, - ), - SizedBox( - height: 4, - ), - Texts( - !projectViewModel.isArabic ?order.nearestProjectDescription - .toString() : - order.nearestProjectDescriptionN - .toString(), - fontSize: 22, + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).hospital + ": ", + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff575757), letterSpacing: -0.4, height: 16 / 10), + ), + Expanded( + child: Text( + order.nearestProjectName.toString(), + style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.56), ), - ], - ), - ), - SizedBox( - height: 12, - ), - if (order.status == 1 ||order.status == 2 ) - Center( - child: Container( - width: MediaQuery - .of(context) - .size - .width * - 0.85, - child: SecondaryButton( - label: "Cancel".toUpperCase(), - onTap: () { - showConfirmMessage(model, order); - } - , - color: Colors.red[800], - disabled: false, - textColor: Theme - .of(context) - .backgroundColor), ), - ), - SizedBox( - height: 12, - ), + ], + ) ], ), - ); - }).toList()) - ], - ), - ), - ), - ), - ), + ), + Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text( + DateUtil.getDayMonthYearDateFormatted(DateTime.tryParse(order.created!)!), + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.4, height: 16 / 10), + ), + SizedBox(height: 12), + if (order.statusId == 1 || order.statusId == 2) + InkWell( + onTap: () { + showConfirmMessage(model!, order); + }, + 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), + ), + ), + ), + ], + ), + ], + ), + ), + ); + }, + separatorBuilder: (context, index) => SizedBox(height: 12), + itemCount: model!.hhcAllPresOrders.length) + : getNoDataWidget(context), ); } } diff --git a/lib/pages/AlHabibMedicalService/all_habib_medical_service_page.dart b/lib/pages/AlHabibMedicalService/all_habib_medical_service_page.dart index 21f277d9..c12aa36a 100644 --- a/lib/pages/AlHabibMedicalService/all_habib_medical_service_page.dart +++ b/lib/pages/AlHabibMedicalService/all_habib_medical_service_page.dart @@ -1,7 +1,10 @@ import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/service/weather_service.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/locator.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; +import 'package:diplomaticquarterapp/models/hmg_services.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/%E2%80%8B%20health_calculators.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/E-Referral/e_referral_page.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/ancillary-orders/ancillaryOrders.dart'; @@ -10,17 +13,24 @@ import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/health_converte import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/my_web_view.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/parking_page.dart'; import 'package:diplomaticquarterapp/pages/Blood/blood_donation.dart'; -import 'package:diplomaticquarterapp/pages/BookAppointment/BookingOptions.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'; import 'package:diplomaticquarterapp/pages/DrawerPages/family/my-family.dart'; import 'package:diplomaticquarterapp/pages/ErService/ErOptions.dart'; -import 'package:diplomaticquarterapp/pages/ToDoList/ToDo.dart'; import 'package:diplomaticquarterapp/pages/insurance/insurance_update_screen.dart'; +import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; +import 'package:diplomaticquarterapp/pages/landing/landing_page_pharmcy.dart'; import 'package:diplomaticquarterapp/pages/livecare/livecare_home.dart'; +import 'package:diplomaticquarterapp/pages/medical/medical_profile_page_new.dart'; +import 'package:diplomaticquarterapp/pages/medical/smart_watch_health_data/smart_watch_instructions.dart'; import 'package:diplomaticquarterapp/pages/paymentService/payment_service.dart'; -import 'package:diplomaticquarterapp/pages/symptom-checker/info.dart'; +import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/location_util.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/data_display/services)contaniner.dart'; @@ -38,9 +48,9 @@ import 'h2o/h2o_page.dart'; class AllHabibMedicalService extends StatefulWidget { //TODO - final Function goToMyProfile; + final Function? goToMyProfile; - AllHabibMedicalService({Key key, this.goToMyProfile}); + AllHabibMedicalService({Key? key, this.goToMyProfile}); @override _AllHabibMedicalServiceState createState() => _AllHabibMedicalServiceState(); @@ -49,25 +59,39 @@ class AllHabibMedicalService extends StatefulWidget { class _AllHabibMedicalServiceState extends State { AppSharedPreferences sharedPref = AppSharedPreferences(); AuthenticatedUser authUser = new AuthenticatedUser(); - LocationUtils locationUtils; + AuthProvider authProvider = new AuthProvider(); + PharmacyModuleViewModel pharmacyModuleViewModel = locator(); + late LocationUtils locationUtils; var weather = '--'; WeatherService _weatherService = WeatherService(); + List hmgServices = []; + @override void initState() { WidgetsBinding.instance.addPostFrameCallback((timeStamp) { - locationUtils = - new LocationUtils(isShowConfirmDialog: true, context: context); - WidgetsBinding.instance.addPostFrameCallback((_) => { - Geolocator.getLastKnownPosition() - .then((value) => setLocation(value)) - }); + locationUtils = new LocationUtils(isShowConfirmDialog: true, context: context); + WidgetsBinding.instance.addPostFrameCallback((_) => {Geolocator.getLastKnownPosition().then((value) => setLocation(value!))}); }); super.initState(); } + 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(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).online, TranslationBase.of(context).payment, "assets/images/new/visa.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).checkup, TranslationBase.of(context).comprehensive, "assets/images/new/comprehensive_checkup.svg", isLogin)); + hmgServices.add(new HmgServices(5, "RRT", TranslationBase.of(context).emergency, "assets/images/new/emergency.svg", isLogin)); + hmgServices.add(new HmgServices(6, TranslationBase.of(context).refferal, TranslationBase.of(context).services2, "assets/images/new/E_Referral.svg", isLogin)); + hmgServices.add(new HmgServices(7, "H\u2082O", TranslationBase.of(context).dailyWater, "assets/images/new/h2o.svg", isLogin)); + hmgServices.add(new HmgServices(8, TranslationBase.of(context).reachUs, TranslationBase.of(context).findUs, "assets/images/new/reach_us.svg", isLogin)); + } + @override Widget build(BuildContext context) { ProjectViewModel projectViewModel = Provider.of(context); + initialiseHmgServices(false); return AppScaffold( isShowAppBar: true, appBarTitle: TranslationBase.of(context).alhabiServices, @@ -99,14 +123,12 @@ class _AllHabibMedicalServiceState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Texts( - TranslationBase.of(context) - .healthWeatherIndicators, + TranslationBase.of(context).healthWeatherIndicators, color: Colors.white, fontWeight: FontWeight.w600, ), Texts( - TranslationBase.of(context) - .healthTipsBasedOnCurrentWeather, + TranslationBase.of(context).healthTipsBasedOnCurrentWeather, color: Colors.white, fontSize: 14, ), @@ -134,11 +156,7 @@ class _AllHabibMedicalServiceState extends State { width: 60, height: 60, ), - Directionality( - textDirection: TextDirection.ltr, - child: AppText(weather, - fontSize: 22, - color: Colors.white)) + Directionality(textDirection: TextDirection.ltr, child: AppText(weather, fontSize: 22, color: Colors.white)) ], ), Texts( @@ -156,10 +174,14 @@ class _AllHabibMedicalServiceState extends State { ServicesContainer( onTap: () { Navigator.pop(context); - widget.goToMyProfile(); + Navigator.push( + context, + FadePage( + page: MedicalProfilePageNew(), + ), + ); }, - imageLocation: - 'assets/images/new-design/my_file_bottom_bar.png', + imageLocation: 'assets/images/new-design/my_file_bottom_bar.png', title: TranslationBase.of(context).myMedicalFile, ), ServicesContainer( @@ -176,13 +198,10 @@ class _AllHabibMedicalServiceState extends State { onTap: () => Navigator.push( context, FadePage( - page: BookingOptions( - isAppbar: true, - ), + page: Search(), ), ), - imageLocation: - 'assets/images/new-design/booking_icon_active.png', + imageLocation: 'assets/images/new-design/booking_icon_active.png', title: TranslationBase.of(context).bookAppo, ), ServicesContainer( @@ -192,8 +211,7 @@ class _AllHabibMedicalServiceState extends State { page: PaymentService(), ), ), - imageLocation: - 'assets/images/al-habib_online_payment_service_icon.png', + imageLocation: 'assets/images/al-habib_online_payment_service_icon.png', title: TranslationBase.of(context).onlinePaymentService, ), ServicesContainer( @@ -203,17 +221,15 @@ class _AllHabibMedicalServiceState extends State { page: AnicllaryOrders(), ), ), - imageLocation: - 'assets/images/comprehensive_medical_checkup_logo.png', + imageLocation: 'assets/images/comprehensive_medical_checkup_logo.png', title: TranslationBase.of(context).anicllaryOrders, ), ServicesContainer( onTap: () => Navigator.push( context, - FadePage(), + FadePage(page: CovidDrivethruLocation()), ), - imageLocation: - 'assets/images/al-habib_online_payment_service_icon.png', + imageLocation: 'assets/images/covid-car.png', title: TranslationBase.of(context).covid19_driveThrueTest, ), ServicesContainer( @@ -230,15 +246,7 @@ class _AllHabibMedicalServiceState extends State { imageLocation: 'assets/images/emergency_service_image.png', title: TranslationBase.of(context).emergencyService, ), - ServicesContainer( - onTap: () => Navigator.push( - context, - FadePage( - page: ParkingPage(), - ), - ), - imageLocation: 'assets/images/pharmacy_logo.png', - title: TranslationBase.of(context).pharmacy), + ServicesContainer(onTap: () => getPharmacyToken(), imageLocation: 'assets/images/pharmacy_logo.png', title: TranslationBase.of(context).pharmacy), ServicesContainer( onTap: () => Navigator.push( context, @@ -246,15 +254,13 @@ class _AllHabibMedicalServiceState extends State { page: InsuranceUpdate(), ), ), - imageLocation: - 'assets/images/medical/insurance_card_icon.png', + imageLocation: 'assets/images/medical/insurance_card_icon.png', title: TranslationBase.of(context).updateInsurance, ), ServicesContainer( onTap: () => Navigator.push( context, - FadePage( - page: EReferralPage()), + FadePage(page: EReferralPage()), ), imageLocation: 'assets/images/ereferral_service_icon.png', title: TranslationBase.of(context).ereferral, @@ -266,39 +272,26 @@ class _AllHabibMedicalServiceState extends State { page: MyFamily(), ), ), - imageLocation: - 'assets/images/new-design/family_menu_icon_red.png', + imageLocation: 'assets/images/new-design/family_icon_bottom_bar.png', title: TranslationBase.of(context).myFamily, ), if (projectViewModel.havePrivilege(35)) ServicesContainer( onTap: () => Navigator.push( context, - FadePage(page: ChildVaccinesPage()), + FadePage(page: ChildInitialPage()), ), - imageLocation: - 'assets/images/new-design/children_vaccines_icon.png', + imageLocation: 'assets/images/new-design/children_vaccines_icon.png', title: TranslationBase.of(context).childVaccine, ), ServicesContainer( - onTap: () => Navigator.push( - context, - FadePage( - page: ToDo(isShowAppBar: true), - ), - ), - imageLocation: - 'assets/images/new-design/upcoming_icon_bottom_bar.png', + onTap: () { + Navigator.pop(context); + LandingPage.shared.switchToDoFromHMGServices(); + }, + imageLocation: 'assets/images/new-design/upcoming_icon_bottom_bar.png', title: TranslationBase.of(context).todoList, ), - if (projectViewModel.havePrivilege(42)) - ServicesContainer( - onTap: () => Navigator.push( - context, - FadePage(page: SymptomInfo()), - ), - imageLocation: 'assets/images/new-design/body_icon.png', - title: TranslationBase.of(context).symptomCheckerTitle), if (projectViewModel.havePrivilege(36)) ServicesContainer( onTap: () => Navigator.push( @@ -315,8 +308,7 @@ class _AllHabibMedicalServiceState extends State { page: (HealthCalculators()), ), ), - imageLocation: - 'assets/images/new-design/health_calculator_icon.png', + imageLocation: 'assets/images/new-design/health_calculator_icon.png', title: TranslationBase.of(context).calculators, ), ServicesContainer( @@ -326,20 +318,12 @@ class _AllHabibMedicalServiceState extends State { page: HealthConverter(), ), ), - imageLocation: - 'assets/images/new-design/health_convertor_icon.png', + imageLocation: 'assets/images/new-design/health_convertor_icon.png', title: TranslationBase.of(context).converters, ), if (projectViewModel.havePrivilege(38)) ServicesContainer( - onTap: () => - Navigator.push(context, FadePage(page: H2OPage())), - // Navigator.push( - // context, - // FadePage( - // page: H2OPageIndexPage(), - // ), - // ), + onTap: () => Navigator.push(context, FadePage(page: H2OPage())), imageLocation: 'assets/images/new-design/water_icon.png', title: TranslationBase.of(context).h2o, ), @@ -347,10 +331,9 @@ class _AllHabibMedicalServiceState extends State { ServicesContainer( onTap: () => Navigator.push( context, - FadePage(), + FadePage(page: SmartWatchInstructions()), ), - imageLocation: - 'assets/images/new-design/smartwatch_icon.png', + imageLocation: 'assets/images/new-design/smartwatch_icon.png', title: TranslationBase.of(context).smartWatches, ), ServicesContainer( @@ -360,15 +343,12 @@ class _AllHabibMedicalServiceState extends State { page: ParkingPage(), ), ), - imageLocation: - 'assets/images/new-design/parking_system_icon.png', + imageLocation: 'assets/images/new-design/parking_system_icon.png', title: TranslationBase.of(context).parking, ), ServicesContainer( - onTap: () => launch( - "https://hmgwebservices.com/vt_mobile/html/index.html"), - imageLocation: - 'assets/images/new-design/virtual_tour_icon.png', + onTap: () => launch("https://hmgwebservices.com/vt_mobile/html/index.html"), + imageLocation: 'assets/images/new-design/virtual_tour_icon.png', title: TranslationBase.of(context).vTour, ), ServicesContainer( @@ -376,12 +356,10 @@ class _AllHabibMedicalServiceState extends State { Navigator.of(context).push(MaterialPageRoute( builder: (BuildContext context) => MyWebView( title: "HMG News", - selectedUrl: - "https://twitter.com/hashtag/مجموعة_د_سليمان_الحبيب_الطبية?src=hashtag_click&f=live", + selectedUrl: " https://twitter.com/HMG", //"https://twitter.com/hashtag/مجموعة_د_سليمان_الحبيب_الطبية?src=hashtag_click&f=live", //this url is not working so changed to the hmg ))); }, - imageLocation: - 'assets/images/new-design/twitter_dashboard_icon.png', + imageLocation: 'assets/images/new-design/twitter_dashboard_icon.png', title: TranslationBase.of(context).latestNews, ), ServicesContainer( @@ -402,10 +380,28 @@ class _AllHabibMedicalServiceState extends State { ); } + getPharmacyToken() async { + if (!authProvider.isLogin) { + Navigator.push(context, FadePage(page: LandingPagePharmacy())); + } else { + GifLoaderDialogUtils.showMyDialog(context); + await pharmacyModuleViewModel.generatePharmacyToken().then((value) async { + if (pharmacyModuleViewModel.error.isNotEmpty) { + await pharmacyModuleViewModel.createUser().then((value) { + GifLoaderDialogUtils.hideDialog(context); + Navigator.push(context, FadePage(page: LandingPagePharmacy())); + }); + } else { + GifLoaderDialogUtils.hideDialog(context); + Navigator.push(context, FadePage(page: LandingPagePharmacy())); + } + }); + } + } + getAuthUser() async { 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)); setState(() { authUser = data; }); @@ -419,8 +415,7 @@ class _AllHabibMedicalServiceState extends State { }); } else { setState(() { - weather = - data != null ? data['Temperature'].toString() + '\u2103' : '--'; + weather = data != null ? data['Temperature'].toString() + '\u2103' : '--'; }); } } diff --git a/lib/pages/AlHabibMedicalService/all_habib_medical_service_page2.dart b/lib/pages/AlHabibMedicalService/all_habib_medical_service_page2.dart new file mode 100644 index 00000000..420f08f1 --- /dev/null +++ b/lib/pages/AlHabibMedicalService/all_habib_medical_service_page2.dart @@ -0,0 +1,277 @@ +import 'dart:io'; + +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/service/weather_service.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; +import 'package:diplomaticquarterapp/models/hmg_services.dart'; +import 'package:diplomaticquarterapp/pages/landing/widgets/services_view.dart'; +import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; +import 'package:diplomaticquarterapp/services/permission/permission_service.dart'; +import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/location_util.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/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'; + +import 'health-weather/health-weather-indicator.dart'; + +class AllHabibMedicalSevicePage2 extends StatefulWidget { + @override + _AllHabibMedicalSevicePage2State createState() => _AllHabibMedicalSevicePage2State(); +} + +class _AllHabibMedicalSevicePage2State extends State { + List hmgServices = []; + late LocationUtils locationUtils; + var weather = '--'; + AppSharedPreferences sharedPref = AppSharedPreferences(); + AuthenticatedUser authUser = new AuthenticatedUser(); + AuthProvider authProvider = new AuthProvider(); + WeatherService _weatherService = WeatherService(); + double weatherNum = 30; + late ProjectViewModel projectViewModel; + + @override + void initState() { + // TODO: implement initState + super.initState(); + WidgetsBinding.instance.addPostFrameCallback((timeStamp) { + locationUtils = new LocationUtils(isShowConfirmDialog: true, context: context); + WidgetsBinding.instance.addPostFrameCallback((_) async => { + if (await PermissionService.isLocationEnabled()) + {Geolocator.getLastKnownPosition().then((value) => setLocation(value!))} + else + { + if (Platform.isAndroid) + { + Utils.showPermissionConsentDialog(context, TranslationBase.of(context).locationPermissionDialog, () { + Geolocator.getLastKnownPosition().then((value) => setLocation(value!)); + }) + } + else + {Geolocator.getLastKnownPosition().then((value) => setLocation(value!))} + } + }); + }); + } + + initialiseHmgServices(bool isLogin) { + hmgServices.clear(); + + hmgServices.add(new HmgServices(0, TranslationBase.of(context).book, TranslationBase.of(context).appointmentLabel, "assets/images/new/book appointment.svg", isLogin)); + hmgServices.add(new HmgServices(1, TranslationBase.of(context).liveCare, TranslationBase.of(context).onlineConsulting, "assets/images/new/Live_Care.svg", isLogin)); + hmgServices.add(new HmgServices(2, TranslationBase.of(context).emergencyTitle, TranslationBase.of(context).emergencySubtitle, "assets/images/new/emergency.svg", isLogin)); + hmgServices.add(new HmgServices(3, TranslationBase.of(context).hhcHome, TranslationBase.of(context).healthCare, "assets/images/new/HHC.svg", isLogin)); + hmgServices.add(new HmgServices(4, TranslationBase.of(context).checkup, TranslationBase.of(context).comprehensive, "assets/images/new/comprehensive_checkup.svg", isLogin)); + hmgServices.add(new HmgServices(5, TranslationBase.of(context).pharmacyTitle, TranslationBase.of(context).pharmacySubtitle, "assets/images/new/Pharmacy.svg", isLogin)); + + hmgServices.add(new HmgServices(6, TranslationBase.of(context).medicalFileTitle2, TranslationBase.of(context).medicalFileSubtitle, "assets/images/new/medical file.svg", isLogin)); + hmgServices.add(new HmgServices(7, TranslationBase.of(context).familyTitle, TranslationBase.of(context).familySubtitle, "assets/images/new/my family.svg", isLogin)); + hmgServices.add(new HmgServices(8, TranslationBase.of(context).online, TranslationBase.of(context).payment, "assets/images/new/paymentMethods.png", isLogin)); + hmgServices.add(new HmgServices(9, TranslationBase.of(context).My_Child, TranslationBase.of(context).Vaccines, "assets/images/new/child vaccines.svg", isLogin)); + hmgServices.add(new HmgServices(10, TranslationBase.of(context).updateInsurance, TranslationBase.of(context).updateInsuranceSubtitle, "assets/images/new/update insurance card.svg", isLogin)); + hmgServices.add(new HmgServices(11, TranslationBase.of(context).ereferralTitle, TranslationBase.of(context).ereferralSubtitle, "assets/images/new/E_Referral.svg", isLogin)); + hmgServices.add(new HmgServices(12, TranslationBase.of(context).waterTitle, TranslationBase.of(context).waterSubtitle, "assets/images/new/h2o.svg", isLogin)); + hmgServices.add(new HmgServices(13, TranslationBase.of(context).healthCalculatorTitle, TranslationBase.of(context).healthCalculatorSubtitle, "assets/images/new/health calculator.svg", isLogin)); + hmgServices.add(new HmgServices(14, TranslationBase.of(context).healthConvertersTitle, TranslationBase.of(context).healthConvertersSubtitle, "assets/images/new/health converter.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).covidTest, TranslationBase.of(context).driveThru, "assets/images/new/CoronaIcon.svg", isLogin)); + + hmgServices.add(new HmgServices(18, TranslationBase.of(context).Virtual, TranslationBase.of(context).Tour, "assets/images/new/virtual tour.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).latestNews.split(" ")[0], TranslationBase.of(context).latestNews.split(" ")[1], "assets/images/new/latest news.svg", isLogin)); + + hmgServices.add(new HmgServices(22, TranslationBase.of(context).connectTitle, TranslationBase.of(context).connectSubtitle, "assets/images/new/reach_us.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, TranslationBase.of(context).waterTitle, TranslationBase.of(context).waterSubtitle, "assets/images/new/h2o.svg", isLogin)); + // hmgServices.add(new HmgServices(8, TranslationBase.of(context).connectTitle, TranslationBase.of(context).connectSubtitle, "assets/images/new/reach_us.svg", isLogin)); + // hmgServices.add(new HmgServices(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).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).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).latestNews.split(" ")[0], TranslationBase.of(context).latestNews.split(" ")[1], "assets/images/new/latest news.svg", isLogin)); + } + + @override + Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + initialiseHmgServices(false); + return AppScaffold( + isShowAppBar: true, + isShowDecPage: false, + showNewAppBar: true, + showNewAppBarTitle: true, + appBarTitle: TranslationBase.of(context).hMGService, + body: Container( + width: double.infinity, + height: double.infinity, + child: SingleChildScrollView( + child: Column( + children: [ + 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( + textDirection: TextDirection.ltr, + child: Text( + weather, + style: TextStyle( + fontSize: 24, + letterSpacing: -0.83, + fontWeight: FontWeight.bold, + color: Colors.white, + ), + ), + ), + Text( + DateUtil.getMonthDayYearDateFormatted(new DateTime.now()), + style: TextStyle( + fontSize: 12, + letterSpacing: -0.60, + fontWeight: FontWeight.w600, + color: Colors.white, + ), + ), + Text( + TranslationBase.of(context).healthWeatherIndicators, + style: TextStyle( + fontSize: 12, + letterSpacing: -0.96, + fontWeight: FontWeight.bold, + color: Colors.white, + ), + ), + Text( + TranslationBase.of(context).healthTipsBasedOnCurrentWeather, + style: TextStyle( + fontSize: 10, + letterSpacing: -0.72, + fontWeight: FontWeight.w600, + color: Colors.white, + ), + ), + ], + ), + ), + 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), + ), + ), + ) + ], + ), + ], + ), + ), + ), + mHeight(16), + Padding( + padding: const EdgeInsets.only( + left: 16, + right: 16, + top: 0, + ), + child: GridView.builder( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, childAspectRatio: 2 / 2, crossAxisSpacing: 12, mainAxisSpacing: 12), + physics: NeverScrollableScrollPhysics(), + shrinkWrap: true, + itemCount: hmgServices.length, + padding: EdgeInsets.zero, + itemBuilder: (BuildContext context, int index) { + return ServicesView(hmgServices[index], index, false, projectViewModel); + }, + ), + ), + mHeight(16), + ], + ), + ), + ), + ); + } + + void setLocation(Position position) { + this.sharedPref.setDouble(USER_LAT, position.latitude ?? 0.0); + this.sharedPref.setDouble(USER_LONG, position.longitude ?? 0.0); + getAuthUser(); + } + + getAuthUser() async { + if (await this.sharedPref.getObject(USER_PROFILE) != null) { + var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE)); + setState(() { + authUser = data; + }); + } + var data = await this.sharedPref.getObject(WEATHER); + if (data == null) { + var d = await _weatherService.getWeatherData(); + weatherNum = d.temperature; + setState(() { + weather = d != null ? d.temperature.toString() + '\u2103' : '--'; + }); + } else { + setState(() { + weather = data != null ? data['Temperature'].toString() + '\u2103' : '--'; + }); + } + } +} diff --git a/lib/pages/AlHabibMedicalService/ancillary-orders/ancillaryOrders.dart b/lib/pages/AlHabibMedicalService/ancillary-orders/ancillaryOrders.dart index eccc1309..37aa7e91 100644 --- a/lib/pages/AlHabibMedicalService/ancillary-orders/ancillaryOrders.dart +++ b/lib/pages/AlHabibMedicalService/ancillary-orders/ancillaryOrders.dart @@ -1,22 +1,26 @@ import 'package:diplomaticquarterapp/core/viewModels/ancillary_orders_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/ancillary-orders/ancillaryOrdersDetails.dart'; -import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/health_calculator/calorie_calculator/calorie_calculator.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/medical/doctor_card.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:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:provider/provider.dart'; class AnicllaryOrders extends StatefulWidget { @override _AnicllaryOrdersState createState() => _AnicllaryOrdersState(); } -class _AnicllaryOrdersState extends State - with SingleTickerProviderStateMixin { - TabController _tabController; +class _AnicllaryOrdersState extends State with SingleTickerProviderStateMixin { + TabController? _tabController; + late ProjectViewModel projectViewModel; + void initState() { super.initState(); _tabController = TabController(length: 2, vsync: this); @@ -24,63 +28,108 @@ class _AnicllaryOrdersState extends State void dispose() { super.dispose(); - _tabController.dispose(); + _tabController!.dispose(); } @override Widget build(BuildContext context) { + projectViewModel = Provider.of(context); return BaseView( onModelReady: (model) => model.getOrders(), builder: (_, model, widget) => AppScaffold( isShowAppBar: true, + showNewAppBar: true, + showNewAppBarTitle: true, baseViewModel: model, appBarTitle: TranslationBase.of(context).anicllaryOrders, body: SingleChildScrollView( - padding: EdgeInsets.all(12), - child: model.ancillaryLists.length > 0 - ? Column(children: [ - getPatientInfo(model), - getAncillaryOrdersList(model) - ]) - : SizedBox()))); + padding: EdgeInsets.all(12), child: model.ancillaryLists.length > 0 ? Column(children: [getPatientInfo(model), getAncillaryOrdersList(model)]) : getNoDataWidget(context)))); } Widget getPatientInfo(AnciallryOrdersViewModel model) { - print(model.ancillaryLists); return Padding( child: Column( children: [ - Row( - children: [ - Texts( - TranslationBase.of(context).mrn, - fontWeight: FontWeight.bold, - fontSize: 22, + Container( + width: double.infinity, + child: Container( + decoration: cardRadius(12), + margin: EdgeInsets.zero, + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Text( + TranslationBase.of(context).patientName + ":", + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 10, + letterSpacing: -0.6, + color: CustomColors.grey, + ), + ), + mWidth(3), + Text( + projectViewModel.user!.firstName! + " " + projectViewModel.user!.lastName!, + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 12, + letterSpacing: -0.48, + ), + ), + ], + ), + Row( + children: [ + Text( + TranslationBase.of(context).mrn + ":", + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 10, + letterSpacing: -0.6, + color: CustomColors.grey, + ), + ), + mWidth(3), + Text( + projectViewModel!.user!.patientID.toString(), + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 12, + letterSpacing: -0.48, + ), + ), + ], + ), + Row( + children: [ + Text( + TranslationBase.of(context).nationalIdNumber + ":", + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 10, + letterSpacing: -0.6, + color: CustomColors.grey, + ), + ), + mWidth(3), + Text( + projectViewModel!.user!.patientIdentificationNo!, + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 12, + letterSpacing: -0.48, + ), + ), + ], + ), + ], + ), ), - Texts( - " : ", - fontSize: 20, - ), - Texts( - model.ancillaryLists[0].patientID.toString(), - ) - ], - ), - Row( - children: [ - Texts( - TranslationBase.of(context).patientName, - fontWeight: FontWeight.bold, - fontSize: 20, - ), - Texts( - " : ", - fontSize: 20, - ), - Texts( - model.ancillaryLists[0].patientName, - ) - ], + ), ), Divider() ], @@ -90,87 +139,35 @@ class _AnicllaryOrdersState extends State } Widget getAncillaryOrdersList(AnciallryOrdersViewModel model) { - return Column( - children: model.ancillaryLists[0].ancillaryOrderList - .map( - (item) => InkWell( - onTap: () { - ancillaryOrdersDetails(item); - }, - child: Container( - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - width: 0.5, - ))), - padding: EdgeInsets.all(15), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: EdgeInsets.all(3), - child: Row( - mainAxisAlignment: - MainAxisAlignment.start, - children: [ - Texts( - TranslationBase.of(context) - .appointmentNo + - ' : ', - fontWeight: FontWeight.bold, - ), - Texts(item.appointmentNo.toString()) - ], - )), - Padding( - padding: EdgeInsets.all(3), - child: Row( - children: [ - Texts( - TranslationBase.of(context) - .appointmentDate + - ' : ', - fontWeight: FontWeight.bold), - Texts(DateUtil.getFormattedDate( - DateUtil.convertStringToDate( - item.appointmentDate), - "MMM dd,yyyy")) - ], - )), - Padding( - padding: EdgeInsets.all(3), - child: Row( - children: [ - Texts( - TranslationBase.of(context) - .doctorName + - ' : ', - fontWeight: FontWeight.bold), - Texts(item.doctorName.toString()) - ], - )), - Divider( - color: Colors.black12, - height: 1, - ) - ]), - Icon( - Icons.arrow_right, - size: 25, - ) - ]))), - ) - .toList()); + return Column(children: [ + ListView.separated( + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + reverse: true, + itemBuilder: (context, index) { + return DoctorCard( + onTap: () => ancillaryOrdersDetails(model.ancillaryLists[0].ancillaryOrderList![index], model.ancillaryLists[0].projectID), + isInOutPatient: true, + name: TranslationBase.of(context).dr.toString() + " " + (model.ancillaryLists[0].ancillaryOrderList![index].doctorName ?? ""), + billNo: model.ancillaryLists[0].ancillaryOrderList![index].orderNo.toString(), + profileUrl: "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png", + subName: model.ancillaryLists[0].projectName, + isLiveCareAppointment: false, + date: DateUtil.convertStringToDate(model.ancillaryLists[0].ancillaryOrderList![index].orderDate!), + isSortByClinic: true, + ); + }, + itemCount: model.ancillaryLists[0].ancillaryOrderList!.length, + separatorBuilder: (context, index) => SizedBox(height: 14), + ), + ]); } - ancillaryOrdersDetails(item) { + ancillaryOrdersDetails(item, projectId) { Navigator.push( context, FadePage( - page: AnicllaryOrdersDetails(item.appointmentNo, item.orderNo), + page: AnicllaryOrdersDetails(item.appointmentNo, item.orderNo, projectId), ), ); } diff --git a/lib/pages/AlHabibMedicalService/ancillary-orders/ancillaryOrdersDetails.dart b/lib/pages/AlHabibMedicalService/ancillary-orders/ancillaryOrdersDetails.dart index 20d2966b..464786df 100644 --- a/lib/pages/AlHabibMedicalService/ancillary-orders/ancillaryOrdersDetails.dart +++ b/lib/pages/AlHabibMedicalService/ancillary-orders/ancillaryOrdersDetails.dart @@ -1,25 +1,68 @@ -import 'package:diplomaticquarterapp/core/viewModels/ancillary_orders_view_model.dart'; -import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'dart:developer'; +import 'dart:io'; + +import "package:collection/collection.dart"; +import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/enum/PayfortEnums.dart'; +import 'package:diplomaticquarterapp/core/service/ancillary_orders_service.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; +import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; +import 'package:diplomaticquarterapp/models/LiveCare/ApplePayInsertRequest.dart'; +import 'package:diplomaticquarterapp/models/anicllary-orders/ancillary_order_proc_model.dart'; +import 'package:diplomaticquarterapp/pages/ToDoList/payment_method_select.dart'; +import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; +import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; +import 'package:diplomaticquarterapp/services/livecare_services/livecare_provider.dart'; +import 'package:diplomaticquarterapp/services/payfort_services/payfort_project_details_resp_model.dart'; +import 'package:diplomaticquarterapp/services/payfort_services/payfort_view_model.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/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:flutter/material.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/dialogs/alert_dialog.dart'; +import 'package:diplomaticquarterapp/widgets/dragable_sheet.dart'; +import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; -import "package:collection/collection.dart"; -import 'package:diplomaticquarterapp/widgets/text/app_texts_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:provider/provider.dart'; class AnicllaryOrdersDetails extends StatefulWidget { final dynamic appoNo; final dynamic orderNo; - AnicllaryOrdersDetails(this.appoNo, this.orderNo); + final dynamic projectID; + + AnicllaryOrdersDetails(this.appoNo, this.orderNo, this.projectID); + @override _AnicllaryOrdersState createState() => _AnicllaryOrdersState(); } -class _AnicllaryOrdersState extends State - with SingleTickerProviderStateMixin { +class _AnicllaryOrdersState extends State with SingleTickerProviderStateMixin { + late ProjectViewModel projectViewModel; + bool _agreeTerms = false; + String selectedPaymentMethod = ""; + late MyInAppBrowser browser; + String transID = ""; + late BuildContext localContext; + String? selectedInstallmentPlan; + + List selectedProcList = []; + List _ancillaryProcLists = []; + + String? tamaraPaymentStatus; + String? tamaraOrderID; + void initState() { + WidgetsBinding.instance.addPostFrameCallback((_) { + getAncillaryOrderDetails(); + }); super.initState(); } @@ -27,254 +70,828 @@ class _AnicllaryOrdersState extends State super.dispose(); } - @override - Widget build(BuildContext context) { - return BaseView( - onModelReady: (model) => - model.getOrdersDetails(widget.appoNo, widget.orderNo), - builder: (_, model, widget) => AppScaffold( - isShowAppBar: true, - baseViewModel: model, - appBarTitle: TranslationBase.of(context).anicllaryOrders, - body: SingleChildScrollView( - padding: EdgeInsets.all(12), - child: model.ancillaryListsDetails.length > 0 - ? Column(children: [ - getPatientInfo(model), - getInvoiceDetails(model), - getInsuranceDetails(model), - getAncillaryDetails(model), - Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - Texts( - TranslationBase.of(context).total, - fontSize: 20, - fontWeight: FontWeight.bold, - ), - Texts( - getTotalValue(model), - fontSize: 20, - fontWeight: FontWeight.bold, - ) - ], - ), - Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - Button( - label: TranslationBase.of(context).payNow, - onTap: () {}, - ) - ], - ) - ]) - : SizedBox()))); + addSelectedProcedure(AncillaryOrderProcDetailsList ancillaryOrderProcDetailsList) { + if (!checkIfProcedureSelected(ancillaryOrderProcDetailsList)) { + selectedProcList.add(ancillaryOrderProcDetailsList); + } else { + selectedProcList.remove(ancillaryOrderProcDetailsList); + } } - Widget getPatientInfo(AnciallryOrdersViewModel model) { - print(model.ancillaryListsDetails); - return Padding( - child: Column( - children: [ - Row( - children: [ - Texts( - TranslationBase.of(context).mrn, - fontWeight: FontWeight.bold, - fontSize: 22, - ), - Texts( - " : ", - fontSize: 20, - ), - Texts( - model.ancillaryListsDetails[0].patientID.toString(), - ) - ], - ), - Row( - children: [ - Texts( - TranslationBase.of(context).patientName, - fontWeight: FontWeight.bold, - fontSize: 20, - ), - Texts( - " : ", - fontSize: 20, - ), - Texts( - model.ancillaryLists[0].patientName, - ) - ], - ), - Divider( - color: Colors.black26, - ) - ], - ), - padding: EdgeInsets.only(top: 5.0, bottom: 5.0), - ); + void getAncillaryOrderDetails() { + GifLoaderDialogUtils.showMyDialog(context); + AncillaryOrdersService ancillaryOrdersService = new AncillaryOrdersService(); + ancillaryOrdersService.getOrdersDetails(widget.appoNo, widget.orderNo, widget.projectID).then((response) { + _ancillaryProcLists = []; + selectedProcList = []; + if (response['AncillaryOrderProcList'] != null && response['AncillaryOrderProcList'].length != 0) { + response['AncillaryOrderProcList'].forEach((item) { + _ancillaryProcLists.add(AncillaryOrdersListProcListModel.fromJson(item)); + }); + addToSelectedProcedures(); + } + GifLoaderDialogUtils.hideDialog(context); + }).catchError((err) { + AppToast.showErrorToast(message: err.toString()); + GifLoaderDialogUtils.hideDialog(context); + }); } - Widget getInvoiceDetails(model) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - Texts( - TranslationBase.of(context).invoiceNo, - fontWeight: FontWeight.bold, + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + localContext = context; + AppGlobal.context = context; + return AppScaffold( + isShowAppBar: true, + showNewAppBar: true, + showNewAppBarTitle: true, + appBarTitle: TranslationBase.of(context).anicllaryOrders, + body: SingleChildScrollView( + padding: EdgeInsets.all(12), + child: _ancillaryProcLists.isNotEmpty + ? Column( + children: [ + getPatientInfo(), + getAncillaryDetails(), + ], + ) + : getNoDataWidget(context), + ), + bottomSheet: Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10), bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10)), + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.5), + spreadRadius: 5, + blurRadius: 7, + offset: Offset(0, 3), // changes position of shadow ), - Texts(" : "), - Texts( - model.ancillaryListsDetails[0].appointmentNo.toString(), - ) ], ), - Row( + padding: EdgeInsets.only(left: 21, right: 21, top: 15, bottom: 15), + width: double.infinity, + // color: Colors.white, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, children: [ - Texts( - TranslationBase.of(context).date, - fontWeight: FontWeight.bold, + SizedBox(height: 12), + Text( + TranslationBase.of(context).YouCanPayByTheFollowingOptions, + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), ), - Texts(" : "), - Texts( - DateUtil.getFormattedDate( - DateUtil.convertStringToDate( - model.ancillaryListsDetails[0].appointmentDate), - "MMM dd,yyyy"), - ) - ], - ), - Row( - children: [ - Texts( - TranslationBase.of(context).date, - fontWeight: FontWeight.bold, + SizedBox( + width: MediaQuery.of(context).size.width * 0.75, + child: getPaymentMethods(), ), - Texts(" : "), - Texts( - model.ancillaryListsDetails[0].doctorName, + _amountView(TranslationBase.of(context).patientShareTotalToDo, getTotalValue(), isBold: true, isTotal: true), + // _amountView(TranslationBase.of(context).patientShareTotalToDo, getTotalValue(), isBold: true, isTotal: true), + SizedBox(height: 12), + DefaultButton( + TranslationBase.of(context).payNow.toUpperCase(), + selectedProcList.length > 0 + ? () { + if (getTotalValue() != "0.00") { + makePayment(); + } else { + autoGenerateInvoice(); + } + } + : null, + color: selectedProcList.length > 0 ? CustomColors.green : CustomColors.grey2, + disabledColor: CustomColors.grey2, ), ], ), - SizedBox( - height: 10, + ), + ); + } + + _getNormalText(text, {bool isBold = false, bool isTotal = false}) { + return Text( + text, + style: TextStyle( + fontSize: isBold + ? isTotal + ? 16 + : 12 + : 11, + letterSpacing: -0.5, + color: isBold ? Color(0xff2E303A) : Color(0xff575757), + fontWeight: isTotal ? FontWeight.bold : FontWeight.w600), + ); + } + + _amountView(String title, String value, {bool isBold = false, bool isTotal = false}) { + return Padding( + padding: const EdgeInsets.only(top: 10, bottom: 10), + child: Row(children: [ + Expanded( + child: _getNormalText(title), + ), + Expanded( + child: Row( + children: [ + projectViewModel.isArabic ? Container() : SvgPicture.asset("assets/images/new/Saudi_Riyal_Symbol.svg", width: 16, height: 16), + mWidth(6), + _getNormalText(value, isBold: isBold, isTotal: isTotal), + mWidth(6), + projectViewModel.isArabic ? SvgPicture.asset("assets/images/new/Saudi_Riyal_Symbol.svg", width: 16, height: 16) : Container(), + ], + ), ), - Divider( - color: Colors.black26, - ) - ], + ]), ); } - Widget getInsuranceDetails(model) { + Widget getPatientInfo() { return Padding( - padding: EdgeInsets.only(top: 10, bottom: 10), - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - Texts( - TranslationBase.of(context).insurance, - fontWeight: FontWeight.bold, - ), - Texts( - TranslationBase.of(context).insuranceID, - fontWeight: FontWeight.bold, - ) - ], - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - Texts( - model.ancillaryListsDetails[0].policyName, + child: Column( + children: [ + Container( + width: double.infinity, + child: Container( + decoration: cardRadius(12), + margin: EdgeInsets.zero, + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Text( + TranslationBase.of(context).patientName + ":", + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 10, + letterSpacing: -0.6, + color: CustomColors.grey, + ), + ), + mWidth(3), + Text( + projectViewModel.user.firstName! + " " + projectViewModel.user.lastName!, + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 12, + letterSpacing: -0.48, + ), + ), + ], + ), + Row( + children: [ + Text( + TranslationBase.of(context).mrn + ":", + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 10, + letterSpacing: -0.6, + color: CustomColors.grey, + ), + ), + mWidth(3), + Text( + projectViewModel.user!.patientID.toString(), + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 12, + letterSpacing: -0.48, + ), + ), + ], + ), + Row( + children: [ + Text( + TranslationBase.of(context).nationalIdNumber + ":", + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 10, + letterSpacing: -0.6, + color: CustomColors.grey, + ), + ), + mWidth(3), + Text( + projectViewModel.user.patientIdentificationNo!, + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 12, + letterSpacing: -0.48, + ), + ), + ], + ), + Row( + children: [ + Text( + TranslationBase.of(context).appointmentNo + ":", + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 10, + letterSpacing: -0.6, + color: CustomColors.grey, + ), + ), + mWidth(3), + Text( + _ancillaryProcLists[0].appointmentNo.toString(), + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 12, + letterSpacing: -0.48, + ), + ), + ], + ), + mWidth(3), + Row( + children: [ + Text( + TranslationBase.of(context).orderNo + ":", + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 10, + letterSpacing: -0.6, + color: CustomColors.grey, + ), + ), + mWidth(3), + Text( + // _ancillaryProcLists[0].ancillaryOrderProcDetailsList![0].orderNo.toString(), + _ancillaryProcLists[0].ancillaryOrderProcDetailsList!.isNotEmpty ? _ancillaryProcLists[0].ancillaryOrderProcDetailsList![0].orderNo.toString() : "0", + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 12, + letterSpacing: -0.48, + ), + ), + ], + ), + mWidth(3), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).insuranceCompany + ":", + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 10, + letterSpacing: -0.6, + color: CustomColors.grey, + ), + ), + mWidth(3), + Expanded( + child: Text( + _ancillaryProcLists[0].companyName.toString(), + overflow: TextOverflow.clip, + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 12, + letterSpacing: -0.48, + ), + ), + ), + ], + ), + mWidth(3), + Row( + children: [ + Text( + TranslationBase.of(context).policyNo + ":", + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 10, + letterSpacing: -0.6, + color: CustomColors.grey, + ), + ), + mWidth(3), + Text( + _ancillaryProcLists[0].insurancePolicyNo.toString(), + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 12, + letterSpacing: -0.48, + ), + ), + ], + ), + ], ), - Texts( - model.ancillaryListsDetails[0].insurancePolicyNo, - ) - ], - ), - SizedBox( - height: 15, + ), ), - Divider( - color: Colors.red[800], - thickness: 3, - ) - ], - )); + ), + ], + ), + padding: EdgeInsets.only(top: 5.0, bottom: 10.0), + ); } - Widget getAncillaryDetails(model) { - Map newMap = groupBy(model.ancillaryListsDetails[0].ancillaryOrderProcList, - (obj) => obj.procedureCategoryName); - print(newMap); - - return Padding( - padding: EdgeInsets.only(top: 10, bottom: 10), - child: getHeaderDetails(newMap)); + Widget getAncillaryDetails() { + Map newMap = groupBy(_ancillaryProcLists[0].ancillaryOrderProcDetailsList as Iterable, (AncillaryOrderProcDetailsList obj) => obj.procedureCategoryName); + return Padding(padding: EdgeInsets.only(top: 0, bottom: 200), child: getHeaderDetails(newMap)); } Widget getHeaderDetails(newMap) { - List list = new List(); - + List list = []; newMap.forEach((key, value) { list.add( - Texts( - key, - fontWeight: FontWeight.bold, + Container( + padding: EdgeInsets.only(bottom: 8.0), + child: Text(key, style: TextStyle(color: Colors.black, letterSpacing: -0.64, fontSize: 18.0, fontWeight: FontWeight.bold)), ), ); - list.add(Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - getLabDetails(value), - ], - )); + list.add( + ListView.separated( + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + itemBuilder: (context, index) { + return AbsorbPointer( + absorbing: isProcedureDisabled(value[index]), + child: Container( + decoration: BoxDecoration( + color: getCardColor(value[index]), + borderRadius: BorderRadius.all( + Radius.circular(10.0), + ), + 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: 12, horizontal: 12), + decoration: BoxDecoration( + color: isProcedureDisabled(value[index]) ? Colors.grey[300] : Colors.white, + border: Border.all(color: isProcedureDisabled(value[index]) ? Colors.grey[300]! : 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, + children: [ + Container( + padding: EdgeInsets.only(bottom: 12.0), + child: Text( + getInsuranceText(value[index]), + style: TextStyle(fontSize: 13, fontWeight: FontWeight.w600, color: getCardColor(value[index]), letterSpacing: -0.4, height: 16 / 10), + ), + ), + Table( + columnWidths: { + 0: FlexColumnWidth(1.0), + 1: FlexColumnWidth(2.5), + 2: FlexColumnWidth(1.5), + 3: FlexColumnWidth(1.5), + 4: FlexColumnWidth(1.5), + }, + children: fullData(context, value[index]), + ), + ], + ), + ), + ), + ); + }, + separatorBuilder: (context, index) => SizedBox(height: 12), + itemCount: value.length), + ); }); - return Column( crossAxisAlignment: CrossAxisAlignment.start, children: list, ); } - String getTotalValue(value) { + String getTotalValue() { double total = 0.0; - value.ancillaryListsDetails[0].ancillaryOrderProcList - .forEach((result) => {total += result.companyShareWithTax}); + selectedProcList.forEach((result) => {total += result.patientShareWithTax}); return total.toStringAsFixed(2); } - getLabDetails(value) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: value.map((result) { - return Container( - width: MediaQuery.of(context).size.width * .9, - padding: EdgeInsets.all(10), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - Expanded( - flex: 3, - child: Text(result.procedureName.toString(), - overflow: TextOverflow.ellipsis)), - Expanded(child: AppText(result.companyShare.toString())), - Expanded(child: AppText(result.companyTaxAmount.toString())), - Expanded( - child: AppText( - result.companyShareWithTax.toString(), - )) - ], - )); - }).toList(), + bool checkIfProcedureSelected(AncillaryOrderProcDetailsList ancillaryOrderProcDetailsList) { + if (selectedProcList.length > 0) { + if (selectedProcList.contains(ancillaryOrderProcDetailsList)) { + return true; + } else { + return false; + } + } else { + return false; + } + } + + bool isProcedureDisabled(AncillaryOrderProcDetailsList ancillaryOrderProcDetailsList) { + if ((ancillaryOrderProcDetailsList.isApprovalRequired! && !ancillaryOrderProcDetailsList.isApprovalCreated!) || + (ancillaryOrderProcDetailsList.isApprovalCreated! && ancillaryOrderProcDetailsList.approvalNo == 0) || + (ancillaryOrderProcDetailsList.isApprovalRequired! && ancillaryOrderProcDetailsList.isApprovalCreated! && ancillaryOrderProcDetailsList.approvalNo == 0)) { + return true; + } else { + return false; + } + } + + addToSelectedProcedures() { + if (_ancillaryProcLists.isNotEmpty) { + selectedProcList.clear(); + if (_ancillaryProcLists[0].ancillaryOrderProcDetailsList != null) { + _ancillaryProcLists[0].ancillaryOrderProcDetailsList!.forEach((element) { + if (!isProcedureDisabled(element)) { + selectedProcList.add(element); + } + }); + } else {} + } + setState(() {}); + } + + String getInsuranceText(value) { + String insuranceText = ""; + if (!value.isApprovalRequired) { + insuranceText = "Cash"; + } else { + if (value.isApprovalCreated && value.approvalNo != 0) { + insuranceText = "Approved"; + } else if (value.isApprovalRequired && value.isApprovalCreated && value.approvalNo == 0) { + insuranceText = "Approval Rejected - Please visit receptionist"; + } else { + insuranceText = "Sent For Approval"; + } + } + return insuranceText; + } + + Color getCardColor(value) { + Color color = Color(0xff); + if (!value.isApprovalRequired) { + color = Color(0xff2E303A); + } else { + if (value.isApprovalCreated && value.approvalNo != 0) { + color = Color(0xff359846); + } else if (value.isApprovalRequired && value.isApprovalCreated && value.approvalNo == 0) { + color = Color(0xffD02127); + } else { + color = Color(0xffCC9B14); + } + } + return color; + } + + List fullData(context, value) { + List tableRow = []; + + tableRow.add( + TableRow( + children: [ + Utils.tableColumnTitle(""), + Utils.tableColumnTitle(TranslationBase.of(context).procedure), + Utils.tableColumnTitle(TranslationBase.of(context).price), + Utils.tableColumnTitle(TranslationBase.of(context).vat), + Utils.tableColumnTitle(TranslationBase.of(context).total), + ], + ), + ); + + tableRow.add( + TableRow(children: [ + Checkbox( + value: checkIfProcedureSelected(value), + onChanged: (v) { + setState(() { + addSelectedProcedure(value); + }); + }), + Utils.tableColumnValue('${value.procedureName}', isLast: true, isCapitable: false, mProjectViewModel: projectViewModel), + Utils.tableColumnValue('${value.patientShare.toString()}', isLast: true, isCapitable: false, mProjectViewModel: projectViewModel), + Utils.tableColumnValue('${value.patientTaxAmount.toString()}', isLast: true, isCapitable: false, mProjectViewModel: projectViewModel), + Utils.tableColumnValue('${value.patientShareWithTax.toString()}', isLast: true, isCapitable: false, mProjectViewModel: projectViewModel), + ]), ); + return tableRow; + } + + makePayment() { + showDraggableDialog( + context, + PaymentMethod( + onSelectedMethod: (String method, [String? selectedInstallmentPlan]) { + selectedPaymentMethod = method; + this.selectedInstallmentPlan = selectedInstallmentPlan; + if (selectedPaymentMethod == "ApplePay") { + if (projectViewModel.havePrivilege(103)) { + startApplePay(); + } else { + openPayment(selectedPaymentMethod, projectViewModel.user, double.parse(getTotalValue()), AppoitmentAllHistoryResultList(), selectedInstallmentPlan); + } + } else { + openPayment(selectedPaymentMethod, projectViewModel.user, double.parse(getTotalValue()), AppoitmentAllHistoryResultList(), selectedInstallmentPlan); + } + }, + patientShare: double.parse(getTotalValue()), + isFromAdvancePayment: !projectViewModel.havePrivilege(94), + )); + } + + void startApplePay() async { + transID = Utils.getAdvancePaymentTransID(widget.projectID, projectViewModel.user.patientID!); + + print("TransactionID: $transID"); + GifLoaderDialogUtils.showMyDialog(context); + + LiveCareService service = new LiveCareService(); + ApplePayInsertRequest applePayInsertRequest = new ApplePayInsertRequest(); + + PayfortProjectDetailsRespModel? payfortProjectDetailsRespModel; + await context.read().getProjectDetailsForPayfort(projectId: widget.projectID, serviceId: ServiceTypeEnum.ancillaryOrder.getIdFromServiceEnum()).then((value) { + payfortProjectDetailsRespModel = value; + }); + + applePayInsertRequest.clientRequestID = transID; + applePayInsertRequest.clinicID = 0; + applePayInsertRequest.currency = projectViewModel.user.outSA == 1 ? "AED" : "SAR"; + // applePayInsertRequest.customerEmail = projectViewModel.authenticatedUserObject.user.emailAddress; + applePayInsertRequest.customerEmail = "CustID_${projectViewModel.user.patientID}@HMG.com"; + applePayInsertRequest.customerID = projectViewModel.user.patientID; + applePayInsertRequest.customerName = projectViewModel.user.firstName! + " " + projectViewModel.user.lastName!; + applePayInsertRequest.deviceToken = await AppSharedPreferences().getString(PUSH_TOKEN); + applePayInsertRequest.voipToken = await AppSharedPreferences().getString(ONESIGNAL_APNS_TOKEN); + applePayInsertRequest.doctorID = 0; + applePayInsertRequest.projectID = widget.projectID.toString(); + applePayInsertRequest.serviceID = ServiceTypeEnum.advancePayment.getIdFromServiceEnum().toString(); + applePayInsertRequest.channelID = 3; + applePayInsertRequest.patientID = projectViewModel.user.patientID; + applePayInsertRequest.patientTypeID = projectViewModel.user.patientType; + applePayInsertRequest.patientOutSA = projectViewModel.user.outSA; + applePayInsertRequest.appointmentDate = null; + applePayInsertRequest.appointmentNo = widget.appoNo; + applePayInsertRequest.orderDescription = "Ancillary Order Payment"; + applePayInsertRequest.liveServiceID = "0"; + applePayInsertRequest.latitude = "0.0"; + applePayInsertRequest.longitude = "0.0"; + applePayInsertRequest.amount = double.parse(getTotalValue()).toString(); + applePayInsertRequest.isSchedule = "0"; + applePayInsertRequest.language = projectViewModel.isArabic ? 'ar' : 'en'; + applePayInsertRequest.languageID = projectViewModel.isArabic ? 1 : 2; + applePayInsertRequest.userName = projectViewModel.user.patientID; + applePayInsertRequest.responseContinueURL = "http://hmg.com/Documents/success.html"; + applePayInsertRequest.backClickUrl = "http://hmg.com/Documents/success.html"; + applePayInsertRequest.paymentOption = "ApplePay"; + + applePayInsertRequest.isMobSDK = true; + applePayInsertRequest.merchantReference = transID; + applePayInsertRequest.merchantIdentifier = payfortProjectDetailsRespModel!.merchantIdentifier; + applePayInsertRequest.commandType = "PURCHASE"; + applePayInsertRequest.signature = payfortProjectDetailsRespModel!.signature; + applePayInsertRequest.accessCode = payfortProjectDetailsRespModel!.accessCode; + applePayInsertRequest.shaRequestPhrase = payfortProjectDetailsRespModel!.shaRequest; + applePayInsertRequest.shaResponsePhrase = payfortProjectDetailsRespModel!.shaResponse; + applePayInsertRequest.returnURL = ""; + + service.applePayInsertRequest(applePayInsertRequest, context).then((res) async { + if (res["MessageStatus"] == 1) { + await context.read().initiateApplePayWithPayfort( + customerName: projectViewModel.user.firstName! + " " + projectViewModel.user.lastName!, + // customerEmail: projectViewModel.authenticatedUserObject.user.emailAddress, + customerEmail: "CustID_${projectViewModel.user.patientID}@HMG.com", + orderDescription: "Ancillary Order Payment", + orderAmount: double.parse(getTotalValue()), + merchantReference: transID, + payfortProjectDetailsRespModel: payfortProjectDetailsRespModel, + currency: projectViewModel.user.outSA == 1 ? "AED" : "SAR", + onFailed: (failureResult) async { + GifLoaderDialogUtils.hideDialog(context); + log("failureResult: ${failureResult.message.toString()}"); + AppToast.showErrorToast(message: failureResult.message.toString()); + }, + onSuccess: (successResult) async { + log("Payfort: ${successResult.responseMessage}"); + await context.read().addPayfortApplePayResponse(projectViewModel.user.patientID!, result: successResult); + checkPaymentStatus(AppoitmentAllHistoryResultList()); + }, + projectId: widget.projectID, + serviceTypeEnum: ServiceTypeEnum.ancillaryOrder, + ); + } else { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: "An error occurred while processing your request"); + } + }).catchError((err) { + print(err); + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + }); + } + + openPayment(String paymentMethod, AuthenticatedUser authenticatedUser, num amount, AppoitmentAllHistoryResultList? appo, [String? selectedInstallmentPlan]) { + browser = new MyInAppBrowser(onExitCallback: onBrowserExit, appo: appo, onLoadStartCallback: onBrowserLoadStart); + transID = Utils.getAdvancePaymentTransID(widget.projectID, projectViewModel.user.patientID!); + + browser.openPaymentBrowser( + amount, + "Ancillary Orders Payment", + transID, + widget.projectID.toString(), + projectViewModel.user.emailAddress!, + paymentMethod, + projectViewModel.user.patientType, + projectViewModel.user.firstName! + " " + projectViewModel.user.lastName!, + projectViewModel.user.patientID, + authenticatedUser, + browser, + false, + "3", + // Need to get new Service ID from Ayman for Ancillary Tamara + "", + context, + _ancillaryProcLists[0].appointmentDate, + _ancillaryProcLists[0].appointmentNo, + _ancillaryProcLists[0].clinicID, + _ancillaryProcLists[0].doctorID, + selectedInstallmentPlan); + } + + onBrowserLoadStart(String url) { + print("onBrowserLoadStart"); + print(url); + + if (selectedPaymentMethod == "TAMARA") { + if (Platform.isAndroid) { + Uri uri = new Uri.dataFromString(url); + tamaraPaymentStatus = uri.queryParameters['status']; + tamaraOrderID = uri.queryParameters['AuthorizePaymentId']; + } else { + Uri uri = new Uri.dataFromString(url); + tamaraPaymentStatus = uri.queryParameters['paymentStatus']; + tamaraOrderID = uri.queryParameters['orderId']; + } + } + + MyInAppBrowser.successURLS.forEach((element) { + if (url.contains(element)) { + if (browser.isOpened()) browser.close(); + MyInAppBrowser.isPaymentDone = true; + return; + } + }); + + MyInAppBrowser.errorURLS.forEach((element) { + if (url.contains(element)) { + if (browser.isOpened()) browser.close(); + MyInAppBrowser.isPaymentDone = false; + return; + } + }); + } + + onBrowserExit(AppoitmentAllHistoryResultList appo, bool isPaymentMade) { + print("onBrowserExit Called!!!!"); + if (selectedPaymentMethod == "TAMARA") { + checkTamaraPaymentStatus(transID, appo); + } else { + checkPaymentStatus(appo); + } + } + + checkTamaraPaymentStatus(String orderID, AppoitmentAllHistoryResultList appo) { + GifLoaderDialogUtils.showMyDialog(context); + DoctorsListService service = new DoctorsListService(); + service.getTamaraPaymentStatus(orderID).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res["status"].toString().toLowerCase() == "success") { + updateTamaraRequestStatus("success", "14", orderID, tamaraOrderID!, int.parse(this.selectedInstallmentPlan!), appo); + } else { + updateTamaraRequestStatus("Failed", "00", transID, tamaraOrderID != null ? tamaraOrderID! : "", int.parse(this.selectedInstallmentPlan!), appo); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + + updateTamaraRequestStatus(String responseMessage, String status, String clientRequestID, String tamaraOrderID, int selectedInstallments, AppoitmentAllHistoryResultList appo) { + GifLoaderDialogUtils.showMyDialog(context); + try { + DoctorsListService service = new DoctorsListService(); + service.updateTamaraRequestStatus(responseMessage, status, clientRequestID, tamaraOrderID, selectedInstallments).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (tamaraPaymentStatus!.toLowerCase() == "approved") { + createAdvancePayment(res, appo); + // addAdvancedNumberRequestTamara("Tamara-Advance-0000", tamaraOrderID, appo.appointmentNo.toString(), appo); + } + }).catchError((err) { + print(err); + AppToast.showErrorToast(message: err); + GifLoaderDialogUtils.hideDialog(context); + }); + } catch (err) { + print(err); + } + } + + checkPaymentStatus(AppoitmentAllHistoryResultList appo) { + GifLoaderDialogUtils.showMyDialog(localContext); + DoctorsListService service = new DoctorsListService(); + service.checkPaymentStatus(transID, false, localContext).then((res) { + String paymentInfo = res['Response_Message']; + if (paymentInfo == 'Success') { + createAdvancePayment(res, appo); + } else { + GifLoaderDialogUtils.hideDialog(localContext); + AppToast.showErrorToast(message: res['Response_Message']); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(localContext); + AppToast.showErrorToast(message: err); + print(err); + }); + } + + createAdvancePayment(res, AppoitmentAllHistoryResultList appo) { + DoctorsListService service = new DoctorsListService(); + String paymentReference = res['Fort_id'].toString(); + service.HIS_createAdvancePayment(appo, widget.projectID.toString(), res['Amount'], res['Fort_id'], res['PaymentMethod'], projectViewModel.user.patientType, + projectViewModel.user.firstName! + " " + projectViewModel.user.lastName!, projectViewModel.user.patientID, localContext, + isAncillaryOrder: true) + .then((res) { + addAdvancedNumberRequest( + Utils.isVidaPlusProject(projectViewModel, widget.projectID) + ? res['OnlineCheckInAppointments'][0]['AdvanceNumber_VP'].toString() + : res['OnlineCheckInAppointments'][0]['AdvanceNumber'].toString(), + paymentReference, + 0, + appo); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(localContext); + AppToast.showErrorToast(message: err); + print(err); + }); + } + + addAdvancedNumberRequest(String advanceNumber, String paymentReference, dynamic appointmentID, AppoitmentAllHistoryResultList appo) { + DoctorsListService service = new DoctorsListService(); + service.addAdvancedNumberRequest(advanceNumber, paymentReference, appointmentID, localContext).then((res) { + autoGenerateInvoice(); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(localContext); + AppToast.showErrorToast(message: err.toString()); + print(err); + }); + } + + autoGenerateInvoice() { + List selectedProcListAPI = []; + + selectedProcList.forEach((element) { + selectedProcListAPI.add({ + "ApprovalLineItemNo": element.approvalLineItemNo, + "OrderLineItemNo": element.orderLineItemNo, + "ProcedureID": element.procedureID, + }); + }); + + GifLoaderDialogUtils.showMyDialog(localContext); + + DoctorsListService service = new DoctorsListService(); + service.autoGenerateAncillaryOrdersInvoice(widget.orderNo, widget.projectID, widget.appoNo, selectedProcListAPI, projectViewModel.isArabic ? 1 : 2, localContext).then((res) { + GifLoaderDialogUtils.hideDialog(localContext); + showAlertDialog(res['AncillaryOrderInvoiceList'][0]['InvoiceNo'], widget.projectID); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(localContext); + AppToast.showErrorToast(message: err); + print(err); + }); + } + + showAlertDialog(dynamic invoiceNo, dynamic projectID) { + AlertDialogBox( + context: context, + confirmMessage: TranslationBase.of(context).ancillaryOrderPaymentSuccess + invoiceNo.toString(), + okText: TranslationBase.of(context).ok, + okFunction: () { + AlertDialogBox.closeAlertDialog(context); + Navigator.of(context).pop(); + Navigator.pushAndRemoveUntil(context, MaterialPageRoute(builder: (context) => LandingPage()), (Route r) => false); + }).showAlertDialog(context); } } diff --git a/lib/pages/AlHabibMedicalService/ancillary-orders/ordersPayment.dart b/lib/pages/AlHabibMedicalService/ancillary-orders/ordersPayment.dart new file mode 100644 index 00000000..03504f57 --- /dev/null +++ b/lib/pages/AlHabibMedicalService/ancillary-orders/ordersPayment.dart @@ -0,0 +1,13 @@ +import 'package:flutter/material.dart'; + +class OrdersPayment extends StatefulWidget { + @override + _OrdersPaymentState createState() => _OrdersPaymentState(); +} + +class _OrdersPaymentState extends State { + @override + Widget build(BuildContext context) { + return Container(); + } +} 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 1558b8c7..00000000 --- a/lib/pages/AlHabibMedicalService/h2o/Dialog/confirm_add_amount_dialog.dart +++ /dev/null @@ -1,105 +0,0 @@ -import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/H2O/insert_user_activity_request_model.dart'; -import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_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'; - -// 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 2df90419..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'; - -// 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/Dialog/setting_page_radio_button_list_dialog.dart b/lib/pages/AlHabibMedicalService/h2o/Dialog/setting_page_radio_button_list_dialog.dart index 580207d8..61e171c3 100644 --- a/lib/pages/AlHabibMedicalService/h2o/Dialog/setting_page_radio_button_list_dialog.dart +++ b/lib/pages/AlHabibMedicalService/h2o/Dialog/setting_page_radio_button_list_dialog.dart @@ -6,7 +6,7 @@ class CommonRadioButtonDialog extends StatefulWidget { final String title; final int selectedIndex; final Function(int) onSelect; - CommonRadioButtonDialog({Key key, this.title = "", this.selectedIndex = 0, this.list, this.onSelect}) : super(key: key); + CommonRadioButtonDialog({Key? key, this.title = "", this.selectedIndex = 0, required this.list, required this.onSelect}) : super(key: key); @override _CommonRadioButtonDialogState createState() { @@ -58,7 +58,7 @@ class _CommonRadioButtonDialogState extends State { dense: true, activeColor: Colors.black54, groupValue: _selectedIndex, - onChanged: (_index) => setState(() => _selectedIndex = _index), + onChanged: (_index) => setState(() => _selectedIndex = _index!), title: Text( widget.list[index], style: TextStyle(fontWeight: FontWeight.w500), @@ -74,7 +74,7 @@ class _CommonRadioButtonDialogState extends State { child: Row( children: [ Expanded( - child: FlatButton( + child: TextButton( child: Text( TranslationBase.of(context).cancel, style: TextStyle(color: Colors.redAccent, fontSize: 16, fontWeight: FontWeight.w500), @@ -83,7 +83,7 @@ class _CommonRadioButtonDialogState extends State { ), ), Expanded( - child: FlatButton( + child: TextButton( child: Text( TranslationBase.of(context).ok, style: TextStyle(color: Colors.black87, fontSize: 16, fontWeight: FontWeight.w500), 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 2b22a100..00000000 --- a/lib/pages/AlHabibMedicalService/h2o/add_custom_amount.dart +++ /dev/null @@ -1,132 +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'; - -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 4295558a..8e3495c1 100644 --- a/lib/pages/AlHabibMedicalService/h2o/h20_setting.dart +++ b/lib/pages/AlHabibMedicalService/h2o/h20_setting.dart @@ -1,25 +1,28 @@ +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/H2O/user_detail_model.dart'; -import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/H2O_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/H2O_view_model.dart'; -import 'package:diplomaticquarterapp/pages/BookAppointment/widgets/BranchView.dart'; -import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/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/radio_selection_dialog.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/painting.dart'; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; +import 'package:manage_calendar_events/manage_calendar_events.dart'; +import 'package:shared_preferences/shared_preferences.dart'; import 'Dialog/setting_page_radio_button_list_dialog.dart'; class H2oSetting extends StatefulWidget { final UserDetailModel userDetailModel; final H2OViewModel viewModel; - H2oSetting({Key key, this.userDetailModel, this.viewModel}) : super(key: key); + + H2oSetting({Key? key, required this.userDetailModel, required this.viewModel}) : super(key: key); @override _H2oSettingState createState() { @@ -31,7 +34,10 @@ class _H2oSettingState extends State { TextEditingController _nameController = TextEditingController(); TextEditingController _heightController = TextEditingController(); TextEditingController _weightController = TextEditingController(); - bool _isUnitML = false; + List _weightPopupList =[]; + List _heightPopupList =[]; + + bool _isUnitML = true; bool _isGenderMale = false; bool _isHeightCM = false; bool _isWeightKG = false; @@ -45,42 +51,39 @@ class _H2oSettingState extends State { DateTime _dobDate = DateTime.now(); DateTime _tempDate = DateTime.now(); - UserDetailModel _userDetailModel; + late UserDetailModel _userDetailModel; @override void initState() { super.initState(); _userDetailModel = widget.userDetailModel; - _heightValue = _userDetailModel.height; - _weightValue = _userDetailModel.weight; + _heightValue = _userDetailModel?.height ?? 100; + _weightValue = _userDetailModel?.weight ?? 50; _heightController.text = _heightValue.toStringAsFixed(0); _weightController.text = _weightValue.toStringAsFixed(0); - _nameController.text = _userDetailModel.firstName; - _isWeightKG = _userDetailModel.isWeightInKG; - _isHeightCM = _userDetailModel.isHeightInCM; - _isGenderMale = _userDetailModel.gender == "M" ? true : false; - _dobDate = DateUtil.convertStringToDate(_userDetailModel.dOB); + _nameController.text = _userDetailModel.firstName ?? ""; + _isWeightKG = _userDetailModel?.isWeightInKG ?? true; + _isHeightCM = _userDetailModel?.isHeightInCM ?? true; + _isGenderMale = (_userDetailModel?.gender ?? "M") == "M" ? true : false; + _dobDate = DateUtil.convertStringToDate(_userDetailModel.dOB ?? DateUtil.convertDateToString(DateTime.now())); _selectedActiveLevel = _userDetailModel.activityID ?? 1; + readPrefs(); + } + + late SharedPreferences prefs; + + void readPrefs() async { + prefs = await SharedPreferences.getInstance(); + _isUnitML = (prefs.getString(H2O_UNIT) ?? "ml") == "ml" ? true : false; + _selectedRemindedTime = prefs.getInt(H2O_REMINDER) ?? 0; + setState(() {}); } @override void didChangeDependencies() { - // TODO: implement didChangeDependencies super.didChangeDependencies(); - - _activityLevelListEng = [ - TranslationBase.of(context).notActive, - TranslationBase.of(context).lightActive, - TranslationBase.of(context).modActive, - TranslationBase.of(context).active - ]; - - _remindedTimeListEng = [ - "1 ${TranslationBase.of(context).time}", - "2 ${TranslationBase.of(context).times}", - "3 ${TranslationBase.of(context).times}", - "4 ${TranslationBase.of(context).times}" - ]; + _activityLevelListEng = [TranslationBase.of(context).notActive, TranslationBase.of(context).lightActive, TranslationBase.of(context).modActive, TranslationBase.of(context).active]; + _remindedTimeListEng = ["1 ${TranslationBase.of(context).time}", "2 ${TranslationBase.of(context).times}", "3 ${TranslationBase.of(context).times}", "4 ${TranslationBase.of(context).times}"]; } @override @@ -90,349 +93,429 @@ class _H2oSettingState extends State { @override Widget build(BuildContext context) { + _weightPopupList = [PopupMenuItem(child: Text(TranslationBase.of(context).kg), value: true), PopupMenuItem(child: Text(TranslationBase.of(context).lb), value: false)]; + _heightPopupList = [PopupMenuItem(child: Text(TranslationBase.of(context).cm), value: true), PopupMenuItem(child: Text(TranslationBase.of(context).ft), value: false)]; + return AppScaffold( isShowAppBar: true, appBarTitle: TranslationBase.of(context).h2o, + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: Color(0xffF7F7F7), showHomeAppBarIcon: false, - body: SingleChildScrollView( - padding: EdgeInsets.fromLTRB(8, 8, 8, 80), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - TextField( - controller: _nameController, - decoration: InputDecoration( - labelText: TranslationBase.of(context).enterNameHere, - labelStyle: TextStyle(color: Colors.black87), - fillColor: Colors.white, - filled: true, - border: UnderlineInputBorder( - borderSide: BorderSide( - width: 0, - style: BorderStyle.none, - ), - borderRadius: BorderRadius.circular(6.0), - ), - ), - ), - SizedBox(height: 8), - Text(TranslationBase.of(context).preferredunit), - SizedBox(height: 8), - _commonButtonsRow(TranslationBase.of(context).ml, TranslationBase.of(context).l, _isUnitML, (value) { - if (_isUnitML != value) { - setState(() { - _isUnitML = value; - }); - } - }), - Padding( - padding: EdgeInsets.only(top: 8.0, bottom: 8.0), - child: Divider(height: 1.5, color: Colors.black54), - ), - Text(TranslationBase.of(context).gender), - SizedBox(height: 8), - _commonButtonsRow(TranslationBase.of(context).male, TranslationBase.of(context).female, _isGenderMale, (value) { - if (_isGenderMale != value) { - setState(() { - _isGenderMale = value; - }); - } - }), - Padding( - padding: EdgeInsets.only(top: 8.0, bottom: 8.0), - child: Divider(height: 1.5, color: Colors.black54), - ), - Text(TranslationBase.of(context).height), - _commonSlidersRow(_heightController, 1, 270, _heightValue, (text) { - _heightController.text = text; - }, (value) { - setState(() { - _heightValue = value; - }); - }), - SizedBox(height: 8), - Text(TranslationBase.of(context).heightUnit), - SizedBox(height: 8), - _commonButtonsRow(TranslationBase.of(context).cm, TranslationBase.of(context).ft, _isHeightCM, (value) { - if (_isHeightCM != value) { - setState(() { - _isHeightCM = value; - }); - } - }), - SizedBox(height: 8), - _commonSlidersRow(_weightController, 1, 250, _weightValue, (text) { - _weightController.text = text; - }, (value) { - setState(() { - _weightValue = value; - }); - }), - SizedBox(height: 8), - Text(TranslationBase.of(context).weightUnit), - SizedBox(height: 8), - _commonButtonsRow(TranslationBase.of(context).kg, TranslationBase.of(context).lb, _isWeightKG, (value) { - if (_isWeightKG != value) { - setState(() { - _isWeightKG = value; - }); - } - }), - Padding( - padding: EdgeInsets.only(top: 8.0, bottom: 8.0), - child: Divider(height: 1.5, color: Colors.black54), - ), - Container( - padding: EdgeInsets.all(8), - width: MediaQuery.of(context).size.width, - decoration: BoxDecoration(borderRadius: BorderRadius.circular(8), color: Colors.white), + body: Column( + children: [ + Expanded( + child: SingleChildScrollView( + physics: BouncingScrollPhysics(), + padding: EdgeInsets.all(21), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text("${TranslationBase.of(context).birth_date}:"), - SizedBox(height: 8), - InkWell( - onTap: () { - 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), - ), + Text( + TranslationBase.of(context).enterDetailBelow, + style: TextStyle( + fontSize: 19, + height: 23 / 19, + fontWeight: FontWeight.w700, + color: Color(0xff2E303A), + letterSpacing: -1.14, + ), + ), + SizedBox(height: 12), + inputWidget(TranslationBase.of(context).enterNameHere, TranslationBase.of(context).name, _nameController).withBorderedContainer, + SizedBox(height: 16), + Text( + TranslationBase.of(context).preferredunit, + style: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.44, + ), + ), + SizedBox(height: 12), + _commonRadioButtonsRow(TranslationBase.of(context).mililitre, TranslationBase.of(context).litre, _isUnitML, (value) { + if (_isUnitML != value) { + setState(() { + _isUnitML = value!; + }); + } + }), + SizedBox(height: 12), + Text( + TranslationBase.of(context).pleaseSelectGender, + style: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.44, + ), + ), + SizedBox(height: 12), + _commonRadioButtonsRow(TranslationBase.of(context).male, TranslationBase.of(context).female, _isGenderMale, (value) { + if (_isGenderMale != value) { + setState(() { + _isGenderMale = value!; + }); + } + }), + SizedBox(height: 18), + _commonInputAndUnitRow( + TranslationBase.of(context).height, + _heightController, + 1, + 270, + _heightValue, + (text) { + _heightController.text = text; + }, + (value) { + _heightValue = value; + }, + _isHeightCM ? TranslationBase.of(context).cm : TranslationBase.of(context).ft, + (value) { + if (_isHeightCM != value) { + setState(() { + _isHeightCM = value; + }); + } + }, + _heightPopupList), + SizedBox(height: 12), + _commonInputAndUnitRow( + TranslationBase.of(context).weight, + _weightController, + 1, + 250, + _weightValue, + (text) { + _heightController.text = text; + }, + (value) { + _weightValue = value; + }, + _isWeightKG ? TranslationBase.of(context).kg : TranslationBase.of(context).lb, + (value) { + if (_isWeightKG != value) { + setState(() { + _isWeightKG = value; + }); + } + }, + _weightPopupList), + SizedBox(height: 12), + 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; + }, ), - ) - ]), - ); - }); - }, // implement cupertino dialog to select date - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [Text(DateUtil.getFormattedDate(_dobDate, "yyyy-MM-dd")), Icon(Icons.arrow_drop_down_outlined)]), - ) + ), + ) + ]), + ); + }); + }, iconData: Icons.calendar_today) + .withBorderedContainer, + SizedBox(height: 12), + 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, + builder: (cxt) => RadioSelectionDialog( + listData: list, + selectedIndex: _selectedActiveLevel, + onValueSelected: (index) { + _selectedActiveLevel = index; + setState(() {}); + }, + ), + ); + }).withBorderedContainer, + SizedBox(height: 18), + Text( + TranslationBase.of(context).reminderLabel, + style: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.44, + ), + ), + SizedBox(height: 12), + CommonDropDownView(TranslationBase.of(context).reminderTimesLabel, _remindedTimeListEng[_selectedRemindedTime], () { + List list = [ + for (int i = 0; i < _remindedTimeListEng.length; i++) RadioSelectionDialogModel(_remindedTimeListEng[i], i), + ]; + + showDialog( + context: context, + builder: (cxt) => RadioSelectionDialog( + listData: list, + selectedIndex: _selectedRemindedTime, + onValueSelected: (index) { + _selectedRemindedTime = index; + setState(() {}); + }, + ), + ); + }).withBorderedContainer, ], ), ), - SizedBox(height: 8), - _commonDialogSelectorRow(TranslationBase.of(context).activityLevel, _activityLevelListEng[_selectedActiveLevel - 1], () { - showDialog( - context: context, - child: CommonRadioButtonDialog( - list: _activityLevelListEng, - title: TranslationBase.of(context).activityLevel, - onSelect: (index) { - Navigator.pop(context); - setState(() { - _selectedActiveLevel = index + 1; - }); - }, - selectedIndex: _selectedActiveLevel - 1, - ), - ); - }), - SizedBox(height: 8), - _commonDialogSelectorRow(TranslationBase.of(context).reminderLabel, _remindedTimeListEng[_selectedRemindedTime], () { - showDialog( - context: context, - child: CommonRadioButtonDialog( - list: _remindedTimeListEng, - onSelect: (index) { - Navigator.pop(context); - setState(() { - _selectedRemindedTime = index; - }); - }, - selectedIndex: _selectedRemindedTime, - ), - ); - }), - SizedBox(height: 16), - SizedBox( - height: 50, - width: MediaQuery.of(context).size.width, - child: FlatButton( - color: Theme.of(context).appBarTheme.color, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8.0), - ), - onPressed: _updateUserDetails, - child: Text( - TranslationBase.of(context).save, - style: TextStyle(color: Colors.white, fontSize: 18, fontWeight: FontWeight.w600), - ), - ), - ) - ], - ), - ), - ); - } - - Widget _commonButtonsRow(String rightText, String leftText, bool checkParam, Function(bool) callBack) { - return Row(children: [ - Expanded( - child: SizedBox( - height: 40, - child: RaisedButton( - color: checkParam ? Theme.of(context).appBarTheme.color : Colors.white, - child: Text( - rightText, - style: TextStyle(color: checkParam ? Colors.white : Theme.of(context).appBarTheme.color, fontWeight: FontWeight.w600), - ), - onPressed: () => callBack(true), ), - ), - ), - SizedBox(width: 12), - Expanded( - child: SizedBox( - height: 40, - child: RaisedButton( - color: !checkParam ? Theme.of(context).appBarTheme.color : Colors.white, - child: Text( - leftText, - style: TextStyle(color: !checkParam ? Colors.white : Theme.of(context).appBarTheme.color, fontWeight: FontWeight.w600), + Container( + color: Colors.white, + padding: EdgeInsets.only(top: 16, bottom: 16, right: 21, left: 21), + child: DefaultButton( + TranslationBase.of(context).save, + _updateUserDetails, + color: Color(0xff349745), ), - onPressed: () => callBack(false), ), - ), + ], ), - ]); + ); } - Widget _commonSlidersRow( - _controller, double _minValue, double _maxValue, double _valueOrg, Function(String) onTextValueChange, Function(double) onValueChange) { - return Container( - margin: EdgeInsets.only(top: 6), - padding: EdgeInsets.all(6), - color: Colors.white, - height: 50, + Widget inputWidget(String _labelText, String _hintText, TextEditingController _controller, {String? prefix, bool isEnable = true, bool hasSelection = false}) { + return InkWell( + onTap: hasSelection ? () {} : null, child: Row( children: [ - SizedBox( - width: 75, - child: TextField( - controller: _controller, - textAlign: TextAlign.center, - 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]')), - ], - decoration: InputDecoration( - contentPadding: EdgeInsets.only(left: 4, right: 4), - fillColor: Colors.white, - filled: true, - focusedBorder: OutlineInputBorder( - borderSide: BorderSide( - width: 1, - color: Colors.grey, - style: BorderStyle.solid, + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + _labelText, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + color: Color(0xff2E303A), + letterSpacing: -0.44, ), - borderRadius: BorderRadius.circular(6.0), ), - enabledBorder: OutlineInputBorder( - borderSide: BorderSide( - width: 1, - color: Colors.grey, - style: BorderStyle.solid, + TextField( + enabled: isEnable, + scrollPadding: EdgeInsets.zero, + keyboardType: TextInputType.text, + controller: _controller, + onChanged: (value) => { + // validateForm() + }, + style: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: Color(0xff575757), + letterSpacing: -0.56, + ), + decoration: InputDecoration( + isDense: true, + hintText: _hintText, + hintStyle: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: Color(0xff575757), + 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, ), - borderRadius: BorderRadius.circular(6.0), ), - ), + ], ), ), - Expanded( - flex: 6, - child: Slider( - min: _minValue, - max: _maxValue, - activeColor: Colors.redAccent, - inactiveColor: Colors.redAccent.withOpacity(.3), - value: _valueOrg, - onChanged: (value) { - onTextValueChange(value.toStringAsFixed(0)); - onValueChange(value); - }, - ), - ) + if (hasSelection) Icon(Icons.keyboard_arrow_down_outlined), ], ), ); } - Widget _commonDialogSelectorRow(String title, String selectedText, VoidCallback onPressed) { - return Column(crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ - Text(title), - SizedBox(height: 8), - InkWell( - onTap: onPressed, - child: Container( - height: 50, - padding: EdgeInsets.all(8), - width: MediaQuery.of(context).size.width, - decoration: BoxDecoration(borderRadius: BorderRadius.circular(8), color: Colors.white), - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [Text(selectedText), Icon(Icons.arrow_drop_down_outlined)], + Widget _commonRadioButtonsRow(String rightText, String leftText, bool checkParam, Function(bool?) callBack) { + return Row( + children: [ + Row( + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox(width: 22, height: 22, child: Radio(value: true, groupValue: checkParam, onChanged: callBack)), + SizedBox(width: 8), + Text( + rightText, + style: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w600, + color: Color(0xff575757), + letterSpacing: -0.44, + ), + ), + ], + ), + SizedBox(width: 12), + Row( + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox(width: 22, height: 22, child: Radio(value: false, groupValue: checkParam, onChanged: callBack)), + SizedBox(width: 8), + Text( + leftText, + style: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w600, + color: Color(0xff575757), + letterSpacing: -0.44, + ), + ), + ], + ), + ], + ); + } + + Widget _commonInputAndUnitRow(_title, _controller, double _minValue, double _maxValue, double _valueOrg, Function(String) onTextValueChange, Function(double) onValueChange, String unitTitle, + Function(bool) onUnitTap, _list) { + 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( + 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, + ), + ), + ], ), ), - ) - ]); + 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, (){}), + onSelected: (value) { + print("Changed By Aamir"); + // Changed By Aamir + /// onUnitTap(value); + }, + itemBuilder: (context) => _list), + ) + ], + ).withBorderedContainer; } void _updateUserDetails() async { @@ -451,13 +534,98 @@ class _H2oSettingState extends State { _userDetailModel.dOB = tempDate; _userDetailModel.activityID = _selectedActiveLevel; GifLoaderDialogUtils.showMyDialog(context); - await widget.viewModel.updateUserDetail(_userDetailModel, (tag) { + await widget.viewModel.updateUserDetail(_userDetailModel, (tag) async { if (tag) { AppToast.showSuccessToast(message: TranslationBase.of(context).success); + await prefs.setString(H2O_UNIT, _isUnitML ? "ml" : "l"); + int _tempRemindTime = prefs.getInt(H2O_REMINDER) ?? 0; + if (_tempRemindTime != _selectedRemindedTime) { + await prefs.setInt(H2O_REMINDER, _selectedRemindedTime); + _addReminderToCalender(_selectedRemindedTime); + } } GifLoaderDialogUtils.hideDialog(context); }); Navigator.pop(context); } + + final CalendarPlugin _myPlugin = CalendarPlugin(); + + void _addReminderToCalender(int _selectedRemindedTime) async { + bool? _calendarPermission = await _myPlugin.hasPermissions(); + if (_calendarPermission!) { + } else { + await _myPlugin.requestPermissions(); + } + _myPlugin.hasPermissions().then((value) { + if (!value!) { + _myPlugin.requestPermissions(); + } else { + _myPlugin.getCalendars().then((value) => {}); + } + }); + } +} + +// 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/h2o_index_page.dart b/lib/pages/AlHabibMedicalService/h2o/h2o_index_page.dart index e6e05ee6..a28c0d3e 100644 --- a/lib/pages/AlHabibMedicalService/h2o/h2o_index_page.dart +++ b/lib/pages/AlHabibMedicalService/h2o/h2o_index_page.dart @@ -1,4 +1,5 @@ import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/h2o/h2o_page.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; @@ -6,7 +7,6 @@ import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:hexcolor/hexcolor.dart'; class H2OPageIndexPage extends StatelessWidget { @override @@ -23,7 +23,7 @@ class H2OPageIndexPage extends StatelessWidget { "Water Tracker:", fontWeight: FontWeight.normal, fontSize: 25, - color: HexColor("#60686b"), + color: Color(0xFF60686b), ), SizedBox( height: 12, @@ -58,9 +58,7 @@ class H2OPageIndexPage extends StatelessWidget { onTap: () => Navigator.push(context, FadePage(page: H2OPage())), label: "Water Tracker", - textColor: Theme - .of(context) - .backgroundColor), + textColor: CustomColors.white), ), ], ), diff --git a/lib/pages/AlHabibMedicalService/h2o/h2o_page.dart b/lib/pages/AlHabibMedicalService/h2o/h2o_page.dart index b4d39682..981f80b1 100644 --- a/lib/pages/AlHabibMedicalService/h2o/h2o_page.dart +++ b/lib/pages/AlHabibMedicalService/h2o/h2o_page.dart @@ -1,31 +1,41 @@ import 'dart:ui'; +import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/H2O_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/extensions/string_extensions.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/h2o/h20_setting.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/h2o/month_page.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/h2o/today_page.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/h2o/week_page.dart'; +import 'package:diplomaticquarterapp/pages/ToDoList/ToDo.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/pages/medical/medical_profile_page_new.dart'; +import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/bottom_navigation/bottom_nav_bar.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'; class H2OPage extends StatefulWidget { @override _H2OPageState createState() => _H2OPageState(); } -class _H2OPageState extends State - with SingleTickerProviderStateMixin { - TabController _tabController; +class _H2OPageState extends State with SingleTickerProviderStateMixin { + late TabController _tabController; @override void initState() { super.initState(); - _tabController = TabController(length: 3, vsync: this,); + _tabController = TabController( + length: 3, + vsync: this, + ); } @override @@ -36,99 +46,101 @@ class _H2OPageState extends State @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); return BaseView( onModelReady: (model) => model.getUserDetail(), builder: (_, model, widget) => AppScaffold( isShowAppBar: true, appBarTitle: TranslationBase.of(context).waterTracker, + description: TranslationBase.of(context).h2oInfo, + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: Color(0xffF7F7F7), + imagesInfo: [ + ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/images-info-home/h2o/en/0.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/images-info-home/h2o/ar/0.png') + ], showHomeAppBarIcon: false, baseViewModel: model, + isHelp: true, appBarIcons: [ - IconButton( - icon: Image.asset("assets/images/new-design/setting_gear_icon.png"), - color: Colors.white, - onPressed: () { - Navigator.push( - context, - FadePage( - page: H2oSetting(userDetailModel: model.userDetail, viewModel: model), - ), - ); - }, - ), - ], - body: Scaffold( - extendBodyBehindAppBar: true, - appBar: PreferredSize( - preferredSize: Size.fromHeight(65.0), - child: Stack( - children: [ - Positioned( - bottom: 1, - left: 0, - right: 0, - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10), - child: Container( - color: Theme.of(context).scaffoldBackgroundColor.withOpacity(0.8), - height: 70.0, - ), - ), - ), - Center( - child: Container( - height: 60.0, - alignment: Alignment.center, - // margin: EdgeInsets.only(top: 10.0), - // width: MediaQuery.of(context).size.width * 0.9, - - child: TabBar( - isScrollable: false, - controller: _tabController, - indicatorWeight: 5.0, - indicatorSize: TabBarIndicatorSize.tab, - indicatorColor: Colors.red[800], - labelColor: Theme.of(context).primaryColor, - labelPadding: EdgeInsets.only(top: 4.0, left: 10.0, right: 13.0), - unselectedLabelColor: Colors.grey[800], - tabs: [ - Container( - width: MediaQuery.of(context).size.width * 0.28, - child: Center( - child: Texts(TranslationBase.of(context).today), - ), - ), - Container( - width: MediaQuery.of(context).size.width * 0.28, - child: Center( - child: Texts(TranslationBase.of(context).week), - ), - ), - Container( - width: MediaQuery.of(context).size.width * 0.28, - child: Center( - child: Texts(TranslationBase.of(context).month), - ), - ), - ], - ), + if (model.isLogin) + IconButton( + icon: Icon(Icons.settings), + color: Color(0xff2B353E), + onPressed: () { + Navigator.push( + context, + FadePage( + page: H2oSetting(userDetailModel: model.userDetail, viewModel: model), ), - ), - ], + ); + }, + ), + ], + body: Column( + children: [ + TabBar( + controller: _tabController, + indicatorWeight: 3.0, + indicatorSize: TabBarIndicatorSize.tab, + labelColor: Color(0xff2B353E), + unselectedLabelColor: Color(0xff575757), + labelPadding: EdgeInsets.only(top: 15, bottom: 13, 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: [Text(TranslationBase.of(context).today), Text(TranslationBase.of(context).week), Text(TranslationBase.of(context).month.toLowerCase().capitalizeFirstofEach)], ), - ), - backgroundColor: Colors.white, - body: Column( - children: [ - Expanded( - child: TabBarView( - physics: BouncingScrollPhysics(), - controller: _tabController, - children: [TodayPage(), WeekPage(), MonthPage()], - ), - ) - ], - ), + Expanded( + child: TabBarView( + physics: BouncingScrollPhysics(), + controller: _tabController, + children: [TodayPage(), WeekPage(), MonthPage()], + ), + ) + ], + ), + bottomNavigationBar: BottomNavBar( + changeIndex: (index) { + if (index == 0) { + IS_VOICE_COMMAND_CLOSED = false; + } else if (index == 1) { + Navigator.push( + context, + FadePage( + page: AppScaffold( + appBarTitle: TranslationBase.of(context).medicalProfile, + isShowAppBar: true, + showHomeAppBarIcon: false, + appBarIcons: [ + IconButton( + icon: Image.asset("assets/images/new-design/setting_gear_icon.png"), + color: Colors.white, + onPressed: () => Navigator.of(context).pushNamed( + SETTINGS, + ), + ), + ], + body: MedicalProfilePageNew()))); + } else if (index == 2) { + Navigator.of(context).pushNamedAndRemoveUntil(HOME, (Route route) => false); + } else if (index == 3) { + Navigator.of(context).pushNamed(MY_FAMILIY); + } else if (index == 4) { + Navigator.push(context, FadePage(page: ToDo(isShowAppBar: false))); + } + }, + showHomeIcon: true, + index: 0, ), ), ); diff --git a/lib/pages/AlHabibMedicalService/h2o/month_page.dart b/lib/pages/AlHabibMedicalService/h2o/month_page.dart index e0118495..49440106 100644 --- a/lib/pages/AlHabibMedicalService/h2o/month_page.dart +++ b/lib/pages/AlHabibMedicalService/h2o/month_page.dart @@ -1,54 +1,58 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/H2O_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/charts/app_bar_chart.dart'; -import 'package:diplomaticquarterapp/widgets/errors/app_embedded_error.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:diplomaticquarterapp/widgets/progress_indicator/app_circular_progress_Indeicator.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:diplomaticquarterapp/widgets/charts/custom_line_chart.dart'; class MonthPage extends StatelessWidget { @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); return BaseView( onModelReady: (model) => model.getUserProgressForMonthData(), builder: (_, model, widget) => AppScaffold( isShowAppBar: false, - appBarTitle: TranslationBase.of(context).h2o, + appBarTitle: TranslationBase.of(context).h2o, baseViewModel: model, - body: Padding( - padding: EdgeInsets.all(8.0), - child: ListView( - children: [ - Center( - child: Text( - TranslationBase.of(context).waterConsumedInMonth, - textAlign: TextAlign.center, - style: TextStyle(fontSize: 20.0, color: Colors.black87), - ), - ), - SizedBox(height: 16), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Container( - height: 10, - width: 40, - color: Colors.blue, + body: SingleChildScrollView( + padding: EdgeInsets.all(21), + physics: BouncingScrollPhysics(), + child: (model.userProgressForMonthDataSeries ?? []).isEmpty + ? getNoDataWidget(context) + : Container( + padding: EdgeInsets.fromLTRB(16, 14, 16, 14), + 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), + ), + ], ), - SizedBox(width: 8), - Text( - TranslationBase.of(context).waterConsumedInMonth, - style: TextStyle(fontSize: 12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Text( + TranslationBase.of(context).waterConsumedInMonth, + style: TextStyle(fontSize: 16.0, color: Color(0xff2E303A), fontWeight: FontWeight.w600, letterSpacing: -0.64), + ), + SizedBox(height: 24), + CustomLineChart(model.userProgressForMonthDataSeries!, projectViewModel.isArabic), + ], ), - ], - ), - // SizedBox(height: 8), - AppBarChart(seriesList: model.userProgressForMonthDataSeries), - ], - ), + ), ), ), ); diff --git a/lib/pages/AlHabibMedicalService/h2o/today_page.dart b/lib/pages/AlHabibMedicalService/h2o/today_page.dart index 33383287..55a12105 100644 --- a/lib/pages/AlHabibMedicalService/h2o/today_page.dart +++ b/lib/pages/AlHabibMedicalService/h2o/today_page.dart @@ -1,14 +1,41 @@ +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'; +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/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:hexcolor/hexcolor.dart'; -import 'package:percent_indicator/circular_percent_indicator.dart'; +import 'package:flutter/services.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:wave/config.dart'; +import 'package:wave/wave.dart'; + +class TodayPage extends StatefulWidget { + TodayPage({Key? key}) : super(key: key); + + @override + _TodayPageState createState() { + return _TodayPageState(); + } +} + +class _TodayPageState extends State { + TextEditingController _h20AmountController = TextEditingController(); + + bool isUnitML = true; + Future readPrefs() async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + isUnitML = (prefs.getString(H2O_UNIT) ?? "ml") == "ml" ? true : false; + return isUnitML; + } + + bool canShowAddButton = false; -class TodayPage extends StatelessWidget { @override Widget build(BuildContext context) { return BaseView( @@ -18,132 +45,318 @@ class TodayPage extends StatelessWidget { appBarTitle: TranslationBase.of(context).h2o, baseViewModel: model, body: SingleChildScrollView( - padding: EdgeInsets.symmetric(vertical: 12), - child: Container( - margin: EdgeInsets.only(top: 60), - child: Column( - children: [ - Center( - child: CircularPercentIndicator( - radius: 180.0, - animation: true, - animationDuration: 1200, - lineWidth: 15.0, - percent: model.userProgressData == null - ? 0.0 - : (model.userProgressData.percentageConsumed / 100) >= 1 - ? 1 - : (model.userProgressData.percentageConsumed / 100), - //, - center: Center( + physics: BouncingScrollPhysics(), + padding: EdgeInsets.all(21), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: 320, + child: Row( + children: [ + Expanded( + child: FutureBuilder( + future: readPrefs(), + builder: (context, data) { + String unit; + if (data.connectionState == ConnectionState.done) { + isUnitML = data.data!; + } + if (isUnitML) { + unit = TranslationBase.of(context).ml; + } else { + unit = TranslationBase.of(context).l; + } + unit = unit.toLowerCase(); + double totalH2O = model?.userProgressData?.quantityLimit ?? 0.0; + double consumedH2O = model?.userProgressData?.quantityConsumed ?? 0.0; + if (!isUnitML) { + totalH2O = totalH2O / 1000; + consumedH2O = consumedH2O / 1000; + } + + if (consumedH2O > totalH2O) { + consumedH2O = totalH2O; + } + + double divide = consumedH2O / totalH2O; + String percentage = (divide * 100).toStringAsFixed(0); + var remainingH2O = totalH2O - consumedH2O; + + return AspectRatio( + aspectRatio: 234 / 320, + child: Stack( + alignment: Alignment.center, + children: [ + ClipRRect( + borderRadius: BorderRadius.circular(18), + child: WaveWidget( + config: CustomConfig( + colors: [Color(0xff0d47a1), Color(0xff1976d2), Color(0xff2196f3)], + durations: [19440, 10800, 6000], + heightPercentages: [1 - divide - .10, 1 - divide - .05, 1 - divide], + blur: MaskFilter.blur(BlurStyle.solid, 0), + ), + waveAmplitude: 0, + backgroundColor: Color(0xff2e303a), + size: Size( + double.infinity, + double.infinity, + ), + ), + ), + Padding( + padding: const EdgeInsets.only(top: 12, bottom: 12), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + remainingH2O.toStringAsFixed(0) + "$unit " + TranslationBase.of(context).left.toLowerCase(), + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + color: Colors.white, + letterSpacing: -0.56, + ), + ), + Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + "$percentage%", + style: TextStyle( + fontSize: 34, + fontWeight: FontWeight.bold, + color: Colors.white, + letterSpacing: -2.34, + ), + ), + Text( + TranslationBase.of(context).consumed, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + color: Colors.white, + letterSpacing: -0.56, + ), + ), + ], + ), + ], + ), + ) + ], + ), + ); + }, + ), + ), + SizedBox(width: 21), + SizedBox( + height: double.infinity, child: Column( - mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, children: [ - // SizedBox( - // height: 40, - // ), - Text( - TranslationBase.of(context).consumed, - style: TextStyle(fontSize: 16.0), - ), - SizedBox( - height: 4, - ), - Text( - model.userProgressData == null - ? "0.0" - : model.userProgressData.quantityConsumed.toString() + TranslationBase.of(context).ml, - style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14.0, color: HexColor("#60BCF9")), - ), - SizedBox( - height: 4, - ), - SizedBox( - height: 5, - width: 50, - child: Container(), - ), - SizedBox( - height: 4, - ), - Text( - TranslationBase.of(context).remaining, - style: TextStyle(fontSize: 16.0), - ), - SizedBox( - height: 4, - ), - Text( - model.userProgressData == null - ? "0.0" - : (model.userProgressData.quantityLimit - model.userProgressData.quantityConsumed) < 0 - ? "0 ${TranslationBase.of(context).ml}" - : (model.userProgressData.quantityLimit - model.userProgressData.quantityConsumed).toString() + - ' ${TranslationBase.of(context).ml}', - style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14.0), + _circularButton(context, 600, model), + SizedBox(height: 8), + _circularButton(context, 330, model), + SizedBox(height: 8), + _circularButton(context, 200, model), + SizedBox(height: 8), + InkWell( + onTap: () => undoVolume(context, model), + child: Text( + TranslationBase.of(context).undo, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + color: Color(0xffD02127), + letterSpacing: -0.56, + decoration: TextDecoration.underline, + ), + ), ), ], ), - ), - circularStrokeCap: CircularStrokeCap.butt, - backgroundColor: HexColor("#D1E3F6"), - progressColor: HexColor("#60BCF9"), + ) + ], + ), + ), + SizedBox(height: 40), + Text( + TranslationBase.of(context).addCustomAmount, + style: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.56, + ), + ), + SizedBox(height: 12), + 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, ), ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, + child: Column( + mainAxisSize: MainAxisSize.min, children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.center, + Row( children: [ - Container( - margin: EdgeInsets.only(bottom: 16), - height: 30, - width: 70, - decoration: BoxDecoration(color: HexColor("#D1E3F6"), borderRadius: BorderRadius.all(Radius.circular(30))), + Expanded( + flex: 3, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).amount_, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + color: Color(0xff2E303A), + letterSpacing: -0.44, + ), + ), + TextField( + controller: _h20AmountController, + keyboardType: TextInputType.number, + onChanged: (value) { + double _value = 0; + if (value.length > 0) _value = double.parse(value); + + if (value.length > 0) { + if (canShowAddButton) { + return; + } + canShowAddButton = true; + setState(() {}); + } else { + canShowAddButton = false; + setState(() {}); + } + }, + 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, + ), + contentPadding: EdgeInsets.zero, + border: InputBorder.none, + focusedBorder: InputBorder.none, + enabledBorder: InputBorder.none, + ), + ), + ], + ), ), - Text( - "${TranslationBase.of(context).remaining} %", - style: TextStyle(fontSize: 16.0), - ) + if (canShowAddButton) + Expanded( + flex: 1, + child: DefaultButton( + TranslationBase.of(context).add, + () async { + await showConfirmMessage(context, int.parse(_h20AmountController.text), model); + _h20AmountController.text = ""; + canShowAddButton = false; + SystemChannels.textInput.invokeMethod('TextInput.hide'); + setState(() {}); + }, + ), + ), ], ), - Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Container( - margin: EdgeInsets.only(bottom: 16), - height: 30, - width: 70, - decoration: BoxDecoration(color: HexColor("#60BCF9"), borderRadius: BorderRadius.all(Radius.circular(30))), - ), - Text( - "${TranslationBase.of(context).consumed} %", - style: TextStyle(fontSize: 16.0), - ) - ], - ) ], ), - SizedBox( - height: 30, - ), - SizedBox( - height: 0.5, - width: MediaQuery.of(context).size.width, - child: Container( - color: Colors.grey, - ), - ), - ], - ), + ), + ], ), ), - floatingActionButton: H20FloatingActionButton( - // controller: _controller, - model: model, + ), + ); + } + + Widget _circularButton(context, int value, model) { + String _text = "$value${TranslationBase.of(context).ml}"; + return InkWell( + onTap: () { + showConfirmMessage(context, value, model); + }, + child: Container( + padding: EdgeInsets.all(21), + alignment: Alignment.center, + decoration: BoxDecoration( + color: Colors.white, + shape: BoxShape.circle, + border: Border.all(width: 1, color: Color(0xffDEDEDE)), + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + TranslationBase.of(context).add, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w500, + color: Color(0xff575757), + letterSpacing: -0.44, + ), + ), + Text( + _text, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + color: Color(0xff2E303A), + letterSpacing: -0.56, + ), + ), + ], ), ), ); } + + Future showConfirmMessage(context, int amount, H2OViewModel model) async { + String title = "${TranslationBase.of(context).areyousure} $amount ${(isUnitML ? TranslationBase.of(context).ml : TranslationBase.of(context).l).toLowerCase()} ?"; + await showDialog( + context: context, + builder: (cxt) => ConfirmWithMessageDialog( + message: title, + onTap: () async { + GifLoaderDialogUtils.showMyDialog(context); + InsertUserActivityRequestModel insertUserActivityRequestModel = InsertUserActivityRequestModel(quantityIntake: amount); + await model.insertUserActivity(insertUserActivityRequestModel); + GifLoaderDialogUtils.hideDialog(context); + FocusManager.instance.primaryFocus!.unfocus(); + }, + ), + ); + } + + void undoVolume(context, H2OViewModel model) async { + GifLoaderDialogUtils.showMyDialog(context); + await model.undoUserActivity(); + GifLoaderDialogUtils.hideDialog(context); + } } diff --git a/lib/pages/AlHabibMedicalService/h2o/week_page.dart b/lib/pages/AlHabibMedicalService/h2o/week_page.dart index 34e365e6..447f8da7 100644 --- a/lib/pages/AlHabibMedicalService/h2o/week_page.dart +++ b/lib/pages/AlHabibMedicalService/h2o/week_page.dart @@ -1,54 +1,57 @@ -import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/H2O_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/charts/app_bar_chart.dart'; -import 'package:diplomaticquarterapp/widgets/errors/app_embedded_error.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/charts/custom_line_chart.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:diplomaticquarterapp/widgets/progress_indicator/app_circular_progress_Indeicator.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; class WeekPage extends StatelessWidget { @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); return BaseView( onModelReady: (model) => model.getUserProgressForWeekData(), builder: (_, model, widget) => AppScaffold( isShowAppBar: false, appBarTitle: TranslationBase.of(context).h2o, baseViewModel: model, - body: Padding( - padding: EdgeInsets.all(8.0), - child: ListView( - children: [ - Center( - child: Text( - TranslationBase.of(context).waterConsumedInWeek, - textAlign: TextAlign.center, - style: TextStyle(fontSize: 20.0, color: Colors.black87), - ), - ), - SizedBox(height: 16), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Container( - height: 10, - width: 40, - color: Colors.blue, + body: SingleChildScrollView( + padding: EdgeInsets.all(21), + physics: BouncingScrollPhysics(), + child: (model.userProgressForWeekDataSeries ?? []).isEmpty + ? getNoDataWidget(context) + : Container( + padding: EdgeInsets.fromLTRB(16, 14, 16, 14), + 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), + ), + ], ), - SizedBox(width: 8), - Text( - TranslationBase.of(context).waterConsumedInWeek, - style: TextStyle(fontSize: 12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Text( + TranslationBase.of(context).waterConsumedInWeek, + style: TextStyle(fontSize: 16.0, color: Color(0xff2E303A), fontWeight: FontWeight.w600, letterSpacing: -0.64), + ), + SizedBox(height: 24), + CustomLineChart(model.userProgressForWeekDataSeries!, projectViewModel.isArabic), + ], ), - ], - ), - // SizedBox(height: 8), - AppBarChart(seriesList: model.userProgressForWeekDataSeries), - ], - ), + ), ), ), ); diff --git a/lib/pages/AlHabibMedicalService/h2o/widgets/h20_buttom_navigation_bar.dart b/lib/pages/AlHabibMedicalService/h2o/widgets/h20_buttom_navigation_bar.dart new file mode 100644 index 00000000..9309fa9b --- /dev/null +++ b/lib/pages/AlHabibMedicalService/h2o/widgets/h20_buttom_navigation_bar.dart @@ -0,0 +1,59 @@ + +import 'package:diplomaticquarterapp/pages/BookAppointment/BookingOptions.dart'; +import 'package:diplomaticquarterapp/pages/DrawerPages/family/my-family.dart'; +import 'package:diplomaticquarterapp/pages/ToDoList/ToDo.dart'; +import 'package:diplomaticquarterapp/pages/landing/home_page_2.dart'; +import 'package:diplomaticquarterapp/pages/medical/medical_profile_page_new.dart'; +import 'package:diplomaticquarterapp/widgets/bottom_navigation/bottom_nav_bar.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/floatingActionButton.dart'; +import 'package:flutter/material.dart'; + +class H20BottomNavigationBar extends StatelessWidget { + H20BottomNavigationBar({Key? key}) : super(key: key); + + PageController pageController = PageController(keepPage: true); + int currentTab = 0; + + @override + Widget build(BuildContext context) { + // TODO: implement build + return Scaffold( + body: PageView( + physics: NeverScrollableScrollPhysics(), + controller: pageController, + children: [ + HomePage2( + goToMyProfile: () { + _changeCurrentTab(1); + }, + ), + MedicalProfilePageNew(), + BookingOptions(), + MyFamily(isAppbarVisible: false), + ToDo(isShowAppBar: false), + ], // Please do not remove the BookingOptions from this array + ), + bottomNavigationBar: BottomNavBar( + changeIndex: _changeCurrentTab, + index: currentTab, + ), + floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, + floatingActionButton: FloatingButton( + elevation: true, + onTap: () { + _changeCurrentTab(2); + }), + ); + } + + _changeCurrentTab(int tab) { + // setState(() { + currentTab = tab; + if (tab != 0) + pageController.jumpToPage(tab); + else { + pageController.jumpToPage(tab); + } + // }); + } +} 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 b692e6ba..00000000 --- a/lib/pages/AlHabibMedicalService/h2o/widgets/h20_floating_action_button.dart +++ /dev/null @@ -1,200 +0,0 @@ -import 'dart:math' as math; - -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/Dialog/confirm_add_amount_dialog.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'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; -import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; -import 'package:flutter/material.dart'; - -import '../add_custom_amount.dart'; - -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/AlHabibMedicalService/health-weather/health-weather-indicator.dart b/lib/pages/AlHabibMedicalService/health-weather/health-weather-indicator.dart index bc1de1f6..f799a161 100644 --- a/lib/pages/AlHabibMedicalService/health-weather/health-weather-indicator.dart +++ b/lib/pages/AlHabibMedicalService/health-weather/health-weather-indicator.dart @@ -3,16 +3,18 @@ import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/weather/weather_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/location_util.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/progress_indicator/app_circular_progress_Indeicator.dart'; 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'; -import 'package:diplomaticquarterapp/widgets/progress_indicator/app_circular_progress_Indeicator.dart'; class HealthWeatherIndicator extends StatefulWidget { @override @@ -22,92 +24,100 @@ class HealthWeatherIndicator extends StatefulWidget { class _HospitalsPageState extends State { var data; AppSharedPreferences sharedPref = AppSharedPreferences(); - LocationUtils locationUtils; + late LocationUtils locationUtils; var weather = '--'; + + late ProjectViewModel projectViewModel; + @override void initState() { - locationUtils = - new LocationUtils(isShowConfirmDialog: true, context: context); - WidgetsBinding.instance - .addPostFrameCallback((_) => locationUtils.getCurrentLocation()); + locationUtils = new LocationUtils(isShowConfirmDialog: true, context: context); + WidgetsBinding.instance.addPostFrameCallback((_) => locationUtils.getCurrentLocation()); getWeather(); super.initState(); } @override Widget build(BuildContext context) { - ProjectViewModel projectViewModel = Provider.of(context); + projectViewModel = Provider.of(context); return BaseView( onModelReady: (model) => model.getWeatherData(), allowAny: true, builder: (_, mode, widget) => AppScaffold( isShowDecPage: false, + showNewAppBar: true, + showNewAppBarTitle: true, appBarTitle: TranslationBase.of(context).healthWeatherIndicators, isShowAppBar: true, body: mode.weatherIndicatorData.length > 0 ? SingleChildScrollView( child: Column(children: [ Container( - margin: EdgeInsets.all(8), width: double.infinity, - height: 150, - decoration: BoxDecoration( - image: DecorationImage( - image: - ExactAssetImage('assets/images/Weather_img.png'), - fit: BoxFit.cover, - ), - borderRadius: BorderRadius.circular(8.0)), + 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: EdgeInsets.symmetric(horizontal: 10.0), + padding: const EdgeInsets.all(20.0), child: Row( children: [ Expanded( - flex: 3, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AppText( - TranslationBase.of(context) - .healthWeatherIndicators, - color: Colors.white, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Directionality( + textDirection: TextDirection.ltr, + child: Text( + weather, + style: TextStyle( + fontSize: 24, + letterSpacing: -0.83, + fontWeight: FontWeight.bold, + color: Colors.white, + ), + ), + ), + Text( + DateUtil.getMonthDayYearDateFormatted(new DateTime.now()), + style: TextStyle( + fontSize: 12, + letterSpacing: -0.60, fontWeight: FontWeight.w600, + color: Colors.white, ), - AppText( - TranslationBase.of(context) - .healthTipsBasedOnCurrentWeather, + ), + Text( + TranslationBase.of(context).healthWeatherIndicators, + style: TextStyle( + fontSize: 12, + letterSpacing: -0.96, + fontWeight: FontWeight.bold, color: Colors.white, - fontSize: 14, ), - ], - )), - Expanded( - flex: 2, - child: InkWell( - onTap: () {}, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Row( - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - Image.asset( - 'assets/images/Weather_ico.png', - width: 60, - height: 60, - ), - Directionality( - textDirection: TextDirection.ltr, - child: AppText(weather, - fontSize: 22, - color: Colors.white)) - ], - ), - ], - )), - ) + ), + Text( + TranslationBase.of(context).healthTipsBasedOnCurrentWeather, + style: TextStyle( + fontSize: 10, + letterSpacing: -0.72, + fontWeight: FontWeight.w600, + color: Colors.white, + ), + ), + ], + ), + ), + SvgPicture.asset( + "assets/images/new/cloudy.svg", + ), ], ), ), @@ -115,9 +125,7 @@ class _HospitalsPageState extends State { Padding( padding: EdgeInsets.all(15), child: AppText( - projectViewModel.isArabic - ? mode.weatherIndicatorData[0].cityNameN - : mode.weatherIndicatorData[0].cityName, + projectViewModel.isArabic ? mode.weatherIndicatorData[0].cityNameN! : mode.weatherIndicatorData[0].cityName!, fontSize: 24, fontWeight: FontWeight.bold, )), @@ -125,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/AlHabibMedicalService/health_calculator/bmi_calculator/bariatrics-screen.dart b/lib/pages/AlHabibMedicalService/health_calculator/bmi_calculator/bariatrics-screen.dart index d9665aa4..f3b88a60 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/bmi_calculator/bariatrics-screen.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/bmi_calculator/bariatrics-screen.dart @@ -1,14 +1,20 @@ +import 'dart:collection'; + import 'package:diplomaticquarterapp/config/size_config.dart'; -import 'package:diplomaticquarterapp/core/enum/viewstate.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/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'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -25,7 +31,7 @@ class BariatricsPage extends StatefulWidget { } class _BariatricsPageState extends State { - DiseasesByClinic _selectedDisease; + DiseasesByClinic? _selectedDisease; @override Widget build(BuildContext context) { @@ -33,125 +39,166 @@ class _BariatricsPageState extends State { return BaseView( onModelReady: (model) => model.getClinicCategory(), - builder: (_, model, w) => - AppScaffold( - isShowAppBar: true, - appBarTitle: "${TranslationBase - .of(context) - .bariatrics}", - baseViewModel: model, - body: Column( - children: [ - Container( - margin: EdgeInsets.all(8.0), - child: Center( - child: Texts(TranslationBase - .of(context) - .bariatricsHeaderMsg), - ), - ), - Expanded( - child: Container( - margin: EdgeInsets.symmetric( - horizontal: 16.0, vertical: 8.0), - child: Row( - children: [ - Expanded( - child: SingleChildScrollView( - child: Column( - children: [ - ...model.diseasesList - .map((item) => - RadioListTile( + builder: (_, model, w) => AppScaffold( + isShowDecPage: false, + isShowAppBar: true, + appBarTitle: "${TranslationBase.of(context).bariatrics}", + baseViewModel: model, + body: Column( + children: [ + Container( + margin: EdgeInsets.all(8.0), + child: Center( + child: Texts(TranslationBase.of(context).bariatricsHeaderMsg), + ), + ), + Expanded( + child: Container( + margin: EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0), + child: Row( + children: [ + Expanded( + child: SingleChildScrollView( + child: Column( + children: [ + ...model.diseasesList + .map((item) => RadioListTile( title: Texts("${item.diseases}"), activeColor: Colors.blue.shade700, value: item.diseasesID, - groupValue: _selectedDisease != null - ? _selectedDisease.diseasesID - : -1, - selected: _selectedDisease != null ? item - .diseasesID == - _selectedDisease.diseasesID : false, + groupValue: _selectedDisease != null ? _selectedDisease!.diseasesID! : -1, + selected: _selectedDisease != null ? item.diseasesID == _selectedDisease!.diseasesID : false, onChanged: (val) { setState(() { _selectedDisease = item; }); }, )) - .toList() - ], - ), - ), + .toList() + ], ), - Image.asset( - _getImageName(widget.gender, widget.obeseResult, - projectProvider.isArabic), - fit: BoxFit.cover, - ), - ], + ), ), - ), - ), - Container( - margin: EdgeInsets.symmetric(horizontal: 16, vertical: 16), - child: BorderedButton( - TranslationBase - .of(context) - .continues, - fontSize: SizeConfig.textMultiplier * 2.1, - textColor: Colors.white, - vPadding: 8, - hPadding: 8, - backgroundColor: Theme - .of(context) - .primaryColor, - radius: 8, - fontWeight: FontWeight.bold, - handler: () async { - await model.searchDoctorsByTime(_selectedDisease); - if(model.state == ViewState.ErrorLocal){ - AppToast.showErrorToast(message: model.error); - } - // Navigator.push( - // context, - // MaterialPageRoute(builder: (context) => BariatricsPage()), - // ); - }, - ), - ), - Container( - margin: EdgeInsets.only(bottom: 16.0, left: 16, right: 16), - child: BorderedButton( - TranslationBase - .of(context) - .skip, - fontSize: SizeConfig.textMultiplier * 2.1, - textColor: Colors.blue, - vPadding: 8, - hPadding: 8, - backgroundColor: Color(0x00000000), - radius: 8, - hasBorder: true, - borderColor: Color(0x00000000), - fontWeight: FontWeight.bold, - handler: () async { - await model.searchDoctorsByTime(_selectedDisease); - if(model.state == ViewState.ErrorLocal){ - AppToast.showErrorToast(message: model.error); - } - // Navigator.push( - // context, - // MaterialPageRoute(builder: (context) => BariatricsPage()), - // ); - }, - ), + Image.asset( + _getImageName(widget.gender, widget.obeseResult, projectProvider.isArabic), + fit: BoxFit.cover, + ), + ], ), - ], + ), + ), + Container( + margin: EdgeInsets.symmetric(horizontal: 16, vertical: 16), + child: BorderedButton( + TranslationBase.of(context).continues, + fontSize: SizeConfig.textMultiplier! * 2.1, + textColor: Colors.white, + vPadding: 8, + hPadding: 8, + backgroundColor: Theme.of(context).primaryColor, + radius: 8, + fontWeight: FontWeight.bold, + handler: () async { + callDoctorsSearchAPI(); + // Navigator.push( + // context, + // FadePage( + // page: DoctorList( + // diseaseByClinic: _selectedDisease, + // )), + // ); + }, + ), + ), + Container( + margin: EdgeInsets.only(bottom: 16.0, left: 16, right: 16), + child: BorderedButton( + TranslationBase.of(context).skip, + fontSize: SizeConfig.textMultiplier! * 2.1, + textColor: Colors.blue, + vPadding: 8, + hPadding: 8, + backgroundColor: Color(0x00000000), + radius: 8, + hasBorder: true, + borderColor: Color(0x00000000), + fontWeight: FontWeight.bold, + handler: () async { + callDoctorsSearchAPI(); + // Navigator.push( + // context, + // FadePage(page: DoctorList()), + // ); + }, + ), ), - ), + ], + ), + ), ); } + callDoctorsSearchAPI() { + ProjectViewModel projectProvider = Provider.of(context); + int languageID = projectProvider.isArabic! ? 1 : 2; + GifLoaderDialogUtils.showMyDialog(context); + List doctorsList = []; + List arr = []; + List arrDistance = []; + List result; + int numAll; + List _patientDoctorAppointmentListHospital =[]; + + DoctorsListService service = new DoctorsListService(); + service.getDoctorsList(108, 0, false, languageID, 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, isDoctorSearchResult: false,))) + .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/bmi_calculator/bmi_calculator.dart b/lib/pages/AlHabibMedicalService/health_calculator/bmi_calculator/bmi_calculator.dart index 8b9a5409..e74a4615 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/bmi_calculator/bmi_calculator.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/bmi_calculator/bmi_calculator.dart @@ -1,12 +1,14 @@ +import 'dart:math'; + +import 'package:diplomaticquarterapp/main.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/button.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/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'dart:math'; import 'result_page.dart'; @@ -19,56 +21,21 @@ class BMICalculator extends StatefulWidget { } class _BMICalculatorState extends State { - TextEditingController textController = new TextEditingController(); - String textResult; - String msg; - double bmiResult; - int height = 150; - int weight = 40; - Color cmCard = activeCardColor; - Color ftCard = inactiveCardColor; - Color lbCard = inactiveCardColor; - Color kgCard = activeCardColor; + TextEditingController textController = TextEditingController(); + String? textResult; + String? msg; + double? bmiResult; - void updateColor(int type) { - //MG/DLT card - if (type == 1) { - if (cmCard == inactiveCardColor) { - cmCard = activeCardColor; - ftCard = inactiveCardColor; - } else { - cmCard = inactiveCardColor; - } - } - if (type == 2) { - if (ftCard == inactiveCardColor) { - ftCard = activeCardColor; - cmCard = inactiveCardColor; - } else { - ftCard = inactiveCardColor; - } - } - } + TextEditingController _heightController = TextEditingController(); + TextEditingController _weightController = TextEditingController(); - void updateColorWeight(int type) { - //MG/DLT card - if (type == 1) { - if (kgCard == inactiveCardColor) { - kgCard = activeCardColor; - lbCard = inactiveCardColor; - } else { - kgCard = inactiveCardColor; - } - } - if (type == 2) { - if (lbCard == inactiveCardColor) { - lbCard = activeCardColor; - kgCard = inactiveCardColor; - } else { - lbCard = inactiveCardColor; - } - } - } + List _weightPopupList = []; + List _heightPopupList = []; + + bool _isHeightCM = true; + bool _isWeightKG = true; + double _heightValue = 150; + double _weightValue = 40; double convertToCm(double number) { return number * 30.48; @@ -79,34 +46,35 @@ class _BMICalculatorState extends State { } double calculateBMI() { - if (ftCard == activeCardColor) { - convertToCm(height.toDouble()); - } - bmiResult = weight / pow(height / 100, 2); + if (!_isHeightCM) _heightValue = convertToCm(_heightValue.toDouble()); + + if (!_isWeightKG) _weightValue = convertToKg(_weightValue); + + bmiResult = _weightValue / pow(_heightValue / 100, 2); - return bmiResult; + return bmiResult!; } void showTextResult(BuildContext context) { - if (bmiResult >= 30) { + if (bmiResult! >= 30) { textResult = TranslationBase.of(context).obese; - } else if (bmiResult < 30 && bmiResult >= 25) { + } else if (bmiResult! < 30 && bmiResult! >= 25) { textResult = TranslationBase.of(context).overWeight; - } else if (bmiResult < 25 && bmiResult >= 18.5) { + } else if (bmiResult! < 25 && bmiResult! >= 18.5) { textResult = TranslationBase.of(context).healthy; - } else if (bmiResult < 18.5) { + } else if (bmiResult! < 18.5) { textResult = TranslationBase.of(context).underWeight; } } void showMsg(BuildContext context) { - if (bmiResult >= 30) { + if (bmiResult! >= 30) { msg = TranslationBase.of(context).bmiCalcMsgObese; - } else if (bmiResult < 30 && bmiResult >= 25) { + } else if (bmiResult! < 30 && bmiResult! >= 25) { msg = TranslationBase.of(context).bmiCalcMsgOverweight; - } else if (bmiResult < 25 && bmiResult >= 18.5) { + } else if (bmiResult! < 25 && bmiResult! >= 18.5) { msg = TranslationBase.of(context).bmiCalcMsgHealthy; - } else if (bmiResult < 18.5) { + } else if (bmiResult! < 18.5) { msg = TranslationBase.of(context).bmiCalcMsgUnderWeight; } } @@ -115,415 +83,281 @@ class _BMICalculatorState extends State { void initState() { super.initState(); textController.text = '0'; // Setting the initial value for the field. + _heightValue = 100; + _weightValue = 50; + _heightController.text = _heightValue.toStringAsFixed(0); + _weightController.text = _weightValue.toStringAsFixed(0); + + _isWeightKG = true; + _isHeightCM = true; } Widget build(BuildContext context) { + _weightPopupList = [PopupMenuItem(child: Text(TranslationBase.of(context).kg), value: true), PopupMenuItem(child: Text(TranslationBase.of(context).lb), value: false)]; + _heightPopupList = [PopupMenuItem(child: Text(TranslationBase.of(context).cm), value: true), PopupMenuItem(child: Text(TranslationBase.of(context).ft), value: false)]; + return AppScaffold( isShowAppBar: true, isShowDecPage: false, - appBarTitle: - "${TranslationBase.of(context).bmi} ${TranslationBase.of(context).calcHealth}", - body: SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Center( - child: Container( - margin: EdgeInsets.symmetric(vertical: 8, horizontal: 16), - child: Padding( - padding: EdgeInsets.symmetric(vertical: 15.0), - child: Text( - TranslationBase.of(context).bmiCalcDesc, - style: TextStyle(fontSize: 18.0), - ), - ), - ), - ), - Container( - margin: EdgeInsets.symmetric(vertical: 8, horizontal: 16), - padding: EdgeInsets.only(bottom: 16), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(12.0), - ), + showHomeAppBarIcon: true, + showNewAppBar: true, + showNewAppBarTitle: true, + appBarTitle: "${TranslationBase.of(context).bmi} ${TranslationBase.of(context).calcHealth}", + body: Column( + children: [ + Expanded( + child: Padding( + padding: const EdgeInsets.all(16.0), child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Row( - children: [ - Padding( - padding: EdgeInsets.all(8.0), - child: Texts(TranslationBase.of(context).height), - ), - ], - ), - Row( - children: [ - Padding( - padding: EdgeInsets.symmetric( - vertical: 10.0, horizontal: 8.0), - child: Center( - child: Container( - width: 60.0, - foregroundDecoration: BoxDecoration( - borderRadius: BorderRadius.circular(5.0), - border: Border.all( - color: Colors.blueGrey, - width: 2.0, - ), - ), - child: Row( - children: [ - Expanded( - child: Center( - child: Text(height.toString()), - ), - ), - Container( - height: 38.0, - child: Column( - crossAxisAlignment: - CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Container( - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - width: 0.5, - ), - ), - ), - child: InkWell( - child: Icon( - Icons.arrow_drop_up, - size: 18.0, - ), - onTap: () { - setState(() { - if (height < 250) height++; - }); - }, - ), - ), - InkWell( - child: Icon( - Icons.arrow_drop_down, - size: 18.0, - ), - onTap: () { - setState(() { - if (height > 120) height--; - }); - }, - ), - ], - ), - ), - ], - ), - ), - ), - ), - Slider( - value: height.toDouble(), - min: 120, - max: 250, - onChanged: (double newValue) { - setState(() { - height = newValue.round(); - }); - }, - activeColor: Color(0xffC5272D), - inactiveColor: Color(0xffF3C5C6), - ), - ], + Text( + TranslationBase.of(context).bmiCalcDesc, + style: TextStyle( + fontSize: 14.0, + letterSpacing: -0.56, + fontWeight: FontWeight.w600, + ), ), - Row( - children: [ - Padding( - padding: EdgeInsets.all(8.0), - child: Texts(TranslationBase.of(context).selectUnit), - ), - ], + mHeight(24), + _commonInputAndUnitRow( + TranslationBase.of(context).height, + _heightController, + 1, + 270, + _heightValue, + (text) { + _heightController.text = text; + }, + (value) { + _heightValue = value; + }, + _isHeightCM ? TranslationBase.of(context).cm : TranslationBase.of(context).ft, + (value) { + if (_isHeightCM != value) { + setState(() { + _isHeightCM = value; + }); + } + }, + _heightPopupList, ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - GestureDetector( - onTap: () { - setState(() { - updateColor(1); - }); - }, - child: Container( - height: 55.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: cmCard, - borderRadius: BorderRadius.circular(3.0), - ), - child: Padding( - padding: const EdgeInsets.symmetric( - vertical: 0.0, horizontal: 18.0), - child: Center( - child: Texts(TranslationBase.of(context).cm)), - ), - ), - ), - GestureDetector( - onTap: () { - setState(() { - updateColor(2); - }); - }, - child: Container( - height: 55.0, - width: 150.0, - decoration: BoxDecoration( - color: ftCard, - 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: Center( - child: Texts(TranslationBase.of(context).feet)), - ), - ), - ), - ], + mHeight(12), + _commonInputAndUnitRow( + TranslationBase.of(context).weight, + _weightController, + 1, + 270, + _weightValue, + (text) { + _weightController.text = text; + }, + (value) { + _weightValue = value; + }, + _isWeightKG ? TranslationBase.of(context).kg : TranslationBase.of(context).pound, + (value) { + if (_isWeightKG != value) { + setState(() { + _isWeightKG = value; + }); + } + }, + _weightPopupList, ), ], ), ), - SizedBox( - height: 25.0, - ), - Container( - margin: EdgeInsets.symmetric(vertical: 8, horizontal: 16), - padding: EdgeInsets.only(bottom: 16), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(12.0), - ), - child: Column( - children: [ - Row( - children: [ - Padding( - padding: EdgeInsets.all(8.0), - child: Texts(TranslationBase.of(context).weight), - ), - ], - ), - Row( - children: [ - Padding( - padding: EdgeInsets.symmetric( - vertical: 10.0, horizontal: 8.0), - child: Center( - child: Container( - width: 60.0, - foregroundDecoration: BoxDecoration( - borderRadius: BorderRadius.circular(5.0), - border: Border.all( - color: Colors.blueGrey, - width: 2.0, - ), - ), - child: Row( - children: [ - Expanded( - child: Center( - child: Text(weight.toString()), - ), - ), - Container( - height: 38.0, - child: Column( - crossAxisAlignment: - CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Container( - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - width: 0.5, - ), - ), - ), - child: InkWell( - child: Icon( - Icons.arrow_drop_up, - size: 18.0, - ), - onTap: () { - setState(() { - if (weight < 250) weight++; - }); - }, - ), - ), - InkWell( - child: Icon( - Icons.arrow_drop_down, - size: 18.0, - ), - onTap: () { - setState(() { - if (weight > 40) weight--; - }); - }, - ), - ], - ), - ), - ], - ), - ), + ), + Container( + color: Colors.white, + padding: EdgeInsets.all(16), + child: SecondaryButton( + label: TranslationBase.of(context).calculate, + color: CustomColors.accentColor, + onTap: () { + setState(() { + calculateBMI(); + showTextResult(context); + showMsg(context); + { + Navigator.push( + context, + FadePage( + page: ResultPage( + finalResult: bmiResult!, + textResult: textResult!, + msg: msg!, ), ), - Slider( - value: weight.toDouble(), - min: 40, - max: 250, - onChanged: (double newValue) { - setState(() { - weight = newValue.round(); - }); - }, - activeColor: Color(0xffC5272D), - inactiveColor: Color(0xffF3C5C6), - ), - ], - ), - Row( - children: [ - Padding( - padding: EdgeInsets.all(8.0), - child: Texts(TranslationBase.of(context).selectUnit), - ), - ], - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - GestureDetector( - onTap: () { - setState(() { - updateColorWeight(1); - }); - }, - child: Container( - height: 55.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: kgCard, - borderRadius: BorderRadius.circular(3.0), - ), - child: Padding( - padding: const EdgeInsets.symmetric( - vertical: 0.0, horizontal: 18.0), - child: Center( - child: Texts(TranslationBase.of(context).kg)), - ), - ), - ), - GestureDetector( - onTap: () { - setState(() { - updateColorWeight(2); - }); - }, - child: Container( - height: 55.0, - width: 150.0, - decoration: BoxDecoration( - color: lbCard, - 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: Center( - child: - Texts(TranslationBase.of(context).pound)), - ), - ), - ), - ], - ), - ], - ), - ), - SizedBox( - height: 25.0, + ); + } + }); + }, ), - Container( - margin: EdgeInsets.symmetric(vertical: 8, horizontal: 16), - padding: EdgeInsets.symmetric(vertical: 8), - child: SecondaryButton( - label: TranslationBase.of(context).calculate, - onTap: () => { - setState(() { - calculateBMI(); - showTextResult(context); - showMsg(context); - { - Navigator.push( - context, - FadePage( - page: ResultPage( - finalResult: bmiResult, - textResult: textResult, - msg: msg, - )), - ); - } - }) + ), + ], + ), + ); + } + + Widget _commonInputAndUnitRow(_title, _controller, double _minValue, double _maxValue, double _valueOrg, Function(String) onTextValueChange, Function(double) onValueChange, String unitTitle, + Function(bool) onUnitTap, _list) { + 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( + 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, + ), ), - ), - ], + ], + ), ), + 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, + (val) async { + final RenderBox overlay = Overlay.of(context).context.findRenderObject() as RenderBox; + await showMenu( + context: context, + position: RelativeRect.fromRect(val.globalPosition & const Size(40, 40), Offset.zero & overlay.size), + items: _list, + elevation: 8.0, + ).then((val) { + print(val); + onUnitTap(val); + }); + }, + ), + itemBuilder: (context) => _list, + ), + ) + ], + ).withBorderedContainer; + } +} + +// todo 'sikander' move these to separate file once usability known +class CommonDropDownView extends StatefulWidget { + final String title; + final String value; + void Function(TapDownDetails details) callback; + final IconData? iconData; + + CommonDropDownView(this.title, this.value, this.callback, {Key? key, this.iconData}) : super(key: key); + + @override + State createState() => _CommonDropDownViewState(); +} + +class _CommonDropDownViewState extends State { + @override + Widget build(BuildContext context) { + return GestureDetector( + onTapDown: (val) { + widget.callback(val); + }, + child: Row( + children: [ + Expanded( + child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ + Text( + widget.title, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + color: Color(0xff2E303A), + letterSpacing: -0.44, + ), + ), + Text( + widget.value, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w400, + color: Color(0xff575757), + letterSpacing: -0.56, + ), + ), + ]), + ), + Icon( + widget.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/health_calculator/bmi_calculator/result_page.dart b/lib/pages/AlHabibMedicalService/health_calculator/bmi_calculator/result_page.dart index a541b3ce..26222569 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/bmi_calculator/result_page.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/bmi_calculator/result_page.dart @@ -1,123 +1,134 @@ -import 'dart:ffi'; +import 'dart:collection'; -import 'package:diplomaticquarterapp/config/size_config.dart'; -import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/health_calculator/bmi_calculator/bariatrics-screen.dart'; +import 'package:auto_size_text/auto_size_text.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/SearchResults.dart'; +import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/borderedButton.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/button.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:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; -import 'package:percent_indicator/percent_indicator.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:provider/provider.dart'; -class ResultPage extends StatelessWidget { +class ResultPage extends StatefulWidget { final double finalResult; final String textResult; final String msg; - ResultPage({this.finalResult, this.textResult, this.msg}); + ResultPage({required this.finalResult, required this.textResult, required this.msg}); - Color inductorColor; - double percent; + @override + _ResultPageState createState() => _ResultPageState(); +} + +class _ResultPageState extends State { + Color? inductorColor; + + double? percent; Color colorInductor() { - if (finalResult >= 30) { + if (widget.finalResult >= 30) { inductorColor = Color(0xffC70D00); - } else if (finalResult < 30 && finalResult >= 25) { + } else if (widget.finalResult < 30 && widget.finalResult >= 25) { inductorColor = Color(0xffC25400); - } else if (finalResult < 25 && finalResult >= 18.5) { + } else if (widget.finalResult < 25 && widget.finalResult >= 18.5) { inductorColor = Color(0xff36D600); - } else if (finalResult < 18.5) { + } else if (widget.finalResult < 18.5) { inductorColor = Color(0xff1BE0EE); } - return inductorColor; + return inductorColor!; } double percentInductor() { - if (finalResult >= 30) { + if (widget.finalResult >= 30) { percent = 1.0; - } else if (finalResult < 30 && finalResult >= 25) { + } else if (widget.finalResult < 30 && widget.finalResult >= 25) { percent = 0.73; - } else if (finalResult < 25 && finalResult >= 18.5) { + } else if (widget.finalResult < 25 && widget.finalResult >= 18.5) { percent = 0.5; - } else if (finalResult < 18.5) { + } else if (widget.finalResult < 18.5) { percent = 0.25; } - return percent; + return percent!; } @override Widget build(BuildContext context) { return AppScaffold( + isShowDecPage: false, isShowAppBar: true, - appBarTitle: - "${TranslationBase.of(context).bmi} ${TranslationBase.of(context).calcHealth}", + showNewAppBarTitle: true, + showNewAppBar: true, + appBarTitle: "${TranslationBase.of(context).bmi} ${TranslationBase.of(context).calcHealth}", body: Column( children: [ - Expanded( - child: SingleChildScrollView( + Container( + margin: EdgeInsets.only(left: 20, right: 20, top: 20, bottom: 6), + decoration: cardRadius(12), + child: Padding( + padding: const EdgeInsets.all(12.0), child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, children: [ - Container( - margin: EdgeInsets.only(top: 50), - child: Center( - child: CircularPercentIndicator( - radius: 220.0, - lineWidth: 20.0, - percent: percentInductor(), - center: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - finalResult.toStringAsFixed(1), - style: TextStyle( - fontSize: 18.0, - fontWeight: FontWeight.bold, - ), - ), - SizedBox( - height: 5.0, - ), - Text( - textResult, - style: TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.w600, - ), - ), - ], - ), - progressColor: colorInductor(), - backgroundColor: Colors.white, - ), + Text( + TranslationBase.of(context).bodyMassIndex + widget.finalResult.toStringAsFixed(2), + style: TextStyle( + fontSize: 16, + letterSpacing: -0.64, + fontWeight: FontWeight.w600, ), ), + mHeight(20), Container( - margin: EdgeInsets.symmetric(horizontal: 16, vertical: 16), - child: Texts(msg), + height: MediaQuery.of(context).size.width / 2.8, + child: Row( + children: [ + showMass(context, TranslationBase.of(context).underWeight, "< 18.5", widget.finalResult <= 18.5 ? Colors.red : Colors.black, 8), + mWidth(12), + showMass(context, TranslationBase.of(context).healthy, "18.5 - 24.9", (widget.finalResult > 18.5 && widget.finalResult < 25) ? Colors.red : Colors.black, 6), + mWidth(12), + showMass(context, TranslationBase.of(context).overWeight, "25 - 29.9", (widget.finalResult >= 25 && widget.finalResult < 30) ? Colors.red : Colors.black, 4), + mWidth(12), + showMass(context, TranslationBase.of(context).obese, "30 - 34.9", (widget.finalResult >= 30 && widget.finalResult < 35) ? Colors.red : Colors.black, 2), + mWidth(12), + showMass(context, TranslationBase.of(context).extremeObese, "> 35", (widget.finalResult >= 35) ? Colors.red : Colors.black, 0), + ], + ), + ), + mHeight(20), + Text( + widget.textResult, + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.w600, + letterSpacing: -0.56, + ), + ), + mHeight(4), + Text( + widget.msg, + style: TextStyle(fontSize: 14.0, fontWeight: FontWeight.w600, letterSpacing: -0.56, color: CustomColors.textColor), ), ], ), ), ), + mFlex(1), Container( - margin: EdgeInsets.symmetric(horizontal: 16, vertical: 16), - child: BorderedButton( + color: Colors.white, + padding: EdgeInsets.all(16), + child: DefaultButton( TranslationBase.of(context).seeListOfDoctor, - fontSize: SizeConfig.textMultiplier * 2.1, - textColor: Colors.white, - vPadding: 8, - hPadding: 8, - backgroundColor: Theme.of(context).primaryColor, - radius: 8, - fontWeight: FontWeight.bold, - handler: (){ - Navigator.push( - context, - FadePage( - page: BariatricsPage(1, 1, finalResult)), - ); + () { + callDoctorsSearchAPI(); }, ), ), @@ -125,4 +136,117 @@ class ResultPage extends StatelessWidget { ), ); } + + callDoctorsSearchAPI() { + int languageID = Provider.of(context, listen: false).isArabic ? 1 : 2; + GifLoaderDialogUtils.showMyDialog(context); + List doctorsList = []; + List arr = []; + List arrDistance = []; + List result; + int numAll; + List _patientDoctorAppointmentListHospital =[]; + + DoctorsListService service = new DoctorsListService(); + service.getDoctorsList(108, 0, false, languageID, 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, isDoctorSearchResult: false,))) + .then((value) { + setState(() { + // dropdownValue = null; + }); + // getProjectsList(); + }); + } + + Widget showMass(BuildContext context, String title, String weight, Color color, int f) { + return Expanded( + flex: 1, + child: Container( + height: double.infinity, + width: double.infinity, + child: Column( + children: [ + Flexible( + child: Row( + children: [ + mFlex(f), + Flexible( + flex: 10, + child: SvgPicture.asset( + "assets/images/new/mass/health_BMI.svg", + height: double.infinity, + width: double.infinity, + fit: BoxFit.fill, + color: color, + ), + ), + mFlex(f), + ], + ), + ), + mHeight(20), + AutoSizeText( + title, + maxLines: 1, + minFontSize: 6, + style: TextStyle( + color: color, + fontSize: 10, + letterSpacing: -0.6, + ), + ), + AutoSizeText( + weight, + maxLines: 1, + minFontSize: 6, + style: TextStyle( + color: color, + fontSize: 10, + letterSpacing: -0.6, + ), + ) + ], + ), + ), + ); + } } 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 9e3d049f..58b55f33 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/bmr_calculator/bmr_calculator.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/bmr_calculator/bmr_calculator.dart @@ -1,10 +1,14 @@ -import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; -import 'dart:math'; +import 'package:flutter/services.dart'; +import 'package:provider/provider.dart'; import 'bmr_result_page.dart'; @@ -27,11 +31,25 @@ class _BmrCalculatorState extends State { Color lbCard = inactiveCardColor; Color cmCard = activeCardColor; Color ftCard = inactiveCardColor; - int age = 0; - int height = 0; - int weight = 0; + + final GlobalKey clinicDropdownKey = GlobalKey(); + TextEditingController ageController = new TextEditingController(); + TextEditingController _heightController = new TextEditingController(); + TextEditingController _weightController = TextEditingController(); + + bool _isHeightCM = true; + bool _isWeightKG = true; + double _heightValue = 150; + double _weightValue = 40; + + List _heightPopupList = []; + List _weightPopupList = []; + + // int age = 0; + // int height = 0; + // int weight = 0; double bmrResult = 0; - String dropdownValue = 'Lighty Active (1-3) days per week'; + String dropdownValue = ''; double calories = 0; void updateColor(int type) { @@ -96,23 +114,22 @@ class _BmrCalculatorState extends State { void calculateBmr() { if (isMale == true) { - bmrResult = 66.5 + (13.75 * weight) + (5.003 * height) - (6.755 * age); + bmrResult = 66.5 + (13.75 * int.parse(_weightController.text)) + (5.003 * int.parse(_heightController.text)) - (6.755 * int.parse(ageController.text)); } else if (isMale == false) { - bmrResult = - 655.0955 + (9.5634 * weight) + (1.850 * height) - (4.676 * age); + bmrResult = 655.0955 + (9.5634 * int.parse(_weightController.text)) + (1.850 * int.parse(_heightController.text)) - (4.676 * int.parse(ageController.text)); } bmrResult = bmrResult.roundToDouble(); } - void calculateCalories() { - if (dropdownValue == "Almost Inactive(Little or no exercises)") { + void calculateCalories(BuildContext context) { + if (dropdownValue == TranslationBase.of(context).almostInactive) { calories = bmrResult * 1.2; - } else if (dropdownValue == "Lighty Active (1-3) days per week") { + } else if (dropdownValue == TranslationBase.of(context).lightActive1) { calories = bmrResult * 1.375; - } else if (dropdownValue == "very Active(6-7) days per week") { + } else if (dropdownValue == TranslationBase.of(context).veryActive) { calories = bmrResult * 1.55; - } else if (dropdownValue == "Super Active(very hard exercises)") { + } else if (dropdownValue == TranslationBase.of(context).superActive) { calories = bmrResult * 1.725; } else if (dropdownValue == "") { calories = bmrResult * 10.725; @@ -121,604 +138,540 @@ class _BmrCalculatorState extends State { @override Widget build(BuildContext context) { + dropdownValue = TranslationBase.of(context).lightActive1; + ProjectViewModel projectViewModel = Provider.of(context); + _weightPopupList = [PopupMenuItem(child: Text(TranslationBase.of(context).kg), value: true), PopupMenuItem(child: Text(TranslationBase.of(context).lb), value: false)]; + _heightPopupList = [PopupMenuItem(child: Text(TranslationBase.of(context).cm), value: true), PopupMenuItem(child: Text(TranslationBase.of(context).ft), value: false)]; + return AppScaffold( isShowAppBar: true, isShowDecPage: false, - appBarTitle: 'Bmr Calculator', - body: Padding( - padding: EdgeInsets.symmetric(horizontal: 25.0, vertical: 15.0), - child: SingleChildScrollView( - child: Container( - height: 850, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: EdgeInsets.all(10.0), - child: Texts( - 'Calculates the amount of energy that the person’s body expends in a day'), - ), - Divider( - thickness: 2.0, - ), - SizedBox( - height: 5.0, - ), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts('Gender'), - SizedBox( - height: 5.0, - ), - Container( - width: 350, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(35.0), - color: Colors.white, - border: Border.all( - color: Colors.black45, - )), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, + showNewAppBarTitle: true, + showNewAppBar: true, + appBarTitle: TranslationBase.of(context).bmr, + showHomeAppBarIcon: false, + appBarIcons: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 7.0), + child: Icon( + Icons.info_outline, + color: Colors.white, + ), + ) + ], + body: Container( + height: double.infinity, + width: double.infinity, + child: Column( + children: [ + Expanded( + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(21.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).calculateAmount, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + letterSpacing: -0.56, + color: CustomColors.textColor, + ), + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - GestureDetector( - onTap: () { - setState(() { - updateColor(1); - isMale = false; - }); - }, - child: Container( - height: 55.0, - width: 170.0, - decoration: BoxDecoration( - color: maleCard, - borderRadius: BorderRadius.circular(35.0), - ), - child: Center(child: Texts('FEMALE')), - ), + SizedBox( + height: 20, ), - GestureDetector( - onTap: () { - setState(() { - updateColor(2); - isMale = true; - }); - }, - child: Container( - height: 55.0, - width: 170.0, - decoration: BoxDecoration( - color: femaleCard, - borderRadius: BorderRadius.circular(35.0), - ), - child: Center(child: Texts('MALE')), + Text( + TranslationBase.of(context).selectGender, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + letterSpacing: -0.56, + color: CustomColors.textColor, ), ), - ], - ), - ), - SizedBox( - height: 5.0, - ), - Texts( - 'The Age ( 11 - 120 ) yrs', - ), - SizedBox( - height: 10.0, - ), - Row( - children: [ - Container( - width: 340.0, - height: 60.0, - decoration: BoxDecoration( - color: Colors.white, + SizedBox( + height: 8.0, ), - child: Row( - children: [ - Padding( - padding: EdgeInsets.symmetric( - vertical: 10.0, horizontal: 8.0), - child: Center( - child: Container( - width: 60.0, - foregroundDecoration: BoxDecoration( - borderRadius: BorderRadius.circular(5.0), - border: Border.all( - color: Colors.blueGrey, - width: 2.0, - ), - ), + Container( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Expanded( + child: GestureDetector( + onTap: () { + setState(() { + updateColor(1); + isMale = false; + }); + }, child: Row( - children: [ - Expanded( - child: Center( - child: Text(age.toString()), + children: [ + Container( + decoration: containerColorRadiusBorderWidth(Colors.white, 1000, CustomColors.darkGreyColor, 1), + width: 24, + height: 24, + padding: EdgeInsets.all(4), + child: Container( + width: double.infinity, + height: double.infinity, + decoration: containerRadius(!isMale ? CustomColors.accentColor : Colors.white, 100), ), ), - Container( - height: 38.0, - child: Column( - crossAxisAlignment: - CrossAxisAlignment.center, - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - Container( - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - width: 0.5, - ), - ), - ), - child: InkWell( - child: Icon( - Icons.arrow_drop_up, - size: 18.0, - ), - onTap: () { - setState(() { - if (age < 120) age++; - }); - }, - ), - ), - InkWell( - child: Icon( - Icons.arrow_drop_down, - size: 18.0, - ), - onTap: () { - setState(() { - if (age > 0) age--; - }); - }, - ), - ], + mWidth(12), + Text( + TranslationBase.of(context).female, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + letterSpacing: -0.56, ), ), ], ), ), ), - ), - Expanded( - child: Slider( - value: age.toDouble(), - min: 0, - max: 120, - onChanged: (double newValue) { - setState(() { - age = newValue.round(); - }); - }, - activeColor: Color(0xffC5272D), - inactiveColor: Color(0xffF3C5C6), - ), - ), - ], - ), - ), - ], - ), - Texts( - 'Height', - ), - Row( - children: [ - Container( - width: 340.0, - height: 60.0, - decoration: BoxDecoration( - color: Colors.white, - ), - child: Row( - children: [ - Padding( - padding: EdgeInsets.symmetric( - vertical: 10.0, horizontal: 8.0), - child: Center( - child: Container( - width: 60.0, - foregroundDecoration: BoxDecoration( - borderRadius: BorderRadius.circular(5.0), - border: Border.all( - color: Colors.blueGrey, - width: 2.0, - ), - ), + Expanded( + child: GestureDetector( + onTap: () { + setState(() { + updateColor(2); + isMale = true; + }); + }, child: Row( - children: [ - Expanded( - child: Center( - child: Text(height.toString()), + children: [ + Container( + decoration: containerColorRadiusBorderWidth(Colors.white, 1000, CustomColors.darkGreyColor, 1), + width: 24, + height: 24, + padding: EdgeInsets.all(4), + child: Container( + width: double.infinity, + height: double.infinity, + decoration: containerRadius(isMale ? CustomColors.accentColor : Colors.white, 100), ), ), - Container( - height: 38.0, - child: Column( - crossAxisAlignment: - CrossAxisAlignment.center, - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - Container( - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - width: 0.5, - ), - ), - ), - child: InkWell( - child: Icon( - Icons.arrow_drop_up, - size: 18.0, - ), - onTap: () { - setState(() { - if (height < 250) - height++; - }); - }, - ), - ), - InkWell( - child: Icon( - Icons.arrow_drop_down, - size: 18.0, - ), - onTap: () { - setState(() { - if (height > 0) height--; - }); - }, - ), - ], + mWidth(12), + Text( + TranslationBase.of(context).male, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + letterSpacing: -0.56, ), ), ], ), ), ), - ), - Expanded( - child: Slider( - value: height.toDouble(), - min: 0, - max: 250, - onChanged: (double newValue) { - setState(() { - height = newValue.round(); - }); - }, - activeColor: Color(0xffC5272D), - inactiveColor: Color(0xffF3C5C6), - ), - ), - ], - ), - ), - ], - ), - Texts('Select Unit'), - SizedBox( - height: 5.0, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - GestureDetector( - onTap: () { - setState(() { - updateColorHeight(1); - isHeightCm = true; - }); - }, - child: Container( - height: 55.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: cmCard, - borderRadius: BorderRadius.circular(3.0), - ), - child: Padding( - padding: const EdgeInsets.symmetric( - vertical: 0.0, horizontal: 18.0), - child: Center(child: Texts('CM')), ), ), - ), - GestureDetector( - onTap: () { - setState(() { - updateColorHeight(2); - isHeightCm = false; - }); - }, - child: Container( - height: 55.0, - width: 150.0, - decoration: BoxDecoration( - color: ftCard, - 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: Center(child: Texts('Ft')), - ), + SizedBox( + height: 12.0, ), - ), - ], - ), - SizedBox( - height: 5.0, - ), - Texts( - 'Weight', - ), - SizedBox( - height: 5.0, - ), - Row( - children: [ - Container( - width: 340.0, - height: 60.0, - decoration: BoxDecoration( - color: Colors.white, + inputWidget(TranslationBase.of(context).age11_120Years, "0", ageController), + SizedBox( + height: 12.0, ), - child: Row( - children: [ - Padding( - padding: EdgeInsets.symmetric( - vertical: 10.0, horizontal: 8.0), - child: Center( - child: Container( - width: 60.0, - foregroundDecoration: BoxDecoration( - borderRadius: BorderRadius.circular(5.0), - border: Border.all( - color: Colors.blueGrey, - width: 2.0, - ), - ), - child: Row( - children: [ - Expanded( - child: Center( - child: Text(weight.toString()), + _commonInputAndUnitRow( + TranslationBase.of(context).height, + _heightController, + 1, + 270, + _heightValue, + (text) { + _heightController.text = text; + }, + (value) { + _heightValue = value; + }, + _isHeightCM ? TranslationBase.of(context).cm : TranslationBase.of(context).ft, + (value) { + if (_isHeightCM != value) { + setState(() { + _isHeightCM = value; + }); + } + }, + _heightPopupList, + ), + SizedBox( + height: 12.0, + ), + _commonInputAndUnitRow( + TranslationBase.of(context).weight, + _weightController, + 1, + 270, + _weightValue, + (text) { + _weightController.text = text; + }, + (value) { + _weightValue = value; + }, + _isWeightKG ? TranslationBase.of(context).kg : TranslationBase.of(context).pound, + (value) { + if (_isWeightKG != value) { + setState(() { + _isWeightKG = value; + }); + } + }, + _weightPopupList, + ), + SizedBox( + height: 12.0, + ), + InkWell( + onTap: () { + // dropdownKey.currentState; + openDropdown(clinicDropdownKey); + }, + child: Container( + // width: double.infinity, + // decoration: containerRadius(Colors.white, 12), + // padding: EdgeInsets.only(left: 10, right: 10, top: 12, bottom: 12), + child: Row( + children: [ + Flexible( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).activityLevel, + style: TextStyle( + fontSize: 11, + letterSpacing: -0.44, + fontWeight: FontWeight.w600, ), ), Container( - height: 38.0, - child: Column( - crossAxisAlignment: - CrossAxisAlignment.center, - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - Container( - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - width: 0.5, - ), - ), - ), - child: InkWell( - child: Icon( - Icons.arrow_drop_up, - size: 18.0, - ), - onTap: () { - setState(() { - if (weight < 250) - weight++; - }); - }, - ), + height: 18, + child: DropdownButtonHideUnderline( + child: DropdownButton( + value: dropdownValue, + key: clinicDropdownKey, + icon: Icon(Icons.arrow_downward), + iconSize: 0, + elevation: 16, + isExpanded: true, + style: TextStyle(color: Colors.black87), + underline: Container( + height: 2, + color: Colors.black54, ), - InkWell( - child: Icon( - Icons.arrow_drop_down, - size: 18.0, - ), - onTap: () { - setState(() { - if (weight > 0) weight--; - }); - }, - ), - ], + onChanged: (String? newValue) { + setState(() { + dropdownValue = newValue!; + }); + }, + items: [ + TranslationBase.of(context).almostInactive, + TranslationBase.of(context).lightActive1, + TranslationBase.of(context).veryActive, + TranslationBase.of(context).superActive + ].map>((String value) { + return DropdownMenuItem( + value: value, + child: Text(value), + ); + }).toList(), + ), ), ), ], ), ), - ), + Icon(Icons.keyboard_arrow_down), + ], ), - Expanded( - child: Slider( - value: weight.toDouble(), - min: 0, - max: 250, - onChanged: (double newValue) { - setState(() { - weight = newValue.round(); - }); - }, - activeColor: Color(0xffC5272D), - inactiveColor: Color(0xffF3C5C6), - ), - ), - ], - ), - ), - ], - ), - Texts('Select Unit'), - SizedBox( - height: 5.0, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - GestureDetector( - onTap: () { - setState(() { - updateColorWeight(1); - }); - }, - child: Container( - height: 55.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: kgCard, - borderRadius: BorderRadius.circular(3.0), - ), - child: Padding( - padding: const EdgeInsets.symmetric( - vertical: 0.0, horizontal: 18.0), - child: Center(child: Texts('KG')), - ), + ).withBorderedContainer, ), - ), - GestureDetector( - onTap: () { - setState(() { - updateColorWeight(2); - }); - }, - child: Container( - height: 55.0, - width: 150.0, - decoration: BoxDecoration( - color: lbCard, - 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: Center(child: Texts('LB')), - ), + SizedBox( + height: 25.0, ), - ), - ], - ), - SizedBox( - height: 45.0, - ), - Divider( - thickness: 2.0, - ), - SizedBox( - height: 5.0, - ), - Texts('Activity level'), - Container( - width: 300, - child: DropdownButton( - value: dropdownValue, - icon: Icon(Icons.arrow_downward), - iconSize: 24, - elevation: 16, - style: TextStyle(color: Colors.black87), - underline: Container( - height: 2, - color: Colors.black54, - ), - onChanged: (String newValue) { - setState(() { - dropdownValue = newValue; - }); - }, - items: [ - 'Almost Inactive(Little or no exercises)', - 'Lighty Active (1-3) days per week', - 'very Active(6-7) days per week', - 'Super Active(very hard exercises)' - ].map>((String value) { - return DropdownMenuItem( - value: value, - child: Text(value), - ); - }).toList(), + ], ), + ], + ), + ), + ), + ), + Container( + margin: EdgeInsets.symmetric(horizontal: 16.0, vertical: 16.0), + color: Colors.white, + child: SecondaryButton( + label: TranslationBase.of(context).calculate, + color: CustomColors.accentColor, + onTap: () { + setState(() { + calculateBmr(); + calculateCalories(context); + + { + Navigator.push( + context, + FadePage( + page: BmrResultPage( + bmrResult: bmrResult, + calories: calories, + )), + ); + } + }); + }, + ), + ), + ], + ), + ), + ); + } + + void openDropdown(GlobalKey key) { + GestureDetector? detector; + + void searchForGestureDetector(BuildContext element) { + element.visitChildElements((element) { + if (element.widget != null && element.widget is GestureDetector) { + detector = element.widget as GestureDetector?; + //return false; + } else { + searchForGestureDetector(element); + } + + //return true; + }); + } + + searchForGestureDetector(key.currentContext!); + assert(detector != null); + + detector!.onTap!(); + } + + 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(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, ), - SizedBox( - height: 30.0, + ), + 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, ), - Container( - height: 50.0, - width: 350.0, - child: SecondaryButton( - label: 'CALCULATE', - onTap: () { - setState(() { - calculateBmr(); - calculateCalories(); - - { - Navigator.push( - context, - FadePage( - page: BmrResultPage( - bmrResult: bmrResult, - calories: calories, - )), - ); - } - }); - }, + decoration: InputDecoration( + isDense: true, + hintText: _hintText, + hintStyle: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: Color(0xff575757), + 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), + ], + ), + ), + ); + } + + Widget _commonInputAndUnitRow(_title, _controller, double _minValue, double _maxValue, double _valueOrg, Function(String) onTextValueChange, Function(double) onValueChange, String unitTitle, + Function(bool) onUnitTap, _list) { + 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( + 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, + ), + ), + ], ), ), + 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, + (val) async { + final RenderBox overlay = Overlay.of(context).context.findRenderObject() as RenderBox; + await showMenu( + context: context, + position: RelativeRect.fromRect(val.globalPosition & const Size(40, 40), Offset.zero & overlay.size), + items: _list, + elevation: 8.0, + ).then((val) { + print(val); + onUnitTap(val); + }); + }, + ), + itemBuilder: (context) => _list), + ) + ], + ).withBorderedContainer; + } +} + +// todo 'sikander' move these to separate file once usability known +class CommonDropDownView extends StatelessWidget { + final String title; + final String value; + void Function(TapDownDetails details) 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( + onTapDown: (val) => callback(val), + 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), + ) + ], ), ); } 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 a3fdb5f7..79060a2d 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/bmr_calculator/bmr_result_page.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/bmr_calculator/bmr_result_page.dart @@ -1,65 +1,180 @@ +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/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/button.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:percent_indicator/circular_percent_indicator.dart'; class BmrResultPage extends StatelessWidget { final double bmrResult; final double calories; - BmrResultPage({this.bmrResult, this.calories}); + + BmrResultPage({required this.bmrResult, required this.calories}); + @override Widget build(BuildContext context) { return AppScaffold( isShowAppBar: true, - appBarTitle: 'BMR Calculator', + isShowDecPage: false, + showNewAppBarTitle: true, + showNewAppBar: true, + appBarTitle: TranslationBase.of(context).bmr, body: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - Center( - child: CircularPercentIndicator( - radius: 220.0, - lineWidth: 20.0, - percent: ((this.bmrResult > 3500) ? 100 : this.bmrResult / 3500), - center: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - bmrResult.toStringAsFixed(1), - style: TextStyle( - fontSize: 18.0, - fontWeight: FontWeight.bold, - ), + Padding( + padding: const EdgeInsets.only(right: 20.0,left: 20,top: 20,bottom: 20), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).calories, + style: TextStyle( + fontSize: 19, + letterSpacing: -1.34, + fontWeight: FontWeight.bold, ), - SizedBox( - height: 5.0, + ), + mHeight(20), + Center( + child: CircularPercentIndicator( + radius: 120.0, + lineWidth: 3.0, + percent: ((this.bmrResult > 3500) ? 100 : this.bmrResult / 3500), + center: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + bmrResult.toStringAsFixed(1), + style: TextStyle( + fontSize: 17, + letterSpacing: -1.02, + fontWeight: FontWeight.w600, + ), + ), + SizedBox( + height: 5.0, + ), + Text( + TranslationBase.of(context).calories, + style: TextStyle( + fontSize: 18, + letterSpacing: -1.08, + fontWeight: FontWeight.w600, + ), + ), + ], + ), + progressColor: CustomColors.accentColor, + backgroundColor: Colors.white, ), - Text( - 'Calories/Day', - style: TextStyle( - fontSize: 16.0, + ), + mHeight(50), + Text( + TranslationBase.of(context).bodyWillBurn+' ( ${bmrResult.toStringAsFixed(1)} )'+TranslationBase.of(context).caloriesEachDay+'( ${calories.toStringAsFixed(1)} ) '+TranslationBase.of(context).maintainWeight, + style: TextStyle( + fontSize: 14, + letterSpacing: -0.56, fontWeight: FontWeight.w600, - ), + color: CustomColors.textColor ), - ], - ), - progressColor: Color(0xff3C3939), - ), - ), - Container( - height: 120, - width: 280.0, - child: Texts( - 'This means the body will burn ( ${bmrResult.toStringAsFixed(1)} ) calories each day, if engaged in no activity for the entire day.. Note: Daily calorie requirement is ( ${calories.toStringAsFixed(1)} ) calories, to maintain the current weight.'), + ), + ], + ).withBorderedContainer, ), + mFlex(1), + Container( - width: 350, - child: Button( - label: 'See List Of Doctors', + margin: EdgeInsets.symmetric(horizontal: 16.0, vertical: 16.0), + color: Colors.white, + child: SecondaryButton( + label: TranslationBase.of(context).viewDocList, + color: CustomColors.accentColor, + onTap: () { + getDoctorsList(context); + }, ), ), + ], ), ); } + + getDoctorsList(BuildContext context) { + GifLoaderDialogUtils.showMyDialog(context); + BariatricsService service = new BariatricsService(); + + List doctorsList = []; + List _patientDoctorAppointmentListHospital =[]; + + 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, isDoctorSearchResult: false,))); + } + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } } +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, + ); +} \ No newline at end of file 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 3bda439f..1d523d55 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/body_fat/body_fat.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/body_fat/body_fat.dart @@ -1,10 +1,13 @@ -import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; +import 'dart:math'; + +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; -import 'dart:math'; +import 'package:flutter/services.dart'; import 'body_fat_result_page.dart'; @@ -19,33 +22,66 @@ class BodyFat extends StatefulWidget { } class _BodyFatState extends State { + final GlobalKey clinicDropdownKey = GlobalKey(); + bool _isHeightCM = true; + bool _isNeckKG = true; + bool _isWaistKG = true; + bool _isHipKG = true; + double _heightValue = 0; + double _neckValue = 0; + double _waistValue = 0; + double _hipValue = 0; + + TextEditingController _heightController = TextEditingController(); + TextEditingController _neckController = TextEditingController(); + TextEditingController _waistController = TextEditingController(); + TextEditingController _hipController = TextEditingController(); + + List _heightPopupList = []; + List _neckPopupList = []; + List _waistPopupList = []; + List _hipPopupList = []; + bool isMale = false; - bool isHeightCm = true; + + // bool isHeightCm = true; Color maleCard = activeCardColorGender; Color femaleCard = inactiveCardColorGender; - Color neckCmCard = activeCardColor; - Color neckFtCard = inactiveCardColor; + + // Color neckCmCard = activeCardColor; + // Color neckFtCard = inactiveCardColor; Color waistCmCard = activeCardColor; Color waistFtCard = inactiveCardColor; Color hipCmCard = activeCardColor; Color hipFtCard = inactiveCardColor; Color cmCard = activeCardColor; Color ftCard = inactiveCardColor; - int neck = 10; - int heightCm = 0; - int heightFt = 0; - int hip = 5; - double heightInches; - double minRange; - double maxRange; - double overWeightBy; - int waist = 5; + + // int neck = 10; + // int heightCm = 0; + // int heightFt = 0; + // int hip = 5; + double? heightInches; + double? minRange; + double? maxRange; + double? overWeightBy; + + // int waist = 5; double bodyFat = 0; double fat = 0; - String dropdownValue; + String? dropdownValue; double calories = 0; String textResult = ''; + @override + void initState() { + _neckController.text = _neckValue.toString(); + _hipController.text = _hipValue.toString(); + _waistController.text = _waistValue.toString(); + _heightController.text = _heightValue.toString(); + super.initState(); + } + void updateColorHeight(int type) { //MG/DLT card if (type == 1) { @@ -66,26 +102,6 @@ class _BodyFatState extends State { } } - void updateColorNeck(int type) { - //MG/DLT card - if (type == 1) { - if (neckCmCard == inactiveCardColor) { - neckCmCard = activeCardColor; - neckFtCard = inactiveCardColor; - } else { - neckCmCard = inactiveCardColor; - } - } - if (type == 2) { - if (neckFtCard == inactiveCardColor) { - neckFtCard = activeCardColor; - neckCmCard = inactiveCardColor; - } else { - neckFtCard = inactiveCardColor; - } - } - } - void updateColorWaist(int type) { //MG/DLT card if (type == 1) { @@ -148,18 +164,10 @@ class _BodyFatState extends State { void calculateBodyFat() { if (isMale == true) { - bodyFat = 495 / - (1.0324 - - 0.19077 * (log(waist - neck) / ln10) + - 0.15456 * (log(heightCm) / ln10)) - - 450; + bodyFat = 495 / (1.0324 - 0.19077 * (log(_waistValue - _neckValue) / ln10) + 0.15456 * (log(int.parse(_heightController.text)) / ln10)) - 450; fat = (bodyFat * 10) / 10.round(); } else if (isMale == false) { - bodyFat = 495 / - (1.29579 - - 0.35004 * (log(waist + hip - neck) / ln10) + - 0.22100 * (log(heightCm) / ln10)) - - 450; + bodyFat = 495 / (1.29579 - 0.35004 * (log(_waistValue + _hipValue - _neckValue) / ln10) + 0.22100 * (log(int.parse(_heightController.text)) / ln10)) - 450; fat = (bodyFat * 10) / 10.round(); } if (fat <= 0) { @@ -167,857 +175,566 @@ class _BodyFatState extends State { } } - void showTextResult() { + void showTextResult(BuildContext context) { if (isMale == false) { if (bodyFat > 9 && bodyFat <= 13) { - textResult = 'The category falls under essential'; + textResult = TranslationBase.of(context).essential; } else if (bodyFat > 13 && bodyFat <= 20) { - textResult = 'The category falls under athlete'; + textResult = TranslationBase.of(context).athlete; } else if (bodyFat > 20 && bodyFat <= 24) { - textResult = 'The category falls under fitness'; + textResult = TranslationBase.of(context).fitness; } else if (bodyFat > 24 && bodyFat <= 31) { - textResult = 'The category falls under acceptable'; + textResult = TranslationBase.of(context).acceptable; } else if (bodyFat > 31 && bodyFat <= 60) { - textResult = 'The category falls under obese'; + textResult = TranslationBase.of(context).underObese; } else if (bodyFat > 60) { - textResult = - 'Please check the value you have entered, since the body fat percentage has crosed the limits.'; + textResult = TranslationBase.of(context).crossedLimits; } else if (bodyFat <= 9) { - textResult = - 'Please check the value you have entered, since the body fat percentage cannot be this low.'; + textResult = TranslationBase.of(context).lowLimits; } } else { if (bodyFat > 5 && fat <= 13) { - textResult = 'The category falls under essential'; + textResult = TranslationBase.of(context).essential; } else if (bodyFat > 13 && bodyFat <= 17) { - textResult = 'The category falls under athlete'; + textResult = TranslationBase.of(context).athlete; } else if (bodyFat > 17 && bodyFat <= 24) { - textResult = 'The category falls under fitness'; + textResult = TranslationBase.of(context).fitness; } else if (bodyFat > 24 && bodyFat <= 45) { - textResult = 'The category falls under obese'; + textResult = TranslationBase.of(context).underObese; } else if (bodyFat > 45) { - textResult = - 'Please check the value you have entered, since the body fat percentage has crosed the limits.'; + textResult = TranslationBase.of(context).crossedLimits; } else if (bodyFat <= 5) { - textResult = - 'Please check the value you have entered, since the body fat percentage cannot be this low.'; + textResult = TranslationBase.of(context).lowLimits; } } } @override Widget build(BuildContext context) { + _neckPopupList = [ + PopupMenuItem( + child: Text(TranslationBase.of(context).kg), + value: true, + ), + PopupMenuItem( + child: Text( + TranslationBase.of(context).lb, + ), + value: false) + ]; + _heightPopupList = [ + PopupMenuItem( + child: Text(TranslationBase.of(context).cm), + value: true, + ), + PopupMenuItem( + child: Text( + TranslationBase.of(context).ft, + ), + value: false) + ]; + + _waistPopupList = [ + PopupMenuItem( + child: Text(TranslationBase.of(context).kg), + value: true, + ), + PopupMenuItem( + child: Text( + TranslationBase.of(context).lb, + ), + value: false) + ]; + _hipPopupList = [ + PopupMenuItem( + child: Text(TranslationBase.of(context).cm), + value: true, + ), + PopupMenuItem( + child: Text( + TranslationBase.of(context).ft, + ), + value: false) + ]; + return AppScaffold( isShowAppBar: true, - appBarTitle: 'Body Fat', - body: Padding( - padding: EdgeInsets.symmetric(horizontal: 25.0, vertical: 15.0), - child: SingleChildScrollView( - child: Container( - height: 1000.0, - child: Column( - children: [ - Padding( - padding: EdgeInsets.all(10.0), - child: - Texts('Estimates the total body fat based on\n the size'), - ), - Divider( - thickness: 2.0, - ), - SizedBox( - height: 5.0, - ), - Column( + isShowDecPage: false, + showNewAppBarTitle: true, + showNewAppBar: true, + appBarTitle: TranslationBase.of(context).bodyFatTitle, + appBarIcons: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 7.0), + child: Icon( + Icons.info_outline, + color: Colors.white, + ), + ) + ], + body: Column( + children: [ + Expanded( + child: SingleChildScrollView( + child: Container( + padding: EdgeInsets.all(20), + child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Texts('Gender'), + Text( + TranslationBase.of(context).bodyFatDesc, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + letterSpacing: -0.56, + color: CustomColors.textColor, + ), + ), + SizedBox( + height: 20, + ), + Text( + TranslationBase.of(context).selectGender, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + letterSpacing: -0.56, + color: CustomColors.textColor, + ), + ), SizedBox( - height: 5.0, + height: 8.0, ), Container( - width: 350, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(35.0), - color: Colors.white, - border: Border.all( - color: Colors.black45, - )), child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - GestureDetector( - onTap: () { - setState(() { - updateColor(1); - isMale = false; - }); - }, - child: Container( - height: 55.0, - width: 170.0, - decoration: BoxDecoration( - color: maleCard, - borderRadius: BorderRadius.circular(35.0), - ), - child: Center(child: Texts('FEMALE')), - ), - ), - GestureDetector( - onTap: () { - setState(() { - updateColor(2); - isMale = true; - }); - }, - child: Container( - height: 55.0, - width: 170.0, - decoration: BoxDecoration( - color: femaleCard, - borderRadius: BorderRadius.circular(35.0), - ), - child: Center(child: Texts('MALE')), - ), - ), - ], - ), - ), - Texts( - 'Height', - ), - Row( - children: [ - Expanded( - child: Container( - width: 340.0, - height: 60.0, - decoration: BoxDecoration( - color: Colors.white, - ), - child: Row( - children: [ - Padding( - padding: EdgeInsets.symmetric( - vertical: 10.0, horizontal: 8.0), - child: Center( + Expanded( + child: GestureDetector( + onTap: () { + setState(() { + updateColor(1); + isMale = false; + }); + }, + child: Row( + children: [ + Container( + decoration: containerColorRadiusBorderWidth(Colors.white, 1000, CustomColors.darkGreyColor, 1), + width: 24, + height: 24, + padding: EdgeInsets.all(4), child: Container( - width: 60.0, - foregroundDecoration: BoxDecoration( - borderRadius: - BorderRadius.circular(5.0), - border: Border.all( - color: Colors.blueGrey, - width: 2.0, - ), - ), - child: Row( - children: [ - Expanded( - child: Center( - child: Text(heightCm.toString()), - ), - ), - Container( - height: 38.0, - child: Column( - crossAxisAlignment: - CrossAxisAlignment.center, - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - Container( - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - width: 0.5, - ), - ), - ), - child: InkWell( - child: Icon( - Icons.arrow_drop_up, - size: 18.0, - ), - onTap: () { - setState(() { - if (heightCm < 250) - heightCm++; - }); - }, - ), - ), - InkWell( - child: Icon( - Icons.arrow_drop_down, - size: 18.0, - ), - onTap: () { - setState(() { - if (heightCm > 0) - heightCm--; - }); - }, - ), - ], - ), - ), - ], - ), + width: double.infinity, + height: double.infinity, + decoration: containerRadius(!isMale ? CustomColors.accentColor : Colors.white, 100), ), ), - ), - Expanded( - child: Slider( - value: heightCm.toDouble(), - min: 0, - max: 250, - onChanged: (double newValue) { - setState(() { - heightCm = newValue.round(); - }); - }, - activeColor: Color(0xffC5272D), - inactiveColor: Color(0xffF3C5C6), + mWidth(12), + Text( + TranslationBase.of(context).female, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + letterSpacing: -0.56, + ), ), - ), - ], - ), - ), - ), - ], - ), - Texts('Select Unit'), - SizedBox( - height: 5.0, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - GestureDetector( - onTap: () { - setState(() { - updateColorHeight(1); - isHeightCm = true; - }); - }, - child: Container( - height: 55.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: cmCard, - borderRadius: BorderRadius.circular(3.0), - ), - child: Padding( - padding: const EdgeInsets.symmetric( - vertical: 0.0, horizontal: 18.0), - child: Center(child: Texts('CM')), - ), - ), - ), - GestureDetector( - onTap: () { - setState(() { - updateColorHeight(2); - isHeightCm = false; - }); - }, - child: Container( - height: 55.0, - width: 150.0, - decoration: BoxDecoration( - color: ftCard, - 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: Center(child: Texts('Ft')), + ], + ), ), ), - ), - ], - ), - SizedBox( - height: 10.0, - ), - Texts( - 'Neck', - ), - Row( - children: [ - Expanded( - child: Container( - width: 340.0, - height: 60.0, - decoration: BoxDecoration( - color: Colors.white, - ), - child: Row( - children: [ - Padding( - padding: EdgeInsets.symmetric( - vertical: 10.0, horizontal: 8.0), - child: Center( + Expanded( + child: GestureDetector( + onTap: () { + setState(() { + updateColor(2); + isMale = true; + }); + }, + child: Row( + children: [ + Container( + decoration: containerColorRadiusBorderWidth(Colors.white, 1000, CustomColors.darkGreyColor, 1), + width: 24, + height: 24, + padding: EdgeInsets.all(4), child: Container( - width: 60.0, - foregroundDecoration: BoxDecoration( - borderRadius: - BorderRadius.circular(5.0), - border: Border.all( - color: Colors.blueGrey, - width: 2.0, - ), - ), - child: Row( - children: [ - Expanded( - child: Center( - child: Text(neck.toString()), - ), - ), - Container( - height: 38.0, - child: Column( - crossAxisAlignment: - CrossAxisAlignment.center, - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - Container( - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - width: 0.5, - ), - ), - ), - child: InkWell( - child: Icon( - Icons.arrow_drop_up, - size: 18.0, - ), - onTap: () { - setState(() { - if (neck < 60) neck++; - }); - }, - ), - ), - InkWell( - child: Icon( - Icons.arrow_drop_down, - size: 18.0, - ), - onTap: () { - setState(() { - if (neck > 5) neck--; - }); - }, - ), - ], - ), - ), - ], - ), + width: double.infinity, + height: double.infinity, + decoration: containerRadius(isMale ? CustomColors.accentColor : Colors.white, 100), ), ), - ), - Expanded( - child: Slider( - value: neck.toDouble(), - min: 5, - max: 60, - onChanged: (double newValue) { - setState(() { - neck = newValue.round(); - }); - }, - activeColor: Color(0xffC5272D), - inactiveColor: Color(0xffF3C5C6), + mWidth(12), + Text( + TranslationBase.of(context).male, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + letterSpacing: -0.56, + ), ), - ), - ], - ), - ), - ), - ], - ), - Texts('Select Unit'), - SizedBox( - height: 5.0, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - GestureDetector( - onTap: () { - setState(() { - updateColorNeck(1); - isHeightCm = true; - }); - }, - child: Container( - height: 55.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: neckCmCard, - borderRadius: BorderRadius.circular(3.0), - ), - child: Padding( - padding: const EdgeInsets.symmetric( - vertical: 0.0, horizontal: 18.0), - child: Center(child: Texts('CM')), - ), - ), - ), - GestureDetector( - onTap: () { - setState(() { - updateColorNeck(2); - isHeightCm = false; - }); - }, - child: Container( - height: 55.0, - width: 150.0, - decoration: BoxDecoration( - color: neckFtCard, - 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: Center(child: Texts('Ft')), + ], + ), ), ), - ), - ], + ], + ), ), SizedBox( - height: 10.0, - ), - Texts( - 'Waist', + height: 12.0, ), - Row( - children: [ - Expanded( - child: Container( - width: 340.0, - height: 60.0, - decoration: BoxDecoration( - color: Colors.white, - ), - child: Row( - children: [ - Padding( - padding: EdgeInsets.symmetric( - vertical: 10.0, horizontal: 8.0), - child: Center( - child: Container( - width: 60.0, - foregroundDecoration: BoxDecoration( - borderRadius: - BorderRadius.circular(5.0), - border: Border.all( - color: Colors.blueGrey, - width: 2.0, - ), - ), - child: Row( - children: [ - Expanded( - child: Center( - child: Text(waist.toString()), - ), - ), - Container( - height: 38.0, - child: Column( - crossAxisAlignment: - CrossAxisAlignment.center, - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - Container( - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - width: 0.5, - ), - ), - ), - child: InkWell( - child: Icon( - Icons.arrow_drop_up, - size: 18.0, - ), - onTap: () { - setState(() { - if (waist < 200) - waist++; - }); - }, - ), - ), - InkWell( - child: Icon( - Icons.arrow_drop_down, - size: 18.0, - ), - onTap: () { - setState(() { - if (waist > 5) waist--; - }); - }, - ), - ], - ), - ), - ], - ), - ), - ), - ), - Expanded( - child: Slider( - value: waist.toDouble(), - min: 5, - max: 200, - onChanged: (double newValue) { - setState(() { - waist = newValue.round(); - }); - }, - activeColor: Color(0xffC5272D), - inactiveColor: Color(0xffF3C5C6), - ), - ), - ], - ), - ), - ), - ], + _commonInputAndUnitRow( + TranslationBase.of(context).height, + _heightController, + 1, + 270, + _heightValue, + (text) { + _heightController.text = text; + }, + (value) { + _heightValue = value; + }, + _isHeightCM ? TranslationBase.of(context).cm : TranslationBase.of(context).ft, + (value) { + if (_isHeightCM != value) { + setState(() { + _isHeightCM = value; + }); + } + }, + _heightPopupList, ), - Texts('Select Unit'), SizedBox( - height: 5.0, + height: 12.0, ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - GestureDetector( - onTap: () { - setState(() { - updateColorWaist(1); - isHeightCm = true; - }); - }, - child: Container( - height: 55.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: waistCmCard, - borderRadius: BorderRadius.circular(3.0), - ), - child: Padding( - padding: const EdgeInsets.symmetric( - vertical: 0.0, horizontal: 18.0), - child: Center(child: Texts('CM')), - ), - ), - ), - GestureDetector( - onTap: () { - setState(() { - updateColorWaist(2); - isHeightCm = false; - }); - }, - child: Container( - height: 55.0, - width: 150.0, - decoration: BoxDecoration( - color: waistFtCard, - 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: Center(child: Texts('Ft')), - ), - ), - ), - ], + _commonInputAndUnitRow( + TranslationBase.of(context).neck, + _neckController, + 1, + 270, + _neckValue, + (text) { + _neckController.text = text; + }, + (value) { + _neckValue = value; + }, + _isNeckKG ? TranslationBase.of(context).cm : TranslationBase.of(context).ft, + (value) { + if (_isNeckKG != value) { + setState(() { + _isNeckKG = value; + }); + } + }, + _neckPopupList, ), SizedBox( - height: 10.0, - ), - Texts( - 'Hip', + height: 12.0, ), - Row( - children: [ - Expanded( - child: Container( - width: 340.0, - height: 60.0, - decoration: BoxDecoration( - color: Colors.white, - ), - child: Row( - children: [ - Padding( - padding: EdgeInsets.symmetric( - vertical: 10.0, horizontal: 8.0), - child: Center( - child: Container( - width: 60.0, - foregroundDecoration: BoxDecoration( - borderRadius: - BorderRadius.circular(5.0), - border: Border.all( - color: Colors.blueGrey, - width: 2.0, - ), - ), - child: Row( - children: [ - Expanded( - child: Center( - child: Text(hip.toString()), - ), - ), - Container( - height: 38.0, - child: Column( - crossAxisAlignment: - CrossAxisAlignment.center, - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - Container( - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - width: 0.5, - ), - ), - ), - child: InkWell( - child: Icon( - Icons.arrow_drop_up, - size: 18.0, - ), - onTap: () { - setState(() { - if (hip < 140) hip++; - }); - }, - ), - ), - InkWell( - child: Icon( - Icons.arrow_drop_down, - size: 18.0, - ), - onTap: () { - setState(() { - if (hip > 5) hip--; - }); - }, - ), - ], - ), - ), - ], - ), - ), - ), - ), - Expanded( - child: Slider( - value: hip.toDouble(), - min: 5, - max: 140, - onChanged: (double newValue) { - setState(() { - hip = newValue.round(); - }); - }, - activeColor: Color(0xffC5272D), - inactiveColor: Color(0xffF3C5C6), - ), - ), - ], - ), - ), - ), - ], + _commonInputAndUnitRow( + TranslationBase.of(context).waist, + _waistController, + 1, + 270, + _waistValue, + (text) { + _waistController.text = text; + }, + (value) { + _waistValue = value; + }, + _isWaistKG ? TranslationBase.of(context).cm : TranslationBase.of(context).ft, + (value) { + if (_isWaistKG != value) { + setState(() { + _isWaistKG = value; + }); + } + }, + _waistPopupList, ), - Texts('Select Unit'), SizedBox( - height: 5.0, + height: 12.0, ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - GestureDetector( - onTap: () { - setState(() { - updateColorHip(1); - isHeightCm = true; - }); - }, - child: Container( - height: 55.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: hipCmCard, - borderRadius: BorderRadius.circular(3.0), - ), - child: Padding( - padding: const EdgeInsets.symmetric( - vertical: 0.0, horizontal: 18.0), - child: Center(child: Texts('CM')), - ), - ), - ), - GestureDetector( - onTap: () { - setState(() { - updateColorHip(2); - isHeightCm = false; - }); - }, - child: Container( - height: 55.0, - width: 150.0, - decoration: BoxDecoration( - color: hipFtCard, - 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: Center(child: Texts('Ft')), - ), - ), - ), - ], + _commonInputAndUnitRow( + TranslationBase.of(context).hip, + _hipController, + 1, + 270, + _hipValue, + (text) { + _hipController.text = text; + }, + (value) { + _hipValue = value; + }, + _isHipKG ? TranslationBase.of(context).cm : TranslationBase.of(context).ft, + (value) { + if (_isHipKG != value) { + setState(() { + _isHipKG = value; + }); + } + }, + _hipPopupList, ), SizedBox( - height: 35.0, + height: 12.0, ), ], ), - Container( - height: 100.0, - width: 350.0, - child: SecondaryButton( - label: 'CALCULATE', - // onTap: () => { - // setState(() { - // print('hiii'); - // }) - // } - onTap: () { - setState(() { - calculateBodyFat(); - showTextResult(); + ), + ), + ), + Container( + margin: EdgeInsets.symmetric(horizontal: 16.0, vertical: 16.0), + color: Colors.white, + child: SecondaryButton( + label: TranslationBase.of(context).calculate, + color: CustomColors.accentColor, + onTap: () { + setState(() { + calculateBodyFat(); + showTextResult(context); - { - Navigator.push( - context, - FadePage( - page: FatResult( - bodyFat: bodyFat, - fat: fat, - textResult: textResult, - )), - ); - } - }); - }, + { + Navigator.push( + context, + FadePage( + page: FatResult( + bodyFat: bodyFat, + fat: fat, + textResult: textResult, + )), + ); + } + }); + }, + ), + ), + ], + ), + ); + } + + 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(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: 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, + hintStyle: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: Color(0xff575757), + 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), + ], + ), + ), + ); + } + + Widget _commonInputAndUnitRow(_title, _controller, double _minValue, double _maxValue, double _valueOrg, Function(String) onTextValueChange, Function(double) onValueChange, String unitTitle, + Function(bool) onUnitTap, _list) { + 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( + 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, + ), + ), + ], ), ), + 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, + (val) async { + final RenderBox overlay = Overlay.of(context).context.findRenderObject() as RenderBox; + await showMenu( + context: context, + position: RelativeRect.fromRect(val.globalPosition & const Size(40, 40), Offset.zero & overlay.size), + items: _list, + elevation: 8.0, + ).then((val) { + print(val); + onUnitTap(val); + }); + }, + ), + itemBuilder: (context) => _list, + enabled: true, + ), + ) + ], + ).withBorderedContainer; + } +} + +// todo 'sikander' move these to separate file once usability known +class CommonDropDownView extends StatelessWidget { + final String title; + final String value; + void Function(TapDownDetails details) callback; + final IconData? iconData; + + CommonDropDownView(this.title, this.value, this.callback, {Key? key, this.iconData}) : super(key: key); + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTapDown: (val) => callback(val), + 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), + ) + ], ), ); } 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 c8c5476e..79014ba2 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/body_fat/body_fat_result_page.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/body_fat/body_fat_result_page.dart @@ -1,6 +1,15 @@ +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/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/button.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:percent_indicator/circular_percent_indicator.dart'; @@ -9,8 +18,10 @@ class FatResult extends StatelessWidget { final double fat; final String textResult; - FatResult({this.bodyFat, this.fat, this.textResult = ''}); - Color inductorColor; + FatResult({required this.bodyFat, required this.fat, this.textResult = ''}); + + Color? inductorColor; + Color colorInductor() { if (bodyFat >= 17) { inductorColor = Color(0xffC70D00); @@ -21,57 +32,146 @@ class FatResult extends StatelessWidget { } else if (bodyFat > 45) { inductorColor = Color(0xff1BE0EE); } - return inductorColor; + return inductorColor!; } @override 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: [ - SizedBox( - // height: 40.0, - ), - Center( - child: CircularPercentIndicator( - radius: 220.0, - lineWidth: 20.0, - percent: ((fat > 70) ? 100 : fat / 100), - center: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - fat.toStringAsFixed(1) + '%', - style: TextStyle( - fontSize: 18.0, - fontWeight: FontWeight.bold, - ), + Padding( + padding: const EdgeInsets.all(20.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).bodyFatTitle, + style: TextStyle( + fontSize: 19, + letterSpacing: -1.34, + fontWeight: FontWeight.bold, ), - SizedBox( - height: 5.0, + ), + mHeight(20), + Center( + child: CircularPercentIndicator( + radius: 220.0, + lineWidth: 3.0, + percent: ((fat > 70) ? 100 : fat / 100), + center: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + fat.toStringAsFixed(1) + '%', + style: TextStyle( + fontSize: 17, + letterSpacing: -1.02, + fontWeight: FontWeight.w600, + ), + ), + ], + ), + progressColor: CustomColors.accentColor, + backgroundColor: Colors.white, ), - ], - ), - progressColor: inductorColor, - backgroundColor: Colors.white, - ), + ), + mHeight(20), + Text( + textResult, + style: TextStyle(fontSize: 14, letterSpacing: -0.56, fontWeight: FontWeight.w600, color: CustomColors.textColor), + ), + ], + ).withBorderedContainer, ), + mFlex(1), Container( - height: 120, - width: 280.0, - child: Texts(textResult), - ), - Container( - width: 350, - child: Button( - label: 'See List Of Doctors', + margin: EdgeInsets.symmetric(horizontal: 16.0, vertical: 16.0), + color: Colors.white, + child: SecondaryButton( + label: TranslationBase.of(context).viewDocList, + color: CustomColors.accentColor, + onTap: () { + getDoctorsList(context); + }, ), ), ], ), ); } + + getDoctorsList(BuildContext context) { + GifLoaderDialogUtils.showMyDialog(context); + BariatricsService service = new BariatricsService(); + + List doctorsList = []; + List _patientDoctorAppointmentListHospital = []; + + service.getCalculationDoctors(calculationID: 5).then((res) { + GifLoaderDialogUtils.hideDialog(context); + 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, isDoctorSearchResult: false,))); + } + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } +} + +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/health_calculator/calorie_calculator/calorie_calculator.dart b/lib/pages/AlHabibMedicalService/health_calculator/calorie_calculator/calorie_calculator.dart index a7f60f68..6916299c 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/calorie_calculator/calorie_calculator.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/calorie_calculator/calorie_calculator.dart @@ -1,10 +1,14 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/button.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/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:provider/provider.dart'; import 'calorie_result_page.dart'; @@ -22,15 +26,30 @@ class _CalorieCalculatorState extends State { bool isMale = false; Color maleCard = activeCardColorGender; Color femaleCard = inactiveCardColorGender; - Color kgCard = activeCardColor; - Color lbCard = inactiveCardColor; - Color cmCard = activeCardColor; - Color ftCard = inactiveCardColor; - int age = 0; - int height = 0; - int weight = 0; - double calories; - String dropdownValue; + + final GlobalKey clinicDropdownKey = GlobalKey(); + bool _isHeightCM = true; + bool _isWeightKG = true; + double _heightValue = 150; + double _weightValue = 40; + + TextEditingController ageController = TextEditingController(); + TextEditingController _heightController = TextEditingController(); + TextEditingController _weightController = TextEditingController(); + + List _heightPopupList = []; + List _weightPopupList = []; + + // int age = 0; + // int height = 0; + // int weight = 0; + double? calories; + String? dropdownValue = ''; + + @override + void initState() { + super.initState(); + } void updateColor(int type) { //MG/DLT card @@ -52,62 +71,35 @@ class _CalorieCalculatorState extends State { } } - void updateColorWeight(int type) { - //MG/DLT card - if (type == 1) { - if (kgCard == inactiveCardColor) { - kgCard = activeCardColor; - lbCard = inactiveCardColor; - } else { - kgCard = inactiveCardColor; - } - } - if (type == 2) { - if (lbCard == inactiveCardColor) { - lbCard = activeCardColor; - kgCard = inactiveCardColor; - } else { - lbCard = inactiveCardColor; - } - } - } - - void updateColorHeight(int type) { - //MG/DLT card - if (type == 1) { - if (cmCard == inactiveCardColor) { - cmCard = activeCardColor; - ftCard = inactiveCardColor; - } else { - cmCard = inactiveCardColor; - } - } - if (type == 2) { - if (ftCard == inactiveCardColor) { - ftCard = activeCardColor; - cmCard = inactiveCardColor; - } else { - ftCard = inactiveCardColor; - } - } - } - void calculateCalories() { - if (isMale == true) { - calories = 66.5 + (13.75 * weight) + (5.003 * height) - (6.755 * age); - } else if (isMale == false) { - calories = - 655.0955 + (9.5634 * weight) + (1.850 * height) - (4.676 * age); + if (isMale == true && int.parse(ageController.text) <121) { + calories = 66.5 + (13.75 * int.parse(_weightController.text)) + (5.003 * int.parse(_heightController.text)) - (6.755 * int.parse(ageController.text)); + } else if (isMale == false && int.parse(ageController.text) <121) { + calories = 655.0955 + (9.5634 * int.parse(_weightController.text)) + (1.850 * int.parse(_heightController.text)) - (4.676 * int.parse(ageController.text)); } } @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + _weightPopupList = [PopupMenuItem(child: Text(TranslationBase.of(context).kg), value: true), PopupMenuItem(child: Text(TranslationBase.of(context).lb), value: false)]; + _heightPopupList = [PopupMenuItem(child: Text(TranslationBase.of(context).cm), value: true), PopupMenuItem(child: Text(TranslationBase.of(context).ft), value: false)]; + dropdownValue = TranslationBase.of(context).almostInactive; return AppScaffold( isShowAppBar: true, isShowDecPage: false, - appBarTitle: - "${TranslationBase.of(context).calories} ${TranslationBase.of(context).calcHealth}", + showNewAppBar: true, + showNewAppBarTitle: true, + appBarTitle: "${TranslationBase.of(context).calories} ${TranslationBase.of(context).calcHealth}", + appBarIcons: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 7.0), + child: Icon( + Icons.info_outline, + color: Colors.black, + ), + ) + ], body: Column( children: [ Expanded( @@ -118,23 +110,31 @@ class _CalorieCalculatorState extends State { //mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ - Texts( + Text( TranslationBase.of(context).calorieCalcDesc, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + letterSpacing: -0.56, + color: CustomColors.textColor, + ), ), SizedBox( - height: 8.0, + height: 20, + ), + Text( + TranslationBase.of(context).selectGender, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + letterSpacing: -0.56, + color: CustomColors.textColor, + ), ), - Texts(TranslationBase.of(context).gender), SizedBox( height: 8.0, ), Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(30.0), - color: Colors.white, - border: Border.all( - color: Colors.black45, - )), child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ @@ -146,15 +146,29 @@ class _CalorieCalculatorState extends State { isMale = false; }); }, - child: Container( - padding: EdgeInsets.symmetric(vertical: 16), - decoration: BoxDecoration( - color: maleCard, - borderRadius: BorderRadius.circular(30.0), - ), - child: Center( - child: Texts( - TranslationBase.of(context).female)), + child: Row( + children: [ + Container( + decoration: containerColorRadiusBorderWidth(Colors.white, 1000, CustomColors.darkGreyColor, 1), + width: 24, + height: 24, + padding: EdgeInsets.all(4), + child: Container( + width: double.infinity, + height: double.infinity, + decoration: containerRadius(!isMale ? CustomColors.accentColor : Colors.white, 100), + ), + ), + mWidth(12), + Text( + TranslationBase.of(context).female, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + letterSpacing: -0.56, + ), + ), + ], ), ), ), @@ -166,499 +180,156 @@ class _CalorieCalculatorState extends State { isMale = true; }); }, - child: Container( - padding: EdgeInsets.symmetric(vertical: 16), - decoration: BoxDecoration( - color: femaleCard, - borderRadius: BorderRadius.circular(30.0), - ), - child: Center( - child: Texts( - TranslationBase.of(context).male)), - ), - ), - ), - ], - ), - ), - SizedBox( - height: 12.0, - ), - Texts( - TranslationBase.of(context).age11_120Years, - ), - Container( - margin: - EdgeInsets.symmetric(horizontal: 4.0, vertical: 12.0), - decoration: BoxDecoration( - color: Colors.white, - ), - child: Row( - children: [ - Padding( - padding: EdgeInsets.symmetric( - vertical: 10.0, horizontal: 8.0), - child: Center( - child: Container( - width: 60, - foregroundDecoration: BoxDecoration( - borderRadius: BorderRadius.circular(5.0), - border: Border.all( - color: Colors.blueGrey, - width: 2.0, - ), - ), - child: Row( - children: [ - Expanded( - child: Padding( - padding: const EdgeInsets.all(4.0), - child: Center( - child: Text(age.toString()), - ), - ), - ), - Container( - padding: - EdgeInsets.symmetric(horizontal: 4), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.center, - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - Container( - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - width: 0.5, - ), - ), - ), - child: InkWell( - child: Icon( - Icons.arrow_drop_up, - size: 18.0, - ), - onTap: () { - setState(() { - if (age < 120) age++; - }); - }, - ), - ), - InkWell( - child: Icon( - Icons.arrow_drop_down, - size: 18.0, - ), - onTap: () { - setState(() { - if (age > 0) age--; - }); - }, - ), - ], - ), + child: Row( + children: [ + Container( + decoration: containerColorRadiusBorderWidth(Colors.white, 1000, CustomColors.darkGreyColor, 1), + width: 24, + height: 24, + padding: EdgeInsets.all(4), + child: Container( + width: double.infinity, + height: double.infinity, + decoration: containerRadius(isMale ? CustomColors.accentColor : Colors.white, 100), ), - ], - ), - ), - ), - ), - Expanded( - child: Slider( - value: age.toDouble(), - min: 0, - max: 120, - onChanged: (double newValue) { - setState(() { - age = newValue.round(); - }); - }, - activeColor: Color(0xffC5272D), - inactiveColor: Color(0xffF3C5C6), - ), - ), - ], - ), - ), - Texts( - TranslationBase.of(context).height, - ), - Container( - margin: - EdgeInsets.symmetric(horizontal: 4.0, vertical: 12.0), - decoration: BoxDecoration( - color: Colors.white, - ), - child: Row( - children: [ - Padding( - padding: EdgeInsets.symmetric( - vertical: 10.0, horizontal: 8.0), - child: Center( - child: Container( - width: 60.0, - foregroundDecoration: BoxDecoration( - borderRadius: BorderRadius.circular(5.0), - border: Border.all( - color: Colors.blueGrey, - width: 2.0, ), - ), - child: Row( - children: [ - Expanded( - child: Padding( - padding: const EdgeInsets.all(4.0), - child: Center( - child: Text(height.toString()), - ), - ), - ), - Container( - padding: - EdgeInsets.symmetric(horizontal: 4.0), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.center, - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - Container( - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - width: 0.5, - ), - ), - ), - child: InkWell( - child: Icon( - Icons.arrow_drop_up, - size: 18.0, - ), - onTap: () { - setState(() { - if (height < 250) height++; - }); - }, - ), - ), - InkWell( - child: Icon( - Icons.arrow_drop_down, - size: 18.0, - ), - onTap: () { - setState(() { - if (height > 0) height--; - }); - }, - ), - ], - ), + mWidth(12), + Text( + TranslationBase.of(context).male, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + letterSpacing: -0.56, ), - ], - ), + ), + ], ), ), ), - Expanded( - child: Slider( - value: height.toDouble(), - min: 0, - max: 250, - onChanged: (double newValue) { - setState(() { - height = newValue.round(); - }); - }, - activeColor: Color(0xffC5272D), - inactiveColor: Color(0xffF3C5C6), - ), - ), ], ), ), - Texts( - TranslationBase.of(context).selectUnit, + SizedBox( + height: 12.0, ), + inputWidget(TranslationBase.of(context).age11_120Years, "0", ageController), SizedBox( - height: 8.0, + height: 12.0, ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Expanded( - child: GestureDetector( - onTap: () { - setState(() { - updateColorHeight(1); - }); - }, - child: Container( - padding: EdgeInsets.all(12), - margin: EdgeInsets.symmetric(horizontal: 8), - decoration: BoxDecoration( - boxShadow: [ - BoxShadow( - color: Colors.grey.withOpacity(0.5), - spreadRadius: 3, - blurRadius: 7, - offset: Offset( - 0, 3), // changes position of shadow - ), - ], - color: cmCard, - borderRadius: BorderRadius.circular(3.0), - ), - child: Padding( - padding: const EdgeInsets.symmetric( - vertical: 0.0, horizontal: 18.0), - child: Center(child: Texts(TranslationBase.of(context).cm)), - ), - ), - ), - ), - Expanded( - child: GestureDetector( - onTap: () { - setState(() { - updateColorHeight(2); - }); - }, - child: Container( - padding: EdgeInsets.all(12), - margin: EdgeInsets.symmetric(horizontal: 8), - decoration: BoxDecoration( - color: ftCard, - 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: Center(child: Texts(TranslationBase.of(context).feet))), - ), - ), - ), - ], + _commonInputAndUnitRow( + TranslationBase.of(context).height, + _heightController, + 1, + 270, + _heightValue, + (text) { + _heightController.text = text; + }, + (value) { + _heightValue = value; + }, + _isHeightCM ? TranslationBase.of(context).cm : TranslationBase.of(context).ft, + (value) { + if (_isHeightCM != value) { + setState(() { + _isHeightCM = value; + }); + } + }, + _heightPopupList, ), SizedBox( - height: 8.0, + height: 12.0, ), - Texts( + _commonInputAndUnitRow( TranslationBase.of(context).weight, + _weightController, + 1, + 270, + _weightValue, + (text) { + _weightController.text = text; + }, + (value) { + _weightValue = value; + }, + _isWeightKG ? TranslationBase.of(context).kg : TranslationBase.of(context).pound, + (value) { + if (_isWeightKG != value) { + setState(() { + _isWeightKG = value; + }); + } + }, + _weightPopupList, ), SizedBox( - height: 5.0, + height: 12.0, ), - Container( - margin: - EdgeInsets.symmetric(horizontal: 4.0, vertical: 12.0), - decoration: BoxDecoration( - color: Colors.white, - ), - child: Row( - children: [ - Padding( - padding: EdgeInsets.symmetric( - vertical: 10.0, horizontal: 8.0), - child: Center( - child: Container( - width: 60.0, - foregroundDecoration: BoxDecoration( - borderRadius: BorderRadius.circular(5.0), - border: Border.all( - color: Colors.blueGrey, - width: 2.0, - ), - ), - child: Row( - children: [ - Expanded( - child: Center( - child: Text(weight.toString()), - ), + InkWell( + onTap: () { + // dropdownKey.currentState; + openDropdown(clinicDropdownKey); + }, + child: Container( + // width: double.infinity, + // decoration: containerRadius(Colors.white, 12), + // padding: EdgeInsets.only(left: 10, right: 10, top: 12, bottom: 12), + child: Row( + children: [ + Flexible( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).activityLevel, + style: TextStyle( + fontSize: 11, + letterSpacing: -0.44, + fontWeight: FontWeight.w600, ), - Container( - height: 38.0, - child: Column( - crossAxisAlignment: - CrossAxisAlignment.center, - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - Container( - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - width: 0.5, - ), - ), - ), - child: InkWell( - child: Icon( - Icons.arrow_drop_up, - size: 18.0, - ), - onTap: () { - setState(() { - if (weight < 250) - weight++; - }); - }, - ), - ), - InkWell( - child: Icon( - Icons.arrow_drop_down, - size: 18.0, - ), - onTap: () { - setState(() { - if (weight > 0) weight--; - }); - }, - ), - ], + ), + Container( + height: 18, + child: DropdownButtonHideUnderline( + child: DropdownButton( + value: dropdownValue, + key: clinicDropdownKey, + icon: Icon(Icons.arrow_downward), + iconSize: 0, + elevation: 16, + isExpanded: true, + style: TextStyle(color: Colors.black87), + underline: Container( + height: 2, + color: Colors.black54, + ), + onChanged: (String? newValue) { + setState(() { + dropdownValue = newValue!; + }); + }, + items: [ + TranslationBase.of(context).almostInactive, + TranslationBase.of(context).lightActive, + TranslationBase.of(context).lightActive1, + TranslationBase.of(context).superActive, + ].map>((String value) { + return DropdownMenuItem( + value: value, + child: Text(value), + ); + }).toList(), ), ), - ], - ), - ), - ), - ), - Expanded( - child: Slider( - value: weight.toDouble(), - min: 0, - max: 250, - onChanged: (double newValue) { - setState(() { - weight = newValue.round(); - }); - }, - activeColor: Color(0xffC5272D), - inactiveColor: Color(0xffF3C5C6), - ), - ), - ], - ), - ), - Texts(TranslationBase.of(context).selectUnit), - SizedBox( - height: 5.0, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Expanded( - child: GestureDetector( - onTap: () { - setState(() { - updateColorWeight(1); - }); - }, - child: Container( - padding: EdgeInsets.all(12), - margin: EdgeInsets.symmetric(horizontal: 8), - decoration: BoxDecoration( - boxShadow: [ - BoxShadow( - color: Colors.grey.withOpacity(0.5), - spreadRadius: 3, - blurRadius: 7, - offset: Offset( - 0, 3), // changes position of shadow ), ], - color: kgCard, - borderRadius: BorderRadius.circular(3.0), - ), - child: Padding( - padding: const EdgeInsets.symmetric( - vertical: 0.0, horizontal: 18.0), - child: Center(child: Texts(TranslationBase.of(context).kg)), ), ), - ), + Icon(Icons.keyboard_arrow_down), + ], ), - Expanded( - child: GestureDetector( - onTap: () { - setState(() { - updateColorWeight(2); - }); - }, - child: Container( - padding: EdgeInsets.all(12), - margin: EdgeInsets.symmetric(horizontal: 8), - decoration: BoxDecoration( - color: lbCard, - 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: Center(child: Texts(TranslationBase.of(context).pound)), - ), - ), - ), - ), - ], - ), - SizedBox( - height: 8.0, - ), - Texts(TranslationBase.of(context).activityLevel), - Container( - child: DropdownButton( - value: dropdownValue, - icon: Icon(Icons.arrow_downward), - iconSize: 24, - elevation: 16, - style: TextStyle(color: Colors.black87), - underline: Container( - height: 2, - color: Colors.black54, - ), - onChanged: (String newValue) { - setState(() { - dropdownValue = newValue; - }); - }, - items: [ - 'Almost Inactive(Little or no exercises)', - 'Lighty Active (1-3) days per week', - 'very Active(6-7) days per week', - 'Super Active(very hard exercises)' - ].map>((String value) { - return DropdownMenuItem( - value: value, - child: Text(value), - ); - }).toList(), - ), + ).withBorderedContainer, ), SizedBox( height: 25.0, @@ -670,19 +341,23 @@ class _CalorieCalculatorState extends State { ), Container( margin: EdgeInsets.symmetric(horizontal: 16.0, vertical: 16.0), + color: Colors.white, child: SecondaryButton( label: TranslationBase.of(context).calculate, + color: ageController.text.isNotEmpty ? int.parse(ageController.text) >120 ? Colors.grey : CustomColors.accentColor : CustomColors.accentColor, onTap: () { + if(ageController.text.isNotEmpty && int.parse(ageController.text) <121 && int.parse(_heightController.text)<250 && int.parse(_weightController.text) <200) setState(() { + calculateCalories(); - print(calories); + { Navigator.push( context, FadePage( page: CalorieResultPage( - calorie: calories, - )), + calorie: calories!, + )), ); } }); @@ -693,4 +368,266 @@ class _CalorieCalculatorState extends State { ), ); } + + // void openDropdown(GlobalKey key) { + // GestureDetector detector; + // void searchForGestureDetector(BuildContext element) { + // element.visitChildElements((element) { + // if (element.widget != null && element.widget is GestureDetector) { + // detector = element.widget; + // return false; + // } else { + // searchForGestureDetector(element); + // } + // + // return true; + // }); + // } + // + // searchForGestureDetector(key.currentContext); + // assert(detector != null); + // + // detector.onTap(); + // } + // + + void openDropdown(GlobalKey key) { + GestureDetector? detector; + + void searchForGestureDetector(BuildContext element) { + element.visitChildElements((element) { + if (element.widget != null && element.widget is GestureDetector) { + detector = element.widget as GestureDetector?; + //return false; + } else { + searchForGestureDetector(element); + } + + //return true; + }); + } + + searchForGestureDetector(key.currentContext!); + assert(detector != null); + + detector!.onTap!(); + } + + 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(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: 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, + hintStyle: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: Color(0xff575757), + 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), + ], + ), + ), + ); + } + + Widget _commonInputAndUnitRow(_title, _controller, double _minValue, double _maxValue, double _valueOrg, Function(String) onTextValueChange, Function(double) onValueChange, String unitTitle, + Function(bool) onUnitTap, _list) { + 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( + 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, + ), + ), + ], + ), + ), + 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, + (val) async { + final RenderBox overlay = Overlay.of(context).context.findRenderObject() as RenderBox; + await showMenu( + context: context, + position: RelativeRect.fromRect(val.globalPosition & const Size(40, 40), Offset.zero & overlay.size), + items: _list, + elevation: 8.0, + ).then((val) { + print(val); + onUnitTap(val); + }); + }, + ), + itemBuilder: (context) => _list), + ) + ], + ).withBorderedContainer; + } +} + +// todo 'sikander' move these to separate file once usability known +class CommonDropDownView extends StatelessWidget { + final String title; + final String value; + void Function(TapDownDetails details) 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( + onTapDown: (val) => callback(val), + 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), + ) + ], + ), + ); + } } 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 110b2afc..5844b006 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/calorie_calculator/calorie_result_page.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/calorie_calculator/calorie_result_page.dart @@ -1,61 +1,183 @@ +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/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/button.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:percent_indicator/circular_percent_indicator.dart'; +import '../../../../uitl/app_toast.dart'; + class CalorieResultPage extends StatelessWidget { final double calorie; - CalorieResultPage({this.calorie}); + CalorieResultPage({required this.calorie}); @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, + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Center( - child: CircularPercentIndicator( - radius: 220.0, - lineWidth: 20.0, - percent: ((this.calorie > 3500) ? 100 : this.calorie / 3500), - center: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - calorie.toStringAsFixed(1), - style: TextStyle( - fontSize: 18.0, - fontWeight: FontWeight.bold, + Padding( + padding: const EdgeInsets.all(20.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).calories, + style: TextStyle( + fontSize: 19, + letterSpacing: -1.34, + fontWeight: FontWeight.bold, + ), + ), + mHeight(20), + Center( + child: CircularPercentIndicator( + radius: 120.0, + lineWidth: 3.0, + percent: ((this.calorie > 3500) ? 100 : this.calorie / 3500), + center: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + calorie.toStringAsFixed(1), + style: TextStyle( + fontSize: 17, + letterSpacing: -1.02, + fontWeight: FontWeight.w600, + ), + ), + SizedBox( + height: 5.0, + ), + Text( + TranslationBase.of(context).calories, + style: TextStyle( + fontSize: 18, + letterSpacing: -1.08, + fontWeight: FontWeight.w600, + ), + ), + ], ), + progressColor: CustomColors.accentColor, + backgroundColor: Colors.white, ), - SizedBox( - height: 5.0, + ), + mHeight(20), + Text( + TranslationBase.of(context).dailyIntake+' ${calorie.toStringAsFixed(1)} '+TranslationBase.of(context).calories, + style: TextStyle( + fontSize: 14, + letterSpacing: -0.56, + fontWeight: FontWeight.w600, + color: CustomColors.textColor ), - Texts('Calories'), - ], - ), - progressColor: Color(0xff3C3939), - backgroundColor: Colors.white, - ), + ), + ], + ).withBorderedContainer, ), + mFlex(1), Container( - child: - Texts('Daily intake is ${calorie.toStringAsFixed(1)} calories'), - ), - Container( - width: 350, - child: Button( - label: 'See List Of Doctors', + margin: EdgeInsets.symmetric(horizontal: 16.0, vertical: 16.0), + color: Colors.white, + child: SecondaryButton( + label: TranslationBase.of(context).viewDocList, + color: CustomColors.accentColor, + onTap: () { + getDoctorsList(context); + }, ), ), + ], ), ); } + + getDoctorsList(BuildContext context) { + GifLoaderDialogUtils.showMyDialog(context); + BariatricsService service = new BariatricsService(); + + List doctorsList = []; + List _patientDoctorAppointmentListHospital =[]; + + service.getCalculationDoctors(calculationID: 2).then((res) { + GifLoaderDialogUtils.hideDialog(context); + + if (res!=null && 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, isDoctorSearchResult: false,))); + } + } + }).catchError((err) { + + AppToast.showErrorToast(message: err); + print(err); + }); + } +} + +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/health_calculator/carbs/carbs.dart b/lib/pages/AlHabibMedicalService/health_calculator/carbs/carbs.dart index 78a737bb..5ee8980f 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/carbs/carbs.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/carbs/carbs.dart @@ -1,11 +1,13 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/health_calculator/calorie_calculator/calorie_calculator.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; 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/services.dart'; +import 'package:provider/provider.dart'; import 'carbs_result_page.dart'; @@ -16,46 +18,47 @@ class Carbs extends StatefulWidget { class _CarbsState extends State { TextEditingController textController = new TextEditingController(); - int calories; - String dropdownValue; + final GlobalKey clinicDropdownKey = GlobalKey(); + int? calories; + late String dropdownValue; bool _visible = false; - int meals; - int protein; - int carbs; + int? meals; + int? protein; + int? carbs; - int fat; - double pCal; - double cCal; - double fCal; - double pCalGram; - double cCalGram; - double fCalGram; - double pCalMeal; - double cCalMeal; - double fCalMeal; + int? fat; + double? pCal; + double? cCal; + double? fCal; + double? pCalGram; + double? cCalGram; + double? fCalGram; + double? pCalMeal; + double? cCalMeal; + double? fCalMeal; void calculateDietRatios() { - if (dropdownValue == 'Very Low Carb') { + if (dropdownValue == TranslationBase.of(context).dietVeryLow) { meals = 3; protein = 45; carbs = 10; fat = 45; - } else if (dropdownValue == 'Low Carb') { + } else if (dropdownValue == TranslationBase.of(context).dietLow) { meals = 3; protein = 40; carbs = 30; fat = 30; - } else if (dropdownValue == 'Moderate Carb') { + } else if (dropdownValue == TranslationBase.of(context).dietModerate) { meals = 3; protein = 25; carbs = 50; fat = 25; - } else if (dropdownValue == 'USDA Gudilines') { + } else if (dropdownValue == TranslationBase.of(context).dietUSDA) { meals = 3; protein = 15; carbs = 55; fat = 30; - } else if (dropdownValue == 'Zone Diet') { + } else if (dropdownValue == TranslationBase.of(context).dietZone) { meals = 3; protein = 30; carbs = 40; @@ -64,304 +67,338 @@ class _CarbsState extends State { } void calculate() { - pCal = (protein / 100.0) * int.parse(textController.text).ceil(); - cCal = (carbs / 100.0) * int.parse(textController.text); - ; - fCal = (fat / 100) * int.parse(textController.text); - ; - pCalGram = pCal / 4.0; - cCalGram = cCal / 4.0; - fCalGram = fCal / 9.0; - pCalMeal = pCalGram / meals.ceil(); - cCalMeal = cCalGram / meals.ceil(); - fCalMeal = fCalGram / meals.ceil(); + pCal = (protein! / 100.0) * int.parse(textController.text).ceil(); + cCal = (carbs! / 100.0) * int.parse(textController.text); + + fCal = (fat! / 100) * int.parse(textController.text); + + pCalGram = pCal! / 4.0; + cCalGram = cCal! / 4.0; + fCalGram = fCal! / 9.0; + pCalMeal = pCalGram! / meals!.ceil(); + cCalMeal = cCalGram! / meals!.ceil(); + fCalMeal = fCalGram! / meals!.ceil(); } @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + + dropdownValue = TranslationBase.of(context).dietVeryLow; return AppScaffold( isShowAppBar: true, - appBarTitle: 'Carb Protein Fat', - body: Padding( - padding: EdgeInsets.symmetric(horizontal: 25.0, vertical: 15.0), - child: SingleChildScrollView( - child: Container( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts( - 'Calculates carbohydrate protein and fat\n ratio in calories and grams according to a\n pre-set ratio', - ), - SizedBox( - height: 15.0, - ), - Column( + isShowDecPage: false, + showNewAppBarTitle: true, + showNewAppBar: true, + appBarTitle: TranslationBase.of(context).carbohydrate, + appBarIcons: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 7.0), + child: Icon( + Icons.info_outline, + color: Colors.white, + ), + ) + ], + body: Column( + children: [ + Expanded( + child: SingleChildScrollView( + child: Container( + padding: EdgeInsets.all(21), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Container( - width: 340.0, - height: 60.0, - decoration: BoxDecoration( - color: Colors.white, - ), - child: Row( - children: [ - Padding( - padding: EdgeInsets.symmetric( - vertical: 10.0, horizontal: 8.0), - child: Center( - child: Container( - width: 300.0, - foregroundDecoration: BoxDecoration( - borderRadius: BorderRadius.circular(5.0), - border: Border.all( - color: Colors.blueGrey, - width: 2.0, - ), - ), - child: Row( - children: [ - Expanded( - child: Center( - child: TextFormField( - controller: textController, - inputFormatters: [ - FilteringTextInputFormatter - .digitsOnly - ], - keyboardType: TextInputType.number, - decoration: InputDecoration( - hintText: " The Calories per day ", - labelStyle: TextStyle( - color: Colors.black87, - ), - ), - ), - ), - ), - Container( - height: 38.0, - child: Column( - crossAxisAlignment: - CrossAxisAlignment.center, - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - Container( - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - width: 0.5, - ), - ), - ), - child: InkWell( - child: Icon( - Icons.arrow_drop_up, - size: 18.0, - ), - onTap: () { - setState(() { - int currentValue = int.parse( - textController.text); - currentValue++; - textController.text = - (currentValue).toString(); - }); - }, - ), - ), - InkWell( - child: Icon( - Icons.arrow_drop_down, - size: 18.0, - ), - onTap: () { - setState(() { - int currentValue = int.parse( - textController.text); - currentValue--; - textController.text = - (currentValue).toString(); - }); - }, - ), - ], - ), - ), - ], - ), - ), - ), - ), - ], + Text( + TranslationBase.of(context).carbProteinDesc, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + letterSpacing: -0.56, + color: CustomColors.textColor, ), ), SizedBox( - height: 20.0, + height: 15.0, ), - Button( - backgroundColor: Color(0xffC5272D), - label: 'NOT SURE? CLICK HERE ', - onTap: () { - setState(() { - { + Column( + mainAxisAlignment: MainAxisAlignment.end, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + inputWidget(TranslationBase.of(context).calDay, "0", textController), + InkWell( + onTap: () { Navigator.push( context, FadePage(page: CalorieCalculator()), ); - } - }); - }, + }, + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Text( + TranslationBase.of(context).notSure, + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, letterSpacing: -0.56, color: CustomColors.accentColor, decoration: TextDecoration.underline), + ), + ), + ) + ], ), - ], - ), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts('Select Diet Type'), - Container( - width: 400, - child: DropdownButton( - value: dropdownValue, - icon: Icon(Icons.arrow_downward), - iconSize: 24, - elevation: 16, - style: TextStyle(color: Colors.black87), - underline: Container( - height: 2, - color: Colors.black54, - ), - onChanged: (String newValue) { - setState(() { - dropdownValue = newValue; - calculateDietRatios(); - - dropdownValue == null - ? _visible = false - : _visible = true; - }); - }, - items: [ - 'Very Low Carb', - 'Low Carb', - 'Moderate Carb', - 'USDA Gudilines', - 'Zone Diet', - ].map>((String value) { - return DropdownMenuItem( - value: value, - child: Text(value), - ); - }).toList(), - ), + SizedBox( + height: 12.0, ), - Visibility( - visible: _visible, + InkWell( + onTap: () { + // dropdownKey.currentState; + openDropdown(clinicDropdownKey); + }, child: Container( - height: 170.0, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceEvenly, + // width: double.infinity, + // decoration: containerRadius(Colors.white, 12), + // padding: EdgeInsets.only(left: 10, right: 10, top: 12, bottom: 12), + child: Row( children: [ - Texts( - 'Ratios are divided according to the selected diet'), - RichText( - text: TextSpan( - style: TextStyle(color: Colors.black), + Flexible( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - TextSpan(text: 'Meals Per Day '), - TextSpan( - text: '$meals', - style: TextStyle(color: Color(0xffC5272D)), - ), - ], - ), - ), - RichText( - text: TextSpan( - style: TextStyle(color: Colors.black), - children: [ - TextSpan( - text: 'Protein ', - ), - TextSpan( - text: '$protein%', - style: TextStyle(color: Color(0xffC5272D)), - ) - ], - ), - ), - RichText( - text: TextSpan( - style: TextStyle(color: Colors.black), - children: [ - TextSpan( - text: 'Carbohydrate ', + Text( + TranslationBase.of(context).selectDiet, + style: TextStyle( + fontSize: 11, + letterSpacing: -0.44, + fontWeight: FontWeight.w600, + ), ), - TextSpan( - text: '$carbs%', - style: TextStyle(color: Color(0xffC5272D)), - ) - ], - ), - ), - RichText( - text: TextSpan( - style: TextStyle(color: Colors.black), - children: [ - TextSpan( - text: 'Fat ', + Container( + height: 18, + child: DropdownButtonHideUnderline( + child: DropdownButton( + value: dropdownValue, + key: clinicDropdownKey, + icon: Icon(Icons.arrow_downward), + iconSize: 0, + elevation: 16, + isExpanded: true, + style: TextStyle(color: Colors.black87), + underline: Container( + height: 2, + color: Colors.black54, + ), + onChanged: (String? newValue) { + setState(() { + dropdownValue = newValue!; + calculateDietRatios(); + }); + }, + items: [ + TranslationBase.of(context).dietVeryLow, + TranslationBase.of(context).dietLow, + TranslationBase.of(context).dietModerate, + TranslationBase.of(context).dietUSDA, + TranslationBase.of(context).dietZone + ].map>((String value) { + return DropdownMenuItem( + value: value, + child: Text(value, + style: TextStyle(fontFamily: projectViewModel.isArabic ? 'Cairo' : 'Poppins', fontSize: 11, letterSpacing: -0.44, fontWeight: FontWeight.w600)), + ); + }).toList(), + ), + ), ), - TextSpan( - text: '$fat%', - style: TextStyle(color: Color(0xffC5272D)), - ) ], ), ), + Icon(Icons.keyboard_arrow_down), ], ), - ), - ) + ).withBorderedContainer, + ), + SizedBox( + height: 25.0, + ), + SizedBox( + height: 55.0, + ), ], ), - SizedBox( - height: 55.0, + ), + ), + ), + Container( + margin: EdgeInsets.symmetric(horizontal: 16.0, vertical: 16.0), + color: Colors.white, + child: SecondaryButton( + label: TranslationBase.of(context).calculate, + color: CustomColors.accentColor, + onTap: () { + setState(() { + { + calculate(); + Navigator.push( + context, + FadePage( + page: CarbsResult( + cCal: cCal!, + pCal: pCal!, + fCal: fCal!, + pCalGram: pCalGram!, + pCalMeal: pCalMeal!, + fCalGram: fCalGram!, + fCalMeal: fCalMeal!, + cCalGram: cCalGram!, + cCalMeal: cCalMeal!, + )), + ); + } + }); + }, + ), + ), + ], + ), + ); + } + + + void openDropdown(GlobalKey key) { + GestureDetector? detector; + + void searchForGestureDetector(BuildContext element) { + element.visitChildElements((element) { + if (element.widget != null && element.widget is GestureDetector) { + detector = element.widget as GestureDetector?; + //return false; + } else { + searchForGestureDetector(element); + } + + //return true; + }); + } + + searchForGestureDetector(key.currentContext!); + assert(detector != null); + + detector!.onTap!(); + } + + // void openDropdown(GlobalKey key) { + // GestureDetector detector; + // void searchForGestureDetector(BuildContext element) { + // element.visitChildElements((element) { + // if (element.widget != null && element.widget is GestureDetector) { + // detector = element.widget; + // return false; + // } else { + // searchForGestureDetector(element); + // } + // + // return true; + // }); + // } + // + // searchForGestureDetector(key.currentContext); + // assert(detector != null); + // + // detector.onTap(); + // } +} + +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(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, + ), ), - Container( - height: 50.0, - width: 350.0, - child: SecondaryButton( - label: 'CALCULATE', - onTap: () { - setState(() { - { - calculate(); - Navigator.push( - context, - FadePage( - page: CarbsResult( - cCal: cCal, - pCal: pCal, - fCal: fCal, - pCalGram: pCalGram, - pCalMeal: pCalMeal, - fCalGram: fCalGram, - fCalMeal: fCalMeal, - cCalGram: cCalGram, - cCalMeal: cCalMeal, - )), - ); - } - }); - }, + 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, + hintStyle: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: Color(0xff575757), + 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), + ], ), - ); - } + ), + ); +} + +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/health_calculator/carbs/carbs_result_page.dart b/lib/pages/AlHabibMedicalService/health_calculator/carbs/carbs_result_page.dart index f8d0815a..29257ccc 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/carbs/carbs_result_page.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/carbs/carbs_result_page.dart @@ -1,10 +1,20 @@ +import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/health-calculator/bariatrics-service.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/SearchResults.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.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; -import 'dart:math'; - import 'package:flutter/painting.dart'; +import 'package:provider/provider.dart'; class CarbsResult extends StatelessWidget { double pCal; @@ -17,159 +27,161 @@ class CarbsResult extends StatelessWidget { double cCalMeal; double fCalMeal; - CarbsResult( - {this.pCal, - this.cCal, - this.fCal, - this.pCalGram, - this.cCalGram, - this.fCalGram, - this.fCalMeal, - this.cCalMeal, - this.pCalMeal}); + CarbsResult({required this.pCal, required this.cCal, required this.fCal, required this.pCalGram, required this.cCalGram, required this.fCalGram, required this.fCalMeal, required this.cCalMeal, required this.pCalMeal}); + @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(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: [ - Padding( - padding: EdgeInsets.symmetric(vertical: 30.0, horizontal: 10.0), - child: Table( - border: TableBorder( - verticalInside: BorderSide(width: 1, color: Colors.black54), - bottom: BorderSide(width: 1, color: Colors.black54), - left: BorderSide(width: 1, color: Colors.black54), - right: BorderSide(width: 1, color: Colors.black54), - top: BorderSide(width: 1, color: Colors.black54), - ), + Container( + decoration: containerRadius(Colors.white, 12), + padding: EdgeInsets.all(12), + margin: EdgeInsets.all(20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - TableRow( - decoration: BoxDecoration( - color: Colors.white, - ), - children: [ - TableCell( - child: Center( - child: Texts('Description'), - ), - ), - TableCell( - child: Center( - child: Texts('Protein'), - ), - ), - TableCell( - child: Center( - child: Texts( - 'Carbohydrate', - ), - ), - ), - TableCell( - child: Center( - child: Texts('Fat'), - ), - ), - ]), - TableRow(children: [ - Padding( - padding: EdgeInsets.all(8.0), - child: TableCell( - child: Center( - child: Texts('Calories\n Per Day'), - ), - ), - ), - TableCell( - child: Center( - child: Texts(pCal.ceil().toString() + ' Cals'), - ), - ), - TableCell( - child: Center( - child: Texts(cCal.ceil().toString() + ' Cals'), - ), - ), - TableCell( - child: Center( - child: Texts(fCal.ceil().toString() + ' Cals'), - ), - ), - ]), - TableRow(children: [ - Padding( - padding: EdgeInsets.all(8.0), - child: TableCell( - child: Center( - child: Texts('Grams Per\n Day'), - ), - ), - ), - TableCell( - child: Center( - child: Texts(pCalGram.ceil().toString() + ' gr'), - ), - ), - TableCell( - child: Center( - child: Texts(cCalGram.ceil().toString() + ' gr'), - ), - ), - TableCell( - child: Center( - child: Texts(fCalGram.ceil().toString() + ' gr'), - ), - ), - ]), - TableRow(children: [ - Padding( - padding: EdgeInsets.all(8.0), - child: TableCell( - child: Center( - child: Texts('Grams Per\n Meal'), - ), - ), + Text( + TranslationBase.of(context).carbsProtin, + style: TextStyle( + fontSize: 19, + fontWeight: FontWeight.bold, + letterSpacing: -1.34, ), - TableCell( - child: Center( - child: Texts(pCalMeal.ceil().toString() + ' gr'), - ), - ), - TableCell( - child: Center( - child: Texts(cCalMeal.ceil().toString() + ' gr'), - ), - ), - TableCell( - child: Center( - child: Texts(fCalMeal.ceil().toString() + ' gr'), - ), - ), - ]), + ), + mHeight(12), + Table( + columnWidths: { + 0: FlexColumnWidth(2.4), + 1: FlexColumnWidth(1.8), + 2: FlexColumnWidth(2), + 3: FlexColumnWidth(1), + }, + children: fullData(context, projectViewModel), + ), ], ), ), Container( - width: 350, - child: Button( - label: 'See List Of Doctors', + margin: EdgeInsets.symmetric(horizontal: 16.0, vertical: 16.0), + color: Colors.white, + child: SecondaryButton( + label: TranslationBase.of(context).seeListOfDoctor, + color: CustomColors.accentColor, + onTap: () { + 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()), + List fullData(BuildContext context, ProjectViewModel projectViewModel) { + List tableRow = []; + tableRow.add( + TableRow( + children: [ + Utils.tableColumnTitle(TranslationBase.of(context).description), + Utils.tableColumnTitle(TranslationBase.of(context).Protein), + Utils.tableColumnTitle(TranslationBase.of(context).carbohydrate), + Utils.tableColumnTitle(TranslationBase.of(context).fat), + ], + ), ); + + tableRow.add( + TableRow( + children: [ + Utils.tableColumnValue(TranslationBase.of(context).calDay, isCapitable: false, mProjectViewModel: projectViewModel), + Utils.tableColumnValue(pCal.ceil().toString() + ' '+TranslationBase.of(context).Cals, isCapitable: false, mProjectViewModel: projectViewModel), + Utils.tableColumnValue(cCal.ceil().toString() + ' '+TranslationBase.of(context).Cals, isCapitable: false, mProjectViewModel: projectViewModel), + Utils.tableColumnValue(cCal.ceil().toString() + ' '+TranslationBase.of(context).Cals, isCapitable: false, mProjectViewModel: projectViewModel), + ], + ), + ); + + tableRow.add( + TableRow( + children: [ + Utils.tableColumnValue(TranslationBase.of(context).gramsPerDay, isCapitable: false, mProjectViewModel: projectViewModel), + Utils.tableColumnValue(pCalGram.ceil().toString() + ' '+TranslationBase.of(context).gr, isCapitable: false, mProjectViewModel: projectViewModel), + Utils.tableColumnValue(cCalGram.ceil().toString() + ' '+TranslationBase.of(context).gr, isCapitable: false, mProjectViewModel: projectViewModel), + Utils.tableColumnValue(fCalGram.ceil().toString() + ' '+TranslationBase.of(context).gr, isCapitable: false, mProjectViewModel: projectViewModel), + ], + ), + ); + tableRow.add( + TableRow( + children: [ + Utils.tableColumnValue(TranslationBase.of(context).gramsPerMeal, isCapitable: false, mProjectViewModel: projectViewModel), + Utils.tableColumnValue(pCalMeal.ceil().toString() + ' '+TranslationBase.of(context).gr, isCapitable: false, mProjectViewModel: projectViewModel), + Utils.tableColumnValue(cCalMeal.ceil().toString() + ' '+TranslationBase.of(context).gr, isCapitable: false, mProjectViewModel: projectViewModel), + Utils.tableColumnValue(fCalMeal.ceil().toString() + ' '+TranslationBase.of(context).gr, isCapitable: false, mProjectViewModel: projectViewModel), + ], + ), + ); + return tableRow; + } + + getDoctorsList(BuildContext context) { + GifLoaderDialogUtils.showMyDialog(context); + BariatricsService service = new BariatricsService(); + + List doctorsList = []; + List _patientDoctorAppointmentListHospital =[]; + + service.getCalculationDoctors(calculationID: 11).then((res) { + GifLoaderDialogUtils.hideDialog(context); + 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, isDoctorSearchResult: false,))); + } + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); } } diff --git a/lib/pages/AlHabibMedicalService/health_calculator/delivery_due/delivery_due.dart b/lib/pages/AlHabibMedicalService/health_calculator/delivery_due/delivery_due.dart index d19c6017..d6d5ab8a 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/delivery_due/delivery_due.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/delivery_due/delivery_due.dart @@ -1,11 +1,13 @@ +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/button.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:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_datetime_picker/flutter_datetime_picker.dart'; +import 'package:flutter_datetime_picker_plus/flutter_datetime_picker_plus.dart'; import 'package:intl/intl.dart'; import 'delivery_due_result_page.dart'; @@ -40,108 +42,118 @@ class _DeliveryDueState extends State { Widget build(BuildContext context) { return AppScaffold( isShowAppBar: true, - appBarTitle: 'Delivery Due Date', - body: Padding( - padding: EdgeInsets.symmetric(horizontal: 35.0, vertical: 20.0), - child: SingleChildScrollView( - child: Container( - child: Column( - //mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - Texts( - 'Congratulations, you are pregnant! Now when will the new baby arrive? To estimate the due date, enter the date when the last menstrual perios began (the first day), then click calculate.', - ), - Divider( - //height: 2, - thickness: 2, - ), - Column( + showNewAppBar: true, + showNewAppBarTitle: true, + isShowDecPage: false, + appBarTitle: TranslationBase.of(context).pregnancyTitle, + body: Column( + children: [ + Expanded( + child: SingleChildScrollView( + child: Container( + padding: EdgeInsets.symmetric(horizontal: 21.0, vertical: 21.0), + child: Column( children: [ - Texts( - 'What was the date of the first day of the last period?', + Text( + TranslationBase.of(context).pregnancyDesc, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + ), ), - InkWell( - onTap: () { - DatePicker.showDatePicker( - context, - showTitleActions: true, - minTime: DateTime(DateTime.now().year - 1, 1, 1), - maxTime: DateTime.now(), - onConfirm: (date) { - print('confirm $date'); - setState(() { - bloodSugarDate == date - ? null - : bloodSugarDate = DateTime.now(); - dateFrom = date.add(Duration(days: 10)); + Divider( + //height: 2, + thickness: 1, + ), + Column( + children: [ + Text( + TranslationBase.of(context).pregnancyDateLabel, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + ), + ), + InkWell( + onTap: () { + DatePicker.showDatePicker( + context, + showTitleActions: true, + minTime: DateTime(DateTime.now().year - 1, 1, 1), + maxTime: DateTime.now(), + onConfirm: (date) { + print('confirm $date'); + setState(() { + bloodSugarDate = date; + dateFrom = date.add(Duration(days: 10)); - dateTo = date.add(Duration(days: 20)); - conceivedDate = date.add(Duration(days: 14)); - deliveryDue = date.add(Duration(days: 280)); - firstTrimester = date.add(Duration(days: 85)); - secondTrimester = date.add(Duration(days: 190)); - thirdTrimester = date.add(Duration(days: 280)); - }); + dateTo = date.add(Duration(days: 20)); + conceivedDate = date.add(Duration(days: 14)); + deliveryDue = date.add(Duration(days: 280)); + firstTrimester = date.add(Duration(days: 85)); + secondTrimester = date.add(Duration(days: 190)); + thirdTrimester = date.add(Duration(days: 280)); + }); + }, + currentTime: DateTime.now(), + ); }, - currentTime: DateTime.now(), - ); - }, - 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: [ - Row( + child: Container( + padding: EdgeInsets.all(12), + margin: EdgeInsets.only(top: 15.0), + width: double.infinity, + height: 65, + decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), color: Colors.white), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Icon(Icons.date_range), - Texts('Date'), + Row( + children: [ + Icon(Icons.date_range), + Texts(TranslationBase.of(context).date), + ], + ), + Texts(getDate()), ], ), - Texts(getDate()), - ], + ), ), - ), + ], ), + ], ), - SizedBox( - height: 280.0, - ), - Container( - height: 50.0, - width: 350.0, - child: SecondaryButton( - label: 'CALCULATE', - onTap: () { - setState(() { - { - Navigator.push( - context, - FadePage( - page: DeliveryDueResult( - conceivedDate: conceivedDate, - dateFrom: dateFrom, - dateTo: dateTo, - deliveryDue: deliveryDue, - firstTrimester: firstTrimester, - secondTrimester: secondTrimester, - thirdTrimester: thirdTrimester, - )), - ); - } - }); - }, - ), - ), - ], + ), + ), + ), + Container( + margin: EdgeInsets.symmetric(horizontal: 16.0, vertical: 16.0), + color: Colors.white, + child: SecondaryButton( + label: TranslationBase.of(context).calculate, + color: CustomColors.accentColor, + onTap: () { + setState(() { + { + Navigator.push( + context, + FadePage( + page: DeliveryDueResult( + conceivedDate: conceivedDate, + dateFrom: dateFrom, + dateTo: dateTo, + deliveryDue: deliveryDue, + firstTrimester: firstTrimester, + secondTrimester: secondTrimester, + thirdTrimester: thirdTrimester, + )), + ); + } + }); + }, ), ), - ), + ], ), ); } diff --git a/lib/pages/AlHabibMedicalService/health_calculator/delivery_due/delivery_due_result_page.dart b/lib/pages/AlHabibMedicalService/health_calculator/delivery_due/delivery_due_result_page.dart index fc53b044..84dc5e5e 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/delivery_due/delivery_due_result_page.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/delivery_due/delivery_due_result_page.dart @@ -1,6 +1,15 @@ -import 'package:diplomaticquarterapp/widgets/buttons/button.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/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/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; @@ -12,95 +21,183 @@ class DeliveryDueResult extends StatelessWidget { var firstTrimester; var secondTrimester; var thirdTrimester; - DeliveryDueResult( - {this.dateFrom, - this.dateTo, - this.conceivedDate, - this.deliveryDue, - this.firstTrimester, - this.secondTrimester, - this.thirdTrimester}); + + DeliveryDueResult({this.dateFrom, this.dateTo, this.conceivedDate, this.deliveryDue, this.firstTrimester, this.secondTrimester, this.thirdTrimester}); + @override Widget build(BuildContext context) { return AppScaffold( isShowAppBar: true, - appBarTitle: 'Delivery Due Date', - body: Padding( - padding: EdgeInsets.symmetric(horizontal: 30.0, vertical: 12.0), - child: SingleChildScrollView( - child: Container( - height: 750.0, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Texts( - 'The next ovulation period is estimated to be:', - fontWeight: FontWeight.w400, - ), - Texts( - 'From:', - fontWeight: FontWeight.w400, - ), - Texts(DateFormat.yMMMEd().format(dateFrom), - fontWeight: FontWeight.w800, - fontSize: 21.0, - color: Color(0xffC5272D)), - Texts( - 'To:', - fontWeight: FontWeight.w400, - ), - Texts(DateFormat.yMMMEd().format(dateTo), - fontWeight: FontWeight.w800, - fontSize: 21.0, - color: Color(0xffC5272D)), - Texts( - 'You have conceived on:', - fontWeight: FontWeight.w400, - ), - Texts( - DateFormat.yMMMEd().format(conceivedDate), - fontWeight: FontWeight.w800, - fontSize: 21.0, - ), - Texts( - 'First Trimester Ends (12 weeks):', - fontWeight: FontWeight.w400, - ), - Texts( - DateFormat.yMMMEd().format(firstTrimester), - fontWeight: FontWeight.w800, - fontSize: 21.0, - ), - Texts( - 'Second Trimester Ends (27 weeks):', - fontWeight: FontWeight.w400, - ), - Texts( - DateFormat.yMMMEd().format(secondTrimester), - fontWeight: FontWeight.w800, - fontSize: 21.0, - ), - Texts( - 'Third Trimester, Estimated Due Date (40 weeks):', - fontWeight: FontWeight.w400, - ), - Texts( - DateFormat.yMMMEd().format(thirdTrimester), - fontWeight: FontWeight.w800, - fontSize: 21.0, - ), - Container( - width: 350, - child: Button( - label: 'See List Of Doctors', - ), - ), - ], + showNewAppBar: true, + showNewAppBarTitle: true, + isShowDecPage: false, + appBarTitle: TranslationBase.of(context).pregnancyTitle, + body: Column( + children: [ + Expanded( + child: SingleChildScrollView( + child: Container( + padding: EdgeInsets.symmetric(horizontal: 21.0, vertical: 21.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Text( + TranslationBase.of(context).pregnancyTitle, + style: TextStyle( + fontSize: 19, + letterSpacing: -1.14, + fontWeight: FontWeight.w600, + ), + ), + Text( + TranslationBase.of(context).ovulationPeriod, + style: TextStyle( + fontSize: 14, + letterSpacing: -0.56, + fontWeight: FontWeight.w600, + color: CustomColors.textColor, + ), + ), + mHeight(20), + showItem(TranslationBase.of(context).from, DateFormat.yMMMEd().format(dateFrom), titleColor: CustomColors.accentColor), + mHeight(12), + showItem(TranslationBase.of(context).to, DateFormat.yMMMEd().format(dateTo), titleColor: CustomColors.accentColor), + mHeight(12), + mDivider(CustomColors.devider), + mHeight(12), + showItem(TranslationBase.of(context).conceive, DateFormat.yMMMEd().format(conceivedDate)), + mHeight(12), + mDivider(CustomColors.devider), + mHeight(12), + showItem(TranslationBase.of(context).firstTri, DateFormat.yMMMEd().format(firstTrimester)), + mHeight(12), + mDivider(CustomColors.devider), + mHeight(12), + showItem(TranslationBase.of(context).secondTri, DateFormat.yMMMEd().format(secondTrimester)), + mHeight(12), + mDivider(CustomColors.devider), + mHeight(12), + showItem(TranslationBase.of(context).thirdTri, DateFormat.yMMMEd().format(thirdTrimester)), + mHeight(12), + mDivider(CustomColors.devider), + mHeight(12), + ], + ).withBorderedContainer, + ), ), ), - ), + Container( + margin: EdgeInsets.symmetric(horizontal: 16.0, vertical: 16.0), + color: Colors.white, + child: SecondaryButton( + label: TranslationBase.of(context).seeDoctorsList, + color: CustomColors.accentColor, + onTap: () { + getDoctorsList(context); + }, + ), + ), + ], + ), + ); + } + + Widget showItem(String title, String value, {Color? titleColor}) { + return Container( + width: double.infinity, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title, + style: TextStyle( + fontSize: 14, + letterSpacing: -0.56, + color: titleColor ?? Colors.black, + fontWeight: FontWeight.w500, + // fontWeight: FontWeight.w600, + ), + ), + Text( + value, + style: TextStyle( + fontSize: 18, + letterSpacing: -1.08, + fontWeight: FontWeight.w600, + ), + ), + ], ), ); } + + getDoctorsList(BuildContext context) { + GifLoaderDialogUtils.showMyDialog(context); + BariatricsService service = new BariatricsService(); + + List doctorsList = []; + List _patientDoctorAppointmentListHospital =[]; + + service.getCalculationDoctors(calculationID: 6).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, isDoctorSearchResult: false,))); + } + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } +} + +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/health_calculator/doctor_list.dart b/lib/pages/AlHabibMedicalService/health_calculator/doctor_list.dart new file mode 100644 index 00000000..04adcfc1 --- /dev/null +++ b/lib/pages/AlHabibMedicalService/health_calculator/doctor_list.dart @@ -0,0 +1,146 @@ +import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HealthCalculator/DiseasesByClinic.dart'; +import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/health-calculator/Bariatrics-viewmodel.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/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_rating_bar/flutter_rating_bar.dart'; + +class DoctorList extends StatelessWidget { + DiseasesByClinic diseaseByClinic; + + DoctorList({Key? key, required this.diseaseByClinic}) : super(key: key); + + @override + Widget build(BuildContext context) { + return BaseView( + allowAny: true, + onModelReady: (model) => model.getDoctorList(disease: diseaseByClinic), + builder: (BuildContext context, BariatricsViewModel model, Widget? child) => AppScaffold( + isShowDecPage: false, + isShowAppBar: true, + baseViewModel: model, + appBarTitle: "Doctors List", + description: TranslationBase.of(context).infoApprovals, + infoList: TranslationBase.of(context).infoApprovalPoints, + body: ListView.builder( + itemCount: model.doctorLists.length, + itemBuilder: (BuildContext context, int index) { + return Padding( + padding: EdgeInsets.symmetric(horizontal: 16.0, vertical: 10.0), + child: Container( + //height: MediaQuery.of(context).size.height * 0.09, + decoration: BoxDecoration(color: Colors.white), + + child: ExpansionTile( + title: Padding( + padding: EdgeInsets.all(21.0), + child: Texts(model.doctorLists[index].filterName), + ), + children: model.doctorLists[index].doctorsByTimeList + .map((doctor) => Card( + margin: EdgeInsets.fromLTRB(10.0, 16.0, 10.0, 8.0), + color: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + child: Container( + decoration: BoxDecoration(), + padding: EdgeInsets.all(7.0), + width: MediaQuery.of(context).size.width, + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Expanded( + flex: 1, + child: ClipRRect( + borderRadius: BorderRadius.circular(100.0), + child: Image.network(doctor.doctorImageURL!, fit: BoxFit.fill, height: 60.0, width: 60.0), + ), + ), + Expanded( + flex: 4, + child: Container( + width: MediaQuery.of(context).size.width * 0.55, + margin: EdgeInsets.fromLTRB(20.0, 10.0, 10.0, 0.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (doctor.doctorTitle != null) + Text(doctor.doctorTitle! + " " + doctor.name!, style: TextStyle(fontSize: 14.0, color: Colors.grey[700], letterSpacing: 1.0)), + Container( + margin: EdgeInsets.only(top: 3.0), + child: Text(doctor.clinicName != null ? doctor.clinicName! : "", style: TextStyle(fontSize: 12.0, color: Colors.grey[600], letterSpacing: 1.0)), + ), + Container( + margin: EdgeInsets.only(top: 3.0), + child: Text(doctor.projectName!, style: TextStyle(fontSize: 12.0, color: Colors.grey[600], letterSpacing: 1.0)), + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + mainAxisSize: MainAxisSize.max, + children: [ + // RatingBar.readOnly( + // initialRating: doctor.actualDoctorRate.toDouble(), + // size: 20.0, + // filledColor: Colors.yellow[700], + // emptyColor: Colors.grey[500], + // isHalfAllowed: true, + // halfFilledIcon: Icons.star_half, + // filledIcon: Icons.star, + // emptyIcon: Icons.star, + // ), + + // Changed By Aamir + RatingBar( + initialRating: 3, + direction: Axis.horizontal, + allowHalfRating: true, + itemCount: 5, + itemSize: 20, + ignoreGestures: true, + ratingWidget: RatingWidget( + full: Icon( + Icons.star, + color: CustomColors.accentColor, + ), + half: Icon( + Icons.star_half, + color: CustomColors.accentColor, + ), + empty: Icon( + Icons.star, + color: CustomColors.accentColor, + ), + ), + tapOnlyMode: true, + unratedColor: Colors.grey[500], + itemPadding: EdgeInsets.symmetric(horizontal: 4.0), + onRatingUpdate: (rating) { + print(rating); + }, + ), + Container( + child: Image.network(doctor.nationalityFlagURL!, width: 25.0, height: 25.0), + ), + ], + ), + ], + ), + ), + ), + ], + ), + ), + )) + .toList(), + ), + ), + ); + }), + )); + } +} diff --git a/lib/pages/AlHabibMedicalService/health_calculator/health_calc_desc.dart b/lib/pages/AlHabibMedicalService/health_calculator/health_calc_desc.dart new file mode 100644 index 00000000..19f8e986 --- /dev/null +++ b/lib/pages/AlHabibMedicalService/health_calculator/health_calc_desc.dart @@ -0,0 +1,40 @@ +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; + +class HealthDescPage extends StatelessWidget { + final String title; + final String desc; + final String icon; + + HealthDescPage(this.title, this.desc, this.icon); + + @override + Widget build(BuildContext context) { + return AppScaffold( + isShowAppBar: true, + isShowDecPage: false, + appBarTitle: title, + body: Container( + margin: EdgeInsets.all(8.0), + child: Row( + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 8), + child: Image.asset( + icon, + fit: BoxFit.cover, + height: 80, + ), + ), + Expanded( + child: Text( + desc, + style: TextStyle(fontSize: 18.0), + ), + ) + ], + ), + ), + ); + } +} 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 4e0b1391..06b59330 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/ideal_body/ideal_body.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/ideal_body/ideal_body.dart @@ -1,10 +1,10 @@ -import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; -import 'dart:math'; +import 'package:flutter/services.dart'; import 'ideal_body_result_page.dart'; @@ -24,535 +24,522 @@ class _IdealBodyState extends State { Color lbCard = inactiveCardColor; Color cmCard = activeCardColor; Color ftCard = inactiveCardColor; - int age = 0; - int height = 0; - double heightInches; - double minRange; - double maxRange; - double overWeightBy; + + // int age = 0; + // int height = 0; + double? heightInches; + double? minRange; + double? maxRange; + double? overWeightBy; int weight = 0; double idealWeight = 0; - String dropdownValue = 'Medium(fingers touch)'; + late String dropdownValue; double calories = 0; String textResult = ''; - double maxIdealWeight; - double heightFeet; + double? maxIdealWeight; + double? heightFeet; - void updateColorHeight(int type) { - //MG/DLT card - if (type == 1) { - if (cmCard == inactiveCardColor) { - cmCard = activeCardColor; - ftCard = inactiveCardColor; - } else { - cmCard = inactiveCardColor; - } - } - if (type == 2) { - if (ftCard == inactiveCardColor) { - ftCard = activeCardColor; - cmCard = inactiveCardColor; - } else { - ftCard = inactiveCardColor; - } - } - } + final GlobalKey clinicDropdownKey = GlobalKey(); + bool _isHeightCM = true; + bool _isWeightKG = true; + double _heightValue = 0; + double _weightValue = 0; - void updateColorWeight(int type) { - //MG/DLT card - if (type == 1) { - if (kgCard == inactiveCardColor) { - kgCard = activeCardColor; - lbCard = inactiveCardColor; - } else { - kgCard = inactiveCardColor; - } - } - if (type == 2) { - if (lbCard == inactiveCardColor) { - lbCard = activeCardColor; - kgCard = inactiveCardColor; - } else { - lbCard = inactiveCardColor; - } - } - } + TextEditingController _heightController = new TextEditingController(); + TextEditingController _weightController = TextEditingController(); + + List _heightPopupList = []; + List _weightPopupList = []; void calculateIdealWeight() { - heightInches = height * .39370078740157477; - heightFeet = heightInches / 12; - idealWeight = (50 + 2.3 * (heightInches - 60)); - if (dropdownValue == 'Small(fingers overlap)') { + var height = int.parse(_heightController.text); + var weight = double.parse(_weightController.text); + var inchesVal = ((height) * .39370078740157477); + var meters = height / 100; + var feetVal = (inchesVal / 12).floor().round(); + inchesVal = (inchesVal % 12).roundToDouble(); + var kgValue = (weight * 2.2).floor(); + var heightFeet = feetVal; + var heightInches = inchesVal; + weight = kgValue.floorToDouble(); + var idealWeight = (((((heightFeet * 12) + heightInches) - 60) * 6) + 106); + if (dropdownValue == TranslationBase.of(context).smallFinger) { idealWeight = idealWeight - 10; - } else if (dropdownValue == 'Medium(fingers touch)') { + } else if (dropdownValue == TranslationBase.of(context).mediumFinger) { idealWeight = idealWeight; - } else if (dropdownValue == 'Large(fingers don\'n touch)') { + } else if (dropdownValue == TranslationBase.of(context).largeFinger) { idealWeight = idealWeight + 10; } - - maxIdealWeight = (((idealWeight) * 1.1).round() * 100) / 100; - overWeightBy = weight - maxIdealWeight.roundToDouble(); - minRange = ((idealWeight / 1.1) * 10).round() / 10; - maxRange = maxIdealWeight; - idealWeight = idealWeight; + var maxIdealWeight = (((idealWeight).floorToDouble() * 1.1) * 100).round() / 100; + var overWeightBy = ((weight - double.parse(maxIdealWeight.toString())) * 100).round() / 100; + var difference = (((overWeightBy / 2.2) * 100) / 100).round(); //+ Loc.healthCalPage.IBWKg; Loc.healthCalPage.IBWRange + var minRange = ((idealWeight / 2.2) * 10).round() / 10; + var maxRange = ((maxIdealWeight / 2.2) * 100).round() / 100; //+ //Loc.healthCalPage.IBWKg; + idealWeight = weight / idealWeight; + idealWeight = (idealWeight * 100).round() / 100; + this.overWeightBy = overWeightBy; + this.minRange = minRange; + this.maxRange = maxIdealWeight; + this.idealWeight = idealWeight; } @override Widget build(BuildContext context) { + dropdownValue = TranslationBase.of(context).mediumFinger; + _weightPopupList = [PopupMenuItem(child: Text(TranslationBase.of(context).kg), value: true), PopupMenuItem(child: Text(TranslationBase.of(context).lb), value: false)]; + _heightPopupList = [PopupMenuItem(child: Text(TranslationBase.of(context).cm), value: true), PopupMenuItem(child: Text(TranslationBase.of(context).ft), value: false)]; + return AppScaffold( isShowAppBar: true, - appBarTitle: 'Ideal Body Weight', - body: Padding( - padding: EdgeInsets.symmetric(vertical: 15.0, horizontal: 25.0), - child: SingleChildScrollView( - child: Container( - height: 800.0, - child: Column( - children: [ - Padding( - padding: EdgeInsets.all(10.0), - child: Texts( - 'Calculates the ideal body weight based on height, Weight, and Body Size', - ), - ), - Divider( - thickness: 2.0, - ), - SizedBox( - height: 5.0, - ), - Column( - crossAxisAlignment: CrossAxisAlignment.start, + isShowDecPage: false, + showNewAppBarTitle: true, + showNewAppBar: true, + appBarTitle: TranslationBase.of(context).idealBody, + showHomeAppBarIcon: false, + appBarIcons: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 7.0), + child: Icon( + Icons.info_outline, + color: Colors.white, + ), + ) + ], + body: Column( + children: [ + Expanded( + child: SingleChildScrollView( + child: Container( + padding: EdgeInsets.all(21), + child: Column( children: [ - Texts( - 'Height', - ), - Row( - children: [ - Expanded( - child: Container( - width: 340.0, - height: 60.0, - decoration: BoxDecoration( - color: Colors.white, - ), - child: Row( - children: [ - Padding( - padding: EdgeInsets.symmetric( - vertical: 10.0, horizontal: 8.0), - child: Center( - child: Container( - width: 60.0, - foregroundDecoration: BoxDecoration( - borderRadius: - BorderRadius.circular(5.0), - border: Border.all( - color: Colors.blueGrey, - width: 2.0, - ), - ), - child: Row( - children: [ - Expanded( - child: Center( - child: Text(height.toString()), - ), - ), - Container( - height: 38.0, - child: Column( - crossAxisAlignment: - CrossAxisAlignment.center, - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - Container( - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - width: 0.5, - ), - ), - ), - child: InkWell( - child: Icon( - Icons.arrow_drop_up, - size: 18.0, - ), - onTap: () { - setState(() { - if (height < 250) - height++; - }); - }, - ), - ), - InkWell( - child: Icon( - Icons.arrow_drop_down, - size: 18.0, - ), - onTap: () { - setState(() { - if (height > 0) height--; - }); - }, - ), - ], - ), - ), - ], - ), - ), - ), - ), - Expanded( - child: Slider( - value: height.toDouble(), - min: 0, - max: 250, - onChanged: (double newValue) { - setState(() { - height = newValue.round(); - }); - }, - activeColor: Color(0xffC5272D), - inactiveColor: Color(0xffF3C5C6), - ), - ), - ], - ), - ), - ), - ], + Text( + TranslationBase.of(context).idealBodyWeight, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + letterSpacing: -0.56, + color: CustomColors.textColor, + ), ), - Texts('Select Unit'), SizedBox( height: 5.0, ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, + Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - GestureDetector( - onTap: () { - setState(() { - updateColorHeight(1); - isHeightCm = true; - }); + SizedBox( + height: 12.0, + ), + _commonInputAndUnitRow( + TranslationBase.of(context).height, + _heightController, + 1, + 270, + _heightValue, + (text) { + _heightController.text = text; }, - child: Container( - height: 55.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: cmCard, - borderRadius: BorderRadius.circular(3.0), - ), - child: Padding( - padding: const EdgeInsets.symmetric( - vertical: 0.0, horizontal: 18.0), - child: Center(child: Texts('CM')), - ), - ), + (value) { + _heightValue = value; + }, + _isHeightCM ? TranslationBase.of(context).cm : TranslationBase.of(context).ft, + (value) { + if (_isHeightCM != value) { + setState(() { + _isHeightCM = value; + }); + } + }, + _heightPopupList, ), - GestureDetector( - onTap: () { - setState(() { - updateColorHeight(2); - isHeightCm = false; - }); + SizedBox( + height: 12.0, + ), + _commonInputAndUnitRow( + TranslationBase.of(context).weight, + _weightController, + 1, + 270, + _weightValue, + (text) { + _weightController.text = text; }, - child: Container( - height: 55.0, - width: 150.0, - decoration: BoxDecoration( - color: ftCard, - 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: Center(child: Texts('Ft')), - ), - ), + (value) { + _weightValue = value; + }, + _isWeightKG ? TranslationBase.of(context).kg : TranslationBase.of(context).pound, + (value) { + if (_isWeightKG != value) { + setState(() { + _isWeightKG = value; + }); + } + }, + _weightPopupList, ), - ], - ), - SizedBox( - height: 45.0, - ), - Divider( - thickness: 2.0, - ), - Texts( - 'Weight', - ), - SizedBox( - height: 5.0, - ), - Row( - children: [ - Expanded( + SizedBox( + height: 12.0, + ), + InkWell( + onTap: () { + // dropdownKey.currentState; + openDropdown(clinicDropdownKey); + }, child: Container( - width: 340.0, - height: 60.0, - decoration: BoxDecoration( - color: Colors.white, - ), + // width: double.infinity, + // decoration: containerRadius(Colors.white, 12), + // padding: EdgeInsets.only(left: 10, right: 10, top: 12, bottom: 12), child: Row( children: [ - Padding( - padding: EdgeInsets.symmetric( - vertical: 10.0, horizontal: 8.0), - child: Center( - child: Container( - width: 60.0, - foregroundDecoration: BoxDecoration( - borderRadius: - BorderRadius.circular(5.0), - border: Border.all( - color: Colors.blueGrey, - width: 2.0, + Flexible( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).bodyFrameSize, + style: TextStyle( + fontSize: 11, + letterSpacing: -0.44, + fontWeight: FontWeight.w600, ), ), - child: Row( - children: [ - Expanded( - child: Center( - child: Text(weight.toString()), + Container( + height: 18, + child: DropdownButtonHideUnderline( + child: DropdownButton( + value: dropdownValue, + icon: Icon(Icons.arrow_downward), + key: clinicDropdownKey, + iconSize: 0, + elevation: 16, + isExpanded: true, + style: TextStyle(color: Colors.black87), + underline: Container( + height: 2, + color: Colors.black54, ), + onChanged: (String? newValue) { + setState(() { + dropdownValue = newValue!; + }); + }, + items: [ + TranslationBase.of(context).smallFinger, + TranslationBase.of(context).mediumFinger, + TranslationBase.of(context).largeFinger, + ].map>((String value) { + return DropdownMenuItem( + value: value, + child: Text(value), + ); + }).toList(), ), - Container( - height: 38.0, - child: Column( - crossAxisAlignment: - CrossAxisAlignment.center, - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - Container( - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - width: 0.5, - ), - ), - ), - child: InkWell( - child: Icon( - Icons.arrow_drop_up, - size: 18.0, - ), - onTap: () { - setState(() { - if (weight < 250) - weight++; - }); - }, - ), - ), - InkWell( - child: Icon( - Icons.arrow_drop_down, - size: 18.0, - ), - onTap: () { - setState(() { - if (weight > 0) weight--; - }); - }, - ), - ], - ), - ), - ], + ), ), - ), - ), - ), - Expanded( - child: Slider( - value: weight.toDouble(), - min: 0, - max: 250, - onChanged: (double newValue) { - setState(() { - weight = newValue.round(); - }); - }, - activeColor: Color(0xffC5272D), - inactiveColor: Color(0xffF3C5C6), + ], ), ), + Icon(Icons.keyboard_arrow_down), ], ), - ), + ).withBorderedContainer, ), ], ), - Texts('Select Unit'), - SizedBox( - height: 5.0, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - GestureDetector( - onTap: () { - setState(() { - updateColorWeight(1); - }); - }, - child: Container( - height: 55.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: kgCard, - borderRadius: BorderRadius.circular(3.0), - ), - child: Padding( - padding: const EdgeInsets.symmetric( - vertical: 0.0, horizontal: 18.0), - child: Center(child: Texts('KG')), - ), - ), - ), - GestureDetector( - onTap: () { - setState(() { - updateColorWeight(2); - }); - }, - child: Container( - height: 55.0, - width: 150.0, - decoration: BoxDecoration( - color: lbCard, - 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: Center(child: Texts('LB')), - ), - ), - ), - ], - ), - SizedBox( - height: 45.0, - ), - Divider( - thickness: 2.0, + ], + ), + ), + ), + ), + Container( + margin: EdgeInsets.symmetric(horizontal: 16.0, vertical: 16.0), + color: Colors.white, + child: SecondaryButton( + label: TranslationBase.of(context).calculate, + color: CustomColors.accentColor, + onTap: () { + setState(() { + calculateIdealWeight(); + { + Navigator.push( + context, + FadePage( + page: IdealBodyResult( + idealBodyWeight: idealWeight, + minRange: minRange!, + mixRange: maxRange!, + overWeightBy: overWeightBy!, + textResult: textResult, + )), + ); + } + }); + }, + ), + ), + ], + ), + ); + } + + void openDropdown(GlobalKey key) { + GestureDetector? detector; + + void searchForGestureDetector(BuildContext element) { + element.visitChildElements((element) { + if (element.widget != null && element.widget is GestureDetector) { + detector = element.widget as GestureDetector?; + //return false; + } else { + searchForGestureDetector(element); + } + + //return true; + }); + } + + searchForGestureDetector(key.currentContext!); + assert(detector != null); + + detector!.onTap!(); + } + + // void openDropdown(GlobalKey key) { + // GestureDetector detector; + // void searchForGestureDetector(BuildContext element) { + // element.visitChildElements((element) { + // if (element.widget != null && element.widget is GestureDetector) { + // detector = element.widget; + // return false; + // } else { + // searchForGestureDetector(element); + // } + // + // return true; + // }); + // } + // + // searchForGestureDetector(key.currentContext); + // assert(detector != null); + // + // detector.onTap(); + // } + + 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(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, ), - SizedBox( - height: 5.0, + ), + 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, ), - Texts('Body Frame Size'), - Container( - width: 300, - child: DropdownButton( - value: dropdownValue, - icon: Icon(Icons.arrow_downward), - iconSize: 24, - elevation: 16, - style: TextStyle(color: Colors.black87), - underline: Container( - height: 2, - color: Colors.black54, - ), - onChanged: (String newValue) { - setState(() { - dropdownValue = newValue; - }); - }, - items: [ - 'Small(fingers overlap)', - 'Medium(fingers touch)', - 'Large(fingers don\'n touch)', - ].map>((String value) { - return DropdownMenuItem( - value: value, - child: Text(value), - ); - }).toList(), + decoration: InputDecoration( + isDense: true, + hintText: _hintText, + hintStyle: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: Color(0xff575757), + 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, ), - SizedBox( - height: 30.0, - ), - Container( - height: 100.0, - width: 350.0, - child: SecondaryButton( - label: 'CALCULATE', - onTap: () { - setState(() { - // calculateBmr(); - // calculateCalories(); - calculateIdealWeight(); + ), + ], + ), + ), + if (hasSelection) Icon(Icons.keyboard_arrow_down_outlined), + ], + ), + ), + ); + } - print(idealWeight); - //print(overWeightBy); - { - Navigator.push( - context, - FadePage( - page: IdealBodyResult( - idealBodyWeight: idealWeight, - minRange: minRange, - mixRange: maxRange, - overWeightBy: overWeightBy, - textResult: textResult, - )), - ); - } - }); - }, - ), - ), - ], + Widget _commonInputAndUnitRow(_title, _controller, double _minValue, double _maxValue, double _valueOrg, Function(String) onTextValueChange, Function(double) onValueChange, String unitTitle, + Function(bool) onUnitTap, _list) { + 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( + 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, + ), + ), + ], ), ), + 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, + (val) async { + final RenderBox overlay = Overlay.of(context).context.findRenderObject() as RenderBox; + await showMenu( + context: context, + position: RelativeRect.fromRect(val.globalPosition & const Size(40, 40), Offset.zero & overlay.size), + items: _list, + elevation: 8.0, + ).then((val) { + print(val); + onUnitTap(val); + }); + }, + ), + itemBuilder: (context) => _list), + ) + ], + ).withBorderedContainer; + } +} + +// todo 'sikander' move these to separate file once usability known +class CommonDropDownView extends StatelessWidget { + final String title; + final String value; + void Function(TapDownDetails details) 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( + onTapDown: (val) => callback(val), + 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), + ) + ], ), ); } 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 605e499a..1fa9d2a9 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/ideal_body/ideal_body_result_page.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/ideal_body/ideal_body_result_page.dart @@ -1,8 +1,15 @@ -import 'package:diplomaticquarterapp/widgets/buttons/button.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/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/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 'dart:math'; class IdealBodyResult extends StatelessWidget { final double idealBodyWeight; @@ -11,160 +18,271 @@ class IdealBodyResult extends StatelessWidget { final double overWeightBy; final String textResult; - IdealBodyResult( - {this.idealBodyWeight, - this.minRange, - this.mixRange, - this.overWeightBy, - this.textResult}); + IdealBodyResult({required this.idealBodyWeight, required this.minRange, required this.mixRange, required this.overWeightBy, required 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, + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Texts( - 'Ideal weight range is', - fontSize: 23.0, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Row( - children: [ - Texts( - minRange.toStringAsFixed(1), - fontSize: 30.0, - ), - Padding( - padding: EdgeInsets.only(top: 8.0, left: 4.0), - child: Text( - 'Kg', - style: TextStyle(color: Colors.red), - ), - ), - ], - ), - Icon( - Icons.arrow_forward, - color: Colors.red, - size: 55.0, - ), - Row( - children: [ - Texts( - mixRange.toStringAsFixed(1), - fontSize: 30.0, + Padding( + padding: const EdgeInsets.all(20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).idealWeightRange, + style: TextStyle( + fontSize: 19, + letterSpacing: -1.34, + fontWeight: FontWeight.bold, ), - Padding( - padding: EdgeInsets.only(top: 8.0, left: 4.0), - child: Text( - 'Kg', - style: TextStyle(color: Colors.red), - ), - ), - ], - ), - ], - ), - overWeightBy >= 0 && overWeightBy <= 10 - ? Column( + ), + mHeight(12), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - Texts( - 'Congratulations! The current weight is\n perfect and considered healthy', - fontSize: 20.0, - ), - ], - ) - : overWeightBy > 10 && overWeightBy < 17 - ? Column( + Row( children: [ Texts( - 'This means that the weight is a little bit more than ideal weight by'), - Texts(overWeightBy.toStringAsFixed(1)), + minRange.toStringAsFixed(1), + fontSize: 30.0, + ), + Padding( + padding: EdgeInsets.only(top: 8.0, left: 4.0), + child: Text( + " " + TranslationBase.of(context).kg + " ", + style: TextStyle(color: Colors.red), + ), + ), + ], + ), + Icon( + Icons.arrow_forward, + color: Colors.red, + size: 55.0, + ), + Row( + children: [ Texts( - 'May wish to consult with the doctor for medical help. Click to view our list of Doctors'), + (mixRange / 2.2).toStringAsFixed(1), + fontSize: 30.0, + ), + Padding( + padding: EdgeInsets.only(top: 8.0, left: 4.0), + child: Text( + " " + TranslationBase.of(context).kg + " ", + style: TextStyle(color: Colors.red), + ), + ), ], - ) - : overWeightBy >= 18 - ? Container( - height: 250.0, - width: 350, - child: Column( + ), + ], + ), + mHeight(12), + overWeightBy >= 0 && overWeightBy <= 10 + ? Column( + children: [ + Texts( + TranslationBase.of(context).currentWeightPerfect, + fontSize: 20.0, + ), + ], + ) + : overWeightBy > 10 && overWeightBy < 17 + ? Column( children: [ - Texts( - 'Means that you suffer from excessive\n obesity by', - ), - SizedBox( - height: 55.0, - ), - Texts( - overWeightBy.toStringAsFixed(1), - fontSize: 40.0, - ), - 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(TranslationBase.of(context).littleBitWeightMore), + Texts(overWeightBy.toStringAsFixed(1)), + Texts(TranslationBase.of(context).consultWithDoctor), ], - ), - ) - : overWeightBy < -18 - ? Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Padding( - padding: const EdgeInsets.all(8.0), - child: Texts( - 'Under Weight', - fontSize: 18.0, - ), - ), - SizedBox( - height: 55.0, + ) + : overWeightBy >= 18 + ? Container( + child: Column( + children: [ + Texts( + TranslationBase.of(context).excessiveObesity, + ), + SizedBox( + height: 12.0, + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Texts( + (overWeightBy / 2.2).toStringAsFixed(1), + fontSize: 30.0, + ), + Padding( + padding: EdgeInsets.only(top: 8.0, left: 4.0), + child: Text( + " " + TranslationBase.of(context).kg + " ", + style: TextStyle(color: Colors.red), + ), + ), + ], + ), + SizedBox( + height: 12.0, + ), + Texts(TranslationBase.of(context).mayWish), + ], ), - Texts( - overWeightBy.toStringAsFixed(1), - fontSize: 20.0, - ), - ], - ) - : Container( - height: 250.0, - width: 350.0, - child: Column( - children: [ - Texts( - 'under wheight', - fontSize: 20.0, - ), - SizedBox( - height: 55.0, + ) + : overWeightBy < -18 + ? Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Texts( + TranslationBase.of(context).underWeight, + fontSize: 18.0, + ), + ), + SizedBox( + height: 12.0, + ), + Text( + overWeightBy.toStringAsFixed(1), + style: TextStyle( + fontSize: 17, + fontWeight: FontWeight.bold, + letterSpacing: -1.34, + ), + ), + ], + ) + : Container( + child: Column( + children: [ + Text( + TranslationBase.of(context).underWeight, + style: TextStyle( + fontSize: 17, + fontWeight: FontWeight.bold, + letterSpacing: -1.34, + ), + ), + SizedBox( + height: 12.0, + ), + Text( + overWeightBy.toStringAsFixed(1), + style: TextStyle( + fontSize: 17, + fontWeight: FontWeight.bold, + letterSpacing: -1.34, + ), + ), + SizedBox( + height: 12.0, + ), + Texts(TranslationBase.of(context).mayWish), + ], + ), ), - Texts( - overWeightBy.toStringAsFixed(1), - fontSize: 20.0, - ), - SizedBox( - height: 25.0, - ), - Texts( - 'May wish to consult with the doctor for\n medical help. Click to view our list of\n Doctors'), - ], - ), - ), + ], + ).withBorderedContainer, + ), Container( - width: 350, - child: Button( - label: 'See List Of Doctors', + margin: EdgeInsets.symmetric(horizontal: 16.0, vertical: 16.0), + color: Colors.white, + child: SecondaryButton( + label: TranslationBase.of(context).viewDocList, + color: CustomColors.accentColor, + onTap: () { + getDoctorsList(context); + }, ), ), ], ), ); } + + getDoctorsList(BuildContext context) { + GifLoaderDialogUtils.showMyDialog(context); + BariatricsService service = new BariatricsService(); + + List doctorsList = []; + List _patientDoctorAppointmentListHospital = []; + + 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, + isDoctorSearchResult: false, + ))); + } + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } +} + +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/health_calculator/ovulation_period/ovulation_period.dart b/lib/pages/AlHabibMedicalService/health_calculator/ovulation_period/ovulation_period.dart index 508e8590..c1fc6097 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/ovulation_period/ovulation_period.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/ovulation_period/ovulation_period.dart @@ -1,12 +1,14 @@ +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_datetime_picker/flutter_datetime_picker.dart'; +import 'package:flutter_datetime_picker_plus/flutter_datetime_picker_plus.dart'; import 'package:intl/intl.dart'; +import 'package:jiffy/jiffy.dart'; import 'ovulation_result_page.dart'; @@ -18,334 +20,228 @@ class OvulationPeriod extends StatefulWidget { class _OvulationPeriodState extends State { DateTime bloodSugarDate = DateTime.now(); DateTime timeSugarDate = DateTime.now(); - int cycleLength = 0; - int lutealPhaseLength = 0; - String selectedDate; + DateTime selectedDateTime = DateTime.now(); + + // int cycleLength = 0; + // int lutealPhaseLength = 0; + late String selectedDate; var dateFrom = DateTime.now(); + var babyAgeWeeks; + var babyAgeDays; var dateTo = DateTime.now(); var conceivedDate = DateTime.now(); var deliveryDue = DateTime.now(); var dt = DateTime.now(); var newFormat = DateFormat("yy-MM-dd"); - String updatedDt; + String? updatedDt; + + TextEditingController cycleLengthController = new TextEditingController(); + TextEditingController lutelLengthController = new TextEditingController(); String getTime() { return " ${timeSugarDate.hour}:${timeSugarDate.minute}"; } String getDate() { - return "${DateUtil.getMonth(bloodSugarDate.month)} ${bloodSugarDate.day}, ${bloodSugarDate.year}"; + return "${DateUtil.getMonth(selectedDateTime.month)} ${selectedDateTime.day}, ${selectedDateTime.year}"; } - // void calculate() {} - // - // void calculateFertility(DateTime selectedDate) {const diff = Date.} + calculateBabyInformation() { + setState(() { + bloodSugarDate = selectedDateTime; + dateFrom = selectedDateTime.add(Duration(days: 10)); + updatedDt = DateFormat.yMMMEd().format(dateFrom); + dateTo = selectedDateTime.add(Duration(days: 20)); + conceivedDate = selectedDateTime.add(Duration(days: 14)); + deliveryDue = selectedDateTime.add(Duration(days: 280)); + + // babyAge = Jiffy([DateTime.now()]).diff(Jiffy([date]), Units.WEEK); + + babyAgeWeeks = + Jiffy.parseFromList([DateTime.now().year, DateTime.now().month, DateTime.now().day]).diff(Jiffy.parseFromList([selectedDateTime.year, selectedDateTime.month, dateTo.day]), unit: Unit.week); + babyAgeDays = + Jiffy.parseFromList([DateTime.now().year, DateTime.now().month, DateTime.now().day]).diff(Jiffy.parseFromList([selectedDateTime.year, selectedDateTime.month, dateTo.day]), unit: Unit.day); + }); + } @override Widget build(BuildContext context) { return AppScaffold( isShowAppBar: true, - appBarTitle: 'Ovulation Period', - body: Padding( - padding: EdgeInsets.symmetric(horizontal: 25.0, vertical: 15.0), - child: SingleChildScrollView( - child: Container( - height: 700.0, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts('Calculates Ovulation Period'), - SizedBox( - height: 12.0, - ), - Divider( - //height: 2, - thickness: 2, - ), - SizedBox( - height: 12.0, - ), - InkWell( - onTap: () { - DatePicker.showDatePicker( - context, - showTitleActions: true, - minTime: DateTime(DateTime.now().year - 1, 1, 1), - maxTime: DateTime.now(), - onConfirm: (date) { - print('confirm $date'); - setState(() { - bloodSugarDate = date; - dateFrom = date.add(Duration(days: 10)); - updatedDt = DateFormat.yMMMEd().format(dateFrom); - - dateTo = date.add(Duration(days: 20)); - conceivedDate = date.add(Duration(days: 14)); - deliveryDue = date.add(Duration(days: 280)); - }); - }, - currentTime: DateTime.now(), - ); - }, - 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('Date'), - Texts(getDate()), - ], - ), - ), - ), - SizedBox( - height: 5.0, - ), - Texts( - 'Average Cycle Length (usually 28 days):', - fontWeight: FontWeight.w400, - ), - SizedBox( - height: 5.0, - ), - Row( + showNewAppBar: true, + showNewAppBarTitle: true, + isShowDecPage: false, + appBarTitle: TranslationBase.of(context).ovulation, + body: Column( + children: [ + Expanded( + child: SingleChildScrollView( + child: Container( + padding: EdgeInsets.all(21), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Container( - width: 340.0, - height: 60.0, - decoration: BoxDecoration( - color: Colors.white, + Text( + TranslationBase.of(context).ovulationDesc, + style: TextStyle( + fontSize: 14, + letterSpacing: -0.54, + color: Colors.black, + fontWeight: FontWeight.w600, ), - child: Row( - children: [ - Padding( - padding: EdgeInsets.symmetric( - vertical: 10.0, horizontal: 8.0), - child: Center( - child: Container( - width: 60.0, - foregroundDecoration: BoxDecoration( - borderRadius: BorderRadius.circular(5.0), - border: Border.all( - color: Colors.blueGrey, - width: 2.0, - ), - ), - child: Row( - children: [ - Expanded( - child: Center( - child: Text(cycleLength.toString()), - ), - ), - Container( - height: 38.0, - child: Column( - crossAxisAlignment: - CrossAxisAlignment.center, - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - Container( - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - width: 0.5, - ), - ), - ), - child: InkWell( - child: Icon( - Icons.arrow_drop_up, - size: 18.0, - ), - onTap: () { - setState(() { - if (cycleLength < 45) - cycleLength++; - }); - }, - ), - ), - InkWell( - child: Icon( - Icons.arrow_drop_down, - size: 18.0, - ), - onTap: () { - setState(() { - if (cycleLength > 0) - cycleLength--; - }); - }, - ), - ], - ), - ), - ], - ), - ), - ), - ), - Expanded( - child: Slider( - value: cycleLength.toDouble(), - min: 0, - max: 45, - onChanged: (double newValue) { - setState(() { - cycleLength = newValue.round(); - }); - }, - activeColor: Color(0xffC5272D), - inactiveColor: Color(0xffF3C5C6), - ), - ), - ], + ), + SizedBox( + height: 12.0, + ), + InkWell( + onTap: () { + DatePicker.showDatePicker( + context, + showTitleActions: true, + minTime: DateTime(DateTime.now().year - 1, 1, 1), + maxTime: DateTime.now(), + onConfirm: (date) { + print('confirm $date'); + setState(() { + selectedDateTime = date; + }); + }, + currentTime: DateTime.now(), + ); + }, + 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.0, + ), + inputWidget(TranslationBase.of(context).cycleLabel, "0", cycleLengthController), + SizedBox( + height: 12.0, + ), + inputWidget(TranslationBase.of(context).lutealLabel, "0", lutelLengthController), ], ), - Texts( - 'Average Luteal Phase Length (usually 14 days):', - fontWeight: FontWeight.w400, - ), - SizedBox( - height: 5.0, - ), - Row( - children: [ - Container( - width: 340.0, - height: 60.0, - decoration: BoxDecoration( - color: Colors.white, + ), + ), + ), + Container( + margin: EdgeInsets.symmetric(horizontal: 16.0, vertical: 16.0), + color: Colors.white, + child: SecondaryButton( + label: TranslationBase.of(context).calculate, + color: CustomColors.accentColor, + onTap: () { + calculateBabyInformation(); + Navigator.push( + context, + FadePage( + page: OvulationResult( + conceivedDate: conceivedDate, + dateFrom: dateFrom, + dateTo: dateTo, + deliveryDue: deliveryDue, + babyAge: babyAgeWeeks, + babyAgeDays: babyAgeDays, + ), + ), + ); + }, + ), + ), + ], + ), + ); + } + + 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(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: 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, + hintStyle: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: Color(0xff575757), + letterSpacing: -0.56, ), - child: Row( - children: [ - Padding( - padding: EdgeInsets.symmetric( - vertical: 10.0, horizontal: 8.0), - child: Center( - child: Container( - width: 60.0, - foregroundDecoration: BoxDecoration( - borderRadius: BorderRadius.circular(5.0), - border: Border.all( - color: Colors.blueGrey, - width: 2.0, - ), - ), - child: Row( - children: [ - Expanded( - child: Center( - child: - Text(lutealPhaseLength.toString()), - ), - ), - Container( - height: 38.0, - child: Column( - crossAxisAlignment: - CrossAxisAlignment.center, - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - Container( - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - width: 0.5, - ), - ), - ), - child: InkWell( - child: Icon( - Icons.arrow_drop_up, - size: 18.0, - ), - onTap: () { - setState(() { - if (lutealPhaseLength < 15) - lutealPhaseLength++; - }); - }, - ), - ), - InkWell( - child: Icon( - Icons.arrow_drop_down, - size: 18.0, - ), - onTap: () { - setState(() { - if (lutealPhaseLength > 0) - lutealPhaseLength--; - }); - }, - ), - ], - ), - ), - ], - ), + 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, ), ), - ), - Expanded( - child: Slider( - value: lutealPhaseLength.toDouble(), - min: 0, - max: 15, - onChanged: (double newValue) { - setState(() { - lutealPhaseLength = newValue.round(); - }); - }, - activeColor: Color(0xffC5272D), - inactiveColor: Color(0xffF3C5C6), - ), - ), - ], - ), + contentPadding: EdgeInsets.zero, + border: InputBorder.none, + focusedBorder: InputBorder.none, + enabledBorder: InputBorder.none, ), - ], - ), - SizedBox( - height: 220.0, - ), - Container( - height: 50.0, - width: 350.0, - child: SecondaryButton( - label: 'CALCULATE', - onTap: () { - setState(() { - { - Navigator.push( - context, - FadePage( - page: OvulationResult( - conceivedDate: conceivedDate, - dateFrom: dateFrom, - dateTo: dateTo, - deliveryDue: deliveryDue, - )), - ); - } - }); - }, ), - ), - ], + ], + ), ), - ), + if (hasSelection) Icon(Icons.keyboard_arrow_down_outlined), + ], ), ), ); diff --git a/lib/pages/AlHabibMedicalService/health_calculator/ovulation_period/ovulation_result_page.dart b/lib/pages/AlHabibMedicalService/health_calculator/ovulation_period/ovulation_result_page.dart index 6669bf75..8af51a3d 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/ovulation_period/ovulation_result_page.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/ovulation_period/ovulation_result_page.dart @@ -1,6 +1,15 @@ -import 'package:diplomaticquarterapp/widgets/buttons/button.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/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/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; @@ -9,88 +18,196 @@ class OvulationResult extends StatelessWidget { var dateTo; var conceivedDate; var deliveryDue; - OvulationResult( - {this.dateFrom, this.dateTo, this.deliveryDue, this.conceivedDate}); + var babyAge; + var babyAgeDays; + + OvulationResult({ + this.dateFrom, + this.dateTo, + this.deliveryDue, + this.conceivedDate, + this.babyAge, + this.babyAgeDays, + }); + //var newFormat = DateFormat("yy-MM-dd"); @override Widget build(BuildContext context) { return AppScaffold( - isShowAppBar: true, - appBarTitle: 'Ovulation Period', - body: Padding( - padding: EdgeInsets.symmetric(horizontal: 30.0, vertical: 15.0), - child: SingleChildScrollView( - child: Container( - height: 750.0, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Texts( - 'The next ovulation period is estimated to be:', - fontWeight: FontWeight.w400, - ), - Texts( - 'From:', - fontWeight: FontWeight.w400, - ), - Texts( - DateFormat.yMMMEd().format(dateFrom), - fontWeight: FontWeight.w800, - fontSize: 21.0, - ), - Texts( - 'To:', - fontWeight: FontWeight.w400, - ), - Texts( - DateFormat.yMMMEd().format(dateTo), - fontWeight: FontWeight.w800, - fontSize: 21.0, - ), - Texts( - 'Useful Information:', - color: Color(0xffC5272D), - ), - Texts( - 'You have conceived on:', - fontWeight: FontWeight.w400, - ), - Texts( - DateFormat.yMMMEd().format(conceivedDate), - fontWeight: FontWeight.w800, - fontSize: 21.0, - ), - Texts( - 'The baby\'s age right now:', - fontWeight: FontWeight.w400, - ), - Texts( - '5 Weeks, 2', - fontWeight: FontWeight.w800, - fontSize: 21.0, - ), - Texts( - 'The delivery due date is estimated to be on the: ', - fontWeight: FontWeight.w400, - ), - Texts( - DateFormat.yMMMEd().format(deliveryDue), - fontWeight: FontWeight.w800, - fontSize: 21.0, - ), - Container( - width: 350, - child: Button( - label: 'See List Of Doctors', - ), - ), - ], + showNewAppBar: true, + showNewAppBarTitle: true, + isShowDecPage: false, + appBarTitle: TranslationBase.of(context).ovulation, + body: Column( + children: [ + Expanded( + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(21), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).ovulation, + style: TextStyle( + fontSize: 19, + letterSpacing: -1.14, + fontWeight: FontWeight.w600, + ), + ), + mHeight(20), + Text( + TranslationBase.of(context).ovulationPeriod, + style: TextStyle( + fontSize: 14, + letterSpacing: -0.56, + fontWeight: FontWeight.w600, + color: CustomColors.textColor, + ), + ), + mHeight(20), + showItem(TranslationBase.of(context).from, DateFormat.yMMMEd().format(dateFrom), titleColor: CustomColors.accentColor), + mHeight(12), + showItem(TranslationBase.of(context).to, DateFormat.yMMMEd().format(dateTo), titleColor: CustomColors.accentColor), + mHeight(12), + mDivider(CustomColors.devider), + mHeight(12), + Text( + TranslationBase.of(context).useFullInfo, + style: TextStyle( + fontSize: 14, + letterSpacing: -0.56, + color: CustomColors.accentColor, + fontWeight: FontWeight.w500, + ), + ), + mHeight(12), + showItem(TranslationBase.of(context).conceive, DateFormat.yMMMEd().format(conceivedDate)), + mHeight(12), + mDivider(CustomColors.devider), + mHeight(12), + showItem(TranslationBase.of(context).babyAge, babyAge <= 0 ? TranslationBase.of(context).babyAgeAvail : babyAge.toString() + TranslationBase.of(context).week), + mHeight(12), + mDivider(CustomColors.devider), + mHeight(12), + showItem(TranslationBase.of(context).deliveryDue, DateFormat.yMMMEd().format(deliveryDue)), + ], + ).withBorderedContainer, + ), ), ), - ), + Container( + margin: EdgeInsets.symmetric(horizontal: 16.0, vertical: 16.0), + color: Colors.white, + child: SecondaryButton( + label: TranslationBase.of(context).viewDocList, + color: CustomColors.accentColor, + onTap: () { + getDoctorsList(context); + }, + ), + ), + ], + ), + ); + } + + Widget showItem(String title, String value, {Color? titleColor}) { + return Container( + width: double.infinity, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title, + style: TextStyle( + fontSize: 14, + letterSpacing: -0.56, + color: titleColor ?? Colors.black, + fontWeight: FontWeight.w500, + // fontWeight: FontWeight.w600, + ), + ), + Text( + value, + style: TextStyle( + fontSize: 18, + letterSpacing: -1.08, + fontWeight: FontWeight.w600, + ), + ), + ], ), ); } + + getDoctorsList(BuildContext context) { + GifLoaderDialogUtils.showMyDialog(context); + BariatricsService service = new BariatricsService(); + + List doctorsList = []; + List _patientDoctorAppointmentListHospital = []; + + service.getCalculationDoctors(calculationID: 6).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, isDoctorSearchResult: false,))); + } + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } +} + +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/health_converter.dart b/lib/pages/AlHabibMedicalService/health_converter.dart index 5ae80183..484b81d7 100644 --- a/lib/pages/AlHabibMedicalService/health_converter.dart +++ b/lib/pages/AlHabibMedicalService/health_converter.dart @@ -16,82 +16,76 @@ class HealthConverter extends StatefulWidget { class _HealthConverterState extends State { @override Widget build(BuildContext context) { + List myMedicalList = myOptionsList(context); + return AppScaffold( isShowAppBar: true, isShowDecPage: false, + showNewAppBar: true, + showNewAppBarTitle: true, appBarTitle: TranslationBase.of(context).converters, body: Column( children: [ - Container( - width: double.infinity, - height: 30, - ), - Row( - children: [ - Expanded( - flex: 1, - child: InkWell( - onTap: () { - Navigator.push( - context, - FadePage(page: BloodSugar()), - ); - }, - child: MedicalProfileItem( - title: TranslationBase.of(context).bloodSugar, - imagePath: 'blood_sugar_icon.png', - subTitle: TranslationBase.of(context).sugar, - ), - ), - ), - Expanded( - flex: 1, - child: InkWell( - onTap: () { - Navigator.push( - context, - FadePage( - page: BloodCholesterol(), - ), - ); - }, - child: MedicalProfileItem( - title: TranslationBase.of(context).bloodCholesterol, - imagePath: 'blood_cholesterol_icon.png', - subTitle: TranslationBase.of(context).cholesterol, - ), - ), - ), - ], + Padding( + padding: EdgeInsets.only(left: 12, right: 12, top: 20.0), + 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]; + }, + ), ), - Row( - children: [ - Expanded( - flex: 1, - child: InkWell( - onTap: () { - Navigator.push( - context, - FadePage( - page: Triglycerides(), - ), - ); - }, - child: MedicalProfileItem( - title: TranslationBase.of(context).triglycerides, - imagePath: 'triglycerides_blood_icon.png', - subTitle: TranslationBase.of(context).fatInBlood, - ), - ), - ), - Expanded( - flex: 1, - child: Container(), - ), - ], - ) ], ), ); } + + List myOptionsList(BuildContext context) { + List medical =[]; + + medical.add(InkWell( + onTap: () => Navigator.push( + context, + FadePage(page: BloodSugar()), + ), + child: MedicalProfileItem( + title: TranslationBase.of(context).bloodSugar, + imagePath: 'sugar-blood-level.svg', + subTitle: TranslationBase.of(context).sugar, + isPngImage: false, + ), + )); + + medical.add(InkWell( + onTap: () => Navigator.push( + context, + FadePage(page: BloodCholesterol()), + ), + child: MedicalProfileItem( + title: TranslationBase.of(context).bloodCholesterol, + imagePath: 'cholesterol.svg', + subTitle: TranslationBase.of(context).cholesterol, + isPngImage: false, + ), + )); + + medical.add(InkWell( + onTap: () => Navigator.push( + context, + FadePage(page: Triglycerides()), + ), + child: MedicalProfileItem( + title: TranslationBase.of(context).triglycerides, + imagePath: 'fat.svg', + subTitle: TranslationBase.of(context).fatInBlood, + 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 513b50ab..29531d6d 100644 --- a/lib/pages/AlHabibMedicalService/health_converter/blood_cholesterol.dart +++ b/lib/pages/AlHabibMedicalService/health_converter/blood_cholesterol.dart @@ -1,14 +1,13 @@ +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:flutter/material.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/button.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(0xff70777A); -const inactiveCardColor = Color(0xffFAFAFd); +const activeCardColor = CustomColors.green; +const inactiveCardColor = CustomColors.white; class BloodCholesterol extends StatefulWidget { @override @@ -20,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; @@ -53,224 +51,246 @@ class _BloodCholesterolState extends State { bool _visible = false; TextEditingController textController = new TextEditingController(); - String finalValue; + TextEditingController resultTextController = new TextEditingController(); + late String finalValue; double inputValue = 0.0; - String unit; + late 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, - //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).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, - ), - child: TextFormField( - controller: textController, - inputFormatters: [ -// FilteringTextInputFormatter.digitsOnly - ], - keyboardType: TextInputType.number, - decoration: InputDecoration( - border: OutlineInputBorder( - borderSide: BorderSide(color: Colors.black45)), - labelText: TranslationBase.of(context).enterReadingValue, - labelStyle: TextStyle( - color: Colors.black87, - ), + ), + 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, ), ), - ), - 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), + TextField( + enabled: isEnable, + scrollPadding: EdgeInsets.zero, + keyboardType: TextInputType.numberWithOptions(decimal: true), + controller: _controller, + onChanged: (value) => {}, + style: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: Color(0xff2B353E), + letterSpacing: -0.44, ), - 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), - ), - 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, - ), - ), - ), - ], - ), - ], + 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, ), ), - ), - 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(); - }); - }, - ), - ), - ), - ], + ], + ), ), - ), + 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 8a7e9792..bbdb0f73 100644 --- a/lib/pages/AlHabibMedicalService/health_converter/blood_sugar.dart +++ b/lib/pages/AlHabibMedicalService/health_converter/blood_sugar.dart @@ -1,28 +1,30 @@ +import 'package:diplomaticquarterapp/theme/colors.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'; +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 activeTextColor = CustomColors.black; +const inactiveCardColor = CustomColors.white; +const inactiveTextColor = CustomColors.black; class BloodSugar extends StatefulWidget { @override _BloodSugarState createState() => _BloodSugarState(); } -Color color; +Color? color; class _BloodSugarState extends State { Color cardMGColor = inactiveCardColor; Color cardMMOLColor = inactiveCardColor; + Color textMGColor = inactiveTextColor; + Color textMMOLColor = inactiveTextColor; void updateColor(int type) { - //MG/DLT card if (type == 1) { if (cardMGColor == inactiveCardColor) { cardMGColor = activeCardColor; @@ -30,6 +32,8 @@ class _BloodSugarState extends State { } else { cardMGColor = inactiveCardColor; } + textMGColor = activeTextColor; + textMMOLColor = inactiveTextColor; } if (type == 2) { if (cardMMOLColor == inactiveCardColor) { @@ -38,207 +42,151 @@ class _BloodSugarState extends State { } else { cardMMOLColor = inactiveCardColor; } + textMGColor = inactiveTextColor; + textMMOLColor = activeTextColor; } } void calculateBloodSugar() { + if (textController.text.isEmpty) return; if (cardMGColor == activeCardColor) { inputValue = double.parse(textController.text); - inputValue = inputValue / 15; + inputValue = inputValue / 18; unit = 'mmol/l'; } else if (cardMMOLColor == activeCardColor) { inputValue = double.parse(textController.text); inputValue = inputValue * 18; unit = 'mg/dlt'; } + setState(() {}); } bool _visible = false; TextEditingController textController = new TextEditingController(); - String finalValue; + TextEditingController resultTextController = new TextEditingController(); + late String finalValue; double inputValue = 0; - String unit; + late String unit; + + @override + void initState() { + updateColor(1); + unit = 'mmol/l'; + super.initState(); + } @override Widget build(BuildContext context) { return AppScaffold( isShowAppBar: true, + isShowDecPage: false, + showNewAppBar: true, + showNewAppBarTitle: true, appBarTitle: TranslationBase.of(context).bloodSugarConversion, - body: Padding( + body: Container( 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).convertBloodSugarStatement, - //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, - children: [ - Padding( - padding: const EdgeInsets.symmetric(horizontal: 15.0), - child: Row( - children: [ - Texts( - TranslationBase.of(context).convertFrom, - ) - ], - ), - ), - SizedBox( - height: 9.0, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - GestureDetector( - onTap: () { - setState(() { - updateColor(1); - inputValue = - double.parse(textController.text); - inputValue = inputValue / 15; - 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'), - ), - ), - ), - GestureDetector( - onTap: () { - setState(() { - updateColor(2); - inputValue = - double.parse(textController.text); - inputValue = inputValue * 18; - 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: Column( + children: [ + 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.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: 25.0, - ), - Container( - height: 65.0, - 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, - border: OutlineInputBorder( - borderSide: BorderSide(color: Colors.black45)), - labelStyle: TextStyle( - color: Colors.black87, - ), + SizedBox( + height: 12.0, ), - ), - ), - 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), + Container( child: Column( crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.center, children: [ - Texts(TranslationBase.of(context).result + ": "), + 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: [ - Text( - inputValue.toStringAsFixed(3), - style: TextStyle(fontSize: 35.0), + Expanded( + child: GestureDetector( + onTap: () { + setState(() { + updateColor(1); + calculateBloodSugar(); + }); + }, + 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), + ), + ), + ), + ), ), - 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( + 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), + ), + 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), + ), + ), ), ), ), @@ -247,31 +195,119 @@ class _BloodSugarState extends State { ], ), ), - ), - ), - SizedBox( - height: 30.0, + 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), + ), + ], ), - Flexible( - child: Container( - height: 60.0, - width: 150.0, - child: SecondaryButton( - label: TranslationBase.of(context).calculate, - onTap: () { - 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.numberWithOptions(decimal: true), + 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 4c5f9a83..8fd454e8 100644 --- a/lib/pages/AlHabibMedicalService/health_converter/triglycerides.dart +++ b/lib/pages/AlHabibMedicalService/health_converter/triglycerides.dart @@ -1,16 +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/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; - -import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; -import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.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 @@ -20,7 +17,8 @@ class Triglycerides extends StatefulWidget { class _TriglyceridesState extends State { Color cardMGColor = inactiveCardColor; Color cardMMOLColor = inactiveCardColor; - int type; + late int type; + void updateColor(type) { //MG/DLT card if (type == 1) { @@ -55,223 +53,250 @@ class _TriglyceridesState extends State { bool _visible = false; TextEditingController textController = new TextEditingController(); - String finalValue; + TextEditingController resultTextController = new TextEditingController(); + late String finalValue; double inputValue = 0.0; - String unit; + late String unit; double conversionConst = 88.57; + @override + void initState() { + updateColor(1); + unit = 'mmol/l'; + super.initState(); + } + @override Widget build(BuildContext context) { return AppScaffold( isShowAppBar: true, appBarTitle: TranslationBase.of(context).triglycerides, + 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).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, - ), - child: TextFormField( - controller: textController, - inputFormatters: [ -// FilteringTextInputFormatter.digitsOnly - ], - keyboardType: TextInputType.number, - decoration: InputDecoration( - border: OutlineInputBorder( - borderSide: BorderSide(color: Colors.black45)), - labelText: TranslationBase.of(context).enterReadingValue, - labelStyle: TextStyle( - color: Colors.black87, - ), + ), + 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, ), ), - ), - 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), + TextField( + enabled: isEnable, + scrollPadding: EdgeInsets.zero, + keyboardType: TextInputType.numberWithOptions(decimal: true), + controller: _controller, + onChanged: (value) => {}, + style: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: Color(0xff2B353E), + letterSpacing: -0.44, ), - 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, - ), - ), - ), - ], - ), - ], + 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, ), ), - ), - 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(); - }); - }, - ), - ), - ), - ], + ], + ), ), - ), + if (hasSelection) Icon(Icons.keyboard_arrow_down_outlined), + ], ), ), ); diff --git a/lib/pages/AlHabibMedicalService/my_web_view.dart b/lib/pages/AlHabibMedicalService/my_web_view.dart index 59163c15..bd824cd4 100644 --- a/lib/pages/AlHabibMedicalService/my_web_view.dart +++ b/lib/pages/AlHabibMedicalService/my_web_view.dart @@ -1,37 +1,60 @@ import 'dart:async'; + import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/material.dart'; - import 'package:webview_flutter/webview_flutter.dart'; -class MyWebView extends StatelessWidget { +class MyWebView extends StatefulWidget { final String title; final String selectedUrl; - final Completer _controller = - Completer(); - MyWebView({ - @required this.title, - @required this.selectedUrl, + required this.title, + required this.selectedUrl, }); @override - Widget build(BuildContext context) { - return AppScaffold( - isShowAppBar: true, - appBarTitle: title, + State createState() => _MyWebViewState(); +} - body: - WebView( - initialUrl: selectedUrl, - javascriptMode: JavascriptMode.unrestricted, - onWebViewCreated: (WebViewController webViewController) { - _controller.complete(webViewController); - }, - ) +class _MyWebViewState extends State { + // final Completer _controller = Completer(); + late final WebViewController _controller; + @override + void initState() { + super.initState(); + _controller = WebViewController() + ..setJavaScriptMode(JavaScriptMode.unrestricted) + ..setNavigationDelegate( + NavigationDelegate( + onProgress: (int progress) { + // Update loading bar. + }, + onPageStarted: (String url) {}, + onPageFinished: (String url) {}, + onHttpError: (HttpResponseError error) {}, + onWebResourceError: (WebResourceError error) {}, + onNavigationRequest: (NavigationRequest request) { + if (request.url.startsWith('https://www.youtube.com/')) { + return NavigationDecision.prevent; + } + return NavigationDecision.navigate; + }, + ), + ) + ..loadRequest(Uri.parse(widget.selectedUrl)); + } - ); + @override + Widget build(BuildContext context) { + return AppScaffold(isShowAppBar: true, appBarTitle: widget.title, isShowDecPage: false, showNewAppBar: true, showNewAppBarTitle: true, body: WebViewWidget(controller: _controller) + // WebView( + // initialUrl: widget.selectedUrl, + // javascriptMode: JavascriptMode.unrestricted, + // onWebViewCreated: (WebViewController webViewController) { + // _controller.complete(webViewController); + // }, + ); } -} \ No newline at end of file +} diff --git a/lib/pages/AlHabibMedicalService/parking_page.dart b/lib/pages/AlHabibMedicalService/parking_page.dart index 82c390ea..9f2216b5 100644 --- a/lib/pages/AlHabibMedicalService/parking_page.dart +++ b/lib/pages/AlHabibMedicalService/parking_page.dart @@ -1,31 +1,38 @@ -import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/qr_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.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:maps_launcher/maps_launcher.dart'; +import 'package:provider/provider.dart'; import '../../d_q_icons_icons.dart'; class ParkingPage extends StatelessWidget { @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); return BaseView( onModelReady: (model) => model.getIsSaveParking(), builder: (_, model, widget) => AppScaffold( isShowAppBar: true, + showNewAppBar: true, + showNewAppBarTitle: true, appBarTitle: TranslationBase.of(context).parking, + description: TranslationBase.of(context).parkingDescription, + imagesInfo: [ImagesInfo(imageAr: 'assets/images/bc_parking.png', imageEn: 'assets/images/bc_parking.png', isAsset: true)], body: SingleChildScrollView( padding: EdgeInsets.all(12), child: !model.isSavePark ? Column( children: [ Texts( - TranslationBase.of(context).parkingTitle, + TranslationBase.of(context).parkingDescription, fontWeight: FontWeight.normal, fontSize: 15, ), @@ -43,7 +50,9 @@ class ParkingPage extends StatelessWidget { Row( children: [ Expanded( - child: Container(child: Icon(/*Icons.landscape*/DQIcons.parking_icon,size: 130),), + child: Container( + child: Icon(/*Icons.landscape*/ DQIcons.parking_icon, size: 130), + ), ), SizedBox( width: 15, @@ -52,19 +61,16 @@ class ParkingPage extends StatelessWidget { child: Container( height: 150, padding: EdgeInsets.all(8), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - color: Colors.white, - shape: BoxShape.rectangle), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(10), color: Colors.white, shape: BoxShape.rectangle), child: Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ - Texts(model.qrParkingModel.parkingDescriptionN), + Texts(model.qrParkingModel!.parkingDescriptionN), Divider( height: 3, ), - Texts(model.qrParkingModel.rowDescriptionN) + Texts(model.qrParkingModel!.rowDescriptionN) ], ), ), @@ -77,16 +83,13 @@ class ParkingPage extends StatelessWidget { Container( padding: EdgeInsets.all(8), width: double.infinity, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - color: Colors.white, - shape: BoxShape.rectangle), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(10), color: Colors.white, shape: BoxShape.rectangle), height: 70, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Texts(TranslationBase.of(context).showMyPark), - Texts(model.qrParkingModel.floorDescriptionN), + Texts(projectViewModel.isArabic ? model.qrParkingModel!.floorDescriptionN : model.qrParkingModel!.floorDescription), ], ), ), @@ -94,10 +97,7 @@ class ParkingPage extends StatelessWidget { height: 15, ), Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - color: Colors.white, - shape: BoxShape.rectangle), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(10), color: Colors.white, shape: BoxShape.rectangle), padding: EdgeInsets.all(8), width: double.infinity, height: 70, @@ -105,7 +105,7 @@ class ParkingPage extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Texts(TranslationBase.of(context).gate), - Texts(model.qrParkingModel.gateDescriptionN), + Texts(projectViewModel.isArabic ? model.qrParkingModel!.gateDescriptionN : model.qrParkingModel!.gateDescription), ], ), ), @@ -113,10 +113,7 @@ class ParkingPage extends StatelessWidget { height: 15, ), Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - color: Colors.white, - shape: BoxShape.rectangle), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(10), color: Colors.white, shape: BoxShape.rectangle), padding: EdgeInsets.all(8), width: double.infinity, height: 70, @@ -124,7 +121,7 @@ class ParkingPage extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Texts(TranslationBase.of(context).building), - Texts(model.qrParkingModel.buildingDescriptionN), + Texts(projectViewModel.isArabic ? model.qrParkingModel!.buildingDescriptionN : model.qrParkingModel!.buildingDescription), ], ), ), @@ -133,17 +130,14 @@ class ParkingPage extends StatelessWidget { ), Container( padding: EdgeInsets.all(8), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - color: Colors.white, - shape: BoxShape.rectangle), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(10), color: Colors.white, shape: BoxShape.rectangle), width: double.infinity, height: 70, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Texts(TranslationBase.of(context).branch), - Texts(model.qrParkingModel.branchDescriptionN), + Texts(projectViewModel.isArabic ? model.qrParkingModel!.branchDescriptionN : model.qrParkingModel!.branchDescription), ], ), ), @@ -155,19 +149,14 @@ class ParkingPage extends StatelessWidget { ), bottomSheet: !model.isSavePark ? Container( + color: Theme.of(context).scaffoldBackgroundColor, height: MediaQuery.of(context).size.height * 0.10, width: double.infinity, child: Column( children: [ Container( width: MediaQuery.of(context).size.width * 0.9, - child: SecondaryButton( - onTap: () async { - model.readQr(); - }, - label: TranslationBase.of(context).readBarcode, - loading: model.state == ViewState.BusyLocal, - textColor: Theme.of(context).backgroundColor), + child: DefaultButton(TranslationBase.of(context).readBarcode, () => {model.readQr()}), ), ], ), @@ -180,16 +169,14 @@ class ParkingPage extends StatelessWidget { children: [ Container( width: MediaQuery.of(context).size.width * 0.9, - child: SecondaryButton( - onTap: () async { - MapsLauncher.launchCoordinates( - model.qrParkingModel.latitude, - model.qrParkingModel.longitude, - ); - }, - disabled: model.qrParkingModel.longitude == 0, - label: TranslationBase.of(context).showMyPark, - textColor: Theme.of(context).backgroundColor), + child: DefaultButton( + TranslationBase.of(context).showMyPark, + () => { + MapsLauncher.launchCoordinates( + model.qrParkingModel!.latitude!, + model.qrParkingModel!.longitude!, + ), + }), ), SizedBox( height: 12, diff --git a/lib/pages/AlHabibMedicalService/​ health_calculators.dart b/lib/pages/AlHabibMedicalService/​ health_calculators.dart index dbd8939c..1fb64dde 100644 --- a/lib/pages/AlHabibMedicalService/​ health_calculators.dart +++ b/lib/pages/AlHabibMedicalService/​ health_calculators.dart @@ -1,18 +1,17 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/health_calculator/body_fat/body_fat.dart'; -import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/health_calculator/bmi_calculator/bmi_calculator.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/health_calculator/calorie_calculator/calorie_calculator.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/health_calculator/carbs/carbs.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/health_calculator/ovulation_period/ovulation_period.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/data_display/medical/medical_profile_item.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 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:provider/provider.dart'; import 'health_calculator/bmi_calculator/bmi_calculator.dart'; import 'health_calculator/bmr_calculator/bmr_calculator.dart'; -import 'health_calculator/calorie_calculator/calorie_calculator.dart'; import 'health_calculator/delivery_due/delivery_due.dart'; import 'health_calculator/ideal_body/ideal_body.dart'; @@ -21,9 +20,9 @@ class HealthCalculators extends StatefulWidget { _HealthCalculatorsState createState() => _HealthCalculatorsState(); } -class _HealthCalculatorsState extends State - with SingleTickerProviderStateMixin { - TabController _tabController; +class _HealthCalculatorsState extends State with SingleTickerProviderStateMixin { + late TabController _tabController; + void initState() { super.initState(); _tabController = TabController(length: 2, vsync: this); @@ -36,257 +35,219 @@ class _HealthCalculatorsState extends State @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + + List generalHealthList = getGeneralHealthList(context); + List womenHealthList = getWomenHealthList(context); + return AppScaffold( isShowAppBar: true, isShowDecPage: false, + showNewAppBar: true, + showNewAppBarTitle: true, appBarTitle: TranslationBase.of(context).calculators, - body: Scaffold( - extendBodyBehindAppBar: true, - appBar: PreferredSize( - preferredSize: Size.fromHeight(70.0), - child: Stack( - children: [ - Center( - child: Container( - height: 60.0, - margin: EdgeInsets.only(top: 10.0), - width: MediaQuery.of(context).size.width * 1.9, - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Theme.of(context).dividerColor, - width: 5.7, - ), - ), - color: Colors.white, - ), - child: Center( - child: TabBar( - controller: _tabController, - isScrollable: true, - indicatorWeight: 4.0, - indicatorColor: Colors.red, - labelColor: Theme.of(context).buttonColor, - labelPadding: - EdgeInsets.symmetric(horizontal: 13.0, vertical: 2.0), - unselectedLabelColor: Colors.grey, - tabs: [ - Container( - width: MediaQuery.of(context).size.width * 0.35, - child: Center( - child: Texts( - TranslationBase.of(context).generalHealth), - ), - ), - Container( - width: MediaQuery.of(context).size.width * 0.35, - child: Center( - child: - Texts(TranslationBase.of(context).womanHealth), - ), - ), - ], - ), - ), + body: Column( + children: [ + TabBar( + controller: _tabController, + indicatorWeight: 3.0, + indicatorSize: TabBarIndicatorSize.tab, + labelColor: Color(0xff2B353E), + unselectedLabelColor: Color(0xff575757), + labelPadding: EdgeInsets.only(top: 15, bottom: 13, 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: [ + Container( + width: MediaQuery.of(context).size.width * 0.35, + child: Center( + child: Text(TranslationBase.of(context).generalHealth), + ), + ), + Container( + width: MediaQuery.of(context).size.width * 0.35, + child: Center( + child: Text(TranslationBase.of(context).womanHealth), ), - ) + ), ], ), - ), - body: Column( - children: [ - Expanded( - child: TabBarView( - physics: BouncingScrollPhysics(), - controller: _tabController, - children: [ - Container( - child: Column( - children: [ - Container( - width: double.infinity, - height: 80, - ), - Row( - children: [ - Expanded( - flex: 1, - child: InkWell( - onTap: () { - Navigator.push( - context, - FadePage(page: BMICalculator()), - ); - }, - child: MedicalProfileItem( - title: TranslationBase.of(context).bmi, - imagePath: 'bmi_health_calculator.png', - subTitle: - TranslationBase.of(context).calcHealth, - ), - ), - ), - Expanded( - flex: 1, - child: InkWell( - onTap: () { - Navigator.push( - context, - FadePage( - page: CalorieCalculator(), - ), - ); - }, - child: MedicalProfileItem( - title: TranslationBase.of(context).calories, - imagePath: 'calories-calculator.png', - subTitle: - TranslationBase.of(context).calcHealth, - ), - ), - ), - ], - ), - Row( - children: [ - Expanded( - flex: 1, - child: InkWell( - onTap: () { - Navigator.push( - context, - FadePage( - page: BmrCalculator(), - ), - ); - }, - child: MedicalProfileItem( - title: TranslationBase.of(context).bmr, - imagePath: 'BMR_calculator.png', - subTitle: - TranslationBase.of(context).calcHealth, - ), - ), - ), - Expanded( - flex: 1, - child: InkWell( - onTap: () { - Navigator.push( - context, - FadePage( - page: IdealBody(), - ), - ); - }, - child: MedicalProfileItem( - title: TranslationBase.of(context).idealBody, - imagePath: 'body_weight.png', - subTitle: TranslationBase.of(context).weight, - ), - ), - ), - ], + Expanded( + child: TabBarView( + physics: NeverScrollableScrollPhysics(), + controller: _tabController, + children: [ + Container( + // margin: EdgeInsets.all(20.0), + child: Column( + children: [ + Padding( + padding: EdgeInsets.only(left: 12, right: 12, top: 20.0), + child: GridView.builder( + shrinkWrap: true, + primary: false, + physics: NeverScrollableScrollPhysics(), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, childAspectRatio: 2 / 2, crossAxisSpacing: 12, mainAxisSpacing: 12), + padding: EdgeInsets.zero, + itemCount: generalHealthList.length, + itemBuilder: (BuildContext context, int index) { + return generalHealthList[index]; + }, ), - Row( - children: [ - Expanded( - flex: 1, - child: InkWell( - onTap: () { - Navigator.push( - context, - FadePage( - page: BodyFat(), - ), - ); - }, - child: MedicalProfileItem( - title: TranslationBase.of(context).bodyWord, - imagePath: 'body_fat.png', - subTitle: TranslationBase.of(context).fat, - ), - ), - ), - Expanded( - flex: 1, - child: InkWell( - onTap: () { - Navigator.push( - context, - FadePage( - page: Carbs(), - ), - ); - }, - child: MedicalProfileItem( - title: - TranslationBase.of(context).carbohydrate, - imagePath: 'carb_protein.png', - subTitle: - TranslationBase.of(context).proteinFat, - ), - ), - ), - ], - ), - ], - ), + ), + ], ), - Container( - child: Column( - children: [ - Container( - width: double.infinity, - height: 80, - ), - Row( - children: [ - Expanded( - flex: 1, - child: InkWell( - onTap: () { - Navigator.push( - context, - FadePage(page: OvulationPeriod()), - ); - }, - child: MedicalProfileItem( - title: TranslationBase.of(context).ovulation, - imagePath: 'ovulation_period_icon.png', - subTitle: TranslationBase.of(context).period, - ), - ), - ), - Expanded( - flex: 1, - child: InkWell( - onTap: () { - Navigator.push( - context, - FadePage( - page: DeliveryDue(), - ), - ); - }, - child: MedicalProfileItem( - title: TranslationBase.of(context).delivery, - imagePath: 'delivery_date_icon.png', - subTitle: TranslationBase.of(context).dueDate, - ), - ), - ), - ], + ), + Container( + // margin: EdgeInsets.all(20.0), + child: Column( + children: [ + Padding( + padding: EdgeInsets.only(left: 12, right: 12, top: 20.0), + child: GridView.builder( + shrinkWrap: true, + primary: false, + physics: NeverScrollableScrollPhysics(), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, childAspectRatio: 2 / 2, crossAxisSpacing: 12, mainAxisSpacing: 12), + padding: EdgeInsets.zero, + itemCount: womenHealthList.length, + itemBuilder: (BuildContext context, int index) { + return womenHealthList[index]; + }, ), - ], - ), + ), + ], ), - ], - ), - ) - ], - ), + ), + ], + ), + ), + ], ), ); } + + List getGeneralHealthList(BuildContext context) { + List medical =[]; + + medical.add(InkWell( + onTap: () => Navigator.push( + context, + FadePage(page: BMICalculator()), + ), + child: MedicalProfileItem( + title: TranslationBase.of(context).bmi, + imagePath: 'bmi.svg', + subTitle: TranslationBase.of(context).calcHealth, + + ), + )); + + medical.add(InkWell( + onTap: () => Navigator.push( + context, + FadePage(page: CalorieCalculator()), + ), + child: MedicalProfileItem( + title: TranslationBase.of(context).calories, + imagePath: 'calories_calc.svg', + subTitle: TranslationBase.of(context).calcHealth, + + ), + )); + + medical.add(InkWell( + onTap: () => Navigator.push( + context, + FadePage(page: BmrCalculator()), + ), + child: MedicalProfileItem( + title: TranslationBase.of(context).bmr, + imagePath: 'bmr_calc.svg', + subTitle: TranslationBase.of(context).calcHealth, + + ), + )); + + medical.add(InkWell( + onTap: () => Navigator.push( + context, + FadePage(page: IdealBody()), + ), + child: MedicalProfileItem( + title: TranslationBase.of(context).idealBody, + imagePath: 'ideal_weight_calc.svg', + subTitle: TranslationBase.of(context).weight, + + ), + )); + + medical.add(InkWell( + onTap: () => Navigator.push( + context, + FadePage(page: BodyFat()), + ), + child: MedicalProfileItem( + title: TranslationBase.of(context).bodyWord, + imagePath: 'bmr_calc.svg', + subTitle: TranslationBase.of(context).fat, + + ), + )); + + medical.add(InkWell( + onTap: () => Navigator.push( + context, + FadePage(page: Carbs()), + ), + child: MedicalProfileItem( + title: TranslationBase.of(context).carbohydrate, + imagePath: 'carbs_proteitn_fat.svg', + subTitle: TranslationBase.of(context).proteinFat, + + ), + )); + + return medical; + } + + List getWomenHealthList(BuildContext context) { + List medical =[]; + + medical.add(InkWell( + onTap: () => Navigator.push( + context, + FadePage(page: OvulationPeriod()), + ), + child: MedicalProfileItem( + title: TranslationBase.of(context).ovulation, + imagePath: 'ovulation.svg', + subTitle: TranslationBase.of(context).period, + ), + )); + + medical.add(InkWell( + onTap: () => Navigator.push( + context, + FadePage(page: DeliveryDue()), + ), + child: MedicalProfileItem( + title: TranslationBase.of(context).delivery, + imagePath: 'delivery.svg', + subTitle: TranslationBase.of(context).dueDate, + ), + )); + + return medical; + } } diff --git a/lib/pages/Blood/advance_payment_page.dart b/lib/pages/Blood/advance_payment_page.dart deleted file mode 100644 index dd3ea666..00000000 --- a/lib/pages/Blood/advance_payment_page.dart +++ /dev/null @@ -1,397 +0,0 @@ -// import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; -// import 'package:diplomaticquarterapp/core/enum/viewstate.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'; -// import 'package:diplomaticquarterapp/core/viewModels/medical/my_balance_view_model.dart'; -// import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; -// 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/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/buttons/secondary_button.dart'; -// import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; -// import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -// import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; -// import 'package:flutter/cupertino.dart'; -// import 'package:flutter/material.dart'; -// import 'package:smart_progress_bar/smart_progress_bar.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 } -// -// class AdvancePaymentPage extends StatefulWidget { -// @override -// _AdvancePaymentPageState createState() => _AdvancePaymentPageState(); -// } -// -// class _AdvancePaymentPageState extends State { -// TextEditingController _fileTextController = TextEditingController(); -// TextEditingController _notesTextController = TextEditingController(); -// BeneficiaryType beneficiaryType = BeneficiaryType.NON; -// HospitalsModel _selectedHospital; -// String amount = ""; -// String email; -// PatientInfo _selectedPatientInfo; -// AuthenticatedUser authenticatedUser; -// GetAllSharedRecordsByStatusList selectedPatientFamily; -// AdvanceModel advanceModel = AdvanceModel(); -// -// AppSharedPreferences sharedPref = AppSharedPreferences(); -// AuthenticatedUser authUser; -// -// @override -// void initState() { -// super.initState(); -// getAuthUser(); -// } -// -// @override -// Widget build(BuildContext context) { -// return BaseView( -// onModelReady: (model) => model.getHospitals(), -// builder: (_, model, w) => AppScaffold( -// isShowAppBar: true, -// appBarTitle: TranslationBase.of(context).advancePayment, -// body: SingleChildScrollView( -// physics: ScrollPhysics(), -// child: Container( -// margin: EdgeInsets.all(12), -// child: Column( -// crossAxisAlignment: CrossAxisAlignment.start, -// children: [ -// Texts( -// TranslationBase.of(context).advancePaymentLabel, -// textAlign: TextAlign.center, -// ), -// SizedBox( -// height: 12, -// ), -// InkWell( -// onTap: () => confirmSelectBeneficiaryDialog(model), -// 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(getBeneficiaryType()), -// Icon(Icons.arrow_drop_down) -// ], -// ), -// ), -// ), -// if (beneficiaryType == BeneficiaryType.MyFamilyFiles) -// SizedBox( -// height: 12, -// ), -// if (beneficiaryType == BeneficiaryType.MyFamilyFiles) -// InkWell( -// onTap: () { -// model.getFamilyFiles().then((value) { -// confirmSelectFamilyDialog(model -// .getAllSharedRecordsByStatusResponse -// .getAllSharedRecordsByStatusList); -// }).showProgressBar( -// text: "Loading", -// backgroundColor: Colors.blue.withOpacity(0.6)); -// }, -// 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(getFamilyMembersName()), -// Icon(Icons.arrow_drop_down) -// ], -// ), -// ), -// ), -// SizedBox( -// height: 12, -// ), -// NewTextFields( -// hintText: TranslationBase.of(context).fileNumber, -// controller: _fileTextController, -// ), -// if (beneficiaryType == BeneficiaryType.OtherAccount) -// SizedBox( -// height: 12, -// ), -// if (beneficiaryType == BeneficiaryType.OtherAccount) -// InkWell( -// onTap: () { -// if (_fileTextController.text.isNotEmpty) -// model -// .getPatientInfoByPatientID( -// id: _fileTextController.text) -// .then((value) { -// confirmSelectPatientDialog(model.patientInfoList); -// }).showProgressBar( -// text: "Loading", -// backgroundColor: -// Colors.blue.withOpacity(0.6)); -// else -// AppToast.showErrorToast( -// message: 'Please Enter The File Number'); -// }, -// 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(getPatientName()), -// Icon(Icons.arrow_drop_down) -// ], -// ), -// ), -// ), -// SizedBox( -// height: 12, -// ), -// InkWell( -// onTap: () => confirmSelectHospitalDialog(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()), -// Icon(Icons.arrow_drop_down) -// ], -// ), -// ), -// ), -// SizedBox( -// height: 12, -// ), -// NewTextFields( -// hintText: TranslationBase.of(context).amount, -// keyboardType: TextInputType.number, -// onChanged: (value) { -// setState(() { -// amount = value; -// }); -// }, -// ), -// SizedBox( -// height: 12, -// ), -// NewTextFields( -// hintText: TranslationBase.of(context).depositorEmail, -// initialValue: model.user.emailAddress, -// onChanged: (value) { -// email = value; -// }, -// ), -// SizedBox( -// height: 12, -// ), -// NewTextFields( -// hintText: TranslationBase.of(context).notes, -// controller: _notesTextController, -// ), -// SizedBox( -// height: MediaQuery.of(context).size.height * 0.15, -// ) -// ], -// ), -// ), -// ), -// bottomSheet: Container( -// height: MediaQuery.of(context).size.height * 0.1, -// width: double.infinity, -// padding: EdgeInsets.all(12), -// child: SecondaryButton( -// textColor: Colors.white, -// label: TranslationBase.of(context).submit, -// disabled: amount.isEmpty || -// _fileTextController.text.isEmpty || -// _selectedHospital == null, -// onTap: () { -// advanceModel.fileNumber = _fileTextController.text; -// advanceModel.hospitalsModel = _selectedHospital; -// advanceModel.note = _notesTextController.text; -// advanceModel.email = email ?? model.user.emailAddress; -// advanceModel.amount = amount; -// -// model.getPatientInfoByPatientIDAndMobileNumber().then((value) { -// if (model.state != ViewState.Error && -// model.state != ViewState.ErrorLocal) { -// Utils.hideKeyboard(context); -// Navigator.push( -// context, -// MaterialPageRoute( -// builder: (context) => PaymentMethod())).then( -// (value) { -// Navigator.push( -// context, -// FadePage( -// page: ConfirmPaymentPage( -// advanceModel: advanceModel, -// selectedPaymentMethod: value, -// patientInfoAndMobileNumber: -// model.patientInfoAndMobileNumber, -// authenticatedUser: authUser, -// ), -// ), -// ); -// }, -// ); -// } -// }).showProgressBar( -// text: "Loading", -// backgroundColor: Colors.blue.withOpacity(0.6)); -// }, -// ), -// )), -// ); -// } -// -// 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 confirmSelectHospitalDialog(List hospitals) { -// showDialog( -// context: context, -// child: SelectHospitalDialog( -// hospitals: hospitals, -// selectedHospital: _selectedHospital, -// onValueSelected: (value) { -// setState(() { -// _selectedHospital = 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 getHospitalName() { -// if (_selectedHospital != null) -// return _selectedHospital.name; -// else -// return 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; -// } -// } diff --git a/lib/pages/Blood/blood_donation.dart b/lib/pages/Blood/blood_donation.dart index adff790c..a3a51207 100644 --- a/lib/pages/Blood/blood_donation.dart +++ b/lib/pages/Blood/blood_donation.dart @@ -1,38 +1,411 @@ -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'; +// import 'package:diplomaticquarterapp/core/model/blooddonation/get_all_cities.dart'; +// import 'package:diplomaticquarterapp/core/viewModels/medical/my_balance_view_model.dart'; +// import 'package:diplomaticquarterapp/core/viewModels/project_view_model.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/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'; +// import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +// import 'package:diplomaticquarterapp/widgets/dialogs/radio_selection_dialog.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'; +// import 'package:provider/provider.dart'; +// +// enum BeneficiaryType { MyAccount, MyFamilyFiles, OtherAccount, NON } +// enum Gender { Male, Female, NON } +// enum Blood { Oplus, Ominus, Aplus, Aminus, Bplus, Bminus, ABplus, ABminus, NON } +// +// class BloodDonationPage extends StatefulWidget { +// @override +// _BloodDonationPageState createState() => _BloodDonationPageState(); +// } +// +// class _BloodDonationPageState extends State { +// BeneficiaryType beneficiaryType = BeneficiaryType.NON; +// +// CitiesModel _selectedHospital; +// +// int _selectedHospitalIndex = 0; +// int _selectedGenderIndex = 1; +// int _selectedBloodTypeIndex = 0; +// String _selectedBloodType = "O+"; +// +// String amount = ""; +// String email; +// +// List_BloodGroupDetailsModel bloodDetails = List_BloodGroupDetailsModel(bloodGroup: "A-"); +// AppSharedPreferences sharedPref = AppSharedPreferences(); +// var checkedValue = false; +// List imagesInfo = List(); +// +// ProjectViewModel projectProvider; +// +// @override +// void initState() { +// imagesInfo.add( +// 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((_) {}); +// super.initState(); +// } +// +// int getSelectedCityID(MyBalanceViewModel model) { +// int cityID = 1; +// model.CitiesModelList.forEach((element) { +// if (element.description == model.bloodModelList[0].city) { +// cityID = element.iD; +// } +// }); +// return cityID; +// } +// +// @override +// Widget build(BuildContext context) { +// projectProvider = Provider.of(context); +// +// return BaseView( +// onModelReady: (model) => model.getCities().then((value) { +// model.getBlood().then((value) { +// if (model.bloodModelList.length > 0) { +// CitiesModel citiesModel = new CitiesModel(); +// citiesModel.iD = getSelectedCityID(model); +// _selectedHospitalIndex = (citiesModel.iD - 1); +// citiesModel.description = model.CitiesModelList[_selectedHospitalIndex].description; +// citiesModel.descriptionN = model.CitiesModelList[_selectedHospitalIndex].descriptionN; +// _selectedHospital = citiesModel; +// _selectedBloodType = model.bloodModelList[0].bloodGroup; +// _selectedBloodTypeIndex = getBloodIndex(_selectedBloodType); +// } else { +// _selectedHospital = model.CitiesModelList[0]; +// } +// }); +// }), +// // { +// // if (projectProvider.isLogin && projectProvider.user != null) { +// // model.getCities().then((value) { +// // model.getBlood().then((value) { +// // if (model.bloodModelList.length > 0) { +// // CitiesModel citiesModel = new CitiesModel(); +// // citiesModel.iD = getSelectedCityID(model); +// // _selectedHospitalIndex = (citiesModel.iD - 1); +// // citiesModel.description = model.CitiesModelList[_selectedHospitalIndex].description; +// // citiesModel.descriptionN = model.CitiesModelList[_selectedHospitalIndex].descriptionN; +// // _selectedHospital = citiesModel; +// // _selectedBloodType = model.bloodModelList[0].bloodGroup; +// // _selectedBloodTypeIndex = getBloodIndex(_selectedBloodType); +// // } else { +// // _selectedHospital = model.CitiesModelList[0]; +// // } +// // }); +// // }); +// // } +// // }, +// builder: (_, model, w) => AppScaffold( +// isShowAppBar: true, +// showNewAppBar: true, +// backgroundColor: Color(0xffF7F7F7), +// showNewAppBarTitle: true, +// baseViewModel: model, +// isShowDecPage: true, +// 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), +// if (projectProvider.isLogin && model.state != ViewState.Busy) +// +// 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, +// builder: (cxt) => RadioSelectionDialog( +// listData: list, +// selectedIndex: _selectedHospitalIndex, +// isScrollable: true, +// onValueSelected: (index) { +// _selectedHospitalIndex = index; +// _selectedHospital = model.CitiesModelList[index]; +// setState(() {}); +// }, +// ), +// ); +// }).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, +// builder: (cxt) => RadioSelectionDialog( +// listData: list, +// selectedIndex: _selectedGenderIndex, +// onValueSelected: (index) { +// _selectedGenderIndex = index; +// setState(() {}); +// }, +// ), +// ); +// }).withBorderedContainer, +// SizedBox(height: 12), +// CommonDropDownView(TranslationBase.of(context).bloodType, _selectedBloodType, () { +// 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, +// builder: (cxt) => RadioSelectionDialog( +// listData: list, +// selectedIndex: _selectedBloodTypeIndex, +// isScrollable: true, +// onValueSelected: (index) { +// _selectedBloodTypeIndex = index; +// _selectedBloodType = getBlood(index); +// setState(() {}); +// }, +// ), +// ); +// }).withBorderedContainer, +// SizedBox(height: 12), +// Row( +// mainAxisAlignment: MainAxisAlignment.spaceBetween, +// children: [ +// Text( +// TranslationBase.of(context).viewTermsConditions + ":", +// style: TextStyle(fontWeight: FontWeight.w600, color: Color(0xff2E303A), fontSize: 14, letterSpacing: -0.56), +// ), +// InkWell( +// onTap: () { +// Navigator.of(context).push(FadePage(page: UserAgreementPage())); +// }, +// child: Text( +// TranslationBase.of(context).clickHere, +// 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: 10, +// ), +// Row( +// mainAxisAlignment: MainAxisAlignment.center, +// crossAxisAlignment: CrossAxisAlignment.center, +// children: [ +// Center( +// child: Container( +// color: Theme.of(context).primaryColor, +// width: 350, +// child: InkWell( +// onTap: () { +// showZoomImageDialog(context, 'assets/images/BloodChrt_EN.png', isNetworkImage: false); +// }, +// 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, +// ) +// ], +// ), +// ), +// ), +// DefaultButton( +// TranslationBase.of(context).save, +// checkedValue +// ? () async { +// if (_selectedHospital == null) { +// AppToast.showErrorToast(message: TranslationBase.of(context).selectCity); +// return; +// } +// bloodDetails.city = _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 +// ], +// ), +// ), +// ); +// } +// +// String getBlood(int index) { +// switch (index) { +// case 0: +// return "O+"; +// break; +// case 1: +// return "O-"; +// break; +// case 2: +// return "AB+"; +// break; +// case 3: +// return "AB-"; +// break; +// case 4: +// return "A+"; +// break; +// case 5: +// return "A-"; +// break; +// case 6: +// return "B-"; +// break; +// case 7: +// return "B-"; +// break; +// case 8: +// return "B+"; +// break; +// +// default: +// return ""; +// } +// } +// +// int getBloodIndex(String type) { +// switch (type) { +// case "O+": +// return 0; +// break; +// case "O-": +// return 1; +// break; +// case "AB+": +// return 2; +// break; +// case "AB-": +// return 3; +// break; +// case "A+": +// return 4; +// break; +// case "A-": +// return 5; +// break; +// case "B-": +// return 6; +// break; +// case "B-": +// return 7; +// break; +// case "B+": +// return 8; +// break; +// +// default: +// return 0; +// } +// } +// +// String getHospitalName(ProjectViewModel projectProvider, BuildContext context) { +// if (_selectedHospital != null) +// return projectProvider.isArabic ? _selectedHospital.descriptionN : _selectedHospital.description; +// else +// return TranslationBase.of(context).selectCity; +// } +// } 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'; import 'package:diplomaticquarterapp/core/viewModels/medical/my_balance_view_model.dart'; 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/blood_donation_book_appointment.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/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'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/custom_text_button.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/radio_selection_dialog.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'; -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 } + enum Blood { Oplus, Ominus, Aplus, Aminus, Bplus, Bminus, ABplus, ABminus, NON } class BloodDonationPage extends StatefulWidget { @@ -41,528 +414,411 @@ class BloodDonationPage extends StatefulWidget { } 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; - //HospitalsModel _selectedHospital; - CitiesModel _selectedHospital; + + late CitiesModel _selectedHospital; + + int _selectedHospitalIndex = 0; + int _selectedGenderIndex = 1; + int _selectedBloodTypeIndex = 0; + String _selectedBloodType = "O+"; String amount = ""; - String email; - PatientInfo _selectedPatientInfo; - AuthenticatedUser authenticatedUser; - GetAllSharedRecordsByStatusList selectedPatientFamily; - AdvanceModel advanceModel = AdvanceModel(); - List_BloodGroupDetailsModel bloodDetails = - List_BloodGroupDetailsModel(bloodGroup: "A-"); + String? email; + + List_BloodGroupDetailsModel bloodDetails = List_BloodGroupDetailsModel(bloodGroup: "A-"); AppSharedPreferences sharedPref = AppSharedPreferences(); - AuthenticatedUser authUser; var checkedValue = false; + List imagesInfo = []; + + late ProjectViewModel projectProvider; @override void initState() { + imagesInfo.add( + 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((_) {}); super.initState(); - getAuthUser(); + } + + int getSelectedCityID(MyBalanceViewModel model) { + int cityID = 1; + model.CitiesModelList.forEach((element) { + if (element.description == model.bloodModelList[0].city) { + cityID = element.iD!; + } + }); + return cityID; } @override Widget build(BuildContext context) { - ProjectViewModel projectProvider = Provider.of(context); + projectProvider = Provider.of(context); return BaseView( - onModelReady: (model) => model.getCities(), //model.getHospitals(), + onModelReady: (model) => model.getCities().then((value) { + model.getBlood().then((value) { + if (model.bloodModelList.length > 0) { + CitiesModel citiesModel = new CitiesModel(); + citiesModel.iD = getSelectedCityID(model); + _selectedHospitalIndex = (citiesModel.iD! - 1); + citiesModel.description = model.CitiesModelList[_selectedHospitalIndex].description; + citiesModel.descriptionN = model.CitiesModelList[_selectedHospitalIndex].descriptionN; + _selectedHospital = citiesModel; + _selectedBloodType = model.bloodModelList[0].bloodGroup!; + _selectedBloodTypeIndex = getBloodIndex(_selectedBloodType); + } else { + _selectedHospital = model.CitiesModelList[0]; + } + }); + }), + // { + // if (projectProvider.isLogin && projectProvider.user != null) { + // model.getCities().then((value) { + // model.getBlood().then((value) { + // if (model.bloodModelList.length > 0) { + // CitiesModel citiesModel = new CitiesModel(); + // citiesModel.iD = getSelectedCityID(model); + // _selectedHospitalIndex = (citiesModel.iD - 1); + // citiesModel.description = model.CitiesModelList[_selectedHospitalIndex].description; + // citiesModel.descriptionN = model.CitiesModelList[_selectedHospitalIndex].descriptionN; + // _selectedHospital = citiesModel; + // _selectedBloodType = model.bloodModelList[0].bloodGroup; + // _selectedBloodTypeIndex = getBloodIndex(_selectedBloodType); + // } else { + // _selectedHospital = model.CitiesModelList[0]; + // } + // }); + // }); + // } + // }, builder: (_, model, w) => AppScaffold( - isShowAppBar: true, - baseViewModel: model, - 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, - textAlign: TextAlign.center, - ), - 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: Theme.of(context).primaryColor), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Texts(getHospitalName(projectProvider, context)), - Icon(Icons.arrow_drop_down) - ], - ), + isShowAppBar: true, + showNewAppBar: true, + backgroundColor: Color(0xffF7F7F7), + showNewAppBarTitle: true, + baseViewModel: model, + isShowDecPage: true, + 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: () => confirmSelectGenderDialog(), - //confirmSelectBeneficiaryDialog(model), - child: Container( - padding: EdgeInsets.all(12), - width: double.infinity, - height: 65, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - color: Theme.of(context).primaryColor), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - //Texts(getBeneficiaryType()), - Texts(getGender(context)), - Icon(Icons.arrow_drop_down) - ], - ), + SizedBox(height: 12), + if (projectProvider.isLogin && model.state != ViewState.Busy) + 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, + builder: (cxt) => RadioSelectionDialog( + listData: list, + selectedIndex: _selectedHospitalIndex, + isScrollable: true, + onValueSelected: (index) { + _selectedHospitalIndex = index; + _selectedHospital = model.CitiesModelList[index]; + setState(() {}); + }, + ), + ); + }).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, + builder: (cxt) => RadioSelectionDialog( + listData: list, + selectedIndex: _selectedGenderIndex, + onValueSelected: (index) { + _selectedGenderIndex = index; + setState(() {}); + }, + ), + ); + }).withBorderedContainer, + SizedBox(height: 12), + CommonDropDownView(TranslationBase.of(context).bloodType, _selectedBloodType, () { + 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, + builder: (cxt) => RadioSelectionDialog( + listData: list, + selectedIndex: _selectedBloodTypeIndex, + isScrollable: true, + onValueSelected: (index) { + _selectedBloodTypeIndex = index; + _selectedBloodType = getBlood(index); + setState(() {}); + }, + ), + ); + }).withBorderedContainer, + SizedBox(height: 12), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + TranslationBase.of(context).viewTermsConditions + ":", + style: TextStyle(fontWeight: FontWeight.w600, color: Color(0xff2E303A), fontSize: 14, letterSpacing: -0.56), + ), + InkWell( + onTap: () { + Navigator.of(context).push(FadePage(page: UserAgreementPage())); + }, + child: Text( + TranslationBase.of(context).clickHere, + style: TextStyle(fontWeight: FontWeight.w600, color: Colors.blue, fontSize: 14, letterSpacing: -0.56), + ), + ) + ], ), - ), - SizedBox( - height: 12, - ), - InkWell( - //======Gender======== - onTap: () => confirmSelectBloodDialog(), - //confirmSelectBeneficiaryDialog(model), - child: Container( - padding: EdgeInsets.all(12), - width: double.infinity, - height: 65, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - color: Theme.of(context).primaryColor), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - //Texts(getBeneficiaryType()), - Texts(getBlood()), - Icon(Icons.arrow_drop_down) - ], - ), + 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: [ - Container( - child: Text( - TranslationBase.of(context).viewTermsConditions), - ), - SizedBox( - width: MediaQuery.of(context).size.height * 0.10, - ), - InkWell( - onTap: () { - Navigator.of(context) - .push(FadePage(page: UserAgreementPage())); - }, - child: Container( - child: Texts( - TranslationBase.of(context).clickHere, - color: Colors.blue, + SizedBox( + height: 10, + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Center( + child: Container( + color: Theme.of(context).primaryColor, + width: 350, + child: InkWell( + onTap: () { + showZoomImageDialog(context, 'assets/images/BloodChrt_EN.png', isNetworkImage: false); + }, + child: Container(width: 250, height: 200, child: Image.asset('assets/images/BloodChrt_EN.png'), color: Colors.white), + ), ), ), - ) - ], - ), - SizedBox( - height: 12, - ), - Row( - children: [ - Checkbox( - onChanged: (bool value) { - setState(() { - checkedValue = value; - }); - }, - // tristate: checkedValue==true,//i == 1, - value: checkedValue, - activeColor: Color(0xFFc5272d), //Color(0xFF6200EE), - ), - SizedBox( - height: 10, - ), - Row( - children: [], - ), - SizedBox( - width: 10, + ], + ), + SizedBox( + height: MediaQuery.of(context).size.height * 0.15, + ) + ], + ), + ), + ), + Container( + color: CustomColors.appBackgroudGreyColor, + margin: EdgeInsets.all(14), + height: 45.0, + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Expanded( + flex: 1, + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), ), - Text( - TranslationBase.of(context) - .iAgreeToTheTermsAndConditions, - style: Theme.of(context).textTheme.subtitle1.copyWith( - color: checkedValue - ? Color(0xFFc5272d) - : Colors.black), + height: 45.0, + child: CustomTextButton( + backgroundColor: CustomColors.green, + elevation: 0, + onPressed: () { + Navigator.push(context, FadePage(page: BloodDonationBookAppointment())); + }, + child: Text(TranslationBase.of(context).bookAppo.toUpperCase(), + style: TextStyle( + fontSize: 16.0, + 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')), - ), - ), + mWidth(7), + Expanded( + flex: 1, + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), ), - ], + height: 45.0, + child: CustomTextButton( + backgroundColor: Color(0xffc5272d), + elevation: 0, + onPressed: () async { + if (_selectedHospital == null) { + AppToast.showErrorToast(message: TranslationBase.of(context).selectCity); + return; + } + bloodDetails.city = _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); + } + }, + child: Text(TranslationBase.of(context).save.toUpperCase(), style: TextStyle(fontSize: 16.0, color: Colors.white)), + ), + ), ), - SizedBox( - height: MediaQuery.of(context).size.height * 0.15, - ) ], ), ), - ), - bottomSheet: Container( - height: MediaQuery.of(context).size.height * 0.12, - width: double.infinity, - padding: EdgeInsets.all(12), - child: SecondaryButton( - textColor: Colors.white, - color: checkedValue == false - ? Color(0xFFa0a4a6) - : Color.fromRGBO( - 63, - 72, - 74, - 1, - ), - label: TranslationBase.of(context).save, - onTap: () 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); - } - }, - ), - )), - ); - } - - //============== - 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, - 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; - }); - }, + // DefaultButton( + // TranslationBase.of(context).save, + // checkedValue + // ? () async { + // if (_selectedHospital == null) { + // AppToast.showErrorToast(message: TranslationBase.of(context).selectCity); + // return; + // } + // bloodDetails.city = _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 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, - 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: - 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) { - 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; - } + int getBloodIndex(String type) { + switch (type) { + case "O+": + return 0; + break; + case "O-": + return 1; + break; + case "AB+": + return 2; + break; + case "AB-": + return 3; + break; + case "A+": + return 4; + break; + case "A-": + return 5; + break; + case "B-": + return 6; + break; + case "B-": + return 7; + break; + case "B+": + return 8; + break; - getAuthUser() async { - if (await this.sharedPref.getObject(USER_PROFILE) != null) { - var data = AuthenticatedUser.fromJson( - await this.sharedPref.getObject(USER_PROFILE)); - setState(() { - authUser = data; - }); + default: + return 0; } } - String getFamilyMembersName() { - if (selectedPatientFamily != null) - return selectedPatientFamily.patientName; + String getHospitalName(ProjectViewModel projectProvider, BuildContext context) { + if (_selectedHospital != null) + return projectProvider.isArabic ? _selectedHospital.descriptionN! : _selectedHospital.description!; else - return TranslationBase.of(context).selectFamilyPatientName; + return TranslationBase.of(context).selectCity; } - -//================ - } diff --git a/lib/pages/Blood/blood_donation_appointment_terms_conditions.dart b/lib/pages/Blood/blood_donation_appointment_terms_conditions.dart new file mode 100644 index 00000000..14c49722 --- /dev/null +++ b/lib/pages/Blood/blood_donation_appointment_terms_conditions.dart @@ -0,0 +1,43 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_html/flutter_html.dart'; +import 'package:provider/provider.dart'; + +class BloodDonationAppointmentTermsConditions extends StatelessWidget { + String contentEN = + ' DONOR EDUCATION

                                 

DONOR EDUCATION

Why Should I Give Blood?

Because You Can Make a Difference!

Learning more about blood donation and knowing

DEAR DONOR:

This information sheet explains how YOU can help us make the donation process safe for yourself and patients who might receive your blood.

 

PLEASE READ THIS INFORMATION BEFORE YOU DONATE!

ACCURACY & HONESTY ARE ESSENTIAL!

Your complete honesty in answering all questions is very important for the safety of patients who receive your blood. All information you provide is confidential.

 

DONATION RISKS (These are not common 1-2%) Some of the risks and/or problems associated with donating include: dizziness or lightheadedness, nausea and/or vomiting, rapid pulse rate, Itching at the site from an allergy to iodine, bruising (hematoma), pain at the site.

 

  1. DONOR ELIGIBILITY

YOU MAY DONATE :

  1.          If  you are 18 years old or older (17 with parental permission) and weigh at least 110 pounds (50 kg)
  2.          If  you are in good health
  3.          Have not donated whole blood in the past 8 weeks
  4.          Have not donated double red cells in the past 16 weeks

YOU MAY NOT DONATE IF YOU:

  1.          Have had AIDS or a Positive HIV test
  2.          Have participated in activities that put you at risk for acquiring AIDS.

 

Why we ask questions about sexual contact (as required by federal regulations)

Sexual contact may cause contagious diseases like HIV to get into the blood stream and be spread through transfusions to someone else.

PLEASE DO NOT DONATE TO GET AN HIV TEST DONE

  1. DONATION PROCESS
  1.       Registration: PHOTO ID must be presented prior to donation to identify you at every donation.
  2.       Interview: to determine if you are all right to donate we will:
  • Ask questions about health, travel and medicines.
  • Ask questions to see if you might be at risk for hepatitis, HIV or AIDS
  1.       Mini-physical Examination
  • Take your blood pressure, pulse, temperature, weight.
  • Take a small blood sample to make sure your Hemoglobin level is normal.
  1.      Phlebotomy
  • You will be seated in a donor chair, a tourniquet will be applied to your arm, and a suitable vein located.
  • The site will be cleaned with an antiseptic
  • A sterile needle will be gently inserted into your vein and the blood will be collected in a sterile bag for 5-15 minutes
  • After donation, a pressure bandage will be applied to the site and you may rest and enjoy some refreshments.

 

WHAT HAPPENS AFTER YOUR DONATION?

 

  1. Your blood is tested for: HepatitisB and C, HIV, HTLV (associated with a virus that causes    leukemia), Syphilis, Malaria, Sickling and Blood Type.
  2. There are certain conditions like in Emergency situation; there is a chance that your unit is released without completion of infectious disease testing.
  3. If your blood tests Positive it will not be given to a patient. Your blood will be discarded.
  4. You will be notified about test results that may disqualify you from donating in the future. Since confirmatory tests are necessary, it may take up few days before notification.
  5. If your blood tests Positive, your name will be put on a confidential list of Deferred Donors. When required, Blood Bank will report your donor information, including test result, to health departments and regulatory agencies as required by law.
  6. To ensure confidentiality, NO test results (including blood type) will be given by phone. Written approval from you will be required before test results are released.

 

CARE AFTER DONATING

 

When you donate blood, your body needs a few minutes to adjust to the slight change in blood fluid volume. It is important to follow these instructions:

  1. Remain lying on the donor chair until a staff member releases you to the refreshment area.
  2. Remain in the refreshment area for at least 10 minutes. Enjoy juice and a snack. If you cannot stay, please notify donor room staff.
  3. Drink more fluid than usual and eat heartily for today.
  4. Avoid smoking for 2 hours
  5. Refrain from strenuous exercise for 24 hours. If safety risks are a normal part of your routine, ask a donor room staff member how long you should wait before resuming regular activities.
  6. If you become light-headed or dizzy, lie down until the feeling disappears. If the feeling continues, contact Blood Bank or your physician.
  7. Leave your bandage in place for 4 to 5 hours. This will help to prevent bruising. If your arm starts bleeding again, apply direct pressure and elevate your arm.
  8. Make sure you’re eating a nutritious, well-balance diet containing foods rich in iron and high in vitamin C.
  9. However, if you are a frequent donor, iron rich foods in your diet may not be enough to replenish the iron you routinely lose through blood donations. We recommend you to consult with your health-care provider to see if taking an iron supplement is right for you.

 

If after donating, you realize that you should not have donated because of previous Risk Factors, behaviors, or diseases, YOUR BLOOD MUST NOT BE USED FOR TRANSFUSION!

PLEASE CONTACT Blood Bank IMMEDIATELY.

 

 

 

If you become ill within the next 72 hours, or think of any reason your blood should not be transfused, Please call Blood Bank at +966-11-4833672 or Ext 3662.

 

 

 

 

THANK YOU FOR GIVING

THE GIFT OF LIFE!

 

 

 

BB Form 091 - Donor Education Material (English)          HMG/QID/1892

'; + + String contentAR = + '

ﺗﺜﻘﯿﻒ اﻟﻤﺘﺒﺮع

لماذا علي أن أتبرع بالدم؟ أنك تستطیع أن تحدث فرق تعلم أكثر عن التبرع بالدم


ﻣﺎذا ﯾﺤﺪث ﺑﻌﺪ اﻟﺘﺒﺮع ﺑﺎﻟﺪم؟

-1 ﯾﺘﻢ ﻓﺤﺺ اﻻﯾﺪز ، ﻓﯿﺮوس اﻟﻜﺒﺪ اﻟﻮﺑﺎﺋﻲ ب و ج ، ﻓﯿﺮوس ﻛﺮﯾﺎت اﻟﺪم اﻟﺒﯿﻀﺎء )ﻣﺮﺗﺒﻂ ﺑﻔﯿﺮوس ﺗﺴﺒﺐ ﺳﺮطﺎن اﻟﺪم(

،اﻟﺰھﺮي ، اﻻﻧﯿﻤﯿﺎ اﻟﻤﻨﺠﻠﯿﺔ ،ﻓﺼﯿﻠﺔ اﻟﺪم و اﻻﺟﺴﺎم اﻟﻤﻀﺎدة.

-2 ﻓﻲ ﺣﺎل اﻟﻨﺘﯿﺠﺔ ﻛﺎﻧﺖ اﯾﺠﺎﺑﯿﺔ ﻻي ﻣﺮض ﻣﻦ اﻷﻣﺮاض اﻟﺴﺎﺑﻘﺔ ﻧﻘﻮم ﺑﺎﻟﺘﺨﻠﺺ ﻣﻦ اﻟﺪم ﻣﺒﺎﺷﺮة وﻻ ﯾﻌﻄﻰ ﻟﻠﻤﺮﯾﺾ وﯾﺘﻢ

اﺑﻼغ اﻟﻤﺘﺒﺮع ﻷﺧﺬ ﻋﯿﻨﺔ اﺧﺮى ﻟﻠﺘﺄﻛﺪ . وﻓﻲ ﺣﺎل وﺟﻮد ﻣﺮض ﯾﻤﻨﻊ اﻟﺘﺒﺮع ﻓﻲ اﻟﻤﺴﺘﻘﺒﻞ وﯾﺘﻢ اﺑﻼغ اﻟﻤﺘﺒﺮع.

-3 ﻓﻲ ﺣﺎل وﺟﻮد ﻣﺮض ﯾﻤﻨﻊ ﻣﻦ اﻟﺘﺒﺮع ﻣﺴﺘﻘﺒﻼ ﯾﺴﺠﻞ اﺳﻢ اﻟﻤﺘﺒﺮع ﻓﻲ ﻗﺎﺋﻤﺔ اﻟﻤﺘﺒﺮﻋﯿﻦ اﻟﻤﺮﻓﻮﺿﯿﯿﻦ ﻟﺪى ﺑﻨﻚ اﻟﺪم ﻣﻊ

ﻣﻌﻠﻮﻣﺎﺗﮫ وﻧﺘﯿﺠﺔ اﻟﻔﺤﺺ وﺗﻌﻄﻲ اﻟﻤﻌﻠﻮﻣﺎت ﻟﻠﺠﮭﺎت اﻟﻤﺨﺘﺼﺔ إذا طُﻠﺒﺖ ﻗﺎﻧﻮﻧﯿﺎً.

-4 ﻟﺴﺮﯾﺔ ﻧﺘﺎﺋﺞ اﻟﻔﺤﻮﺻﺎت ﻻ ﺗﻌﻄﻲ اي ﻧﺘﯿﺠﺔ ﺑﺎﻟﮭﺎﺗﻒ وﯾﺠﺐ ﺣﻀﻮر اﻟﻤﺮﯾﺾ ﻣﻊ اﺛﺒﺎﺗﮫ ﻷﺧﺬ اﻟﻨﺘﯿﺠﺔ.

اﺣﺘﯿﺎطﺎت اﻟﺴﻼﻣﺔ ﺑﻌﺪ اﻟﺘﺒﺮع:

ﺑﻌﺪ اﻟﺘﺒﺮع ﺑﺎﻟﺪم ﺟﺴﻤﻚ ﯾﺤﺘﺎج ﻟﺒﻌﺾ اﻟﻮﻗﺖ ﻟﻠﺮاﺣﺔ ﻟﯿﺘﻢ ﺿﺒﻂ اﻟﺘﻐﯿﺮ ﻓﻲ اﻟﺴﻮاﺋﻞ اﻟﺪم ﻟﺬﻟﻚ ﻧﺮﺟﻮ اﺗﺒﺎع اﻻرﺷﺎدات

اﻟﺘﺎﻟﯿﺔ:

 

ﺑﻌﺪ اﻟﺘﺒﺮع ﻣﺒﺎﺷﺮة ﻻ ﺗﻐﺎدر ﻛﺮﺳﻲ اﻟﺘﺒﺮع اﻻﺑﻌﺪ ارﺷﺎدك ﻣﻦ ﻗﺒﻞ اﻟﻌﺎﻣﻠﯿﻦ ﻟﺘﺠﻠﺲ ﻓﻲ ﻣﻜﺎن

-1

ﻣﺨﺼﺺ ﻟﻠﺮاﺣﺔ

 

اﻟﺠﻠﻮس ﻓﻲ اﻟﻤﻜﺎن اﻟﻤﺨﺼﺺ ﻟﻠﺮاﺣﺔ ﻟﻤﺪة 10 دﻗﺎﺋﻖ ﻣﻊ ﺷﺮب اﻟﻌﺼﯿﺮ واﻟﻤﺎء وﻓﻲ ﺣﺎل رﻏﺒﺘﻚ

-2

ﺑﺎﻟﻤﻐﺎدرة اﻟﺮﺟﺎء اﺧﺒﺎر أﺣﺪ اﻟﻌﺎﻣﻠﯿﻦ.

 

اﻟﺮﺟﺎء ﺷﺮب ﻛﻤﯿﺔ ﻛﺒﯿﺮة ﻣﻦ اﻟﺴﻮاﺋﻞ أﻛﺜﺮ ﻣﻦ اﻟﻤﻌﺘﺎد وﺗﻨﺎول طﻌﺎم ﺻﺤﻲ ﻟﺬﻟﻚ اﻟﯿﻮم.

-3

ﺗﺠﻨﺐ اﻟﺘﺪﺧﯿﻦ ﻟﻤﺪة ﺳﺎﻋﺘﯿﻦ ﺑﻌﺪ اﻟﺘﺒﺮع.

-4

ﺗﺠﻨﺐ اﻻﺟﮭﺎد أو اﻟﻨﺸﺎطﺎت اﻟﻘﻮﯾﺔ ﻟﻤﺪة 24 ﺳﺎﻋﺔ، اﻣﺎ إذا ﻛﺎن ﻟﺪﯾﻚ ﻧﺸﺎطﺎت آﻣﻨﺔ ﺑﺼﻮرة دورﯾﺔ

-5

اﻟﺮﺟﺎء اﻻﺳﺘﻔﺴﺎر ﻣﻦ اﻟﻌﺎﻣﻠﯿﻦ ﻓﻲ وﺣﺪة اﻟﺘﺒﺮع ﺑﺎﻟﺪم.

 

ﻟﻮ ﺷﻌﺮت ﺑﺎﻟﺪوار ﺑﻌﺪ ﻣﻐﺎدرﺗﻚ وﺣﺪة اﻟﺘﺒﺮع ﯾﺠﺐ وﺿﻊ رأﺳﻚ إﻟﻰ اﻻﺳﻔﻞ وﻗﺪﻣﯿﻚ إﻟﻰ اﻷﻋﻠﻰ

-6

ﺣﺘﻰ ﺗﺸﻌﺮ ﺑﺎﻟﺮاﺣﺔ وﻓﻲ ﺣﺎﻟﺔ ﻋﺪم ﺷﻌﻮرك ﺑﺎﻟﺮاﺣﺔ اﻟﺮﺟﺎء اﻟﺘﻮاﺻﻞ ﻣﻊ وﺣﺪة اﻟﺘﺒﺮع ﺑﺎﻟﺪم أو

 

اﻟﺘﺤﺪث ﻣﻊ طﺒﯿﺒﻚ.

 

اﺳﺤﺐ اﻟﻠﺼﻘﺔ ﻣﻦ ﻣﻜﺎن اﻟﺘﺒﺮع ﺑﻌﺪ 4 إﻟﻰ 5 ﺳﺎﻋﺎت ﻣﻦ اﻟﺘﺒﺮع ﻟﺘﺠﻨﺐ ﻧﺰﯾﻒ اﻟﺪم وإذا ﻧﺰف اﻟﺪم

-7

ﻗﻢ ﺑﻮﺿﻌﮭﺎ ﻓﻲ ﻣﻜﺎﻧﮭﺎ ﻣﺮة اﺧﺮى وارﻓﻊ ﯾﺪك إﻟﻰ اﻻﻋﻠﻰ.

 

اﺣﺮص ﻋﻠﻰ اﻟﺤﺼﻮل ﻋﻠﻰ وﺟﺒﺎت ﻏﻨﯿﺔ وﺻﺤﯿﺔ وإذا ﻛﻨﺖ ﺗﺘﺒﻊ ﺣﻤﯿﺔ ﻏﺬاﺋﯿﺔ اﺣﺮص ﻋﻠﻰ أن

-8

ﺗﻜﻮن ﺣﻤﯿﺘﻚ ﻣﺤﺘﻮﯾﺔ ﻋﻠﻰ ﻧﺴﺒﺔ ﻋﺎﻟﯿﺔ ﻣﻦ اﻟﺤﺪﯾﺪ وﻓﯿﺘﺎﻣﯿﻦ ﺳﻲ، ﻋﻠﻰ ﻛﻞ ﺣﺎل إذا ﻛﻨﺖ ﻣﻦ

 

اﻟﻤﺘﺒﺮﻋﯿﻦ اﻟﺪاﺋﻤﯿﻦ ﻓﺈن ﺣﻤﯿﺘﻚ اﻟﻐﺬاﺋﯿﺔ ﻗﺪ ﻻﺗﻜﻮن ﻛﺎﻓﯿﺔ ﻟﺘﻌﻮﯾﺾ ﺟﺴﻤﻚ ﻣﺎ ﯾﻔﻘﺪه ﻣﻦ ﺣﺪﯾﺪ ﻋﻨﺪ

 

ﺗﺒﺮﻋﻚ ﺑﺎﻟﺪم وﻧﻨﺼﺤﻚ ﺑﻤﺮاﺟﻌﺔ أﺧﺼﺎﺋﻲ اﻟﺮﻋﺎﯾﺔ اﻟﺼﺤﯿﺔ ﻟﯿﻘﺮر إذا ﻛﻨﺖ ﺗﺤﺘﺎج إﻟﻰ ﻣﻜﻤﻞ ﻏﺬاﺋﻲ

 

ﻣﺤﺘﻮي ﻋﻠﻰ اﻟﺤﺪﯾﺪ.

 

إذا أدرﻛﺖ ﺑﻌﺪ اﻟﺘﺒﺮع أﻧﻚ ﻗﺪ ﻗﻤﺖ ﺑﻨﺸﺎطﺎت أو ﺗﻌﺮﺿﺖ ﻷﻣﺮاض أو ﺳﻠﻮك ﯾﻤﻨﻌﻚ ﻣﻦ اﻟﺘﺒﺮع ﻧﺮﺟﻮ اﻻﺗﺼﺎل

ﺑﺒﻨﻚ اﻟﺪم ﻟﻌﻤﻞ اﻻﺣﺘﯿﺎطﺎت اﻟﻼزﻣﺔ ﻟﻤﻨﻊ ﻧﻘﻞ دﻣﻚ ﻻي ﻣﺮﯾﺾ. وﻟﻮ ﺷﻌﺮت ﺑﻌﺪ 72ﺳﺎﻋﺔ أﻧﻚ ﺑﺤﺎﻟﺔ ﻏﯿﺮ ﺟﯿﺪة أو دﻣﻚ ﯾﺠﺐ أن ﻻ ﯾﻌﻄﻰ ﻻي ﻣﺮﯾﺾ ﻻي ﺳﺒﺐ ﻣﻦ اﻷﺳﺒﺎب

ﯾﺠﺐ اﻻﺗﺼﺎل ﺑﺒﻨﻚ اﻟﺪم

(+966114833672)واﻟﺘﺤﻮﯾﻠﺔ ھﻲ 3662

ﺷﻜﺮا ﻟﻌﻄﺎﺋﻚ..

ﻓﻌﻄﺎﺋﻚ ھﻮ ﺣﯿﺎة..

 

'; + + ProjectViewModel? projectViewModel; + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + return AppScaffold( + isShowAppBar: true, + showNewAppBar: true, + backgroundColor: Color(0xffF7F7F7), + showNewAppBarTitle: true, + description: TranslationBase.of(context).bloodDonationInfo, + appBarTitle: TranslationBase.of(context).bloodD, + body: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Html( + data: projectViewModel!.isArabic ? contentAR : contentEN, + shrinkWrap: true, + ) + ], + ), + ), + ), + ); + } +} diff --git a/lib/pages/Blood/blood_donation_book_appointment.dart b/lib/pages/Blood/blood_donation_book_appointment.dart new file mode 100644 index 00000000..6485b2d8 --- /dev/null +++ b/lib/pages/Blood/blood_donation_book_appointment.dart @@ -0,0 +1,503 @@ +import 'package:diplomaticquarterapp/core/model/blooddonation/blood_donation_free_slots_response.dart'; +import 'package:diplomaticquarterapp/core/model/blooddonation/blood_donation_projects_list_response.dart'; +import 'package:diplomaticquarterapp/core/service/blood/blood_donation_service.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/Appointments/FreeSlot.dart'; +import 'package:diplomaticquarterapp/models/Appointments/timeSlot.dart'; +import 'package:diplomaticquarterapp/pages/Blood/blood_donation_appointment_terms_conditions.dart'; +import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/custom_text_button.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.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/material.dart'; +import 'package:intl/intl.dart'; +import 'package:provider/provider.dart'; +import 'package:syncfusion_flutter_calendar/calendar.dart'; + +import '../AlHabibMedicalService/h2o/h20_setting.dart'; + +class BloodDonationBookAppointment extends StatefulWidget { + const BloodDonationBookAppointment(); + + static bool areSlotsAvailable = false; + static DateTime? selectedAppoDateTime; + static String? selectedDate; + static String? selectedTime; + + @override + State createState() => _BloodDonationBookAppointmentState(); +} + +class _BloodDonationBookAppointmentState extends State with TickerProviderStateMixin { + Map? _events; + AnimationController? _animationController; + CalendarController? _calendarController; + + List bloodDonationProjectsListResponse = []; + int _selectedProjectID = 0; + int _clinicID = 0; + int _doctorID = 0; + + String selectedProjectName = ""; + + List docFreeSlots = []; + List dayEvents = []; + + var selectedDate = ""; + dynamic selectedDateJSON; + dynamic jsonFreeSlots; + + int selectedButtonIndex = 0; + + List bloodDonationFreeSlotsResponse = []; + + ProjectViewModel? projectViewModel; + ScrollController? _scrollController; + + var checkedValue = false; + + @override + void initState() { + final _selectedDay = DateTime.now(); + super.initState(); + + _events = { + _selectedDay: ['Event A0'] + }; + + _scrollController = new ScrollController(); + + _calendarController = CalendarController(); + _animationController = AnimationController( + vsync: this, + duration: const Duration(milliseconds: 50), + ); + + WidgetsBinding.instance.addPostFrameCallback((_) { + getBloodDonationProjectsList(); + }); + } + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + return AppScaffold( + isShowAppBar: true, + showNewAppBar: true, + backgroundColor: Color(0xffF7F7F7), + showNewAppBarTitle: true, + isShowDecPage: true, + description: TranslationBase.of(context).bloodDonationInfo, + appBarTitle: TranslationBase.of(context).bloodD, + body: SingleChildScrollView( + child: Padding( + padding: EdgeInsets.all(21), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(TranslationBase.of(context).selectHospitalBloodDonation, style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.w600, letterSpacing: -0.64)), + mHeight(12), + CommonDropDownView( + TranslationBase.of(context).selectProject, + selectedProjectName, + () { + List list = []; + bloodDonationProjectsListResponse.forEach((element) { + list.add(RadioSelectionDialogModel(element.projectName!, element.projectID!)); + }); + showDialog( + context: context, + builder: (cxt) => RadioSelectionDialog( + listData: list, + selectedIndex: 0, + onValueSelected: (index) { + print(index); + _selectedProjectID = index; + selectedProjectName = bloodDonationProjectsListResponse.firstWhere((element) => element.projectID == index).projectName!; + getBloodDonationFreeSlots(); + setState(() {}); + }, + ), + ); + }, + ).withBorderedContainer, + mHeight(12), + Container( + decoration: cardRadius(12), + child: _buildTableCalendarWithBuilders(projectViewModel!), + ), + mHeight(12), + Text(selectedDate, style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.w600, letterSpacing: -0.64)), + mHeight(8), + BloodDonationBookAppointment.areSlotsAvailable + ? Container( + height: 40, + child: ListView.builder( + controller: _scrollController, + scrollDirection: Axis.horizontal, + itemCount: dayEvents.length, + itemBuilder: (context, index) { + return Container( + margin: EdgeInsets.only(right: (index == dayEvents.length - 1) ? 0 : 5.0, left: index == 0 ? 0 : 5), + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5.0), + side: BorderSide( + color: index == selectedButtonIndex ? CustomColors.green : Colors.black, //Color of the border + style: BorderStyle.solid, //Style of the border + width: 1.5, //width of the border + ), + ), + minWidth: MediaQuery.of(context).size.width * 0.2, + child: index == selectedButtonIndex ? getSelectedButton(index) : getNormalButton(index)), + ); + }, + ), + ) + : Center( + child: Padding( + padding: const EdgeInsets.only(left: 12.0, right: 12.0), + child: Text(TranslationBase.of(context).noSlotsError, style: TextStyle(fontSize: 14.0, fontWeight: FontWeight.w600, letterSpacing: -0.46, color: CustomColors.grey)), + ), + ), + SizedBox(height: 16), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + TranslationBase.of(context).viewTermsConditions + ":", + style: TextStyle(fontWeight: FontWeight.w600, color: Color(0xff2E303A), fontSize: 14, letterSpacing: -0.56), + ), + InkWell( + onTap: () { + Navigator.of(context).push(FadePage(page: BloodDonationAppointmentTermsConditions())); + }, + child: Text( + TranslationBase.of(context).clickHere, + 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), + ), + ], + ), + ], + ), + ), + ), + bottomSheet: Container( + color: Colors.white, + height: MediaQuery.of(context).size.height * 0.081, + width: double.infinity, + padding: EdgeInsets.all(12.0), + child: Column( + children: [ + Container( + width: MediaQuery.of(context).size.width * 0.9, + child: DefaultButton( + TranslationBase.of(context).bookAppo, + () async { + if (BloodDonationBookAppointment.areSlotsAvailable) { + if (checkedValue) { + insertBloodDonationAppointment(); + } else { + AppToast.showErrorToast(message: TranslationBase.of(context).pleaseAcceptTerms); + } + } else { + AppToast.showErrorToast(message: TranslationBase.of(context).selectSlot); + } + }, + textColor: Colors.white, + color: CustomColors.green, + ), + ), + ], + ), + ), + ); + } + + void insertBloodDonationAppointment() { + DoctorsListService service = new DoctorsListService(); + final timeSlot = BloodDonationBookAppointment.selectedAppoDateTime; + GifLoaderDialogUtils.showMyDialog(context); + service + .insertAppointment(_doctorID, _clinicID, _selectedProjectID, BloodDonationBookAppointment.selectedTime!, BloodDonationBookAppointment.selectedDate!, 45, projectViewModel!.isArabic ? 1 : 2, + context, null, null, null, projectViewModel) + .then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res['MessageStatus'] == 1) { + AppToast.showSuccessToast(message: TranslationBase.of(context).bookedSuccess); + Navigator.of(context).pop(); + } else { + ConfirmDialog dialog = new ConfirmDialog( + context: context, + confirmMessage: res['ErrorEndUserMessage'], + okText: TranslationBase.of(context).ok, + cancelText: TranslationBase.of(context).cancel_nocaps, + okFunction: () async { + // openAppSettings(); + Navigator.pop(context); + }, + cancelFunction: () => {}); + dialog.showAlertDialog(context); + // AppToast.showErrorToast(message: res['ErrorEndUserMessage']); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + ConfirmDialog dialog = new ConfirmDialog( + context: context, + confirmMessage: err, + okText: TranslationBase.of(context).ok, + cancelText: TranslationBase.of(context).cancel_nocaps, + okFunction: () async { + // openAppSettings(); + Navigator.pop(context); + }, + cancelFunction: () => {}); + dialog.showAlertDialog(context); + }); + } + + void _onDaySelected(DateTime day, ProjectViewModel projectViewModel) { + final DateFormat formatter = DateFormat('yyyy-MM-dd'); + setState(() { + this.selectedDate = DateUtil.getWeekDayMonthDayYearDateFormatted(day, projectViewModel.isArabic ? "ar" : "en"); + openTimeSlotsPickerForDate(day, docFreeSlots); + BloodDonationBookAppointment.selectedDate = formatter.format(day); + _calendarController!.selectedDate = day; + print(BloodDonationBookAppointment.selectedDate); + }); + } + + Widget _buildTableCalendarWithBuilders(ProjectViewModel projectViewModel) { + return SfCalendar( + controller: _calendarController, + minDate: DateTime.now(), + showNavigationArrow: true, + headerStyle: CalendarHeaderStyle(textAlign: TextAlign.center, textStyle: TextStyle(fontSize: 14.0, fontWeight: FontWeight.w600, letterSpacing: -0.46)), + viewHeaderStyle: ViewHeaderStyle(dayTextStyle: TextStyle(fontSize: 12.0, fontWeight: FontWeight.w600, letterSpacing: -0.46, color: CustomColors.black)), + view: CalendarView.month, + todayHighlightColor: CustomColors.green, + selectionDecoration: containerColorRadiusBorderWidthCircular(Colors.transparent, 4, CustomColors.green, 2.5), + cellBorderColor: Colors.white, + dataSource: MeetingDataSource(_getDataSource()), + monthViewSettings: const MonthViewSettings(appointmentDisplayMode: MonthAppointmentDisplayMode.indicator, showTrailingAndLeadingDates: false, appointmentDisplayCount: 1), + onTap: (CalendarTapDetails details) { + _calendarController!.selectedDate = details.date; + _onDaySelected(details.date!, projectViewModel); + }, + ); + } + + Widget getNormalButton(int index) { + return CustomTextButton( + backgroundColor: Colors.white, + elevation: 0, + side: BorderSide( + color: Colors.black, //Color of the border + style: BorderStyle.solid, //Style of the border + width: 1.5 //width of the border + ), + onPressed: () { + final timeslot = dayEvents[index]; + BloodDonationBookAppointment.selectedAppoDateTime = timeslot.end; + + setState(() { + selectedButtonIndex = index; + BloodDonationBookAppointment.selectedTime = dayEvents[index].isoTime; + print(BloodDonationBookAppointment.selectedTime); + }); + }, + child: Text(dayEvents[index].isoTime!, style: TextStyle(fontSize: 12.0, color: Color(0xFF60686b))), + ); + } + + Widget getSelectedButton(int index) { + return CustomTextButton( + backgroundColor: CustomColors.green, + elevation: 0, + side: BorderSide( + color: CustomColors.green, //Color of the border + style: BorderStyle.solid, //Style of the border + width: 1.5 //width of the border + ), + onPressed: () { + setState(() { + selectedButtonIndex = index; + BloodDonationBookAppointment.selectedTime = dayEvents[index].isoTime; + print(BloodDonationBookAppointment.selectedTime); + }); + }, + child: Text(dayEvents[index].isoTime!, style: TextStyle(fontSize: 12.0, color: Colors.white)), + ); + } + + getBloodDonationFreeSlots() { + BloodDonationService service = new BloodDonationService(); + GifLoaderDialogUtils.showMyDialog(context); + service.getBloodDonationFreeSlots(134, _selectedProjectID).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res["MessageStatus"] == 1) { + res['BD_FreeSlots'].forEach((element) { + bloodDonationFreeSlotsResponse.add(BloodDonationFreeSlotsResponseModel.fromJson(element)); + }); + print(bloodDonationFreeSlotsResponse.length); + _getJSONSlots().then((value) => { + setState(() => {_clinicID = bloodDonationFreeSlotsResponse[0].clinicID!, _doctorID = bloodDonationFreeSlotsResponse[0].doctorID!, _events!.clear(), _events = value}) + }); + } else { + AppToast.showErrorToast(message: res["ErrorEndUserMessage"]); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } + + openTimeSlotsPickerForDate(DateTime dateStart, List freeSlots) { + dayEvents.clear(); + DateTime dateStartObj = new DateTime(dateStart.year, dateStart.month, dateStart.day, 0, 0, 0, 0, 0); + + freeSlots.forEach((v) { + if (v.start == dateStartObj) dayEvents.add(v); + }); + + setState(() { + if (dayEvents.length != 0) { + BloodDonationBookAppointment.areSlotsAvailable = true; + selectedButtonIndex = 0; + BloodDonationBookAppointment.selectedTime = dayEvents[selectedButtonIndex].isoTime; + } else + BloodDonationBookAppointment.areSlotsAvailable = false; + }); + } + + Future> _getJSONSlots() async { + Map _eventsParsed; + List slotsList = []; + DateTime date; + final DateFormat formatter = DateFormat('HH:mm'); + final DateFormat dateFormatter = DateFormat('yyyy-MM-dd'); + for (var i = 0; i < bloodDonationFreeSlotsResponse.length; i++) { + date = DateUtil.convertStringToDate(bloodDonationFreeSlotsResponse[i].freeTimeSlots); + slotsList.add(FreeSlot(date, ['slot'])); + docFreeSlots.add(TimeSlot(isoTime: formatter.format(date), start: new DateTime(date.year, date.month, date.day, 0, 0, 0, 0), end: date)); + } + _eventsParsed = Map.fromIterable(slotsList, key: (e) => e.slot, value: (e) => e.event); + setState(() { + BloodDonationBookAppointment.selectedDate = dateFormatter.format(DateUtil.convertStringToDate(bloodDonationFreeSlotsResponse[0].freeTimeSlots)); + selectedDate = DateUtil.getMonthDayYearDateFormatted(DateUtil.convertStringToDate(bloodDonationFreeSlotsResponse[0].freeTimeSlots)); + selectedDateJSON = bloodDonationFreeSlotsResponse[0].freeTimeSlots; + }); + openTimeSlotsPickerForDate(DateUtil.convertStringToDate(selectedDateJSON), docFreeSlots); + _calendarController!.selectedDate = DateUtil.convertStringToDate(selectedDateJSON); + return _eventsParsed; + } + + getBloodDonationProjectsList() { + BloodDonationService service = new BloodDonationService(); + GifLoaderDialogUtils.showMyDialog(context); + service.getBloodDonationProjectsList().then((res) { + GifLoaderDialogUtils.hideDialog(context); + print(res['BD_getProjectsHaveBDClinics']); + if (res["MessageStatus"] == 1) { + res['BD_getProjectsHaveBDClinics'].forEach((element) { + bloodDonationProjectsListResponse.add(BloodDonationProjectsListResponse.fromJson(element)); + }); + print(bloodDonationProjectsListResponse.length); + } else { + AppToast.showErrorToast(message: res["ErrorEndUserMessage"]); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } + + List _getDataSource() { + 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(minutes: 20)); + meetings.add(Meeting("", startTime, endTime, CustomColors.green, false, "")); + }); + return meetings; + } +} + +class MeetingDataSource extends CalendarDataSource { + MeetingDataSource(List source) { + appointments = source; + } + + @override + DateTime getStartTime(int index) { + return _getMeetingData(index).from; + } + + @override + DateTime getEndTime(int index) { + return _getMeetingData(index).to; + } + + @override + String getSubject(int index) { + return _getMeetingData(index).eventName; + } + + @override + Color getColor(int index) { + return _getMeetingData(index).background; + } + + @override + bool isAllDay(int index) { + return _getMeetingData(index).isAllDay; + } + + Meeting _getMeetingData(int index) { + final dynamic meeting = appointments![index]; + Meeting? meetingData; + if (meeting is Meeting) { + meetingData = meeting; + } + return meetingData!; + } +} + +class Meeting { + Meeting(this.eventName, this.from, this.to, this.background, this.isAllDay, this.notes); + + String eventName; + DateTime from; + DateTime to; + Color background; + bool isAllDay; + String notes; +} \ No newline at end of file diff --git a/lib/pages/Blood/confirm_payment_page.dart b/lib/pages/Blood/confirm_payment_page.dart index c384b7b5..edf3d0e5 100644 --- a/lib/pages/Blood/confirm_payment_page.dart +++ b/lib/pages/Blood/confirm_payment_page.dart @@ -1,8 +1,11 @@ +import 'dart:js'; + import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/my_balance/AdvanceModel.dart'; import 'package:diplomaticquarterapp/core/model/my_balance/patient_info_and_mobile_number.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/my_balance_view_model.dart'; +import 'package:diplomaticquarterapp/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'; @@ -19,42 +22,40 @@ import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:provider/provider.dart'; import 'dialogs/ConfirmSMSDialog.dart'; import 'new_text_Field.dart'; class ConfirmPaymentPage extends StatelessWidget { - final AdvanceModel advanceModel; + late AdvanceModel advanceModel; final PatientInfoAndMobileNumber patientInfoAndMobileNumber; final String selectedPaymentMethod; - MyInAppBrowser browser; + late MyInAppBrowser browser; AuthenticatedUser authenticatedUser; AppSharedPreferences sharedPref = AppSharedPreferences(); + late ProjectViewModel projectViewModel; - ConfirmPaymentPage( - {this.advanceModel, - this.patientInfoAndMobileNumber, - this.selectedPaymentMethod, - this.authenticatedUser}); + ConfirmPaymentPage({required this.advanceModel, required this.patientInfoAndMobileNumber, required this.selectedPaymentMethod, required this.authenticatedUser}); @override Widget build(BuildContext context) { + projectViewModel = Provider.of(context); void showSMSDialog() { showDialog( context: context, barrierDismissible: false, - child: ConfirmSMSDialog( - phoneNumber: patientInfoAndMobileNumber.mobileNumber, + builder: (cxt) => ConfirmSMSDialog( + phoneNumber: patientInfoAndMobileNumber.mobileNumber!, ), ).then((value) { print("dialog dismissed"); print(value); if (value != null && value) { - AppoitmentAllHistoryResultList appo = - new AppoitmentAllHistoryResultList(); + AppoitmentAllHistoryResultList appo = new AppoitmentAllHistoryResultList(); appo.projectID = patientInfoAndMobileNumber.projectID; - openPayment(selectedPaymentMethod, authenticatedUser, - double.parse(advanceModel.amount), appo); + openPayment(selectedPaymentMethod, authenticatedUser, double.parse(advanceModel.amount!), appo, context); } }); } @@ -86,10 +87,10 @@ class ConfirmPaymentPage extends StatelessWidget { height: 100.0, padding: EdgeInsets.all(7.0), width: MediaQuery.of(context).size.width * 0.45, - child: Image.asset(getImagePath(selectedPaymentMethod)), + child: selectedPaymentMethod == "ApplePay" ? SvgPicture.asset(getImagePath(selectedPaymentMethod)) : Image.asset(getImagePath(selectedPaymentMethod)), ), Texts( - '${advanceModel.amount} SAR', + advanceModel.hospitalsModel!.projectOutSA! ? '${advanceModel.amount} AED' : '${advanceModel.amount} SAR', fontSize: 26, bold: true, ) @@ -105,7 +106,7 @@ class ConfirmPaymentPage extends StatelessWidget { margin: EdgeInsets.all(3), child: NewTextFields( hintText: TranslationBase.of(context).fileNumber, - initialValue: advanceModel.fileNumber, + initialValue: advanceModel.fileNumber!, isEnabled: false, ), ), @@ -115,7 +116,7 @@ class ConfirmPaymentPage extends StatelessWidget { margin: EdgeInsets.all(3), child: NewTextFields( hintText: TranslationBase.of(context).name, - initialValue: patientInfoAndMobileNumber.firstName, + initialValue: patientInfoAndMobileNumber.firstName!, isEnabled: false, ), ), @@ -127,7 +128,7 @@ class ConfirmPaymentPage extends StatelessWidget { ), NewTextFields( hintText: TranslationBase.of(context).mobileNumber, - initialValue: patientInfoAndMobileNumber.mobileNumber, + initialValue: patientInfoAndMobileNumber.mobileNumber!, isEnabled: false, ), SizedBox( @@ -135,7 +136,7 @@ class ConfirmPaymentPage extends StatelessWidget { ), NewTextFields( hintText: TranslationBase.of(context).depositorName, - initialValue: advanceModel.depositorName, + initialValue: advanceModel.depositorName!, isEnabled: false, ), SizedBox( @@ -143,7 +144,7 @@ class ConfirmPaymentPage extends StatelessWidget { ), NewTextFields( hintText: TranslationBase.of(context).notes, - initialValue: advanceModel.note, + initialValue: advanceModel.note!, isEnabled: false, ), ], @@ -160,14 +161,9 @@ class ConfirmPaymentPage extends StatelessWidget { disabled: model.state == ViewState.Busy, onTap: () { GifLoaderDialogUtils.showMyDialog(context); - model - .sendActivationCodeForAdvancePayment( - patientID: int.parse(advanceModel.fileNumber), - projectID: advanceModel.hospitalsModel.iD) - .then((value) { + model.sendActivationCodeForAdvancePayment(patientID: int.parse(advanceModel.fileNumber!), projectID: advanceModel.hospitalsModel!.iD).then((value) { GifLoaderDialogUtils.hideDialog(context); - if (model.state != ViewState.ErrorLocal && - model.state != ViewState.Error) showSMSDialog(); + if (model.state != ViewState.ErrorLocal && model.state != ViewState.Error) showSMSDialog(); }); }, ), @@ -193,32 +189,34 @@ class ConfirmPaymentPage extends StatelessWidget { case "Installment": return 'assets/images/new-design/installment.png'; break; + case "ApplePay": + return 'assets/images/new-design/applepay.svg'; + break; } return 'assets/images/new-design/mada.png'; } - openPayment(String paymentMethod, AuthenticatedUser authenticatedUser, - double amount, AppoitmentAllHistoryResultList appo) { - browser = new MyInAppBrowser( - onExitCallback: onBrowserExit, - appo: appo, - onLoadStartCallback: onBrowserLoadStart); + openPayment(String paymentMethod, AuthenticatedUser authenticatedUser, num amount, AppoitmentAllHistoryResultList appo, BuildContext context) { + browser = new MyInAppBrowser(onExitCallback: onBrowserExit, appo: appo, onLoadStartCallback: onBrowserLoadStart); browser.openPaymentBrowser( - amount, - "Advance Payment", - Utils.getAdvancePaymentTransID( - authenticatedUser.projectID, authenticatedUser.patientID), - appo.projectID.toString(), - authenticatedUser.emailAddress, - paymentMethod, - authenticatedUser.patientType, - authenticatedUser.firstName, - authenticatedUser.patientID, - authenticatedUser, - browser, - false); + amount, + "Advance Payment", + Utils.getAdvancePaymentTransID(authenticatedUser.projectID!, authenticatedUser.patientID!), + appo.projectID.toString(), + authenticatedUser.emailAddress!, + paymentMethod, + authenticatedUser.patientType, + authenticatedUser.firstName!, + authenticatedUser.patientID, + authenticatedUser, + browser, + false, + "3", + "", + context, + ); } onBrowserLoadStart(String url) { @@ -244,18 +242,13 @@ class ConfirmPaymentPage extends StatelessWidget { onBrowserExit(AppoitmentAllHistoryResultList appo, bool isPaymentMade) { print("onBrowserExit Called!!!!"); - if (isPaymentMade) checkPaymentStatus(appo); + checkPaymentStatus(appo); } checkPaymentStatus(AppoitmentAllHistoryResultList appo) { DoctorsListService service = new DoctorsListService(); GifLoaderDialogUtils.showMyDialog(AppGlobal.context); - service - .checkPaymentStatus( - Utils.getAppointmentTransID( - appo.projectID, appo.clinicID, appo.appointmentNo), - AppGlobal.context) - .then((res) { + service.checkPaymentStatus(Utils.getAppointmentTransID(appo.projectID!, appo.clinicID!, appo.appointmentNo!), false, AppGlobal.context).then((res) { GifLoaderDialogUtils.hideDialog(AppGlobal.context); print("Printing Payment Status Reponse!!!!"); print(res); @@ -276,14 +269,12 @@ class ConfirmPaymentPage extends StatelessWidget { DoctorsListService service = new DoctorsListService(); String paymentReference = res['Fort_id'].toString(); GifLoaderDialogUtils.showMyDialog(AppGlobal.context); - service - .createAdvancePayment(appo, appo.projectID.toString(), res['Amount'], - res['Fort_id'], res['PaymentMethod'], AppGlobal.context) - .then((res) { + service.createAdvancePayment(appo, appo.projectID.toString(), res['Amount'], res['Fort_id'], res['PaymentMethod'], AppGlobal.context).then((res) { GifLoaderDialogUtils.hideDialog(AppGlobal.context); - print(res['OnlineCheckInAppointments'][0]['AdvanceNumber']); addAdvancedNumberRequest( - res['OnlineCheckInAppointments'][0]['AdvanceNumber'].toString(), + Utils.isVidaPlusProject(projectViewModel, appo.projectID!) + ? res['OnlineCheckInAppointments'][0]['AdvanceNumber_VP'].toString() + : res['OnlineCheckInAppointments'][0]['AdvanceNumber'].toString(), paymentReference, appo.appointmentNo.toString(), appo); @@ -294,16 +285,11 @@ class ConfirmPaymentPage extends StatelessWidget { }); } - addAdvancedNumberRequest(String advanceNumber, String paymentReference, - String appointmentID, AppoitmentAllHistoryResultList appo) { + addAdvancedNumberRequest(String advanceNumber, String paymentReference, String appointmentID, AppoitmentAllHistoryResultList appo) { DoctorsListService service = new DoctorsListService(); GifLoaderDialogUtils.showMyDialog(AppGlobal.context); - service - .addAdvancedNumberRequest( - advanceNumber, paymentReference, appointmentID, AppGlobal.context) - .then((res) { + service.addAdvancedNumberRequest(advanceNumber, paymentReference, appointmentID, AppGlobal.context).then((res) { GifLoaderDialogUtils.hideDialog(AppGlobal.context); - print(res); navigateToHome(AppGlobal.context); }).catchError((err) { GifLoaderDialogUtils.hideDialog(AppGlobal.context); diff --git a/lib/pages/Blood/dialogs/ConfirmSMSDialog.dart b/lib/pages/Blood/dialogs/ConfirmSMSDialog.dart index 5cfb2372..40ef3240 100644 --- a/lib/pages/Blood/dialogs/ConfirmSMSDialog.dart +++ b/lib/pages/Blood/dialogs/ConfirmSMSDialog.dart @@ -8,6 +8,7 @@ import 'package:diplomaticquarterapp/core/model/my_balance/patient_info_and_mobi import 'package:diplomaticquarterapp/core/viewModels/medical/my_balance_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; @@ -18,17 +19,11 @@ import 'package:provider/provider.dart'; class ConfirmSMSDialog extends StatefulWidget { final String phoneNumber; - final AdvanceModel advanceModel; - final PatientInfoAndMobileNumber patientInfoAndMobileNumber; - final String selectedPaymentMethod; + final AdvanceModel? advanceModel; + final PatientInfoAndMobileNumber? patientInfoAndMobileNumber; + final String? selectedPaymentMethod; - const ConfirmSMSDialog( - {Key key, - this.phoneNumber, - this.advanceModel, - this.selectedPaymentMethod, - this.patientInfoAndMobileNumber}) - : super(key: key); + const ConfirmSMSDialog({Key? key, required this.phoneNumber, this.advanceModel, this.selectedPaymentMethod, this.patientInfoAndMobileNumber}) : super(key: key); @override _ConfirmSMSDialogState createState() => _ConfirmSMSDialogState(); @@ -51,7 +46,7 @@ class _ConfirmSMSDialogState extends State { String timerText = (TIMER_MIN - 1).toString() + ':59'; int min = TIMER_MIN - 1; int sec = 59; - Timer _timer; + late Timer _timer; resendCode() { min = TIMER_MIN - 1; @@ -76,10 +71,10 @@ class _ConfirmSMSDialogState extends State { }); } - FocusNode focusD1; - FocusNode focusD2; - FocusNode focusD3; - FocusNode focusD4; + late FocusNode focusD1; + late FocusNode focusD2; + late FocusNode focusD3; + late FocusNode focusD4; @override void initState() { @@ -125,8 +120,7 @@ class _ConfirmSMSDialogState extends State { child: InkWell( onTap: () => Navigator.pop(context), child: Container( - decoration: BoxDecoration( - shape: BoxShape.circle, color: Colors.white), + decoration: BoxDecoration(shape: BoxShape.circle, color: Colors.white), child: Icon( Icons.clear, color: Colors.grey[900], @@ -150,8 +144,7 @@ class _ConfirmSMSDialogState extends State { Padding( padding: const EdgeInsets.all(8.0), child: Texts( - TranslationBase.of(context).pleaseEnterTheVerificationCode + - '[${widget.phoneNumber}]', + TranslationBase.of(context).pleaseEnterTheVerificationCode + '[${widget.phoneNumber}]', textAlign: TextAlign.center, ), ), @@ -161,7 +154,7 @@ class _ConfirmSMSDialogState extends State { Form( key: verifyAccountForm, child: Container( - width: SizeConfig.realScreenWidth * 0.90, + width: SizeConfig.realScreenWidth! * 0.90, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -176,7 +169,7 @@ class _ConfirmSMSDialogState extends State { child: TextFormField( textInputAction: TextInputAction.next, style: TextStyle( - fontSize: SizeConfig.textMultiplier * 3, + fontSize: SizeConfig.textMultiplier! * 3, ), focusNode: focusD1, maxLength: 1, @@ -207,7 +200,7 @@ class _ConfirmSMSDialogState extends State { maxLength: 1, textAlign: TextAlign.center, style: TextStyle( - fontSize: SizeConfig.textMultiplier * 3, + fontSize: SizeConfig.textMultiplier! * 3, ), keyboardType: TextInputType.number, decoration: buildInputDecoration(context), @@ -234,7 +227,7 @@ class _ConfirmSMSDialogState extends State { maxLength: 1, textAlign: TextAlign.center, style: TextStyle( - fontSize: SizeConfig.textMultiplier * 3, + fontSize: SizeConfig.textMultiplier! * 3, ), keyboardType: TextInputType.number, decoration: buildInputDecoration(context), @@ -247,8 +240,7 @@ class _ConfirmSMSDialogState extends State { }, onChanged: (val) { if (val.length == 1) { - FocusScope.of(context) - .requestFocus(focusD4); + FocusScope.of(context).requestFocus(focusD4); } }, )), @@ -260,7 +252,7 @@ class _ConfirmSMSDialogState extends State { maxLength: 1, textAlign: TextAlign.center, style: TextStyle( - fontSize: SizeConfig.textMultiplier * 3, + fontSize: SizeConfig.textMultiplier! * 3, ), keyboardType: TextInputType.number, decoration: buildInputDecoration(context), @@ -274,8 +266,7 @@ class _ConfirmSMSDialogState extends State { }, onChanged: (val) { if (val.length == 1) { - FocusScope.of(context) - .requestFocus(focusD4); + FocusScope.of(context).requestFocus(focusD4); submit(model); } }), @@ -285,8 +276,7 @@ class _ConfirmSMSDialogState extends State { SizedBox( height: 8, ), - if (model.state == ViewState.ErrorLocal || - model.state == ViewState.Error) + if (model.state == ViewState.ErrorLocal || model.state == ViewState.Error) Container( margin: EdgeInsets.only(left: 8, right: 8), width: double.maxFinite, @@ -301,9 +291,7 @@ class _ConfirmSMSDialogState extends State { Padding( padding: const EdgeInsets.all(8.0), child: Texts( - TranslationBase.of(context) - .theVerificationCodeExpiresIn + - ' $timerText', + TranslationBase.of(context).theVerificationCodeExpiresIn + ' $timerText', textAlign: TextAlign.center, ), ), @@ -314,8 +302,7 @@ class _ConfirmSMSDialogState extends State { padding: EdgeInsets.all(12), child: SecondaryButton( textColor: Colors.white, - label: - TranslationBase.of(context).submit.toUpperCase(), + label: TranslationBase.of(context).submit.toUpperCase(), onTap: () { submit(model); }, @@ -333,13 +320,10 @@ class _ConfirmSMSDialogState extends State { } void submit(MyBalanceViewModel model) { - if (verifyAccountForm.currentState.validate()) { + if (verifyAccountForm.currentState!.validate()) { GifLoaderDialogUtils.showMyDialog(context); - final activationCode = - digit1.text + digit2.text + digit3.text + digit4.text; - model - .checkActivationCodeForAdvancePayment(activationCode: activationCode) - .then((value) { + final activationCode = digit1.text + digit2.text + digit3.text + digit4.text; + model.checkActivationCodeForAdvancePayment(activationCode: activationCode).then((value) { GifLoaderDialogUtils.hideDialog(context); Navigator.pop(context, true); }); @@ -350,7 +334,7 @@ class _ConfirmSMSDialogState extends State { if (value.isEmpty) { return ''; } - return null; + return 'null'; } InputDecoration buildInputDecoration(BuildContext context) { @@ -367,11 +351,11 @@ class _ConfirmSMSDialogState extends State { ), errorBorder: OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(5.0)), - borderSide: BorderSide(color: Theme.of(context).errorColor), + borderSide: BorderSide(color: CustomColors.accentColor), ), focusedErrorBorder: OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(5.0)), - borderSide: BorderSide(color: Theme.of(context).errorColor), + borderSide: BorderSide(color: CustomColors.accentColor), ), ); } diff --git a/lib/pages/Blood/dialogs/SelectBeneficiaryDialog.dart b/lib/pages/Blood/dialogs/SelectBeneficiaryDialog.dart index eae22f36..c4780f8b 100644 --- a/lib/pages/Blood/dialogs/SelectBeneficiaryDialog.dart +++ b/lib/pages/Blood/dialogs/SelectBeneficiaryDialog.dart @@ -7,15 +7,15 @@ import 'package:flutter/material.dart'; //import '../advance_payment_page.dart'; class SelectBeneficiaryDialog extends StatefulWidget { - final BeneficiaryType beneficiaryType; - final Function(BeneficiaryType) onValueSelected; + final BeneficiaryType? beneficiaryType; + final Function(BeneficiaryType)? onValueSelected; SelectBeneficiaryDialog( - {Key key, this.beneficiaryType, this.onValueSelected}); + {Key? key, this.beneficiaryType, this.onValueSelected}); @override _SelectBeneficiaryDialogState createState() => - _SelectBeneficiaryDialogState(this.beneficiaryType); + _SelectBeneficiaryDialogState(this.beneficiaryType!); } class _SelectBeneficiaryDialogState extends State { @@ -47,9 +47,9 @@ class _SelectBeneficiaryDialogState extends State { value: BeneficiaryType.MyAccount, groupValue: beneficiaryType, activeColor: Colors.red[800], - onChanged: (BeneficiaryType value) { + onChanged: (BeneficiaryType? value) { setState(() { - beneficiaryType = value; + beneficiaryType = value!; }); }, ), @@ -77,9 +77,9 @@ class _SelectBeneficiaryDialogState extends State { value: BeneficiaryType.MyFamilyFiles, groupValue: beneficiaryType, activeColor: Colors.red[800], - onChanged: (BeneficiaryType value) { + onChanged: (BeneficiaryType? value) { setState(() { - beneficiaryType = value; + beneficiaryType = value!; }); }, ), @@ -107,9 +107,9 @@ class _SelectBeneficiaryDialogState extends State { value: BeneficiaryType.OtherAccount, groupValue: beneficiaryType, activeColor: Colors.red[800], - onChanged: (BeneficiaryType value) { + onChanged: (BeneficiaryType? value) { setState(() { - beneficiaryType = value; + beneficiaryType = value!; }); }, ), @@ -152,7 +152,7 @@ class _SelectBeneficiaryDialogState extends State { flex: 1, child: InkWell( onTap: () { - widget.onValueSelected(beneficiaryType); + widget.onValueSelected!(beneficiaryType); Navigator.pop(context); }, child: Padding( 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/Blood/dialogs/SelectGenderDialog.dart b/lib/pages/Blood/dialogs/SelectGenderDialog.dart index a097ae8e..d1c8a8b2 100644 --- a/lib/pages/Blood/dialogs/SelectGenderDialog.dart +++ b/lib/pages/Blood/dialogs/SelectGenderDialog.dart @@ -8,7 +8,7 @@ class SelectGenderDialog extends StatefulWidget { final Gender beneficiaryType; final Function(Gender) onValueSelected; - SelectGenderDialog({Key key, this.beneficiaryType, this.onValueSelected}); + SelectGenderDialog({Key? key, required this.beneficiaryType, required this.onValueSelected}); @override _SelectGenderDialogState createState() => @@ -43,9 +43,9 @@ class _SelectGenderDialogState extends State { value: Gender.Male, groupValue: beneficiaryType, activeColor: Colors.red[800], - onChanged: (Gender value) { + onChanged: (Gender? value) { setState(() { - beneficiaryType = value; + beneficiaryType = value!; }); }, ), @@ -73,9 +73,9 @@ class _SelectGenderDialogState extends State { value: Gender.Female, groupValue: beneficiaryType, activeColor: Colors.red[800], - onChanged: (Gender value) { + onChanged: (Gender? value) { setState(() { - beneficiaryType = value; + beneficiaryType = value!; }); }, ), diff --git a/lib/pages/Blood/dialogs/SelectHospitalDialog.dart b/lib/pages/Blood/dialogs/SelectHospitalDialog.dart index c7554c20..40fbb036 100644 --- a/lib/pages/Blood/dialogs/SelectHospitalDialog.dart +++ b/lib/pages/Blood/dialogs/SelectHospitalDialog.dart @@ -7,10 +7,10 @@ import 'package:flutter/material.dart'; class SelectHospitalDialog extends StatefulWidget { final List hospitals; final Function(HospitalsModel) onValueSelected; - HospitalsModel selectedHospital; + HospitalsModel? selectedHospital; SelectHospitalDialog( - {Key key, this.hospitals, this.onValueSelected, this.selectedHospital}); + {Key? key, required this.hospitals, required this.onValueSelected, this.selectedHospital}); @override _SelectHospitalDialogState createState() => _SelectHospitalDialogState(); @@ -49,7 +49,7 @@ class _SelectHospitalDialogState extends State { }); }, child: ListTile( - title: Text(widget.hospitals[index].name), + title: Text(widget.hospitals[index].name!), leading: Radio( value: widget.hospitals[index], groupValue: widget.selectedHospital, @@ -105,7 +105,7 @@ class _SelectHospitalDialogState extends State { flex: 1, child: InkWell( onTap: () { - widget.onValueSelected(widget.selectedHospital); + widget.onValueSelected(widget.selectedHospital!); Navigator.pop(context); }, child: Padding( diff --git a/lib/pages/Blood/dialogs/SelectPatientFamilyDialog.dart b/lib/pages/Blood/dialogs/SelectPatientFamilyDialog.dart index 5808aed8..09495348 100644 --- a/lib/pages/Blood/dialogs/SelectPatientFamilyDialog.dart +++ b/lib/pages/Blood/dialogs/SelectPatientFamilyDialog.dart @@ -1,5 +1,3 @@ -import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; -import 'package:diplomaticquarterapp/core/model/my_balance/patient_info.dart'; import 'package:diplomaticquarterapp/models/FamilyFiles/GetAllSharedRecordByStatusResponse.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; @@ -9,9 +7,9 @@ import 'package:flutter/material.dart'; class SelectPatientFamilyDialog extends StatefulWidget { final List getAllSharedRecordsByStatusList; final Function(GetAllSharedRecordsByStatusList) onValueSelected; - GetAllSharedRecordsByStatusList selectedPatientFamily; + GetAllSharedRecordsByStatusList? selectedPatientFamily; - SelectPatientFamilyDialog({Key key, this.getAllSharedRecordsByStatusList, this.onValueSelected,this.selectedPatientFamily}); + SelectPatientFamilyDialog({Key? key, required this.getAllSharedRecordsByStatusList, required this.onValueSelected,this.selectedPatientFamily}); @override _SelectPatientFamilyDialogState createState() => _SelectPatientFamilyDialogState(); @@ -51,7 +49,7 @@ class _SelectPatientFamilyDialogState extends State { }); }, child: ListTile( - title: Text(widget.getAllSharedRecordsByStatusList[index].patientName), + title: Text(widget.getAllSharedRecordsByStatusList[index].patientName!), leading: Radio( value: widget.getAllSharedRecordsByStatusList[index], groupValue: widget.selectedPatientFamily, @@ -107,7 +105,7 @@ class _SelectPatientFamilyDialogState extends State { flex: 1, child: InkWell( onTap: () { - widget.onValueSelected(widget.selectedPatientFamily); + widget.onValueSelected(widget.selectedPatientFamily!); Navigator.pop(context); }, child: Padding( diff --git a/lib/pages/Blood/dialogs/SelectPatientInfoDialog.dart b/lib/pages/Blood/dialogs/SelectPatientInfoDialog.dart index bea4f694..f2368c0d 100644 --- a/lib/pages/Blood/dialogs/SelectPatientInfoDialog.dart +++ b/lib/pages/Blood/dialogs/SelectPatientInfoDialog.dart @@ -1,6 +1,4 @@ -import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; import 'package:diplomaticquarterapp/core/model/my_balance/patient_info.dart'; -import 'package:diplomaticquarterapp/models/FamilyFiles/GetAllSharedRecordByStatusResponse.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:flutter/cupertino.dart'; @@ -11,7 +9,7 @@ class SelectPatientInfoDialog extends StatefulWidget { final Function(PatientInfo) onValueSelected; PatientInfo selectedPatientInfo; - SelectPatientInfoDialog({Key key, this.patientInfoList, this.onValueSelected,this.selectedPatientInfo}); + SelectPatientInfoDialog({Key? key, required this.patientInfoList, required this.onValueSelected,required this.selectedPatientInfo}); @override _SelectPatientInfoDialogState createState() => _SelectPatientInfoDialogState(); @@ -51,14 +49,14 @@ class _SelectPatientInfoDialogState extends State { }); }, child: ListTile( - title: Text(widget.patientInfoList[index].fullName), + title: Text(widget.patientInfoList[index].fullName!), leading: Radio( value: widget.patientInfoList[index], groupValue: widget.selectedPatientInfo, activeColor: Colors.red[800], onChanged: (value) { setState(() { - widget.selectedPatientInfo = value; + widget.selectedPatientInfo = value!; }); }, ), diff --git a/lib/pages/Blood/new_text_Field.dart b/lib/pages/Blood/new_text_Field.dart index ad9eb580..61a97eb8 100644 --- a/lib/pages/Blood/new_text_Field.dart +++ b/lib/pages/Blood/new_text_Field.dart @@ -1,12 +1,11 @@ -import 'package:eva_icons_flutter/eva_icons_flutter.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; class NumberTextInputFormatter extends TextInputFormatter { @override - TextEditingValue formatEditUpdate( - TextEditingValue oldValue, TextEditingValue newValue) { + TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) { final int newTextLength = newValue.text.length; int selectionIndex = newValue.selection.end; int usedSubstringIndex = 0; @@ -28,8 +27,7 @@ class NumberTextInputFormatter extends TextInputFormatter { if (newValue.selection.end >= 10) selectionIndex++; } // Dump the rest. - if (newTextLength >= usedSubstringIndex) - newText.write(newValue.text.substring(usedSubstringIndex)); + if (newTextLength >= usedSubstringIndex) newText.write(newValue.text.substring(usedSubstringIndex)); return TextEditingValue( text: newText.toString(), selection: TextSelection.collapsed(offset: selectionIndex), @@ -41,76 +39,76 @@ final _mobileFormatter = NumberTextInputFormatter(); class NewTextFields extends StatefulWidget { NewTextFields( - {Key key, - this.type, - this.hintText, - this.suffixIcon, - this.autoFocus, - this.onChanged, - this.initialValue, - this.minLines, - this.maxLines, - this.inputFormatters, - this.padding, - this.focus = false, - this.maxLengthEnforced = true, - this.suffixIconColor, - this.inputAction, - this.onSubmit, - this.keepPadding = true, - this.textCapitalization = TextCapitalization.none, - this.controller, - this.keyboardType, - this.validator, - this.borderOnlyError = false, - this.onSaved, - this.onSuffixTap, - this.readOnly: false, - this.maxLength, - this.prefixIcon, - this.bare = false, - this.onTap, - this.fontSize = 16.0, - this.fontWeight = FontWeight.w700, - this.autoValidate = false, - this.hintColor,this.isEnabled=true}) + {Key? key, + this.type, + this.hintText, + this.suffixIcon, + this.autoFocus, + this.onChanged, + this.initialValue, + this.minLines, + this.maxLines, + this.inputFormatters, + this.padding, + this.focus = false, + this.maxLengthEnforced = true, + this.suffixIconColor, + this.inputAction, + this.onSubmit, + this.keepPadding = true, + this.textCapitalization = TextCapitalization.none, + this.controller, + this.keyboardType, + this.validator, + this.borderOnlyError = false, + this.onSaved, + this.onSuffixTap, + this.readOnly = false, + this.maxLength, + this.prefixIcon, + this.bare = false, + this.onTap, + this.fontSize = 16.0, + this.fontWeight = FontWeight.w700, + this.hintColor, + this.isEnabled = true}) : super(key: key); - final String hintText; + final String? hintText; // final String initialValue; - final String type; - final bool autoFocus; - final IconData suffixIcon; - final Color suffixIconColor; - final Icon prefixIcon; - final VoidCallback onTap; - final TextEditingController controller; - final TextInputType keyboardType; - final FormFieldValidator validator; - final Function onSaved; - final Function onSuffixTap; - final Function onChanged; - final Function onSubmit; - final bool readOnly; - final int maxLength; - final int minLines; - final int maxLines; - final bool maxLengthEnforced; - final bool bare; - final bool isEnabled; - final TextInputAction inputAction; - final double fontSize; - final FontWeight fontWeight; - final bool keepPadding; + final String? type; + final bool? autoFocus; + final IconData? suffixIcon; + final Color? suffixIconColor; + final Icon? prefixIcon; + final VoidCallback? onTap; + final TextEditingController? controller; + final TextInputType? keyboardType; + final FormFieldValidator? validator; + final Function(String?)? onSaved; + final Function? onSuffixTap; + final Function(String)? onChanged; + final Function(String)? onSubmit; + final bool? readOnly; + final int? maxLength; + final int? minLines; + final int? maxLines; + final bool? maxLengthEnforced; + final bool? bare; + final bool? isEnabled; + final TextInputAction? inputAction; + final double? fontSize; + final FontWeight? fontWeight; + final bool? keepPadding; final TextCapitalization textCapitalization; - final List inputFormatters; - final bool autoValidate; - final EdgeInsets padding; - final bool focus; - final bool borderOnlyError; - final Color hintColor; - final String initialValue; + final List? inputFormatters; + final EdgeInsets? padding; + final bool? focus; + final bool? borderOnlyError; + final Color? hintColor; + final String? initialValue; + @override _NewTextFieldsState createState() => _NewTextFieldsState(); } @@ -132,7 +130,7 @@ class _NewTextFieldsState extends State { @override void didUpdateWidget(NewTextFields oldWidget) { - if (widget.focus) _focusNode.requestFocus(); + if (widget.focus!) _focusNode.requestFocus(); super.didUpdateWidget(oldWidget); } @@ -142,9 +140,8 @@ class _NewTextFieldsState extends State { super.dispose(); } - bool _determineReadOnly() { - if (widget.readOnly != null && widget.readOnly) { + if (widget.readOnly != null && widget.readOnly!) { _focusNode.unfocus(); return true; } else { @@ -156,30 +153,26 @@ class _NewTextFieldsState extends State { Widget build(BuildContext context) { return AnimatedContainer( duration: Duration(milliseconds: 300), - decoration:BoxDecoration( - borderRadius: BorderRadius.circular(12), - color: Colors.white), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), color: Colors.white), child: Container( margin: EdgeInsets.only(top: 8), - child: TextFormField( enabled: widget.isEnabled, initialValue: widget.initialValue, keyboardAppearance: Theme.of(context).brightness, scrollPhysics: BouncingScrollPhysics(), - autovalidate: widget.autoValidate, textCapitalization: widget.textCapitalization, onFieldSubmitted: widget.inputAction == TextInputAction.next ? (widget.onSubmit != null - ? widget.onSubmit - : (val) { - _focusNode.nextFocus(); - }) + ? widget.onSubmit + : (val) { + _focusNode.nextFocus(); + }) : widget.onSubmit, textInputAction: widget.inputAction, minLines: widget.minLines ?? 1, maxLines: widget.maxLines ?? 1, - maxLengthEnforced: widget.maxLengthEnforced, + // maxLengthEnforced: widget.maxLengthEnforced, onChanged: widget.onChanged, focusNode: _focusNode, maxLength: widget.maxLength ?? null, @@ -191,44 +184,23 @@ class _NewTextFieldsState extends State { validator: widget.validator, onSaved: widget.onSaved, - style: Theme.of(context) - .textTheme - .body2 - .copyWith(fontSize: widget.fontSize, fontWeight: widget.fontWeight), + // style: Theme.of(context).textTheme.bodyText2!.copyWith(fontSize: widget.fontSize, fontWeight: widget.fontWeight), + style: TextStyle(color: Colors.black, letterSpacing: 0.6, fontSize: widget.fontSize, fontWeight: widget.fontWeight), inputFormatters: widget.keyboardType == TextInputType.phone ? [ - WhitelistingTextInputFormatter.digitsOnly, - _mobileFormatter, - ] + FilteringTextInputFormatter.digitsOnly, + _mobileFormatter, + ] : widget.inputFormatters, decoration: InputDecoration( labelText: widget.hintText, labelStyle: TextStyle(color: Colors.black), - errorBorder: OutlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context) - .errorColor - .withOpacity(0.5), - width: 1.0), - borderRadius: BorderRadius.circular(12.0)), - focusedErrorBorder: OutlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context) - .errorColor - .withOpacity(0.5), - width: 1.0), - borderRadius: BorderRadius.circular(8.0)), - focusedBorder: OutlineInputBorder( - borderSide: - BorderSide(color: Colors.white, width: 1.0), - borderRadius: BorderRadius.circular(12)), - disabledBorder: OutlineInputBorder( - borderSide: - BorderSide(color: Colors.white, width: 1.0), - borderRadius: BorderRadius.circular(12)), + errorBorder: OutlineInputBorder(borderSide: BorderSide(color: CustomColors.accentColor.withOpacity(0.5), width: 1.0), borderRadius: BorderRadius.circular(12.0)), + focusedErrorBorder: OutlineInputBorder(borderSide: BorderSide(color: CustomColors.accentColor.withOpacity(0.5), width: 1.0), borderRadius: BorderRadius.circular(8.0)), + focusedBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.white, width: 1.0), borderRadius: BorderRadius.circular(12)), + disabledBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.white, width: 1.0), borderRadius: BorderRadius.circular(12)), enabledBorder: OutlineInputBorder( - borderSide: - BorderSide(color: Colors.white, width: 1.0), + borderSide: BorderSide(color: Colors.white, width: 1.0), borderRadius: BorderRadius.circular(12), ), ), diff --git a/lib/pages/Blood/user_agreement_page.dart b/lib/pages/Blood/user_agreement_page.dart index 36989ea5..1f922444 100644 --- a/lib/pages/Blood/user_agreement_page.dart +++ b/lib/pages/Blood/user_agreement_page.dart @@ -1,23 +1,523 @@ import 'package:diplomaticquarterapp/core/viewModels/TermsConditionsViewModel.dart'; +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/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/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_html/flutter_html.dart'; +import 'package:provider/provider.dart'; + +class UserAgreementPage extends StatefulWidget { + @override + State createState() => _UserAgreementPageState(); +} + +class _UserAgreementPageState extends State { + late ProjectViewModel projectViewModel; + + bool acceptTerms = false; -class UserAgreementPage extends StatelessWidget { @override Widget build(BuildContext context) { + projectViewModel = Provider.of(context); return BaseView( onModelReady: (model) => model.getUserTermsAndConditions(), builder: (_, model, w) => AppScaffold( - isShowAppBar: true, - appBarTitle: TranslationBase.of(context).userAgreement, - body: SingleChildScrollView( - child: Html( - data: model.userAgreementContent, + isShowAppBar: true, + showNewAppBarTitle: true, + showNewAppBar: true, + isShowDecPage: false, + appBarTitle: TranslationBase.of(context).termsConditions, + body: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).termsHeading, + style: TextStyle( + fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions1, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions2, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions3, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions4, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions5, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsHeading2, + style: TextStyle( + fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions6, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsHeading3, + style: TextStyle( + fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions7, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions8, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions9, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions10, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions11, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions12, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions12a, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions12b, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions12c, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions13, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions14, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions14a, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions14b, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsHeading4, + style: TextStyle( + fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions15, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions16, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions16a, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions16b, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions17, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions18, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions19, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions19a, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions19b, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsHeading5, + style: TextStyle( + fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions20, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions21, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsHeading6, + style: TextStyle( + fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions21, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions22, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions23, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions24, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsHeading7, + style: TextStyle( + fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions25, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions25a, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions25b, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions25c, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions26, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions27, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions28, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions29, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions30, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions31, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions32, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsHeading8, + style: TextStyle( + fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions33, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions33a, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions33b, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions34, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions34a, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions34b, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions34c, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions34d, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions34e, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions35, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions35a, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions35b, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions35c, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions35d, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions35e, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions36, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions37, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions38, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions39, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions39a, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions39b, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions39c, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions39d, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsHeading9, + style: TextStyle( + fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions40, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions41, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsHeading10, + style: TextStyle( + fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions42, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions43, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsHeading11, + style: TextStyle( + fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions44, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsHeading12, + style: TextStyle( + fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions45, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(24.0), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Checkbox( + value: acceptTerms, + onChanged: (v) { + setState(() => acceptTerms = v!); + }), + Expanded( + child: Text( + TranslationBase.of(context).termsConditionsRead, + style: TextStyle( + fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + ), + ], + ), + mHeight(75.0), + ], ), - )), + ), + ), + bottomSheet: Container( + color: CustomColors.white, + padding: EdgeInsets.fromLTRB(12.0, 1.0, 12.0, 25.0), + child: DefaultButton( + TranslationBase.of(context).acceptLbl.toUpperCase(), + acceptTerms + ? () { + Navigator.pop(context); + } + : null, + color: CustomColors.green, + disabledColor: CustomColors.grey2, + ), + ), + ), ); } } diff --git a/lib/pages/BookAppointment/BookConfirm.dart b/lib/pages/BookAppointment/BookConfirm.dart index 966dc4d4..cd2d8c7a 100644 --- a/lib/pages/BookAppointment/BookConfirm.dart +++ b/lib/pages/BookAppointment/BookConfirm.dart @@ -1,26 +1,48 @@ +import 'dart:convert'; +import 'dart:developer'; +import 'dart:io'; + import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/enum/PayfortEnums.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; import 'package:diplomaticquarterapp/models/Appointments/PatientShareResposne.dart'; import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; +import 'package:diplomaticquarterapp/models/LiveCare/ApplePayInsertRequest.dart'; +import 'package:diplomaticquarterapp/models/header_model.dart'; +import 'package:diplomaticquarterapp/pages/ToDoList/payment_method_select.dart'; +import 'package:diplomaticquarterapp/pages/ToDoList/widgets/paymentDialog.dart'; +import 'package:diplomaticquarterapp/pages/insurance/insurance_update_screen.dart'; +import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; +import 'package:diplomaticquarterapp/services/livecare_services/livecare_provider.dart'; +import 'package:diplomaticquarterapp/services/payfort_services/payfort_project_details_resp_model.dart'; +import 'package:diplomaticquarterapp/services/payfort_services/payfort_view_model.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/custom_text_button.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; +import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart'; +import 'package:diplomaticquarterapp/widgets/new_design/doctor_header.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; -import 'package:rating_bar/rating_bar.dart'; -import 'BookSuccess.dart'; +import '../../models/Appointments/PatientPackageComponent.dart'; +import 'book_reminder_page.dart'; +import 'components/DocAvailableAppointments.dart'; class BookConfirm extends StatefulWidget { DoctorList doctor; @@ -30,28 +52,43 @@ class BookConfirm extends StatefulWidget { String appoDateFormatted = ""; String appoTimeFormatted = ""; bool isLiveCareAppointment; + int initialSlotDuration; + + bool isWalkinAppointment = false; BookConfirm( - {@required this.doctor, - @required this.selectedDate, - @required this.isLiveCareAppointment, - @required this.selectedTime}); + {required this.doctor, required this.selectedDate, required this.isLiveCareAppointment, required this.selectedTime, required this.initialSlotDuration, required this.isWalkinAppointment}); + + late DoctorsListService service; + late PatientShareResponse patientShareResponse; - DoctorsListService service; - PatientShareResponse patientShareResponse; - AuthenticatedUser authUser; + // AuthenticatedUser authUser; @override _BookConfirmState createState() => _BookConfirmState(); } class _BookConfirmState extends State { - ToDoCountProviderModel toDoProvider; + late ProjectViewModel projectViewModel; + late ToDoCountProviderModel toDoProvider; + + AppSharedPreferences sharedPref = new AppSharedPreferences(); + + bool isInsured = false; + bool isEligible = false; + bool isCash = false; + + String? selectedPaymentMethod = ""; + String? selectedInstallments = ""; + String? tamaraPaymentStatus; + String? tamaraOrderID; + String? transID; + late MyInAppBrowser browser; @override void initState() { - widget.authUser = new AuthenticatedUser(); - getPatientData(); + // widget.authUser = new AuthenticatedUser(); + // getPatientData(); widget.service = new DoctorsListService(); widget.patientShareResponse = new PatientShareResponse(); super.initState(); @@ -60,388 +97,836 @@ class _BookConfirmState extends State { @override Widget build(BuildContext context) { toDoProvider = Provider.of(context); + projectViewModel = Provider.of(context); return AppScaffold( - appBarTitle: TranslationBase.of(context).bookAppo, + appBarTitle: widget.doctor.doctorTitle! + " " + widget.doctor.name!, isShowDecPage: false, isShowAppBar: true, + showNewAppBarTitle: true, + showNewAppBar: true, + backgroundColor: CustomColors.appBackgroudGreyColor, body: SingleChildScrollView( - child: Container( - margin: EdgeInsets.all(20.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - children: [ - Container( - margin: EdgeInsets.only(bottom: 5.0), - alignment: Alignment.center, - child: Text(TranslationBase.of(context).confirmAppoHeading, - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 22.0, - color: new Color(0xFF60686b), - letterSpacing: 0.9))), - Divider( - color: Colors.grey[400], + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.max, + children: [ + DoctorHeader( + headerModel: HeaderModel( + widget.doctor.name!, + widget.doctor.doctorID!, + widget.doctor.doctorImageURL!, + widget.doctor.speciality!, + "", + widget.doctor.projectName!, + null, + null, + widget.doctor.nationalityFlagURL ?? "", + widget.doctor.doctorRate, + null, + widget.doctor.noOfPatientsRate, + "", ), - Container( - margin: EdgeInsets.only(top: 15.0), - child: Text(TranslationBase.of(context).docInfo, - style: TextStyle( - fontSize: 22.0, - color: Colors.black, - letterSpacing: 0.9))), - Container( - child: Card( - color: Colors.white, - margin: EdgeInsets.fromLTRB(0.0, 5.0, 0.0, 16.0), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - side: BorderSide(color: Colors.grey[400], width: 0.6)), - child: Container( - padding: EdgeInsets.all(7.0), - width: MediaQuery.of(context).size.width, - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - ClipRRect( - borderRadius: BorderRadius.circular(100.0), - child: Image.network(widget.doctor.doctorImageURL, - fit: BoxFit.fill, height: 70.0, width: 70.0), - ), - Container( - width: MediaQuery.of(context).size.width * 0.58, - margin: EdgeInsets.fromLTRB(20.0, 5.0, 10.0, 5.0), - child: Column( + isNeedToShowButton: false, + ), + Padding( + padding: const EdgeInsets.all(20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).confirmAppoHeading, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 16.0, + letterSpacing: -0.64, + fontWeight: FontWeight.w600, + ), + ), + mHeight(20), + Container( + decoration: cardRadius(12), + margin: EdgeInsets.zero, + child: Padding( + padding: const EdgeInsets.fromLTRB(16, 20, 16, 20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).appoInfo, + style: TextStyle( + fontSize: 14.0, + color: Colors.black, + letterSpacing: -0.36, + fontWeight: FontWeight.w600, + ), + ), + mHeight(16), + Column( crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.max, children: [ - Text( - widget.doctor.doctorTitle + - "" + - widget.doctor.name, - style: TextStyle( - fontSize: 14.0, - color: Colors.grey[700], - letterSpacing: 1.0)), - Container( - margin: EdgeInsets.only(top: 3.0), - child: Text(widget.doctor.clinicName, - style: TextStyle( - fontSize: 12.0, - color: Colors.grey[600], - letterSpacing: 1.0)), - ), - Container( - margin: EdgeInsets.only(top: 3.0, bottom: 3.0), - child: Text( - getDoctorSpeciality( - widget.doctor.speciality) - .trim(), - style: TextStyle( - fontSize: 12.0, - color: Colors.grey[600], - letterSpacing: 1.0)), - ), - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - mainAxisSize: MainAxisSize.max, - children: [ - RatingBar.readOnly( - initialRating: widget - .doctor.actualDoctorRate - .toDouble(), - size: 20.0, - filledColor: Colors.yellow[700], - emptyColor: Colors.grey[500], - isHalfAllowed: true, - halfFilledIcon: Icons.star_half, - filledIcon: Icons.star, - emptyIcon: Icons.star, - ), - ], - ), + if (!widget.isLiveCareAppointment) showInfo(TranslationBase.of(context).hospital, widget.doctor.projectName!), + showInfo(TranslationBase.of(context).clinic, widget.doctor.clinicName!), + showInfo(TranslationBase.of(context).date, getDate()), + showInfo(TranslationBase.of(context).time, widget.selectedTime) ], ), - ), - ], + ], + ), ), ), - ), - ), - Container( - margin: EdgeInsets.only(top: 15.0), - child: Text(TranslationBase.of(context).appoInfo, - style: TextStyle( - fontSize: 22.0, - color: Colors.black, - letterSpacing: 0.9))), - Container( - child: Card( - color: Colors.white, - margin: EdgeInsets.fromLTRB(0.0, 5.0, 0.0, 16.0), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - side: BorderSide(color: Colors.grey[400], width: 0.6)), - child: Container( - padding: EdgeInsets.all(7.0), - width: MediaQuery.of(context).size.width, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - children: [ - !widget.isLiveCareAppointment ? Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Container( - margin: - EdgeInsets.fromLTRB(5.0, 0.0, 5.0, 0.0), - child: Image.asset( - "assets/images/new-design/icon_hospital.png"), - ), - Container( - margin: - EdgeInsets.fromLTRB(20.0, 5.0, 10.0, 5.0), - child: Text( - TranslationBase.of(context).hospital + - ": " + - widget.doctor.projectName, - style: TextStyle( - fontSize: 14.0, - color: Colors.grey[700], - letterSpacing: 1.0)), - ), - ], - ) : Container(), - Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Container( - margin: EdgeInsets.fromLTRB(5.0, 0.0, 5.0, 0.0), - child: Image.asset( - "assets/images/new-design/icon_hospital.png"), - ), - Container( - width: MediaQuery.of(context).size.width * 0.7, - margin: EdgeInsets.fromLTRB(20.0, 5.0, 10.0, 5.0), - child: Text( - TranslationBase.of(context).clinic + - ": " + - widget.doctor.clinicName, - overflow: TextOverflow.clip, - style: TextStyle( - fontSize: 14.0, - color: Colors.grey[700], - letterSpacing: 1.0)), - ), - ], - ), - Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Container( - child: Icon( - Icons.today, - color: Colors.grey[700], - ), - ), - Container( - margin: EdgeInsets.fromLTRB(20.0, 5.0, 20.0, 5.0), - child: Text( - TranslationBase.of(context).date + - ": " + - getDate(), - style: TextStyle( - fontSize: 14.0, - color: Colors.grey[700], - letterSpacing: 1.0)), + mHeight(12), + Container( + decoration: cardRadius(12), + margin: EdgeInsets.zero, + child: Padding( + padding: const EdgeInsets.fromLTRB(16, 20, 16, 20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).patientInfo, + style: TextStyle( + fontSize: 14.0, + color: Colors.black, + letterSpacing: -0.36, + fontWeight: FontWeight.w600, ), - ], - ), - Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Container( - child: Icon( - Icons.timer, - color: Colors.grey[700], - ), - ), - Container( - margin: EdgeInsets.fromLTRB(20.0, 5.0, 10.0, 5.0), - child: Text( - TranslationBase.of(context).time + - ": " + - widget.selectedTime, - style: TextStyle( - fontSize: 14.0, - color: Colors.grey[700], - letterSpacing: 1.0)), - ), - ], - ), - ], - ), - ), - ), - ), - Container( - margin: EdgeInsets.only(top: 15.0), - child: Text(TranslationBase.of(context).patientInfo, - style: TextStyle( - fontSize: 22.0, - color: Colors.black, - letterSpacing: 0.9))), - Container( - child: Card( - color: Colors.white, - margin: EdgeInsets.fromLTRB(0.0, 5.0, 0.0, 16.0), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - side: BorderSide(color: Colors.grey[400], width: 0.6)), - child: Container( - padding: EdgeInsets.all(7.0), - width: MediaQuery.of(context).size.width, - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Container( - padding: EdgeInsets.all(10.0), - child: Image.asset( - "assets/images/new-design/appointment_info.png", - fit: BoxFit.fill, - height: 60.0, - width: 60.0), - ), - Container( - width: MediaQuery.of(context).size.width * 0.58, - margin: EdgeInsets.fromLTRB(10.0, 5.0, 10.0, 5.0), - child: Column( + ), + mHeight(16), + Column( crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.max, children: [ - Text( - widget.authUser.firstName + - " " + - widget.authUser.lastName, - style: TextStyle( - fontSize: 14.0, - color: Colors.grey[900], - letterSpacing: 1.0)), - Container( - margin: EdgeInsets.only(top: 5.0), - child: Text( - TranslationBase.of(context).gender + - ": " + - widget.authUser.genderDescription, - style: TextStyle( - fontSize: 12.0, - color: Colors.grey[600], - letterSpacing: 1.0)), - ), - Container( - margin: EdgeInsets.only(top: 5.0, bottom: 3.0), - child: Text( - TranslationBase.of(context).age + - ": " + - widget.authUser.age.toString(), - style: TextStyle( - fontSize: 12.0, - color: Colors.grey[600], - letterSpacing: 1.0)), - ), + showInfo(TranslationBase.of(context).name, projectViewModel.user!.firstName! + " " + projectViewModel.user!.lastName!), + showInfo(TranslationBase.of(context).gender, projectViewModel.user!.genderDescription!), + showInfo(TranslationBase.of(context).age, projectViewModel.user!.age.toString()) ], ), - ), - ], + ], + ), ), ), - ), - ), - SizedBox( - height: 120.0, + ], ), - ], - ), + ), + SizedBox( + height: 120.0, + ), + ], ), ), bottomSheet: Container( - width: MediaQuery.of(context).size.width, - height: 50.0, - margin: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 20.0), - child: ButtonTheme( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10.0), - ), - minWidth: MediaQuery.of(context).size.width * 0.7, + color: CustomColors.appBackgroudGreyColor, + child: Container( + width: MediaQuery.of(context).size.width, height: 45.0, - child: RaisedButton( - color: new Color(0xFF60686b), - textColor: Colors.white, - disabledTextColor: Colors.white, - disabledColor: new Color(0xFFbcc2c4), - onPressed: () { - if (!widget.isLiveCareAppointment) { - insertAppointment(context, widget.doctor); - } else { - insertLiveCareScheduledAppointment(context, widget.doctor); - } - }, - child: Text(TranslationBase.of(context).bookNow, - style: TextStyle(fontSize: 18.0)), + margin: EdgeInsets.all(16), + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + minWidth: MediaQuery.of(context).size.width * 0.7, + height: 40.0, + child: CustomTextButton( + backgroundColor: CustomColors.green, + disabledForegroundColor: new Color(0xFFbcc2c4).withOpacity(0.38), + disabledBackgroundColor: new Color(0xFFbcc2c4).withOpacity(0.12), + elevation: 0, + onPressed: () async { + bool isLiveCareSchedule = await this.sharedPref.getBool(IS_LIVECARE_APPOINTMENT) ?? false; + + if (widget.isWalkinAppointment) { + getWalkinAppointmentPatientShare(); + } else { + if (isLiveCareSchedule) { + insertLiveCareScheduledAppointment(context, widget.doctor); + } else { + checkPatientHasDermaPackage(widget.doctor, projectViewModel.user.patientID!); + } + } + }, + child: Text(widget.isWalkinAppointment ? TranslationBase.of(context).addToWaitingList : TranslationBase.of(context).bookAppo, + style: TextStyle(fontSize: 16.0, letterSpacing: -0.48, color: Colors.white)), + ), ), ), ), ); } - cancelAppointment(DoctorList docObject, AppoitmentAllHistoryResultList appo, - BuildContext context) { - ConfirmDialog.closeAlertDialog(context); + getWalkinAppointmentPatientShare() { + String errorMsg = ""; + AppoitmentAllHistoryResultList appo = new AppoitmentAllHistoryResultList(); + GifLoaderDialogUtils.showMyDialog(context); + appo.doctorTitle = widget.doctor.doctorTitle; + appo.doctorNameObj = widget.doctor.name; + appo.appointmentDate = DateUtil.convertDateToString(DateTime.now()); + appo.projectName = widget.doctor.projectName; + + widget.service + .getPatientShareForWalkInAppointment( + widget.doctor.clinicID!, + widget.doctor.projectID!, + widget.doctor.doctorID!, + ) + .then((res) { + widget.patientShareResponse = new PatientShareResponse.fromJson(res["OnlineCheckInAppointmentsWalkInModel"]); + GifLoaderDialogUtils.hideDialog(context); + + isInsured = res["IsInsured"]; + isEligible = res["IsEligible"]; + isCash = res["IsCash"]; + + if (isCash) { + if (widget.patientShareResponse.patientShareWithTax != 0 || widget.patientShareResponse.patientShareWithTax != 0.0) { + openPaymentDialog(appo, widget.patientShareResponse!); + } else { + insertWalkInAppointment(context, widget.doctor, widget.initialSlotDuration, null); + } + } else { + if (isInsured && isEligible) { + if (widget.patientShareResponse.patientShareWithTax != 0 || widget.patientShareResponse.patientShareWithTax != 0.0) { + openPaymentDialog(appo, widget.patientShareResponse!); + } else { + insertWalkInAppointment(context, widget.doctor, widget.initialSlotDuration, null); + } + } else { + if (isInsured && !isEligible) { + errorMsg = TranslationBase.of(context).invalidEligibility; + } else { + errorMsg = TranslationBase.of(context).invalidInsurance; + } + ConfirmDialog dialog = new ConfirmDialog( + isDissmissable: false, + context: context, + confirmMessage: errorMsg, + okText: TranslationBase.of(context).updateInsuranceText, + cancelText: TranslationBase.of(context).continueCash, + okFunction: () => {openUpdateInsurance()}, + cancelFunction: () => {continueAsCashForWalkIn(widget.doctor.projectID!)}); + dialog.showAlertDialog(context); + } + } + + // widget.patientShareResponse = new PatientShareResponse.fromJson(res["OnlineCheckInAppointmentsWalkInModel"]); + // GifLoaderDialogUtils.hideDialog(context); + // if (widget.patientShareResponse.patientShareWithTax != 0 || widget.patientShareResponse.patientShareWithTax != 0.0) { + // openPaymentDialog(appo, widget.patientShareResponse!); + // } else { + // insertWalkInAppointment(context, widget.doctor, widget.initialSlotDuration, null); + // } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + + openPaymentDialog(AppoitmentAllHistoryResultList appo, PatientShareResponse patientShareResponse) { + showGeneralDialog( + barrierColor: Colors.black.withOpacity(0.5), + transitionBuilder: (context, a1, a2, widget) { + final curvedValue = Curves.easeInOutBack.transform(a1.value) - 1.0; + return Transform( + transform: Matrix4.translationValues(0.0, curvedValue * 200, 0.0), + child: Opacity( + opacity: a1.value, + child: PaymentDialog( + appo: appo, + patientShareResponse: patientShareResponse, + isCashPatient: isCash, + onPaymentMethodSelected: () {}, + ), + ), + ); + }, + transitionDuration: Duration(milliseconds: 500), + barrierDismissible: false, + barrierLabel: '', + context: context, + pageBuilder: (context, animation1, animation2) => SizedBox()).then((value) { + print(value); + if (value != null) { + navigateToPaymentMethod(context, value as PatientShareResponse); + // projectViewModel.analytics.todoList.to_do_list_confirm_payment_details(appo); + } else { + // projectViewModel.analytics.todoList.to_do_list_cancel_payment_details(appo); + } + }); + } + + Future navigateToPaymentMethod(context, PatientShareResponse patientShareResponse) async { + AppoitmentAllHistoryResultList appo = new AppoitmentAllHistoryResultList(); + appo.projectID = widget.doctor.projectID; + appo.clinicID = widget.doctor.clinicID; + appo.clinicName = widget.doctor.clinicName; + appo.projectName = widget.doctor.projectName; + appo.appointmentNo = DateTime.now().millisecondsSinceEpoch; + appo.isLiveCareAppointment = false; + appo.doctorID = widget.doctor.doctorID; + appo.appointmentDate = DateUtil.convertDateToString(DateTime.now()); //widget.patientShareResponse.appointmentDate; + appo.serviceID = widget.patientShareResponse.serviceID; + + Navigator.push( + context, + FadePage( + page: PaymentMethod( + onSelectedMethod: (String metohd, [String? selectedInstallmentPlan]) { + setState(() {}); + }, + patientShare: widget.patientShareResponse.patientShareWithTax))) + .then((value) { + selectedPaymentMethod = value[0]; + if (value != null) { + if (selectedPaymentMethod == "ApplePay") { + if (projectViewModel.havePrivilege(103)) { + startApplePay(appo, patientShareResponse); + } else { + openPayment(value, projectViewModel.user, double.parse(patientShareResponse.patientShareWithTax.toString()), patientShareResponse, appo); + } + } else { + openPayment(value, projectViewModel.user, double.parse(patientShareResponse.patientShareWithTax.toString()), patientShareResponse, appo); + } + projectViewModel.analytics.appointment.payment_method(appointment_type: 'Walk-In', clinic: widget.doctor.clinicName, payment_method: value[0], payment_type: 'appointment'); + } + }); + } + + void startApplePay(AppoitmentAllHistoryResultList appo, PatientShareResponse patientShareResponse) async { + transID = Utils.getAppointmentTransID(appo.projectID, appo.clinicID, appo.appointmentNo); + print("TransactionID: $transID"); + GifLoaderDialogUtils.showMyDialog(context); + + LiveCareService service = new LiveCareService(); + ApplePayInsertRequest applePayInsertRequest = new ApplePayInsertRequest(); + + PayfortProjectDetailsRespModel? payfortProjectDetailsRespModel; + await context.read().getProjectDetailsForPayfort(projectId: appo.projectID, serviceId: ServiceTypeEnum.appointmentPayment.getIdFromServiceEnum()).then((value) { + payfortProjectDetailsRespModel = value!; + }); + + applePayInsertRequest.clientRequestID = transID; + applePayInsertRequest.clinicID = appo.clinicID; + applePayInsertRequest.currency = projectViewModel.user.outSA == 1 ? "AED" : "SAR"; + // applePayInsertRequest.customerEmail = projectViewModel.authenticatedUserObject.user.emailAddress; + applePayInsertRequest.customerEmail = "CustID_${projectViewModel.user.patientID}@HMG.com"; + applePayInsertRequest.customerID = projectViewModel.user.patientID; + applePayInsertRequest.customerName = projectViewModel.user.firstName! + " " + projectViewModel.user.lastName!; + applePayInsertRequest.deviceToken = await AppSharedPreferences().getString(PUSH_TOKEN); + applePayInsertRequest.voipToken = await AppSharedPreferences().getString(ONESIGNAL_APNS_TOKEN); + applePayInsertRequest.doctorID = appo.doctorID; + applePayInsertRequest.projectID = appo.projectID.toString(); + applePayInsertRequest.serviceID = ServiceTypeEnum.appointmentPayment.getIdFromServiceEnum().toString(); + applePayInsertRequest.channelID = 3; + applePayInsertRequest.patientID = projectViewModel.user.patientID; + applePayInsertRequest.patientTypeID = projectViewModel.user.patientType; + applePayInsertRequest.patientOutSA = projectViewModel.user.outSA; + applePayInsertRequest.appointmentDate = appo.appointmentDate; + applePayInsertRequest.appointmentNo = appo.appointmentNo; + applePayInsertRequest.orderDescription = "Appointment Payment"; + applePayInsertRequest.liveServiceID = "0"; + applePayInsertRequest.latitude = "0.0"; + applePayInsertRequest.longitude = "0.0"; + applePayInsertRequest.amount = patientShareResponse.patientShareWithTax.toString(); + applePayInsertRequest.isSchedule = appo.isLiveCareAppointment! ? "1" : "0"; + applePayInsertRequest.language = projectViewModel.isArabic ? 'ar' : 'en'; + applePayInsertRequest.languageID = projectViewModel.isArabic ? 1 : 2; + applePayInsertRequest.userName = projectViewModel.user.patientID; + applePayInsertRequest.responseContinueURL = "http://hmg.com/Documents/success.html"; + applePayInsertRequest.backClickUrl = "http://hmg.com/Documents/success.html"; + applePayInsertRequest.paymentOption = "ApplePay"; + + applePayInsertRequest.isMobSDK = true; + applePayInsertRequest.merchantReference = transID; + applePayInsertRequest.merchantIdentifier = payfortProjectDetailsRespModel!.merchantIdentifier!; + applePayInsertRequest.commandType = "PURCHASE"; + applePayInsertRequest.signature = payfortProjectDetailsRespModel!.signature; + applePayInsertRequest.accessCode = payfortProjectDetailsRespModel!.accessCode; + applePayInsertRequest.shaRequestPhrase = payfortProjectDetailsRespModel!.shaRequest; + applePayInsertRequest.shaResponsePhrase = payfortProjectDetailsRespModel!.shaResponse; + applePayInsertRequest.returnURL = ""; + + service.applePayInsertRequest(applePayInsertRequest, context).then((res) async { + if (res["MessageStatus"] == 1) { + await context.read().initiateApplePayWithPayfort( + customerName: projectViewModel.user.firstName! + " " + projectViewModel.user.lastName!, + // customerEmail: projectViewModel.authenticatedUserObject.user.emailAddress, + customerEmail: "CustID_${projectViewModel.user.patientID}@HMG.com", + orderDescription: "Walk-In appointment payment", + orderAmount: double.parse(patientShareResponse.patientShareWithTax.toString()), + merchantReference: transID, + payfortProjectDetailsRespModel: payfortProjectDetailsRespModel, + currency: projectViewModel.user.outSA == 1 ? "AED" : "SAR", + onFailed: (failureResult) async { + GifLoaderDialogUtils.hideDialog(context); + log("failureResult: ${failureResult.message.toString()}"); + AppToast.showErrorToast(message: failureResult.message.toString()); + }, + onSuccess: (successResult) async { + log("Payfort: ${successResult.responseMessage}"); + await context.read().addPayfortApplePayResponse(projectViewModel.user.patientID!, result: successResult); + checkPaymentStatus(appo); + }, + projectId: appo.projectID, + serviceTypeEnum: ServiceTypeEnum.appointmentPayment, + ); + } else { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: "An error occurred while processing your request"); + } + }).catchError((err) { + print(err); + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + }); + } + + openPayment(List paymentMethod, AuthenticatedUser authenticatedUser, num amount, PatientShareResponse patientShareResponse, AppoitmentAllHistoryResultList appo) async { + browser = new MyInAppBrowser(onExitCallback: onBrowserExit, appo: appo, onLoadStartCallback: onBrowserLoadStart, context: context); + selectedPaymentMethod = paymentMethod[0]; + selectedInstallments = paymentMethod[1]; + transID = Utils.getAppointmentTransID(appo.projectID, appo.clinicID, appo.appointmentNo); + browser.openPaymentBrowser( + amount, + "Walk-In appointment payment", + transID!, + appo.projectID.toString(), + authenticatedUser.emailAddress!, + paymentMethod[0]!, + authenticatedUser.patientType, + authenticatedUser.firstName!, + authenticatedUser.patientID, + authenticatedUser, + browser, + widget.patientShareResponse.isLiveCareAppointment!, + "2", + widget.patientShareResponse.isLiveCareAppointment! ? widget.patientShareResponse.clinicID.toString() : "", + context, + widget.patientShareResponse.appointmentDate, + widget.patientShareResponse.appointmentNo, + widget.patientShareResponse.clinicID, + widget.patientShareResponse.doctorID, + paymentMethod[1]); + // } + } + + onBrowserLoadStart(String url) { + if (selectedPaymentMethod == "TAMARA") { + if (Platform.isAndroid) { + Uri uri = new Uri.dataFromString(url); + tamaraPaymentStatus = uri.queryParameters['status']; + tamaraOrderID = uri.queryParameters['AuthorizePaymentId']; + } else { + Uri uri = new Uri.dataFromString(url); + tamaraPaymentStatus = uri.queryParameters['paymentStatus']; + tamaraOrderID = uri.queryParameters['orderId']; + } + } + + MyInAppBrowser.successURLS.forEach((element) { + if (url.contains(element)) { + if (browser.isOpened()) browser.close(); + MyInAppBrowser.isPaymentDone = true; + return; + } + }); + + MyInAppBrowser.errorURLS.forEach((element) { + if (url.contains(element)) { + if (browser.isOpened()) browser.close(); + MyInAppBrowser.isPaymentDone = false; + return; + } + }); + } + + onBrowserExit(AppoitmentAllHistoryResultList appo, bool isPaymentMade) { + try { + if (selectedPaymentMethod == "TAMARA") { + checkTamaraPaymentStatus(transID!, appo); + // if (tamaraPaymentStatus != null && tamaraPaymentStatus!.toLowerCase() == "approved") { + // updateTamaraRequestStatus("success", "14", Utils.getAppointmentTransID(appo.projectID, appo.clinicID, appo.appointmentNo), tamaraOrderID!, num.parse(selectedInstallments!), appo); + // } else { + // updateTamaraRequestStatus( + // "Failed", "00", Utils.getAppointmentTransID(appo.projectID, appo.clinicID, appo.appointmentNo), tamaraOrderID! != null ? tamaraOrderID! : "", num.parse(selectedInstallments!), appo); + // } + } else { + checkPaymentStatus(appo); + } + } catch (err) { + print(err); + } + } + + checkTamaraPaymentStatus(String orderID, AppoitmentAllHistoryResultList appo) { + GifLoaderDialogUtils.showMyDialog(context); + DoctorsListService service = new DoctorsListService(); + service.getTamaraPaymentStatus(orderID).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res["status"].toString().toLowerCase() == "success") { + updateTamaraRequestStatus("success", "14", orderID, tamaraOrderID!, int.parse(selectedInstallments!), appo); + } else { + updateTamaraRequestStatus( + "Failed", "00", Utils.getAppointmentTransID(appo.projectID!, appo.clinicID!, appo.appointmentNo!), tamaraOrderID != null ? tamaraOrderID! : "", int.parse(selectedInstallments!), appo); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + + updateTamaraRequestStatus(String responseMessage, String status, String clientRequestID, String tamaraOrderID, num selectedInstallments, AppoitmentAllHistoryResultList appo) { + GifLoaderDialogUtils.showMyDialog(context); + try { + DoctorsListService service = new DoctorsListService(); + service.updateTamaraRequestStatus(responseMessage, status, clientRequestID, tamaraOrderID, selectedInstallments).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (tamaraPaymentStatus!.toLowerCase() == "approved") { + insertWalkInAppointment(context, widget.doctor, widget.initialSlotDuration, tamaraOrderID); + } + }).catchError((err) { + print(err); + AppToast.showErrorToast(message: err); + GifLoaderDialogUtils.hideDialog(context); + }); + } catch (err) { + print(err); + } + } + + addAdvancedNumberRequestTamara(String advanceNumber, String paymentReference, String appointmentID, AppoitmentAllHistoryResultList appo) { + DoctorsListService service = new DoctorsListService(); + service.addAdvancedNumberRequest(advanceNumber, paymentReference, appointmentID, context).then((res) {}).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + + markAppointmentForTamara(AppoitmentAllHistoryResultList appo) { + GifLoaderDialogUtils.showMyDialog(context); + DoctorsListService service = new DoctorsListService(); + service.markAppointmentForTamara(appo.projectID!, appo.appointmentNo.toString()).then((res) { + GifLoaderDialogUtils.hideDialog(context); + sendNfcCheckInRequest(projectViewModel.waitingAppointmentNFCCode, 2, int.parse(appo.appointmentNo), projectViewModel.waitingAppointmentProjectID, appo.clinicID); + }).catchError((err) { + print(err); + AppToast.showErrorToast(message: err); + GifLoaderDialogUtils.hideDialog(context); + }); + } + + checkPaymentStatus(AppoitmentAllHistoryResultList appo) { + String txn_ref; + num amount; + String payment_method; + final currency = projectViewModel.user!.outSA == 0 ? "sar" : 'aed'; GifLoaderDialogUtils.showMyDialog(context); DoctorsListService service = new DoctorsListService(); - service.cancelAppointment(appo, context).then((res) { + service.checkPaymentStatus(transID!, false, context).then((res) { + String paymentInfo = res['Response_Message']; + if (paymentInfo == 'Success') { + txn_ref = res['Merchant_Reference']; + amount = res['Amount']; + payment_method = res['PaymentMethod']; + GifLoaderDialogUtils.hideDialog(context); + insertWalkInAppointment(context, widget.doctor, widget.initialSlotDuration, res); + projectViewModel.analytics.appointment.payment_success( + appointment_type: 'Walk-In', payment_method: payment_method, clinic: appo.clinicName, hospital: appo.projectName, txn_amount: "$amount", txn_currency: currency, txn_number: txn_ref); + } else { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: res['Response_Message']); + projectViewModel.analytics.appointment.payment_fail( + appointment_type: 'Walk-In', + payment_method: selectedPaymentMethod, + clinic: appo.clinicName, + hospital: appo.projectName, + txn_amount: widget.patientShareResponse.patientShareWithTax.toString(), + txn_currency: currency, + error_type: res['Response_Message']); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err.toString()); + print(err); + }); + } + + Widget showInfo(String title, String des) { + return Container( + child: Row( + children: [ + Text( + title + ": ", + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + color: Color(0xFF575757), + letterSpacing: -0.4, + ), + ), + Text( + des, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + color: Colors.black, + letterSpacing: -0.48, + ), + ), + ], + ), + ); + } + + cancelAppointment(DoctorList docObject, AppoitmentAllHistoryResultList appo, BuildContext context, {int? invoiceNumber, int? lineItemNo, String? invoiceNoVP}) async { + ConfirmDialog.closeAlertDialog(context); + GifLoaderDialogUtils.showMyDialog(context, barrierDismissible: false); + DoctorsListService service = new DoctorsListService(); + bool isLiveCareSchedule = await this.sharedPref.getBool(IS_LIVECARE_APPOINTMENT) ?? false; + service.cancelAppointment(appo, context, isReschedule: true).then((res) { GifLoaderDialogUtils.hideDialog(context); if (res['MessageStatus'] == 1) { - Future.delayed(new Duration(milliseconds: 1500), () { - if (!widget.isLiveCareAppointment) { - insertAppointment(context, widget.doctor); - } else { + Future.delayed(Duration(milliseconds: 500), () async { + if (isLiveCareSchedule != null && isLiveCareSchedule) { insertLiveCareScheduledAppointment(context, widget.doctor); + } else { + insertAppointment(context, widget.doctor, widget.initialSlotDuration, invoiceNumber: invoiceNumber, lineItemNo: lineItemNo, invoiceNoVP: invoiceNoVP); + } + }); + } else { + AppToast.showErrorToast(message: res['ErrorEndUserMessage']); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + }); + } + + checkPatientNphiesEligibility(DoctorList docObject, String appointmentNo, BuildContext context) { + widget.service.checkPatientNphiesEligibility(docObject.projectID!).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res["isNphiesMatchedWithVida"]) { + getPatientShare(context, appointmentNo, docObject.clinicID!, docObject.projectID!, docObject); + getToDoCount(); + } else { + ConfirmDialog dialog = ConfirmDialog( + isDissmissable: false, + context: context, + confirmMessage: res['ErrorEndUserMessage'], + okText: "Update insurance", + cancelText: "Continue as cash", + okFunction: () => {openUpdateInsurance()}, + cancelFunction: () => {continueAsCash(docObject, appointmentNo, false)}); + dialog.showAlertDialog(context); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } + + void openUpdateInsurance() { + Navigator.pushAndRemoveUntil(context, MaterialPageRoute(builder: (context) => LandingPage()), (Route r) => false); + Navigator.push(context, FadePage(page: InsuranceUpdate())); + } + + void continueAsCash(DoctorList docObject, String appointmentNo, bool isLiveCareAppointment) { + GifLoaderDialogUtils.showMyDialog(context); + widget.service.convertPatientToCash(docObject.projectID!).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res["MessageStatus"] == 1) { + if (isLiveCareAppointment) { + getLiveCareAppointmentPatientShare(context, appointmentNo, docObject!.clinicID!, docObject.projectID!, docObject); + } else { + getPatientShare(context, appointmentNo, docObject.clinicID!, docObject.projectID!, docObject); + } + getToDoCount(); + } else { + AppToast.showErrorToast(message: res["ErrorEndUserMessage"]); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + + void continueAsCashForWalkIn(int projectID) { + GifLoaderDialogUtils.showMyDialog(context); + widget.service.convertPatientToCash(projectID).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res["MessageStatus"] == 1) { + getWalkinAppointmentPatientShare(); + } else { + AppToast.showErrorToast(message: res["ErrorEndUserMessage"]); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + + insertWalkInAppointment(context, DoctorList docObject, int initialSlotDuration, paymentRes) async { + GifLoaderDialogUtils.showMyDialog( + context, + ); + AppoitmentAllHistoryResultList appo = new AppoitmentAllHistoryResultList(); + appo.doctorID = docObject.doctorID; + appo.clinicID = docObject.clinicID; + appo.projectID = docObject.projectID; + + widget.service + .insertWalkInAppointment( + docObject.doctorID!, docObject.clinicID!, docObject.projectID!, widget.selectedTime, widget.selectedDate, initialSlotDuration, projectViewModel.isArabic ? 1 : 2, context) + .then((res) { + if (res['MessageStatus'] == 1) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showSuccessToast(message: TranslationBase.of(context).bookedSuccess); + appo.appointmentNo = res["AppointmentNo"]; // Add appointment No to the appointment project + Future.delayed(Duration(milliseconds: 500), () { + if (selectedPaymentMethod == "TAMARA") { + markAppointmentForTamara(appo); + addAdvancedNumberRequestTamara("Tamara-Advance-0000", paymentRes, res["AppointmentNo"].toString(), appo); + } else { + if (widget.patientShareResponse.patientShareWithTax != 0 || widget.patientShareResponse.patientShareWithTax != 0.0) { + createAdvancePayment(paymentRes, appo); + } else { + sendNfcCheckInRequest(projectViewModel.waitingAppointmentNFCCode, 2, int.parse(res["AppointmentNo"]), projectViewModel.waitingAppointmentProjectID, appo.clinicID); + } } }); } else { + GifLoaderDialogUtils.hideDialog(context); AppToast.showErrorToast(message: res['ErrorEndUserMessage']); } }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + }); + } + + createAdvancePayment(res, AppoitmentAllHistoryResultList appo) { + GifLoaderDialogUtils.showMyDialog( + context, + ); + DoctorsListService service = new DoctorsListService(); + String paymentReference = res['Fort_id'].toString(); + service.createAdvancePayment(appo, appo.projectID.toString(), res['Amount'], res['Fort_id'], res['PaymentMethod'], context).then((res) { + GifLoaderDialogUtils.hideDialog(context); + addAdvancedNumberRequest( + Utils.isVidaPlusProject(projectViewModel, appo.projectID!) + ? res['OnlineCheckInAppointments'][0]['AdvanceNumber_VP'].toString() + : res['OnlineCheckInAppointments'][0]['AdvanceNumber'].toString(), + paymentReference, + appo.appointmentNo.toString(), + appo); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + + addAdvancedNumberRequest(String advanceNumber, String paymentReference, String appointmentID, AppoitmentAllHistoryResultList appo) { + GifLoaderDialogUtils.showMyDialog( + context, + ); + DoctorsListService service = new DoctorsListService(); + service.addAdvancedNumberRequest(advanceNumber, paymentReference, appointmentID, context).then((res) { + GifLoaderDialogUtils.hideDialog(context); + sendNfcCheckInRequest(projectViewModel.waitingAppointmentNFCCode, 2, int.parse(appointmentID), projectViewModel.waitingAppointmentProjectID, appo.clinicID); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); print(err); + }); + } + + sendNfcCheckInRequest(String nfcId, int checkInBy, int appoNo, int projectID, int clinicID) { + GifLoaderDialogUtils.showMyDialog(context); + DoctorsListService service = new DoctorsListService(); + service.sendCheckinNfcRequest(appoNo, nfcId, projectID, checkInBy, clinicID, context).then((res) { GifLoaderDialogUtils.hideDialog(context); + _showMyDialog(res["SuccessMsg"], this.context); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + _showMyDialog(err, this.context); }); } - insertAppointment(context, DoctorList docObject) { + checkPatientHasDermaPackage(DoctorList doctor, int patientID) { GifLoaderDialogUtils.showMyDialog(context); + widget.service + .checkPatientHasDermaPackage( + patientID!, + doctor.clinicID!, + doctor.projectID!, + doctor.doctorID!, + projectViewModel.isArabic ? 1 : 2, + context, + ) + .then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res['MessageStatus'] == 1 && res['PatientPackageComponent']['Message'] == 'Success') { + PatientPackageComponent package = PatientPackageComponent.fromJson(res['PatientPackageComponent']); + + ConfirmDialog dialog = ConfirmDialog( + context: context, + confirmMessage: "${TranslationBase.of(context).existingPackage} ${package.patientPackageComponents![0].procedureName}, ${TranslationBase.of(context).continueOrbookNew}", + okText: TranslationBase.of(context).proceedPackage, + cancelText: TranslationBase.of(context).newAppointment, + okFunction: () => { + ConfirmDialog.closeAlertDialog(context), + insertAppointment(context, widget.doctor, widget.initialSlotDuration, + invoiceNumber: package.patientPackageComponents![0].invoiceNo, + lineItemNo: package.patientPackageComponents![0].lineItemNo, + invoiceNoVP: package.patientPackageComponents![0].invoiceNo_VP.toString()) + }, + cancelFunction: () => {insertAppointment(context, widget.doctor, widget.initialSlotDuration)}, + ); + dialog.showAlertDialog(context); + } else { + insertAppointment(context, widget.doctor, widget.initialSlotDuration); + } + }).onError((error, stackTrace) { + insertAppointment(context, widget.doctor, widget.initialSlotDuration); + }); + } + + insertAppointment(context, DoctorList docObject, int initialSlotDuration, {int? invoiceNumber, int? lineItemNo, String? invoiceNoVP}) async { + final timeSlot = DocAvailableAppointments.selectedAppoDateTime; + String logs = await sharedPref.getString('selectedLogSlots'); + List decodedLogs = json.decode(logs); + GifLoaderDialogUtils.showMyDialog(context, barrierDismissible: false); AppoitmentAllHistoryResultList appo; widget.service - .insertAppointment( - docObject.doctorID, - docObject.clinicID, - docObject.projectID, - widget.selectedTime, - widget.selectedDate, - context) + // .insertAppointment(docObject.doctorID!, docObject.clinicID!, docObject.projectID!, widget.selectedTime, widget.selectedDate, initialSlotDuration, context, 'null', null, null, projectViewModel) + .insertAppointment(docObject.doctorID!, docObject.clinicID!, docObject.projectID!, widget.selectedTime, widget.selectedDate, initialSlotDuration, projectViewModel.isArabic ? 1 : 2, context, + null, null, null, projectViewModel, invoiceNumber, lineItemNo, invoiceNoVP) .then((res) { if (res['MessageStatus'] == 1) { - AppToast.showSuccessToast( - message: TranslationBase.of(context).bookedSuccess); - print(res['AppointmentNo']); + AppToast.showSuccessToast(message: TranslationBase.of(context).bookedSuccess); - Future.delayed(new Duration(milliseconds: 500), () { - getPatientShare(context, res['AppointmentNo'], docObject.clinicID, - docObject.projectID, docObject); + Future.delayed(Duration(milliseconds: 500), () { + // checkPatientNphiesEligibility(docObject, res['AppointmentNo'], context); getToDoCount(); + getPatientShare(context, res['AppointmentNo'], docObject.clinicID!, docObject.projectID!, docObject); }); + widget.service.logDoctorFreeSlots(docObject.doctorID!, docObject.clinicID!, docObject.projectID!, decodedLogs, res['AppointmentNo'], context).then((res) { + if (res['MessageStatus'] == 1) { + print("Logs Saved"); + } else { + print("Error Saving logs"); + } + }); + projectViewModel.analytics.appointment.book_appointment_confirmation_success(appointment_type: 'regular', dateTime: timeSlot!, doctor: widget.doctor); } else { GifLoaderDialogUtils.hideDialog(context); - appo = new AppoitmentAllHistoryResultList(); + appo = AppoitmentAllHistoryResultList(); appo.appointmentNo = res['SameClinicApptList'][0]['AppointmentNo']; appo.clinicID = res['SameClinicApptList'][0]['DoctorID']; appo.projectID = res['SameClinicApptList'][0]['ProjectID']; @@ -453,44 +938,42 @@ class _BookConfirmState extends State { appo.originalProjectID = 0; appo.appointmentDate = res['SameClinicApptList'][0]['AppointmentDate']; - ConfirmDialog dialog = new ConfirmDialog( - context: context, - confirmMessage: res['ErrorEndUserMessage'], - okText: TranslationBase.of(context).confirm, - cancelText: TranslationBase.of(context).cancel_nocaps, - okFunction: () => {cancelAppointment(docObject, appo, context)}, - cancelFunction: () => {}); + ConfirmDialog dialog = ConfirmDialog( + context: context, + confirmMessage: res['ErrorEndUserMessage'], + okText: TranslationBase.of(context).confirm, + cancelText: TranslationBase.of(context).cancel_nocaps, + okFunction: () => {cancelAppointment(docObject, appo, context, invoiceNumber: invoiceNumber, lineItemNo: lineItemNo)}, + cancelFunction: () => {}, + ); dialog.showAlertDialog(context); } }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); - AppToast.showErrorToast(message: err); - print(err); + AppToast.showErrorToast(message: err, localContext: context); }); + projectViewModel.analytics.appointment.book_appointment_click_confirm(appointment_type: 'regular', dateTime: timeSlot!, doctor: widget.doctor); } insertLiveCareScheduledAppointment(context, DoctorList docObject) { - GifLoaderDialogUtils.showMyDialog(context); + final timeSlot = DocAvailableAppointments.selectedAppoDateTime; + widget.selectedDate = timeSlot!.toUtc().add(Duration(hours: 3)).toString().split(" ")[0]; + widget.selectedTime = timeSlot.toUtc().add(Duration(hours: 3)).toString().split(" ")[1].substring(0, 5); + GifLoaderDialogUtils.showMyDialog(context, barrierDismissible: false); AppoitmentAllHistoryResultList appo; widget.service .insertLiveCareScheduleAppointment( - docObject.doctorID, - docObject.clinicID, - docObject.projectID, - docObject.serviceID, - widget.selectedTime, - widget.selectedDate, - context) + docObject!.doctorID!, docObject.clinicID!, docObject.projectID!, docObject.serviceID, widget.selectedTime, widget.selectedDate, projectViewModel.isArabic ? 1 : 2, context) .then((res) { if (res['MessageStatus'] == 1) { - AppToast.showSuccessToast(message: "Appointment Booked Successfully"); + AppToast.showSuccessToast(message: TranslationBase.of(context).bookedSuccess); print(res['AppointmentNo']); Future.delayed(new Duration(milliseconds: 500), () { - getLiveCareAppointmentPatientShare(context, res['AppointmentNo'], - docObject.clinicID, docObject.projectID, docObject); + getLiveCareAppointmentPatientShare(context, res['AppointmentNo'], docObject!.clinicID!, docObject.projectID!, docObject); getToDoCount(); }); + projectViewModel.analytics.appointment.book_appointment_confirmation_success(appointment_type: 'livecare', dateTime: timeSlot, doctor: widget.doctor); } else { GifLoaderDialogUtils.hideDialog(context); appo = new AppoitmentAllHistoryResultList(); @@ -519,47 +1002,106 @@ class _BookConfirmState extends State { AppToast.showErrorToast(message: err); print(err); }); + + projectViewModel.analytics.appointment.book_appointment_click_confirm(appointment_type: 'livecare', dateTime: timeSlot, doctor: widget.doctor); } getToDoCount() { - toDoProvider.setState(0, true); + toDoProvider.setState(0, 0, true, toDoProvider.notificationsCount); ClinicListService service = new ClinicListService(); service.getActiveAppointmentNo(context).then((res) { print(res['AppointmentActiveNumber']); if (res['MessageStatus'] == 1) { - toDoProvider.setState(res['AppointmentActiveNumber'], true); + toDoProvider.setState(res['AppointmentActiveNumber'], res['AncillaryOrderListCount'], true, toDoProvider.notificationsCount); + // toDoProvider.setState(res['AppointmentActiveNumber'], true, toDoProvider.notificationsCount); } else {} }).catchError((err) { print(err); }); } - getPatientShare(context, String appointmentNo, int clinicID, int projectID, - DoctorList docObject) { - widget.service - .getPatientShare(appointmentNo, clinicID, projectID, context) - .then((res) { - print(res); - widget.patientShareResponse = new PatientShareResponse.fromJson(res); - navigateToBookSuccess(context, docObject, widget.patientShareResponse); + getPatientShare(context, String appointmentNo, int clinicID, int projectID, DoctorList docObject) { + int languageID = projectViewModel.isArabic ? 1 : 2; + String errorMsg = ""; + GifLoaderDialogUtils.showMyDialog(context, barrierDismissible: false); + widget.service.getPatientShare(appointmentNo, clinicID, projectID, languageID, context).then((res) { + projectViewModel.selectedBodyPartList.clear(); + projectViewModel.laserSelectionDuration = 0; + if (res['OnlineCheckInAppointments'].length != 0) { + widget.patientShareResponse = new PatientShareResponse.fromJson(res['OnlineCheckInAppointments'][0]); + } + + isInsured = res["IsInsured"]; + isEligible = res["IsEligible"]; + isCash = res["IsCash"]; + + if (isCash) { + navigateToBookSuccess(context, docObject, widget.patientShareResponse, isCash); + } else { + if (isInsured && isEligible) { + navigateToBookSuccess(context, docObject, widget.patientShareResponse, isCash); + } else { + if (isInsured && !isEligible) { + errorMsg = TranslationBase.of(context).invalidEligibility; + } else { + errorMsg = TranslationBase.of(context).invalidInsurance; + } + ConfirmDialog dialog = new ConfirmDialog( + isDissmissable: false, + context: context, + confirmMessage: errorMsg, + okText: TranslationBase.of(context).updateInsuranceText, + cancelText: TranslationBase.of(context).continueCash, + okFunction: () => {openUpdateInsurance()}, + cancelFunction: () => {continueAsCash(docObject, appointmentNo, false)}); + dialog.showAlertDialog(context); + } + } }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); - AppToast.showErrorToast(message: err); + // AppToast.showErrorToast(message: err); + projectViewModel.selectedBodyPartList.clear(); + projectViewModel.laserSelectionDuration = 0; navigateToHome(context); print(err); }); } - getLiveCareAppointmentPatientShare(context, String appointmentNo, - int clinicID, int projectID, DoctorList docObject) { - widget.service - .getLiveCareAppointmentPatientShare( - appointmentNo, clinicID, projectID, context) - .then((res) { - print(res); + getLiveCareAppointmentPatientShare(context, String appointmentNo, int clinicID, int projectID, DoctorList docObject) { + String errorMsg = ""; + + widget.service.getLiveCareAppointmentPatientShare(appointmentNo, clinicID, projectID, projectViewModel.isArabic ? 1 : 2, context).then((res) { widget.patientShareResponse = new PatientShareResponse.fromJson(res); GifLoaderDialogUtils.hideDialog(context); - navigateToBookSuccess(context, docObject, widget.patientShareResponse); + + isInsured = res["IsInsured"]; + isEligible = res["IsEligible"]; + isCash = res["IsCash"]; + + if (isCash) { + navigateToBookSuccess(context, docObject, widget.patientShareResponse, isCash); + } else { + if (isInsured && isEligible) { + navigateToBookSuccess(context, docObject, widget.patientShareResponse, isCash); + } else { + if (isInsured && !isEligible) { + errorMsg = TranslationBase.of(context).invalidEligibility; + } else { + errorMsg = TranslationBase.of(context).invalidInsurance; + } + ConfirmDialog dialog = new ConfirmDialog( + isDissmissable: false, + context: context, + confirmMessage: errorMsg, + okText: TranslationBase.of(context).updateInsuranceText, + cancelText: TranslationBase.of(context).continueCash, + okFunction: () => {openUpdateInsurance()}, + cancelFunction: () => {continueAsCash(docObject, appointmentNo, true)}); + dialog.showAlertDialog(context); + } + } + + // navigateToBookSuccess(context, docObject, widget.patientShareResponse, false); }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); AppToast.showErrorToast(message: err); @@ -578,26 +1120,26 @@ class _BookConfirmState extends State { } String getDate() { - var dateObj = new DateTime( - int.parse(widget.selectedDate.split("-")[0]), - int.parse(widget.selectedDate.split("-")[1]), - int.parse(widget.selectedDate.split("-")[2]), - 0, - 0, - 0, - 0); + var dateObj = new DateTime(int.parse(widget.selectedDate.split("-")[0]), int.parse(widget.selectedDate.split("-")[1]), int.parse(widget.selectedDate.split("-")[2]), 0, 0, 0, 0); setState(() { - widget.appoDateFormatted = DateUtil.getWeekDay(dateObj.weekday) + - ", " + - dateObj.day.toString() + - " " + - DateUtil.getMonth(dateObj.month) + - " " + - dateObj.year.toString(); + widget.appoDateFormatted = DateUtil.getWeekDay(dateObj.weekday) + ", " + dateObj.day.toString() + " " + DateUtil.getMonth(dateObj.month) + " " + dateObj.year.toString(); }); - return widget.appoDateFormatted; + return DateUtil.getDayMonthYearDateFormatted(dateObj); + } + + DateTime getDateTime() { + var parts = widget.selectedTime.split(':'); + + try { + var dateObj = new DateTime(int.parse(widget.selectedDate.split("-")[0]), int.parse(widget.selectedDate.split("-")[1]), int.parse(widget.selectedDate.split("-")[2]), int.parse(parts[0].trim()), + int.parse(parts[1].trim()), 0, 0); + return dateObj; + } catch (e) { + var dateObj = new DateTime(int.parse(widget.selectedDate.split("-")[0]), int.parse(widget.selectedDate.split("-")[1]), int.parse(widget.selectedDate.split("-")[2]), 0, 0, 0, 0); + return dateObj; + } } String getDoctorSpeciality(List docSpecial) { @@ -608,32 +1150,64 @@ class _BookConfirmState extends State { return docSpeciality; } - getPatientData() async { - AppSharedPreferences sharedPref = AppSharedPreferences(); - if (await sharedPref.getObject(USER_PROFILE) != null) { - var data = - AuthenticatedUser.fromJson(await sharedPref.getObject(USER_PROFILE)); - setState(() { - print(data); - widget.authUser = data; - }); - } - } + // getPatientData() async { + // AppSharedPreferences sharedPref = AppSharedPreferences(); + // if (await sharedPref.getObject(USER_PROFILE) != null) { + // var data = AuthenticatedUser.fromJson(await sharedPref.getObject(USER_PROFILE)); + // setState(() { + // print(data); + // widget.authUser = data; + // }); + // } + // } Future navigateToHome(context) async { Navigator.of(context).popAndPushNamed(HOME); } - Future navigateToBookSuccess(context, DoctorList docObject, - PatientShareResponse patientShareResponse) async { + Future navigateToBookSuccess(context, DoctorList docObject, PatientShareResponse patientShareResponse, bool isCash) async { GifLoaderDialogUtils.hideDialog(context); + this.sharedPref.remove(IS_LIVECARE_APPOINTMENT); Navigator.push( - context, - FadePage( - page: BookSuccess( - docObject: docObject, - patientShareResponse: patientShareResponse, - appoDateFormatted: widget.appoDateFormatted, - appoTimeFormatted: widget.selectedTime))); + context, + FadePage( + page: BookReminderPage( + docObject: docObject, + patientShareResponse: patientShareResponse, + appoDateFormatted: widget.appoDateFormatted, + appoTimeFormatted: widget.selectedTime, + dateTime: getDateTime(), + isCash: isCash, + ), + ), + ); + } + + Future _showMyDialog(String message, BuildContext context) async { + return showDialog( + context: context, + barrierDismissible: true, // user must tap button! + builder: (BuildContext context) { + return AlertDialog( + title: const Text('Alert'), + content: SingleChildScrollView( + child: ListBody( + children: [ + Text(message), + ], + ), + ), + actions: [ + TextButton( + child: const Text('OK'), + onPressed: () { + Navigator.of(context).pop(); + Navigator.pushAndRemoveUntil(context, MaterialPageRoute(builder: (context) => LandingPage()), (Route r) => false); + }, + ), + ], + ); + }, + ); } } diff --git a/lib/pages/BookAppointment/BookSuccess.dart b/lib/pages/BookAppointment/BookSuccess.dart index 26a5b0fe..61b0f9d9 100644 --- a/lib/pages/BookAppointment/BookSuccess.dart +++ b/lib/pages/BookAppointment/BookSuccess.dart @@ -1,39 +1,55 @@ -import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'dart:developer'; +import 'dart:io'; + +import 'package:diplomaticquarterapp/core/enum/PayfortEnums.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; import 'package:diplomaticquarterapp/models/Appointments/PatientShareResposne.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; +import 'package:diplomaticquarterapp/models/LiveCare/ApplePayInsertRequest.dart'; +import 'package:diplomaticquarterapp/models/header_model.dart'; import 'package:diplomaticquarterapp/pages/ToDoList/payment_method_select.dart'; +import 'package:diplomaticquarterapp/pages/insurance/insurance_update_screen.dart'; +import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; +import 'package:diplomaticquarterapp/services/livecare_services/livecare_provider.dart'; +import 'package:diplomaticquarterapp/services/payfort_services/payfort_project_details_resp_model.dart'; +import 'package:diplomaticquarterapp/services/payfort_services/payfort_view_model.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/custom_text_button.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart'; +import 'package:diplomaticquarterapp/widgets/new_design/doctor_header.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:provider/provider.dart'; +import '../../config/shared_pref_kay.dart'; import 'QRCode.dart'; class BookSuccess extends StatefulWidget { PatientShareResponse patientShareResponse; DoctorList docObject; - MyInAppBrowser browser; - final ChromeSafariBrowser chromeBrowser = - new MyChromeSafariBrowser(new MyInAppBrowser()); + late MyInAppBrowser browser; + + // final ChromeSafariBrowser chromeBrowser = new MyChromeSafariBrowser(new MyInAppBrowser()); String appoDateFormatted; String appoTimeFormatted; + bool isCash = false; - BookSuccess( - {@required this.patientShareResponse, - @required this.docObject, - @required this.appoDateFormatted, - @required this.appoTimeFormatted}); + BookSuccess({required this.patientShareResponse, required this.docObject, required this.appoDateFormatted, required this.appoTimeFormatted, this.isCash = false}); @override _BookSuccessState createState() => _BookSuccessState(); @@ -41,136 +57,90 @@ class BookSuccess extends StatefulWidget { class _BookSuccessState extends State { AppSharedPreferences sharedPref = AppSharedPreferences(); - AuthenticatedUser authUser; + + // AuthenticatedUser authUser; + + late ProjectViewModel projectViewModel; + String? selectedPaymentMethod = ""; + String? selectedInstallments = ""; + String? tamaraPaymentStatus; + String? tamaraOrderID; + String? transID; + + @override + initState() { + WidgetsBinding.instance.addPostFrameCallback((_) async { + if (widget.patientShareResponse.isLiveCareAppointment! && + (widget.patientShareResponse.patientShareWithTax.toString() == "0" || widget.patientShareResponse.patientShareWithTax.toString() == "0.0")) { + setOnlineCheckInForAppointment(); + } + }); + super.initState(); + } @override Widget build(BuildContext context) { - return Scaffold( + projectViewModel = Provider.of(context); + return AppScaffold( + appBarTitle: widget.docObject.doctorTitle! + " " + widget.docObject.name!, + isShowDecPage: false, + isShowAppBar: true, + showNewAppBarTitle: true, + showNewAppBar: true, + backgroundColor: CustomColors.appBackgroudGreyColor, body: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.max, children: [ + DoctorHeader( + headerModel: HeaderModel( + widget.docObject.name!, + widget.docObject.doctorID!, + widget.docObject.doctorImageURL!, + widget.docObject.speciality!, + "", + widget.docObject.projectName!, + null, + null, + widget.docObject.nationalityFlagURL ?? "", + widget.docObject.doctorRate, + null, + widget.docObject.noOfPatientsRate, + "", + ), + isNeedToShowButton: false, + ), Container( - width: MediaQuery.of(context).size.width, - padding: EdgeInsets.only(bottom: 10.0), - color: new Color(0xFF20bc44), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - alignment: Alignment.center, - margin: EdgeInsets.only(top: 40.0), - child: Text(TranslationBase.of(context).bookSuccess, - style: TextStyle( - color: Colors.white, - fontSize: 18.0, - fontWeight: FontWeight.bold, - letterSpacing: 0.9)), + alignment: Alignment.center, + color: CustomColors.green, + child: Table( + border: TableBorder(verticalInside: BorderSide(width: 0.5, color: Colors.white)), + children: [ + TableRow( + children: [ + TableCell(child: _getNormalText(TranslationBase.of(context).patientShare)), + TableCell(child: _getNormalText(TranslationBase.of(context).patientShareWithTax)), + ], ), - Container( - margin: EdgeInsets.fromLTRB(10.0, 10.0, 10.0, 20.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Container( - padding: EdgeInsets.all(10.0), - child: Image.asset( - "assets/images/new-design/check-icon.png", - fit: BoxFit.fill, - height: 80.0, - width: 80.0), - ), - Container( - width: MediaQuery.of(context).size.width * 0.62, - margin: EdgeInsets.fromLTRB(10.0, 5.0, 10.0, 5.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - children: [ - Text(widget.docObject.projectName, - overflow: TextOverflow.clip, - style: _getTextStyling()), - Container( - margin: EdgeInsets.only(top: 5.0), - child: - Text("Insurance", style: _getTextStyling()), - ), - Container( - margin: EdgeInsets.only(top: 5.0, bottom: 3.0), - child: Text(widget.docObject.clinicName, - overflow: TextOverflow.clip, - style: _getTextStyling()), - ), - Container( - margin: EdgeInsets.only(top: 5.0, bottom: 3.0), - child: Text( - widget.appoDateFormatted + - ", " + - widget.appoTimeFormatted, - overflow: TextOverflow.clip, - style: _getTextStyling()), - ), - Container( - width: MediaQuery.of(context).size.width * 0.65, - margin: EdgeInsets.only(top: 5.0, bottom: 3.0), - child: Text( - widget.docObject.doctorTitle + - " " + - widget.docObject.name, - overflow: TextOverflow.clip, - style: _getTextStyling()), - ), - ], - ), - ), - ], - ), - ), - Container( - alignment: Alignment.center, - decoration: BoxDecoration( - border: Border.all(color: Colors.white, width: 0.5)), - margin: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 10.0), - child: Table( - border: TableBorder( - verticalInside: - BorderSide(width: 0.5, color: Colors.white)), - children: [ - TableRow(children: [ - TableCell( - child: _getNormalText( - TranslationBase.of(context).patientShare)), - TableCell( - child: _getNormalText(TranslationBase.of(context) - .patientShareWithTax)), - ]), - TableRow(children: [ - TableCell( - child: _getHeadingText("SR " + - widget.patientShareResponse.patientShare - .toString())), - TableCell( - child: _getHeadingText("SR " + - widget - .patientShareResponse.patientShareWithTax - .toString())), - ]), - ], - ), + TableRow( + children: [ + TableCell(child: _getHeadingText(widget.patientShareResponse.patientShare.toString())), + TableCell(child: _getHeadingText(widget.patientShareResponse.patientShareWithTax.toString())), + ], ), ], ), ), - getNextActionWidget(), + getNextActionWidget()!, ], ), ), - bottomNavigationBar: getBottomContainer(), + bottomSheet: getBottomContainer(), ); } - Widget getBottomContainer() { + Widget? getBottomContainer() { switch (widget.patientShareResponse.nextAction) { case 0: return Container(); @@ -190,34 +160,62 @@ class _BookSuccessState extends State { case 50: return _getConfirmAppoButtons(); break; + case 90: + return _getQRButtons(); } } Widget _getQRButtons() { return Container( alignment: Alignment.bottomCenter, + margin: EdgeInsets.all(14), height: MediaQuery.of(context).size.height * 0.18, child: Column( mainAxisAlignment: MainAxisAlignment.end, children: [ - 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, - disabledTextColor: Colors.white, - disabledColor: new Color(0xFFbcc2c4), - onPressed: () { -// navigateToQR(context); - getAppoQR(context); - }, - child: Text(TranslationBase.of(context).viewQR.toUpperCase(), - style: TextStyle(fontSize: 18.0)), - ), + Row( + children: [ + Expanded( + flex: 1, + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + minWidth: MediaQuery.of(context).size.width * 0.7, + height: 45.0, + child: CustomTextButton( + backgroundColor: CustomColors.green, + elevation: 0, + onPressed: () { + GifLoaderDialogUtils.showMyDialog(context); + getAppoQR(context); + }, + child: Text(TranslationBase.of(context).checkinOptions, style: TextStyle(fontSize: 18.0, color: Colors.white)), + ), + ), + ), + mWidth(7), + Expanded( + flex: 1, + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + minWidth: MediaQuery.of(context).size.width * 0.7, + height: 45.0, + child: CustomTextButton( + backgroundColor: Color(0xffc5272d), + elevation: 0, + onPressed: () { + navigateToHome(context); + // GifLoaderDialogUtils.showMyDialog(context); + // getAppoQR(context); + }, + child: Text(TranslationBase.of(context).done, style: TextStyle(fontSize: 18.0, color: Colors.white)), + ), + ), + ), + ], ), ], ), @@ -226,117 +224,170 @@ class _BookSuccessState extends State { Widget _getPayNowButtons() { return Container( - alignment: Alignment.bottomCenter, - height: MediaQuery.of(context).size.height * 0.2, - child: Column( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - 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, - disabledTextColor: Colors.white, - disabledColor: new Color(0xFFbcc2c4), - onPressed: () { - startPaymentProcess(); - }, - child: Text(TranslationBase.of(context).payNow.toUpperCase(), - style: TextStyle(fontSize: 18.0)), - ), - ), - ButtonTheme( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10.0), - ), - minWidth: MediaQuery.of(context).size.width * 0.7, - height: 45.0, - child: RaisedButton( - color: new Color(0xffc5272d), - textColor: Colors.white, - disabledTextColor: Colors.white, - disabledColor: new Color(0xFFbcc2c4), - onPressed: () { - navigateToHome(context); - }, - child: Text(TranslationBase.of(context).payLater.toUpperCase(), - style: TextStyle(fontSize: 18.0)), + color: CustomColors.appBackgroudGreyColor, + child: Container( + color: CustomColors.appBackgroudGreyColor, + margin: EdgeInsets.all(14), + height: widget.isCash ? 150.0 : 50, + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Expanded( + flex: 1, + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + height: 45.0, + child: CustomTextButton( + backgroundColor: CustomColors.green, + elevation: 0, + onPressed: () { + startPaymentProcess(); + projectViewModel.analytics.appointment.pay_now_for_appointment(appointment_type: 'regular', doctorDetail: widget.docObject, payNow: true); + }, + child: Text(TranslationBase.of(context).payNow.toUpperCase(), + style: TextStyle( + fontSize: 18.0, + color: Colors.white, + )), + ), + ), + ), + mWidth(7), + Expanded( + flex: 1, + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + height: 45.0, + child: CustomTextButton( + backgroundColor: Color(0xffc5272d), + elevation: 0, + onPressed: () { + navigateToHome(context); + projectViewModel.analytics.appointment.pay_now_for_appointment(appointment_type: 'regular', doctorDetail: widget.docObject, payNow: false); + }, + child: Text(TranslationBase.of(context).payLater.toUpperCase(), style: TextStyle(fontSize: 18.0, color: Colors.white)), + ), + ), + ), + ], ), - ), - ], + widget.isCash + ? Column( + children: [ + mHeight(10.0), + Text( + TranslationBase.of(context).cashAmountUpdateInsurance, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2E303A), + ), + ), + mHeight(5.0), + DefaultButton( + TranslationBase.of(context).updateInsuranceText, + () { + Navigator.pop(context, null); + Navigator.pushAndRemoveUntil( + context, + MaterialPageRoute(builder: (context) => LandingPage()), + (Route route) => false, + ); + Navigator.push(context, FadePage(page: InsuranceUpdate())); + }, + color: Color(0xffEAA118), + textColor: Colors.white, + ), + ], + ) + : Container(), + ], + ), ), ); } Widget _getConfirmAppoButtons() { return Container( - alignment: Alignment.bottomCenter, - margin: EdgeInsets.only(bottom: 5.0), - height: MediaQuery.of(context).size.height * 0.15, - child: Column( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - 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, - disabledTextColor: Colors.white, - disabledColor: new Color(0xFFbcc2c4), - onPressed: () { - AppoitmentAllHistoryResultList appo = - new AppoitmentAllHistoryResultList(); - appo.clinicID = widget.docObject.clinicID; - appo.projectID = widget.docObject.projectID; - appo.appointmentNo = widget.patientShareResponse.appointmentNo; - appo.serviceID = widget.patientShareResponse.serviceID; - appo.isLiveCareAppointment = - widget.patientShareResponse.isLiveCareAppointment; - appo.doctorID = widget.patientShareResponse.doctorID; - confirmAppointment(appo); - }, - child: Text( - widget.patientShareResponse.isLiveCareAppointment - ? TranslationBase.of(context) - .confirmLiveCare - .toUpperCase() - : TranslationBase.of(context).confirm.toUpperCase(), - style: TextStyle(fontSize: 18.0)), - ), - ), - ButtonTheme( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10.0), + color: CustomColors.appBackgroudGreyColor, + child: Container( + color: CustomColors.appBackgroudGreyColor, + margin: EdgeInsets.all(14), + height: 45.0, + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Expanded( + flex: 1, + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + height: 45.0, + child: CustomTextButton( + backgroundColor: Color(0xffc5272d), + elevation: 0, + onPressed: () { + AppoitmentAllHistoryResultList appo = new AppoitmentAllHistoryResultList(); + appo.clinicID = widget.docObject.clinicID; + appo.projectID = widget.docObject.projectID; + appo.appointmentNo = widget.patientShareResponse.appointmentNo; + appo.serviceID = widget.patientShareResponse.serviceID; + appo.isLiveCareAppointment = widget.patientShareResponse.isLiveCareAppointment; + appo.doctorID = widget.patientShareResponse.doctorID; + appo.appointmentDate = widget.patientShareResponse.appointmentDate; + if (appo.isLiveCareAppointment!) + insertLiveCareVIDARequest(appo); + else + navigateToHome(context); + }, + child: Text(TranslationBase.of(context).confirmLater, style: TextStyle(fontSize: 16.0, color: Colors.white)), + ), + ), ), - minWidth: MediaQuery.of(context).size.width * 0.7, - height: 45.0, - child: RaisedButton( - color: new Color(0xFFc5272d), - textColor: Colors.white, - disabledTextColor: Colors.white, - disabledColor: new Color(0xFFbcc2c4), - onPressed: () { - navigateToHome(context); - }, - child: Text( - TranslationBase.of(context).confirmLater.toUpperCase(), - style: TextStyle(fontSize: 18.0)), + mWidth(7), + Expanded( + flex: 1, + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + height: 45.0, + child: CustomTextButton( + backgroundColor: CustomColors.green, + elevation: 0, + onPressed: () { + AppoitmentAllHistoryResultList appo = new AppoitmentAllHistoryResultList(); + appo.clinicID = widget.docObject.clinicID; + appo.projectID = widget.docObject.projectID; + appo.appointmentNo = widget.patientShareResponse.appointmentNo; + appo.serviceID = widget.patientShareResponse.serviceID; + appo.isLiveCareAppointment = widget.patientShareResponse.isLiveCareAppointment; + appo.doctorID = widget.patientShareResponse.doctorID; + if (appo.isLiveCareAppointment!) { + navigateToHome(context); + } else { + confirmAppointment(appo); + } + }, + child: Text(widget.patientShareResponse.isLiveCareAppointment! ? TranslationBase.of(context).confirmLiveCare : TranslationBase.of(context).confirm, + style: TextStyle(fontSize: 16.0, color: Colors.white)), + ), + ), ), - ), - ], + ], + ), ), ); } - Widget getNextActionWidget() { + Widget? getNextActionWidget() { switch (widget.patientShareResponse.nextAction) { case 0: return Container(); @@ -356,10 +407,12 @@ class _BookSuccessState extends State { case 50: return _getConfirmAppo(); break; + case 90: + return _getQRAppo(); } } - String getNextAction() { + String? getNextAction() { switch (widget.patientShareResponse.nextAction) { case 0: return 'No Action'; @@ -379,6 +432,9 @@ class _BookSuccessState extends State { case 50: return 'Confirm LiveCare'; break; + case 90: + return 'QR Code'; + break; } } @@ -390,8 +446,7 @@ class _BookSuccessState extends State { Container( margin: EdgeInsets.only(top: 30.0, bottom: 40.0), alignment: Alignment.center, - child: Text(TranslationBase.of(context).confirmAppo, - style: TextStyle(fontSize: 18.0, letterSpacing: 0.8)), + child: Text(TranslationBase.of(context).confirmAppo, style: TextStyle(fontSize: 18.0, letterSpacing: 0.8)), ), Flex( direction: Axis.horizontal, @@ -406,9 +461,7 @@ class _BookSuccessState extends State { _getBulletPoint("1"), Container( width: MediaQuery.of(context).size.width * 0.8, - child: Text(TranslationBase.of(context).upcomingConfirm, - overflow: TextOverflow.clip, - style: TextStyle(fontSize: 13.0)), + child: Text(TranslationBase.of(context).upcomingConfirm, overflow: TextOverflow.clip, style: TextStyle(fontSize: 13.0)), ), ], ), @@ -429,10 +482,7 @@ class _BookSuccessState extends State { _getBulletPoint("2"), Container( width: MediaQuery.of(context).size.width * 0.8, - child: Text( - TranslationBase.of(context).upcomingConfirmMore, - overflow: TextOverflow.clip, - style: TextStyle(fontSize: 13.0)), + child: Text(TranslationBase.of(context).upcomingConfirmMore, overflow: TextOverflow.clip, style: TextStyle(fontSize: 13.0)), ), ], ), @@ -440,10 +490,7 @@ class _BookSuccessState extends State { ), ], ), - Container( - margin: EdgeInsets.fromLTRB(50.0, 20.0, 50.0, 20.0), - child: Image.asset("assets/images/new-design/payment-method.png"), - ), + Container(margin: EdgeInsets.fromLTRB(20.0, 20.0, 20.0, 5.0), child: getPaymentMethods()), ], ); } @@ -452,17 +499,35 @@ class _BookSuccessState extends State { return Container(); } + setOnlineCheckInForAppointment() { + DoctorsListService service = new DoctorsListService(); + GifLoaderDialogUtils.showMyDialog(context); + service.setOnlineCheckInForAppointment(widget.patientShareResponse.appointmentNo.toString(), widget.patientShareResponse.projectID!, projectViewModel.isArabic ? 1 : 2, context).then((res) { + AppoitmentAllHistoryResultList appo = new AppoitmentAllHistoryResultList(); + appo.clinicID = widget.docObject.clinicID; + appo.projectID = widget.docObject.projectID; + appo.appointmentNo = widget.patientShareResponse.appointmentNo; + appo.serviceID = widget.patientShareResponse.serviceID; + appo.isLiveCareAppointment = widget.patientShareResponse.isLiveCareAppointment; + appo.doctorID = widget.patientShareResponse.doctorID; + appo.appointmentDate = widget.patientShareResponse.appointmentDate; + insertLiveCareVIDARequest(appo, isMoveHome: false); + GifLoaderDialogUtils.hideDialog(context); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + confirmAppointment(AppoitmentAllHistoryResultList appo) { DoctorsListService service = new DoctorsListService(); GifLoaderDialogUtils.showMyDialog(context); - service - .confirmAppointment(appo.appointmentNo, appo.clinicID, appo.projectID, - appo.isLiveCareAppointment, context) - .then((res) { + service.confirmAppointment(appo.appointmentNo!, appo.clinicID!, appo.projectID!, appo.isLiveCareAppointment!, context).then((res) { GifLoaderDialogUtils.hideDialog(context); if (res['MessageStatus'] == 1) { AppToast.showSuccessToast(message: res['ErrorEndUserMessage']); - if (appo.isLiveCareAppointment) { + if (appo.isLiveCareAppointment!) { insertLiveCareVIDARequest(appo); } else { navigateToHome(context); @@ -477,17 +542,16 @@ class _BookSuccessState extends State { }); } - insertLiveCareVIDARequest(AppoitmentAllHistoryResultList appo) { + insertLiveCareVIDARequest(AppoitmentAllHistoryResultList appo, {bool isMoveHome = true}) { DoctorsListService service = new DoctorsListService(); GifLoaderDialogUtils.showMyDialog(context); service - .insertVIDARequest(appo.appointmentNo, appo.clinicID, appo.projectID, - appo.serviceID, appo.doctorID, context) + .insertVIDARequest(appo.appointmentNo, appo.clinicID, appo.projectID, appo.serviceID, appo.doctorID, appo.appointmentDate!, + Utils.getAppointmentTransID(appo.projectID, appo.clinicID, appo.appointmentNo), projectViewModel.isArabic ? 1 : 2, context) .then((res) { GifLoaderDialogUtils.hideDialog(context); if (res['MessageStatus'] == 1) { - AppToast.showSuccessToast(message: res['ErrorEndUserMessage']); - navigateToHome(context); + if (isMoveHome) navigateToHome(context); } else { AppToast.showErrorToast(message: res['ErrorEndUserMessage']); } @@ -499,77 +563,46 @@ class _BookSuccessState extends State { } Widget _getPayNowAppo() { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - children: [ - Container( - margin: EdgeInsets.only(top: 20.0, bottom: 0.0), - alignment: Alignment.center, - child: Text(TranslationBase.of(context).payNowBookSuccess, - style: TextStyle( - fontSize: 20.0, - letterSpacing: 0.8, - fontWeight: FontWeight.bold)), - ), - Container( - alignment: Alignment.center, - child: Image.asset("assets/images/new-design/no-wait-queue.png", - width: 120.0, height: 120.0), - ), - Flex( - direction: Axis.horizontal, - children: [ - Expanded( - child: Container( - padding: EdgeInsets.only(left: 10.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - children: [ - _getBulletPoint("1"), - Container( - width: MediaQuery.of(context).size.width * 0.8, - child: Text( - TranslationBase.of(context).payNowBookSuccesstext1, - overflow: TextOverflow.fade, - style: TextStyle(fontSize: 13.0)), - ), - ], - ), - ), + return Padding( + padding: const EdgeInsets.only(left: 20, right: 20, top: 24), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.max, + children: [ + Text( + TranslationBase.of(context).payNowBookSuccess, + style: TextStyle( + fontSize: 24.0, + letterSpacing: -1.44, + fontWeight: FontWeight.bold, ), - ], - ), - Container( - margin: EdgeInsets.fromLTRB(50.0, 20.0, 50.0, 20.0), - child: Image.asset("assets/images/new-design/payment-method.png"), - ), - Flex( - direction: Axis.horizontal, - children: [ - Expanded( - child: Container( - padding: EdgeInsets.only(top: 0.0, left: 10.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - children: [ - _getBulletPoint("2"), - Container( - width: MediaQuery.of(context).size.width * 0.8, - child: Text( - TranslationBase.of(context).payNowBookSuccesstext2, - overflow: TextOverflow.clip, - style: TextStyle(fontSize: 13.0)), - ), - ], - ), - ), + ), + Text( + TranslationBase.of(context).neverWait, + style: TextStyle( + fontSize: 12.0, + letterSpacing: -0.54, + fontWeight: FontWeight.w600, ), - ], - ), - ], + ), + mHeight(24), + Text(TranslationBase.of(context).payNowBookSuccesstext1, + overflow: TextOverflow.fade, + style: TextStyle( + fontSize: 12.0, + letterSpacing: -0.36, + )), + Container(margin: EdgeInsets.fromLTRB(20.0, 5.0, 20.0, 5.0), child: getPaymentMethods()), + Text( + TranslationBase.of(context).payNowBookSuccesstext2, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 12.0, + letterSpacing: -0.36, + ), + ), + ], + ), ); } @@ -577,79 +610,173 @@ class _BookSuccessState extends State { navigateToPaymentMethod(context, widget.patientShareResponse); } - Future navigateToPaymentMethod( - context, PatientShareResponse patientShareResponse) async { - if (await this.sharedPref.getObject(USER_PROFILE) != null) { - var data = AuthenticatedUser.fromJson( - await this.sharedPref.getObject(USER_PROFILE)); - setState(() { - authUser = data; - }); - } - + Future navigateToPaymentMethod(context, PatientShareResponse patientShareResponse) async { AppoitmentAllHistoryResultList appo = new AppoitmentAllHistoryResultList(); appo.projectID = widget.patientShareResponse.projectID; appo.clinicID = widget.patientShareResponse.clinicID; + appo.clinicName = widget.patientShareResponse.clinicName; + appo.projectName = widget.patientShareResponse.projectName; appo.appointmentNo = widget.patientShareResponse.appointmentNo; + appo.isLiveCareAppointment = widget.patientShareResponse.isLiveCareAppointment; + appo.doctorID = widget.patientShareResponse.doctorID; + appo.appointmentDate = widget.patientShareResponse.appointmentDate; + appo.serviceID = widget.patientShareResponse.serviceID; Navigator.push( - context, FadePage(page: PaymentMethod())) + context, + FadePage( + page: PaymentMethod( + onSelectedMethod: (String metohd, [String? selectedInstallmentPlan]) { + setState(() {}); + }, + patientShare: widget.patientShareResponse.patientShareWithTax))) .then((value) { - print(value); + selectedPaymentMethod = value[0]; if (value != null) { - openPayment( - value, - authUser, - double.parse(patientShareResponse.patientShareWithTax.toString()), - patientShareResponse, - appo); + if (selectedPaymentMethod == "ApplePay") { + if (projectViewModel.havePrivilege(103)) { + startApplePay(appo, patientShareResponse); + } else { + openPayment(value, projectViewModel.user, double.parse(patientShareResponse.patientShareWithTax.toString()), patientShareResponse, appo); + } + } else { + openPayment(value, projectViewModel.user, double.parse(patientShareResponse.patientShareWithTax.toString()), patientShareResponse, appo); + } + projectViewModel.analytics.appointment.payment_method(appointment_type: 'regular', clinic: widget.docObject.clinicName, payment_method: value[0], payment_type: 'appointment'); } }); } - openPayment( - String paymentMethod, - AuthenticatedUser authenticatedUser, - double amount, - PatientShareResponse patientShareResponse, - AppoitmentAllHistoryResultList appo) async { - if (paymentMethod == "ApplePay") { - await widget.chromeBrowser.open( - url: "https://applepay-datatrans-sample.herokuapp.com/", - options: ChromeSafariBrowserClassOptions( - android: AndroidChromeCustomTabsOptions( - addDefaultShareMenuItem: false), - ios: IOSSafariOptions(barCollapsingEnabled: true))); - } else { - widget.browser = new MyInAppBrowser( - onExitCallback: onBrowserExit, - appo: appo, - onLoadStartCallback: onBrowserLoadStart); - - widget.browser.openPaymentBrowser( - amount, - "Appointment check in", - Utils.getAppointmentTransID( - appo.projectID, appo.clinicID, appo.appointmentNo), - appo.projectID.toString(), - authenticatedUser.emailAddress, - paymentMethod, - authenticatedUser.patientType, - authenticatedUser.firstName, - authenticatedUser.patientID, - authenticatedUser, - widget.browser, - widget.patientShareResponse.isLiveCareAppointment, - widget.patientShareResponse.appointmentDate, - widget.patientShareResponse.appointmentNo, - widget.patientShareResponse.clinicID, - widget.patientShareResponse.doctorID); - } + void startApplePay(AppoitmentAllHistoryResultList appo, PatientShareResponse patientShareResponse) async { + transID = Utils.getAppointmentTransID(appo.projectID, appo.clinicID, appo.appointmentNo); + print("TransactionID: $transID"); + GifLoaderDialogUtils.showMyDialog(context); + + LiveCareService service = new LiveCareService(); + ApplePayInsertRequest applePayInsertRequest = new ApplePayInsertRequest(); + + PayfortProjectDetailsRespModel? payfortProjectDetailsRespModel; + await context.read().getProjectDetailsForPayfort(projectId: appo.projectID, serviceId: ServiceTypeEnum.appointmentPayment.getIdFromServiceEnum()).then((value) { + payfortProjectDetailsRespModel = value!; + }); + + applePayInsertRequest.clientRequestID = transID; + applePayInsertRequest.clinicID = appo.clinicID; + applePayInsertRequest.currency = projectViewModel.user.outSA == 1 ? "AED" : "SAR"; + // applePayInsertRequest.customerEmail = projectViewModel.authenticatedUserObject.user.emailAddress; + applePayInsertRequest.customerEmail = "CustID_${projectViewModel.user.patientID}@HMG.com"; + applePayInsertRequest.customerID = projectViewModel.user.patientID; + applePayInsertRequest.customerName = projectViewModel.user.firstName! + " " + projectViewModel.user.lastName!; + applePayInsertRequest.deviceToken = await AppSharedPreferences().getString(PUSH_TOKEN); + applePayInsertRequest.voipToken = await AppSharedPreferences().getString(ONESIGNAL_APNS_TOKEN); + applePayInsertRequest.doctorID = appo.doctorID; + applePayInsertRequest.projectID = appo.projectID.toString(); + applePayInsertRequest.serviceID = ServiceTypeEnum.appointmentPayment.getIdFromServiceEnum().toString(); + applePayInsertRequest.channelID = 3; + applePayInsertRequest.patientID = projectViewModel.user.patientID; + applePayInsertRequest.patientTypeID = projectViewModel.user.patientType; + applePayInsertRequest.patientOutSA = projectViewModel.user.outSA; + applePayInsertRequest.appointmentDate = appo.appointmentDate; + applePayInsertRequest.appointmentNo = appo.appointmentNo; + applePayInsertRequest.orderDescription = "Appointment Payment"; + applePayInsertRequest.liveServiceID = "0"; + applePayInsertRequest.latitude = "0.0"; + applePayInsertRequest.longitude = "0.0"; + applePayInsertRequest.amount = patientShareResponse.patientShareWithTax.toString(); + applePayInsertRequest.isSchedule = appo.isLiveCareAppointment! ? "1" : "0"; + applePayInsertRequest.language = projectViewModel.isArabic ? 'ar' : 'en'; + applePayInsertRequest.languageID = projectViewModel.isArabic ? 1 : 2; + applePayInsertRequest.userName = projectViewModel.user.patientID; + applePayInsertRequest.responseContinueURL = "http://hmg.com/Documents/success.html"; + applePayInsertRequest.backClickUrl = "http://hmg.com/Documents/success.html"; + applePayInsertRequest.paymentOption = "ApplePay"; + + applePayInsertRequest.isMobSDK = true; + applePayInsertRequest.merchantReference = transID; + applePayInsertRequest.merchantIdentifier = payfortProjectDetailsRespModel!.merchantIdentifier!; + applePayInsertRequest.commandType = "PURCHASE"; + applePayInsertRequest.signature = payfortProjectDetailsRespModel!.signature; + applePayInsertRequest.accessCode = payfortProjectDetailsRespModel!.accessCode; + applePayInsertRequest.shaRequestPhrase = payfortProjectDetailsRespModel!.shaRequest; + applePayInsertRequest.shaResponsePhrase = payfortProjectDetailsRespModel!.shaResponse; + applePayInsertRequest.returnURL = ""; + + service.applePayInsertRequest(applePayInsertRequest, context).then((res) async { + if (res["MessageStatus"] == 1) { + await context.read().initiateApplePayWithPayfort( + customerName: projectViewModel.user.firstName! + " " + projectViewModel.user.lastName!, + // customerEmail: projectViewModel.authenticatedUserObject.user.emailAddress, + customerEmail: "CustID_${projectViewModel.user.patientID}@HMG.com", + orderDescription: "Appointment Payment", + orderAmount: double.parse(patientShareResponse.patientShareWithTax.toString()), + merchantReference: transID, + payfortProjectDetailsRespModel: payfortProjectDetailsRespModel, + currency: projectViewModel.user.outSA == 1 ? "AED" : "SAR", + onFailed: (failureResult) async { + GifLoaderDialogUtils.hideDialog(context); + log("failureResult: ${failureResult.message.toString()}"); + AppToast.showErrorToast(message: failureResult.message.toString()); + }, + onSuccess: (successResult) async { + log("Payfort: ${successResult.responseMessage}"); + await context.read().addPayfortApplePayResponse(projectViewModel.user.patientID!, result: successResult); + checkPaymentStatus(appo); + }, + projectId: appo.projectID, + serviceTypeEnum: ServiceTypeEnum.appointmentPayment, + ); + } else { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: "An error occurred while processing your request"); + } + }).catchError((err) { + print(err); + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + }); + } + + openPayment(List paymentMethod, AuthenticatedUser authenticatedUser, num amount, PatientShareResponse patientShareResponse, AppoitmentAllHistoryResultList appo) async { + widget.browser = new MyInAppBrowser(onExitCallback: onBrowserExit, appo: appo, onLoadStartCallback: onBrowserLoadStart, context: context); + selectedPaymentMethod = paymentMethod[0]; + selectedInstallments = paymentMethod[1]; + transID = Utils.getAppointmentTransID(appo.projectID, appo.clinicID, appo.appointmentNo); + widget.browser.openPaymentBrowser( + amount, + "Appointment check in", + transID!, + appo.projectID.toString(), + authenticatedUser.emailAddress!, + paymentMethod[0]!, + authenticatedUser.patientType, + authenticatedUser.firstName!, + authenticatedUser.patientID, + authenticatedUser, + widget.browser, + widget.patientShareResponse.isLiveCareAppointment!, + "2", + widget.patientShareResponse.isLiveCareAppointment! ? widget.patientShareResponse.clinicID.toString() : "", + context, + widget.patientShareResponse.appointmentDate, + widget.patientShareResponse.appointmentNo, + widget.patientShareResponse.clinicID, + widget.patientShareResponse.doctorID, + paymentMethod[1]); + // } } onBrowserLoadStart(String url) { - print("onBrowserLoadStart"); - print(url); + if (selectedPaymentMethod == "TAMARA") { + if (Platform.isAndroid) { + Uri uri = new Uri.dataFromString(url); + tamaraPaymentStatus = uri.queryParameters['status']; + tamaraOrderID = uri.queryParameters['AuthorizePaymentId']; + } else { + Uri uri = new Uri.dataFromString(url); + tamaraPaymentStatus = uri.queryParameters['paymentStatus']; + tamaraOrderID = uri.queryParameters['orderId']; + } + } MyInAppBrowser.successURLS.forEach((element) { if (url.contains(element)) { @@ -669,31 +796,133 @@ class _BookSuccessState extends State { } onBrowserExit(AppoitmentAllHistoryResultList appo, bool isPaymentMade) { - print("onBrowserExit Called!!!!"); - if (isPaymentMade) checkPaymentStatus(appo); + try { + if (selectedPaymentMethod == "TAMARA") { + checkTamaraPaymentStatus(transID!, appo); + if (tamaraPaymentStatus != null && tamaraPaymentStatus!.toLowerCase() == "approved") { + updateTamaraRequestStatus("success", "14", Utils.getAppointmentTransID(appo.projectID, appo.clinicID, appo.appointmentNo), tamaraOrderID!, num.parse(selectedInstallments!), appo); + } else { + updateTamaraRequestStatus( + "Failed", "00", Utils.getAppointmentTransID(appo.projectID, appo.clinicID, appo.appointmentNo), tamaraOrderID! != null ? tamaraOrderID! : "", num.parse(selectedInstallments!), appo); + } + } else { + checkPaymentStatus(appo); + } + } catch (err) { + print(err); + } + } + + checkTamaraPaymentStatus(String orderID, AppoitmentAllHistoryResultList appo) { + GifLoaderDialogUtils.showMyDialog(context); + DoctorsListService service = new DoctorsListService(); + service.getTamaraPaymentStatus(orderID).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res["status"].toString().toLowerCase() == "success") { + updateTamaraRequestStatus("success", "14", orderID, tamaraOrderID!, int.parse(selectedInstallments!), appo); + } else { + updateTamaraRequestStatus( + "Failed", "00", Utils.getAppointmentTransID(appo.projectID!, appo.clinicID!, appo.appointmentNo!), tamaraOrderID != null ? tamaraOrderID! : "", int.parse(selectedInstallments!), appo); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + + addAdvancedNumberRequestTamara(String advanceNumber, String paymentReference, String appointmentID, AppoitmentAllHistoryResultList appo) { + DoctorsListService service = new DoctorsListService(); + service.addAdvancedNumberRequest(advanceNumber, paymentReference, appointmentID, context).then((res) {}).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + + updateTamaraRequestStatus(String responseMessage, String status, String clientRequestID, String tamaraOrderID, num selectedInstallments, AppoitmentAllHistoryResultList appo) { + GifLoaderDialogUtils.showMyDialog(context); + try { + DoctorsListService service = new DoctorsListService(); + service.updateTamaraRequestStatus(responseMessage, status, clientRequestID, tamaraOrderID, selectedInstallments).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (tamaraPaymentStatus!.toLowerCase() == "approved") { + markAppointmentForTamara(appo); + addAdvancedNumberRequestTamara("Tamara-Advance-0000", tamaraOrderID, appo.appointmentNo.toString(), appo); + } + }).catchError((err) { + print(err); + AppToast.showErrorToast(message: err); + GifLoaderDialogUtils.hideDialog(context); + }); + } catch (err) { + print(err); + } + } + + markAppointmentForTamara(AppoitmentAllHistoryResultList appo) { + GifLoaderDialogUtils.showMyDialog(context); + DoctorsListService service = new DoctorsListService(); + service.markAppointmentForTamara(appo.projectID!, appo.appointmentNo.toString()).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (appo.isLiveCareAppointment!) + insertLiveCareVIDARequest(appo); + else + getAppoQR(context); + }).catchError((err) { + print(err); + AppToast.showErrorToast(message: err); + GifLoaderDialogUtils.hideDialog(context); + }); + } + + autoGenerateInvoiceTamara(AppoitmentAllHistoryResultList appo) { + GifLoaderDialogUtils.showMyDialog(context); + DoctorsListService service = new DoctorsListService(); + service.autoGenerateInvoiceTamara(appo.projectID!, appo.appointmentNo.toString(), projectViewModel.user!.mobileNumber!).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (appo.isLiveCareAppointment!) + insertLiveCareVIDARequest(appo); + else + getAppoQR(context); + }).catchError((err) { + print(err); + AppToast.showErrorToast(message: err); + GifLoaderDialogUtils.hideDialog(context); + }); } checkPaymentStatus(AppoitmentAllHistoryResultList appo) { + String txn_ref; + num amount; + String payment_method; + final currency = projectViewModel.user!.outSA == 0 ? "sar" : 'aed'; GifLoaderDialogUtils.showMyDialog(context); DoctorsListService service = new DoctorsListService(); - service - .checkPaymentStatus( - Utils.getAppointmentTransID( - appo.projectID, appo.clinicID, appo.appointmentNo), - context) - .then((res) { - print("Printing Payment Status Reponse!!!!"); - print(res); + service.checkPaymentStatus(transID!, false, context).then((res) { String paymentInfo = res['Response_Message']; if (paymentInfo == 'Success') { + txn_ref = res['Merchant_Reference']; + amount = res['Amount']; + payment_method = res['PaymentMethod']; createAdvancePayment(res, appo); + projectViewModel.analytics.appointment.payment_success( + appointment_type: 'regular', payment_method: payment_method, clinic: appo.clinicName, hospital: appo.projectName, txn_amount: "$amount", txn_currency: currency, txn_number: txn_ref); } else { GifLoaderDialogUtils.hideDialog(context); AppToast.showErrorToast(message: res['Response_Message']); + projectViewModel.analytics.appointment.payment_fail( + appointment_type: 'regular', + payment_method: selectedPaymentMethod, + clinic: appo.clinicName, + hospital: appo.projectName, + txn_amount: widget.patientShareResponse.patientShareWithTax.toString(), + txn_currency: currency, + error_type: res['Response_Message']); } }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); - AppToast.showErrorToast(message: err); + AppToast.showErrorToast(message: err.toString()); print(err); }); } @@ -701,15 +930,9 @@ class _BookSuccessState extends State { getApplePayAPQ(AppoitmentAllHistoryResultList appo) { GifLoaderDialogUtils.showMyDialog(context); DoctorsListService service = new DoctorsListService(); - service - .checkPaymentStatus( - Utils.getAppointmentTransID( - appo.projectID, appo.clinicID, appo.appointmentNo), - context) - .then((res) { + service.checkPaymentStatus(Utils.getAppointmentTransID(appo.projectID!, appo.clinicID!, appo.appointmentNo!), false, context).then((res) { GifLoaderDialogUtils.hideDialog(context); - print("Printing Payment Status Reponse!!!!"); - print(res); + String paymentInfo = res['Response_Message']; if (paymentInfo == 'Success') { createAdvancePayment(res, appo); @@ -726,15 +949,14 @@ class _BookSuccessState extends State { createAdvancePayment(res, AppoitmentAllHistoryResultList appo) { DoctorsListService service = new DoctorsListService(); String paymentReference = res['Fort_id'].toString(); - service - .createAdvancePayment(appo, appo.projectID.toString(), res['Amount'], - res['Fort_id'], res['PaymentMethod'], context) - .then((res) { - print(res['OnlineCheckInAppointments'][0]['AdvanceNumber']); + service.createAdvancePayment(appo, appo.projectID.toString(), res['Amount'], res['Fort_id'], res['PaymentMethod'], context).then((res) { addAdvancedNumberRequest( - res['OnlineCheckInAppointments'][0]['AdvanceNumber'].toString(), + Utils.isVidaPlusProject(projectViewModel, appo.projectID!) + ? res['OnlineCheckInAppointments'][0]['AdvanceNumber_VP'].toString() + : res['OnlineCheckInAppointments'][0]['AdvanceNumber'].toString(), paymentReference, - appo.appointmentNo.toString()); + appo.appointmentNo.toString(), + appo); }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); AppToast.showErrorToast(message: err); @@ -742,15 +964,14 @@ class _BookSuccessState extends State { }); } - addAdvancedNumberRequest( - String advanceNumber, String paymentReference, String appointmentID) { + addAdvancedNumberRequest(String advanceNumber, String paymentReference, String appointmentID, AppoitmentAllHistoryResultList appo) { DoctorsListService service = new DoctorsListService(); - service - .addAdvancedNumberRequest( - advanceNumber, paymentReference, appointmentID, context) - .then((res) { - print(res); - getAppoQR(context); + service.addAdvancedNumberRequest(advanceNumber, paymentReference, appointmentID, context).then((res) { + if (appo.isLiveCareAppointment!) { + insertLiveCareVIDARequest(appo); + } else { + getAppoQR(context); + } }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); AppToast.showErrorToast(message: err); @@ -766,13 +987,11 @@ class _BookSuccessState extends State { Container( margin: EdgeInsets.only(top: 30.0, bottom: 40.0), alignment: Alignment.center, - child: Text(TranslationBase.of(context).noNeedToWaitInLine, - style: TextStyle(fontSize: 18.0, letterSpacing: 0.8)), + child: Text(TranslationBase.of(context).noNeedToWaitInLine, style: TextStyle(fontSize: 18.0, letterSpacing: 0.8)), ), Container( alignment: Alignment.center, - child: Image.asset("assets/images/new-design/device_icon.png", - width: 120.0, height: 120.0), + child: Image.asset("assets/images/new-design/device_icon.png", width: 120.0, height: 120.0), ), Flex( direction: Axis.horizontal, @@ -791,10 +1010,7 @@ class _BookSuccessState extends State { _getBulletPoint("1"), Container( width: MediaQuery.of(context).size.width * 0.8, - child: Text( - TranslationBase.of(context).useQRAppoAttend, - overflow: TextOverflow.fade, - style: TextStyle(fontSize: 13.0)), + child: Text(TranslationBase.of(context).useQRAppoAttend, overflow: TextOverflow.fade, style: TextStyle(fontSize: 13.0)), ), ], ), @@ -806,10 +1022,7 @@ class _BookSuccessState extends State { _getBulletPoint("2"), Container( width: MediaQuery.of(context).size.width * 0.8, - child: Text( - TranslationBase.of(context).passQRAppoAttend, - overflow: TextOverflow.fade, - style: TextStyle(fontSize: 13.0)), + child: Text(TranslationBase.of(context).passQRAppoAttend, overflow: TextOverflow.fade, style: TextStyle(fontSize: 13.0)), ), ], ), @@ -821,10 +1034,7 @@ class _BookSuccessState extends State { _getBulletPoint("3"), Container( width: MediaQuery.of(context).size.width * 0.8, - child: Text( - TranslationBase.of(context).sitWaitingQR, - overflow: TextOverflow.fade, - style: TextStyle(fontSize: 13.0)), + child: Text(TranslationBase.of(context).sitWaitingQR, overflow: TextOverflow.fade, style: TextStyle(fontSize: 13.0)), ), ], ), @@ -867,10 +1077,6 @@ class _BookSuccessState extends State { ); } - _getTextStyling() { - return TextStyle(fontSize: 14.0, color: Colors.white, letterSpacing: 0.7); - } - _getBulletPoint(bulletPoint) { return Container( margin: EdgeInsets.only(left: 20.0, right: 20.0), @@ -889,14 +1095,26 @@ class _BookSuccessState extends State { _getHeadingText(text) { return Container( - padding: EdgeInsets.only(bottom: 10.0), - child: Text(text, - textAlign: TextAlign.center, + padding: EdgeInsets.only(bottom: 10.0, left: 20, right: 20), + child: Row( + children: [ + projectViewModel.isArabic ? Container() : SvgPicture.asset("assets/images/new/Saudi_Riyal_Symbol.svg", width: 16, height: 16, color: Colors.white), + mWidth(6), + Text( + text, + textAlign: TextAlign.start, style: TextStyle( - fontSize: 26.0, - fontFamily: 'Open-Sans', - letterSpacing: 0.5, - color: Colors.white))); + fontSize: 16.0, + letterSpacing: -0.64, + color: Colors.white, + fontWeight: FontWeight.w600, + ), + ), + mWidth(6), + projectViewModel.isArabic ? SvgPicture.asset("assets/images/new/Saudi_Riyal_Symbol.svg", width: 16, height: 16, color: Colors.white) : Container(), + ], + ), + ); } Future navigateToHome(context) async { @@ -905,10 +1123,7 @@ class _BookSuccessState extends State { getAppoQR(context) { DoctorsListService service = new DoctorsListService(); - service - .generateAppointmentQR(widget.patientShareResponse, context) - .then((res) { - print(res); + service.generateAppointmentQR(widget.patientShareResponse, context).then((res) { GifLoaderDialogUtils.hideDialog(context); navigateToQR(context, res['AppointmentQR']); }).catchError((err) { @@ -919,26 +1134,48 @@ class _BookSuccessState extends State { } Future navigateToQR(context, String appoQR) async { + AppoitmentAllHistoryResultList appointment = new AppoitmentAllHistoryResultList(); + + appointment.doctorTitle = "Dr. "; + appointment.doctorNameObj = widget.patientShareResponse.doctorNameObj; + appointment.doctorImageURL = widget.patientShareResponse.doctorImageURL; + appointment.doctorSpeciality = (widget.patientShareResponse.doctorSpeciality != null) ? widget.patientShareResponse.doctorSpeciality as List : [""]; + appointment.projectName = widget.patientShareResponse.projectName; + appointment.projectID = widget.patientShareResponse.projectID; + appointment.appointmentDate = widget.patientShareResponse.appointmentDate; + appointment.isLiveCareAppointment = widget.patientShareResponse.isLiveCareAppointment; + appointment.startTime = widget.patientShareResponse.startTime; + appointment.doctorRate = 5; + appointment.actualDoctorRate = 5; + appointment.noOfPatientsRate = 0; + appointment.clinicName = widget.patientShareResponse.clinicName; + Navigator.push( context, FadePage( page: QRCode( patientShareResponse: widget.patientShareResponse, appoQR: appoQR, + appointment: appointment, ))); } _getNormalText(text) { return Container( - margin: EdgeInsets.only(top: 5.0), - padding: EdgeInsets.only(top: 5.0, bottom: 5.0), + margin: EdgeInsets.only(top: 5.0, left: 20, right: 20), + padding: EdgeInsets.only(top: 5.0, bottom: 0), child: Text(text, - textAlign: TextAlign.center, + textAlign: TextAlign.start, style: TextStyle( - fontSize: 12, - fontFamily: 'Open-Sans', - letterSpacing: 0.5, - color: Colors.white)), + fontSize: 12, + letterSpacing: -0.36, + color: Colors.white, + fontWeight: FontWeight.w600, + )), ); } + + _getTextStyling() { + return TextStyle(fontSize: 14.0, color: Colors.white, letterSpacing: 0.7); + } } diff --git a/lib/pages/BookAppointment/BookingOptions.dart b/lib/pages/BookAppointment/BookingOptions.dart index 83af454f..791631dc 100644 --- a/lib/pages/BookAppointment/BookingOptions.dart +++ b/lib/pages/BookAppointment/BookingOptions.dart @@ -15,7 +15,7 @@ class BookingOptions extends StatefulWidget { } class _BookingOptionsState extends State { - LocationUtils locationUtils; + late LocationUtils locationUtils; @override void initState() { diff --git a/lib/pages/BookAppointment/DentalComplaints.dart b/lib/pages/BookAppointment/DentalComplaints.dart index 614189e0..99f40cef 100644 --- a/lib/pages/BookAppointment/DentalComplaints.dart +++ b/lib/pages/BookAppointment/DentalComplaints.dart @@ -1,18 +1,35 @@ +import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/locator.dart'; import 'package:diplomaticquarterapp/models/Appointments/DentalChiefComplaintsModel.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DentalProceduresModel.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; import 'package:diplomaticquarterapp/models/Appointments/SearchInfoModel.dart'; import 'package:diplomaticquarterapp/pages/BookAppointment/widgets/DentalComplaintCard.dart'; -import 'package:diplomaticquarterapp/pages/livecare/widgets/clinic_card.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/widgets/DoctorView.dart'; +import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/app_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'; +import 'package:diplomaticquarterapp/uitl/utils_new.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'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; class DentalComplaints extends StatefulWidget { SearchInfo searchInfo; + Function? onSelectedMethod; + bool isDoctorNameSearch; + bool isFromHospitalSearchPage; - DentalComplaints({@required this.searchInfo}); + DentalComplaints({required this.searchInfo, this.onSelectedMethod, this.isDoctorNameSearch = false, this.isFromHospitalSearchPage = false}); @override _DentalComplaintsState createState() => _DentalComplaintsState(); @@ -22,34 +39,141 @@ class _DentalComplaintsState extends State { List complaintsList = []; AppSharedPreferences sharedPref = AppSharedPreferences(); bool isDataLoaded = false; + bool hasDentalPlan = false; var languageID; + int totalAppointmentTime = 0; + + List doctorsList = []; + + late DentalProceduresModel dentalProceduresModel; + List patientDoctorAppointmentListHospital = []; + + late ProjectViewModel projectViewModel; + + bool isDoctorsList = false; @override void initState() { - WidgetsBinding.instance - .addPostFrameCallback((_) => getChiefComplaintsList()); + WidgetsBinding.instance.addPostFrameCallback((_) => checkIfHasDentalPlan()); super.initState(); } @override Widget build(BuildContext context) { + projectViewModel = Provider.of(context); return AppScaffold( isShowAppBar: true, - appBarTitle: "Symptoms", + appBarTitle: TranslationBase.of(context).chiefComplaints, + showNewAppBar: true, + showNewAppBarTitle: true, + isShowDecPage: false, + backgroundColor: CustomColors.appBackgroudGreyColor, body: Container( - margin: EdgeInsets.fromLTRB(10.0, 10.0, 10.0, 0.0), - child: ListView.builder( - itemCount: complaintsList.length, - itemBuilder: (BuildContext context, int index) { - return Container( - margin: EdgeInsets.only(bottom: 10.0), - child: DentalComplaintCard( - listDentalChiefComplain: complaintsList[index], - languageID: languageID, + child: !hasDentalPlan + ? isDoctorsList + ? Container( + child: SingleChildScrollView( + child: Column( + children: [ + ...List.generate( + patientDoctorAppointmentListHospital.length, + (index) => Padding( + padding: const EdgeInsets.all(14.0), + child: AppExpandableNotifier( + isExpand: true, + title: patientDoctorAppointmentListHospital[index].filterName! + + " - " + + patientDoctorAppointmentListHospital[index].distanceInKMs! + + " " + + TranslationBase.of(context).km, + bodyWidget: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: patientDoctorAppointmentListHospital[index].patientDoctorAppointmentList!.map((doctor) { + return DoctorView( + doctor: doctor, + isLiveCareAppointment: false, + isContinueDentalPlan: hasDentalPlan, + ); + }).toList(), + )), + ), + ) + ], + ), + ), + ) + : ListView.separated( + itemCount: complaintsList.length, + itemBuilder: (BuildContext context, int index) { + return Container( + child: DentalComplaintCard( + listDentalChiefComplain: complaintsList[index], + languageID: languageID, + isDoctorNameSearch: widget.isDoctorNameSearch, + onSelectedMethod: widget.onSelectedMethod, + isFromHospitalSearchPage: widget.isFromHospitalSearchPage, + onDoctorFetched: widget.isFromHospitalSearchPage + ? (doctorsList) { + if (doctorsList.registeredDoctorMap?.isNotEmpty == true) { + Navigator.pop(context, doctorsList); + } else { + Utils.showErrorToast(TranslationBase.of(context).noDataAvailable); + } + } + : null, + )..logAnalytics = () { + final info = widget.searchInfo; + locator() + .appointment + .book_appointment_chief_complaints(appointment_type: 'regular', hospital: info.hospital, clinic: info.clinic, treatment: complaintsList[index]); + }, + ); + }, + separatorBuilder: (BuildContext context, int index) { + return Padding( + padding: const EdgeInsets.only(left: 14, right: 14), + child: mDivider(CustomColors.devider), + ); + }, + ) + : Container( + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + margin: EdgeInsets.only(top: 12.0, left: 12.0, right: 12.0), + child: Text(TranslationBase.of(context).dentalProcedureList, style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold, letterSpacing: -0.46)), + ), + Container( + decoration: cardRadius(10), + margin: EdgeInsets.all(12.0), + child: Table( + children: getProceduresData(), + ), + ), + ...List.generate( + patientDoctorAppointmentListHospital.length, + (index) => AppExpandableNotifier( + isExpand: true, + title: patientDoctorAppointmentListHospital[index].filterName! + " - " + patientDoctorAppointmentListHospital[index].distanceInKMs! + " " + TranslationBase.of(context).km, + bodyWidget: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: patientDoctorAppointmentListHospital[index].patientDoctorAppointmentList!.map((doctor) { + return DoctorView( + doctor: doctor, + isLiveCareAppointment: false, + isContinueDentalPlan: hasDentalPlan, + ); + }).toList(), + )), + ) + ], + ), ), - ); - }, - ), + ), ), ); } @@ -58,22 +182,174 @@ class _DentalComplaintsState extends State { languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); } + checkIfHasDentalPlan() { + DoctorsListService service = new DoctorsListService(); + GifLoaderDialogUtils.showMyDialog(context); + service.checkIfHasDentalPlan(widget.searchInfo!.ProjectID!, context).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res['MessageStatus'] == 1) { + if (res['List_IsPatientHasOnGoingEstimation'].length != 0) { + ConfirmDialog dialog = new ConfirmDialog( + context: context, + confirmMessage: TranslationBase.of(context).continuePlan, + okText: TranslationBase.of(context).yes, + cancelText: TranslationBase.of(context).no, + okFunction: () => {Navigator.of(context).pop(), continueDentalPlan(), hasDentalPlan = true}, + cancelFunction: () => {getChiefComplaintsList(), hasDentalPlan = false}); + dialog.showAlertDialog(context); + } else { + getChiefComplaintsList(); + } + } + }).catchError((err) { + print(err); + }); + } + + List getProceduresData() { + List tableRow = []; + + tableRow.add( + TableRow( + children: [ + Container( + child: Container( + margin: EdgeInsets.all(12.0), + child: Text(TranslationBase.of(context).procedureName, style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, letterSpacing: -0.46)), + ), + ), + Container( + child: Container( + margin: EdgeInsets.all(12.0), + child: Text(TranslationBase.of(context).timeNeeded, style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, letterSpacing: -0.46)), + ), + ), + ], + ), + ); + dentalProceduresModel.listIsPatientHasOnGoingEstimation!.forEach((procedure) { + tableRow.add(TableRow(children: [ + Container( + margin: EdgeInsets.all(12.0), + child: Text(procedure!.procedureName!, style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, letterSpacing: -0.46)), + ), + Container( + margin: EdgeInsets.all(12.0), + child: Text(procedure.neededTime.toString() + " " + TranslationBase.of(context).minute, style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, letterSpacing: -0.46)), + ), + ])); + }); + tableRow.add( + TableRow( + children: [ + Container( + margin: EdgeInsets.all(12.0), + child: Text(TranslationBase.of(context).totalTimeNeeded, style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, letterSpacing: -0.46)), + ), + Container( + margin: EdgeInsets.all(12.0), + child: Text(totalAppointmentTime.toString() + " " + TranslationBase.of(context).minute, style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, letterSpacing: -0.46)), + ), + ], + ), + ); + return tableRow; + } + + continueDentalPlan() { + int languageID = projectViewModel.isArabic ? 1 : 2; + DoctorsListService service = new DoctorsListService(); + + GifLoaderDialogUtils.showMyDialog(context); + int appoTime = 0; + service.getDoctorsList(int.parse("17"), widget.searchInfo!.ProjectID!, false, languageID, context, isContinueDentalPlan: true).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res['MessageStatus'] == 1) { + dentalProceduresModel = DentalProceduresModel.fromJson(res as Map); + //Changed by Aamir added Map into string dynamic + dentalProceduresModel.listIsPatientHasOnGoingEstimation!.forEach((procedure) { + appoTime += procedure!.neededTime!; + }); + setState(() { + hasDentalPlan = true; + totalAppointmentTime = appoTime; + }); + + 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(), + projectTopName: element.projectTopName, + projectBottomName: element.projectBottomName, + patientDoctorAppointment: element)); + } + }); + } else {} + } else { + AppToast.showErrorToast(message: res['ErrorEndUserMessage']); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + AppToast.showErrorToast(message: err); + }); + } + getChiefComplaintsList() { + int languageID = projectViewModel.isArabic ? 1 : 2; GifLoaderDialogUtils.showMyDialog(context); getLanguageID(); + hasDentalPlan = false; ClinicListService service = new ClinicListService(); - service - .getChiefComplaintsList( - widget.searchInfo.ClinicID, widget.searchInfo.ProjectID, context) - .then((res) { + int? patientID = projectViewModel.isLogin ? projectViewModel.user.patientID : -1; + service.getChiefComplaintsList(patientID!, widget.searchInfo.ClinicID!, widget.searchInfo.ProjectID!, languageID, false, context).then((res) { GifLoaderDialogUtils.hideDialog(context); if (res['MessageStatus'] == 1) { - print(res['List_DentalChiefComplain']); setState(() { - res['List_DentalChiefComplain'].forEach((v) { - complaintsList.add(new ListDentalChiefComplain.fromJson(v)); - }); - print(complaintsList.length); + if (res['DoctorList'].length != 0) { + isDoctorsList = true; + 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(), + projectTopName: element.projectTopName, + projectBottomName: element.projectBottomName, + patientDoctorAppointment: element)); + } + }); + } else { + isDoctorsList = false; + res['List_DentalChiefComplain'].forEach((v) { + complaintsList.add(new ListDentalChiefComplain.fromJson(v)); + }); + } }); } else {} }).catchError((err) { diff --git a/lib/pages/BookAppointment/DoctorProfile.dart b/lib/pages/BookAppointment/DoctorProfile.dart index 2a349cf2..2072109b 100644 --- a/lib/pages/BookAppointment/DoctorProfile.dart +++ b/lib/pages/BookAppointment/DoctorProfile.dart @@ -1,20 +1,36 @@ import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorProfile.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorRateDetails.dart'; +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/models/header_model.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/DentalComplaints.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/LaserBooking.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/components/LaserClinic.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/doctor_post_pre_images_page.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/waiting_appointment/waiting_appointment_info.dart'; +import 'package:diplomaticquarterapp/pages/MyAppointments/SchedulePage.dart'; import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; import 'package:diplomaticquarterapp/services/robo_search/event_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'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/custom_text_button.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; +import 'package:diplomaticquarterapp/widgets/new_design/doctor_header.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; -import 'package:rating_bar/rating_bar.dart'; +import 'package:flutter_rating_bar/flutter_rating_bar.dart'; +import 'package:provider/provider.dart'; import 'BookConfirm.dart'; import 'components/DocAvailableAppointments.dart'; @@ -25,35 +41,29 @@ class DoctorProfile extends StatefulWidget { DoctorProfileList docProfileList; final bool isOpenAppt; bool isLiveCareAppointment; + bool isDoctorNameSearch; + bool isContinueDentalPlan; - DoctorProfile( - {@required this.doctor, - @required this.docProfileList, - @required this.isLiveCareAppointment, - this.isOpenAppt = false}); + DoctorProfile({required this.doctor, required this.docProfileList, required this.isLiveCareAppointment, this.isOpenAppt = false, this.isDoctorNameSearch = false, this.isContinueDentalPlan = false}); - AuthenticatedUser authUser; + late AuthenticatedUser authUser; @override _DoctorProfileState createState() => _DoctorProfileState(); } -class _DoctorProfileState extends State - with TickerProviderStateMixin { - TabController _tabController; +class _DoctorProfileState extends State with TickerProviderStateMixin { + late TabController _tabController; bool showFooterButton = false; var event = RobotProvider(); - + dynamic doctorSchedule; AppSharedPreferences sharedPref = AppSharedPreferences(); - List doctorDetailsList = List(); + List doctorDetailsList = []; @override void initState() { - _tabController = new TabController( - length: 2, - vsync: this, - initialIndex: widget.isOpenAppt == true ? 1 : 0); + _tabController = new TabController(length: 2, vsync: this, initialIndex: widget.isOpenAppt == true ? 1 : 0); _tabController = new TabController(length: 2, vsync: this); widget.authUser = new AuthenticatedUser(); widget.doctor.speciality = widget.docProfileList.specialty; @@ -61,150 +71,144 @@ class _DoctorProfileState extends State super.initState(); } + late ProjectViewModel projectViewModel; + @override Widget build(BuildContext context) { + projectViewModel = Provider.of(context); return AppScaffold( - appBarTitle: TranslationBase.of(context).bookAppo, + appBarTitle: widget.doctor.doctorTitle! + " " + widget.doctor.name!, isShowAppBar: true, isShowDecPage: false, + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: CustomColors.appBackgroudGreyColor, bottomSheet: showFooterButton ? Container( - width: MediaQuery.of(context).size.width, - height: 50.0, - margin: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0), - child: ButtonTheme( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10.0), - ), - minWidth: MediaQuery.of(context).size.width * 0.7, + color: CustomColors.appBackgroudGreyColor, + child: Container( + width: MediaQuery.of(context).size.width, height: 45.0, - child: RaisedButton( - color: new Color(0xFF60686b), - textColor: Colors.white, - disabledTextColor: Colors.white, - disabledColor: new Color(0xFFbcc2c4), - onPressed: goToBookConfirm, - child: Text(TranslationBase.of(context).bookNow, - style: TextStyle(fontSize: 18.0)), + color: CustomColors.appBackgroudGreyColor, + margin: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0), + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + minWidth: MediaQuery.of(context).size.width * 0.7, + height: 40.0, + child: CustomTextButton( + backgroundColor: CustomColors.accentColor, + elevation: 0, + onPressed: goToBookConfirm, + child: Text(TranslationBase.of(context).reviewAppointment, style: TextStyle(fontSize: 16.0, letterSpacing: -0.48, color: Colors.white, fontWeight: FontWeight.w600)), + ), ), ), ) : null, body: Container( - color: new Color(0xFFf6f6f6), + color: new Color(0xFFF8F8F8), child: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Container( - color: Colors.white, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - margin: EdgeInsets.only(top: 20.0), - alignment: Alignment.center, - child: ClipRRect( - borderRadius: BorderRadius.circular(100.0), - child: Image.network(widget.doctor.doctorImageURL, - fit: BoxFit.fill, height: 120.0, width: 120.0), - ), - ), - Container( - margin: EdgeInsets.only(top: 10.0), - alignment: Alignment.center, - child: Text( - widget.doctor.doctorTitle + " " + widget.doctor.name, - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 20.0, - color: Colors.grey[900], - letterSpacing: 1.0)), - ), - Container( - margin: EdgeInsets.only(top: 10.0), - alignment: Alignment.center, - child: Text(widget.doctor.clinicName, - style: TextStyle( - fontSize: 13.0, - color: Colors.grey[900], - letterSpacing: 1.0)), - ), - Container( - margin: EdgeInsets.only(top: 5.0), - alignment: Alignment.center, - child: RatingBar.readOnly( - initialRating: - widget.doctor.actualDoctorRate.toDouble(), - size: 35.0, - filledColor: Colors.yellow[700], - emptyColor: Colors.grey[500], - isHalfAllowed: true, - halfFilledIcon: Icons.star_half, - filledIcon: Icons.star, - emptyIcon: Icons.star, - ), + DoctorHeader( + headerModel: HeaderModel( + widget.doctor.name!, + widget.doctor.doctorID!, + widget.doctor.doctorImageURL!, + widget.doctor.speciality!, + "", + widget.doctor.projectName!, + null, + null, + widget.doctor.nationalityFlagURL!, + widget.doctor.doctorRate, + widget.doctor.actualDoctorRate!, + widget.docProfileList.noOfPatientsRate!, + "", + decimalDoctorRate: widget.docProfileList.decimalDoctorRate.toString(), + ), + buttonIcon: 'assets/images/new/Boo_ Appointment.svg', + showConfirmMessageDialog: false, + isNeedToShowButton: !widget.isLiveCareAppointment, + onTap: () { + Navigator.push( + context, + FadePage( + page: SchedulePage(doctorList: widget.doctor), ), - InkWell( - onTap: () { - getDoctorRatingsDetails(); - }, - child: Container( - margin: EdgeInsets.only(top: 5.0), - alignment: Alignment.center, - child: Text( - "(" + - widget.docProfileList.noOfPatientsRate - .toString() + - " " + - TranslationBase.of(context).reviews + - ")", - style: TextStyle( - fontSize: 14.0, - color: Colors.blue[800], - letterSpacing: 1.0, - decoration: TextDecoration.underline, - )), + ).then((value) { + setState(() { + if (_tabController.index == 0) { + _tabController.animateTo((_tabController.index + 1) % 2); + showFooterButton = true; + } + this.doctorSchedule = value; + }); + }); + projectViewModel.analytics.appointment.book_appointment_schedule(appointment_type: 'regular', doctor: widget.doctor); + }, + onRatingAndReviewTap: () { + getDoctorRatingsDetails(); + }, + buttonTitle: TranslationBase.of(context).schedule, + ), + mDivider(Colors.grey[300]!), + if (widget.docProfileList.isDoctorHasPrePostImages == true) Container(height: 50, alignment: Alignment.center, child: prePostImagesButton(context)), + TabBar( + onTap: (index) { + setState(() { + if (index == 1) { + if (widget.doctor.clinicID == 23 || widget.doctor.clinicID == 47 || widget.isLiveCareAppointment) { + _tabController.index = _tabController.previousIndex; + showFooterButton = false; + } else { + showFooterButton = true; + } + } + print(showFooterButton); + }); + }, + tabs: [ + Tab( + child: Text( + TranslationBase.of(context).docInfo, + style: TextStyle( + color: Colors.black, + fontSize: 12, + letterSpacing: -0.36, + fontWeight: FontWeight.w600, ), ), - Container( - margin: EdgeInsets.only(top: 10.0), - child: Divider( - color: Colors.grey[500], + ), + Tab( + child: Text( + TranslationBase.of(context).availableAppo, + style: TextStyle( + color: widget.isLiveCareAppointment ? Colors.grey : Colors.black, + fontSize: 12, + letterSpacing: -0.36, + fontWeight: FontWeight.w600, ), ), - TabBar( - onTap: (index) { - setState(() { - index == 1 - ? showFooterButton = true - : showFooterButton = false; - print(showFooterButton); - }); - }, - tabs: [ - Tab( - child: Text(TranslationBase.of(context).docInfo, - style: TextStyle(color: Colors.black))), - Tab( - child: Text(TranslationBase.of(context).availableAppo, - style: TextStyle(color: Colors.black)), - ) - ], - controller: _tabController, - ), - ], - ), + ) + ], + controller: _tabController, ), Container( - height: MediaQuery.of(context).size.height, + height: MediaQuery.of(context).size.height * 1.5, child: TabBarView( physics: NeverScrollableScrollPhysics(), children: [ DoctorInformation(docProfileList: widget.docProfileList), DocAvailableAppointments( - doctor: widget.doctor, - isLiveCareAppointment: widget.isLiveCareAppointment) + doctor: widget.doctor, + isLiveCareAppointment: widget.isLiveCareAppointment, + doctorSchedule: doctorSchedule, + isContinueDentalPlan: widget.isContinueDentalPlan, + ), ], controller: _tabController, ), @@ -216,10 +220,26 @@ class _DoctorProfileState extends State ); } + Widget prePostImagesButton(BuildContext context) { + return Padding( + padding: const EdgeInsets.all(10), + child: MaterialButton( + height: 50, + color: Theme.of(context).appBarTheme.backgroundColor, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), + onPressed: () => openDoctorPrePostImages(), + child: Text( + TranslationBase.of(context).beforeAfterImages, + style: TextStyle(color: Colors.white, fontSize: 15, letterSpacing: 1), + ), + ), + ); + } + getDoctorRatings() { GifLoaderDialogUtils.showMyDialog(context); DoctorsListService service = new DoctorsListService(); - service.getDoctorsRating(widget.doctor.doctorID, context).then((res) { + service.getDoctorsRating(widget.doctor.doctorID!, projectViewModel.isArabic ? 1 : 2, context).then((res) { GifLoaderDialogUtils.hideDialog(context); if (res['MessageStatus'] == 1) { print(res['NotesDoctorRatingList']); @@ -236,9 +256,7 @@ class _DoctorProfileState extends State getDoctorRatingsDetails() { GifLoaderDialogUtils.showMyDialog(context); DoctorsListService service = new DoctorsListService(); - service - .getDoctorsRatingDetails(widget.doctor.doctorID, context) - .then((res) { + service.getDoctorsRatingDetails(widget.doctor.doctorID!, projectViewModel.isArabic ? 1 : 2, context).then((res) { GifLoaderDialogUtils.hideDialog(context); if (res['MessageStatus'] == 1) { doctorDetailsList.clear(); @@ -256,6 +274,29 @@ class _DoctorProfileState extends State }); } + openDoctorPrePostImages() { + GifLoaderDialogUtils.showMyDialog(context); + DoctorsListService().getDoctorPrePostImages(widget.docProfileList, context).then((images) { + GifLoaderDialogUtils.hideDialog(context); + showDialog( + context: context, + barrierDismissible: true, + builder: (ctx) { + return DoctorPostPreImagesContent(doctorPrePostImages: images); + }); + // Navigator.push( + // context, + // FadePage( + // page: DoctorPostPreImagesPage(doctorPrePostImages: images,) + // ) + // ); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + void showRatingDialog(List doctorDetailsList) { showGeneralDialog( barrierColor: Colors.black.withOpacity(0.5), @@ -281,69 +322,59 @@ class _DoctorProfileState extends State color: Theme.of(context).primaryColor, margin: EdgeInsets.only(bottom: 5.0), padding: EdgeInsets.all(10.0), - child: Text( - TranslationBase.of(context).doctorRating, - style: TextStyle( - fontSize: 22.0, color: Colors.white))), + child: Text(TranslationBase.of(context).doctorRating, style: TextStyle(fontSize: 22.0, color: Colors.white))), Container( - margin: EdgeInsets.only(top: 0.0), - child: Text( - this - .widget - .doctor - .actualDoctorRate - .ceilToDouble() - .toString(), - style: TextStyle( - fontSize: 32.0, color: Colors.black))), + margin: EdgeInsets.only(top: 0.0), child: Text(this.widget.doctor.actualDoctorRate!.ceilToDouble().toString(), style: TextStyle(fontSize: 32.0, color: Colors.black))), Container( margin: EdgeInsets.only(top: 5.0), alignment: Alignment.center, - child: RatingBar.readOnly( - initialRating: this - .widget - .doctor - .actualDoctorRate - .toDouble(), - size: 35.0, - filledColor: Colors.yellow[700], - emptyColor: Colors.grey[500], - isHalfAllowed: true, - halfFilledIcon: Icons.star_half, - filledIcon: Icons.star, - emptyIcon: Icons.star, + // child: RatingBar.readOnly( + // initialRating: this.widget.doctor.actualDoctorRate!.toDouble(), + // size: 35.0, + // filledColor: Colors.yellow[700], + // emptyColor: Colors.grey[500], + // isHalfAllowed: true, + // halfFilledIcon: Icons.star_half, + // filledIcon: Icons.star, + // emptyIcon: Icons.star, + // ), + child: RatingBar( + itemSize: 20.0, + allowHalfRating: true, + ignoreGestures: true, + initialRating: this.widget.doctor.actualDoctorRate!.toDouble(), + ratingWidget: RatingWidget( + full: Icon( + Icons.star, + color: CustomColors.accentColor, + ), + half: Icon( + Icons.star_half, + color: CustomColors.accentColor, + ), + empty: Icon( + Icons.star_border, + color: CustomColors.accentColor, + ), + ), + onRatingUpdate: (double value) {}, ), ), Container( margin: EdgeInsets.only(top: 10.0), - child: Text( - this - .widget - .doctor - .noOfPatientsRate - .toString() + - " " + - TranslationBase.of(context).reviews, - style: TextStyle( - fontSize: 14.0, color: Colors.black))), + child: Text(this.widget.doctor.noOfPatientsRate.toString() + " " + TranslationBase.of(context).reviews, style: TextStyle(fontSize: 14.0, color: Colors.black))), Container( margin: EdgeInsets.only(top: 10.0), child: Row( children: [ Container( width: 100.0, - margin: EdgeInsets.only( - top: 10.0, left: 15.0, right: 15.0), - child: Text( - TranslationBase.of(context).excellent, - style: TextStyle( - fontSize: 13.0, - color: Colors.black))), + margin: EdgeInsets.only(top: 10.0, left: 15.0, right: 15.0), + child: Text(TranslationBase.of(context).excellent, style: TextStyle(fontSize: 13.0, color: Colors.black))), Container( margin: EdgeInsets.only(top: 10.0), child: SizedBox( - width: getRatingWidth( - doctorDetailsList[0].patientNumber), + width: getRatingWidth(doctorDetailsList[0].patientNumber), height: 6.0, child: Container( color: Colors.green[700], @@ -358,18 +389,12 @@ class _DoctorProfileState extends State children: [ Container( width: 100.0, - margin: EdgeInsets.only( - top: 10.0, left: 15.0, right: 15.0), - child: Text( - TranslationBase.of(context).v_good, - style: TextStyle( - fontSize: 13.0, - color: Colors.black))), + margin: EdgeInsets.only(top: 10.0, left: 15.0, right: 15.0), + child: Text(TranslationBase.of(context).v_good, style: TextStyle(fontSize: 13.0, color: Colors.black))), Container( margin: EdgeInsets.only(top: 10.0), child: SizedBox( - width: getRatingWidth( - doctorDetailsList[1].patientNumber), + width: getRatingWidth(doctorDetailsList[1].patientNumber), height: 6.0, child: Container( color: Color(0xffB7B723), @@ -384,18 +409,12 @@ class _DoctorProfileState extends State children: [ Container( width: 100.0, - margin: EdgeInsets.only( - top: 10.0, left: 15.0, right: 15.0), - child: Text( - TranslationBase.of(context).good, - style: TextStyle( - fontSize: 13.0, - color: Colors.black))), + margin: EdgeInsets.only(top: 10.0, left: 15.0, right: 15.0), + child: Text(TranslationBase.of(context).good, style: TextStyle(fontSize: 13.0, color: Colors.black))), Container( margin: EdgeInsets.only(top: 10.0), child: SizedBox( - width: getRatingWidth( - doctorDetailsList[2].patientNumber), + width: getRatingWidth(doctorDetailsList[2].patientNumber), height: 6.0, child: Container( color: Color(0xffEBA727), @@ -410,18 +429,12 @@ class _DoctorProfileState extends State children: [ Container( width: 100.0, - margin: EdgeInsets.only( - top: 10.0, left: 15.0, right: 15.0), - child: Text( - TranslationBase.of(context).average, - style: TextStyle( - fontSize: 13.0, - color: Colors.black))), + margin: EdgeInsets.only(top: 10.0, left: 15.0, right: 15.0), + child: Text(TranslationBase.of(context).average, style: TextStyle(fontSize: 13.0, color: Colors.black))), Container( margin: EdgeInsets.only(top: 10.0), child: SizedBox( - width: getRatingWidth( - doctorDetailsList[3].patientNumber), + width: getRatingWidth(doctorDetailsList[3].patientNumber), height: 6.0, child: Container( color: Color(0xffEB7227), @@ -436,19 +449,12 @@ class _DoctorProfileState extends State children: [ Container( width: 100.0, - margin: EdgeInsets.only( - top: 10.0, left: 15.0, right: 15.0), - child: Text( - TranslationBase.of(context) - .below_average, - style: TextStyle( - fontSize: 13.0, - color: Colors.black))), + margin: EdgeInsets.only(top: 10.0, left: 15.0, right: 15.0), + child: Text(TranslationBase.of(context).below_average, style: TextStyle(fontSize: 13.0, color: Colors.black))), Container( margin: EdgeInsets.only(top: 10.0), child: SizedBox( - width: getRatingWidth( - doctorDetailsList[4].patientNumber), + width: getRatingWidth(doctorDetailsList[4].patientNumber), height: 6.0, child: Container( color: Color(0xffE20C0C), @@ -458,9 +464,7 @@ class _DoctorProfileState extends State ], ), ), - Container( - margin: EdgeInsets.only(top: 40.0), - child: Divider()), + Container(margin: EdgeInsets.only(top: 40.0), child: Divider()), Container( margin: EdgeInsets.only(top: 0.0), child: Align( @@ -471,20 +475,13 @@ class _DoctorProfileState extends State ), minWidth: MediaQuery.of(context).size.width, height: 40.0, - child: RaisedButton( + child: CustomTextButton( elevation: 0.0, - color: Colors.white, - textColor: Colors.red, - hoverColor: Colors.transparent, - focusColor: Colors.transparent, - highlightColor: Colors.transparent, - disabledColor: new Color(0xFFbcc2c4), + backgroundColor: Colors.white, onPressed: () { Navigator.of(context).pop(); }, - child: Text( - TranslationBase.of(context).cancel, - style: TextStyle(fontSize: 18.0)), + child: Text(TranslationBase.of(context).cancel, style: TextStyle(fontSize: 18.0, color: Colors.red)), ), ), ), @@ -502,19 +499,19 @@ class _DoctorProfileState extends State barrierDismissible: true, barrierLabel: '', context: context, - pageBuilder: (context, animation1, animation2) {}); + pageBuilder: (context, animation1, animation2) { + return SizedBox(); + }); } double getRatingWidth(int patientNumber) { - var width = - (patientNumber / this.widget.docProfileList.noOfPatientsRate) * 100; + var width = (patientNumber / this.widget.docProfileList.noOfPatientsRate!) * 100; return width; } getPatientData() async { if (await sharedPref.getObject(USER_PROFILE) != null) { - var data = - AuthenticatedUser.fromJson(await sharedPref.getObject(USER_PROFILE)); + var data = AuthenticatedUser.fromJson(await sharedPref.getObject(USER_PROFILE)); setState(() { print(data); widget.authUser = data; @@ -523,9 +520,12 @@ class _DoctorProfileState extends State } void goToBookConfirm() async { - if (DocAvailableAppointments.areSlotsAvailable) { - if (await sharedPref.getObject(USER_PROFILE) != null) { - navigateToBookConfirm(context); + // if (widget.isDoctorNameSearch && widget.doctor.clinicID == 17) { + // navigateToDentalComplaints(context); + // } else { + if (DocAvailableAppointments.selectedTime == TranslationBase.of(context).waitingAppointment) { + if (projectViewModel.isLogin) { + canPayForWalkInAppointment(); } else { ConfirmDialog dialog = new ConfirmDialog( context: context, @@ -536,8 +536,69 @@ class _DoctorProfileState extends State cancelFunction: () => {}); dialog.showAlertDialog(context); } - } else - AppToast.showErrorToast(message: "Please select Time Slot to continue"); + } else { + if (DocAvailableAppointments.areSlotsAvailable) { + if (projectViewModel.isLogin) { + // if (widget.isDoctorNameSearch && widget.doctor.clinicID == 17 && projectViewModel.user!.age! > 12) { + if (widget.isDoctorNameSearch && widget.doctor.clinicID == 17) { + navigateToDentalComplaints(context); + } else if (widget.isDoctorNameSearch && widget.doctor.clinicID == 253) { + navigateToLaserClinic(context); + } else { + final timeSlot = DocAvailableAppointments.selectedAppoDateTime; + navigateToBookConfirm(context); + projectViewModel.analytics.appointment.book_appointment_review(appointment_type: 'regular', dateTime: timeSlot!, doctor: widget.doctor); + } + } else { + ConfirmDialog dialog = new ConfirmDialog( + context: context, + confirmMessage: TranslationBase.of(context).loginToUseService, + okText: TranslationBase.of(context).confirm, + cancelText: TranslationBase.of(context).cancel_nocaps, + okFunction: () => {navigateToLogin()}, + cancelFunction: () => {}); + dialog.showAlertDialog(context); + } + } else { + AppToast.showErrorToast(message: TranslationBase.of(context).selectSlot); + } + } + } + + Future navigateToLaserClinic(BuildContext context) async { + HospitalsModel tempselectedHospital = new HospitalsModel(); + tempselectedHospital.iD = widget.doctor.projectID; + Navigator.push( + context, + FadePage( + page: LaserClinic(selectedHospital: tempselectedHospital!), + ), + ); + } + + Future navigateToDentalComplaints(BuildContext context) async { + HospitalsModel selectedHospital = new HospitalsModel(); + selectedHospital.name = widget.doctor.projectName; + ListClinicCentralized selectedClinic = new ListClinicCentralized(); + selectedClinic.clinicDescription = widget.doctor.clinicName; + + SearchInfo searchInfo = new SearchInfo(); + searchInfo.ProjectID = widget.doctor.projectID; + searchInfo.ClinicID = widget.doctor.clinicID; + searchInfo.date = DateTime.now(); + searchInfo.hospital = selectedHospital; + searchInfo.clinic = selectedClinic; + + Navigator.push( + context, + FadePage( + page: DentalComplaints(searchInfo: searchInfo), + ), + ).then((value) { + // setState(() { + // dropdownValue = null; + // }); + }); } navigateToLogin() { @@ -549,12 +610,41 @@ class _DoctorProfileState extends State Future navigateToBookConfirm(context) async { Navigator.push( - context, - FadePage( - page: BookConfirm( - doctor: widget.doctor, - isLiveCareAppointment: widget.isLiveCareAppointment, - selectedDate: DocAvailableAppointments.selectedDate, - selectedTime: DocAvailableAppointments.selectedTime))); + context, + FadePage( + page: BookConfirm( + doctor: widget.doctor, + isLiveCareAppointment: widget.isLiveCareAppointment, + selectedDate: DocAvailableAppointments.selectedDate!, + selectedTime: DocAvailableAppointments.selectedTime!, + initialSlotDuration: DocAvailableAppointments.initialSlotDuration!, + isWalkinAppointment: false, + ), + ), + ); + } + + Future navigateToWaitingAppointment(context) async { + projectViewModel.setWaitingAppointmentProjectID(widget.doctor.projectID!); + projectViewModel.setWaitingAppointmentDoctor(widget.doctor); + Navigator.push( + context, + FadePage( + page: WaitingAppointmentInfo(), + ), + ); + } + + canPayForWalkInAppointment() { + DoctorsListService service = new DoctorsListService(); + GifLoaderDialogUtils.showMyDialog(context); + service.canPayForWalkInAppointment(widget.doctor.clinicID!, widget.doctor.projectID!, widget.doctor.doctorID!).then((res) { + GifLoaderDialogUtils.hideDialog(context); + navigateToWaitingAppointment(context); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err, localContext: context); + print(err); + }); } } diff --git a/lib/pages/BookAppointment/LaserBooking.dart b/lib/pages/BookAppointment/LaserBooking.dart new file mode 100644 index 00000000..942e5e18 --- /dev/null +++ b/lib/pages/BookAppointment/LaserBooking.dart @@ -0,0 +1,15 @@ +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/material.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: TranslationBase.of(context).laserClinic, body: Container()); + } +} diff --git a/lib/pages/BookAppointment/QRCode.dart b/lib/pages/BookAppointment/QRCode.dart index 00fb2fc8..c79e1fcf 100644 --- a/lib/pages/BookAppointment/QRCode.dart +++ b/lib/pages/BookAppointment/QRCode.dart @@ -1,227 +1,311 @@ -import 'dart:convert'; import 'dart:typed_data'; +import 'package:barcode_scan2/barcode_scan2.dart'; +import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/model/privilege/ProjectDetailListModel.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/locator.dart'; +import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; import 'package:diplomaticquarterapp/models/Appointments/PatientShareResposne.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; +import 'package:diplomaticquarterapp/models/header_model.dart'; +import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; +import 'package:diplomaticquarterapp/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/location_util.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/custom_text_button.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/medical/medical_profile_item.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; +import 'package:diplomaticquarterapp/widgets/new_design/doctor_header.dart'; +import 'package:diplomaticquarterapp/widgets/nfc/nfc_reader_sheet.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_nfc_kit/flutter_nfc_kit.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:provider/provider.dart'; class QRCode extends StatefulWidget { - PatientShareResponse patientShareResponse; - String appoQR; - AuthenticatedUser authUser; + late PatientShareResponse? patientShareResponse; + late AppoitmentAllHistoryResultList? appointment; + late String? appoQR; + AuthenticatedUser? authUser; AppSharedPreferences sharedPref = AppSharedPreferences(); - QRCode({@required this.patientShareResponse, @required this.appoQR}); + QRCode({required this.patientShareResponse, required this.appoQR, this.appointment}); @override _QRCodeState createState() => _QRCodeState(); } class _QRCodeState extends State { - Uint8List _bytes; + late Uint8List _bytes; + bool _supportsNFC = false; + late BuildContext _context; + + late ProjectViewModel projectViewModel; + late LocationUtils locationUtils; + ProjectDetailListModel projectDetailListModel = ProjectDetailListModel(); @override void initState() { // TODO: implement initState - _bytes = base64.decode(widget.appoQR.split(',').last); + + // _bytes = base64.decode(widget.appoQR.split(',').last); widget.authUser = new AuthenticatedUser(); + + // WidgetsBinding.instance.addPostFrameCallback((timeStamp) { + // startNFCScan(); + // }); + super.initState(); } + startNFCScan() { + Future.delayed(const Duration(milliseconds: 500), () { + showNfcReader(context, onNcfScan: (String nfcId) { + Future.delayed(const Duration(milliseconds: 100), () { + sendNfcCheckInRequest(nfcId, 2); + locator().todoList.to_do_list_nfc(widget.appointment!); + }); + }, onCancel: () { + // Navigator.of(context).pop(); + locator().todoList.to_do_list_nfc_cancel(widget.appointment!); + }); + }); + } + + startQRCodeScan() async { + String onlineCheckInQRCode = (await BarcodeScanner.scan().then((value) => value.rawContent)); + if (onlineCheckInQRCode != "") { + sendNfcCheckInRequest(onlineCheckInQRCode, 2); + locator().todoList.to_do_list_nfc(widget.appointment!); + } else {} + } + + startLocationCheckIn() async { + GifLoaderDialogUtils.showMyDialog(context); + locationUtils = new LocationUtils(isShowConfirmDialog: true, context: context); + locationUtils.getCurrentLocation(callBack: (value) { + projectDetailListModel = Utils.getProjectDetailObj(projectViewModel, widget.appointment!.projectID); + double dist = Utils.distance(value.latitude, value.longitude, double.parse(projectDetailListModel.latitude!), double.parse(projectDetailListModel.longitude!)).ceilToDouble() * 1000; + print(dist); + if (dist <= projectDetailListModel.geofenceRadius!) { + sendNfcCheckInRequest(projectDetailListModel.checkInQrCode!, 2); + } else { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: TranslationBase.of(context).locationCheckInError); + } + }); + } + @override Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + _context = context; + FlutterNfcKit.nfcAvailability.then((value) { + _supportsNFC = (value == NFCAvailability.available); + }); + List checkInOptionsList = getCheckInOptionsList(context); return AppScaffold( - appBarTitle: TranslationBase.of(context).attendRegisterCode, + appBarTitle: TranslationBase.of(context).onlineCheckIn, isShowAppBar: true, + showNewAppBar: true, + showNewAppBarTitle: true, body: SingleChildScrollView( - child: Container( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - children: [ - Container( - margin: EdgeInsets.only(top: 30.0), - alignment: Alignment.center, - child: Image.memory(_bytes, scale: 0.5), - ), - Container( - margin: EdgeInsets.only(top: 20.0, left: 20.0, right: 20.0), - child: Divider( - color: Colors.red[700], - thickness: 0.8, - ), - ), - Container( - child: Row( - children: [ - Container( - margin: - EdgeInsets.only(top: 10.0, left: 40.0, bottom: 10.0), - child: Image.asset( - "assets/images/new-design/device_icon.png", - width: 120.0, - height: 120.0), - ), - Container( - width: MediaQuery.of(context).size.width * 0.5, - margin: EdgeInsets.only( - top: 15.0, bottom: 10.0, left: 20.0, right: 20.0), - child: Text(TranslationBase.of(context).scanQRHospital, - style: TextStyle( - color: Colors.red[700], - fontSize: 20.0, - fontWeight: FontWeight.bold)), - ), - ], - ), - ), - Container( - margin: EdgeInsets.only(top: 10.0, left: 20.0, right: 20.0), - child: Divider( - color: Colors.red[700], - thickness: 0.8, - ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + DoctorHeader( + headerModel: HeaderModel( + widget.appointment!.doctorTitle! + " " + widget.appointment!.doctorNameObj!, + widget.appointment!.doctorID ?? 0, + widget.appointment!.doctorImageURL!, + widget.appointment!.doctorSpeciality!, + "", + widget.appointment!.projectName!, + DateUtil.convertStringToDate(widget.appointment!.appointmentDate!), + widget.appointment!.isLiveCareAppointment! + ? DateUtil.convertStringToDate(widget.appointment!.appointmentDate!).toString().split(" ")[1].substring(0, 5) + : widget.appointment!.startTime!.substring(0, 5), + "null", + widget.appointment!.doctorRate, + widget.appointment!.actualDoctorRate, + widget.appointment!.noOfPatientsRate, + "", ), - Container( - margin: EdgeInsets.only( - top: 15.0, bottom: 10.0, left: 20.0, right: 20.0), - child: Text(TranslationBase.of(context).appoInfo, - style: TextStyle( - fontSize: 18.0, - color: Colors.grey[700], - fontWeight: FontWeight.bold)), - ), - Container( - margin: EdgeInsets.only(left: 20.0, bottom: 20.0), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - color: Colors.grey[200], - boxShadow: [ - BoxShadow(color: Colors.grey, spreadRadius: 2), - ], - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - margin: EdgeInsets.only( - top: 15.0, bottom: 10.0, left: 20.0, right: 20.0), - child: Text(widget.patientShareResponse.doctorNameObj, - style: TextStyle( - fontSize: 18.0, - color: Colors.grey[700], - fontWeight: FontWeight.bold)), - ), - Container( - margin: EdgeInsets.only( - bottom: 10.0, left: 20.0, right: 20.0), - child: Text( - getDoctorSpeciality( - widget.patientShareResponse.doctorSpeciality), - style: TextStyle( - fontSize: 18.0, color: Colors.grey[700])), - ), - Container( - margin: EdgeInsets.only( - top: 0.0, bottom: 10.0, left: 20.0, right: 20.0), - child: Text(widget.patientShareResponse.projectName, - style: TextStyle( - fontSize: 18.0, color: Colors.grey[700])), - ), - Container( - margin: EdgeInsets.only( - top: 0.0, bottom: 10.0, left: 20.0, right: 20.0), - child: Text( - getDate(widget.patientShareResponse.appointmentDate), - style: TextStyle( - fontSize: 18.0, color: Colors.grey[700])), - ), - ], - ), - ), - Container( - margin: EdgeInsets.zero, - alignment: Alignment.bottomCenter, - child: Column( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - 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, - disabledTextColor: Colors.white, - disabledColor: new Color(0xFFbcc2c4), - onPressed: () { -// navigateToQR(context); -// getAppoQR(context); - sendEmail(); - }, - child: Text( - TranslationBase.of(context).sendEmail.toUpperCase(), - style: TextStyle(fontSize: 18.0)), - ), - ), - ], + isShowName: true, + isNeedToShowButton: false, + buttonTitle: '', + onTap: () {}, + onRatingAndReviewTap: () {}, + ), + InkWell( + child: Container( + margin: EdgeInsets.only(top: 30.0), + padding: EdgeInsets.all(8), + child: SvgPicture.asset( + "assets/images/nfc/contactless.svg", + width: 80.0, + height: 80.0, ), ), - Container( - alignment: Alignment.bottomCenter, - height: MediaQuery.of(context).size.height * 0.1, - margin: EdgeInsets.only(bottom: 20.0), - child: Column( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - 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, - disabledTextColor: Colors.white, - disabledColor: new Color(0xFFbcc2c4), - onPressed: () { - navigateToHome(context); - }, - child: Text( - TranslationBase.of(context).close.toUpperCase(), - style: TextStyle(fontSize: 18.0)), - ), - ), - ], + onTap: () { + showNfcReader(context, onNcfScan: (String nfcId) { + Future.delayed(const Duration(milliseconds: 100), () { + sendNfcCheckInRequest(nfcId, 2); + + locator().todoList.to_do_list_nfc(widget.appointment!); + }); + }, onCancel: () { + // Navigator.of(context).pop(); + locator().todoList.to_do_list_nfc_cancel(widget.appointment!); + }); + }, + ), + Row( + children: [ + Expanded( + child: Container( + width: double.infinity, + margin: EdgeInsets.only(top: 15.0, bottom: 10.0, left: 20.0, right: 20.0), + child: Text(TranslationBase.of(context).scanQRHospital, + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + )), + ), ), + ], + ), + mHeight(21), + Padding( + padding: EdgeInsets.only(left: 21, right: 21), + child: GridView.builder( + shrinkWrap: true, + primary: false, + physics: NeverScrollableScrollPhysics(), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, childAspectRatio: 2 / 2, crossAxisSpacing: 12, mainAxisSpacing: 12), + padding: EdgeInsets.zero, + itemCount: checkInOptionsList.length, + itemBuilder: (BuildContext context, int index) { + return checkInOptionsList[index]; + }, ), - ], - ), + ), + ], ), ), + // bottomSheet: Container( + // color: CustomColors.appBackgroudGreyColor, + // padding: EdgeInsets.all(21), + // // height: 45.0, + // child: Row( + // children: [ + // Expanded( + // flex: 1, + // child: ButtonTheme( + // shape: RoundedRectangleBorder( + // borderRadius: BorderRadius.circular(10.0), + // ), + // height: 45.0, + // child: CustomTextButton( + // backgroundColor: CustomColors.green, + // elevation: 0, + // onPressed: () { + // startNFCScan(); + // }, + // child: Text(TranslationBase.of(context).scanNFC, + // style: TextStyle( + // fontSize: 18.0, + // color: Colors.white, + // )), + // ), + // ), + // ), + // ], + // ), + // ), ); } + List getCheckInOptionsList(BuildContext context) { + List optionsList = []; + + optionsList.add( + InkWell( + onTap: () { + if (projectViewModel.havePrivilege(102)) { + startLocationCheckIn(); + } + }, + child: MedicalProfileItem( + title: TranslationBase.of(context).checkInViaLocation, + imagePath: 'location.svg', + subTitle: "", + isEnable: projectViewModel.havePrivilege(102), + width: 70.0, + height: 70.0, + ), + ), + ); + + optionsList.add( + InkWell( + onTap: () { + if (projectViewModel.havePrivilege(79)) { + startQRCodeScan(); + } + }, + child: MedicalProfileItem( + title: TranslationBase.of(context).pharmaLiveCareScanQR, + imagePath: 'qr_code.svg', + subTitle: "", + isEnable: projectViewModel.havePrivilege(79), + width: 80.0, + height: 80.0, + ), + ), + ); + + optionsList.add( + InkWell( + onTap: () { + if (projectViewModel.havePrivilege(80) && _supportsNFC) { + startNFCScan(); + } else { + Utils.showErrorToast(TranslationBase.of(context).NFCNotSupported); + } + }, + child: MedicalProfileItem( + title: TranslationBase.of(context).scanNFC, + imagePath: 'contactless.svg', + subTitle: "", + isEnable: projectViewModel.havePrivilege(80), + width: 80.0, + height: 80.0, + ), + ), + ); + + return optionsList; + } + sendEmail() async { DoctorsListService service = new DoctorsListService(); if (await widget.sharedPref.getObject(USER_PROFILE) != null) { - var data = AuthenticatedUser.fromJson( - await widget.sharedPref.getObject(USER_PROFILE)); + var data = AuthenticatedUser.fromJson(await widget.sharedPref.getObject(USER_PROFILE)); setState(() { widget.authUser = data; }); @@ -229,23 +313,21 @@ class _QRCodeState extends State { ConfirmDialog dialog = new ConfirmDialog( context: context, - confirmMessage: "Send a copy of this QR to the email " + - widget.authUser.emailAddress + - "?", + confirmMessage: "Send a copy of this QR to the email " + widget.authUser!.emailAddress! + "?", okText: TranslationBase.of(context).confirm, cancelText: TranslationBase.of(context).cancel_nocaps, okFunction: () { GifLoaderDialogUtils.showMyDialog(context); service .sendAppointmentQREmail( - widget.authUser.emailAddress, - widget.patientShareResponse.appointmentDate, - widget.patientShareResponse.appointmentNo.toString(), - widget.patientShareResponse.doctorNameObj, - widget.patientShareResponse.projectName, - widget.appoQR, - getDoctorSpeciality( - widget.patientShareResponse.doctorSpeciality), + widget.authUser!.emailAddress!, + widget.patientShareResponse!.appointmentDate!, + widget.patientShareResponse!.appointmentNo!.toString(), + //Changed By Aamir + widget.patientShareResponse!.doctorNameObj, + widget.patientShareResponse!.projectName, + widget.appoQR!, + getDoctorSpeciality(widget.patientShareResponse!.doctorSpeciality as List), context) .then((res) { GifLoaderDialogUtils.hideDialog(context); @@ -265,8 +347,7 @@ class _QRCodeState extends State { Navigator.of(context).pushNamed(HOME); } - getPatientShare(context, String appointmentNo, int clinicID, int projectID, - DoctorList docObject) {} + getPatientShare(context, String appointmentNo, int clinicID, int projectID, DoctorList docObject) {} String getDate(String appoDate) { var appoDateFormatted = ""; @@ -300,4 +381,48 @@ class _QRCodeState extends State { } return docSpeciality; } + + sendNfcCheckInRequest(String nfcId, int checkInBy) { + GifLoaderDialogUtils.showMyDialog(context); + + DoctorsListService service = new DoctorsListService(); + + service.sendCheckinNfcRequest(widget!.patientShareResponse!.appointmentNo!, nfcId, widget.patientShareResponse!.projectID!, checkInBy, widget.patientShareResponse!.clinicID!, context).then((res) { + print(res); + GifLoaderDialogUtils.hideDialog(context); + _showMyDialog(res["SuccessMsg"], this.context); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + _showMyDialog(err, this.context); + }); + } + + Future _showMyDialog(String message, BuildContext context) async { + return showDialog( + context: context, + barrierDismissible: true, // user must tap button! + builder: (BuildContext context) { + return AlertDialog( + title: const Text('Alert'), + content: SingleChildScrollView( + child: ListBody( + children: [ + Text(message), + ], + ), + ), + actions: [ + TextButton( + child: const Text('OK'), + onPressed: () { + Navigator.of(context).pop(); + Navigator.pushAndRemoveUntil(context, MaterialPageRoute(builder: (context) => LandingPage()), (Route r) => false); + }, + ), + ], + ); + }, + ); + } } diff --git a/lib/pages/BookAppointment/QRCode.dart.orig b/lib/pages/BookAppointment/QRCode.dart.orig new file mode 100644 index 00000000..83249dee --- /dev/null +++ b/lib/pages/BookAppointment/QRCode.dart.orig @@ -0,0 +1,355 @@ +import 'dart:convert'; +import 'dart:typed_data'; + +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/locator.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; +import 'package:diplomaticquarterapp/models/Appointments/PatientShareResposne.dart'; +import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; +import 'package:diplomaticquarterapp/routes.dart'; +import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.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/widgets/buttons/defaultButton.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; +import 'package:diplomaticquarterapp/widgets/nfc/nfc_reader_sheet.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_nfc_kit/flutter_nfc_kit.dart'; + +class QRCode extends StatefulWidget { + PatientShareResponse patientShareResponse; + String appoQR; + AuthenticatedUser authUser; + AppSharedPreferences sharedPref = AppSharedPreferences(); + + QRCode({@required this.patientShareResponse, @required this.appoQR}); + + @override + _QRCodeState createState() => _QRCodeState(); +} + +class _QRCodeState extends State { + Uint8List _bytes; + bool _supportsNFC = false; + BuildContext _context; + + @override + void initState() { + // TODO: implement initState + + _bytes = base64.decode(widget.appoQR.split(',').last); + widget.authUser = new AuthenticatedUser(); + + WidgetsBinding.instance.addPostFrameCallback((timeStamp) { + FlutterNfcKit.nfcAvailability.then((value) { + setState(() { + _supportsNFC = (value == NFCAvailability.available); + }); + }); + }); + + super.initState(); + } + + @override + Widget build(BuildContext context) { + _context = context; + return AppScaffold( + appBarTitle: TranslationBase.of(context).attendRegisterCode, + isShowAppBar: true, + showNewAppBar: true, + showNewAppBarTitle: true, + body: SingleChildScrollView( + child: Container( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.max, + children: [ + Container( + width: double.infinity, + height: MediaQuery.of(context).size.width / 3, + child: Row( + children: [ +<<<<<<< HEAD + _supportsNFC + ? Expanded( + flex: 1, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + InkWell( + child: Container( + margin: EdgeInsets.only(top: 30.0), + alignment: Alignment.center, + padding: EdgeInsets.all(8), + decoration: BoxDecoration( + border: Border.all(color: Colors.black), + borderRadius: BorderRadius.circular(10), + ), + child: Image.asset("assets/images/nfc/ic_nfc.png"), + ), + onTap: () { + locator().analytics.todoList.to_do_list_nfc(); + showNfcReader(context, onNcfScan: (String nfcId) { + Future.delayed(const Duration(milliseconds: 100), () { + sendNfcCheckInRequest(nfcId); + }); + }, onCancel: (){ + locator().analytics.todoList.to_do_list_nfc_cancel(); + }); + }, + ), + ], +======= + // _supportsNFC + // ? + Expanded( + flex: 1, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + InkWell( + child: Container( + margin: EdgeInsets.only(top: 30.0), + alignment: Alignment.center, + padding: EdgeInsets.all(8), + decoration: BoxDecoration( + border: Border.all(color: Colors.black), + borderRadius: BorderRadius.circular(10), + ), + child: Image.asset("assets/images/nfc/ic_nfc.png"), +>>>>>>> 259e27d4a7e8d7ddf751de88de36fe901df0e2da + ), + onTap: () { + showNfcReader(context, onNcfScan: (String nfcId) { + Future.delayed(const Duration(milliseconds: 100), () { + sendNfcCheckInRequest(nfcId); + }); + }); + }, + ), + ], + ), + ), + // : Container(), + Expanded( + flex: 1, + child: Container( + margin: EdgeInsets.only(top: 30.0), + alignment: Alignment.center, + child: Image.memory( + _bytes, + ), + ), + ), + ], + ), + ), + Container( + margin: EdgeInsets.only(top: 20.0, left: 20.0, right: 20.0), + child: Divider( + color: Colors.red[700], + thickness: 0.8, + ), + ), + Container( + child: Row( + children: [ + Container( + margin: EdgeInsets.only(top: 10.0, left: 40.0, bottom: 10.0), + child: Image.asset("assets/images/new-design/device_icon.png", width: MediaQuery.of(context).size.width / 3.4, height: MediaQuery.of(context).size.width / 3.4), + ), + Expanded( + child: Container( + width: double.infinity, + margin: EdgeInsets.only(top: 15.0, bottom: 10.0, left: 20.0, right: 20.0), + child: Text(TranslationBase.of(context).scanQRHospital, style: TextStyle(color: Colors.red[700], fontSize: 18.0, fontWeight: FontWeight.bold)), + ), + ), + ], + ), + ), + Container( + margin: EdgeInsets.only(top: 10.0, left: 20.0, right: 20.0), + child: Divider( + color: Colors.red[700], + thickness: 0.8, + ), + ), + Container( + margin: EdgeInsets.only(top: 15.0, bottom: 10.0, left: 20.0, right: 20.0), + child: Text(TranslationBase.of(context).appoInfo, style: TextStyle(fontSize: 18.0, color: Colors.grey[700], fontWeight: FontWeight.bold)), + ), + Container( + margin: EdgeInsets.only(left: 20.0, bottom: 20.0, right: 20.0), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: Colors.grey[200], + boxShadow: [ + BoxShadow(color: Colors.grey, spreadRadius: 2), + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + margin: EdgeInsets.only(top: 15.0, bottom: 10.0, left: 20.0, right: 20.0), + child: Text(widget.patientShareResponse.doctorNameObj, style: TextStyle(fontSize: 18.0, color: Colors.grey[700], fontWeight: FontWeight.bold)), + ), + if (getDoctorSpeciality(widget.patientShareResponse.doctorSpeciality) != "null\n") + Container( + margin: EdgeInsets.only(bottom: 10.0, left: 20.0, right: 20.0), + child: Text(getDoctorSpeciality(widget.patientShareResponse.doctorSpeciality), style: TextStyle(fontSize: 18.0, color: Colors.grey[700])), + ), + Container( + margin: EdgeInsets.only(top: 0.0, bottom: 10.0, left: 20.0, right: 20.0), + child: Text(widget.patientShareResponse.projectName, style: TextStyle(fontSize: 18.0, color: Colors.grey[700])), + ), + Container( + margin: EdgeInsets.only(top: 0.0, bottom: 10.0, left: 20.0, right: 20.0), + child: Text(getDate(widget.patientShareResponse.appointmentDate), style: TextStyle(fontSize: 18.0, color: Colors.grey[700])), + ), + ], + ), + ), + Container( + margin: EdgeInsets.only(left: 20.0, right: 20.0, top: 15.0), + alignment: Alignment.bottomCenter, + child: Column( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + DefaultButton(TranslationBase.of(context).sendEmail.toUpperCase(), () => {sendEmail()}) + ], + ), + ), + ], + ), + ), + ), + ); + } + + sendEmail() async { + DoctorsListService service = new DoctorsListService(); + + if (await widget.sharedPref.getObject(USER_PROFILE) != null) { + var data = AuthenticatedUser.fromJson(await widget.sharedPref.getObject(USER_PROFILE)); + setState(() { + widget.authUser = data; + }); + } + + ConfirmDialog dialog = new ConfirmDialog( + context: context, + confirmMessage: "Send a copy of this QR to the email " + widget.authUser.emailAddress + "?", + okText: TranslationBase.of(context).confirm, + cancelText: TranslationBase.of(context).cancel_nocaps, + okFunction: () { + GifLoaderDialogUtils.showMyDialog(context); + service + .sendAppointmentQREmail(widget.authUser.emailAddress, widget.patientShareResponse.appointmentDate, widget.patientShareResponse.appointmentNo.toString(), + widget.patientShareResponse.doctorNameObj, widget.patientShareResponse.projectName, widget.appoQR, getDoctorSpeciality(widget.patientShareResponse.doctorSpeciality), context) + .then((res) { + GifLoaderDialogUtils.hideDialog(context); + ConfirmDialog.closeAlertDialog(context); + }).catchError((err) { + ConfirmDialog.closeAlertDialog(context); + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); + }); + }, + cancelFunction: () => {}); + dialog.showAlertDialog(context); + } + + Future navigateToHome(context) async { + Navigator.of(context).pushNamed(HOME); + } + + getPatientShare(context, String appointmentNo, int clinicID, int projectID, DoctorList docObject) {} + + String getDate(String appoDate) { + var appoDateFormatted = ""; + + var dateObj = DateUtil.convertStringToDate(appoDate); + + setState(() { + appoDateFormatted = DateUtil.getWeekDay(dateObj.weekday) + + ", " + + dateObj.day.toString() + + " " + + DateUtil.getMonth(dateObj.month) + + " " + + dateObj.year.toString() + + ", " + + dateObj.hour.toString() + + ":" + + dateObj.minute.toString() + + ":00"; + }); + + return appoDateFormatted; + } + + String getDoctorSpeciality(List docSpecial) { + String docSpeciality = ""; + if (docSpecial != null && docSpecial.length != 0) { + docSpecial.forEach((v) { + docSpeciality = docSpeciality + v + "\n"; + }); + } + return docSpeciality; + } + + sendNfcCheckInRequest(String nfcId) { + GifLoaderDialogUtils.showMyDialog(context); + + DoctorsListService service = new DoctorsListService(); + + service.sendCheckinNfcRequest(widget.patientShareResponse.appointmentNo, nfcId, widget.patientShareResponse.projectID, context).then((res) { + print(res); + + GifLoaderDialogUtils.hideDialog(context); + _showMyDialog(res["SuccessMsg"], this.context); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + _showMyDialog(err, this.context); + }); + } + + Future _showMyDialog(String message, BuildContext context) async { + return showDialog( + context: context, + barrierDismissible: true, // user must tap button! + builder: (BuildContext context) { + return AlertDialog( + title: const Text('Alert'), + content: SingleChildScrollView( + child: ListBody( + children: [ + Text(message), + ], + ), + ), + actions: [ + TextButton( + child: const Text('OK'), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ], + ); + }, + ); + } +} diff --git a/lib/pages/BookAppointment/Search.dart b/lib/pages/BookAppointment/Search.dart index 6dee1076..efdf79dc 100644 --- a/lib/pages/BookAppointment/Search.dart +++ b/lib/pages/BookAppointment/Search.dart @@ -1,73 +1,121 @@ +import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/BookAppointment/components/SearchByClinic.dart'; import 'package:diplomaticquarterapp/pages/BookAppointment/components/SearchByDoctor.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/components/search_by_hospital_name.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/material.dart'; - -import 'components/SearchByClinic.dart'; +import 'package:provider/provider.dart'; class Search extends StatefulWidget { final int type; - final List clnicIds; + final List? clnicIds; + Function()? onBackClick; - Search({this.type = 0, this.clnicIds}); + Search({this.type = 0, this.clnicIds, this.onBackClick}); @override _SearchState createState() => _SearchState(); } class _SearchState extends State with TickerProviderStateMixin { - TabController _tabController; + late TabController _tabController; @override void initState() { - _tabController = - new TabController(length: 2, vsync: this, initialIndex: widget.type); - + _tabController = new TabController( + length: 3, + vsync: this, + initialIndex: widget.type, + ); super.initState(); } @override Widget build(BuildContext context) { AppGlobal.context = context; + // ProjectViewModel projectViewModel = Provider.of(context); + GAnalytics.TREATMENT_TYPE = + null; // reset treatment type on start new booking + return AppScaffold( - isShowAppBar: true, - isShowDecPage: false, - appBarTitle: TranslationBase.of(context).bookAppo, - body: Container( - child: Column( - children: [ - TabBar( - tabs: [ - Tab( - child: Text(TranslationBase.of(context).clinicName, - style: TextStyle(color: Colors.black))), - Tab( - child: Text(TranslationBase.of(context).doctorName, - style: TextStyle(color: Colors.black)), - ) - ], - controller: _tabController, + isShowAppBar: false, + isShowDecPage: false, + showNewAppBarTitle: true, + showNewAppBar: true, + appBarTitle: TranslationBase.of(context).bookAppo, + backgroundColor: Color(0xFFF7F7F7), + onTap: widget.onBackClick, + body: Column( + children: [ + TabBar( + controller: _tabController, + indicatorWeight: 3.0, + indicatorSize: TabBarIndicatorSize.tab, + labelColor: Color(0xff2B353E), + unselectedLabelColor: Color(0xff575757), + labelPadding: + EdgeInsets.only(top: 15, bottom: 13, left: 20, right: 20), + labelStyle: TextStyle( + fontFamily: context.read().isArabic + ? 'Cairo' + : 'Poppins', + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + ), + unselectedLabelStyle: TextStyle( + fontFamily: context.read().isArabic + ? 'Cairo' + : 'Poppins', + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + ), + tabs: [ + Text( + TranslationBase.of(context).hospitalName, + style: TextStyle(fontSize: 12), ), - Divider( - color: Colors.grey[600], - thickness: 0.5, + Text( + TranslationBase.of(context).clinicName, + style: TextStyle(fontSize: 12), ), - Expanded( - child: new TabBarView( - physics: NeverScrollableScrollPhysics(), - children: [ - SearchByClinic( - clnicIds: widget.clnicIds, - ), - SearchByDoctor() - ], - controller: _tabController, - ), + Text( + TranslationBase.of(context).doctorName, + style: TextStyle(fontSize: 12), ) ], + onTap: (idx) { + if (idx == 0) + context + .read() + .analytics + .appointment + .book_appointment_by_clinic(); + else + context + .read() + .analytics + .appointment + .book_appointment_by_doctor(); + }, ), - )); + Expanded( + child: TabBarView( + physics: NeverScrollableScrollPhysics(), + children: [ + SearchByHospital(), + SearchByClinic(clnicIds: widget.clnicIds), + SearchByDoctor(), + ], + controller: _tabController, + ), + ) + ], + ), + ); } } diff --git a/lib/pages/BookAppointment/SearchResults.dart b/lib/pages/BookAppointment/SearchResults.dart index e5f219f0..97946268 100644 --- a/lib/pages/BookAppointment/SearchResults.dart +++ b/lib/pages/BookAppointment/SearchResults.dart @@ -1,26 +1,32 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; +import 'package:diplomaticquarterapp/models/Appointments/OBGyneProcedureListResponse.dart'; import 'package:diplomaticquarterapp/pages/BookAppointment/widgets/DoctorView.dart'; -// import 'package:diplomaticquarterapp/services/robo_search/event_provider.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/widgets/others/app_expandable_notifier.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; -class SearchResults extends StatefulWidget { +class SearchResults extends StatelessWidget { List doctorsList = []; List patientDoctorAppointmentListHospital; bool isLiveCareAppointment; + bool isObGyneAppointment; + bool isDoctorNameSearch; + OBGyneProcedureListResponse? obGyneProcedureListResponse; + bool isDoctorSearchResult; SearchResults( - {@required this.doctorsList, this.patientDoctorAppointmentListHospital, @required this.isLiveCareAppointment}); - - @override - _SearchResultsState createState() => _SearchResultsState(); -} - -class _SearchResultsState extends State { - // var event = RobotProvider(); - List tempList = []; + {required this.doctorsList, + required this.patientDoctorAppointmentListHospital, + this.isObGyneAppointment = false, + this.isDoctorNameSearch = false, + required this.isLiveCareAppointment, + required this.isDoctorSearchResult, + this.obGyneProcedureListResponse}); @override Widget build(BuildContext context) { @@ -28,41 +34,62 @@ class _SearchResultsState extends State { appBarTitle: TranslationBase.of(context).bookAppo, isShowDecPage: false, isShowAppBar: true, - body: Container( - margin: EdgeInsets.all(10.0), - child: SingleChildScrollView( - physics: BouncingScrollPhysics(), - child: Column( - children: [ - ...List.generate( - widget.patientDoctorAppointmentListHospital.length, - (index) => AppExpandableNotifier( - // isExpand: index == 0 ? true : false, - title: widget.patientDoctorAppointmentListHospital[index] - .filterName + - " - " + - widget.patientDoctorAppointmentListHospital[index] - .distanceInKMs + - " " + - TranslationBase.of(context).km, - bodyWidget: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: widget - .patientDoctorAppointmentListHospital[index] - .patientDoctorAppointmentList - .map((doctor) { + showNewAppBarTitle: true, + showNewAppBar: true, + backgroundColor: CustomColors.appBackgroudGrey2Color, + body: patientDoctorAppointmentListHospital.isNotEmpty + ? ListView.separated( + addAutomaticKeepAlives: true, + physics: BouncingScrollPhysics(), + separatorBuilder: (context, index) { + return Container( + height: 12, + margin: EdgeInsets.only(left: 21, right: 21), + ); + }, + itemBuilder: (context, index) { + return AppExpandableNotifier( + title: (patientDoctorAppointmentListHospital[index].distanceInKMs != "0") + ? patientDoctorAppointmentListHospital[index].filterName! + " - " + patientDoctorAppointmentListHospital[index].distanceInKMs! + " " + TranslationBase.of(context).km + : patientDoctorAppointmentListHospital[index].filterName, + projectTitleTop: patientDoctorAppointmentListHospital[index].projectTopName, + projectTitleBottom: (patientDoctorAppointmentListHospital[index].distanceInKMs != "0") + ? patientDoctorAppointmentListHospital[index].projectBottomName.toString() + + " - " + + patientDoctorAppointmentListHospital[index].distanceInKMs! + + " " + + TranslationBase.of(context).km + : patientDoctorAppointmentListHospital[index].projectBottomName.toString(), + isTitleSingleLine: false, + isHMC: patientDoctorAppointmentListHospital[index].isHMC ?? + false, + isForAppointmentSearch: true, + isDoctorSearchResult: isDoctorSearchResult, + isExpand: patientDoctorAppointmentListHospital.length == 1 ? true : false, + bodyWidget: ListView.separated( + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + padding: EdgeInsets.only(bottom: 10, top: 10, left: 21, right: 21), + itemBuilder: (context, _index) { + final doctor = patientDoctorAppointmentListHospital[index].patientDoctorAppointmentList![_index]; return DoctorView( - doctor: doctor, - isLiveCareAppointment: widget.isLiveCareAppointment, - ); - }).toList(), - )), - ) - ], - ), - ), - ), + doctor: doctor, + isLiveCareAppointment: isLiveCareAppointment, + isObGyneAppointment: isObGyneAppointment, + isDoctorNameSearch: isDoctorNameSearch, + obGyneProcedureListResponse: obGyneProcedureListResponse, + isShowDate: false, + onTap: () { + context.read().analytics.appointment.book_appointment_select_doctor(appointment_type: 'regular', doctor: doctor); + }); + }, + separatorBuilder: (context, index) => SizedBox(height: 14), + itemCount: patientDoctorAppointmentListHospital[index].patientDoctorAppointmentList!.length), + ); + }, + itemCount: patientDoctorAppointmentListHospital.length, + ) + : getNoDataWidget(context), ); } } diff --git a/lib/pages/BookAppointment/SearchResultsByRegion.dart b/lib/pages/BookAppointment/SearchResultsByRegion.dart new file mode 100644 index 00000000..a1666ffc --- /dev/null +++ b/lib/pages/BookAppointment/SearchResultsByRegion.dart @@ -0,0 +1,380 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; +import 'package:diplomaticquarterapp/models/Appointments/OBGyneProcedureListResponse.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/widgets/DoctorView.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_expandable_notifier.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 SearchResultsByRegion extends StatelessWidget { + List doctorsList = []; + RegionList patientDoctorAppointmentListHospital; + bool isLiveCareAppointment; + bool isObGyneAppointment; + bool isDoctorNameSearch; + OBGyneProcedureListResponse? obGyneProcedureListResponse; + bool isDoctorSearchResult; + + SearchResultsByRegion( + {required this.doctorsList, + required this.patientDoctorAppointmentListHospital, + this.isObGyneAppointment = false, + this.isDoctorNameSearch = false, + required this.isLiveCareAppointment, + required this.isDoctorSearchResult, + this.obGyneProcedureListResponse}); + + @override + Widget build(BuildContext context) { + return AppScaffold( + appBarTitle: TranslationBase.of(context).bookAppo, + isShowDecPage: false, + isShowAppBar: true, + showNewAppBarTitle: true, + showNewAppBar: true, + backgroundColor: CustomColors.appBackgroudGrey2Color, + body: patientDoctorAppointmentListHospital + .registeredDoctorMap?.isNotEmpty == + true + ? ListView.separated( + addAutomaticKeepAlives: true, + physics: BouncingScrollPhysics(), + separatorBuilder: (context, index) { + return Material( + color: Color(0xFFf5f5f5), + child: SizedBox( + height: 12, + ), + ); + }, + itemBuilder: (context, index) { + String key = patientDoctorAppointmentListHospital + .registeredDoctorMap?.keys + .toList()[index] ?? + ''; + + return AppExpandableNotifier( + paddingValue: 10, + applyBackgroundToOnlyHeader: true, + completeHeaderColor: CustomColors.appBackgroudGrey2Color, + headerWidget: RegionTitle( + title: key, + hmcCount: + "${patientDoctorAppointmentListHospital.registeredDoctorMap?[key]?.hmcSize ?? 0}", + hmgCount: + "${patientDoctorAppointmentListHospital.registeredDoctorMap?[key]?.hmgSize ?? 0}", + ), + showDropDownIconWithCustomHeader: true, + isTitleSingleLine: false, + isDoctorSearchResult: isDoctorSearchResult, + widgetColor: Color(0xFFF8F8F8), + bodyWidget: Column( + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: AppExpandableNotifier( + paddingValue: 8, + applyBackgroundColor: false, + applyBackgroundToOnlyHeader: true, + completeHeaderColor: Colors.white, + headerRadius: BorderRadius.circular(16), + headerWidget: HospitalTitle( + iconUrl: 'assets/images/svg/HMG.svg', + title: TranslationBase.of(context).hmgHospital, + isHMC: false, + itemCount: + "${patientDoctorAppointmentListHospital.registeredDoctorMap?[key]?.hmgSize ?? 0}", + ), + showDropDownIconWithCustomHeader: true, + bodyWidget: HospitalBodyWidget( + patientDoctorAppointmentListHospital: + patientDoctorAppointmentListHospital + .registeredDoctorMap?[key]?.hmgDoctorList, + isLiveCareAppointment: isLiveCareAppointment, + isObGyneAppointment: isObGyneAppointment, + isDoctorNameSearch: isDoctorNameSearch, + isDoctorSearchResult: isDoctorSearchResult, + ), + ), + ), + Padding( + padding: const EdgeInsets.only( + bottom: 8.0, left: 8, right: 8), + child: AppExpandableNotifier( + paddingValue: 8, + applyBackgroundColor: false, + applyBackgroundToOnlyHeader: true, + completeHeaderColor: Colors.white, + headerRadius: BorderRadius.circular(16), + headerWidget: HospitalTitle( + iconUrl: 'assets/images/svg/HMC.svg', + title: TranslationBase.of(context).hmcHospital, + isHMC: true, + itemCount: + "${patientDoctorAppointmentListHospital.registeredDoctorMap?[key]?.hmcSize ?? 0}", + ), + showDropDownIconWithCustomHeader: true, + bodyWidget: HospitalBodyWidget( + patientDoctorAppointmentListHospital: + patientDoctorAppointmentListHospital + .registeredDoctorMap?[key]?.hmcDoctorList, + isLiveCareAppointment: isLiveCareAppointment, + isObGyneAppointment: isObGyneAppointment, + isDoctorNameSearch: isDoctorNameSearch, + isDoctorSearchResult: isDoctorSearchResult, + ), + ), + ), + ], + )); + // return AppExpandableNotifier( + // title: (patientDoctorAppointmentListHospital[index].distanceInKMs != "0") + // ? patientDoctorAppointmentListHospital[index].filterName! + " - " + patientDoctorAppointmentListHospital[index].distanceInKMs! + " " + TranslationBase.of(context).km + // : patientDoctorAppointmentListHospital[index].filterName, + // projectTitleTop: patientDoctorAppointmentListHospital[index].projectTopName, + // projectTitleBottom: (patientDoctorAppointmentListHospital[index].distanceInKMs != "0") + // ? patientDoctorAppointmentListHospital[index].projectBottomName.toString() + + // " - " + + // patientDoctorAppointmentListHospital[index].distanceInKMs! + + // " " + + // TranslationBase.of(context).km + // : patientDoctorAppointmentListHospital[index].projectBottomName.toString(), + // isTitleSingleLine: false, + // isDoctorSearchResult: isDoctorSearchResult, + // isExpand: patientDoctorAppointmentListHospital.length == 1 ? true : false, + // bodyWidget: ListView.separated( + // shrinkWrap: true, + // physics: NeverScrollableScrollPhysics(), + // padding: EdgeInsets.only(bottom: 10, top: 10, left: 21, right: 21), + // itemBuilder: (context, _index) { + // final doctor = patientDoctorAppointmentListHospital[index].patientDoctorAppointmentList![_index]; + // return DoctorView( + // doctor: doctor, + // isLiveCareAppointment: isLiveCareAppointment, + // isObGyneAppointment: isObGyneAppointment, + // isDoctorNameSearch: isDoctorNameSearch, + // obGyneProcedureListResponse: obGyneProcedureListResponse, + // isShowDate: false, + // onTap: () { + // context.read().analytics.appointment.book_appointment_select_doctor(appointment_type: 'regular', doctor: doctor); + // }); + // }, + // separatorBuilder: (context, index) => SizedBox(height: 14), + // itemCount: patientDoctorAppointmentListHospital[index].patientDoctorAppointmentList!.length), + // ); + }, + itemCount: patientDoctorAppointmentListHospital + .registeredDoctorMap?.length ?? + 0, + ) + : getNoDataWidget(context), + ); + } +} + +class HospitalBodyWidget extends StatelessWidget { + final List? + patientDoctorAppointmentListHospital; + final bool isLiveCareAppointment; + final bool isObGyneAppointment; + final bool isDoctorNameSearch; + final bool isDoctorSearchResult; + final OBGyneProcedureListResponse? obGyneProcedureListResponse; + + const HospitalBodyWidget({ + super.key, + this.patientDoctorAppointmentListHospital, + required this.isLiveCareAppointment, + required this.isObGyneAppointment, + required this.isDoctorNameSearch, + required this.isDoctorSearchResult, + this.obGyneProcedureListResponse, + }); + + @override + Widget build(BuildContext context) { + return ListView.separated( + addAutomaticKeepAlives: true, + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + itemCount: patientDoctorAppointmentListHospital?.length ?? 0, + separatorBuilder: (context, index) { + return Container( + height: 12, + margin: EdgeInsets.only(left: 21, right: 21), + ); + }, + itemBuilder: (context, index) { + return AppExpandableNotifier( + applyBackgroundColor: false, + widgetColor: CustomColors.appBackgroudGrey2Color, + title: (patientDoctorAppointmentListHospital?[index].distanceInKMs != + "0") + ? patientDoctorAppointmentListHospital![index].filterName! + + " - " + + patientDoctorAppointmentListHospital![index].distanceInKMs! + + " " + + TranslationBase.of(context).km + : patientDoctorAppointmentListHospital![index].filterName, + projectTitleTop: + patientDoctorAppointmentListHospital![index].projectTopName, + projectTitleBottom: (patientDoctorAppointmentListHospital![index] + .distanceInKMs != + "0") + ? patientDoctorAppointmentListHospital![index] + .projectBottomName + .toString() + + " - " + + patientDoctorAppointmentListHospital![index].distanceInKMs! + + " " + + TranslationBase.of(context).km + : patientDoctorAppointmentListHospital![index] + .projectBottomName + .toString(), + isTitleSingleLine: false, + isDoctorSearchResult: isDoctorSearchResult, + isExpand: + patientDoctorAppointmentListHospital?.length == 1 ? true : false, + bodyWidget: ListView.separated( + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + padding: + EdgeInsets.only(bottom: 10, top: 10, left: 21, right: 21), + itemBuilder: (context, _index) { + // print("the index of patientDoctorAppointmentList is ${_index}"); + // print("the index of parent is ${index}"); + final doctor = patientDoctorAppointmentListHospital![index] + .patientDoctorAppointmentList![_index]; + // print('the doctor is ${doctor.toJson()}'); + return DoctorView( + doctor: doctor, + isLiveCareAppointment: isLiveCareAppointment, + isObGyneAppointment: isObGyneAppointment, + isDoctorNameSearch: isDoctorNameSearch, + obGyneProcedureListResponse: obGyneProcedureListResponse, + isShowDate: false, + onTap: () { + context + .read() + .analytics + .appointment + .book_appointment_select_doctor( + appointment_type: 'regular', doctor: doctor); + }); + }, + separatorBuilder: (context, index) => SizedBox(height: 14), + itemCount: patientDoctorAppointmentListHospital?[index].patientDoctorAppointmentList?.length ?? 0), + ); + }, + ); + } +} + +class RegionTitle extends StatelessWidget { + final String title; + final String hmcCount; + final String hmgCount; + + const RegionTitle( + {super.key, + required this.title, + required this.hmcCount, + required this.hmgCount}); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title, + style: TextStyle( + fontSize: 22, color: Colors.black, fontWeight: FontWeight.w700), + ), + SizedBox( + height: 8, + ), + Row( + children: [ + Text( + "${TranslationBase.of(context).HospitalString(num.parse(hmgCount)).replaceAll("@", hmgCount)} ,", + style: TextStyle( + fontSize: 14, + color: Color(0xFFD02127), + fontWeight: FontWeight.w600), + ), + SizedBox( + width: 8, + ), + Text( + "${TranslationBase.of(context).MedicalCenterString(num.parse(hmcCount)).replaceAll("@", hmcCount)}", + style: TextStyle( + fontSize: 14, + color: Color(0xFF40ACC9), + fontWeight: FontWeight.w600), + ), + ], + ), + ], + ), + ); + } +} + +class HospitalTitle extends StatelessWidget { + final String title; + final String iconUrl; + final bool isHMC; + final String itemCount; + + const HospitalTitle( + {super.key, + required this.title, + required this.iconUrl, + required this.isHMC, + required this.itemCount}); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + SvgPicture.asset(iconUrl), + SizedBox( + width: 8, + ), + Text( + title, + style: TextStyle( + fontSize: 18, + color: isHMC ? Color(0xFF40ACC9) : Color(0xFFD02127), + fontWeight: FontWeight.w600), + ), + ], + ), + SizedBox( + height: 6, + ), + Text( + isHMC + ? "${TranslationBase.of(context).MedicalCenterString(num.parse(itemCount)).replaceAll("@", itemCount)}" + : "${TranslationBase.of(context).HospitalString(num.parse(itemCount)).replaceAll("@", itemCount)}", + style: TextStyle( + fontSize: 12, color: Colors.black, fontWeight: FontWeight.w600), + ), + ], + ), + ); + } +} diff --git a/lib/pages/BookAppointment/book_reminder_page.dart b/lib/pages/BookAppointment/book_reminder_page.dart new file mode 100644 index 00000000..547ab901 --- /dev/null +++ b/lib/pages/BookAppointment/book_reminder_page.dart @@ -0,0 +1,227 @@ +import 'package:auto_size_text/auto_size_text.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; +import 'package:diplomaticquarterapp/models/Appointments/PatientShareResposne.dart'; +import 'package:diplomaticquarterapp/models/header_model.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/widgets/reminder_dialog.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/custom_text_button.dart'; +import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart'; +import 'package:diplomaticquarterapp/widgets/new_design/doctor_header.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +import 'package:flutter/material.dart'; +import 'package:permission_handler/permission_handler.dart'; +import 'package:provider/provider.dart'; + +import 'BookSuccess.dart'; + +class BookReminderPage extends StatefulWidget { + PatientShareResponse patientShareResponse; + DoctorList docObject; + + String appoDateFormatted; + String appoTimeFormatted; + DateTime? dateTime; + bool isCash; + + BookReminderPage({required this.patientShareResponse, required this.docObject, required this.appoDateFormatted, required this.appoTimeFormatted, this.dateTime, this.isCash = false}); + + @override + _BookReminderPageState createState() => _BookReminderPageState(); +} + +class _BookReminderPageState extends State { + late MyInAppBrowser browser; + + // final ChromeSafariBrowser chromeBrowser = new MyChromeSafariBrowser(new MyInAppBrowser()); + + String? selectedTime; + bool isSuccessShow = true; + + @override + void initState() { + // TODO: implement initState + super.initState(); + Future.delayed(const Duration(seconds: 2), () { +// Here you can write your code + + setState(() { + isSuccessShow = false; + }); + }); + } + + late ProjectViewModel projectViewModel; + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + return AppScaffold( + appBarTitle: widget.docObject.doctorTitle! + " " + widget.docObject.name!, + isShowDecPage: false, + isShowAppBar: true, + showNewAppBarTitle: true, + showNewAppBar: true, + backgroundColor: CustomColors.appBackgroudGrey2Color, + body: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.max, + children: [ + DoctorHeader( + headerModel: HeaderModel( + widget.docObject.name!, + widget.docObject.doctorID!, + widget.docObject.doctorImageURL!, + widget.docObject.speciality!, + "", + widget.docObject.projectName!, + null, + null, + widget.docObject.nationalityFlagURL ?? "", + widget.docObject.doctorRate ?? 0, + null, + widget.docObject.noOfPatientsRate ?? 0, + "", + ), + isNeedToShowButton: false, + ), + Expanded( + child: Container( + width: double.infinity, + height: double.infinity, + padding: EdgeInsets.only(bottom: 70), + child: Padding( + padding: const EdgeInsets.all(20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Icon( + Icons.notifications_active, + size: 60, + ), + Text( + TranslationBase.of(context).appointmentCalendar, + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + ), + ), + mFlex(1), + if (isSuccessShow) + Container( + width: double.infinity, + child: Container( + decoration: cardRadius(12), + margin: EdgeInsets.all(10), + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Row( + children: [ + circularAviator( + 30, + icon: Icons.done_rounded, + iconColor: Colors.white, + bcColor: CustomColors.green, + brColor: CustomColors.green, + ), + mWidth(10), + Expanded( + child: AutoSizeText( + TranslationBase.of(context).appointmentSuccess, + maxLines: 1, + minFontSize: 6, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.65, + ), + ), + ) + ], + ), + ), + ), + ), + ], + ), + ), + ), + ), + ], + ), + bottomSheet: Container( + color: CustomColors.appBackgroudGreyColor, + child: Container( + color: CustomColors.white, + margin: EdgeInsets.all(14), + height: 45.0, + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Expanded( + flex: 1, + child: CustomTextButton( + backgroundColor: CustomColors.accentColor, + elevation: 0, + onPressed: () { + navigateToBookSuccess(context); + projectViewModel.analytics.appointment.appointment_reminder(false); + }, + child: Text(TranslationBase.of(context).no, style: TextStyle(fontSize: 16.0, letterSpacing: -0.48, color: Colors.white)), + ), + ), + mWidth(7), + Expanded( + flex: 1, + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + height: 45.0, + child: CustomTextButton( + backgroundColor: CustomColors.green, + elevation: 0, + onPressed: () async { + showReminderDialog(context, widget.dateTime!, widget.docObject.name!, widget.patientShareResponse.appointmentNo.toString(), widget.appoDateFormatted, widget.appoTimeFormatted, + onSuccess: () { + AppToast.showSuccessToast(message: TranslationBase.of(context).reminderSuccess); + navigateToBookSuccess(context); + }, title: null, description: null); + projectViewModel.analytics.appointment.appointment_reminder(true); + }, + child: Text(TranslationBase.of(context).yes, style: TextStyle(fontSize: 16.0, letterSpacing: -0.48, color: Colors.white)), + ), + ), + ), + ], + ), + ), + ), + ); + } + + Future navigateToBookSuccess(BuildContext context) async { + Navigator.push( + context, + FadePage( + page: BookSuccess( + docObject: widget.docObject, + patientShareResponse: widget.patientShareResponse, + appoDateFormatted: widget.appoDateFormatted, + appoTimeFormatted: widget.appoTimeFormatted, + isCash: widget.isCash, + ), + ), + ); + } + + Future> requestPermissions() async { + var permissionResults = [Permission.calendarFullAccess].request(); + return permissionResults; + } +} diff --git a/lib/pages/BookAppointment/components/DocAvailableAppointments.dart b/lib/pages/BookAppointment/components/DocAvailableAppointments.dart index cd8bb789..67a795da 100644 --- a/lib/pages/BookAppointment/components/DocAvailableAppointments.dart +++ b/lib/pages/BookAppointment/components/DocAvailableAppointments.dart @@ -1,57 +1,80 @@ import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; import 'package:diplomaticquarterapp/models/Appointments/FreeSlot.dart'; import 'package:diplomaticquarterapp/models/Appointments/timeSlot.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.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'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/custom_text_button.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; -import 'package:table_calendar/table_calendar.dart'; - +import 'package:provider/provider.dart'; +import 'package:syncfusion_flutter_calendar/calendar.dart'; +import 'dart:convert'; import '../../../uitl/date_uitl.dart'; class DocAvailableAppointments extends StatefulWidget { DoctorList doctor; static bool areSlotsAvailable = false; static bool areAppointmentsAvailable = false; - static DateTime selectedAppoDateTime; - static String selectedDate; - static String selectedTime; + static DateTime? selectedAppoDateTime; + static String? selectedDate; + static String? selectedTime; bool isLiveCareAppointment; + bool isContinueDentalPlan; + final dynamic doctorSchedule; + static int? initialSlotDuration; - DocAvailableAppointments( - {@required this.doctor, @required this.isLiveCareAppointment}); + DocAvailableAppointments({required this.doctor, this.doctorSchedule, required this.isLiveCareAppointment, this.isContinueDentalPlan = false}); @override - _DocAvailableAppointmentsState createState() => - _DocAvailableAppointmentsState(); + _DocAvailableAppointmentsState createState() => _DocAvailableAppointmentsState(); } -class _DocAvailableAppointmentsState extends State - with TickerProviderStateMixin { - Map _events; - AnimationController _animationController; - CalendarController _calendarController; +class _DocAvailableAppointmentsState extends State with TickerProviderStateMixin { + late Map _events; + late AnimationController _animationController; + late CalendarController _calendarController; AppSharedPreferences sharedPref = new AppSharedPreferences(); var selectedDate = ""; + var selectedNextDate = ""; dynamic selectedDateJSON; dynamic jsonFreeSlots; - + final DateFormat dateFormatter = DateFormat('yyyy-MM-dd'); List docFreeSlots = []; List dayEvents = []; - + List nextDayEvents = []; int selectedButtonIndex = 0; - + int selectedNextDayButtonIndex = -1; dynamic freeSlotsResponse; - ScrollController _scrollController; + // String nextDayAppointmentDate =""; + late ScrollController _scrollController; var language; + bool isLiveCareSchedule = false; + + bool isWaitingAppointmentAvailable = false; + + // String selectedLogSlots =''; + + @override + void didUpdateWidget(covariant DocAvailableAppointments oldWidget) { + if (oldWidget.doctorSchedule != widget.doctorSchedule) { + _onDaySelected(DateUtil.convertStringToDate(widget.doctorSchedule['Date'])); + _calendarController.selectedDate = DateUtil.convertStringToDate(widget.doctorSchedule['Date']); + } + super.didUpdateWidget(oldWidget); + } @override void initState() { @@ -67,7 +90,8 @@ class _DocAvailableAppointmentsState extends State WidgetsBinding.instance.addPostFrameCallback((_) async { getCurrentLanguage(); - if (widget.isLiveCareAppointment) + isLiveCareSchedule = await this.sharedPref.getBool(IS_LIVECARE_APPOINTMENT) ?? false; + if (isLiveCareSchedule != null && isLiveCareSchedule) getDoctorScheduledFreeSlots(context, widget.doctor); else { getDoctorFreeSlots(context, widget.doctor); @@ -90,68 +114,87 @@ class _DocAvailableAppointmentsState extends State super.dispose(); } - void _onDaySelected(DateTime day, List events) { + void _onDaySelected(DateTime day) { final DateFormat formatter = DateFormat('yyyy-MM-dd'); setState(() { - this.selectedDate = - DateUtil.getWeekDayMonthDayYearDateFormatted(day, language); + this.selectedDate = DateUtil.getWeekDayMonthDayYearDateFormatted(day, language); + this.selectedNextDate = DateUtil.getWeekDayMonthDayYearDateFormatted(day.add(Duration(days: 1)), language); + _calendarController.selectedDate = day; openTimeSlotsPickerForDate(day, docFreeSlots); DocAvailableAppointments.selectedDate = formatter.format(day); - print(DocAvailableAppointments.selectedDate); + selectedNextDayButtonIndex = -1; + print(_calendarController.selectedDate); }); } - void _onVisibleDaysChanged( - DateTime first, DateTime last, CalendarFormat format) { - print('CALLBACK: _onVisibleDaysChanged'); - } - - void _onCalendarCreated( - DateTime first, DateTime last, CalendarFormat format) { - print('CALLBACK: _onCalendarCreated'); - } + late ProjectViewModel projectViewModel; @override Widget build(BuildContext context) { + projectViewModel = Provider.of(context); return SingleChildScrollView( child: Container( - decoration: BoxDecoration( - color: Colors.white, borderRadius: BorderRadius.circular(10.0)), - margin: EdgeInsets.all(20.0), - padding: EdgeInsets.only(bottom: 10.0, top: 10.0), child: Column( mainAxisSize: MainAxisSize.max, + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text(selectedDate, - style: TextStyle(fontSize: 18.0, fontWeight: FontWeight.bold)), - Container( - height: 50, - margin: EdgeInsets.all(20.0), - child: ListView.builder( - controller: _scrollController, - scrollDirection: Axis.horizontal, - itemCount: dayEvents.length, - itemBuilder: (context, index) { - return Container( - margin: EdgeInsets.only(right: 10.0), - child: ButtonTheme( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(5.0), - side: BorderSide( - color: Color(0xff76cfb7), //Color of the border - style: BorderStyle.solid, //Style of the border - width: 1.5, //width of the border - ), - ), - minWidth: MediaQuery.of(context).size.width * 0.2, - child: index == selectedButtonIndex - ? getSelectedButton(index) - : getNormalButton(index)), - ); - }, - ), - ), _buildTableCalendarWithBuilders(), + Padding( + padding: const EdgeInsets.only(left: 16, right: 16, bottom: 16), + child: Text(selectedDate, style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.w600, letterSpacing: -0.64)), + ), + DocAvailableAppointments.areSlotsAvailable + ? Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + height: 40, + child: ListView.builder( + controller: _scrollController, + scrollDirection: Axis.horizontal, + itemCount: dayEvents.length, + itemBuilder: (context, index) { + return Container( + margin: EdgeInsets.only(right: (index == dayEvents.length - 1) ? 16 : 5.0, left: index == 0 ? 16 : 5), + child: index == selectedButtonIndex ? getSelectedButton(index) : getNormalButton(index), + ); + }, + ), + ), + SizedBox( + height: 20, + ), + nextDayEvents.isNotEmpty && projectViewModel.havePrivilege(110) + ? Container( + padding: EdgeInsets.only(left: 20, right: 20, bottom: 20), + child: Text( + selectedNextDate, + style: TextStyle(fontSize: 14.0, fontWeight: FontWeight.w600, letterSpacing: -0.46, color: CustomColors.black), + ), + ) + : SizedBox(), + Container( + height: 40, + padding: EdgeInsets.only(left: 0, right: 0), + child: ListView.builder( + controller: _scrollController, + scrollDirection: Axis.horizontal, + itemCount: nextDayEvents.length, + itemBuilder: (context, index) { + return Container( + margin: EdgeInsets.only(right: (index == nextDayEvents.length - 1) ? 16 : 5.0, left: index == 0 ? 16 : 5), + child: index == selectedNextDayButtonIndex ? getSelectedNextDayButton(index) : getNormalNextDayButton(index), + ); + }, + ), + ) + ], + ) + : Center( + child: Padding( + padding: const EdgeInsets.only(left: 12.0, right: 12.0), + child: Text(TranslationBase.of(context).noSlotsError, style: TextStyle(fontSize: 14.0, fontWeight: FontWeight.w600, letterSpacing: -0.46, color: CustomColors.grey)), + )), ], ), ), @@ -159,202 +202,297 @@ class _DocAvailableAppointmentsState extends State } Widget _buildTableCalendarWithBuilders() { - return TableCalendar( - locale: language == "en" ? 'en_US' : 'ar_SA', - calendarController: _calendarController, - events: _events, - initialCalendarFormat: CalendarFormat.month, - startDay: DateTime.now(), - formatAnimation: FormatAnimation.slide, - startingDayOfWeek: StartingDayOfWeek.sunday, - weekendDays: [DateTime.friday, DateTime.saturday], - availableGestures: AvailableGestures.horizontalSwipe, - availableCalendarFormats: const { - CalendarFormat.month: '', - CalendarFormat.week: '', - }, - calendarStyle: CalendarStyle( - outsideDaysVisible: false, - weekendStyle: TextStyle().copyWith(color: Colors.blue[800]), - holidayStyle: TextStyle().copyWith(color: Colors.blue[800]), - ), - daysOfWeekStyle: DaysOfWeekStyle( - weekendStyle: TextStyle().copyWith(color: Colors.black, fontSize: 14.0), - weekdayStyle: TextStyle().copyWith(color: Colors.black, fontSize: 14.0), - ), - headerStyle: HeaderStyle( - centerHeaderTitle: true, - formatButtonVisible: false, - ), - builders: CalendarBuilders( - selectedDayBuilder: (context, date, _) { - return FadeTransition( - opacity: Tween(begin: 0.0, end: 1.0).animate(_animationController), - child: Container( - margin: const EdgeInsets.all(4.0), - padding: const EdgeInsets.only(top: 5.0, left: 5.0), - color: Colors.transparent, - width: 0, - height: 0, - child: Text( - '${date.day}', - style: TextStyle().copyWith(fontSize: 16.0), - ), - ), - ); - }, - todayDayBuilder: (context, date, _) { - return Container( - decoration: BoxDecoration( - shape: BoxShape.circle, - color: _calendarController.isSelected(date) - ? Colors.green[400] - : _calendarController.isToday(date) - ? Colors.transparent - : Color(0xff76cfb7), - ), - width: 40.0, - height: 40.0, - child: Center( - child: Text( - '${date.day}', - style: TextStyle().copyWith( - color: Colors.white, - fontSize: 14.0, - ), - ), + return Container( + decoration: cardRadius(12), + margin: EdgeInsets.all(16), + clipBehavior: Clip.antiAlias, + child: Padding( + padding: const EdgeInsets.only(bottom: 12), + child: Container( + child: SfCalendar( + controller: _calendarController, + minDate: DateTime.now(), + // showNavigationArrow: true, + headerStyle: CalendarHeaderStyle(textAlign: TextAlign.center, textStyle: TextStyle(fontSize: 14.0, fontWeight: FontWeight.w600, letterSpacing: -0.46)), + viewHeaderStyle: ViewHeaderStyle(dayTextStyle: TextStyle(fontSize: 12.0, fontWeight: FontWeight.w600, letterSpacing: -0.46, color: CustomColors.black)), + view: CalendarView.month, + todayHighlightColor: Colors.transparent, + todayTextStyle: TextStyle(color: Colors.black), + selectionDecoration: containerColorRadiusBorderWidthCircular(Colors.transparent, 4, CustomColors.green, 2.5), + cellBorderColor: Colors.white, + dataSource: MeetingDataSource(_getDataSource()), + monthViewSettings: const MonthViewSettings(appointmentDisplayMode: MonthAppointmentDisplayMode.indicator, showTrailingAndLeadingDates: false, appointmentDisplayCount: 1), + onTap: (CalendarTapDetails details) { + _calendarController.selectedDate = details.date; + _onDaySelected(details.date!); + }, ), - ); - }, - markersBuilder: (context, date, events, _) { - final children = []; - if (events.isNotEmpty) { - children.add( - Positioned( - right: 4, - bottom: 4, - child: _buildEventsMarker(date, events), - ), - ); - } + ), + )); + } - return children; - }, - ), - onDaySelected: (date, event, _) { - _onDaySelected(date, event); - _animationController.forward(from: 0.0); - }, - onVisibleDaysChanged: _onVisibleDaysChanged, - onCalendarCreated: _onCalendarCreated, - ); + List _getDataSource() { + 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)); + meetings.add(Meeting("", startTime, endTime, CustomColors.green, false, "")); + }); + return meetings; } openTimeSlotsPickerForDate(DateTime dateStart, List freeSlots) { dayEvents.clear(); - DateTime dateStartObj = new DateTime( - dateStart.year, dateStart.month, dateStart.day, 0, 0, 0, 0, 0); - + DateTime dateStartObj = new DateTime(dateStart.year, dateStart.month, dateStart.day, 0, 0, 0, 0, 0); + if (isWaitingAppointmentAvailable && DateUtils.isSameDay(dateStart, DateTime.now())) { + dayEvents.add(TimeSlot(isoTime: TranslationBase.of(context).waitingAppointment, start: DateTime.now(), end: DateTime.now(), vidaDate: "")); + } freeSlots.forEach((v) { if (v.start == dateStartObj) dayEvents.add(v); }); setState(() { - if (dayEvents.length != 0) + if (dayEvents.length != 0) { DocAvailableAppointments.areSlotsAvailable = true; - else + selectedButtonIndex = 0; + // selectedLogSlots = dayEvents[selectedButtonIndex].toString(); + List> timeList = []; + for (var i = 0; i < dayEvents.length; i++) { + Map timeSlot = {"isoTime": dayEvents[i].isoTime, "start": dayEvents[i].start.toString(), "end": dayEvents[i].end.toString(), "vidaDate": dayEvents[i].vidaDate}; + timeList.add(timeSlot); + } + filterNextDayAppo(freeSlots, timeList.last); + AppSharedPreferences sharedPref = new AppSharedPreferences(); + sharedPref.setString('selectedLogSlots', json.encode(timeList)); + DocAvailableAppointments.selectedTime = dayEvents[selectedButtonIndex].isoTime; + } else DocAvailableAppointments.areSlotsAvailable = false; - - selectedButtonIndex = 0; - - DocAvailableAppointments.selectedTime = - dayEvents[selectedButtonIndex].isoTime; - -// _scrollController.animateTo(0.0, duration: new Duration(seconds: 1), curve: Curves.ease); }); } + filterNextDayAppo(List freeSlots, Map listList) { + DateTime dateStart = DateTime.parse(listList['end']).add(Duration(days: 1)); + + DateTime dateStartObj = new DateTime(dateStart.year, dateStart.month, dateStart.day, 0, 0, 0, 0, 0); + nextDayEvents = []; + DateTime beforeHour = new DateTime(dateStart.year, dateStart.month, dateStart.day, 6, 0, 0, 0, 0); + if (projectViewModel.havePrivilege(110)) { + freeSlots.forEach((v) { + if (v.start == dateStartObj && v.end!.isBefore(beforeHour)) nextDayEvents.add(v); + }); + } else { + nextDayEvents = []; + } + // print(nextDayEvents); + } + Future> _getJSONSlots() async { Map _eventsParsed; List slotsList = []; DateTime date; final DateFormat formatter = DateFormat('HH:mm'); - final DateFormat dateFormatter = DateFormat('yyyy-MM-dd'); for (var i = 0; i < freeSlotsResponse.length; i++) { - date = DateUtil.convertStringToDate(freeSlotsResponse[i]); + date = (isLiveCareSchedule != null && isLiveCareSchedule) + ? DateUtil.convertStringToDate(freeSlotsResponse[i]) + : DateUtil.convertStringToDateSaudiTimezone(freeSlotsResponse[i], int.parse(widget.doctor.projectID.toString())); slotsList.add(FreeSlot(date, ['slot'])); - docFreeSlots.add(TimeSlot( - isoTime: formatter.format(date), - start: new DateTime(date.year, date.month, date.day, 0, 0, 0, 0), - end: date)); + docFreeSlots.add(TimeSlot(isoTime: formatter.format(date), start: new DateTime(date.year, date.month, date.day, 0, 0, 0, 0), end: date, vidaDate: freeSlotsResponse[i])); } - _eventsParsed = - Map.fromIterable(slotsList, key: (e) => e.slot, value: (e) => e.event); + _eventsParsed = Map.fromIterable(slotsList, key: (e) => e.slot, value: (e) => e.event); setState(() { - DocAvailableAppointments.selectedDate = dateFormatter - .format(DateUtil.convertStringToDate(freeSlotsResponse[0])); + DocAvailableAppointments.selectedDate = dateFormatter.format( + (isLiveCareSchedule != null && isLiveCareSchedule) + ? DateUtil.convertStringToDate(freeSlotsResponse[0]) + : DateUtil.convertStringToDateSaudiTimezone( + freeSlotsResponse[0], + int.parse( + widget.doctor.projectID.toString(), + ), + ), + ); + + DocAvailableAppointments.selectedAppoDateTime = (isLiveCareSchedule != null && isLiveCareSchedule) + ? DateUtil.convertStringToDate(freeSlotsResponse[0]) + : DateUtil.convertStringToDateSaudiTimezone( + freeSlotsResponse[0], + int.parse( + widget.doctor.projectID.toString(), + ), + ); selectedDate = DateUtil.getWeekDayMonthDayYearDateFormatted( - DateUtil.convertStringToDate(freeSlotsResponse[0]), language); + (isLiveCareSchedule != null && isLiveCareSchedule) + ? DateUtil.convertStringToDate(freeSlotsResponse[0]) + : DateUtil.convertStringToDateSaudiTimezone( + freeSlotsResponse[0], + int.parse( + widget.doctor.projectID.toString(), + ), + ), + language); + selectedNextDate = DateUtil.getWeekDayMonthDayYearDateFormatted( + (isLiveCareSchedule != null && isLiveCareSchedule) + ? DateUtil.convertStringToDate(freeSlotsResponse[0]).add(Duration(days: 1)) + : DateUtil.convertStringToDateSaudiTimezone( + freeSlotsResponse[0], + int.parse( + widget.doctor.projectID.toString(), + ), + ).add(Duration(days: 1)), + language); selectedDateJSON = freeSlotsResponse[0]; }); openTimeSlotsPickerForDate( - DateUtil.convertStringToDate(selectedDateJSON), docFreeSlots); - _calendarController - .setFocusedDay(DateUtil.convertStringToDate(selectedDateJSON)); + isWaitingAppointmentAvailable + ? DateTime.now() + : (isLiveCareSchedule != null && isLiveCareSchedule) + ? DateUtil.convertStringToDate(selectedDateJSON) + : DateUtil.convertStringToDateSaudiTimezone( + selectedDateJSON, + int.parse( + widget.doctor.projectID.toString(), + ), + ), + docFreeSlots); + _calendarController.selectedDate = isWaitingAppointmentAvailable + ? DateTime.now() + : (isLiveCareSchedule != null && isLiveCareSchedule) + ? DateUtil.convertStringToDate(selectedDateJSON) + : DateUtil.convertStringToDateSaudiTimezone( + selectedDateJSON, + int.parse( + widget.doctor.projectID.toString(), + ), + ); + _calendarController.displayDate = _calendarController.selectedDate; return _eventsParsed; } Widget getNormalButton(int index) { - return RaisedButton( - color: Colors.white, - textColor: new Color(0xFF60686b), + return CustomTextButton( + backgroundColor: Colors.white, + elevation: 0, + side: BorderSide( + color: Colors.black, //Color of the border + style: BorderStyle.solid, //Style of the border + width: 1.5 //width of the border + ), onPressed: () { + final timeslot = dayEvents[index]; + DocAvailableAppointments.selectedAppoDateTime = timeslot.end; + setState(() { selectedButtonIndex = index; + selectedNextDayButtonIndex = -1; DocAvailableAppointments.selectedTime = dayEvents[index].isoTime; print(DocAvailableAppointments.selectedTime); + DocAvailableAppointments.selectedDate = dateFormatter.format(_calendarController.selectedDate!); }); + projectViewModel.analytics.appointment.book_appointment_time_selection(appointment_type: 'regular', dateTime: timeslot.end, doctor: widget.doctor); }, - child: Text(dayEvents[index].isoTime, - style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold)), + child: Text(dayEvents[index].isoTime!, style: TextStyle(fontSize: 12.0, color: Color(0xFF60686b))), ); } Widget getSelectedButton(int index) { - return RaisedButton( - color: Color(0xff76cfb7), //Color of the border - textColor: Colors.white, + return CustomTextButton( + backgroundColor: dayEvents[index].isoTime == TranslationBase.of(context).waitingAppointment ? CustomColors.darkOrange : CustomColors.green, + elevation: 0, + side: BorderSide( + color: dayEvents[index].isoTime == TranslationBase.of(context).waitingAppointment ? CustomColors.darkOrange : CustomColors.green, //Color of the border + style: BorderStyle.solid, //Style of the border + width: 1.5 //width of the border + ), onPressed: () { setState(() { selectedButtonIndex = index; DocAvailableAppointments.selectedTime = dayEvents[index].isoTime; + DocAvailableAppointments.selectedDate = dateFormatter.format(_calendarController.selectedDate!); + print(DocAvailableAppointments.selectedTime); + }); + }, + child: Text(dayEvents[index].isoTime!, style: TextStyle(fontSize: 12.0, color: Colors.white)), + ); + } + + Widget getNormalNextDayButton(int index) { + return CustomTextButton( + backgroundColor: Colors.white, + elevation: 0, + side: BorderSide( + color: Colors.black, //Color of the border + style: BorderStyle.solid, //Style of the border + width: 1.5 //width of the border + ), + onPressed: () { + final timeslot = nextDayEvents[index]; + DocAvailableAppointments.selectedAppoDateTime = timeslot.end; + + setState(() { + selectedButtonIndex = -1; + selectedNextDayButtonIndex = index; + DocAvailableAppointments.selectedTime = nextDayEvents[index].isoTime; + DocAvailableAppointments.selectedDate = dateFormatter.format(_calendarController.selectedDate!.add(Duration(days: 1))); + print(DocAvailableAppointments.selectedTime); + }); + projectViewModel.analytics.appointment.book_appointment_time_selection(appointment_type: 'regular', dateTime: timeslot.end, doctor: widget.doctor); + }, + child: Text(nextDayEvents[index].isoTime!, style: TextStyle(fontSize: 12.0, color: Color(0xFF60686b))), + ); + } + + Widget getSelectedNextDayButton(int index) { + return CustomTextButton( + backgroundColor: nextDayEvents[index].isoTime == TranslationBase.of(context).waitingAppointment ? CustomColors.darkOrange : CustomColors.green, + elevation: 0, + side: BorderSide( + color: nextDayEvents[index].isoTime == TranslationBase.of(context).waitingAppointment ? CustomColors.darkOrange : CustomColors.green, //Color of the border + style: BorderStyle.solid, //Style of the border + width: 1.5 //width of the border + ), + onPressed: () { + setState(() { + selectedButtonIndex = -1; + selectedNextDayButtonIndex = index; + DocAvailableAppointments.selectedTime = nextDayEvents[index].isoTime; + DocAvailableAppointments.selectedDate = dateFormatter.format(_calendarController.selectedDate!.add(Duration(days: 1))); print(DocAvailableAppointments.selectedTime); }); }, - child: Text(dayEvents[index].isoTime, - style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold)), + child: Text(nextDayEvents[index].isoTime!, style: TextStyle(fontSize: 12.0, color: Colors.white)), ); } getDoctorFreeSlots(context, DoctorList docObject) { + print(DocAvailableAppointments.initialSlotDuration); GifLoaderDialogUtils.showMyDialog(context); DoctorsListService service = new DoctorsListService(); - service - .getDoctorFreeSlots(docObject.doctorID, docObject.clinicID, - docObject.projectID, context) - .then((res) { + service.getDoctorFreeSlots(docObject.doctorID!, docObject.clinicID!, docObject.projectID!, widget.isContinueDentalPlan, context, projectViewModel).then((res) { GifLoaderDialogUtils.hideDialog(context); if (res['MessageStatus'] == 1) { if (res['FreeTimeSlots'].length != 0) { + isWaitingAppointmentAvailable = res['IsAllowToBookWaitingAppointment']; // true; + // isWaitingAppointmentAvailable = true; // true; + DocAvailableAppointments.initialSlotDuration = res['InitialSlotDuration']; DocAvailableAppointments.areAppointmentsAvailable = true; freeSlotsResponse = res['FreeTimeSlots']; - print("res['FreeTimeSlots']"); - print(res['FreeTimeSlots'].length); - _getJSONSlots().then((value) => { - setState(() => {_events.clear(), _events = value}) - }); + _getJSONSlots().then((value) { + setState(() { + _events.clear(); + _events = value; + if (widget.doctorSchedule != null) { + _onDaySelected(DateUtil.convertStringToDate(widget.doctorSchedule['Date'])); + _calendarController.selectedDate = DateUtil.convertStringToDate( + widget.doctorSchedule['Date'], + ); + } + ; + }); + }); } else { DocAvailableAppointments.areAppointmentsAvailable = false; + DocAvailableAppointments.areSlotsAvailable = false; + AppToast.showErrorToast(message: res['ErrorEndUserMessage']); } } else { AppToast.showErrorToast(message: res['ErrorEndUserMessage']); @@ -370,16 +508,20 @@ class _DocAvailableAppointmentsState extends State GifLoaderDialogUtils.showMyDialog(context); DoctorsListService service = new DoctorsListService(); service - .getDoctorScheduledFreeSlots(docObject.doctorID, docObject.clinicID, - docObject.projectID, docObject.serviceID, context) + .getDoctorScheduledFreeSlots( + int.parse(docObject.doctorID.toString()), + int.parse(docObject.clinicID.toString()), + int.parse(docObject.projectID.toString()), + docObject.serviceID, + context, + ) .then((res) { GifLoaderDialogUtils.hideDialog(context); if (res['MessageStatus'] == 1) { if (res['PatientER_DoctorFreeSlots'].length != 0) { + DocAvailableAppointments.initialSlotDuration = res['InitialSlotDuration']; DocAvailableAppointments.areAppointmentsAvailable = true; freeSlotsResponse = res['PatientER_DoctorFreeSlots']; - print("res['PatientER_DoctorFreeSlots']"); - print(res['PatientER_DoctorFreeSlots'].length); _getJSONSlots().then((value) => { setState(() => {_events.clear(), _events = value}) }); @@ -397,34 +539,61 @@ class _DocAvailableAppointmentsState extends State } getCurrentLanguage() async { - var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); - setState(() { - this.language = languageID; - }); + this.language = projectViewModel.isArabic ? "ar" : "en"; + // var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + // setState(() { + // this.language = languageID; + // }); } +} - Widget _buildEventsMarker(DateTime date, List events) { - return Container( - decoration: BoxDecoration( - shape: BoxShape.circle, - color: _calendarController.isSelected(date) - ? Color(0xffB8382C) - : _calendarController.isToday(date) - ? Colors.brown[300] - : Color(0xff76cfb7), - ), - width: 40.0, - height: 40.0, - child: Center( - child: Text( - '${date.day}', - style: TextStyle().copyWith( - color: Colors.white, - fontSize: 14.0, - ), - ), - ), - ); +class MeetingDataSource extends CalendarDataSource { + MeetingDataSource(List source) { + appointments = source; + } + + @override + DateTime getStartTime(int index) { + return _getMeetingData(index)!.from; } + + @override + DateTime getEndTime(int index) { + return _getMeetingData(index)!.to; + } + + @override + String getSubject(int index) { + return _getMeetingData(index)!.eventName; + } + + @override + Color getColor(int index) { + return _getMeetingData(index)!.background; + } + + @override + bool isAllDay(int index) { + return _getMeetingData(index)!.isAllDay; + } + + Meeting? _getMeetingData(int index) { + final dynamic meeting = appointments?[index]; + Meeting? meetingData; + if (meeting is Meeting) { + meetingData = meeting; + } + return meetingData; + } +} + +class Meeting { + Meeting(this.eventName, this.from, this.to, this.background, this.isAllDay, this.notes); + + String eventName; + DateTime from; + DateTime to; + Color background; + bool isAllDay; + String notes; } diff --git a/lib/pages/BookAppointment/components/DocInfo.dart b/lib/pages/BookAppointment/components/DocInfo.dart index 89b9e4d0..eda3a1e4 100644 --- a/lib/pages/BookAppointment/components/DocInfo.dart +++ b/lib/pages/BookAppointment/components/DocInfo.dart @@ -1,13 +1,13 @@ import 'package:diplomaticquarterapp/models/Appointments/DoctorProfile.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/others/app_expandable_notifier.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; class DoctorInformation extends StatelessWidget { DoctorProfileList docProfileList; - DoctorInformation({@required this.docProfileList}); + DoctorInformation({required this.docProfileList}); @override Widget build(BuildContext context) { @@ -16,141 +16,115 @@ class DoctorInformation extends StatelessWidget { child: Column( mainAxisSize: MainAxisSize.min, children: [ - AppExpandableNotifier( - isExpand: true, - headerWidget: Container( - margin: EdgeInsets.all(10.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - SvgPicture.asset( - "assets/images/DQ/doctor_information_icon.svg"), - Container( - margin: EdgeInsets.fromLTRB(15.0, 5.0, 15.0, 0.0), - child: Text(TranslationBase.of(context).docInfo, - style: TextStyle(fontSize: 16.0, letterSpacing: 0.8)), - ), - ], - ), - ), - bodyWidget: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - children: [ - Container( - padding: EdgeInsets.fromLTRB(10.0, 5.0, 10.0, 10.0), - child: Table( - children: [ - TableRow(children: [ - TableCell( - child: _getHeadingText( - TranslationBase.of(context).gender)), - TableCell( - child: _getHeadingText( - TranslationBase.of(context).nationality)), - ]), - TableRow(children: [ - TableCell( - child: _getNormalText( - docProfileList.genderDescription)), - TableCell( - child: _getNormalTextWithIcon( - docProfileList.nationalityName, - docProfileList.nationalityFlagURL)), - ]), - ], - ), - ), - Divider( - color: Colors.grey[400], + Container( + width: double.infinity, + child: Container( + decoration: cardRadius(12), + child: Padding( + padding: EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).docInfo, + style: TextStyle( + fontSize: 16.0, + letterSpacing: -0.64, + fontWeight: FontWeight.w600, + ), + ), + mHeight(10), + Row( + children: [ + Text( + TranslationBase.of(context).gender + ":", + style: TextStyle( + fontSize: 10, + letterSpacing: -0.4, + color: Color(0xFF575757), + fontWeight: FontWeight.w600, + ), + ), + mWidth(2), + Text( + docProfileList.genderDescription!, + style: TextStyle( + fontSize: 12, + letterSpacing: -0.48, + color: Color(0xFF575757), + fontWeight: FontWeight.w600, + ), + ), + ], + ), + Row( + children: [ + Text( + TranslationBase.of(context).nationality + ":", + style: TextStyle( + fontSize: 10, + letterSpacing: -0.4, + color: Color(0xFF575757), + fontWeight: FontWeight.w600, + ), + ), + mWidth(2), + Text( + docProfileList.nationalityName!, + style: TextStyle( + fontSize: 12, + letterSpacing: -0.48, + color: Color(0xFF575757), + fontWeight: FontWeight.w600, + ), + ), + ], + ), + ], ), - Container( - margin: EdgeInsets.fromLTRB(10.0, 5.0, 10.0, 10.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - _getHeadingText(TranslationBase.of(context).clinic), - _getNormalText(docProfileList.clinicDescription) - ], - ), - ) - ], + ), ), ), - // ), - AppExpandableNotifier( - isExpand: true, - headerWidget: Container( - margin: EdgeInsets.all(10.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - SvgPicture.asset( - "assets/images/DQ/doctor_qualification_icon.svg"), - Container( - margin: EdgeInsets.fromLTRB(15.0, 5.0, 15.0, 0.0), - child: Text(TranslationBase.of(context).docQualifications, - style: TextStyle(fontSize: 16.0, letterSpacing: 0.8)), - ), - ], + mHeight(8), + Container( + width: double.infinity, + child: Container( + decoration: cardRadius(12), + child: Padding( + padding: EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).docQualifications, + style: TextStyle( + fontSize: 16.0, + letterSpacing: -0.64, + fontWeight: FontWeight.w600, + ), + ), + mHeight(10), + Text( + docProfileList.doctorProfileInfo != null ? docProfileList.doctorProfileInfo! : "", + style: TextStyle( + fontSize: 12, + letterSpacing: -0.48, + color: Color(0xFF575757), + fontWeight: FontWeight.w600, + ), + ), + ], + ), ), ), - bodyWidget: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - children: [ - Container( - margin: EdgeInsets.fromLTRB(20.0, 0.0, 10.0, 5.0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - _getNormalText(docProfileList.doctorProfileInfo) - ], - ), - ) - ], - ), ), ], ), ); } - - _getHeadingText(text) { - return Text(text, - style: TextStyle( - fontSize: 13, - fontWeight: FontWeight.bold, - letterSpacing: 0.5, - color: Colors.grey[800])); - } - - _getNormalText(text) { - return Container( - margin: EdgeInsets.only(top: 5.0), - child: Text(text, - maxLines: 16, - style: TextStyle( - fontSize: 13, letterSpacing: 0.5, color: Colors.grey[700])), - ); - } - - _getNormalTextWithIcon(String text, icon) { - return Container( - margin: EdgeInsets.only(top: 5.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - children: [ - Text(text.trim(), - style: TextStyle( - fontSize: 13, letterSpacing: 0.5, color: Colors.grey[700])), - Container( - margin: EdgeInsets.only(left: 5.0, right: 5.0), - child: Image.network(icon, width: 18.0, height: 18.0), - ), - ], - ), - ); + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties.add(DiagnosticsProperty('docProfileList', docProfileList)); } } diff --git a/lib/pages/BookAppointment/components/LaserClinic.dart b/lib/pages/BookAppointment/components/LaserClinic.dart new file mode 100644 index 00000000..f1b9be57 --- /dev/null +++ b/lib/pages/BookAppointment/components/LaserClinic.dart @@ -0,0 +1,529 @@ +import 'dart:collection'; + +import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; +import 'package:diplomaticquarterapp/models/Appointments/laser_body_parts.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/SearchResults.dart'; +import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/laser_body_parts_data.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:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class LaserClinic extends StatefulWidget { + HospitalsModel selectedHospital; + + LaserClinic({required this.selectedHospital}); + + @override + _LaserClinicState createState() { + return _LaserClinicState(); + } +} + +class _LaserClinicState extends State with SingleTickerProviderStateMixin { + List _laserCategoryList = [1, 2, 11]; + List _selectedBodyPartList = []; + bool _isFullBody = false; + late LaserBodyPart fullBody; + int _selectedCategoryIndex = 0; + List laserBodyPartsList = []; + + late TabController _tabController; + int _duration = 0; + + List maleLaserCategory = []; + List femaleLaserCategory = []; + + @override + void initState() { + super.initState(); + _tabController = TabController(length: 2, vsync: this); + _tabController.addListener(() { + if (_tabController.indexIsChanging) { + } else { + _selectedBodyPartList = []; + laserBodyPartsList = []; + _selectedCategoryIndex = 0; + setState(() {}); + if (_tabController.index == 0) { + callLaserBodyPartsAPI(maleLaserCategory[_selectedCategoryIndex].laserCategoryID); + } else { + callLaserBodyPartsAPI(femaleLaserCategory[_selectedCategoryIndex].laserCategoryID); + } + } + }); + Future.delayed(Duration.zero, () { + callLaserBodyPartsAPI(maleLaserCategory[_selectedCategoryIndex].laserCategoryID); + }); + } + + callLaserBodyPartsAPI(int laserCategoryId) async { + GifLoaderDialogUtils.showMyDialog(context); + + DoctorsListService service = new DoctorsListService(); + service.getLaserBodyPartsList(laserCategoryId, widget.selectedHospital.iD, projectViewModel.isArabic ? 1 : 2).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res['MessageStatus'] == 1) { + if (res['Laser_GetBodyPartsByCategoryList'].length != 0) { + List _tempList = []; + res['Laser_GetBodyPartsByCategoryList'].forEach((v) { + _tempList.add(LaserBodyPart.fromJson(v)); + }); + // if (_tempList[0].category == 1 || _tempList[0].category == 11 || _tempList[0].category == 2 || _tempList[0].category == 10) { + if (_tempList[0].category == 2 || _tempList[0].category == 10) { + // fullBody = _tempList[0]; + _tempList.removeAt(0); + } + laserBodyPartsList = _tempList; + } else {} + setState(() {}); + } else { + AppToast.showErrorToast(message: res['ErrorEndUserMessage']); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + AppToast.showErrorToast(message: err); + }); + } + + bool lastIndexIsFirst = false; + bool isLastIndexIsBack = false; + late ProjectViewModel projectViewModel; + + bool get isMale => _tabController.index == 0; + + @override + void dispose() { + super.dispose(); + _tabController.dispose(); + } + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + maleLaserCategory = [ + LaserCategoryType(1, TranslationBase.of(context).bodyString), + LaserCategoryType(2, TranslationBase.of(context).face), + LaserCategoryType(11, TranslationBase.of(context).retouch), + ]; + femaleLaserCategory = [ + LaserCategoryType(1, TranslationBase.of(context).bodyString), + LaserCategoryType(2, TranslationBase.of(context).face), + LaserCategoryType(10, TranslationBase.of(context).bikini), + LaserCategoryType(11, TranslationBase.of(context).retouch), + ]; + return AppScaffold( + appBarTitle: TranslationBase.of(context).laserClinic, + showNewAppBar: true, + showNewAppBarTitle: true, + isShowDecPage: false, + backgroundColor: Color(0xfff7f7f7), + body: Column( + children: [ + TabBar( + controller: _tabController, + indicatorWeight: 3.0, + indicatorSize: TabBarIndicatorSize.tab, + labelColor: Color(0xff2B353E), + unselectedLabelColor: Color(0xff575757), + labelPadding: EdgeInsets.only(top: 15, bottom: 13, left: 20, right: 20), + labelStyle: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + fontFamily: projectViewModel.isArabic ? 'Cairo' : 'Poppins', + letterSpacing: -0.48, + ), + unselectedLabelStyle: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + fontFamily: projectViewModel.isArabic ? 'Cairo' : 'Poppins', + letterSpacing: -0.48, + ), + tabs: [Text(TranslationBase.of(context).male), Text(TranslationBase.of(context).female)], + ), + Expanded( + child: TabBarView( + physics: BouncingScrollPhysics(), + controller: _tabController, + children: [male(), female()], + ), + ), + Row( + children: [ + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).totalMinutes + ":", + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + color: Color(0xff575757), + letterSpacing: -0.48, + ), + ), + Text( + "${getDuration()} / 90", + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + color: Color(0xff2E303A), + letterSpacing: -0.64, + ), + ), + ], + ), + ), + Expanded( + child: DefaultButton( + TranslationBase.of(context).continues, + getDuration() != 0 + ? () { + callDoctorsSearchAPI(); + } + : null, + color: CustomColors.green, + disabledColor: CustomColors.grey2, + ), + ), + ], + ).insideContainer, + ], + ), + ); + } + + callDoctorsSearchAPI() { + int languageID = projectViewModel.isArabic ? 1 : 2; + GifLoaderDialogUtils.showMyDialog(context, barrierDismissible: false); + List doctorsList = []; + List arr = []; + List arrDistance = []; + List result; + int numAll; + List _patientDoctorAppointmentListHospital = []; + + DoctorsListService service = new DoctorsListService(); + projectViewModel.selectedBodyPartList = _selectedBodyPartList; + service.getDoctorsList(253, 0, false, languageID, 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(), + projectTopName: element.projectTopName, + projectBottomName: element.projectBottomName, + patientDoctorAppointment: element)); + } + }); + } else {} + }); + + result = LinkedHashSet.from(arr).toList(); + numAll = result.length; + projectViewModel.laserSelectionDuration = _duration; + 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, + isDoctorSearchResult: true, + ))).then((value) { + setState(() { + // dropdownValue = null; + }); + // getProjectsList(); + }); + } + + int getDuration() { + int duration = 0; + if (_isFullBody) { + _duration = int.parse(fullBody.timeDuration!); + projectViewModel.laserSelectionDuration = duration; + return _duration; + } + + var lowerUpperLegsList = _selectedBodyPartList.where((element) => element.mappingCode == "47" || element.mappingCode == "48")?.toList() ?? []; + var upperLowerArmsList = _selectedBodyPartList.where((element) => element.mappingCode == "40" || element.mappingCode == "41")?.toList() ?? []; + + if (_selectedBodyPartList.length > 0) { + duration = _selectedBodyPartList.fold(0, (previousValue, element) => previousValue + int.parse(element.timeDuration!)); + } + if (lowerUpperLegsList.length == 2) { + duration -= 30; + } + if (upperLowerArmsList.length == 2) { + duration -= 15; + } + _duration = duration; + projectViewModel.laserSelectionDuration = duration; + return duration; + } + + Widget laserCategoryWidget(List list, VoidCallback onTap) { + return SizedBox( + height: 40, + child: ListView.separated( + itemCount: list.length, + physics: BouncingScrollPhysics(), + scrollDirection: Axis.horizontal, + separatorBuilder: (cxt, index) => SizedBox(width: 8), + itemBuilder: (cxt, index) { + return InkWell( + onTap: () { + // setState(() { + _selectedCategoryIndex = index; + // }); + onTap(); + }, + child: Container( + decoration: BoxDecoration( + color: _selectedCategoryIndex == index ? Color(0xffD02127) : Colors.white, + borderRadius: BorderRadius.circular(36), + border: Border.all( + width: 1, + color: _selectedCategoryIndex == index ? Colors.transparent : Color(0xffEAEAEA), + ), + ), + padding: EdgeInsets.symmetric(vertical: 8, horizontal: 26), + child: Text( + list[index].title, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + color: _selectedCategoryIndex == index ? Colors.white : Color(0xff535353), + letterSpacing: -0.48, + ), + ), + ), + ); + }, + ), + ); + } + + Widget bodyPartsGridView() { + return Container( + padding: EdgeInsets.symmetric(vertical: 21, horizontal: 14), + margin: EdgeInsets.only(top: 16), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all( + Radius.circular(15.0), + ), + boxShadow: [ + BoxShadow( + color: Color(0xff000000).withOpacity(.05), + blurRadius: 27, + offset: Offset(0, -3), + ), + ], + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + // if (fullBody != null) + // Row( + // children: [ + // SizedBox( + // width: 22, + // height: 22, + // child: Theme( + // data: Theme.of(context).copyWith( + // unselectedWidgetColor: Color(0xffEAEAEA), + // ), + // child: Checkbox( + // value: _isFullBody, + // onChanged: (value) { + // setState(() { + // if (value!) { + // _selectedBodyPartList.clear(); + // _selectedBodyPartList.add(fullBody); + // } else { + // _selectedBodyPartList.clear(); + // } + // _isFullBody = !_isFullBody; + // }); + // }, + // activeColor: Color(0xffD02127), + // ), + // ), + // ), + // SizedBox(width: 12), + // Text( + // projectViewModel.isArabic ? fullBody.bodyPartN! : fullBody.bodyPart!, + // style: TextStyle(fontSize: 15, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.6, height: 21 / 14), + // ), + // ], + // ), + GridView.builder( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, childAspectRatio: 85 / 107, crossAxisSpacing: 4, mainAxisSpacing: 21), + physics: NeverScrollableScrollPhysics(), + shrinkWrap: true, + itemCount: laserBodyPartsList.length, + // padding: fullBody != null ? EdgeInsets.only(top: 16) : EdgeInsets.zero, + padding: EdgeInsets.zero, + itemBuilder: (BuildContext context, int index) { + bool _isSelected = _selectedBodyPartList.any((file) => file.id == laserBodyPartsList[index].id); + return InkWell( + onTap: _isFullBody + ? null + : () { + if (_duration >= 90) { + if (_isSelected) { + _selectedBodyPartList.removeWhere((element) => element.id == laserBodyPartsList[index].id); + + // _selectedBodyPartList.remove(laserBodyPartsList[index]); + setState(() {}); + return; + } + AppToast.showToast(message: TranslationBase.of(context).laserMaxLimitReach, timeInSeconds: 3); + return; + } + if (_isSelected) { + _selectedBodyPartList.removeWhere((element) => element.id == laserBodyPartsList[index].id); + // _selectedBodyPartList.remove(laserBodyPartsList[index]); + } else { + if (_duration + int.parse(laserBodyPartsList[index].timeDuration!) > 90) { + AppToast.showToast(message: TranslationBase.of(context).laserMaxLimitReach); + return; + } + _selectedBodyPartList.add(laserBodyPartsList[index]); + } + setState(() {}); + }, + child: AnimatedOpacity( + opacity: _isFullBody ? 0.25 : 1.0, + duration: Duration(milliseconds: 200), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AspectRatio( + aspectRatio: 97 / 97, + child: FittedBox( + fit: BoxFit.fitWidth, + child: Stack( + alignment: Alignment.topRight, + children: [ + Container( + margin: EdgeInsets.only(top: 5, right: 5), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15.0), + border: Border.all(color: _isSelected ? Color(0xffD02127) : Color(0xffEAEAEA), width: 2), + ), + child: LaserBodyParts() + .getCategoryImage(isMale, (isMale ? maleLaserCategory : femaleLaserCategory)[_selectedCategoryIndex].laserCategoryID, laserBodyPartsList[index].mappingCode!), + ), + if (_isSelected) + Container( + width: 18, + height: 18, + child: Icon(Icons.done, color: Colors.white, size: 12), + decoration: BoxDecoration( + color: Color(0xffD02127), + borderRadius: BorderRadius.circular(30.0), + ), + ), + ], + ), + ), + ), + SizedBox(height: 6), + Expanded( + child: Text( + projectViewModel.isArabic ? laserBodyPartsList[index].bodyPartN! : laserBodyPartsList[index].bodyPart!, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.48, + ), + maxLines: 1, + ), + ), + ], + ), + ), + ); + }, + ), + ], + ), + ); + } + + Widget male() { + return ListView( + physics: BouncingScrollPhysics(), + padding: EdgeInsets.all(21), + children: [ + laserCategoryWidget(maleLaserCategory, () { + callLaserBodyPartsAPI(maleLaserCategory[_selectedCategoryIndex].laserCategoryID); + }), + if (laserBodyPartsList.isNotEmpty) bodyPartsGridView() + ], + ); + } + + Widget female() { + return ListView( + physics: BouncingScrollPhysics(), + padding: EdgeInsets.all(21), + children: [ + laserCategoryWidget(femaleLaserCategory, () { + callLaserBodyPartsAPI(femaleLaserCategory[_selectedCategoryIndex].laserCategoryID); + }), + if (laserBodyPartsList.isNotEmpty) bodyPartsGridView() + ], + ); + } +} + +class LaserCategoryType { + int laserCategoryID; + String title; + + LaserCategoryType(this.laserCategoryID, this.title); +} diff --git a/lib/pages/BookAppointment/components/LiveCareBookAppointment.dart b/lib/pages/BookAppointment/components/LiveCareBookAppointment.dart new file mode 100644 index 00000000..28c07be1 --- /dev/null +++ b/lib/pages/BookAppointment/components/LiveCareBookAppointment.dart @@ -0,0 +1,356 @@ +import 'package:diplomaticquarterapp/config/shared_pref_kay.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'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +class LiveCareBookAppointment extends StatefulWidget { + final dynamic clinicName; + final dynamic liveCareClinicID; + final dynamic liveCareServiceID; + + LiveCareBookAppointment( + {this.clinicName, this.liveCareClinicID, this.liveCareServiceID}); + + @override + _LiveCareBookAppointmentState createState() => + _LiveCareBookAppointmentState(); +} + +class _LiveCareBookAppointmentState extends State { + AppSharedPreferences sharedPref = AppSharedPreferences(); + + @override + Widget build(BuildContext context) { + return AppScaffold( + showNewAppBarTitle: true, + showNewAppBar: true, + appBarTitle: TranslationBase.of(context).bookAppo, + isShowAppBar: true, + isShowDecPage: false, + body: SingleChildScrollView( + child: Container( + margin: EdgeInsets.all(10.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + margin: EdgeInsets.all(5.0), + child: Text(TranslationBase.of(context).clinicAcceptLivecare, + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.black, + fontSize: 16.0, + letterSpacing: 0.5)), + ), + Container( + margin: EdgeInsets.all(15.0), + padding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0), + decoration: BoxDecoration( + color: Color(0xff20bc44), + borderRadius: BorderRadius.all(Radius.circular(8.0))), + child: Text(TranslationBase.of(context).livecareModalTop, + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, + fontSize: 16.0, + fontWeight: FontWeight.w600, + letterSpacing: 0.5)), + ), + Container( + margin: EdgeInsets.all(15.0), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SvgPicture.asset( + "assets/images/new-design/liveCare_mobile_care.svg", + ), + Flexible( + child: Container( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + margin: EdgeInsets.only(bottom: 7.0), + child: Text( + TranslationBase.of(context).whyLivecare, + style: TextStyle( + fontSize: 20.0, + fontWeight: FontWeight.w600, + letterSpacing: 1.0, + color: Colors.black)), + ), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + child: SvgPicture.asset( + "assets/images/new-design/ionic-ios-checkmark-circle.svg"), + ), + Container( + width: + MediaQuery.of(context).size.width * 0.4, + margin: EdgeInsets.only( + left: 5.0, right: 5.0, bottom: 10.0), + child: Text( + TranslationBase.of(context) + .livecarePoint1, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 12.0, + letterSpacing: 0.5, + color: Colors.black)), + ), + ], + ), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + child: SvgPicture.asset( + "assets/images/new-design/ionic-ios-checkmark-circle.svg"), + ), + Container( + width: + MediaQuery.of(context).size.width * 0.4, + margin: EdgeInsets.only( + left: 5.0, right: 5.0, bottom: 10.0), + child: Text( + TranslationBase.of(context) + .livecarePoint5, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 12.0, + letterSpacing: 0.5, + color: Colors.black)), + ), + ], + ), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + child: SvgPicture.asset( + "assets/images/new-design/ionic-ios-checkmark-circle.svg"), + ), + Container( + width: + MediaQuery.of(context).size.width * 0.4, + margin: EdgeInsets.only( + left: 5.0, right: 5.0, bottom: 10.0), + child: Text( + TranslationBase.of(context) + .livecarePoint2, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 12.0, + letterSpacing: 0.5, + color: Colors.black)), + ), + ], + ), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + child: SvgPicture.asset( + "assets/images/new-design/ionic-ios-checkmark-circle.svg"), + ), + Container( + width: + MediaQuery.of(context).size.width * 0.4, + margin: EdgeInsets.only( + left: 5.0, right: 5.0, bottom: 10.0), + child: Text( + TranslationBase.of(context) + .livecarePoint3, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 12.0, + letterSpacing: 0.5, + color: Colors.black)), + ), + ], + ), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + child: SvgPicture.asset( + "assets/images/new-design/ionic-ios-checkmark-circle.svg"), + ), + Container( + width: + MediaQuery.of(context).size.width * 0.4, + margin: + EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context) + .livecarePoint4, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 12.0, + letterSpacing: 0.5, + color: Colors.black)), + ), + ], + ), + ], + ), + ), + ) + ], + ), + ), + Container( + child: Text(TranslationBase.of(context).livecareSummary, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 12.0, + letterSpacing: 0.5, + color: Colors.black)), + ), + Container( + child: InkWell( + onTap: () { + sharedPref.setString( + LIVECARE_CLINIC_DATA, + widget.clinicName + + "-" + + widget.liveCareClinicID + + "-" + + widget.liveCareServiceID); + Navigator.pop(context, "livecare"); + }, + child: Container( + decoration: BoxDecoration( + color: Colors.grey[700], + borderRadius: + BorderRadius.all(Radius.circular(10.0))), + margin: EdgeInsets.only(top: 10.0), + padding: EdgeInsets.all(10.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: 70), + ), + Container( + width: MediaQuery.of(context).size.width * 0.58, + margin: EdgeInsets.fromLTRB(0.0, 5.0, 0.0, 0.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + margin: EdgeInsets.fromLTRB( + 10.0, 0.0, 10.0, 0.0), + child: Text( + TranslationBase.of(context) + .bookImmediateLivecare, + overflow: TextOverflow.clip, + style: TextStyle( + fontWeight: FontWeight.w500, + fontSize: 16.0, + letterSpacing: 0.7, + color: Colors.white)), + ), + Container( + margin: + EdgeInsets.only(top: 5.0, left: 10.0), + child: Text( + TranslationBase.of(context) + .bookVideoLivecare2, + textAlign: TextAlign.start, + style: TextStyle( + fontSize: 13.0, + color: Colors.white)), + ) + ], + ), + ), + ], + )), + ), + ), + Container( + child: InkWell( + onTap: () { + Navigator.pop(context, "schedule"); + }, + child: Container( + decoration: BoxDecoration( + color: Colors.grey[700], + borderRadius: + BorderRadius.all(Radius.circular(10.0))), + margin: EdgeInsets.only(top: 10.0), + padding: EdgeInsets.all(10.0), + child: Row( + children: [ + Container( + margin: EdgeInsets.only(left: 10.0, right: 10.0), + child: Image.asset( + "assets/images/new-design/doctor_white.png", + width: 50), + ), + Container( + width: MediaQuery.of(context).size.width * 0.58, + margin: EdgeInsets.fromLTRB(0.0, 5.0, 0.0, 0.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + margin: EdgeInsets.fromLTRB( + 28.0, 0.0, 28.0, 0.0), + child: Text( + TranslationBase.of(context).noThankyou, + overflow: TextOverflow.clip, + style: TextStyle( + fontWeight: FontWeight.w500, + fontSize: 16.0, + letterSpacing: 0.7, + color: Colors.white)), + ), + Container( + margin: EdgeInsets.only( + top: 5.0, left: 28.0, right: 28.0), + child: Text( + TranslationBase.of(context).visitClinic, + textAlign: TextAlign.start, + style: TextStyle( + fontSize: 13.0, + color: Colors.white)), + ) + ], + ), + ), + ], + )), + ), + ), + Container( + margin: EdgeInsets.only(top: 10.0), + child: InkWell( + onTap: () { + Navigator.pop(context, "false"); + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Text(TranslationBase.of(context).cancel, + style: TextStyle( + fontSize: 16.0, + letterSpacing: 0.5, + color: Color(0xffc5272d))), + ], + ), + ), + ), + ], + ), + ), + )); + } +} diff --git a/lib/pages/BookAppointment/components/SearchByClinic.dart b/lib/pages/BookAppointment/components/SearchByClinic.dart index 63c5e8e1..53bc10f2 100644 --- a/lib/pages/BookAppointment/components/SearchByClinic.dart +++ b/lib/pages/BookAppointment/components/SearchByClinic.dart @@ -1,24 +1,41 @@ -import "dart:collection"; - +import 'package:auto_size_text/auto_size_text.dart'; +import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/config/size_config.dart'; import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; 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/BookAppointment/dialog/clinic_list_dialog.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/search_result/SearchResultWithTab.dart'; +import 'package:diplomaticquarterapp/pages/livecare/livecare_home.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; +import 'package:diplomaticquarterapp/services/appointment_services/doctor_response_mapper.dart'; +import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/location_util.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/widgets/card/rounded_container.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +import 'LaserClinic.dart'; +import 'LiveCareBookAppointment.dart'; class SearchByClinic extends StatefulWidget { - final List clnicIds; + final List? clnicIds; - SearchByClinic({this.clnicIds}); + SearchByClinic({required this.clnicIds}); @override _SearchByClinicState createState() => _SearchByClinicState(); @@ -26,8 +43,9 @@ class SearchByClinic extends StatefulWidget { class _SearchByClinicState extends State { bool nearestAppo = false; - String dropdownValue; - String projectDropdownValue; + String? dropdownValue; + String dropdownTitle = ""; + String? projectDropdownValue; // var event = RobotProvider(); List clinicsList = []; @@ -36,297 +54,709 @@ class _SearchByClinicState extends State { bool isLoaded = false; bool isProjectLoaded = false; + ListClinicCentralized? selectedClinic; + HospitalsModel? selectedHospital; + + AuthenticatedUser authUser = new AuthenticatedUser(); + AuthProvider authProvider = new AuthProvider(); + + final GlobalKey clinicDropdownKey = GlobalKey(); + final GlobalKey projectDropdownKey = GlobalKey(); + TextEditingController ageController = new TextEditingController(); + + String radioValue = ""; + + late LocationUtils locationUtils; + @override void initState() { + locationUtils = new LocationUtils(isShowConfirmDialog: true, isShowLocationTimeoutDialog: false, context: context); WidgetsBinding.instance.addPostFrameCallback((_) => getClinicsList()); + checkPVM(); super.initState(); } + void checkPVM() { + if (context.read().isLogin) { + if (radioValue == null) { + if (context.read().user.gender == 1) { + radioValue = TranslationBase.of(context).male; + } else { + radioValue = TranslationBase.of(context).female; + } + } + } else if (radioValue == null) { + radioValue = TranslationBase.of(context).female; + } + if (ageController.text.isEmpty) { + ageController.text = context.read().isLogin ? context.read().user!.age.toString() : ""; + ageController.selection = TextSelection.fromPosition(TextPosition(offset: ageController.text.length)); + } + } + @override Widget build(BuildContext context) { + AppGlobal.context = context; return Container( - margin: EdgeInsets.all(10.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - Checkbox( - activeColor: new Color(0xFF40ACC9), - value: nearestAppo, - onChanged: (bool value) { - setState(() { - nearestAppo = value; - print(nearestAppo); - if (nearestAppo) - getProjectsList(); - else - isProjectLoaded = false; - }); - }, + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (context.read().isLogin) + Column( + children: [ + Padding( + padding: const EdgeInsets.only( + left: 20, + right: 20, + top: 20, + ), + child: Text( + TranslationBase.of(context).doctorFilter, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.64, + ), + ), + ), + mHeight(30), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(left: 20, right: 20), + child: Text( + TranslationBase.of(context).gender, + style: TextStyle( + fontSize: 12, + letterSpacing: -0.48, + color: Colors.black, + fontWeight: FontWeight.w600, + ), + ), + ), + Container( + padding: EdgeInsets.only(left: 6, right: 6), + child: Row( + children: [ + Flexible( + child: Row( + children: [ + Radio( + value: TranslationBase.of(context).female, + groupValue: radioValue, + onChanged: (v) { + setState(() { + radioValue = v!; + }); + }, + ), + Text( + TranslationBase.of(context).female, + style: TextStyle( + fontSize: 12, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + ), + ), + ], + )), + Flexible( + child: Row( + children: [ + Radio( + value: TranslationBase.of(context).male, + groupValue: radioValue, + onChanged: (v) { + setState(() { + radioValue = v!; + }); + }, + ), + Text( + TranslationBase.of(context).male, + style: TextStyle( + fontSize: 12, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + ), + ), + ], + )), + ], + ), + ), + ], + ), + Container( + child: inputWidget("Age", "", ageController), + margin: EdgeInsets.only(left: 20, right: 20), + ), + ], ), - Text(TranslationBase.of(context).nearestAppo, - style: TextStyle(fontSize: 16.0, letterSpacing: 0.9)), - ], - ), - widget.clnicIds != null && - widget.clnicIds.length > 1 && - isLoaded == true - ? Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: clinicsList.map((result) { - return RoundedContainer( - child: ListTile( - onTap: () { - // setState(() { - dropdownValue = result.clinicID.toString(); - setState(() { - if (!isDentalSelectedAndSupported()) { - projectDropdownValue = ""; - getDoctorsList(context); - } - }); - }, - title: Text(result.clinicDescription, - style: TextStyle( - fontSize: 14.0, - color: Colors.grey[700], - letterSpacing: 1.0)))); - }).toList()) - : Container( - height: 60.0, - decoration: BoxDecoration( - color: Colors.white, - border: Border.all( - color: Colors.grey[400], - width: 1.0, + Padding( + padding: const EdgeInsets.only(left: 6, right: 6, top: 16), + child: Row( + children: [ + Checkbox( + activeColor: CustomColors.accentColor, + value: nearestAppo, + onChanged: (bool? value) { + setState(() { + nearestAppo = value!; + if (nearestAppo) + getProjectsList(); + else + isProjectLoaded = false; + }); + }, + ), + AutoSizeText( + TranslationBase.of(context).nearestAppo.trim(), + maxLines: 1, + minFontSize: 10, + style: TextStyle( + fontSize: SizeConfig.textMultiplier! * 1.4, + fontWeight: FontWeight.w600, + letterSpacing: -0.39, + height: 0.8, ), - borderRadius: BorderRadius.circular(10), ), - // margin: EdgeInsets.fromLTRB(10.0, 20.0, 10.0, 20.0), - padding: EdgeInsets.all(8.0), - width: MediaQuery.of(context).size.width, - child: DropdownButtonHideUnderline( - child: DropdownButton( - hint: new Text(TranslationBase.of(context).selectClinic), - value: dropdownValue, - items: clinicsList.map((item) { - return new DropdownMenuItem( - value: item.clinicID.toString(), - child: new Text(item.clinicDescription), - ); - }).toList(), - onChanged: (newValue) { + // Text(TranslationBase.of(context).nearestAppo, style: TextStyle(fontSize: 14.0, letterSpacing: -0.56)), + ], + ), + ), + widget.clnicIds != null && widget.clnicIds!.length > 1 && isLoaded == true + ? Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: clinicsList.map((result) { + return RoundedContainer( + child: ListTile( + onTap: () { + // setState(() { + dropdownValue = result.clinicID.toString(); + setState(() { + if (!isDentalSelectedAndSupported()) { + dropdownValue = ""; + projectDropdownValue = ""; + getDoctorsList(context); + } else {} + }); + }, + title: Text(result.clinicDescription!, style: TextStyle(fontSize: 14.0, color: Colors.grey[700], letterSpacing: 1.0)))); + }).toList()) + : InkWell( + onTap: () { + showClickListDialog(context, clinicsList, onSelection: (ListClinicCentralized clincs) { + selectedClinic = clincs; + Navigator.pop(context); setState(() { - dropdownValue = newValue; - if (!isDentalSelectedAndSupported() && !nearestAppo) { + dropdownTitle = clincs.clinicDescription!; + dropdownValue = + clincs.clinicID.toString() + "-" + clincs.isLiveCareClinicAndOnline.toString() + "-" + clincs.liveCareClinicID.toString() + "-" + clincs.liveCareServiceID.toString(); + if (dropdownValue == "253-false-0-0") { + // Navigator.push(context, FadePage(page: LaserClinic())); + } else if (!isDentalSelectedAndSupported()) { projectDropdownValue = ""; - getDoctorsList(context); - } + if (!nearestAppo) getDoctorsList(context); + } else {} }); - }, + context.read().analytics.appointment.book_appointment_select_clinic(appointment_type: 'regular', clinic: clincs.clinicDescription); + }); + }, + child: Container( + width: double.infinity, + decoration: containerRadius(Colors.white, 12), + margin: EdgeInsets.only(left: 20, right: 20), + padding: EdgeInsets.only(left: 10, right: 10, top: 12, bottom: 8), + child: Row( + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).selectClinic, + style: TextStyle( + fontSize: 11, + letterSpacing: -0.44, + fontWeight: FontWeight.w600, + ), + ), + Padding( + padding: const EdgeInsets.only(top: 4, bottom: 2), + child: Text( + dropdownTitle, + style: TextStyle( + fontSize: 13, + letterSpacing: -0.44, + fontWeight: FontWeight.w600, + ), + ), + ), + ], + ), + ), + Icon(Icons.keyboard_arrow_down), + ], + ), ), - )), - isDentalSelectedAndSupported() == true || - (nearestAppo && isProjectLoaded) - ? Container( - height: 60.0, - decoration: BoxDecoration( - color: Colors.white, - border: Border.all( - color: Colors.grey[400], - width: 1.0, + ), + mHeight(20), + isDentalSelectedAndSupported() == true || (nearestAppo && isProjectLoaded) + ? InkWell( + onTap: () { + openDropdown(projectDropdownKey); + }, + child: Container( + width: double.infinity, + decoration: containerRadius(Colors.white, 12), + margin: EdgeInsets.only(left: 20, right: 20), + padding: EdgeInsets.only(left: 10, right: 10, top: 12, bottom: 12), + child: Row( + children: [ + Flexible( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).selectHospital, + style: TextStyle( + fontSize: 11, + letterSpacing: -0.44, + fontWeight: FontWeight.w600, + ), + ), + Container( + height: 18, + child: DropdownButtonHideUnderline( + child: DropdownButton( + key: projectDropdownKey, + hint: Text(TranslationBase.of(context).selectHospital), + value: selectedHospital, + iconSize: 0, + isExpanded: true, + style: TextStyle(fontSize: 14, letterSpacing: -0.56, color: Colors.black), + items: projectsList.map((HospitalsModel item) { + return DropdownMenuItem( + value: item, + child: AutoSizeText( + item.name!, + maxLines: 1, + minFontSize: 10, + style: TextStyle( + fontSize: SizeConfig.textMultiplier! * 1.6, + fontWeight: FontWeight.w600, + letterSpacing: -0.39, + height: 0.8, + ), + ), + // Text('${item.name!}'), + ); + }).toList(), + onChanged: (HospitalsModel? newValue) async { + setState(() { + HospitalsModel tempselectedHospital = new HospitalsModel.fromJson(newValue!.toJson()); + projectDropdownValue = newValue.mainProjectID.toString(); + if (dropdownValue!.split("-")[0] == "253") { + Navigator.push( + context, + FadePage( + page: LaserClinic(selectedHospital: tempselectedHospital!), + ), + ); + } else { + getDoctorsList(context); + } + }); + }, + ), + ), + ), + ], + ), + ), + Icon(Icons.keyboard_arrow_down), + ], + )), + ) + : Container(), + ], + ), + ), + ); + } + + 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(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, ), - borderRadius: BorderRadius.circular(10), ), - padding: EdgeInsets.all(8.0), - width: MediaQuery.of(context).size.width, - margin: EdgeInsets.only(top: 15.0), - child: DropdownButtonHideUnderline( - child: DropdownButton( - hint: new Text("Select Project"), - value: projectDropdownValue, - items: projectsList.map((item) { - return new DropdownMenuItem( - value: item.mainProjectID.toString(), - child: new Text(item.name), - ); - }).toList(), - onChanged: (newValue) { - setState(() { - projectDropdownValue = newValue; - getDoctorsList(context); - }); - }, + 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, ), - )) - : Container(), - ], + decoration: InputDecoration( + isDense: true, + hintText: _hintText, + hintStyle: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: Color(0xff575757), + 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), + ], + ), ), ); } +//Changed By Aamir + void openDropdown(GlobalKey key) { + GestureDetector? detector; + + void searchForGestureDetector(BuildContext element) { + element.visitChildElements((element) { + if (element.widget != null && element.widget is GestureDetector) { + detector = element.widget as GestureDetector?; + //return false; + } else { + searchForGestureDetector(element); + } + + //return true; + }); + } + + searchForGestureDetector(key.currentContext!); + assert(detector != null); + + detector!.onTap!(); + } + + // void openDropdown(GlobalKey key) { + // GestureDetector detector; + // void searchForGestureDetector(BuildContext element) { + // element.visitChildElements((element) { + // if (element.widget != null && element.widget is GestureDetector) { + // detector = element.widget; + // return false; + // } else { + // searchForGestureDetector(element); + // } + // + // return true; + // }); + // } + // + // searchForGestureDetector(key.currentContext); + // assert(detector != null); + // + // detector.onTap(); + // } + bool isDentalSelectedAndSupported() { - return dropdownValue != "" && - (dropdownValue == "17") && - isMobileAppDentalAllow; + if (dropdownValue != null) + return dropdownValue != "" && (dropdownValue!.split("-")[0] == "17" || dropdownValue!.split("-")[0] == "253") && isMobileAppDentalAllow; + else + return false; } - getClinicsList() { - GifLoaderDialogUtils.showMyDialog(context); - ClinicListService service = new ClinicListService(); - service.getClinicsList(context).then((res) { - if (res['MessageStatus'] == 1) { - setState(() { - isMobileAppDentalAllow = res['ISMobileAppDentalAllow']; - res['ListClinicCentralized'].forEach((v) { - clinicsList.add(new ListClinicCentralized.fromJson(v)); - }); + getClinicsList() async { + AppGlobal.context = context; + if (await sharedPref.getObject(CLINICS_LIST) != null) { + dynamic res = await sharedPref.getObject(CLINICS_LIST); + setState(() { + isMobileAppDentalAllow = res['ISMobileAppDentalAllow']; + res['ListClinicCentralized'].forEach((v) { + clinicsList.add(new ListClinicCentralized.fromJson(v)); }); - getProjectsList(); + }); + getProjectsList(); + // GifLoaderDialogUtils.hideDialog(context); + } else { + GifLoaderDialogUtils.showMyDialog(context); + ClinicListService service = new ClinicListService(); + service.getClinicsList(context).then((res) { + if (res['MessageStatus'] == 1) { + setState(() { + isMobileAppDentalAllow = res['ISMobileAppDentalAllow']; + res['ListClinicCentralized'].forEach((v) { + clinicsList.add(new ListClinicCentralized.fromJson(v)); + }); + }); + getProjectsList(); + GifLoaderDialogUtils.hideDialog(context); + } else {} + }).catchError((err) { + print(err); GifLoaderDialogUtils.hideDialog(context); - } else {} - }).catchError((err) { - print(err); - GifLoaderDialogUtils.hideDialog(context); - }); + }); + } } getProjectsList() { + int languageID = context.read().isArabic ? 1 : 2; ClinicListService service = new ClinicListService(); List projectsListLocal = []; - service.getProjectsList(context).then((res) { - if (res['MessageStatus'] == 1) { - setState(() { - res['ListProject'].forEach((v) { - projectsListLocal.add(new HospitalsModel.fromJson(v)); - }); - projectsList = projectsListLocal; + service + .getProjectsList(languageID, context) + .then((res) { + if (res['MessageStatus'] == 1) { + setState(() { + res['ListProject'].forEach((v) { + projectsListLocal.add(new HospitalsModel.fromJson(v)); + }); + projectsList = projectsListLocal; + }); + filterClinic(); + isProjectLoaded = true; + } else { + isProjectLoaded = false; + } + locationUtils.getCurrentLocation(); + }) + .catchError((err) {}) + .catchError((err) { + print(err); }); - filterClinic(); - isProjectLoaded = true; - } else { - isProjectLoaded = false; - } - }).catchError((err) { - print(err); - }); } // TODO Mosa_REMARk to come back later getDoctorsList(BuildContext context) { - GifLoaderDialogUtils.showMyDialog(context); SearchInfo searchInfo = new SearchInfo(); - if (dropdownValue == "17") { - searchInfo.ProjectID = int.parse(projectDropdownValue); - searchInfo.ClinicID = int.parse(dropdownValue); + if (dropdownValue != null) if (dropdownValue!.split("-")[0] == "17") { + searchInfo.ProjectID = int.parse(projectDropdownValue!); + searchInfo.ClinicID = int.parse(dropdownValue!.split("-")[0]); + searchInfo.hospital = selectedHospital; + searchInfo.clinic = selectedClinic; searchInfo.date = DateTime.now(); - GifLoaderDialogUtils.hideDialog(context); - navigateToDentalComplaints(context, searchInfo); + if (context.read().isLogin) { + if (context.read().user.age! > 12) { + navigateToDentalComplaints(context, searchInfo); + } else { + callDoctorsSearchAPI(17); + } + } else { + navigateToDentalComplaints(context, searchInfo); + } + } else if (dropdownValue!.split("-")[0] == "253") { + navigateToLaserClinic(context); + // callDoctorsSearchAPI(); + } else if (dropdownValue!.split("-")[1] == "true" + // && authProvider.isLogin && + // authUser.patientType == 1 + ) { + Navigator.push( + context, + FadePage( + page: LiveCareBookAppointment(clinicName: dropdownTitle, liveCareClinicID: dropdownValue!.split("-")[2], liveCareServiceID: dropdownValue!.split("-")[3]), + ), + ).then((value) { + setState(() { + if (value == "false") dropdownValue = "null"; + }); + if (value == "livecare") { + Navigator.push(context, FadePage(page: LiveCareHome())); + } + if (value == "schedule") { + callDoctorsSearchAPI(int.parse(dropdownValue!.split("-")[0])); + } + }); } else { - List doctorsList = []; - List arr = []; - List arrDistance = []; - List result; - int numAll; - List _patientDoctorAppointmentListHospital = - List(); - - DoctorsListService service = new DoctorsListService(); - service - .getDoctorsList( - int.parse(dropdownValue), - projectDropdownValue != "" ? int.parse(projectDropdownValue) : 0, - nearestAppo, - context) - .then((res) { - GifLoaderDialogUtils.hideDialog(context); - if (res['MessageStatus'] == 1) { - setState(() { - if (res['DoctorList'].length != 0) { - // print(res['DoctorList']); - 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 {} + callDoctorsSearchAPI(int.parse(dropdownValue!.split("-")[0])); + } + } + + callDoctorsSearchAPI(int clinicID) { + bool isArabic = context.read().isArabic; + int languageID = context.read().isArabic ? 1 : 2; + GifLoaderDialogUtils.showMyDialog(context); + List doctorsList = []; + List arr = []; + List arrDistance = []; + List result; + int numAll; + List _patientDoctorAppointmentListHospital = []; + + DoctorsListService service = new DoctorsListService(); + service.getDoctorsList(clinicID, projectDropdownValue != "" ? int.parse(projectDropdownValue!) : 0, nearestAppo, languageID, context).then((res) async { + GifLoaderDialogUtils.hideDialog(context); + RegionList regionHospitalList = RegionList(); + + if (res['MessageStatus'] == 1) { + if (res['DoctorList'].length != 0) { + res['DoctorList'].forEach((v) { + doctorsList.add(new DoctorList.fromJson( + v, + )); }); + if (nearestAppo) { + doctorsList.forEach((element) { + List doctorByHospital = + _patientDoctorAppointmentListHospital.where((elementClinic) => elementClinic.filterName == element.getProjectCompleteName()).toList(); + + if (doctorByHospital.length != 0) { + _patientDoctorAppointmentListHospital[_patientDoctorAppointmentListHospital.indexOf(doctorByHospital[0])].patientDoctorAppointmentList!.add(element); + } else { + _patientDoctorAppointmentListHospital.add(PatientDoctorAppointmentList( + filterName: element.getProjectCompleteName(), + distanceInKMs: element.projectDistanceInKiloMeters.toString(), + projectTopName: element.projectTopName, + projectBottomName: element.projectBottomName, + patientDoctorAppointment: element, + isHMC: element.isHMC, + )); + } + }); + navigateToSearchResultsForNearestAppointment(context, doctorsList, _patientDoctorAppointmentListHospital); + return; + } + + regionHospitalList = await DoctorMapper.getMappedDoctor(doctorsList, isArabic: isArabic); + var lat = await sharedPref.getDouble(USER_LAT); + + var lng = await sharedPref.getDouble(USER_LONG); + var isLocationEnabled = (lat != null && lat != 0.0) && (lng != null && lng != 0.0); + regionHospitalList = await DoctorMapper.sortList(isLocationEnabled, regionHospitalList); - result = LinkedHashSet.from(arr).toList(); - numAll = result.length; - navigateToSearchResults( - context, doctorsList, _patientDoctorAppointmentListHospital); + setState(() {}); } else { - AppToast.showErrorToast(message: res['ErrorEndUserMessage']); + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: res['ErrorSearchMsg']); } - }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); - print(err); - AppToast.showErrorToast(message: err); - }); - } + // navigateToSearchResults(context, doctorsList, _patientDoctorAppointmentListHospital); + navigateToSearchResults(context, regionHospitalList); + } else { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: res['ErrorEndUserMessage']); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + AppToast.showErrorToast(message: err, localContext: context); + }); } - Future navigateToDentalComplaints( - BuildContext context, SearchInfo searchInfo) async { + Future navigateToDentalComplaints(BuildContext context, SearchInfo searchInfo) async { Navigator.push( context, FadePage( page: DentalComplaints(searchInfo: searchInfo), ), - ); + ).then((value) { + setState(() { + dropdownValue = "null"; + }); + }); } - Future navigateToSearchResults( - context, - List docList, - List - patientDoctorAppointmentListHospital) async { - isProjectLoaded = false; + navigateToSearchResultsForNearestAppointment(context, List docList, List patientDoctorAppointmentListHospital) { Navigator.push( - context, - FadePage( - page: SearchResults( - isLiveCareAppointment: false, - doctorsList: docList, - patientDoctorAppointmentListHospital: - patientDoctorAppointmentListHospital))) - .then((value) { - getProjectsList(); + context, + FadePage( + page: SearchResults( + isLiveCareAppointment: false, + isDoctorNameSearch: true, + doctorsList: docList, + patientDoctorAppointmentListHospital: patientDoctorAppointmentListHospital, + isDoctorSearchResult: true, + ))); + } + + Future navigateToLaserClinic(BuildContext context) async { + Navigator.push( + context, + FadePage( + page: LaserBooking(), + ), + ).then((value) { + setState(() { + dropdownValue = "null"; + }); }); } + navigateToSearchResults(context, RegionList regionHospitalList) { + // Navigator.push(context, + // FadePage(page: SearchResults(isLiveCareAppointment: false, isDoctorNameSearch: true, doctorsList: docList, patientDoctorAppointmentListHospital: patientDoctorAppointmentListHospital, isDoctorSearchResult: true,))); + Navigator.push( + context, + FadePage( + page: SearchResultWithTab( + doctorsList: [], + patientDoctorAppointmentListHospital: regionHospitalList, + isLiveCareAppointment: false, + isDoctorSearchResult: true, + ))); + } + filterClinic() { setState(() { - if (widget.clnicIds != null && widget.clnicIds.length > 0) { - clinicsList = clinicsList - .where((i) => widget.clnicIds.indexOf(i.clinicID) > -1) - .toList(); + if (widget.clnicIds != null && widget.clnicIds!.length > 0) { + clinicsList = clinicsList.where((i) => widget.clnicIds!.indexOf(i.clinicID) > -1).toList(); isLoaded = true; } }); diff --git a/lib/pages/BookAppointment/components/SearchByDoctor.dart b/lib/pages/BookAppointment/components/SearchByDoctor.dart index a1ecb7a0..7676b3d4 100644 --- a/lib/pages/BookAppointment/components/SearchByDoctor.dart +++ b/lib/pages/BookAppointment/components/SearchByDoctor.dart @@ -1,12 +1,16 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/SearchResults.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/location_util.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/custom_text_button.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; - -import '../SearchResults.dart'; +import 'package:provider/provider.dart'; class SearchByDoctor extends StatefulWidget { @override @@ -15,84 +19,94 @@ class SearchByDoctor extends StatefulWidget { class _SearchByDoctorState extends State { TextEditingController doctorNameController = new TextEditingController(); - bool _isButtonDisabled; + late bool _isButtonDisabled; + late LocationUtils locationUtils; @override void initState() { + super.initState(); + locationUtils = + new LocationUtils(isShowConfirmDialog: true, context: context); + locationUtils.getCurrentLocation(); _isButtonDisabled = true; } @override Widget build(BuildContext context) { - return Container( - margin: EdgeInsets.all(20.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - children: [ - Container( - margin: EdgeInsets.only(top: 10.0, bottom: 15.0), - child: Text(TranslationBase.of(context).searchByDocText, - style: TextStyle(fontSize: 16.0, letterSpacing: 0.9)), - ), - 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())), - ), - Expanded( - child: Align( - alignment: FractionalOffset.bottomCenter, - child: _buildCounterButton(), + return Column( + children: [ + Expanded( + child: Container( + margin: EdgeInsets.all(20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.max, + children: [ + Container( + margin: EdgeInsets.only(top: 10.0, bottom: 15.0), + child: Text( + TranslationBase.of(context).searchByDocText, + style: TextStyle( + fontSize: 14.0, + letterSpacing: -0.9, + fontWeight: FontWeight.w600, + ), + ), + ), + inputWidget(TranslationBase.of(context).enterDocName, '', + doctorNameController), + ], ), ), - ], - ), + ), + _buildCounterButton(), + ], ); } Widget _buildCounterButton() { - return new 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, - disabledTextColor: Colors.white, - disabledColor: new Color(0xFFbcc2c4), - onPressed: () { - if (_isButtonDisabled == false) { - _searchDoctor(context); - } - }, - child: Text(TranslationBase.of(context).search, - style: TextStyle(fontSize: 18.0)), + return Container( + width: double.infinity, + padding: EdgeInsets.all(16), + color: Colors.white, + child: new ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + minWidth: MediaQuery.of(context).size.width, + height: 45.0, + child: CustomTextButton( + backgroundColor: CustomColors.accentColor, + elevation: 0, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(6), + ), + onPressed: () { + if (_isButtonDisabled == false) { + FocusManager.instance.primaryFocus?.unfocus(); + _searchDoctor(context); + } + }, + child: Text(TranslationBase.of(context).search, + style: TextStyle(fontSize: 18.0, color: Colors.white)), + ), ), ); } getDoctorsList(BuildContext context) { + int languageID = context.read().isArabic ? 1 : 2; GifLoaderDialogUtils.showMyDialog(context); List doctorsList = []; DoctorsListService service = new DoctorsListService(); List _patientDoctorAppointmentListHospital = - List(); + []; service - .getDoctorsListByName(doctorNameController.text, context) + .getDoctorsListByName(doctorNameController.text, languageID, context) .then((res) { + // GifLoaderDialogUtils.hideDialog(context); if (res['MessageStatus'] == 1) { setState(() { if (res['DoctorList'].length != 0) { @@ -103,35 +117,45 @@ class _SearchByDoctorState extends State { doctorsList.forEach((element) { List doctorByHospital = _patientDoctorAppointmentListHospital - .where( - (elementClinic) => - elementClinic.filterName == element.projectName, - ) + .where((elementClinic) => + elementClinic.filterName == + element.getProjectCompleteName()) .toList(); if (doctorByHospital.length != 0) { _patientDoctorAppointmentListHospital[ _patientDoctorAppointmentListHospital .indexOf(doctorByHospital[0])] - .patientDoctorAppointmentList + .patientDoctorAppointmentList! .add(element); } else { _patientDoctorAppointmentListHospital.add( PatientDoctorAppointmentList( - filterName: element.projectName, - distanceInKMs: element.projectDistanceInKiloMeters.toString(), - patientDoctorAppointment: element)); + filterName: element.getProjectCompleteName(), + distanceInKMs: + element.projectDistanceInKiloMeters.toString(), + projectTopName: element.projectTopName, + projectBottomName: element.projectBottomName, + patientDoctorAppointment: element, + isHMC: element.isHMC, + )); } }); - } else {} + } else { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: res['ErrorSearchMsg']); + } }); GifLoaderDialogUtils.hideDialog(context); navigateToSearchResults( context, doctorsList, _patientDoctorAppointmentListHospital); } else { + GifLoaderDialogUtils.hideDialog(context); AppToast.showErrorToast(message: res['ErrorEndUserMessage']); } }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); print(err); }); } @@ -152,20 +176,109 @@ class _SearchByDoctorState extends State { _searchDoctor(BuildContext context) { getDoctorsList(context); + context + .read() + .analytics + .appointment + .book_appointment_doctor_search(query: doctorNameController.text); } - Future navigateToSearchResults( - context, - List docList, - List - patientDoctorAppointmentListHospital) async { + navigateToSearchResults(context, List docList, + List patientDoctorAppointmentListHospital) { Navigator.push( context, FadePage( page: SearchResults( - isLiveCareAppointment: false, - doctorsList: docList, - patientDoctorAppointmentListHospital: - patientDoctorAppointmentListHospital))); + isLiveCareAppointment: false, + isDoctorNameSearch: true, + doctorsList: docList, + patientDoctorAppointmentListHospital: + patientDoctorAppointmentListHospital, + isDoctorSearchResult: true, + ))); + } + + Widget inputWidget( + String _labelText, String _hintText, TextEditingController _controller, + {String? prefix, bool isEnable = true, bool hasSelection = false}) { + 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: TextInputType.text, + controller: _controller, + onChanged: (value) => {_onDocTextChanged(value)}, + 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, + ), + 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/BookAppointment/components/search_by_hospital_name.dart b/lib/pages/BookAppointment/components/search_by_hospital_name.dart new file mode 100644 index 00000000..b6b04e30 --- /dev/null +++ b/lib/pages/BookAppointment/components/search_by_hospital_name.dart @@ -0,0 +1,549 @@ +import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/components/LaserClinic.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/search_result/SearchResultWithTab.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/search_result/SearchResultWithTabForHospital.dart'; +import 'package:diplomaticquarterapp/services/appointment_services/doctor_response_mapper.dart'; +import 'package:diplomaticquarterapp/uitl/location_util.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +import '../../../core/model/hospitals/hospitals_model.dart'; +import '../../../core/viewModels/project_view_model.dart'; +import '../../../models/Appointments/DoctorListResponse.dart'; +import '../../../models/Appointments/SearchInfoModel.dart'; +import '../../../models/Clinics/ClinicListResponse.dart'; +import '../../../services/appointment_services/GetDoctorsList.dart'; +import '../../../services/authentication/auth_provider.dart'; +import '../../../services/clinic_services/get_clinic_service.dart'; +import '../../../uitl/app_toast.dart'; +import '../../../uitl/gif_loader_dialog_utils.dart'; +import '../../../uitl/translations_delegate_base.dart'; +import '../../../widgets/transitions/fade_page.dart'; +import '../../livecare/livecare_home.dart'; +import '../DentalComplaints.dart'; +import 'LiveCareBookAppointment.dart'; + +class SearchByHospital extends StatefulWidget { + @override + State createState() => _SearchByHospitalState(); +} + +class _SearchByHospitalState extends State { + HospitalsModel? selectedHospital; + bool nearestAppo = false; + RegionList? hospitalList; + + String? selectedClinicName; + List projectsList = []; + List? clinicIds = List.empty(); + + final GlobalKey projectDropdownKey = GlobalKey(); + + List clinicsList = []; + bool isMobileAppDentalAllow = false; + ListClinicCentralized? selectedClinic; + + String? dropdownValue; + String dropdownTitle = ""; + late LocationUtils locationUtils; + + @override + void initState() { + WidgetsBinding.instance.addPostFrameCallback((_) { + locationUtils = new LocationUtils(isShowConfirmDialog: true, context: context); + locationUtils.getCurrentLocation(); + getProjectsList(); + }); + } + + @override + void deactivate() { + super.deactivate(); + } + + @override + void reassemble() { + super.reassemble(); + } // @override + // void didChangeDependencies() { + // WidgetsBinding.instance.addPostFrameCallback((_) { + // getProjectsList(); + // }); + // } + + // @override + // void didUpdateWidget(SearchByHospital oldWidget) { + // WidgetsBinding.instance.addPostFrameCallback((_) { + // getProjectsList(); + // }); + // } + + @override + Widget build(BuildContext context) { + AppGlobal.context = context; + return (hospitalList != null) + ? SearchResultWithTabForHospital( + patientDoctorAppointmentListHospital: hospitalList!, + doctorsList: [], + isDoctorSearchResult: false, + isLiveCareAppointment: false, + ) + : SizedBox.shrink(); + // return Column( + // children: [ + // Padding( + // padding: const EdgeInsets.only(left: 6, right: 6, top: 16), + // child: Row( + // children: [ + // Checkbox( + // activeColor: CustomColors.accentColor, + // value: nearestAppo, + // onChanged: (bool? value) { + // nearestAppo = value ?? false; + // setState(() {}); + // }, + // ), + // AutoSizeText( + // TranslationBase.of(context).nearestAppo.trim(), + // maxLines: 1, + // minFontSize: 10, + // style: TextStyle( + // fontSize: SizeConfig.textMultiplier! * 1.4, + // fontWeight: FontWeight.w600, + // letterSpacing: -0.39, + // height: 0.8, + // ), + // ), + // // Text(TranslationBase.of(context).nearestAppo, style: TextStyle(fontSize: 14.0, letterSpacing: -0.56)), + // ], + // ), + // ), + // mHeight(8), + // InkWell( + // onTap: () { + // openDropdown(projectDropdownKey); + // }, + // child: Container( + // width: double.infinity, + // decoration: containerRadius(Colors.white, 12), + // margin: EdgeInsets.only(left: 20, right: 20), + // padding: EdgeInsets.only(left: 10, right: 10, top: 12, bottom: 12), + // child: Row( + // children: [ + // Flexible( + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // Text( + // TranslationBase.of(context).selectHospital, + // style: TextStyle( + // fontSize: 11, + // letterSpacing: -0.44, + // fontWeight: FontWeight.w600, + // ), + // ), + // Container( + // height: 18, + // width: double.infinity, + // child: DropdownButtonHideUnderline( + // child: DropdownButton( + // key: projectDropdownKey, + // hint: Text(TranslationBase.of(context).selectHospital), + // value: selectedHospital, + // iconSize: 0, + // isExpanded: true, + // style: TextStyle(fontSize: 14, letterSpacing: -0.56, color: Colors.black), + // items: projectsList.map((HospitalsModel item) { + // return DropdownMenuItem( + // value: item, + // child: AutoSizeText( + // item.name!, + // maxLines: 1, + // minFontSize: 10, + // style: TextStyle( + // fontSize: SizeConfig.textMultiplier! * 1.6, + // fontWeight: FontWeight.w600, + // letterSpacing: -0.39, + // height: 0.8, + // ), + // ), + // // Text('${item.name!}'), + // ); + // }).toList(), + // onChanged: (HospitalsModel? newValue) { + // getClinicWrtHospital(newValue); + // setState(() { + // selectedHospital = newValue; + // }); + // }, + // ), + // ), + // ), + // ], + // ), + // ), + // Icon(Icons.keyboard_arrow_down), + // ], + // )), + // ), + // if (clinicIds?.isNotEmpty == true) ...[ + // mHeight(8), + // InkWell( + // onTap: () { + // showClickListDialog(context, clinicIds ?? List.empty(), onSelection: (ListClinicCentralized clincs) { + // selectedClinic = clincs; + // Navigator.pop(context); + // setState(() { + // dropdownTitle = clincs.clinicDescription!; + // dropdownValue = clincs.clinicID.toString() + "-" + clincs.isLiveCareClinicAndOnline.toString() + "-" + clincs.liveCareClinicID.toString() + "-" + clincs.liveCareServiceID.toString(); + // }); + // getDoctorsList(context); + // + // context.read().analytics.appointment.book_appointment_select_clinic(appointment_type: 'regular', clinic: clincs.clinicDescription); + // }); + // }, + // child: Container( + // width: double.infinity, + // decoration: containerRadius(Colors.white, 12), + // margin: EdgeInsets.only(left: 20, right: 20), + // padding: EdgeInsets.only(left: 10, right: 10, top: 12, bottom: 8), + // child: Row( + // children: [ + // Expanded( + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // Text( + // TranslationBase.of(context).selectClinic, + // style: TextStyle( + // fontSize: 11, + // letterSpacing: -0.44, + // fontWeight: FontWeight.w600, + // ), + // ), + // Padding( + // padding: const EdgeInsets.only(top: 4, bottom: 2), + // child: Text( + // dropdownTitle, + // style: TextStyle( + // fontSize: 13, + // letterSpacing: -0.44, + // fontWeight: FontWeight.w600, + // ), + // ), + // ), + // ], + // ), + // ), + // Icon(Icons.keyboard_arrow_down), + // ], + // ), + // ), + // ) + // ] + // ], + // ); + } + + void openDropdown(GlobalKey key) { + GestureDetector? detector; + + void searchForGestureDetector(BuildContext element) { + element.visitChildElements((element) { + if (element.widget != null && element.widget is GestureDetector) { + detector = element.widget as GestureDetector?; + //return false; + } else { + searchForGestureDetector(element); + } + + //return true; + }); + } + + searchForGestureDetector(key.currentContext!); + assert(detector != null); + + detector!.onTap!(); + } + + GestureDetector? searchForGestureDetector(BuildContext element) { + GestureDetector? detector; + element.visitChildElements((element) { + if (element.widget != null && element.widget is GestureDetector) { + detector = element.widget as GestureDetector?; + //return false; + } else { + searchForGestureDetector(element); + } + }); + return detector; + } + + getProjectsList() { + AppGlobal.context = context; + GifLoaderDialogUtils.showMyDialog(context); + int languageID = context.read().isArabic ? 1 : 2; + ClinicListService service = new ClinicListService(); + List projectsListLocal = []; + service.getProjectsList(languageID, context).then((res) async { + if (res['MessageStatus'] == 1) { + res['ListProject'].forEach((v) { + projectsListLocal.add(new HospitalsModel.fromJson(v)); + }); + projectsList = projectsListLocal; + hospitalList = await DoctorMapper.getMappedHospitals(projectsList, isArabic: context.read().isArabic); + var lat = await sharedPref.getDouble(USER_LAT); + + var lng = await sharedPref.getDouble(USER_LONG); + var isLocationEnabled = (lat != null && lat != 0.0) && (lng != null && lng != 0.0); + hospitalList = await DoctorMapper.sortList(isLocationEnabled, hospitalList!); + setState(() {}); + GifLoaderDialogUtils.hideDialog(context); + } else {} + GifLoaderDialogUtils.hideDialog(context); + locationUtils.getCurrentLocation(); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + locationUtils.getCurrentLocation(); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + locationUtils.getCurrentLocation(); + print(err); + }); + } + + void getClinicWrtHospital(HospitalsModel? newValue) async { + GifLoaderDialogUtils.showMyDialog(context); + ClinicListService service = new ClinicListService(); + List projectsListLocal = []; + setState(() { + clinicIds = List.empty(); + }); + List clinicId = []; + try { + Map res = await service.getClinicByHospital(projectID: newValue?.mainProjectID.toString() ?? ""); + GifLoaderDialogUtils.hideDialog(context); + if (res['MessageStatus'] == 1) { + List list = res['ListClinic']; + + if (list.isEmpty) { + AppToast.showErrorToast( + message: TranslationBase.of(context).NoClinicFound, + ); + } + res['ListClinic'].forEach((v) { + clinicId.add(ListClinicCentralized.fromJson(v)); + }); + clinicIds = clinicId; + setState(() {}); + } else { + AppToast.showErrorToast( + message: TranslationBase.of(context).NoClinicFound, + ); + } + } catch (e) { + print("the error is $e"); + AppToast.showErrorToast( + message: TranslationBase.of(context).NoClinicFound, + ); + GifLoaderDialogUtils.hideDialog(context); + } + + // .then((res) { + // print("the result is obtained"); + // GifLoaderDialogUtils.hideDialog(context); + // if (res['MessageStatus'] == 1) { + // List list = res['ListClinic']; + // + // if(list.isEmpty){ + // AppToast.showErrorToast(message: + // TranslationBase.of(context).NoClinicFound, + // ); + // + // } + // res['ListClinic'].forEach((v) { + // clinicId?.add(ListClinicCentralized.fromJson(v)); + // }); + // clinicIds = clinicId; + // setState(() { + // + // }); + // } else { + // AppToast.showErrorToast(message: + // TranslationBase.of(context).NoClinicFound, + // ); + // } + // }).catchError((err) { + // print('the error is $err'); + // AppToast.showErrorToast(message: + // TranslationBase.of(context).NoClinicFound, + // ); + // GifLoaderDialogUtils.hideDialog(context); + // }).catchError((err) { + // AppToast.showErrorToast(message: + // TranslationBase.of(context).NoClinicFound, + // ); + // GifLoaderDialogUtils.hideDialog(context); + // + // print(err); + // }); + } + + @override + void dispose() { + super.dispose(); + } + + Future navigateToDentalComplaints(BuildContext context, SearchInfo searchInfo) async { + Navigator.push( + context, + FadePage( + page: DentalComplaints(searchInfo: searchInfo), + ), + ).then((value) { + setState(() { + dropdownValue = null; + selectedHospital = null; + dropdownTitle = ""; + clinicIds = List.empty(); + }); + }); + } + + callDoctorsSearchAPI(int clinicID) { + var isArabic = context.read().isArabic; + int languageID = isArabic ? 1 : 2; + GifLoaderDialogUtils.showMyDialog(context); + List doctorsList = []; + List arr = []; + List arrDistance = []; + List result; + int numAll; + List _patientDoctorAppointmentListHospital = []; + + DoctorsListService service = new DoctorsListService(); + service + .getDoctorsList(clinicID, selectedHospital?.mainProjectID.toString() != "" ? int.parse(selectedHospital?.mainProjectID.toString() ?? "-1") : 0, nearestAppo, languageID, null) + .then((res) async { + GifLoaderDialogUtils.hideDialog(context); + if (res['MessageStatus'] == 1) { + RegionList regionHospitalList = RegionList(); + + if (res['DoctorList'].length != 0) { + res['DoctorList'].forEach((v) { + doctorsList.add(new DoctorList.fromJson( + v, + )); + }); + + regionHospitalList = await DoctorMapper.getMappedDoctor(doctorsList, isArabic: isArabic); + var lat = await sharedPref.getDouble(USER_LAT); + + var lng = await sharedPref.getDouble(USER_LONG); + var isLocationEnabled = (lat != null && lat != 0.0) && (lng != null && lng != 0.0); + regionHospitalList = await DoctorMapper.sortList(isLocationEnabled, regionHospitalList); + + setState(() {}); + } else { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: res['ErrorSearchMsg']); + } + + GifLoaderDialogUtils.hideDialog(context); + // navigateToSearchResults(context, doctorsList, _patientDoctorAppointmentListHospital); + navigateToSearchResults(context, regionHospitalList); + } else { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: res['ErrorEndUserMessage']); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + AppToast.showErrorToast(message: err, localContext: context); + }); + } + + navigateToSearchResults(context, RegionList regionHospitalList) { + // Navigator.push(context, + // FadePage(page: SearchResults(isLiveCareAppointment: false, isDoctorNameSearch: true, doctorsList: docList, patientDoctorAppointmentListHospital: patientDoctorAppointmentListHospital, isDoctorSearchResult: true,))); + Navigator.push( + context, + FadePage( + page: SearchResultWithTab( + doctorsList: [], + patientDoctorAppointmentListHospital: regionHospitalList, + isLiveCareAppointment: false, + isDoctorSearchResult: true, + ), + ), + ); + } + + Future navigateToLaserClinic(BuildContext context) async { + Navigator.push( + context, + FadePage( + page: LaserClinic(selectedHospital: selectedHospital!), + ), + ).then((value) { + print("LaserBooking navigation return "); + setState(() { + dropdownValue = null; + selectedHospital = null; + dropdownTitle = ""; + clinicIds = List.empty(); + }); + }); + } + + getDoctorsList(BuildContext context) { + SearchInfo searchInfo = new SearchInfo(); + if (dropdownValue != null) if (dropdownValue!.split("-")[0] == "17") { + searchInfo.ProjectID = int.parse(selectedHospital?.mainProjectID.toString() ?? ""); + searchInfo.ClinicID = int.parse(dropdownValue!.split("-")[0]); + searchInfo.hospital = selectedHospital; + searchInfo.clinic = selectedClinic; + searchInfo.date = DateTime.now(); + + if (context.read().isLogin) { + if (context.read().user.age! > 12) { + navigateToDentalComplaints(context, searchInfo); + } else { + callDoctorsSearchAPI(17); + } + } else { + navigateToDentalComplaints(context, searchInfo); + } + } else if (dropdownValue!.split("-")[0] == "253") { + navigateToLaserClinic(context); + // callDoctorsSearchAPI(); + } else if (dropdownValue!.split("-")[1] == "true" + // && authProvider.isLogin && + // authUser.patientType == 1 + ) { + Navigator.push( + context, + FadePage( + page: LiveCareBookAppointment(clinicName: dropdownTitle, liveCareClinicID: dropdownValue!.split("-")[2], liveCareServiceID: dropdownValue!.split("-")[3]), + ), + ).then((value) { + print("navigation return "); + if (value == "false") dropdownValue = null; + + // setState(() { + // }); + if (value == "livecare") { + Navigator.push(context, FadePage(page: LiveCareHome())); + } + if (value == "schedule") { + callDoctorsSearchAPI(int.parse(dropdownValue!.split("-")[0])); + } + }); + setState(() {}); + } else { + callDoctorsSearchAPI(int.parse(dropdownValue!.split("-")[0])); + } + } +} diff --git a/lib/pages/BookAppointment/dialog/clinic_list_dialog.dart b/lib/pages/BookAppointment/dialog/clinic_list_dialog.dart new file mode 100644 index 00000000..c3d82c74 --- /dev/null +++ b/lib/pages/BookAppointment/dialog/clinic_list_dialog.dart @@ -0,0 +1,141 @@ +import 'package:auto_size_text/auto_size_text.dart'; +import 'package:diplomaticquarterapp/config/size_config.dart'; +import 'package:diplomaticquarterapp/models/Clinics/ClinicListResponse.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; +import 'package:flutter_svg/svg.dart'; + +showClickListDialog(BuildContext context, List clinicsList, {Function(ListClinicCentralized)? onSelection}) { + showDialog( + context: context, + builder: (BuildContext context) { + return Dialog( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(4.0), + ), //this right here + child: Container( + width: double.infinity, + // width: MediaQuery.of(context).size.width - 10, + height: MediaQuery.of(context).size.height - 80, + child: ClickListDialog( + clinicsList: clinicsList, + onSelection: onSelection!, + ), + ), + ); + }, + ); +} + +class ClickListDialog extends StatefulWidget { + List? clinicsList; + Function(ListClinicCentralized)? onSelection; + + ClickListDialog({this.clinicsList, this.onSelection}); + + @override + _ClickListDialogState createState() => _ClickListDialogState(); +} + +class _ClickListDialogState extends State { + TextEditingController controller = new TextEditingController(); + List tempClinicsList = []; + + @override + void initState() { + // TODO: implement initState + super.initState(); + addAllData(); + } + + addAllData() { + tempClinicsList.clear(); + for (int i = 0; i < widget.clinicsList!.length; i++) { + tempClinicsList.add(widget.clinicsList![i]); + } + setState(() {}); + } + + @override + Widget build(BuildContext context) { + return Container( + child: Column( + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: TextField( + controller: controller, + onChanged: (v) { + if (v.length > 0) { + tempClinicsList.clear(); + for (int i = 0; i < widget.clinicsList!.length; i++) { + if (widget.clinicsList![i].clinicDescription!.toLowerCase().contains(v.toLowerCase())) { + tempClinicsList.add(widget.clinicsList![i]); + } + } + } else { + addAllData(); + } + setState(() {}); + }, + decoration: InputDecoration( + hintStyle: TextStyle(fontSize: 17), + hintText: TranslationBase.of(context).searchClinic, + suffixIcon: Icon(Icons.search), + border: InputBorder.none, + contentPadding: EdgeInsets.all(12), + ), + ), + ), + Expanded( + child: ListView.separated( + padding: EdgeInsets.all(12), + itemBuilder: (context, index) { + return InkWell( + onTap: () { + widget.onSelection!(tempClinicsList[index]); + }, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: AutoSizeText( + tempClinicsList[index].clinicDescription!.trim(), + maxLines: 1, + minFontSize: 10, + style: TextStyle( + fontSize: SizeConfig.textMultiplier! * 1.4, + fontWeight: FontWeight.w600, + letterSpacing: -0.39, + height: 0.8, + ), + ), + ), + tempClinicsList[index].isLiveCareClinicAndOnline == true + ? SvgPicture.asset( + 'assets/images/new-design/video_icon_green_right.svg', + height: 12, + width: 12, + fit: BoxFit.cover, + ) + : Container(), + ], + ), + ), + ); + }, + itemCount: tempClinicsList.length, + separatorBuilder: (BuildContext context, int index) { + return mHeight(8); + }, + ), + ), + ], + ), + ); + } +} diff --git a/lib/pages/BookAppointment/doctor_post_pre_images_page.dart b/lib/pages/BookAppointment/doctor_post_pre_images_page.dart new file mode 100644 index 00000000..f3cdc0c5 --- /dev/null +++ b/lib/pages/BookAppointment/doctor_post_pre_images_page.dart @@ -0,0 +1,74 @@ +import 'package:diplomaticquarterapp/models/Appointments/doctor_pre_post_image.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +class DoctorPostPreImagesContent extends StatefulWidget { + final DoctorPrePostImages doctorPrePostImages; + + const DoctorPostPreImagesContent({required this.doctorPrePostImages}); + + @override + DoctorPostPreImagesContentState createState() => DoctorPostPreImagesContentState(); +} + +class DoctorPostPreImagesContentState extends State { + @override + Widget build(BuildContext context) { + var images = widget.doctorPrePostImages; + return Center( + child: Material( + color: Colors.transparent, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row( + children: [ + Expanded( + child: Column( + children: [ + Text( + "Before", + style: TextStyle(color: Colors.white, fontSize: 17, fontWeight: FontWeight.bold, letterSpacing: 1), + ), + SizedBox( + height: 10, + ), + Image.memory( + images.getPreBytes(), + errorBuilder: (ctx, err, trace) { + return Container( + color: Colors.grey.withOpacity(0.25), + ); + }, + ) + ], + )), + Divider(color: Colors.grey.withOpacity(0.5)), + Expanded( + child: Column( + children: [ + Text( + "After", + style: TextStyle(color: Colors.white, fontSize: 17, fontWeight: FontWeight.bold, letterSpacing: 1), + ), + SizedBox( + height: 10, + ), + Image.memory( + images.getPostBytes(), + errorBuilder: (ctx, err, trace) { + return Container( + color: Colors.grey.withOpacity(0.25), + ); + }, + ) + ], + )) + ], + ), + ], + ), + ), + ); + } +} diff --git a/lib/pages/BookAppointment/search_result/ResultByClinic.dart b/lib/pages/BookAppointment/search_result/ResultByClinic.dart new file mode 100644 index 00000000..15fc79f3 --- /dev/null +++ b/lib/pages/BookAppointment/search_result/ResultByClinic.dart @@ -0,0 +1,261 @@ +import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/Appointments/SearchInfoModel.dart'; +import 'package:diplomaticquarterapp/models/Clinics/ClinicListResponse.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/DentalComplaints.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/components/LaserClinic.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/components/LiveCareBookAppointment.dart'; +import 'package:diplomaticquarterapp/pages/livecare/livecare_home.dart'; +import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; +import 'package:diplomaticquarterapp/services/appointment_services/doctor_response_mapper.dart'; +import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.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/transitions/fade_page.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +import '../../../config/shared_pref_kay.dart'; +import '../../../models/Appointments/DoctorListResponse.dart'; +import '../../../services/authentication/auth_provider.dart'; +import '../../../theme/colors.dart'; +import '../../../uitl/gif_loader_dialog_utils.dart'; + +class ResultByClinic extends StatefulWidget { + HospitalsModel? selectedValue; + Function(RegionList, int?) onClinicSelected; + + ResultByClinic({super.key, this.selectedValue, required this.onClinicSelected}); + + @override + State createState() => _ResultByClinicState(); +} + +class _ResultByClinicState extends State { + List? clinicIds = List.empty(); + + @override + void initState() { + super.initState(); + WidgetsBinding.instance.addPostFrameCallback((_) => getClinicWrtHospital(widget.selectedValue)); + } + + @override + Widget build(BuildContext context) { + return Column( + children: [ + Expanded( + child: clinicIds?.isNotEmpty == true + ? ListView.builder( + itemBuilder: (_, index) => InkWell( + onTap: () { + getDoctorsList( + context, + "${clinicIds?[index].clinicID.toString() ?? ''}-${clinicIds?[index].isLiveCareClinicAndOnline!.toString()}-${clinicIds?[index].liveCareClinicID.toString()}-${clinicIds?[index].liveCareServiceID.toString()}", + clinicIds?[index].clinicDescription!, + widget.selectedValue, + clinicIds?[index]); + }, + child: Material( + color: CustomColors.white, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 24), + child: Row( + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + clinicIds?[index].clinicDescription ?? '', + style: TextStyle(fontSize: 22, color: Colors.black, fontWeight: FontWeight.w700), + ), + ], + ), + ), + Padding( + padding: EdgeInsets.all(8), + child: Center( + child: Icon( + Icons.arrow_forward_ios, + color: CustomColors.black, + size: 16, + ), + ), + ), + ], + )), + ), + ), + itemCount: clinicIds?.length ?? 0, + ) + : getNoDataWidget(context)), + ], + ); + } + + getDoctorsList(BuildContext context, String? dropdownValue, String? dropdownTitle, HospitalsModel? selectedHospital, ListClinicCentralized? selectedClinic) { + SearchInfo searchInfo = new SearchInfo(); + if (dropdownValue != null) if (dropdownValue!.split("-")[0] == "17") { + searchInfo.ProjectID = int.parse(selectedHospital?.mainProjectID.toString() ?? ""); + searchInfo.ClinicID = int.parse(dropdownValue!.split("-")[0]); + searchInfo.hospital = selectedHospital; + searchInfo.clinic = selectedClinic; + searchInfo.date = DateTime.now(); + + if (context.read().isLogin) { + if (context.read().user.age! > 12) { + navigateToDentalComplaints(context, searchInfo); + } else { + callDoctorsSearchAPI(17); + } + } else { + navigateToDentalComplaints(context, searchInfo); + } + } else if (dropdownValue!.split("-")[0] == "253") { + navigateToLaserClinic(context); + // callDoctorsSearchAPI(); + } else if (dropdownValue!.split("-")[1] == "true" + // && authProvider.isLogin && + // authUser.patientType == 1 + ) { + Navigator.push( + context, + FadePage( + page: LiveCareBookAppointment(clinicName: dropdownTitle, liveCareClinicID: dropdownValue!.split("-")[2], liveCareServiceID: dropdownValue!.split("-")[3]), + ), + ).then((value) { + print("navigation return "); + if (value == "false") return; + + // setState(() { + // }); + if (value == "livecare") { + Navigator.push(context, FadePage(page: LiveCareHome())); + } + if (value == "schedule") { + callDoctorsSearchAPI(int.parse(dropdownValue!.split("-")[0])); + } + }); + setState(() {}); + } else { + callDoctorsSearchAPI(int.parse(dropdownValue!.split("-")[0])); + } + } + + Future navigateToLaserClinic(BuildContext context) async { + Navigator.push( + context, + FadePage( + page: LaserClinic(selectedHospital: widget.selectedValue!), + ), + ).then((value) {}); + } + + Future navigateToDentalComplaints(BuildContext context, SearchInfo searchInfo) async { + Navigator.push( + context, + FadePage( + page: DentalComplaints( + searchInfo: searchInfo, + isFromHospitalSearchPage: true, + ), + ), + ).then((value) { + if (value is RegionList) { + widget.onClinicSelected(value,null); + } + }); + } + + callDoctorsSearchAPI(int clinicID) { + var isArabic = context.read().isArabic; + int languageID = isArabic ? 1 : 2; + GifLoaderDialogUtils.showMyDialog(context); + List doctorsList = []; + List arr = []; + List arrDistance = []; + List result; + int numAll; + List _patientDoctorAppointmentListHospital = []; + + DoctorsListService service = new DoctorsListService(); + service + .getDoctorsList(clinicID, widget.selectedValue?.mainProjectID.toString() != "" ? int.parse(widget.selectedValue?.mainProjectID.toString() ?? "-1") : 0, false, languageID, null) + .then((res) async { + GifLoaderDialogUtils.hideDialog(context); + if (res['MessageStatus'] == 1) { + RegionList regionHospitalList = RegionList(); + + if (res['DoctorList'].length != 0) { + res['DoctorList'].forEach((v) { + doctorsList.add(new DoctorList.fromJson( + v, + )); + }); + + regionHospitalList = await DoctorMapper.getMappedDoctor(doctorsList, isArabic: isArabic); + var lat = await sharedPref.getDouble(USER_LAT); + + var lng = await sharedPref.getDouble(USER_LONG); + var isLocationEnabled = (lat != null && lat != 0.0) && (lng != null && lng != 0.0); + regionHospitalList = await DoctorMapper.sortList(isLocationEnabled, regionHospitalList); + widget.onClinicSelected(regionHospitalList, clinicID); + setState(() {}); + } else { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: res['ErrorSearchMsg']); + } + + GifLoaderDialogUtils.hideDialog(context); + // navigateToSearchResults(context, doctorsList, _patientDoctorAppointmentListHospital); + } else { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: res['ErrorEndUserMessage']); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + AppToast.showErrorToast(message: err, localContext: context); + }); + } + + void getClinicWrtHospital(HospitalsModel? newValue) async { + AppGlobal.context = context; + GifLoaderDialogUtils.showMyDialog(context); + ClinicListService service = new ClinicListService(); + List projectsListLocal = []; + clinicIds = List.empty(); + List clinicId = []; + try { + Map res = await service.getClinicByHospital(projectID: newValue?.mainProjectID.toString() ?? ""); + GifLoaderDialogUtils.hideDialog(context); + if (res['MessageStatus'] == 1) { + List list = res['ListClinic']; + + if (list.isEmpty) { + AppToast.showErrorToast( + message: TranslationBase.of(context).NoClinicFound, + ); + } + res['ListClinic'].forEach((v) { + clinicId.add(ListClinicCentralized.fromJson(v)); + }); + clinicIds = clinicId; + setState(() {}); + } else { + AppToast.showErrorToast( + message: TranslationBase.of(context).NoClinicFound, + ); + } + } catch (e) { + print("the error is $e"); + AppToast.showErrorToast( + message: TranslationBase.of(context).NoClinicFound, + ); + GifLoaderDialogUtils.hideDialog(context); + } + } +} diff --git a/lib/pages/BookAppointment/search_result/ResultByDoctors.dart b/lib/pages/BookAppointment/search_result/ResultByDoctors.dart new file mode 100644 index 00000000..bdb74688 --- /dev/null +++ b/lib/pages/BookAppointment/search_result/ResultByDoctors.dart @@ -0,0 +1,130 @@ +import 'package:auto_size_text/auto_size_text.dart'; +import 'package:diplomaticquarterapp/config/size_config.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; +import 'package:diplomaticquarterapp/models/Appointments/OBGyneProcedureListResponse.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/widgets/DoctorView.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class ResultByDoctor extends StatefulWidget { + List doctorsList = []; + List? patientDoctorAppointmentListHospital; + final bool isLiveCareAppointment; + final bool isObGyneAppointment; + final bool isDoctorNameSearch; + final bool isDoctorSearchResult; + final bool showNearestAppointment; + final bool nearestAppointmentDoctors; + final OBGyneProcedureListResponse? obGyneProcedureListResponse; + final Function(bool)? refreshDoctorList; + + ResultByDoctor({ + required this.doctorsList, + required this.patientDoctorAppointmentListHospital, + required this.isLiveCareAppointment, + required this.isObGyneAppointment, + required this.isDoctorNameSearch, + required this.isDoctorSearchResult, + this.showNearestAppointment = false, + this.nearestAppointmentDoctors = false, + this.obGyneProcedureListResponse, + this.refreshDoctorList + }); + + @override + State createState() => _ResultByDoctorState(); +} + +class _ResultByDoctorState extends State { + + bool nearestAppo = false; + + @override + void initState() { + nearestAppo = widget.nearestAppointmentDoctors; + super.initState(); + } + @override + Widget build(BuildContext context) { + return Column( + children: [ + + Visibility( + visible: widget.showNearestAppointment, + child: Padding( + padding: const EdgeInsets.only(left: 6, right: 6,), + child: Row( + children: [ + Checkbox( + activeColor: CustomColors.accentColor, + value: nearestAppo, + onChanged: (bool? value) { + setState(() { + nearestAppo = value ?? false; + }); + widget.refreshDoctorList?.call(nearestAppo); + }, + ), + AutoSizeText( + TranslationBase.of(context).nearestAppo.trim(), + maxLines: 1, + minFontSize: 10, + style: TextStyle( + fontSize: SizeConfig.textMultiplier! * 1.4, + fontWeight: FontWeight.w600, + letterSpacing: -0.39, + height: 0.8, + ), + ), + // Text(TranslationBase.of(context).nearestAppo, style: TextStyle(fontSize: 14.0, letterSpacing: -0.56)), + ], + ), + ), + ), + widget.patientDoctorAppointmentListHospital?.isNotEmpty == true + ? Expanded( + child: ListView.separated( + addAutomaticKeepAlives: true, + physics: BouncingScrollPhysics(), + separatorBuilder: (context, index) { + return Material( + color: Color(0xFFf5f5f5), + child: SizedBox( + height: 12, + ), + ); + }, + itemBuilder: (context, index) { + final doctor = widget.patientDoctorAppointmentListHospital![index]; + + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 12.0), + child: DoctorView( + doctor: doctor, + isLiveCareAppointment: widget.isLiveCareAppointment, + isObGyneAppointment: widget.isObGyneAppointment, + isDoctorNameSearch: widget.isDoctorNameSearch, + obGyneProcedureListResponse: widget.obGyneProcedureListResponse, + isShowDate: false, + onTap: () { + context.read().analytics.appointment.book_appointment_select_doctor(appointment_type: 'regular', doctor: doctor); + }), + ); + }, + itemCount: widget.patientDoctorAppointmentListHospital?.length ?? 0, + ), + ) + : getNoDataWidget(context), + ], + ); + } + + @override + void dispose() { + super.dispose(); + } +} diff --git a/lib/pages/BookAppointment/search_result/ResultByFacility.dart b/lib/pages/BookAppointment/search_result/ResultByFacility.dart new file mode 100644 index 00000000..f1f7ba88 --- /dev/null +++ b/lib/pages/BookAppointment/search_result/ResultByFacility.dart @@ -0,0 +1,173 @@ +import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +typedef OnFacilitySelected = Function(bool); + +class ResultByFacility extends StatelessWidget { + List doctorsList = []; + String selectedRegion = ''; + RegionList patientDoctorAppointmentListHospital; + OnFacilitySelected onFacilitySelected; + + ResultByFacility( + {required this.doctorsList, + required this.patientDoctorAppointmentListHospital, + required this.onFacilitySelected, + required this.selectedRegion}); + + @override + Widget build(BuildContext context) { + return Column( + children: [ + Visibility( + visible: patientDoctorAppointmentListHospital + .registeredDoctorMap?[selectedRegion]?.hmgSize != + 0, + child: InkWell( + onTap: () { + if (patientDoctorAppointmentListHospital + .registeredDoctorMap?[selectedRegion]?.hmgSize == + 0) return; + onFacilitySelected(false); + }, + child: HospitalTitle( + iconUrl: 'assets/images/svg/HMG.svg', + title: TranslationBase.of(context).hmgHospital, + isHMC: false, + itemCount: + "${patientDoctorAppointmentListHospital.registeredDoctorMap?[selectedRegion]?.hmgSize ?? 0}", + nearest: patientDoctorAppointmentListHospital + .registeredDoctorMap?[selectedRegion]?.hmgDistance), + ), + ), + SizedBox(height: 16,), + Visibility( + visible: patientDoctorAppointmentListHospital + .registeredDoctorMap?[selectedRegion]?.hmcSize != + 0, + child: InkWell( + onTap: () { + if (patientDoctorAppointmentListHospital + .registeredDoctorMap?[selectedRegion]?.hmcSize == + 0) return; + onFacilitySelected(true); + }, + child: HospitalTitle( + iconUrl: 'assets/images/svg/HMC.svg', + title: TranslationBase.of(context).hmcHospital, + isHMC: true, + itemCount: + "${patientDoctorAppointmentListHospital.registeredDoctorMap?[selectedRegion]?.hmcSize ?? 0}", + nearest: patientDoctorAppointmentListHospital + .registeredDoctorMap?[selectedRegion]?.hmcDistance), + ), + ) + ]); + } +} + +class HospitalTitle extends StatelessWidget { + final String title; + final String iconUrl; + final bool isHMC; + final num? nearest; + final String itemCount; + + const HospitalTitle( + {super.key, + required this.title, + required this.iconUrl, + required this.isHMC, + required this.itemCount,this.nearest}); + + @override + Widget build(BuildContext context) { + return Material( + color: Colors.white, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 24), + child: Row( + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + SvgPicture.asset(iconUrl), + SizedBox( + width: 8, + ), + Text( + title, + style: TextStyle( + fontSize: 18, + color: + isHMC ? Color(0xFF40ACC9) : Color(0xFFD02127), + fontWeight: FontWeight.w600), + ), + ], + ), + SizedBox( + height: 6, + ), + Row( + children: [ + Text( + isHMC + ? "${TranslationBase.of(context).MedicalCenterString(num.parse(itemCount)).replaceAll("@", itemCount)}" + : "${TranslationBase.of(context).HospitalString(num.parse(itemCount)).replaceAll("@", itemCount)}", + style: TextStyle( + fontSize: 12, + color: Colors.black, + fontWeight: FontWeight.w600), + ), + Visibility( + visible: nearest != double.infinity && + nearest != "0" && + nearest != 0, + child: Row( + children: [ + SizedBox( + width: 8, + ), + SvgPicture.asset( + 'assets/images/svg/location.svg', + ), + SizedBox( + width: 8, + ), + Text( + "${TranslationBase.of(context).nearest}: $nearest ${TranslationBase.of(context).kilometerUnit}", + style: TextStyle( + fontSize: 12, + color: Colors.black, + fontWeight: FontWeight.w600), + ), + ], + ), + ), + ], + ), + ], + ), + ), + Padding( + padding: EdgeInsets.all(8), + child: Center( + child: Icon( + Icons.arrow_forward_ios, + color: CustomColors.black, + size: 16, + ), + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/pages/BookAppointment/search_result/ResultByHospital.dart b/lib/pages/BookAppointment/search_result/ResultByHospital.dart new file mode 100644 index 00000000..b487094e --- /dev/null +++ b/lib/pages/BookAppointment/search_result/ResultByHospital.dart @@ -0,0 +1,248 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; +import 'package:diplomaticquarterapp/models/Appointments/OBGyneProcedureListResponse.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:provider/provider.dart'; + +typedef OnHospitalSelected = Function(String, int); + +class ResultByHospital extends StatelessWidget { + List doctorsList = []; + List? paitientDoctorAppointmentList; + bool isHMCSelected; + + bool isLiveCareAppointment; + bool isObGyneAppointment; + bool isDoctorNameSearch; + OBGyneProcedureListResponse? obGyneProcedureListResponse; + bool isDoctorSearchResult; + OnHospitalSelected onHospitalSelected; + + ResultByHospital( + {required this.doctorsList, + required this.paitientDoctorAppointmentList, + required this.isHMCSelected, + this.isObGyneAppointment = false, + this.isDoctorNameSearch = false, + required this.isLiveCareAppointment, + required this.isDoctorSearchResult, + this.obGyneProcedureListResponse, + required this.onHospitalSelected}); + + @override + Widget build(BuildContext context) { + return Column( + children: [ + Expanded( + child: HospitalBodyWidget( + patientDoctorAppointmentListHospital: paitientDoctorAppointmentList, + isLiveCareAppointment: isLiveCareAppointment, + isObGyneAppointment: isObGyneAppointment, + isDoctorNameSearch: isDoctorNameSearch, + isDoctorSearchResult: isDoctorSearchResult, + onHospitalSelected: onHospitalSelected, + isHMC: isHMCSelected), + ), + ], + ); + } +} + +class HospitalBodyWidget extends StatelessWidget { + final List? + patientDoctorAppointmentListHospital; + final bool isLiveCareAppointment; + final bool isObGyneAppointment; + final bool isDoctorNameSearch; + final bool isDoctorSearchResult; + final OBGyneProcedureListResponse? obGyneProcedureListResponse; + final OnHospitalSelected onHospitalSelected; + final bool isHMC; + + const HospitalBodyWidget( + {super.key, + this.patientDoctorAppointmentListHospital, + required this.isLiveCareAppointment, + required this.isObGyneAppointment, + required this.isDoctorNameSearch, + required this.isDoctorSearchResult, + this.obGyneProcedureListResponse, + required this.onHospitalSelected, + required this.isHMC}); + + @override + Widget build(BuildContext context) { + return ListView.separated( + addAutomaticKeepAlives: true, + shrinkWrap: true, + physics: BouncingScrollPhysics(), + itemCount: patientDoctorAppointmentListHospital?.length ?? 0, + separatorBuilder: (context, index) { + return Container( + height: 12, + margin: EdgeInsets.only(left: 21, right: 21), + ); + }, + itemBuilder: (context, index) { + return InkWell( + onTap: () { + onHospitalSelected( + patientDoctorAppointmentListHospital![index].filterName ?? '', + index); + }, + child: Material( + color: CustomColors.white, + child: Padding( + padding: + const EdgeInsets.symmetric(horizontal: 16, vertical: 24), + child: Row( + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Padding( + padding: const EdgeInsets.all(6.0), + child: SvgPicture.asset( + isHMC + ? 'assets/images/svg/HMC.svg' + : 'assets/images/svg/HMG.svg', + ), + ), + Expanded( + child: Directionality( + textDirection: (context + .read() + .isArabic == + true) + ? TextDirection.rtl + : TextDirection.ltr, + child: Text( + patientDoctorAppointmentListHospital![index] + .filterName ?? + '', + style: TextStyle( + fontSize: 22, + color: isHMC + ? Color(0xFF40ACC9) + : Color(0xFFD02127), + fontWeight: FontWeight.w700), + ), + ), + ), + ], + ), + SizedBox( + height: 8, + ), + Visibility( + visible: + (patientDoctorAppointmentListHospital?[index] + .distanceInKMs != + "0"), + child: Row( + children: [ + SvgPicture.asset( + 'assets/images/svg/location.svg', + ), + SizedBox( + width: 8, + ), + Text( + // "${TranslationBase.of(context).nearest}: ${patientDoctorAppointmentListHospital?[index].distanceInKMs} ${TranslationBase.of(context).kilometerUnit}", + "${patientDoctorAppointmentListHospital?[index].distanceInKMs} ${TranslationBase.of(context).kilometerUnit}", + style: TextStyle( + fontSize: 14, + color: Colors.black, + fontWeight: FontWeight.w600), + ), + ], + ), + ), + ], + ), + ), + Padding( + padding: EdgeInsets.all(8), + child: Center( + child: Icon( + Icons.arrow_forward_ios, + color: CustomColors.black, + size: 16, + ), + ), + ), + ], + )), + ), + ); + // return AppExpandableNotifier( + // applyBackgroundColor: false, + // widgetColor: CustomColors.appBackgroudGrey2Color, + // title: (patientDoctorAppointmentListHospital?[index].distanceInKMs != + // "0") + // ? patientDoctorAppointmentListHospital![index].filterName! + + // " - " + + // patientDoctorAppointmentListHospital![index].distanceInKMs! + + // " " + + // TranslationBase.of(context).km + // : patientDoctorAppointmentListHospital![index].filterName, + // projectTitleTop: + // patientDoctorAppointmentListHospital![index].projectTopName, + // projectTitleBottom: (patientDoctorAppointmentListHospital![index] + // .distanceInKMs != + // "0") + // ? patientDoctorAppointmentListHospital![index] + // .projectBottomName + // .toString() + + // " - " + + // patientDoctorAppointmentListHospital![index].distanceInKMs! + + // " " + + // TranslationBase.of(context).km + // : patientDoctorAppointmentListHospital![index] + // .projectBottomName + // .toString(), + // isTitleSingleLine: false, + // isDoctorSearchResult: isDoctorSearchResult, + // isDisabled: true, + // isExpand: + // patientDoctorAppointmentListHospital?.length == 1 ? true : false, + // // bodyWidget: ListView.separated( + // // shrinkWrap: true, + // // physics: NeverScrollableScrollPhysics(), + // // padding: + // // EdgeInsets.only(bottom: 10, top: 10, left: 21, right: 21), + // // itemBuilder: (context, _index) { + // // // print("the index of patientDoctorAppointmentList is ${_index}"); + // // // print("the index of parent is ${index}"); + // // final doctor = patientDoctorAppointmentListHospital![index] + // // .patientDoctorAppointmentList![_index]; + // // // print('the doctor is ${doctor.toJson()}'); + // // return DoctorView( + // // doctor: doctor, + // // isLiveCareAppointment: isLiveCareAppointment, + // // isObGyneAppointment: isObGyneAppointment, + // // isDoctorNameSearch: isDoctorNameSearch, + // // obGyneProcedureListResponse: obGyneProcedureListResponse, + // // isShowDate: false, + // // onTap: () { + // // context + // // .read() + // // .analytics + // // .appointment + // // .book_appointment_select_doctor( + // // appointment_type: 'regular', doctor: doctor); + // // }); + // // }, + // // separatorBuilder: (context, index) => SizedBox(height: 14), + // // itemCount: patientDoctorAppointmentListHospital?[index].patientDoctorAppointmentList?.length ?? 0), + // ); + }, + ); + } +} diff --git a/lib/pages/BookAppointment/search_result/ResultByRegion.dart b/lib/pages/BookAppointment/search_result/ResultByRegion.dart new file mode 100644 index 00000000..6eaa83d2 --- /dev/null +++ b/lib/pages/BookAppointment/search_result/ResultByRegion.dart @@ -0,0 +1,170 @@ +import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; +import 'package:diplomaticquarterapp/theme/colors.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/flutter_svg.dart'; + +typedef OnRegionSelected = Function(String); +class ResultByRegion extends StatelessWidget { + List doctorsList = []; + RegionList patientDoctorAppointmentListHospital; + OnRegionSelected onRegionSelected; + ResultByRegion( + {required this.doctorsList, + required this.patientDoctorAppointmentListHospital, + required this.onRegionSelected + }); + + @override + Widget build(BuildContext context) { + return Column( + children: [ + Expanded( + child: patientDoctorAppointmentListHospital + .registeredDoctorMap?.isNotEmpty == + true + ? ListView.separated( + addAutomaticKeepAlives: true, + physics: BouncingScrollPhysics(), + separatorBuilder: (context, index) { + return Material( + color: Color(0xFFf5f5f5), + child: SizedBox( + height: 12, + ), + ); + }, + itemBuilder: (context, index) { + String key = patientDoctorAppointmentListHospital + .registeredDoctorMap?.keys + .toList()[index] ?? + ''; + + return InkWell( + onTap: (){ + onRegionSelected(key); + }, + child: RegionTitle( + title: key, + hmcCount: + "${patientDoctorAppointmentListHospital.registeredDoctorMap?[key]?.hmcSize ?? 0}", + hmgCount: + "${patientDoctorAppointmentListHospital.registeredDoctorMap?[key]?.hmgSize ?? 0}", + ), + ); + + }, + itemCount: patientDoctorAppointmentListHospital + .registeredDoctorMap?.length ?? + 0, + ) + : getNoDataWidget(context), + ), + ], + ); + } +} + + +class RegionTitle extends StatelessWidget { + final String title; + final String hmcCount; + final String hmgCount; + + const RegionTitle( + {super.key, + required this.title, + required this.hmcCount, + required this.hmgCount}); + + @override + Widget build(BuildContext context) { + return Material( + color: CustomColors.white, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 24), + child: Row( + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title, + style: TextStyle( + fontSize: 22, color: Colors.black, fontWeight: FontWeight.w700), + ), + SizedBox( + height: 8, + ), + Row( + children: [ + Visibility( + visible: hmgCount != "0", + child: Row( + children: [ + SvgPicture.asset( + 'assets/images/svg/HMG.svg', + width: 10, + height: 10, + ), + SizedBox( + width: 8, + ), + Text( + "${TranslationBase.of(context).HospitalString(num.parse(hmgCount)).replaceAll("@", hmgCount)}", + style: TextStyle( + fontSize: 14, + color: Color(0xFFD02127), + fontWeight: FontWeight.w600), + ), + ], + ), + ), + Visibility( + visible: hmcCount != "0" && hmgCount != "0", + child: Text(", ")), + Visibility( + visible: hmcCount != "0", + child: Row( + children: [ + SvgPicture.asset( + 'assets/images/svg/HMC.svg', + width: 10, + height: 10, + ), + SizedBox( + width: 8, + ), + Text( + "${TranslationBase.of(context).MedicalCenterString(num.parse(hmcCount)).replaceAll("@", hmcCount)}", + style: TextStyle( + fontSize: 14, + color: Color(0xFF40ACC9), + fontWeight: FontWeight.w600), + ), + ], + ), + ), + ], + ), + ], + ), + ), + Padding( + padding: EdgeInsets.all(8), + child: Center( + child: Icon( + Icons.arrow_forward_ios, + color: CustomColors.black, + size: 16, + ), + ), + ), + ], + ) + ), + ); + } +} diff --git a/lib/pages/BookAppointment/search_result/SearchResultWithTab.dart b/lib/pages/BookAppointment/search_result/SearchResultWithTab.dart new file mode 100644 index 00000000..25d527b9 --- /dev/null +++ b/lib/pages/BookAppointment/search_result/SearchResultWithTab.dart @@ -0,0 +1,725 @@ +import 'package:diplomaticquarterapp/config/size_config.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; +import 'package:diplomaticquarterapp/models/Appointments/OBGyneProcedureListResponse.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/search_result/ResultByDoctors.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/search_result/ResultByFacility.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/search_result/ResultByHospital.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/search_result/ResultByRegion.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/widgets/DoctorView.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_expandable_notifier.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 SearchResultWithTab extends StatefulWidget { + List doctorsList = []; + RegionList patientDoctorAppointmentListHospital; + bool isLiveCareAppointment; + bool isObGyneAppointment; + bool isDoctorNameSearch; + OBGyneProcedureListResponse? obGyneProcedureListResponse; + bool isDoctorSearchResult; + + bool isForHospital; + + SearchResultWithTab({required this.doctorsList, + required this.patientDoctorAppointmentListHospital, + this.isObGyneAppointment = false, + this.isDoctorNameSearch = false, + required this.isLiveCareAppointment, + required this.isDoctorSearchResult, + this.obGyneProcedureListResponse, + this.isForHospital = false, + }); + + @override + State createState() => _SearchResultWithTabState(); +} + +class _SearchResultWithTabState extends State { + int _currentIndex = 0; + late PageController _controller; + String selectedRegion = ""; + bool isHMCSelected = false; + int selectedHospitalIndex = -1; + ScrollController scrollController = ScrollController(); + + @override + void initState() { + super.initState(); + _controller = new PageController(); + } + + changePageViewIndex(pageIndex) { + _controller.jumpToPage(pageIndex); + // scrollController.jumpTo(pageIndex); + } + + + @override + Widget build(BuildContext context) { + return AppScaffold( + appBarTitle: TranslationBase.of(context).bookAppo, + isShowDecPage: false, + isShowAppBar: true, + showNewAppBarTitle: true, + showNewAppBar: true, + backgroundColor: CustomColors.appBackgroudGrey2Color, + body: widget.patientDoctorAppointmentListHospital + .registeredDoctorMap?.isNotEmpty == + true + ? SizedBox( + height: SizeConfig.realScreenHeight! * .9, + width: SizeConfig.realScreenWidth, + child: Column(children: [ + Container( + width: double.infinity, + padding: EdgeInsets.only(left: 20, right: 20, top: 12), + child: SizedBox( + height: 100, + child: ListView( + scrollDirection: Axis.horizontal, + controller: scrollController, + children: [ + SizedBox( + width: MediaQuery.of(context).size.width / 4, + child: showProgress( + title: TranslationBase.of(context).selectRegion, + status: _currentIndex == 0 + ? TranslationBase.of(context).inPrgress + : _currentIndex > 0 + ? TranslationBase.of(context).completed + : TranslationBase.of(context).locked, + color: _currentIndex == 0 + ? CustomColors.orange + : CustomColors.green, + onTap: () { + setState(() { + selectedHospitalIndex = -1; + selectedRegion = ""; + _currentIndex = 0; + changePageViewIndex(0); + }); + }, + ), + ), + SizedBox( + width: MediaQuery.of(context).size.width / 4, + child: showProgress( + title: TranslationBase.of(context).selectFacitlity, + status: _currentIndex == 1 + ? TranslationBase.of(context).inPrgress + : _currentIndex > 1 + ? TranslationBase.of(context).completed + : TranslationBase.of(context).locked, + color: _currentIndex == 1 + ? CustomColors.orange + : _currentIndex > 1 + ? CustomColors.green + : CustomColors.grey2, + onTap: () { + setState(() { + selectedHospitalIndex = -1; + _currentIndex = 1; + changePageViewIndex(1); + }); + }, + ), + ), + SizedBox( + width: MediaQuery.of(context).size.width / 4, + child: showProgress( + title: TranslationBase.of(context).selectBranch, + status: _currentIndex == 2 + ? TranslationBase.of(context).inPrgress + : _currentIndex > 1 + ? TranslationBase.of(context).completed + : TranslationBase.of(context).locked, + color: _currentIndex == 2 + ? CustomColors.orange + : _currentIndex > 2 + ? CustomColors.green + : CustomColors.grey2, + onTap: () { + setState(() { + selectedHospitalIndex = -1; + _currentIndex = 2; + changePageViewIndex(2); + }); + }, + ), + ), + (widget.isForHospital) + ? SizedBox( + width: MediaQuery.of(context).size.width / 4, + child: showProgress( + title: + TranslationBase.of(context).selectClinic, + status: _currentIndex == 3 + ? TranslationBase.of(context).inPrgress + : TranslationBase.of(context).locked, + color: _currentIndex == 3 + ? CustomColors.orange + : _currentIndex > 4 + ? CustomColors.green + : CustomColors.grey2, + isNeedBorder: false, + onTap: () { + setState(() { + _currentIndex = 3; + changePageViewIndex(3); + }); + }, + ), + ) + : SizedBox.shrink(), + SizedBox( + width: MediaQuery.of(context).size.width / 4, + child: showProgress( + title: TranslationBase.of(context).selectDoctor, + status: _currentIndex == + ((widget.isForHospital) ? 4 : 3) + ? TranslationBase.of(context).inPrgress + : TranslationBase.of(context).locked, + color: _currentIndex == + ((widget.isForHospital) ? 4 : 3) + ? CustomColors.orange + : _currentIndex == + ((widget.isForHospital) ? 5 : 4) + ? CustomColors.green + : CustomColors.grey2, + isNeedBorder: false, + onTap: () { + setState(() { + _currentIndex = + ((widget.isForHospital) ? 4 : 3); + changePageViewIndex(_currentIndex); + }); + }, + ), + ), + ], + ), + ), + ), + Padding( + padding: + const EdgeInsetsDirectional.fromSTEB(10.0, 18, 0, 24), + child: Row( + children: [ + (_currentIndex != 0) + ? InkWell( + onTap: () { + handleBackClick(); + }, + child: Padding( + padding: const EdgeInsetsDirectional.fromSTEB( + 0, 0, 04, 0), + child: Icon( + Icons.arrow_back, + color: Theme.of(context).primaryColor, + ), + ), + ) + : mWidth(24), + Text( + getTitle(), + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.w600, + color: Colors.black), + ) + ], + ), + ), + // mHeight(24), + Expanded( + child: PageView( + physics: NeverScrollableScrollPhysics(), + controller: _controller, + onPageChanged: (index) { + setState(() { + _currentIndex = index; + }); + }, + scrollDirection: Axis.horizontal, + children: [ + ResultByRegion( + doctorsList: widget.doctorsList, + patientDoctorAppointmentListHospital: + widget.patientDoctorAppointmentListHospital, + onRegionSelected: (key) { + setState(() { + selectedRegion = key; + _currentIndex = 1; + changePageViewIndex(1); + }); + }), + (selectedRegion != "") + ? ResultByFacility( + doctorsList: widget.doctorsList, + patientDoctorAppointmentListHospital: + widget.patientDoctorAppointmentListHospital, + selectedRegion: selectedRegion, + onFacilitySelected: (isHMCSelected) { + setState(() { + this.isHMCSelected = isHMCSelected; + _currentIndex = 2; + changePageViewIndex(2); + }); + }, + ) : SizedBox.shrink(), + (selectedRegion != '') ? + ResultByHospital(doctorsList: widget.doctorsList, + paitientDoctorAppointmentList: (isHMCSelected) ? + widget.patientDoctorAppointmentListHospital + .registeredDoctorMap![selectedRegion]! + .hmcDoctorList ?? + [] + : widget + .patientDoctorAppointmentListHospital + .registeredDoctorMap?[selectedRegion] + ?.hmgDoctorList ?? + [], + isHMCSelected: isHMCSelected, + isLiveCareAppointment: widget.isLiveCareAppointment, + isDoctorSearchResult: widget.isDoctorSearchResult, + onHospitalSelected: (hospital, index) { + setState(() { + selectedHospitalIndex = index; + _currentIndex = 3; + changePageViewIndex(3); + }); + }) + : SizedBox.shrink(), + (selectedRegion != '' && selectedHospitalIndex != -1) + ? ResultByDoctor( + doctorsList: widget.doctorsList, + patientDoctorAppointmentListHospital: (!isHMCSelected) + ? widget + .patientDoctorAppointmentListHospital + .registeredDoctorMap![selectedRegion]! + .hmgDoctorList![selectedHospitalIndex] + .patientDoctorAppointmentList ?? + [] + : widget + .patientDoctorAppointmentListHospital + .registeredDoctorMap?[selectedRegion] + ?.hmcDoctorList?[ + selectedHospitalIndex] + .patientDoctorAppointmentList ?? + [], + isLiveCareAppointment: + widget.isLiveCareAppointment, + isDoctorSearchResult: widget.isDoctorSearchResult, + isObGyneAppointment: widget.isObGyneAppointment, + isDoctorNameSearch: widget.isDoctorNameSearch) + : SizedBox.shrink(), + ], + ), + ), + ]), + ) + : getNoDataWidget(context),); + } + + String getTitle() { + switch (_currentIndex) { + case 0: + return TranslationBase + .of(context) + .selectRegion; + case 1: + return TranslationBase + .of(context) + .selectFacitlity; + case 2: + return TranslationBase + .of(context) + .selectBranch; + case 3: + return TranslationBase + .of(context) + .selectDoctor; + } + return ""; + } + + void handleBackClick() { + switch (_currentIndex) { + case 1: + selectedHospitalIndex = -1; + selectedRegion = ""; + _currentIndex = 0; + changePageViewIndex(0); + break; + case 2: + selectedHospitalIndex = -1; + _currentIndex = 1; + changePageViewIndex(1); + break; + case 3: + selectedHospitalIndex = -1; + _currentIndex = 2; + changePageViewIndex(2); + break; + } + } + + Widget showProgress( + {String? title, + String? status, + Color? color, + bool isNeedBorder = true, + Function()? onTap}) { + return InkWell( + onTap: () { + if (status == TranslationBase + .of(context) + .completed) { + onTap?.call(); + } + }, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Container( + width: 26, + height: 26, + decoration: containerRadius(color!, 200), + child: Icon( + Icons.done, + color: Colors.white, + size: 16, + ), + ), + if (isNeedBorder) + Expanded( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: mDivider(Colors.grey), + )), + ], + ), + mHeight(8), + Text( + title!, + style: TextStyle( + fontSize: 11, + fontWeight: FontWeight.w600, + letterSpacing: -0.44, + ), + ), + mHeight(2), + Container( + padding: EdgeInsets.all(5), + decoration: containerRadius(color!.withOpacity(0.2), 4), + child: Text( + status!, + style: TextStyle( + fontSize: 8, + fontWeight: FontWeight.w600, + letterSpacing: -0.32, + color: color, + ), + ), + ), + ], + ) + ], + ), + ); + } +} + +class HospitalBodyWidget extends StatelessWidget { + final List? + patientDoctorAppointmentListHospital; + final bool isLiveCareAppointment; + final bool isObGyneAppointment; + final bool isDoctorNameSearch; + final bool isDoctorSearchResult; + final OBGyneProcedureListResponse? obGyneProcedureListResponse; + + const HospitalBodyWidget({ + super.key, + this.patientDoctorAppointmentListHospital, + required this.isLiveCareAppointment, + required this.isObGyneAppointment, + required this.isDoctorNameSearch, + required this.isDoctorSearchResult, + this.obGyneProcedureListResponse, + }); + + @override + Widget build(BuildContext context) { + return ListView.separated( + addAutomaticKeepAlives: true, + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + itemCount: patientDoctorAppointmentListHospital?.length ?? 0, + separatorBuilder: (context, index) { + return Container( + height: 12, + margin: EdgeInsets.only(left: 21, right: 21), + ); + }, + itemBuilder: (context, index) { + return AppExpandableNotifier( + applyBackgroundColor: false, + widgetColor: CustomColors.appBackgroudGrey2Color, + title: (patientDoctorAppointmentListHospital?[index].distanceInKMs != + "0") + ? patientDoctorAppointmentListHospital![index].filterName! + + " - " + + patientDoctorAppointmentListHospital![index].distanceInKMs! + + " " + + TranslationBase + .of(context) + .km + : patientDoctorAppointmentListHospital![index].filterName, + projectTitleTop: + patientDoctorAppointmentListHospital![index].projectTopName, + projectTitleBottom: (patientDoctorAppointmentListHospital![index] + .distanceInKMs != + "0") + ? patientDoctorAppointmentListHospital![index] + .projectBottomName + .toString() + + " - " + + patientDoctorAppointmentListHospital![index].distanceInKMs! + + " " + + TranslationBase + .of(context) + .km + : patientDoctorAppointmentListHospital![index] + .projectBottomName + .toString(), + isTitleSingleLine: false, + isDoctorSearchResult: isDoctorSearchResult, + isExpand: + patientDoctorAppointmentListHospital?.length == 1 ? true : false, + bodyWidget: ListView.separated( + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + padding: + EdgeInsets.only(bottom: 10, top: 10, left: 21, right: 21), + itemBuilder: (context, _index) { + // print("the index of patientDoctorAppointmentList is ${_index}"); + // print("the index of parent is ${index}"); + final doctor = patientDoctorAppointmentListHospital![index] + .patientDoctorAppointmentList![_index]; + // print('the doctor is ${doctor.toJson()}'); + return DoctorView( + doctor: doctor, + isLiveCareAppointment: isLiveCareAppointment, + isObGyneAppointment: isObGyneAppointment, + isDoctorNameSearch: isDoctorNameSearch, + obGyneProcedureListResponse: obGyneProcedureListResponse, + isShowDate: false, + onTap: () { + context + .read() + .analytics + .appointment + .book_appointment_select_doctor( + appointment_type: 'regular', doctor: doctor); + }); + }, + separatorBuilder: (context, index) => SizedBox(height: 14), + itemCount: patientDoctorAppointmentListHospital?[index] + .patientDoctorAppointmentList?.length ?? 0), + ); + }, + ); + } +} + +class RegionTitle extends StatelessWidget { + final String title; + final String hmcCount; + final String hmgCount; + + const RegionTitle({super.key, + required this.title, + required this.hmcCount, + required this.hmgCount}); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title, + style: TextStyle( + fontSize: 22, color: Colors.black, fontWeight: FontWeight.w700), + ), + SizedBox( + height: 8, + ), + Row( + children: [ + Text( + "${TranslationBase.of(context).HospitalString(num.parse(hmgCount)).replaceAll("@", hmgCount)} ,", + style: TextStyle( + fontSize: 14, + color: Color(0xFFD02127), + fontWeight: FontWeight.w600), + ), + SizedBox( + width: 8, + ), + Text( + "${TranslationBase.of(context).MedicalCenterString(num.parse(hmcCount)).replaceAll("@", hmcCount)}", + style: TextStyle( + fontSize: 14, + color: Color(0xFF40ACC9), + fontWeight: FontWeight.w600), + ), + ], + ), + ], + ), + ); + } +} + +class HospitalTitle extends StatelessWidget { + final String title; + final String iconUrl; + final bool isHMC; + final String itemCount; + + const HospitalTitle({super.key, + required this.title, + required this.iconUrl, + required this.isHMC, + required this.itemCount}); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + SvgPicture.asset(iconUrl), + SizedBox( + width: 8, + ), + Text( + title, + style: TextStyle( + fontSize: 18, + color: isHMC ? Color(0xFF40ACC9) : Color(0xFFD02127), + fontWeight: FontWeight.w600), + ), + ], + ), + SizedBox( + height: 6, + ), + Text( + isHMC + ? "${TranslationBase.of(context).MedicalCenterString(num.parse(itemCount)).replaceAll("@", itemCount)}" + : "${TranslationBase.of(context).HospitalString(num.parse(itemCount)).replaceAll("@", itemCount)}", + style: TextStyle( + fontSize: 12, color: Colors.black, fontWeight: FontWeight.w600), + ), + ], + ), + ); + } +} + + +///todo the current content of the application +/// return AppExpandableNotifier( +// paddingValue: 10, +// applyBackgroundToOnlyHeader: true, +// completeHeaderColor: CustomColors.appBackgroudGrey2Color, +// headerWidget: RegionTitle( +// title: key, +// hmcCount: +// "${widget.patientDoctorAppointmentListHospital.registeredDoctorMap?[key]?.hmcSize ?? 0}", +// hmgCount: +// "${widget.patientDoctorAppointmentListHospital.registeredDoctorMap?[key]?.hmgSize ?? 0}", +// ), +// showDropDownIconWithCustomHeader: true, +// isTitleSingleLine: false, +// isDoctorSearchResult: widget.isDoctorSearchResult, +// widgetColor: Color(0xFFF8F8F8), +// bodyWidget: Column( +// children: [ +// Padding( +// padding: const EdgeInsets.all(8.0), +// child: AppExpandableNotifier( +// paddingValue: 8, +// applyBackgroundColor: false, +// applyBackgroundToOnlyHeader: true, +// completeHeaderColor: Colors.white, +// headerRadius: BorderRadius.circular(16), +// headerWidget: HospitalTitle( +// iconUrl: 'assets/images/svg/HMG.svg', +// title: TranslationBase.of(context).hmgHospital, +// isHMC: false, +// itemCount: +// "${widget.patientDoctorAppointmentListHospital.registeredDoctorMap?[key]?.hmgSize ?? 0}", +// ), +// showDropDownIconWithCustomHeader: true, +// bodyWidget: HospitalBodyWidget( +// patientDoctorAppointmentListHospital: +// widget.patientDoctorAppointmentListHospital +// .registeredDoctorMap?[key]?.hmgDoctorList, +// isLiveCareAppointment: widget.isLiveCareAppointment, +// isObGyneAppointment: widget.isObGyneAppointment, +// isDoctorNameSearch: widget.isDoctorNameSearch, +// isDoctorSearchResult: widget.isDoctorSearchResult, +// ), +// ), +// ), +// Padding( +// padding: const EdgeInsets.only( +// bottom: 8.0, left: 8, right: 8), +// child: AppExpandableNotifier( +// paddingValue: 8, +// applyBackgroundColor: false, +// applyBackgroundToOnlyHeader: true, +// completeHeaderColor: Colors.white, +// headerRadius: BorderRadius.circular(16), +// headerWidget: HospitalTitle( +// iconUrl: 'assets/images/svg/HMC.svg', +// title: TranslationBase.of(context).hmcHospital, +// isHMC: true, +// itemCount: +// "${widget.patientDoctorAppointmentListHospital.registeredDoctorMap?[key]?.hmcSize ?? 0}", +// ), +// showDropDownIconWithCustomHeader: true, +// bodyWidget: HospitalBodyWidget( +// patientDoctorAppointmentListHospital: +// widget.patientDoctorAppointmentListHospital +// .registeredDoctorMap?[key]?.hmcDoctorList, +// isLiveCareAppointment: widget.isLiveCareAppointment, +// isObGyneAppointment: widget.isObGyneAppointment, +// isDoctorNameSearch: widget.isDoctorNameSearch, +// isDoctorSearchResult: widget.isDoctorSearchResult, +// ), +// ), +// ), +// ], +// )); diff --git a/lib/pages/BookAppointment/search_result/SearchResultWithTabForHospital.dart b/lib/pages/BookAppointment/search_result/SearchResultWithTabForHospital.dart new file mode 100644 index 00000000..4f0e94cd --- /dev/null +++ b/lib/pages/BookAppointment/search_result/SearchResultWithTabForHospital.dart @@ -0,0 +1,853 @@ +import 'package:diplomaticquarterapp/config/size_config.dart'; +import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; +import 'package:diplomaticquarterapp/models/Appointments/OBGyneProcedureListResponse.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/search_result/ResultByClinic.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/search_result/ResultByDoctors.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/search_result/ResultByFacility.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/search_result/ResultByHospital.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/search_result/ResultByRegion.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/widgets/DoctorView.dart'; +import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; +import 'package:diplomaticquarterapp/services/appointment_services/doctor_response_mapper.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_expandable_notifier.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:provider/provider.dart'; + +import '../../../config/shared_pref_kay.dart'; +import '../../../core/service/client/base_app_client.dart'; + +class SearchResultWithTabForHospital extends StatefulWidget { + List doctorsList = []; + RegionList patientDoctorAppointmentListHospital; + bool isLiveCareAppointment; + bool isObGyneAppointment; + bool isDoctorNameSearch; + OBGyneProcedureListResponse? obGyneProcedureListResponse; + bool isDoctorSearchResult; + + bool isForHospital; + + SearchResultWithTabForHospital({ + required this.doctorsList, + required this.patientDoctorAppointmentListHospital, + this.isObGyneAppointment = false, + this.isDoctorNameSearch = false, + required this.isLiveCareAppointment, + required this.isDoctorSearchResult, + this.obGyneProcedureListResponse, + this.isForHospital = true, + }); + + @override + State createState() => + _SearchResultWithTabForHospitalState(); +} + +class _SearchResultWithTabForHospitalState + extends State { + int _currentIndex = 0; + late PageController _controller; + String selectedRegion = ""; + HospitalsModel? selectedHospital; + bool isHMCSelected = false; + int selectedHospitalIndex = -1; + ScrollController scrollController = ScrollController(); + RegionList? doctorList; + bool nearestAppointment= false; + int clinicId = -1; + + @override + void initState() { + super.initState(); + _controller = new PageController(); + } + + changePageViewIndex(pageIndex) { + _controller.jumpToPage(pageIndex); + // if (scrollController.hasClients) { + // print("it has clients"); + // scrollController.animateTo(pageIndex.toDouble(),curve: Curves.easeOut, + // duration: const Duration(milliseconds: 300),);} + } + + void handleBackClick() { + switch (_currentIndex) { + case 1: + selectedHospitalIndex = -1; + selectedRegion = ""; + doctorList = null; + _currentIndex = 0; + changePageViewIndex(0); + break; + case 2: + selectedHospitalIndex = -1; + doctorList = null; + _currentIndex = 1; + changePageViewIndex(1); + break; + case 3: + selectedHospitalIndex = -1; + doctorList = null; + _currentIndex = 2; + changePageViewIndex(2); + break; + case 4: + _currentIndex = 3; + doctorList = null; + changePageViewIndex(3); + } + } + + @override + Widget build(BuildContext context) { + return SizedBox( + child: widget.patientDoctorAppointmentListHospital.registeredDoctorMap + ?.isNotEmpty == + true + ? SizedBox( + height: SizeConfig.realScreenHeight! * .9, + width: SizeConfig.realScreenWidth, + child: Column(children: [ + Container( + width: double.infinity, + padding: EdgeInsets.only(left: 20, right: 20, top: 12), + child: SizedBox( + height: 100, + child: ListView( + scrollDirection: Axis.horizontal, + controller: scrollController, + children: [ + SizedBox( + width: MediaQuery.of(context).size.width / 5.2, + child: showProgress( + title: TranslationBase.of(context).selectRegion, + status: _currentIndex == 0 + ? TranslationBase.of(context).inPrgress + : _currentIndex > 0 + ? TranslationBase.of(context).completed + : TranslationBase.of(context).locked, + color: _currentIndex == 0 + ? CustomColors.orange + : CustomColors.green, + onTap: () { + setState(() { + selectedHospitalIndex = -1; + selectedRegion = ""; + doctorList = null; + _currentIndex = 0; + changePageViewIndex(0); + nearestAppointment = false; + clinicId = -1; + }); + }, + ), + ), + SizedBox( + width: MediaQuery.of(context).size.width / 5.2, + child: showProgress( + title: TranslationBase.of(context).selectFacitlity, + status: _currentIndex == 1 + ? TranslationBase.of(context).inPrgress + : _currentIndex > 1 + ? TranslationBase.of(context).completed + : TranslationBase.of(context).locked, + color: _currentIndex == 1 + ? CustomColors.orange + : _currentIndex > 1 + ? CustomColors.green + : CustomColors.grey2, + onTap: () { + setState(() { + selectedHospitalIndex = -1; + doctorList = null; + _currentIndex = 1; + changePageViewIndex(1); + nearestAppointment = false; + clinicId = -1; + + }); + }, + ), + ), + SizedBox( + width: MediaQuery.of(context).size.width / 5.2, + child: showProgress( + title: TranslationBase.of(context).selectBranch, + status: _currentIndex == 2 + ? TranslationBase.of(context).inPrgress + : _currentIndex > 1 + ? TranslationBase.of(context).completed + : TranslationBase.of(context).locked, + color: _currentIndex == 2 + ? CustomColors.orange + : _currentIndex > 2 + ? CustomColors.green + : CustomColors.grey2, + onTap: () { + setState(() { + selectedHospitalIndex = -1; + doctorList = null; + _currentIndex = 2; + changePageViewIndex(2); + nearestAppointment = false; + clinicId = -1; + + }); + }, + ), + ), + SizedBox( + width: MediaQuery.of(context).size.width / 5.2, + child: showProgress( + title: TranslationBase.of(context).selectClinic, + status: _currentIndex == 3 + ? TranslationBase.of(context).inPrgress + : _currentIndex > 3 + ? TranslationBase.of(context).completed + : TranslationBase.of(context).locked, + color: _currentIndex == 3 + ? CustomColors.orange + : _currentIndex > 3 + ? CustomColors.green + : CustomColors.grey2, + onTap: () { + setState(() { + doctorList = null; + changePageViewIndex(3); + _currentIndex = 3; + nearestAppointment= false; + clinicId = -1; + + }); + }, + ), + ), + SizedBox( + width: MediaQuery.of(context).size.width / 5.2, + child: showProgress( + title: TranslationBase.of(context).selectDoctor, + status: _currentIndex == + ((widget.isForHospital) ? 4 : 3) + ? TranslationBase.of(context).inPrgress + : TranslationBase.of(context).locked, + color: _currentIndex == + ((widget.isForHospital) ? 4 : 3) + ? CustomColors.orange + : _currentIndex == + ((widget.isForHospital) ? 5 : 4) + ? CustomColors.green + : CustomColors.grey2, + isNeedBorder: false, + onTap: () { + setState(() { + _currentIndex = + ((widget.isForHospital) ? 4 : 3); + changePageViewIndex(_currentIndex); + }); + }, + ), + ), + ], + ), + ), + ), + Padding( + padding: + const EdgeInsetsDirectional.fromSTEB(10.0, 18, 0, 24), + child: Row( + children: [ + (_currentIndex != 0) + ? InkWell( + onTap: () { + handleBackClick(); + }, + child: Padding( + padding: const EdgeInsetsDirectional.fromSTEB( + 0, 0, 04, 0), + child: Icon( + Icons.arrow_back, + color: Theme.of(context).primaryColor, + ), + ), + ) + : mWidth(24), + Text( + getTitle(), + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.w600, + color: Colors.black), + ) + ], + ), + ), + // mHeight(24), + Expanded( + child: PageView( + physics: NeverScrollableScrollPhysics(), + controller: _controller, + onPageChanged: (index) { + setState(() { + _currentIndex = index; + }); + }, + scrollDirection: Axis.horizontal, + children: [ + ResultByRegion( + doctorsList: widget.doctorsList, + patientDoctorAppointmentListHospital: + widget.patientDoctorAppointmentListHospital, + onRegionSelected: (key) { + setState(() { + selectedRegion = key; + _currentIndex = 1; + changePageViewIndex(1); + }); + }), + (selectedRegion != "") + ? ResultByFacility( + doctorsList: widget.doctorsList, + patientDoctorAppointmentListHospital: + widget.patientDoctorAppointmentListHospital, + selectedRegion: selectedRegion, + onFacilitySelected: (isHMCSelected) { + setState(() { + this.isHMCSelected = isHMCSelected; + _currentIndex = 2; + changePageViewIndex(2); + }); + }, + ) + : SizedBox.shrink(), + (selectedRegion != '') + ? ResultByHospital( + doctorsList: widget.doctorsList, + paitientDoctorAppointmentList: (isHMCSelected) + ? widget + .patientDoctorAppointmentListHospital + .registeredDoctorMap![selectedRegion]! + .hmcDoctorList ?? + [] + : widget + .patientDoctorAppointmentListHospital + .registeredDoctorMap?[selectedRegion] + ?.hmgDoctorList ?? + [], + isHMCSelected: isHMCSelected, + isLiveCareAppointment: + widget.isLiveCareAppointment, + isDoctorSearchResult: widget.isDoctorSearchResult, + onHospitalSelected: (hospitalName, index) { + setState(() { + selectedHospitalIndex = index; + selectedHospital = (!isHMCSelected) + ? widget + .patientDoctorAppointmentListHospital + .registeredDoctorMap![selectedRegion]! + .hmgDoctorList![selectedHospitalIndex] + .hospitalList + .first + : widget + .patientDoctorAppointmentListHospital + .registeredDoctorMap![selectedRegion]! + .hmcDoctorList![selectedHospitalIndex] + .hospitalList + .first; + _currentIndex = 3; + changePageViewIndex(3); + }); + }) + : SizedBox.shrink(), + (selectedHospital != null && + selectedRegion != '' && + selectedHospitalIndex != -1) + ? ResultByClinic( + onClinicSelected: (doctorList, clinicId) { + setState(() { + this.nearestAppointment = false; + this.doctorList = doctorList; + _currentIndex = 4; + changePageViewIndex(4); + if(clinicId != null) + this.clinicId = clinicId; + }); + }, + selectedValue: selectedHospital) + : SizedBox.shrink(), + (selectedRegion != '' && + selectedHospitalIndex != -1 && + doctorList != null) + ? ResultByDoctor( + doctorsList: widget.doctorsList, + patientDoctorAppointmentListHospital: + (!isHMCSelected) + ? doctorList! + .registeredDoctorMap![ + selectedRegion]! + .hmgDoctorList! + .first + .patientDoctorAppointmentList ?? + [] + : doctorList! + .registeredDoctorMap?[ + selectedRegion] + ?.hmcDoctorList! + .first + .patientDoctorAppointmentList ?? + [], + isLiveCareAppointment: + widget.isLiveCareAppointment, + isDoctorSearchResult: widget.isDoctorSearchResult, + isObGyneAppointment: widget.isObGyneAppointment, + isDoctorNameSearch: widget.isDoctorNameSearch, + showNearestAppointment: clinicId != -1 , + nearestAppointmentDoctors: nearestAppointment, + refreshDoctorList: (isNearestAppointmentChecked){ + setState(() { + // changePageViewIndex(3); + // _currentIndex = 3; + nearestAppointment= false; + }); + callDoctorsSearchAPI(clinicId, isNearestAppointmentChecked); + }, + + ) + : SizedBox.shrink(), + ], + ), + ), + ]), + ) + : getNoDataWidget(context), + ); + } + + callDoctorsSearchAPI(int clinicID, bool nearestAppointment) { + var isArabic = context.read().isArabic; + int languageID = isArabic ? 1 : 2; + GifLoaderDialogUtils.showMyDialog(context); + List doctorsList = []; + List arr = []; + List arrDistance = []; + List result; + int numAll; + List _patientDoctorAppointmentListHospital = []; + + DoctorsListService service = new DoctorsListService(); + service + .getDoctorsList(clinicID, selectedHospital?.mainProjectID.toString() != "" ? int.parse(selectedHospital?.mainProjectID.toString() ?? "-1") : 0, nearestAppointment, languageID, null) + .then((res) async { + GifLoaderDialogUtils.hideDialog(context); + if (res['MessageStatus'] == 1) { + RegionList regionHospitalList = RegionList(); + + if (res['DoctorList'].length != 0) { + res['DoctorList'].forEach((v) { + doctorsList.add(new DoctorList.fromJson( + v, + )); + }); + + regionHospitalList = await DoctorMapper.getMappedDoctor(doctorsList, isArabic: isArabic); + var lat = await sharedPref.getDouble(USER_LAT); + + var lng = await sharedPref.getDouble(USER_LONG); + var isLocationEnabled = (lat != null && lat != 0.0) && (lng != null && lng != 0.0); + regionHospitalList = await DoctorMapper.sortList(isLocationEnabled, regionHospitalList); + + setState(() { + this.doctorList = regionHospitalList; + _currentIndex = 4; + changePageViewIndex(4); + this.nearestAppointment = nearestAppointment; + }); + } else { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: res['ErrorSearchMsg']); + } + + GifLoaderDialogUtils.hideDialog(context); + // navigateToSearchResults(context, doctorsList, _patientDoctorAppointmentListHospital); + } else { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: res['ErrorEndUserMessage']); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + AppToast.showErrorToast(message: err, localContext: context); + }); + } + String getTitle() { + switch (_currentIndex) { + case 0: + return TranslationBase.of(context).selectRegion; + case 1: + return TranslationBase.of(context).selectFacitlity; + case 2: + return TranslationBase.of(context).selectBranch; + case 3: + return TranslationBase.of(context).selectClinic; + case 4: + return TranslationBase.of(context).selectDoctor; + } + return ""; + } + + Widget showProgress( + {String? title, + String? status, + Color? color, + bool isNeedBorder = true, + Function()? onTap}) { + return InkWell( + onTap: () { + if (status == TranslationBase.of(context).completed) { + onTap?.call(); + } + }, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Container( + width: 26, + height: 26, + decoration: containerRadius(color!, 200), + child: Icon( + Icons.done, + color: Colors.white, + size: 16, + ), + ), + if (isNeedBorder) + Expanded( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: mDivider(Colors.grey), + )), + ], + ), + mHeight(8), + Text( + title!, + style: TextStyle( + fontSize: 10, + fontWeight: FontWeight.w500, + letterSpacing: -0.44, + ), + ), + mHeight(2), + Container( + padding: EdgeInsets.all(5), + decoration: containerRadius(color!.withOpacity(0.2), 4), + child: Text( + status!, + style: TextStyle( + fontSize: 8, + fontWeight: FontWeight.w600, + letterSpacing: -0.32, + color: color, + ), + ), + ), + ], + ) + ], + ), + ); + } +} + +class HospitalBodyWidget extends StatelessWidget { + final List? + patientDoctorAppointmentListHospital; + final bool isLiveCareAppointment; + final bool isObGyneAppointment; + final bool isDoctorNameSearch; + final bool isDoctorSearchResult; + final OBGyneProcedureListResponse? obGyneProcedureListResponse; + + const HospitalBodyWidget({ + super.key, + this.patientDoctorAppointmentListHospital, + required this.isLiveCareAppointment, + required this.isObGyneAppointment, + required this.isDoctorNameSearch, + required this.isDoctorSearchResult, + this.obGyneProcedureListResponse, + }); + + @override + Widget build(BuildContext context) { + return ListView.separated( + addAutomaticKeepAlives: true, + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + itemCount: patientDoctorAppointmentListHospital?.length ?? 0, + separatorBuilder: (context, index) { + return Container( + height: 12, + margin: EdgeInsets.only(left: 21, right: 21), + ); + }, + itemBuilder: (context, index) { + return AppExpandableNotifier( + applyBackgroundColor: false, + widgetColor: CustomColors.appBackgroudGrey2Color, + title: (patientDoctorAppointmentListHospital?[index].distanceInKMs != + "0") + ? patientDoctorAppointmentListHospital![index].filterName! + + " - " + + patientDoctorAppointmentListHospital![index].distanceInKMs! + + " " + + TranslationBase.of(context).km + : patientDoctorAppointmentListHospital![index].filterName, + projectTitleTop: + patientDoctorAppointmentListHospital![index].projectTopName, + projectTitleBottom: (patientDoctorAppointmentListHospital![index] + .distanceInKMs != + "0") + ? patientDoctorAppointmentListHospital![index] + .projectBottomName + .toString() + + " - " + + patientDoctorAppointmentListHospital![index].distanceInKMs! + + " " + + TranslationBase.of(context).km + : patientDoctorAppointmentListHospital![index] + .projectBottomName + .toString(), + isTitleSingleLine: false, + isDoctorSearchResult: isDoctorSearchResult, + isExpand: + patientDoctorAppointmentListHospital?.length == 1 ? true : false, + bodyWidget: ListView.separated( + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + padding: + EdgeInsets.only(bottom: 10, top: 10, left: 21, right: 21), + itemBuilder: (context, _index) { + // print("the index of patientDoctorAppointmentList is ${_index}"); + // print("the index of parent is ${index}"); + final doctor = patientDoctorAppointmentListHospital![index] + .patientDoctorAppointmentList![_index]; + // print('the doctor is ${doctor.toJson()}'); + return DoctorView( + doctor: doctor, + isLiveCareAppointment: isLiveCareAppointment, + isObGyneAppointment: isObGyneAppointment, + isDoctorNameSearch: isDoctorNameSearch, + obGyneProcedureListResponse: obGyneProcedureListResponse, + isShowDate: false, + onTap: () { + context + .read() + .analytics + .appointment + .book_appointment_select_doctor( + appointment_type: 'regular', doctor: doctor); + }); + }, + separatorBuilder: (context, index) => SizedBox(height: 14), + itemCount: patientDoctorAppointmentListHospital?[index] + .patientDoctorAppointmentList + ?.length ?? + 0), + ); + }, + ); + } +} + +class RegionTitle extends StatelessWidget { + final String title; + final String hmcCount; + final String hmgCount; + + const RegionTitle( + {super.key, + required this.title, + required this.hmcCount, + required this.hmgCount}); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title, + style: TextStyle( + fontSize: 22, color: Colors.black, fontWeight: FontWeight.w700), + ), + SizedBox( + height: 8, + ), + Row( + children: [ + Text( + "${TranslationBase.of(context).HospitalString(num.parse(hmgCount)).replaceAll("@", hmgCount)} ,", + style: TextStyle( + fontSize: 14, + color: Color(0xFFD02127), + fontWeight: FontWeight.w600), + ), + SizedBox( + width: 8, + ), + Text( + "${TranslationBase.of(context).MedicalCenterString(num.parse(hmcCount)).replaceAll("@", hmcCount)}", + style: TextStyle( + fontSize: 14, + color: Color(0xFF40ACC9), + fontWeight: FontWeight.w600), + ), + ], + ), + ], + ), + ); + } +} + +class HospitalTitle extends StatelessWidget { + final String title; + final String iconUrl; + final bool isHMC; + final String itemCount; + + const HospitalTitle( + {super.key, + required this.title, + required this.iconUrl, + required this.isHMC, + required this.itemCount}); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + SvgPicture.asset(iconUrl), + SizedBox( + width: 8, + ), + Text( + title, + style: TextStyle( + fontSize: 18, + color: isHMC ? Color(0xFF40ACC9) : Color(0xFFD02127), + fontWeight: FontWeight.w600), + ), + ], + ), + SizedBox( + height: 6, + ), + Text( + isHMC + ? "${TranslationBase.of(context).MedicalCenterString(num.parse(itemCount)).replaceAll("@", itemCount)}" + : "${TranslationBase.of(context).HospitalString(num.parse(itemCount)).replaceAll("@", itemCount)}", + style: TextStyle( + fontSize: 12, color: Colors.black, fontWeight: FontWeight.w600), + ), + ], + ), + ); + } +} + +///todo the current content of the application +/// return AppExpandableNotifier( +// paddingValue: 10, +// applyBackgroundToOnlyHeader: true, +// completeHeaderColor: CustomColors.appBackgroudGrey2Color, +// headerWidget: RegionTitle( +// title: key, +// hmcCount: +// "${widget.patientDoctorAppointmentListHospital.registeredDoctorMap?[key]?.hmcSize ?? 0}", +// hmgCount: +// "${widget.patientDoctorAppointmentListHospital.registeredDoctorMap?[key]?.hmgSize ?? 0}", +// ), +// showDropDownIconWithCustomHeader: true, +// isTitleSingleLine: false, +// isDoctorSearchResult: widget.isDoctorSearchResult, +// widgetColor: Color(0xFFF8F8F8), +// bodyWidget: Column( +// children: [ +// Padding( +// padding: const EdgeInsets.all(8.0), +// child: AppExpandableNotifier( +// paddingValue: 8, +// applyBackgroundColor: false, +// applyBackgroundToOnlyHeader: true, +// completeHeaderColor: Colors.white, +// headerRadius: BorderRadius.circular(16), +// headerWidget: HospitalTitle( +// iconUrl: 'assets/images/svg/HMG.svg', +// title: TranslationBase.of(context).hmgHospital, +// isHMC: false, +// itemCount: +// "${widget.patientDoctorAppointmentListHospital.registeredDoctorMap?[key]?.hmgSize ?? 0}", +// ), +// showDropDownIconWithCustomHeader: true, +// bodyWidget: HospitalBodyWidget( +// patientDoctorAppointmentListHospital: +// widget.patientDoctorAppointmentListHospital +// .registeredDoctorMap?[key]?.hmgDoctorList, +// isLiveCareAppointment: widget.isLiveCareAppointment, +// isObGyneAppointment: widget.isObGyneAppointment, +// isDoctorNameSearch: widget.isDoctorNameSearch, +// isDoctorSearchResult: widget.isDoctorSearchResult, +// ), +// ), +// ), +// Padding( +// padding: const EdgeInsets.only( +// bottom: 8.0, left: 8, right: 8), +// child: AppExpandableNotifier( +// paddingValue: 8, +// applyBackgroundColor: false, +// applyBackgroundToOnlyHeader: true, +// completeHeaderColor: Colors.white, +// headerRadius: BorderRadius.circular(16), +// headerWidget: HospitalTitle( +// iconUrl: 'assets/images/svg/HMC.svg', +// title: TranslationBase.of(context).hmcHospital, +// isHMC: true, +// itemCount: +// "${widget.patientDoctorAppointmentListHospital.registeredDoctorMap?[key]?.hmcSize ?? 0}", +// ), +// showDropDownIconWithCustomHeader: true, +// bodyWidget: HospitalBodyWidget( +// patientDoctorAppointmentListHospital: +// widget.patientDoctorAppointmentListHospital +// .registeredDoctorMap?[key]?.hmcDoctorList, +// isLiveCareAppointment: widget.isLiveCareAppointment, +// isObGyneAppointment: widget.isObGyneAppointment, +// isDoctorNameSearch: widget.isDoctorNameSearch, +// isDoctorSearchResult: widget.isDoctorSearchResult, +// ), +// ), +// ), +// ], +// )); diff --git a/lib/pages/BookAppointment/waiting_appointment/waiting_appointment_info.dart b/lib/pages/BookAppointment/waiting_appointment/waiting_appointment_info.dart new file mode 100644 index 00000000..f1f8d934 --- /dev/null +++ b/lib/pages/BookAppointment/waiting_appointment/waiting_appointment_info.dart @@ -0,0 +1,113 @@ +import 'package:diplomaticquarterapp/pages/BookAppointment/waiting_appointment/waiting_appointment_verification.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +class WaitingAppointmentInfo extends StatelessWidget { + const WaitingAppointmentInfo({super.key}); + + @override + Widget build(BuildContext context) { + return AppScaffold( + appBarTitle: TranslationBase.of(context).waitingAppointment, + isShowAppBar: true, + isShowDecPage: false, + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: CustomColors.appBackgroudGreyColor, + body: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: MediaQuery.of(context).size.width, + decoration: containerRadius(Colors.white, 10), + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SvgPicture.asset( + "assets/images/new/waitingAppo.svg", + width: 52.0, + height: 52.0, + ), + mHeight(11), + Text( + TranslationBase.of(context).whatWaitingAppointment, + maxLines: 1, + style: TextStyle(fontSize: 17, fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(11), + Container( + width: MediaQuery.of(context).size.width * 0.8, + child: Text( + TranslationBase.of(context).waitingAppointmentText1, + style: TextStyle(fontSize: 14, color: CustomColors.textDarkColor, letterSpacing: -1.04, height: 35 / 24, overflow: TextOverflow.clip), + ), + ), + mHeight(18), + Container( + width: MediaQuery.of(context).size.width * 0.8, + child: Text( + TranslationBase.of(context).waitingAppointmentText2, + style: TextStyle(fontSize: 14, color: CustomColors.textDarkColor, letterSpacing: -1.04, height: 35 / 24, overflow: TextOverflow.clip), + ), + ), + mHeight(24), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Icon( + Icons.warning, + size: 20, + color: Color(0xffA78618), + ), + mWidth(10), + Container( + width: MediaQuery.of(context).size.width * 0.7, + child: Text( + TranslationBase.of(context).waitingAppointmentText3, + style: TextStyle( + fontSize: 14, fontStyle: FontStyle.italic, fontWeight: FontWeight.w600, color: Color(0xffA78618), letterSpacing: -1.04, height: 35 / 24, overflow: TextOverflow.clip), + ), + ), + ], + ), + ], + ), + ), + ), + ], + ), + ), + ), + bottomSheet: Container( + height: 80, + color: CustomColors.white, + padding: EdgeInsets.fromLTRB(12.0, 12.0, 12.0, 25.0), + child: Container( + child: DefaultButton( + TranslationBase.of(context).continues, + () { + Navigator.push( + context, + FadePage( + page: WaitingAppointmentVerification(), + ), + ); + }, + color: CustomColors.accentColor, + ), + ), + ), + ); + } +} diff --git a/lib/pages/BookAppointment/waiting_appointment/waiting_appointment_verification.dart b/lib/pages/BookAppointment/waiting_appointment/waiting_appointment_verification.dart new file mode 100644 index 00000000..6853c6d9 --- /dev/null +++ b/lib/pages/BookAppointment/waiting_appointment/waiting_appointment_verification.dart @@ -0,0 +1,292 @@ +import 'package:barcode_scan2/barcode_scan2.dart'; +import 'package:diplomaticquarterapp/core/model/privilege/ProjectDetailListModel.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/BookConfirm.dart'; +import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/location_util.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:diplomaticquarterapp/widgets/nfc/nfc_reader_sheet.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:intl/intl.dart'; +import 'package:provider/provider.dart'; + +import '../../../uitl/utils.dart'; + +class WaitingAppointmentVerification extends StatefulWidget { + const WaitingAppointmentVerification({super.key}); + + @override + State createState() => _WaitingAppointmentVerificationState(); +} + +class _WaitingAppointmentVerificationState extends State { + String selectedVerificationMethod = "QR"; + + late ProjectViewModel projectViewModel; + late LocationUtils locationUtils; + ProjectDetailListModel projectDetailListModel = ProjectDetailListModel(); + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + return AppScaffold( + appBarTitle: TranslationBase.of(context).waitingAppointment, + isShowAppBar: true, + isShowDecPage: false, + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: CustomColors.appBackgroudGreyColor, + body: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + mHeight(11), + Text( + TranslationBase.of(context).waitingAppointmentVerificationMethod, + maxLines: 1, + style: TextStyle(fontSize: 18, fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.04, height: 35 / 24), + ), + mHeight(12), + Container( + width: MediaQuery.of(context).size.width, + decoration: containerRadius(Colors.white, 10), + child: Padding( + padding: const EdgeInsets.fromLTRB(16.0, 0.0, 16.0, 0.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + InkWell( + onTap: () { + setState(() { + selectedVerificationMethod = "QR"; + }); + }, + child: Row( + children: [ + Container( + width: 20, + height: 20, + decoration: containerColorRadiusBorderWidth(selectedVerificationMethod == "QR" ? CustomColors.accentColor : Colors.transparent, 100, Colors.grey, 0.5), + ), + mWidth(6), + Container( + height: 40.0, + width: 40.0, + padding: EdgeInsets.all(7.0), + child: SvgPicture.asset( + "assets/images/new/services/qr_code.svg", + ), + ), + Text( + TranslationBase.of(context).pharmaLiveCareScanQR, + style: TextStyle(fontSize: 14, color: CustomColors.textDarkColor, fontWeight: FontWeight.w600, letterSpacing: -1.04, height: 35 / 24, overflow: TextOverflow.clip), + ), + ], + ), + ), + Divider(), + InkWell( + onTap: () { + setState(() { + selectedVerificationMethod = "NFC"; + }); + }, + child: Row( + children: [ + Container( + width: 20, + height: 20, + decoration: containerColorRadiusBorderWidth(selectedVerificationMethod == "NFC" ? CustomColors.accentColor : Colors.transparent, 100, Colors.grey, 0.5), + ), + mWidth(6), + Container( + height: 40.0, + width: 40.0, + padding: EdgeInsets.all(7.0), + child: SvgPicture.asset( + "assets/images/new/services/contactless.svg", + ), + ), + Text( + TranslationBase.of(context).scanNFC, + style: TextStyle(fontSize: 14, color: CustomColors.textDarkColor, fontWeight: FontWeight.w600, letterSpacing: -1.04, height: 35 / 24, overflow: TextOverflow.clip), + ), + ], + ), + ), + Divider(), + InkWell( + onTap: () { + setState(() { + selectedVerificationMethod = "Location"; + }); + }, + child: Row( + children: [ + Container( + width: 20, + height: 20, + decoration: containerColorRadiusBorderWidth(selectedVerificationMethod == "Location" ? CustomColors.accentColor : Colors.transparent, 100, Colors.grey, 0.5), + ), + mWidth(6), + Container( + height: 40.0, + width: 40.0, + padding: EdgeInsets.all(7.0), + child: SvgPicture.asset( + "assets/images/new/services/location.svg", + ), + ), + Text( + TranslationBase.of(context).checkInViaLocation, + style: TextStyle(fontSize: 14, color: CustomColors.textDarkColor, fontWeight: FontWeight.w600, letterSpacing: -1.04, height: 35 / 24, overflow: TextOverflow.clip), + ), + ], + ), + ), + mHeight(6), + ], + ), + ), + ), + mHeight(12), + Container( + width: MediaQuery.of(context).size.width, + decoration: containerRadius(Colors.white, 10), + child: Padding( + padding: const EdgeInsets.fromLTRB(16.0, 0.0, 16.0, 0.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + mHeight(12), + Text( + TranslationBase.of(context).howToUseVerificationMethod, + maxLines: 1, + style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -1.04, height: 35 / 24), + ), + mHeight(12), + Image.asset( + 'assets/images/new/NFCCheckIn_QR_gps_HMG.png', + fit: BoxFit.fitWidth, + width: MediaQuery.of(context).size.width, + ), + mHeight(12), + ], + ), + ), + ), + ], + ), + ), + ), + bottomSheet: Container( + height: 80, + color: CustomColors.white, + padding: EdgeInsets.fromLTRB(12.0, 12.0, 12.0, 25.0), + child: Container( + child: DefaultButton( + TranslationBase.of(context).continues, + () { + startVerification(); + }, + color: CustomColors.accentColor, + ), + ), + ), + ); + } + + startVerification() { + switch (selectedVerificationMethod) { + case "QR": + startQRCodeScan(); + break; + case "NFC": + startNFCScan(); + break; + case "Location": + startLocationCheckIn(); + break; + } + } + + checkScannedNFCAndQRCode(String nfcId) { + GifLoaderDialogUtils.showMyDialog(context); + DoctorsListService service = new DoctorsListService(); + service.checkScannedNFCAndQRCode(nfcId, projectViewModel.waitingAppointmentDoctor!.projectID!).then((res) { + GifLoaderDialogUtils.hideDialog(context); + projectViewModel.setWaitingAppointmentNFCCode(nfcId); + if (res["returnValue"] == 1) { + navigateToBookConfirm(context); + } else { + AppToast.showErrorToast(message: "Invalid verification point scanned."); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } + + Future navigateToBookConfirm(context) async { + final DateFormat formatter = DateFormat('yyyy-MM-dd'); + Navigator.push( + context, + FadePage( + page: BookConfirm( + doctor: projectViewModel.waitingAppointmentDoctor!, + isLiveCareAppointment: false, + selectedDate: formatter.format(DateTime.now()), + selectedTime: TranslationBase.of(context).waitingAppointment, + initialSlotDuration: 15, + isWalkinAppointment: true, + ), + ), + ); + } + + startLocationCheckIn() async { + locationUtils = new LocationUtils(isShowConfirmDialog: true, context: context); + locationUtils.getCurrentLocation(callBack: (value) { + projectDetailListModel = Utils.getProjectDetailObj(projectViewModel, projectViewModel.waitingAppointmentProjectID); + double dist = Utils.distance(value.latitude, value.longitude, double.parse(projectDetailListModel.latitude!), double.parse(projectDetailListModel.longitude!)).ceilToDouble() * 1000; + projectViewModel.setWaitingAppointmentNFCCode(projectDetailListModel.checkInQrCode!); + print(dist); + if (dist <= projectDetailListModel.geofenceRadius!) { + navigateToBookConfirm(context); + } else { + AppToast.showErrorToast(message: TranslationBase.of(context).locationCheckInError); + } + }); + } + + startNFCScan() { + Future.delayed(const Duration(milliseconds: 500), () { + showNfcReader(context, onNcfScan: (String nfcId) { + Future.delayed(const Duration(milliseconds: 100), () { + checkScannedNFCAndQRCode(nfcId); + }); + }, onCancel: () { + // Navigator.of(context).pop(); + // locator().todoList.to_do_list_nfc_cancel(widget.appointment!); + }); + }); + } + + startQRCodeScan() async { + String onlineCheckInQRCode = (await BarcodeScanner.scan().then((value) => value.rawContent)); + if (onlineCheckInQRCode != "") { + checkScannedNFCAndQRCode(onlineCheckInQRCode); + } else {} + } +} diff --git a/lib/pages/BookAppointment/widgets/BranchView.dart b/lib/pages/BookAppointment/widgets/BranchView.dart index 747775d5..3312b337 100644 --- a/lib/pages/BookAppointment/widgets/BranchView.dart +++ b/lib/pages/BookAppointment/widgets/BranchView.dart @@ -14,7 +14,7 @@ class BranchView extends StatefulWidget { final int num; const BranchView( - {Key key, this.doctorsList, this.result, this.resultDistance, this.num}) + {Key? key, required this.doctorsList, required this.result, required this.resultDistance, required this.num}) : super(key: key); @override @@ -45,14 +45,14 @@ class _BranchViewState extends State { } class ExpandableListView extends StatefulWidget { - final List result2; - final List resultDistance; - final List doctorsList2; + final List? result2; + final List? resultDistance; + final List? doctorsList2; final val; static int doctorListheight = 0; - final bool isExpanded; + final bool? isExpanded; const ExpandableListView( - {Key key, + {Key? key, this.result2, this.resultDistance, this.val, @@ -69,8 +69,8 @@ class _ExpandableListViewState extends State { @override void initState() { setState(() { - expandFlag = widget.isExpanded; - setDoctorViewHeight(widget.result2[widget.val].toString()); + expandFlag = widget.isExpanded!; + setDoctorViewHeight(widget.result2![widget.val].toString()); }); super.initState(); } @@ -98,10 +98,10 @@ class _ExpandableListViewState extends State { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ new Text( - widget.result2[widget.val].toString() + + widget.result2![widget.val].toString() + " " + getProjectDistance( - widget.resultDistance[widget.val].toString()), + widget.resultDistance![widget.val].toString()), style: new TextStyle( fontWeight: FontWeight.bold, color: Colors.black), ), @@ -128,7 +128,7 @@ class _ExpandableListViewState extends State { expandFlag = !expandFlag; if (expandFlag == true) { setDoctorViewHeight( - widget.result2[widget.val].toString()); + widget.result2![widget.val].toString()); } }); }), @@ -143,13 +143,13 @@ class _ExpandableListViewState extends State { shrinkWrap: true, physics: ScrollPhysics(), padding: EdgeInsets.all(0.0), - itemCount: widget.doctorsList2.length, + itemCount: widget.doctorsList2!.length, itemBuilder: (context, index) { - return widget.result2[widget.val].toString() == - widget.doctorsList2[index].projectName.toString() + return widget.result2![widget.val].toString() == + widget.doctorsList2![index].projectName.toString() ? DoctorView( //AJ note - doctor: widget.doctorsList2[index], + doctor: widget.doctorsList2![index], isLiveCareAppointment: false, // widget.doctorsList2[index] ) @@ -166,7 +166,7 @@ class _ExpandableListViewState extends State { setDoctorViewHeight(name) { ExpandableListView.doctorListheight = - widget.doctorsList2.where((e) => e.projectName == name).toList().length; + widget.doctorsList2!.where((e) => e.projectName == name).toList().length; } String getProjectDistance(String distance) { @@ -188,7 +188,7 @@ class ExpandableContainer extends StatelessWidget { final Widget child; ExpandableContainer({ - @required this.child, + required this.child, this.collapsedHeight = 0.0, this.expandedHeight = 300.0, this.expanded = true, diff --git a/lib/pages/BookAppointment/widgets/CardBottom.dart b/lib/pages/BookAppointment/widgets/CardBottom.dart index e982d854..a50faf82 100644 --- a/lib/pages/BookAppointment/widgets/CardBottom.dart +++ b/lib/pages/BookAppointment/widgets/CardBottom.dart @@ -20,7 +20,7 @@ class CardBottom extends StatelessWidget { decoration: BoxDecoration( boxShadow: [ BoxShadow( - color: Colors.grey[300], + color: Colors.grey[300]!, blurRadius: 3.0, spreadRadius: 0.0, // offset: Offset(2.0), // shadow direction: bottom right diff --git a/lib/pages/BookAppointment/widgets/CardCommon.dart b/lib/pages/BookAppointment/widgets/CardCommon.dart index ce26200d..f871a7d6 100644 --- a/lib/pages/BookAppointment/widgets/CardCommon.dart +++ b/lib/pages/BookAppointment/widgets/CardCommon.dart @@ -11,10 +11,10 @@ class CardCommon extends StatelessWidget { final type; const CardCommon( - {@required this.image, - @required this.text, - @required this.subText, - @required this.type}); + {required this.image, + required this.text, + required this.subText, + required this.type}); @override Widget build(BuildContext context) { @@ -25,7 +25,7 @@ class CardCommon extends StatelessWidget { child: Container( margin: EdgeInsets.fromLTRB(9.0, 9.0, 9.0, 9.0), decoration: BoxDecoration(boxShadow: [ - BoxShadow(color: Colors.grey[400], blurRadius: 2.0, spreadRadius: 0.0) + BoxShadow(color: Colors.grey[400]!, blurRadius: 2.0, spreadRadius: 0.0) ], borderRadius: BorderRadius.circular(10), color: Colors.white), child: Column( crossAxisAlignment: CrossAxisAlignment.start, diff --git a/lib/pages/BookAppointment/widgets/CardHome.dart b/lib/pages/BookAppointment/widgets/CardHome.dart index 551c9cf4..5ee62977 100644 --- a/lib/pages/BookAppointment/widgets/CardHome.dart +++ b/lib/pages/BookAppointment/widgets/CardHome.dart @@ -7,10 +7,10 @@ class CardHome extends StatelessWidget { final textColor; const CardHome( - {@required this.image, - @required this.backgroundImage, - @required this.text, - @required this.textColor}); + {required this.image, + required this.backgroundImage, + required this.text, + required this.textColor}); @override Widget build(BuildContext context) { @@ -22,7 +22,7 @@ class CardHome extends StatelessWidget { decoration: BoxDecoration( boxShadow: [ BoxShadow( - color: Colors.grey[400], + color: Colors.grey[400]!, blurRadius: 2.0, spreadRadius: 0.0 ) diff --git a/lib/pages/BookAppointment/widgets/DentalComplaintCard.dart b/lib/pages/BookAppointment/widgets/DentalComplaintCard.dart index 02d40b3f..bfd0c60c 100644 --- a/lib/pages/BookAppointment/widgets/DentalComplaintCard.dart +++ b/lib/pages/BookAppointment/widgets/DentalComplaintCard.dart @@ -1,19 +1,31 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/DentalChiefComplaintsModel.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; import 'package:diplomaticquarterapp/pages/BookAppointment/SearchResults.dart'; +import 'package:diplomaticquarterapp/services/appointment_services/doctor_response_mapper.dart'; import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; // ignore: must_be_immutable class DentalComplaintCard extends StatefulWidget { final ListDentalChiefComplain listDentalChiefComplain; + late Function logAnalytics; var languageID; + Function? onSelectedMethod; + bool isDoctorNameSearch; + bool isFromHospitalSearchPage; + Function(RegionList)? onDoctorFetched; - DentalComplaintCard( - {@required this.listDentalChiefComplain, this.languageID}); + DentalComplaintCard({required this.listDentalChiefComplain, + this.languageID, + this.onSelectedMethod, + this.isDoctorNameSearch = false, + this.isFromHospitalSearchPage = false, + this.onDoctorFetched}); @override _DentalComplaintCardState createState() => _DentalComplaintCardState(); @@ -25,38 +37,32 @@ class _DentalComplaintCardState extends State { return Container( child: InkWell( onTap: () { - getChiefComplaintsList(); + if (widget.logAnalytics != null) widget.logAnalytics(); + // if(widget.isDoctorNameSearch) { + // widget.onSelectedMethod(); + // } else { + if (widget.isFromHospitalSearchPage) { + getChiefComplaintsDoctorMappedList(); + } else + getChiefComplaintsList(); + // } }, - child: Card( - color: Colors.white, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - ), - child: Row( + child: Container( + width: double.infinity, + padding: EdgeInsets.all(14.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.max, children: [ Container( - width: MediaQuery.of(context).size.width * 0.85, - padding: EdgeInsets.all(12.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - children: [ - Container( - child: Text(widget.listDentalChiefComplain.name, - style: - TextStyle(fontSize: 16.0, color: Colors.black)), - ), - ], - ), - ), - Container( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - children: [ - Icon(Icons.arrow_forward_ios, - size: 20.0, color: Colors.black54), - ], + child: Text( + widget.listDentalChiefComplain!.name!, + style: TextStyle( + fontSize: 16.0, + color: Colors.black, + letterSpacing: -0.64, + fontWeight: FontWeight.w600, + ), ), ), ], @@ -67,16 +73,13 @@ class _DentalComplaintCardState extends State { } getChiefComplaintsList() { + int languageID = Provider.of(context, listen: false).isArabic ? 1 : 2; List doctorsList = []; - List _patientDoctorAppointmentListHospital = - List(); + List _patientDoctorAppointmentListHospital = []; GifLoaderDialogUtils.showMyDialog(context); ClinicListService service = new ClinicListService(); - service - .getChiefComplaintDoctorList(widget.listDentalChiefComplain.iD, - widget.listDentalChiefComplain.projectID, context) - .then((res) { + service.getChiefComplaintDoctorList(widget.listDentalChiefComplain!.iD!, widget.listDentalChiefComplain.projectID!, languageID, context).then((res) { GifLoaderDialogUtils.hideDialog(context); if (res['MessageStatus'] == 1) { print(res['List_DentalDoctorChiefComplaintMapping']); @@ -87,31 +90,24 @@ class _DentalComplaintCardState extends State { }); doctorsList.forEach((element) { - List doctorByHospital = - _patientDoctorAppointmentListHospital - .where( - (elementClinic) => - elementClinic.filterName == element.projectName, - ) - .toList(); + List doctorByHospital = _patientDoctorAppointmentListHospital + .where( + (elementClinic) => elementClinic.filterName == element.projectName, + ) + .toList(); if (doctorByHospital.length != 0) { - _patientDoctorAppointmentListHospital[ - _patientDoctorAppointmentListHospital - .indexOf(doctorByHospital[0])] - .patientDoctorAppointmentList - .add(element); + _patientDoctorAppointmentListHospital[_patientDoctorAppointmentListHospital.indexOf(doctorByHospital[0])].patientDoctorAppointmentList!.add(element); } else { - _patientDoctorAppointmentListHospital.add( - PatientDoctorAppointmentList( - filterName: element.projectName, - distanceInKMs: - element.projectDistanceInKiloMeters.toString(), - patientDoctorAppointment: element)); + _patientDoctorAppointmentListHospital.add(PatientDoctorAppointmentList( + filterName: element.projectName, + distanceInKMs: element.projectDistanceInKiloMeters.toString(), + projectTopName: element.projectTopName, + projectBottomName: element.projectBottomName, + patientDoctorAppointment: element)); } }); - navigateToSearchResults( - context, doctorsList, _patientDoctorAppointmentListHospital); + navigateToSearchResults(context, doctorsList, _patientDoctorAppointmentListHospital); }); } else { AppToast.showErrorToast(message: res['ErrorEndUserMessage']); @@ -122,17 +118,44 @@ class _DentalComplaintCardState extends State { }); } - Future navigateToSearchResults( - context, - List docList, - List - patientDoctorAppointmentListHospital) async { - Navigator.push( - context, - FadePage( - page: SearchResults( - doctorsList: docList, - patientDoctorAppointmentListHospital: - patientDoctorAppointmentListHospital))); + Future navigateToSearchResults(context, List docList, List patientDoctorAppointmentListHospital) async { + Navigator.push(context, FadePage(page: SearchResults(doctorsList: docList, patientDoctorAppointmentListHospital: patientDoctorAppointmentListHospital, isLiveCareAppointment: false, isDoctorSearchResult: true,))); + } + + void getChiefComplaintsDoctorMappedList() { + var isArabic = context.read().isArabic; + int languageID = + Provider.of(context, listen: false).isArabic ? 1 : 2; + List doctorsList = []; + List _patientDoctorAppointmentListHospital = + []; + + GifLoaderDialogUtils.showMyDialog(context); + ClinicListService service = new ClinicListService(); + service + .getChiefComplaintDoctorList(widget.listDentalChiefComplain!.iD!, + widget.listDentalChiefComplain.projectID!, languageID, context) + .then((res) async { + GifLoaderDialogUtils.hideDialog(context); + if (res['MessageStatus'] == 1) { + RegionList regionHospitalList = RegionList(); + print(res['List_DentalDoctorChiefComplaintMapping']); + setState(() async { + doctorsList.clear(); + res['List_DentalDoctorChiefComplaintMapping'].forEach((v) { + doctorsList.add(new DoctorList.fromJson(v)); + }); + + regionHospitalList = await DoctorMapper.getMappedDoctor(doctorsList, + isArabic: isArabic); + widget.onDoctorFetched?.call(regionHospitalList); + }); + } else { + AppToast.showErrorToast(message: res['ErrorEndUserMessage']); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); } } diff --git a/lib/pages/BookAppointment/widgets/DoctorView.dart b/lib/pages/BookAppointment/widgets/DoctorView.dart index bb6fccab..5e5d2775 100644 --- a/lib/pages/BookAppointment/widgets/DoctorView.dart +++ b/lib/pages/BookAppointment/widgets/DoctorView.dart @@ -1,127 +1,202 @@ +import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorProfile.dart'; +import 'package:diplomaticquarterapp/models/Appointments/OBGyneProcedureListResponse.dart'; +import 'package:diplomaticquarterapp/models/Appointments/SearchInfoModel.dart'; +import 'package:diplomaticquarterapp/models/Clinics/ClinicListResponse.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/DentalComplaints.dart'; +import 'package:diplomaticquarterapp/pages/ToDoList/ObGyne/ObGyne-TimeSlots.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/avatar/large_avatar.dart'; +import 'package:diplomaticquarterapp/widgets/dragable_sheet.dart'; +import 'package:diplomaticquarterapp/widgets/my_rich_text.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; -import 'package:rating_bar/rating_bar.dart'; +import 'package:flutter_rating_bar/flutter_rating_bar.dart'; +import 'package:provider/provider.dart'; import '../DoctorProfile.dart'; -class DoctorView extends StatelessWidget { +class DoctorView extends StatefulWidget { final DoctorList doctor; - bool isLiveCareAppointment; + bool? isLiveCareAppointment; + bool isObGyneAppointment; + bool isShowFlag; + bool isDoctorNameSearch; + bool isContinueDentalPlan; + OBGyneProcedureListResponse? obGyneProcedureListResponse; + final VoidCallback? onTap; + bool isShowDate; - DoctorView({@required this.doctor, @required this.isLiveCareAppointment}); + DoctorView( + {required this.doctor, + this.isLiveCareAppointment, + this.isObGyneAppointment = false, + this.isDoctorNameSearch = false, + this.isContinueDentalPlan = false, + this.isShowFlag = true, + this.isShowDate = true, + this.onTap, + this.obGyneProcedureListResponse}); + + @override + State createState() => _DoctorViewState(); +} + +class _DoctorViewState extends State { + late ProjectViewModel projectViewModel; @override Widget build(BuildContext context) { + projectViewModel = Provider.of(context); return InkWell( onTap: () { - getDoctorsProfile(context, doctor); + if (widget.isObGyneAppointment) { + next(context); + } else { + // if (doctor.clinicID == 17 && isDoctorNameSearch) { + // showDentalChiefComplaintsList(context); + // } else + if (widget.isShowFlag) { + getDoctorsProfile(context, widget.doctor, isAppo: true, isContinueDentalPlan: widget.isContinueDentalPlan); + } + (widget.onTap ?? () {})(); // For log analytics of doctor click from book appointment + } }, - child: Card( - margin: EdgeInsets.fromLTRB(10.0, 16.0, 10.0, 8.0), - color: Colors.white, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - ), - child: Container( - decoration: BoxDecoration(), - padding: EdgeInsets.all(7.0), - width: MediaQuery.of(context).size.width, - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Expanded( - flex: 1, - child: ClipRRect( - borderRadius: BorderRadius.circular(100.0), - child: Image.network(this.doctor.doctorImageURL, - fit: BoxFit.fill, height: 60.0, width: 60.0), - ), + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.all( + Radius.circular(10.0), + ), + boxShadow: [ + BoxShadow( + color: Color(0xff000000).withOpacity(.05), + //spreadRadius: 5, + blurRadius: 5, + offset: Offset(0, -3), ), - Expanded( - flex: 4, - child: Container( - width: MediaQuery.of(context).size.width * 0.55, - margin: EdgeInsets.fromLTRB(20.0, 10.0, 10.0, 0.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - if (doctor.doctorTitle != null) - Text(this.doctor.doctorTitle + " " + this.doctor.name, - style: TextStyle( - fontSize: 14.0, - color: Colors.grey[700], - letterSpacing: 1.0)), - Container( - margin: EdgeInsets.only(top: 3.0), - child: Text( - this.doctor.clinicName != null - ? this.doctor.clinicName - : "", - style: TextStyle( - fontSize: 12.0, - color: Colors.grey[600], - letterSpacing: 1.0)), - ), - Container( - margin: EdgeInsets.only(top: 3.0), - child: Text(this.doctor.projectName, - style: TextStyle( - fontSize: 12.0, - color: Colors.grey[600], - letterSpacing: 1.0)), - ), - if (doctor.speciality != null) - Container( - margin: EdgeInsets.only(top: 3.0, bottom: 3.0), - child: Text( - getDoctorSpeciality(this.doctor.speciality) - .trim(), - style: TextStyle( - fontSize: 12.0, - color: Colors.grey[600], - letterSpacing: 1.0)), - ), - this.doctor.nearestFreeSlot != null - ? Container( - margin: EdgeInsets.only(top: 3.0, bottom: 3.0), - child: Text(getDate(this.doctor.nearestFreeSlot), - style: TextStyle( - fontSize: 14.0, - fontWeight: FontWeight.bold, - color: Colors.green[600], - letterSpacing: 1.0)), - ) - : Container(), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - mainAxisSize: MainAxisSize.max, - children: [ - RatingBar.readOnly( - initialRating: - this.doctor.actualDoctorRate.toDouble(), - size: 20.0, - filledColor: Colors.yellow[700], - emptyColor: Colors.grey[500], - isHalfAllowed: true, - halfFilledIcon: Icons.star_half, - filledIcon: Icons.star, - emptyIcon: Icons.star, - ), - Container( - child: Image.network(this.doctor.nationalityFlagURL, - width: 25.0, height: 25.0), + ], + color: Colors.white), + child: Padding( + padding: const EdgeInsets.only(left: 12, right: 12, top: 12, bottom: 12), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Expanded( + child: Text( + widget.doctor.name ?? "", + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.64, height: 25 / 16), + ), + ), + // widget.isShowDate + // ? Text( + // DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(widget.doctor.date)), + // style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.48, height: 18 / 12), + // ) + // : Container(), + ], + ), + if (widget.doctor.doctorTitle != null) SizedBox(height: 6), + Row( + mainAxisSize: MainAxisSize.min, + children: [ + LargeAvatar( + name: widget.doctor.name ?? "", + url: widget.doctor.doctorImageURL!, + width: 48, + height: 48, + ), + SizedBox(width: 11), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + if (widget.doctor.clinicName != null) MyRichText(TranslationBase.of(context).clinic + ":", widget.doctor.clinicName!, context.read().isArabic), + if (widget.doctor.projectName != null) MyRichText(TranslationBase.of(context).branch, widget.doctor.projectName!, context.read().isArabic), + if (!projectViewModel.isArabic) + if (widget.doctor.speciality != null && widget.doctor.speciality!.length > 0) + Text( + this.widget.doctor.speciality![0].trim(), + // getDoctorSpeciality(this.doctor.speciality).trim(), + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.48, height: 18 / 12), + ), + if (projectViewModel.isArabic) + if (widget.doctor.specialityN != null && widget.doctor.specialityN!.length > 0) + Text( + this.widget.doctor.specialityN![0].trim(), + // getDoctorSpeciality(this.doctor.speciality).trim(), + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.48, height: 18 / 12), + ), + if (widget.doctor.nearestFreeSlot != null) + Text( + getDate(widget.doctor.nearestFreeSlot), + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff359846), letterSpacing: -0.48, height: 18 / 12), ), - ], - ), - ], + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + mainAxisSize: MainAxisSize.max, + children: [ + //changed By Aamir + RatingBar( + initialRating: 3, + direction: Axis.horizontal, + allowHalfRating: true, + itemCount: 5, + itemSize: 20, + ignoreGestures: true, + ratingWidget: RatingWidget( + full: Icon( + Icons.star, + color: CustomColors.accentColor, + ), + half: Icon( + Icons.star_half, + color: CustomColors.accentColor, + ), + empty: Icon( + Icons.star, + color: CustomColors.accentColor, + ), + ), + tapOnlyMode: true, + itemPadding: EdgeInsets.symmetric(horizontal: 4.0), + unratedColor: Colors.grey[500], + onRatingUpdate: (rating) { + print(rating); + }, + ), + // RatingBar.readOnly( + // initialRating: this.doctor.actualDoctorRate!.toDouble(), + // size: 16.0, + // filledColor: Color(0XFFD02127), + // emptyColor: Color(0XFFD02127), + // isHalfAllowed: true, + // halfFilledIcon: Icons.star_half, + // filledIcon: Icons.star, + // emptyIcon: Icons.star_border, + // ), + if (widget.isShowFlag) + Icon( + Icons.arrow_forward, + color: Theme.of(context).primaryColor, + ), + // if (isShowFlag) Image.network(this.doctor.nationalityFlagURL, width: 22.0, height: 22.0) + ], + ), + ], + ), ), - ), + ], ), ], ), @@ -130,6 +205,29 @@ class DoctorView extends StatelessWidget { ); } + showDentalChiefComplaintsList(BuildContext context) { + HospitalsModel selectedHospital = new HospitalsModel(); + selectedHospital.name = widget.doctor.projectName; + ListClinicCentralized selectedClinic = new ListClinicCentralized(); + selectedClinic.clinicDescription = widget.doctor.clinicName; + + SearchInfo searchInfo = new SearchInfo(); + searchInfo.ProjectID = widget.doctor.projectID; + searchInfo.ClinicID = widget.doctor.clinicID; + searchInfo.date = DateTime.now(); + searchInfo.hospital = selectedHospital; + searchInfo.clinic = selectedClinic; + + showDraggableDialog( + context, + DentalComplaints( + isDoctorNameSearch: true, + onSelectedMethod: () { + Navigator.pop(context); + }, + searchInfo: searchInfo)); + } + String getDoctorSpeciality(List docSpecial) { String docSpeciality = ""; docSpecial.forEach((v) { @@ -138,14 +236,12 @@ class DoctorView extends StatelessWidget { return docSpeciality; } - getDoctorsProfile(context, DoctorList docObject, {isAppo}) { + getDoctorsProfile(context, DoctorList docObject, {isAppo, bool isContinueDentalPlan = false}) { + int languageID = projectViewModel.isArabic ? 1 : 2; GifLoaderDialogUtils.showMyDialog(context); List docProfileList = []; DoctorsListService service = new DoctorsListService(); - service - .getDoctorsProfile(docObject.doctorID, docObject.clinicID, - docObject.projectID, context) - .then((res) { + service.getDoctorsProfile(docObject.doctorID!, docObject.clinicID!, docObject!.projectID!, languageID, context).then((res) { GifLoaderDialogUtils.hideDialog(context); if (res['MessageStatus'] == 1) { if (res['DoctorProfileList'].length != 0) { @@ -153,12 +249,13 @@ class DoctorView extends StatelessWidget { docProfileList.add(new DoctorProfileList.fromJson(v)); }); } else {} - navigateToDoctorProfile(context, docObject, docProfileList[0], - isAppo: isAppo); + navigateToDoctorProfile(context, docObject, docProfileList[0], isAppo: isAppo, isContinueDentalPlan: isContinueDentalPlan); } else { AppToast.showErrorToast(message: res['ErrorEndUserMessage']); } }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err, localContext: context); print(err); }); } @@ -186,16 +283,34 @@ class DoctorView extends StatelessWidget { } } - Future navigateToDoctorProfile(context, docObject, docProfile, - {isAppo}) async { + void next(BuildContext context) { Navigator.push( context, FadePage( - page: DoctorProfile( + page: ObGyneTimeSlots( + projectID: widget.doctor.projectID!, + selectedClinicID: widget.doctor.clinicID!, + selectedDoctorID: widget.doctor.doctorID!, + obGyneProcedureListResponse: widget.obGyneProcedureListResponse!))); + } + + Future navigateToDoctorProfile(context, docObject, docProfile, {isAppo, bool isContinueDentalPlan = false}) async { + Navigator.push( + context, + FadePage( + page: DoctorProfile( doctor: docObject, - isLiveCareAppointment: isLiveCareAppointment, + isLiveCareAppointment: widget.isLiveCareAppointment!, docProfileList: docProfile, isOpenAppt: isAppo, - ))); + isDoctorNameSearch: widget.isDoctorNameSearch, + isContinueDentalPlan: isContinueDentalPlan, + ), + ), + ); } + + @override + // TODO: implement wantKeepAlive + bool get wantKeepAlive => true; } diff --git a/lib/pages/BookAppointment/widgets/TopCard.dart b/lib/pages/BookAppointment/widgets/TopCard.dart index 2d5bef61..5291e524 100644 --- a/lib/pages/BookAppointment/widgets/TopCard.dart +++ b/lib/pages/BookAppointment/widgets/TopCard.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; class TopCard extends StatelessWidget { - TopCard({@required this.image, @required this.isSVG}); + TopCard({required this.image, required this.isSVG}); final String image; final bool isSVG; @@ -21,9 +21,7 @@ class TopCard extends StatelessWidget { height: 100.0, padding: EdgeInsets.all(7.0), width: MediaQuery.of(context).size.width * 0.45, - child: this.isSVG - ? SvgPicture.asset(this.image) - : Image.asset(this.image), + child: this.isSVG ? SvgPicture.asset(this.image) : Image.asset(this.image), ), ), ); diff --git a/lib/pages/BookAppointment/widgets/reminder_dialog.dart b/lib/pages/BookAppointment/widgets/reminder_dialog.dart new file mode 100644 index 00000000..b3c39861 --- /dev/null +++ b/lib/pages/BookAppointment/widgets/reminder_dialog.dart @@ -0,0 +1,259 @@ +import 'dart:io'; + +import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; +import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/locator.dart'; +import 'package:diplomaticquarterapp/services/permission/permission_service.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/CalendarUtils.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:flutter/material.dart'; +import 'package:jiffy/jiffy.dart'; +import 'package:permission_handler/permission_handler.dart'; + +Future> requestPermissions() async { + var permissionResults = [Permission.calendarFullAccess].request(); + return permissionResults; +} + +showReminderDialog(BuildContext context, DateTime dateTime, String doctorName, String eventId, String appoDateFormatted, String appoTimeFormatted, + {required Function() onSuccess, String? title, String? description, Function(int)? onMultiDateSuccess, bool isMultiAllowed = false}) async { + if (Platform.isAndroid) { + if (await PermissionService.isCalendarPermissionEnabled()) { + _showReminderDialog(context, dateTime, doctorName, eventId, appoDateFormatted, appoTimeFormatted, + onSuccess: onSuccess, title: title, description: description, onMultiDateSuccess: onMultiDateSuccess, isMultiAllowed: isMultiAllowed); + } else { + Utils.showPermissionConsentDialog(context, TranslationBase.of(context).calendarPermission, () async { + if (await Permission.calendarFullAccess.request().isGranted) { + _showReminderDialog(context, dateTime, doctorName, eventId, appoDateFormatted, appoTimeFormatted, + onSuccess: onSuccess, title: title, description: description, onMultiDateSuccess: onMultiDateSuccess, isMultiAllowed: isMultiAllowed); + } + }); + } + } else { + if (await Permission.calendarWriteOnly.request().isGranted) { + if (await Permission.calendarFullAccess.request().isGranted) { + _showReminderDialog(context, dateTime, doctorName, eventId, appoDateFormatted, appoTimeFormatted, + onSuccess: onSuccess, title: title, description: description, onMultiDateSuccess: onMultiDateSuccess, isMultiAllowed: isMultiAllowed); + } + } + } +} + +Future _showReminderDialog(BuildContext providedContext, DateTime dateTime, String doctorName, String eventId, String appoDateFormatted, String appoTimeFormatted, + {required Function onSuccess, String? title, String? description, Function(int)? onMultiDateSuccess, bool? isMultiAllowed}) async { + return showDialog( + context: providedContext, + barrierDismissible: true, // user must tap button! + builder: (BuildContext context) { + return Dialog( + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(0.0)), + insetPadding: EdgeInsets.all(21), + child: ReminderDialog( + onClick: (int i) async { + String text = ""; + if (i == 0) { + // Before 30 mints + dateTime = Jiffy.parseFromDateTime(dateTime).subtract(minutes: 30).dateTime; + text = "30 minutes"; + // dateTime.add(new Duration(minutes: -30)); + } else if (i == 1) { + // Before 1 hour + // dateTime.add(new Duration(minutes: -60)); + dateTime = Jiffy.parseFromDateTime(dateTime).subtract(hours: 1).dateTime; + text = "1 hours"; + } else if (i == 2) { + // Before 1 hour and 30 mints + // dateTime.add(new Duration(minutes: -90)); + dateTime = Jiffy.parseFromDateTime(dateTime).subtract(hours: 1, minutes: 30).dateTime; + text = "1 hours 30 minutes"; + } else if (i == 3) { + // Before 2 hours + // dateTime.add(new Duration(minutes: -120)); + dateTime = Jiffy.parseFromDateTime(dateTime).subtract(hours: 2).dateTime; + text = "2 hours"; + } + if (!isMultiAllowed!) { + if (onMultiDateSuccess == null) { + CalendarUtils calendarUtils = await CalendarUtils.getInstance(); + await calendarUtils.createOrUpdateEvent( + title: title ?? TranslationBase.of(providedContext).reminderTitle + " " + doctorName, + description: description ?? "At " + appoDateFormatted + " " + appoTimeFormatted, + scheduleDateTime: dateTime, + eventId: eventId); + onSuccess(); + } + } else { + onMultiDateSuccess!(i); + } + locator().appointment.appointment_reminder_time(reminde_before: text); + }, + ), + ); + }, + ); +} + +class ReminderDialog extends StatefulWidget { + Function? onClick; + + ReminderDialog({this.onClick}); + + @override + _ReminderDialogState createState() => _ReminderDialogState(); +} + +class _ReminderDialogState 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( + TranslationBase.of(context).appointmentReminder, + style: TextStyle( + fontSize: 16, + color: Color(0xff2B353E), + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + ), + ), + mHeight(20), + Text( + TranslationBase.of(context).pleaseSelectFromBelowOptions, + style: TextStyle( + fontSize: 12, + color: Color(0xff2B353E), + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + ), + ), + Row( + children: [ + Radio( + value: 0, + groupValue: i, + onChanged: (int? value) { + setState(() { + i = value!; + }); + }, + ), + Text( + TranslationBase.of(context).appoReminder30, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + ), + ), + ], + ), + Row( + children: [ + Radio( + value: 1, + groupValue: i, + onChanged: (int? value) { + setState(() { + i = value!; + }); + }, + ), + Text( + TranslationBase.of(context).appoReminder60, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + ), + ), + ], + ), + Row( + children: [ + Radio( + value: 2, + groupValue: i, + onChanged: (int? value) { + setState(() { + i = value!; + }); + }, + ), + Text( + TranslationBase.of(context).appoReminder90, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + ), + ), + ], + ), + Row( + children: [ + Radio( + value: 3, + groupValue: i, + onChanged: (int? value) { + setState(() { + i = value!; + }); + }, + ), + Text( + TranslationBase.of(context).appoReminder120, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + ), + ), + ], + ), + mHeight(12), + DefaultButton( + TranslationBase.of(context).save, + () { + widget.onClick!(i); + Navigator.pop(context); + }, + color: CustomColors.green, + ), + ], + ), + ); + } +} diff --git a/lib/pages/ChildVaccines/add_newchild_page.dart b/lib/pages/ChildVaccines/add_newchild_page.dart index 3c0d072b..19ccae1e 100644 --- a/lib/pages/ChildVaccines/add_newchild_page.dart +++ b/lib/pages/ChildVaccines/add_newchild_page.dart @@ -4,56 +4,40 @@ 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/core/viewModels/child_vaccines/child_vaccines_view_model.dart'; -import 'package:diplomaticquarterapp/pages/Blood/new_text_Field.dart'; -import 'package:diplomaticquarterapp/pages/ChildVaccines/add_newchild_page.dart'; -import 'package:diplomaticquarterapp/pages/ChildVaccines/child_page.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/medical/active_medications/DayCheckBoxDialog.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/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:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_datetime_picker/flutter_datetime_picker.dart'; -import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:flutter_datetime_picker_plus/flutter_datetime_picker_plus.dart'; enum Gender { Male, Female, NON } enum BeneficiaryType { MyAccount, MyFamilyFiles, OtherAccount, NON } class AddNewChildPage extends StatefulWidget { - final int frequency; - final int days; - final String itemDescription; - String dateAdd; + final int? frequency; + final int? days; + final String? itemDescription; + String? dateAdd; - List _scheduleList = List(); - List daysOfWeek = [ - DayOfWeek.Monday, - DayOfWeek.Tuesday, - DayOfWeek.Wednesday, - DayOfWeek.Thursday, - DayOfWeek.Friday, - DayOfWeek.Saturday, - DayOfWeek.Sunday - ]; + List _scheduleList =[]; + List daysOfWeek = [DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday, DayOfWeek.Friday, DayOfWeek.Saturday, DayOfWeek.Sunday]; - DateTime startDay; - DateTime endDay; + DateTime? startDay; + DateTime? endDay; //AddNewChildPage({Key key, this.frequency, this.days, this.itemDescription}) : super(key: key); - AddNewChildPage({Key key, this.frequency, this.days, this.itemDescription}) { + 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))); } } @@ -62,8 +46,8 @@ class AddNewChildPage extends StatefulWidget { } class _AddNewChildPageState extends State { - int tappedIndex; - int checkedValue; + late int tappedIndex; + int checkedValue =0; @override void initState() { @@ -85,197 +69,207 @@ 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, + showNewAppBarTitle: true, + 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: DefaultButton( + TranslationBase.of(context).add, + () 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: @@ -284,11 +278,11 @@ class _AddNewChildPageState extends State { } String getStartDay() { - return "${DateUtil.getMonth(widget.startDay.month)} ${widget.startDay.day}, ${widget.startDay.year}"; + return "${DateUtil.getMonth(widget.startDay!.month)} ${widget.startDay!.day}, ${widget.startDay!.year}"; } String getEndDay() { - return "${DateUtil.getMonth(widget.endDay.month)} ${widget.endDay.day}, ${widget.endDay.year}"; + return "${DateUtil.getMonth(widget.endDay!.month)} ${widget.endDay!.day}, ${widget.endDay!.year}"; } String getDateTime(DateTime dateTime) { @@ -306,7 +300,7 @@ class _AddNewChildPageState extends State { void confirmSelectDayDialog() { showDialog( context: context, - child: DayCheckBoxDialog( + builder: (cxt) => DayCheckBoxDialog( title: 'Select Day', selectedDaysOfWeek: widget.daysOfWeek, onValueSelected: (value) { @@ -317,4 +311,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/child_page.dart b/lib/pages/ChildVaccines/child_page.dart index fad0b0c2..a5b65067 100644 --- a/lib/pages/ChildVaccines/child_page.dart +++ b/lib/pages/ChildVaccines/child_page.dart @@ -18,8 +18,7 @@ class ChildPage extends StatefulWidget { _ChildPageState createState() => _ChildPageState(); } -class _ChildPageState extends State - with SingleTickerProviderStateMixin { +class _ChildPageState extends State with SingleTickerProviderStateMixin { DeleteBaby deleteBaby = DeleteBaby(); @override @@ -57,20 +56,16 @@ class _ChildPageState extends State Navigator.push( context, FadePage( - page: VaccinationTablePage(model - .babyInformationModelList[index]), + page: VaccinationTablePage(model.babyInformationModelList[index]), ), ); }, child: Container( - margin: EdgeInsets.only( - left: 0, right: 0, bottom: 20), + margin: EdgeInsets.only(left: 0, right: 0, bottom: 20), decoration: BoxDecoration( shape: BoxShape.rectangle, - border: Border.all( - color: Colors.white, width: 0.5), - borderRadius: - BorderRadius.all(Radius.circular(5)), + border: Border.all(color: Colors.white, width: 0.5), + borderRadius: BorderRadius.all(Radius.circular(5)), color: Colors.white, ), padding: EdgeInsets.all(12), @@ -78,24 +73,14 @@ class _ChildPageState extends State child: Column( children: [ Row(children: [ - Texts(TranslationBase.of(context) - .childName), + Texts(TranslationBase.of(context).childName), ]), Row(children: [ - Texts(model - .babyInformationModelList[index] - .babyName - .trim()), + Texts(model.babyInformationModelList[index].babyName!.trim()), ]), Row(children: [ IconButton( - icon: Image.asset(model - .babyInformationModelList[ - index] - .gender == - 1 - ? 'assets/images/new-design/male.png' - : 'assets/images/new-design/female.png'), + icon: Image.asset(model.babyInformationModelList[index].gender == 1 ? 'assets/images/new-design/male.png' : 'assets/images/new-design/female.png'), tooltip: '', onPressed: () { setState(() { @@ -104,9 +89,7 @@ class _ChildPageState extends State }); }, ), - Texts(model - .babyInformationModelList[index] - .genderDescription), + Texts(model.babyInformationModelList[index].genderDescription), IconButton( icon: Icon( Icons.remove_red_eye, @@ -117,9 +100,7 @@ class _ChildPageState extends State Navigator.push( context, FadePage( - page: VaccinationTablePage(model - .babyInformationModelList[ - index]), + page: VaccinationTablePage(model.babyInformationModelList[index]), ), ); }, @@ -130,47 +111,34 @@ class _ChildPageState extends State ]), Row(children: [ IconButton( - icon: new Image.asset( - 'assets/images/new-design/calender-secondary.png'), + icon: new Image.asset('assets/images/new-design/calender-secondary.png'), tooltip: '', onPressed: () { setState(() {}); }, ), - Texts(DateUtil.yearMonthDay(model - .babyInformationModelList[index] - .dOB)), + Texts(DateUtil.yearMonthDay(model.babyInformationModelList[index].dOB!)), ]), Row(children: [ IconButton( - icon: new Image.asset( - 'assets/images/new-design/garbage.png'), + icon: new Image.asset('assets/images/new-design/garbage.png'), tooltip: '', onPressed: () async { //===================== - await model.deleteBabyOrders( - newChild: deleteBaby); + await model.deleteBabyOrders(newChild: deleteBaby); - deleteBaby.babyID = model - .babyInformationModelList[index] - .babyID; + deleteBaby.babyID = model.babyInformationModelList[index].babyID; - await model.deleteBabyOrders( - newChild: deleteBaby); + await model.deleteBabyOrders(newChild: deleteBaby); if (model.isDeleted) { - AppToast.showSuccessToast( - message: TranslationBase.of( - context) - .recordDeleted); - Navigator.pop( - context, model.isDeleted); + AppToast.showSuccessToast(message: TranslationBase.of(context).recordDeleted); + Navigator.pop(context, model.isDeleted); } else { //TODO handling error } }, ), - Texts(TranslationBase.of(context) - .deleteView), + Texts(TranslationBase.of(context).deleteView), ]), SizedBox( height: 12, diff --git a/lib/pages/ChildVaccines/child_vaccines_page.dart b/lib/pages/ChildVaccines/child_vaccines_page.dart index 38c6b5af..d48811be 100644 --- a/lib/pages/ChildVaccines/child_vaccines_page.dart +++ b/lib/pages/ChildVaccines/child_vaccines_page.dart @@ -1,6 +1,5 @@ -import 'package:diplomaticquarterapp/core/viewModels/child_vaccines/child_vaccines_view_model.dart'; +import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; import 'package:diplomaticquarterapp/core/viewModels/child_vaccines/user_information_view_model.dart'; -import 'package:diplomaticquarterapp/core/viewModels/medical/my_balance_view_model.dart'; import 'package:diplomaticquarterapp/pages/ChildVaccines/child_page.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; @@ -13,13 +12,14 @@ import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import '../Blood/new_text_Field.dart'; + class ChildVaccinesPage extends StatefulWidget { @override _ChildVaccinesPageState createState() => _ChildVaccinesPageState(); } -class _ChildVaccinesPageState extends State - with SingleTickerProviderStateMixin { +class _ChildVaccinesPageState extends State with SingleTickerProviderStateMixin { TextEditingController titleController = TextEditingController(); var checkedValue = false; String addEmail = ""; @@ -30,9 +30,17 @@ class _ChildVaccinesPageState extends State onModelReady: (model) => model.getUserInformationRequestOrders(), builder: (_, model, w) => AppScaffold( isShowAppBar: true, - baseViewModel: model, + isShowDecPage: 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, - //TranslationBase.of(context).advancePayment, body: SingleChildScrollView( physics: ScrollPhysics(), child: Column( @@ -78,24 +86,22 @@ class _ChildVaccinesPageState extends State padding: const EdgeInsets.all(10.0), child: Container( margin: EdgeInsets.only(left: 10, right: 10, top: 15), - child: TextFields( - fillColor: Colors.red, - hintText: model.user.emailAddress, + child: NewTextFields( + // fillColor: Colors.red, + hintText: model.user != null ? model.user!.emailAddress : "", controller: titleController, fontSize: 20, hintColor: Colors.black, fontWeight: FontWeight.w600, onChanged: (text) { addEmail = text; - model.user.emailAddress == addEmail - ? checkedValue = false - : checkedValue = true; + model.user!.emailAddress == addEmail ? checkedValue = false : checkedValue = true; }, validator: (value) { if (value == null) { - return model.user.emailAddress; + return model.user!.emailAddress; } else { - return model.user.emailAddress; + return model.user!.emailAddress; } }, ), @@ -118,9 +124,8 @@ class _ChildVaccinesPageState extends State label: TranslationBase.of(context).updateEmail, // onTap: () { - model.user.emailAddress = addEmail.toString(); - AppToast.showSuccessToast( - message: TranslationBase.of(context).updateEmailMsg); + model.user!.emailAddress = addEmail.toString(); + AppToast.showSuccessToast(message: TranslationBase.of(context).updateEmailMsg); // bloodDetails.city=_selectedHospital.toString(); // bloodDetails. diff --git a/lib/pages/ChildVaccines/dialogs/SelectGenderDialog.dart b/lib/pages/ChildVaccines/dialogs/SelectGenderDialog.dart index c08749b8..92bd248e 100644 --- a/lib/pages/ChildVaccines/dialogs/SelectGenderDialog.dart +++ b/lib/pages/ChildVaccines/dialogs/SelectGenderDialog.dart @@ -1,5 +1,3 @@ -import 'package:diplomaticquarterapp/pages/Blood/blood_donation.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:flutter/cupertino.dart'; @@ -9,7 +7,7 @@ class SelectGenderDialog extends StatefulWidget { final Email; final Function okFunction; - const SelectGenderDialog({Key key, this.Email, this.okFunction}) + const SelectGenderDialog({Key? key, this.Email, required this.okFunction}) : super(key: key); @override diff --git a/lib/pages/ChildVaccines/dialogs/delete_child.dart b/lib/pages/ChildVaccines/dialogs/delete_child.dart index 250f40d3..9eb49d27 100644 --- a/lib/pages/ChildVaccines/dialogs/delete_child.dart +++ b/lib/pages/ChildVaccines/dialogs/delete_child.dart @@ -1,4 +1,3 @@ -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'; 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..aba29817 --- /dev/null +++ b/lib/pages/ChildVaccines/new/child_initial_page.dart @@ -0,0 +1,147 @@ +import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; +import 'package:diplomaticquarterapp/core/viewModels/child_vaccines/user_information_view_model.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/pages/medical/balance/new_text_Field.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/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, + ), + NewTextFields( + /// fillColor: Colors.red, + //Changed By Aamir + 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), + 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 new file mode 100644 index 00000000..ddbbf198 --- /dev/null +++ b/lib/pages/ChildVaccines/new/child_vaccine_page.dart @@ -0,0 +1,206 @@ +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/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/defaultButton.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; + +import '../add_newchild_page.dart'; +import '../vaccinationtable_page.dart'; + +class ChildVaccinePage extends StatefulWidget { + @override + _ChildPageState createState() => _ChildPageState(); +} + +class _ChildPageState extends State with SingleTickerProviderStateMixin { + DeleteBaby deleteBaby = DeleteBaby(); + + @override + Widget build(BuildContext context) { + var size = MediaQuery.of(context).size; + final double height = (size.height - kToolbarHeight - 60); + final double itemWidth = size.width / 2; + final double itemHeight = height / 2 + 40; + + var checkedValue = true; + return BaseView( + onModelReady: (model) => model.getNewUserOrders(), + builder: (_, model, widget) => AppScaffold( + isShowAppBar: true, + appBarTitle: TranslationBase.of(context).vaccination, + baseViewModel: model, + showNewAppBarTitle: true, + showNewAppBar: true, + body: Column( + children: [ + Expanded( + child: ListView.separated( + itemBuilder: (context, index) { + Color selectedColor = model.babyInformationModelList[index].gender == 1 ? Color(0xFF5A282E) : Colors.white; + return InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: VaccinationTablePage(model.babyInformationModelList[index]), + ), + ); + }, + child: Container( + 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)), + color: Colors.white, + gradient: LinearGradient( + colors: model.babyInformationModelList[index].gender == 2 + ? [ + Color(0xFFFDA4B0), + Color(0xFFFBC8CC), + ] + : [ + Color(0xFF6EA8FF), + Color(0xFF7AB8FD), + ], + begin: Alignment.centerLeft, + end: Alignment.centerRight, + ), + ), + padding: EdgeInsets.all(12), + //double.infinity, + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + model.babyInformationModelList[index].babyName!.trim(), + style: TextStyle( + fontSize: 14, + letterSpacing: -0.46, + fontWeight: FontWeight.bold, + color: selectedColor, + ), + ), + Text( + model.babyInformationModelList[index].genderDescription!, + style: TextStyle( + fontSize: 11, + color: selectedColor, + ), + ), + Row( + children: [ + Text( + TranslationBase.of(context).dob, + style: TextStyle( + fontSize: 11, + color: selectedColor, + ), + ), + Text(" " + DateUtil.getDayMonthYearDateFormatted(model.babyInformationModelList[index].dOB!), + style: TextStyle( + fontSize: 11, + color: selectedColor, + )), + ], + ), + mHeight(20), + ], + ), + ), + 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; + + 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, + ), + ), + ], + ), + ), + ), + ], + ), + ], + ), + ), + ); + }, + separatorBuilder: (BuildContext context, int index) { + return mHeight(12); + }, + itemCount: model.babyInformationModelList.length, + ), + ), + Container( + width: double.infinity, + padding: EdgeInsets.all(16), + color: Colors.white, + child: DefaultButton( + TranslationBase.of(context).addNewChild, + () { + Navigator.push( + context, + FadePage( + page: AddNewChildPage(), + ), + ).then((value) { + if (value) model.getNewUserOrders(); + }); + }, + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/pages/ChildVaccines/vaccinationtable_page.dart b/lib/pages/ChildVaccines/vaccinationtable_page.dart index 7b8499e0..c909875c 100644 --- a/lib/pages/ChildVaccines/vaccinationtable_page.dart +++ b/lib/pages/ChildVaccines/vaccinationtable_page.dart @@ -1,18 +1,21 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/childvaccines/List_BabyInformationModel.dart'; import 'package:diplomaticquarterapp/core/viewModels/child_vaccines/vaccination_table_view_model.dart'; -import 'package:diplomaticquarterapp/core/viewModels/medical/reports_monthly_view_model.dart'; +import 'package:diplomaticquarterapp/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/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/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_html/flutter_html.dart'; -import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +import 'package:provider/provider.dart'; import 'dialogs/SelectGenderDialog.dart'; @@ -25,6 +28,7 @@ class VaccinationTablePage extends StatelessWidget { Widget build(BuildContext context) { var size = MediaQuery.of(context).size; final double height = (size.height - kToolbarHeight - 60); + ProjectViewModel projectViewModel = Provider.of(context); var checkedValue; return BaseView( @@ -33,147 +37,164 @@ class VaccinationTablePage extends StatelessWidget { isShowAppBar: true, baseViewModel: model, appBarTitle: TranslationBase.of(context).vaccination, + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: CustomColors.appBackgroudGrey2Color, body: Container( - height: height * 0.85, - child: SingleChildScrollView( - child: Container( - margin: EdgeInsets.only(left: 16, right: 16, top: 16), - child: Column( - children: [ - Row( - children: [ - Expanded( - child: Texts(TranslationBase.of(context).childName), - ), - Expanded( - child: Texts(TranslationBase.of(context).dob), - ), - ], - ), - SizedBox( - height: 10, - ), - Row( - children: [ - Expanded( - child: Texts(babyInfo.babyName), - ), - Expanded( - child: Texts(DateUtil.getFormattedDate( - babyInfo.dOB, "MMM dd,yyyy")), - ), - ], - ), - SizedBox( - height: 10, - ), - Divider( - color: Colors.black, - ), - Row( - children: [ - Text(TranslationBase.of(context).visit), - SizedBox( - width: 25, - ), - Expanded( - child: Text(TranslationBase.of(context).description)), - Text(TranslationBase.of(context).dueDate), - ], - ), - ...List.generate( - model.creteVaccinationTableModelList.length, - (index) => Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - // border: Border.all(color: Colors.white, width: 0.5), - borderRadius: BorderRadius.all(Radius.circular(5)), - // color: Colors.white, - ), + height: double.infinity, + child: Column( + children: [ + Expanded( + child: SingleChildScrollView( + child: Container( + margin: EdgeInsets.only(left: 16, right: 16, top: 16), + child: Column( + children: [ + Container( + decoration: containerRadius(Colors.white, 12), padding: EdgeInsets.all(12), - width: double.infinity, child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, children: [ + Text( + babyInfo.babyName!, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.64, + ), + ), + mHeight(8), Row( children: [ - Text(model - .creteVaccinationTableModelList[index] - .visit), - SizedBox( - width: 10, + Text( + TranslationBase.of(context).gender + " :", + style: TextStyle( + fontSize: 10, + fontWeight: FontWeight.w600, + letterSpacing: -0.4, + color: CustomColors.textColor, + ), ), - Expanded( - child: Column( - mainAxisAlignment: - MainAxisAlignment.start, - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Html( - // data:"
BCG
HEPATITIS B
"//model.creteVaccinationTableModelList[index].vaccinesDescription - data: model - .creteVaccinationTableModelList[ - index] - .vaccinesDescription, - ), - ], + Text( + babyInfo.gender == 1 ? TranslationBase.of(context).female : TranslationBase.of(context).male, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + letterSpacing: -0.4, + color: CustomColors.black, ), ), - Text(model - .creteVaccinationTableModelList[index] - .givenAt), ], ), - Divider( - color: Colors.black, + Row( + children: [ + Text( + TranslationBase.of(context).dateOfBirth + " :", + style: TextStyle( + fontSize: 10, + fontWeight: FontWeight.w600, + letterSpacing: -0.4, + color: CustomColors.textColor, + ), + ), + Text( + DateUtil.getFormattedDate(babyInfo.dOB!, "MMM dd,yyyy"), + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + letterSpacing: -0.4, + color: CustomColors.black, + ), + ), + ], ), ], - ))) - ], - ), - ), - ), - ), - bottomSheet: Container( - height: height * 0.15, - width: double.infinity, - padding: EdgeInsets.all(12), - child: SecondaryButton( - textColor: Colors.white, - color: checkedValue == false - ? Colors.white24 - : Color.fromRGBO( - 63, - 72, - 74, - 1, + ), + ), + mHeight(12), + Container( + decoration: containerRadius(Colors.white, 12), + padding: EdgeInsets.all(12), + child: Table( + columnWidths: { + 0: FlexColumnWidth(1.8), + 1: FlexColumnWidth(1.8), + 2: FlexColumnWidth(1.8), + }, + children: fullData(context, model, projectViewModel), + ), + ), + ], ), - label: TranslationBase.of(context).sendEmail, - // - onTap: () { - //SelectGenderDialog(); -//=============== - showDialog( - context: context, - child: SelectGenderDialog( - okFunction: () async { - await model.getCreateVaccinationTable(babyInfo, true); - if (model.state == ViewState.Idle) { - AppToast.showSuccessToast( - message: TranslationBase.of(context) - .emailSentSuccessfully); - } else { - AppToast.showErrorToast( - message: TranslationBase.of(context) - .EmailSentError); - } - }, ), - ); - //========= - }), + ), + ), + Container( + width: double.infinity, + padding: EdgeInsets.all(12), + color: Colors.white, + child: SecondaryButton( + textColor: Colors.white, + color: CustomColors.accentColor, + label: TranslationBase.of(context).sendEmail, + // + onTap: () { + //SelectGenderDialog(); +//=============== + showDialog( + context: context, + builder: (cxt) => SelectGenderDialog( + okFunction: () async { + await model.getCreateVaccinationTable(babyInfo, true); + if (model.state == ViewState.Idle) { + AppToast.showSuccessToast(message: TranslationBase.of(context).emailSentSuccessfully); + } else { + AppToast.showErrorToast(message: TranslationBase.of(context).EmailSentError); + } + }, + ), + ); + //========= + }, + ), + ), + ], + ), ), ), ); } + + List fullData(BuildContext context, VaccinationTableViewModel model, ProjectViewModel projectViewModel) { + List tableRow = []; + tableRow.add( + TableRow( + children: [ + Utils.tableColumnTitle(TranslationBase.of(context).visit), + Utils.tableColumnTitle(TranslationBase.of(context).description), + Utils.tableColumnTitle(TranslationBase.of(context).dueDate), + ], + ), + ); + model.creteVaccinationTableModelList.forEach( + (diabtec) { + tableRow.add( + TableRow( + children: [ + Utils.tableColumnValue(diabtec.visit!, isCapitable: false, mProjectViewModel: projectViewModel), + // Utils.tableColumnValue(diabtec.vaccinesDescription, isCapitable: false, mProjectViewModel: projectViewModel), + Html( + // data:"
BCG
HEPATITIS B
"//model.creteVaccinationTableModelList[index].vaccinesDescription + data: diabtec.vaccinesDescription, + ), + Utils.tableColumnValue(diabtec.givenAt!, isCapitable: false, mProjectViewModel: projectViewModel), + ], + ), + ); + }, + ); + return tableRow; + } } diff --git a/lib/pages/ContactUs/LiveChat/hospitalsLivechat_page.dart b/lib/pages/ContactUs/LiveChat/hospitalsLivechat_page.dart index d85971bb..6abd177c 100644 --- a/lib/pages/ContactUs/LiveChat/hospitalsLivechat_page.dart +++ b/lib/pages/ContactUs/LiveChat/hospitalsLivechat_page.dart @@ -1,16 +1,12 @@ -import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/viewModels/contactus/livechat_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.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'; +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:provider/provider.dart'; - import 'package:url_launcher/url_launcher.dart'; class HospitalsLiveChatPage extends StatefulWidget { @@ -19,8 +15,8 @@ class HospitalsLiveChatPage extends StatefulWidget { } class _HospitalsLiveChatPageState extends State { - int tappedIndex; - String chat; + int? tappedIndex; + String? chat; @override void initState() { @@ -37,182 +33,89 @@ class _HospitalsLiveChatPageState extends State { builder: (_, model, widget) => AppScaffold( baseViewModel: model, isShowDecPage: false, - body: SingleChildScrollView( - child: Container( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Stack( + body: Column( + children: [ + Expanded( + child: SingleChildScrollView( + physics: BouncingScrollPhysics(), + padding: EdgeInsets.only(top: 16, bottom: 16, right: 21, left: 21), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 70, - ), - Container( - width: double.infinity, - height: 230, + Text( + TranslationBase.of(context).instructions, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64, height: 23 / 16), + ), + SizedBox(height: 20), + Text( + TranslationBase.of(context).selectHospitalDec + " :", + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64, height: 23 / 16), + ), + SizedBox(height: 20), + ListView.separated( + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + separatorBuilder: (context, index) => SizedBox(height: 14), + itemCount: model.LiveChatModelList.length, + itemBuilder: (context, index) => InkWell( + onTap: () { + setState(() { + tappedIndex = index; + chat = + "http://chat.dshmg.com:7788/hmgchatapp/hmgchattest/Index.aspx?Name=${model.user!.firstName}&PatientID=${model.user!.patientID}&MobileNo=${model.user!.mobileNumber}&Language=${projectViewModel.currentLanguage}&WorkGroup=${model.LiveChatModelList[index].value}"; + }); + }, + child: Container( + padding: EdgeInsets.only(right: 12, left: 18, top: 16, bottom: 16), decoration: BoxDecoration( - image: DecorationImage( - image: ExactAssetImage( - 'assets/images/dashboard_top_bg.png'), - fit: BoxFit.cover), - ), - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: projectViewModel.isArabic? 10:20, - ), - Texts( - TranslationBase.of(context).instructions, - color: Colors.white, - textAlign: TextAlign.start, - ), - SizedBox( - height:projectViewModel.isArabic? 8:25, - ), - Texts( - TranslationBase.of(context) - .selectHospitalDec + - " :", - color: Colors.white, - fontWeight: FontWeight.w700, - textAlign: TextAlign.start, + borderRadius: BorderRadius.all( + Radius.circular(10.0), + ), + boxShadow: [ + BoxShadow( + color: Color(0xff000000).withOpacity(.05), + blurRadius: 27, + offset: Offset(0, -3), ), ], - ), + color: tappedIndex == index ? Color(0xff28323A).withOpacity(.7) : Colors.white), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( + child: Text( + model.LiveChatModelList[index].projectName.toString() + "\n" + model.LiveChatModelList[index].distanceInKilometers.toString() + " " + TranslationBase.of(context).km_ ?? "", + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: tappedIndex == index ? Colors.white : Color(0xff2B353E), letterSpacing: -0.64, height: 23 / 16), + ), + ), + Icon( + Icons.arrow_forward, + color: tappedIndex == index ? Colors.white : Colors.black, + ), + ], ), ), - SizedBox( - height: MediaQuery.of(context).size.height * 0.85, - ), - SizedBox( - height: 100, - ), - ], - ), - Positioned( - left: 13, - right: 13, - top: 200, - child: Container( - width: double.maxFinite, - child: Column( - children: [ - ...List.generate( - model.LiveChatModelList.length, - (index) => Container( - margin: EdgeInsets.only( - left: 0, right: 0, bottom: 20), - decoration: BoxDecoration( - shape: BoxShape.rectangle, - border: Border.all( - color: Colors.white, width: 0.5), - borderRadius: BorderRadius.all( - Radius.circular(5)), - color: tappedIndex == index - ? Theme.of(context).primaryColor - : Colors.white, - ), - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - InkWell( - onTap: () { - setState(() { - tappedIndex = index; - chat = "http://chat.dshmg.com:7788/hmgchatapp/hmgchattest/Index.aspx?Name=${model.user.firstName}&PatientID=${model.user.patientID}&MobileNo=${model.user.mobileNumber}&Language=${projectViewModel.currentLanguage}&WorkGroup=${model.LiveChatModelList[index].value}"; - }); - }, - child: Row( - mainAxisAlignment: - MainAxisAlignment - .spaceAround, - crossAxisAlignment: - CrossAxisAlignment.center, - children: [ - SizedBox( - width: 20, - ), - Expanded( - child: Container( - margin: - EdgeInsets.only( - left: 5, - right: 5), - child: Texts( - '${model.LiveChatModelList[index].projectName}', - color: - tappedIndex == - index - ? Colors - .white - : Colors - .black, - textAlign: TextAlign - .center, - ))), - //model.cOCItemList[index].cOCTitl - IconButton( - icon: Icon( - Icons.arrow_forward_ios, - color: - tappedIndex == index - ? Colors.white - : Colors.black, - ), - tooltip: '', - onPressed: () { - setState(() {}); - }, - ), - ], - ), - ) - ], - ), - ), - )), - ], - ), ), ), ], ), - Container( - height: MediaQuery.of(context).size.height * 0.20, - width: double.maxFinite, - ) - ], + ), ), - ), - ), - bottomSheet: Container( - height: MediaQuery.of(context).size.height * 0.10, - width: double.infinity, - padding: EdgeInsets.all(8.0), - child: Center( - child: Container( - height: MediaQuery.of(context).size.height * 0.07, - width: MediaQuery.of(context).size.width * 0.8, - child: SecondaryButton( - label: TranslationBase.of(context).start, - loading: model.state == ViewState.BusyLocal, - textColor: Colors.white, - disabled: chat.isEmpty, - onTap: () { - launch(chat); - }, + Container( + color: Colors.white, + padding: EdgeInsets.only(top: 16, bottom: 16, right: 21, left: 21), + child: DefaultButton( + TranslationBase.of(context).start, + //Changed By Aamir URL + chat!.isEmpty ? null : () => {launch(chat!)}, + color: Color(0xffD02127), + textColor: chat!.isEmpty ? Color(0xff000000) : Colors.white, + disabledColor: Color(0xffEAEAEA), ), ), - ), + ], ), ), ); diff --git a/lib/pages/ContactUs/LiveChat/livechat_page.dart b/lib/pages/ContactUs/LiveChat/livechat_page.dart index a747db3d..4d5c9c88 100644 --- a/lib/pages/ContactUs/LiveChat/livechat_page.dart +++ b/lib/pages/ContactUs/LiveChat/livechat_page.dart @@ -1,9 +1,6 @@ -import 'dart:ui'; - import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; -import 'package:diplomaticquarterapp/pages/ContactUs/LiveChat/pharmaciesLivechat_page.dart'; +import 'package:diplomaticquarterapp/theme/colors.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:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -15,17 +12,19 @@ class LiveChatPage extends StatefulWidget { _LiveChatPageState createState() => _LiveChatPageState(); } -class _LiveChatPageState extends State - with SingleTickerProviderStateMixin { - TabController _tabController; - List imagesInfo = List(); +class _LiveChatPageState extends State with SingleTickerProviderStateMixin { + late TabController _tabController; + List imagesInfo =[]; @override void initState() { super.initState(); - imagesInfo.add(ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/live-chat/en/0.png',imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/live-chat/ar/0.png')); - imagesInfo.add(ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/live-chat/en/1.png',imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/live-chat/ar/1.png')); - imagesInfo.add(ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/live-chat/en/2.png',imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/live-chat/ar/2.png')); + imagesInfo + .add(ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/live-chat/en/0.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/live-chat/ar/0.png')); + imagesInfo + .add(ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/live-chat/en/1.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/live-chat/ar/1.png')); + imagesInfo + .add(ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/live-chat/en/2.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/live-chat/ar/2.png')); _tabController = TabController(length: 2, vsync: this); } @@ -36,7 +35,6 @@ class _LiveChatPageState extends State _tabController.dispose(); } - @override @override Widget build(BuildContext context) { return AppScaffold( @@ -44,86 +42,11 @@ class _LiveChatPageState extends State imagesInfo: imagesInfo, title: TranslationBase.of(context).liveChat, description: TranslationBase.of(context).infoChat, - appBarTitle: TranslationBase.of(context).service, - body: Scaffold( - extendBodyBehindAppBar: true, - appBar: PreferredSize( - preferredSize: Size.fromHeight(65.0), - child: Stack( - children: [ - Positioned( - bottom: 1, - left: 0, - right: 0, - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10), - child: Container( - color: Theme.of(context) - .scaffoldBackgroundColor - .withOpacity(0.8), - height: 70.0, - ), - ), - ), - Center( - child: Container( - height: 60.0, - margin: EdgeInsets.only(top: 10.0), - width: MediaQuery.of(context).size.width * 0.92, // 0.9, - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Theme.of(context).dividerColor, - width: 0.9), //width: 0.7 - ), - color: Colors.white), - child: Center( - child: TabBar( - isScrollable: true, - controller: _tabController, - indicatorWeight: 5.0, - indicatorSize: TabBarIndicatorSize.tab, - indicatorColor: Theme.of(context).primaryColor, - labelColor: Theme.of(context).primaryColor, - labelPadding: EdgeInsets.only(top: 4.0, left: 35.0, right: 35.0), - unselectedLabelColor: Colors.grey[800], - tabs: [ - Container( - width: MediaQuery.of(context).size.width * 0.30, - child: Center( - child: Texts(TranslationBase.of(context).hospitals), - ), - ), - Container( - width: MediaQuery.of(context).size.width * 0.30, - child: Center( - child: Texts(TranslationBase.of(context).pharmacies), - ), - ), - ], - ), - ), - ), - ), - ], - ), - ), - body: Column( - children: [ - Expanded( - child: TabBarView( - physics: BouncingScrollPhysics(), - controller: _tabController, - children: [ - HospitalsLiveChatPage(), //SendFeedbackPage(), - PhamaciesLiveChatPage() - //StatusFeedbackPage() - ], - ), - ) - ], - ), - ), + appBarTitle: TranslationBase.of(context).liveChat, + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: CustomColors.appBackgroudGrey2Color, + body: HospitalsLiveChatPage(), ); } -} +} \ No newline at end of file diff --git a/lib/pages/ContactUs/LiveChat/pharmaciesLivechat_page.dart b/lib/pages/ContactUs/LiveChat/pharmaciesLivechat_page.dart index c5300b5d..e5b0647a 100644 --- a/lib/pages/ContactUs/LiveChat/pharmaciesLivechat_page.dart +++ b/lib/pages/ContactUs/LiveChat/pharmaciesLivechat_page.dart @@ -1,33 +1,16 @@ -import 'package:diplomaticquarterapp/core/viewModels/contactus/findus_view_model.dart'; -import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/viewModels/contactus/livechat_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.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/buttons/defaultButton.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'; - import 'package:url_launcher/url_launcher.dart'; -class PhamaciesLiveChatPage extends StatefulWidget { - @override - _PhamaciesLiveChatPageState createState() => _PhamaciesLiveChatPageState(); -} - -class _PhamaciesLiveChatPageState extends State { - int tappedIndex; - String chat; - - @override - void initState() { - super.initState(); - tappedIndex = -1; - chat = ""; - } +class PharmaciesLiveChatPage extends StatelessWidget { + PharmaciesLiveChatPage({Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -36,53 +19,41 @@ class _PhamaciesLiveChatPageState extends State { builder: (_, model, widget) => AppScaffold( baseViewModel: model, isShowDecPage: false, - body: SingleChildScrollView( - child: Container( - margin: EdgeInsets.only(left: 15, right: 15), - child: Column( - children: [ - SizedBox( - height: 20, + body: Column( + children: [ + Expanded( + child: SingleChildScrollView( + physics: BouncingScrollPhysics(), + padding: EdgeInsets.only(top: 16, bottom: 16, right: 21, left: 21), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox(height: 20), + Text( + TranslationBase.of(context).instructions, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64, height: 23 / 16), + ), + ], ), - Container( - width: double.infinity, - height: 200, - - child: Texts( - TranslationBase.of(context).instructionsPharmacies, - color: Colors.black, - textAlign: TextAlign.center, - ), - ), - /////////// - - SizedBox( - height: 100, - ), - ], + ), ), - ), - ), - bottomSheet: Container( - height: MediaQuery.of(context).size.height * 0.10, - width: double.infinity, - padding: EdgeInsets.all(8.0), - child: Center( - child: Container( - height: MediaQuery.of(context).size.height * 0.87, - width: MediaQuery.of(context).size.width * 0.8, - child: Button( - label: TranslationBase.of(context).start, - loading: model.state == ViewState.BusyLocal, - onTap: () { - print("chat=" + chat); - chat = - "http://chat.dshmg.com:7788/EPharmacyChat/EIndex.aspx?CustomerID=undefined&Name=${model.user.firstName}&MobileNo=${model.user.mobileNumber}&Language=${projectViewModel.isArabic? 1:2}"; - launch(chat); - }, + Container( + color: Colors.white, + padding: EdgeInsets.only(top: 16, bottom: 16, right: 21, left: 21), + child: DefaultButton( + TranslationBase.of(context).start, + null, + // () { + // String chat; + // chat = + // "http://chat.dshmg.com:7788/EPharmacyChat/EIndex.aspx?CustomerID=undefined&Name=${model.user.firstName}&MobileNo=${model.user.mobileNumber}&Language=${projectViewModel.isArabic ? 1 : 2}"; + // launch(chat); + // }, + disabledColor: Color(0xffEAEAEA), ), ), - ), + ], ), ), ); diff --git a/lib/pages/ContactUs/contact_us_page.dart b/lib/pages/ContactUs/contact_us_page.dart index d301df3e..2334b00f 100644 --- a/lib/pages/ContactUs/contact_us_page.dart +++ b/lib/pages/ContactUs/contact_us_page.dart @@ -1,10 +1,13 @@ -import 'package:diplomaticquarterapp/pages/ContactUs/widgets/card_common_contat.dart'; +import 'package:diplomaticquarterapp/pages/feedback/feedback_home_page.dart'; import 'package:diplomaticquarterapp/uitl/location_util.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'; import 'package:flutter/material.dart'; + import '../../uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/pages/ErService/widgets/card_common.dart'; +import 'LiveChat/livechat_page.dart'; +import 'findus/findus_page.dart'; class ContactUsPage extends StatefulWidget { @override @@ -12,76 +15,94 @@ class ContactUsPage extends StatefulWidget { } class _ContactUsPageState extends State { - - LocationUtils locationUtils; + late LocationUtils locationUtils; @override void initState() { - locationUtils = - new LocationUtils(isShowConfirmDialog: true, context: context); - WidgetsBinding.instance - .addPostFrameCallback((_) => locationUtils.getCurrentLocation()); + locationUtils = new LocationUtils(isShowConfirmDialog: true, context: context); + WidgetsBinding.instance.addPostFrameCallback((_) => locationUtils.getCurrentLocation()); super.initState(); } + @override Widget build(BuildContext context) { + List myMedicalList = myOptionsList(context); + return AppScaffold( isShowAppBar: true, - appBarTitle: TranslationBase.of(context).hMGServiceLabel, + appBarTitle: TranslationBase.of(context).contactUs, isShowDecPage: false, - body: Container( - margin: EdgeInsets.fromLTRB(10.0, 20.0, 10.0, 10.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - - Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Expanded( - child: CardCommonContact( - image: 'assets/images/new-design/find_us_icon.png', - text: TranslationBase.of(context).findUs, - subText: "", - type: 0, + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: Color(0xffF8F8F8), + body: Column( + children: [ + Container( + width: double.infinity, + height: 30, + ), + 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]; + }, + ), + ), + ], + ), + ); + } - ), - ), - Expanded( - child: CardCommonContact( - image: 'assets/images/new-design/feedback_icon.png', - text: TranslationBase.of(context).feedback, - subText: "", - type: 1), + List myOptionsList(BuildContext context) { + List medical =[]; - ), - ], - ), - Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Expanded( - child: CardCommonContact( - image: 'assets/images/new-design/live_chat_icon.png', - text: TranslationBase.of(context).liveChat, - subText: TranslationBase.of(context).service, - type: 2, + medical.add(InkWell( + onTap: () => Navigator.push( + context, + FadePage(page: FindUsPage()), + ), + child: MedicalProfileItem( + title: TranslationBase.of(context).findUs, + imagePath: 'assets/images/new-design/find_us_icon.png', + subTitle: "", + isPngImage: true, + ), + )); - ), - ), - Expanded( - child: Container(), + medical.add(InkWell( + onTap: () => Navigator.push( + context, + FadePage(page: FeedbackHomePage()), + ), + child: MedicalProfileItem( + title: TranslationBase.of(context).feedback, + imagePath: 'assets/images/new-design/feedback_icon.png', + subTitle: "", + isPngImage: true, + ), + )); - ), - ], - ), - ], - ), + medical.add(InkWell( + onTap: () => Navigator.push( + context, + FadePage(page: LiveChatPage()), ), - ); + child: MedicalProfileItem( + title: TranslationBase.of(context).liveChat, + imagePath: 'assets/images/new-design/live_chat_icon.png', + subTitle: "", + isPngImage: true, + ), + )); + + return medical; } } - diff --git a/lib/pages/ContactUs/findus/findus_page.dart b/lib/pages/ContactUs/findus/findus_page.dart index 80648292..78bb4e7e 100644 --- a/lib/pages/ContactUs/findus/findus_page.dart +++ b/lib/pages/ContactUs/findus/findus_page.dart @@ -4,8 +4,7 @@ import 'package:diplomaticquarterapp/core/viewModels/contactus/findus_view_model import 'package:diplomaticquarterapp/pages/ContactUs/findus/hospitrals_page.dart'; import 'package:diplomaticquarterapp/pages/ContactUs/findus/pharmacies_page.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; - -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +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'; @@ -15,9 +14,8 @@ class FindUsPage extends StatefulWidget { _FindUsPageState createState() => _FindUsPageState(); } -class _FindUsPageState extends State - with SingleTickerProviderStateMixin { - TabController _tabController; +class _FindUsPageState extends State with SingleTickerProviderStateMixin { + late TabController _tabController; @override void initState() { super.initState(); @@ -39,90 +37,43 @@ class _FindUsPageState extends State builder: (_, model, w) => AppScaffold( isShowAppBar: true, isShowDecPage: false, - appBarTitle: 'Locations', + appBarTitle: TranslationBase.of(context).location, + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: Color(0xffF8F8F8), baseViewModel: model, - body: Scaffold( - extendBodyBehindAppBar: true, - appBar: PreferredSize( - preferredSize: Size.fromHeight(65.0), - child: Stack( - children: [ - Positioned( - bottom: 1, - left: 0, - right: 0, - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10), - child: Container( - color: Theme.of(context) - .scaffoldBackgroundColor - .withOpacity(0.8), - height: 70.0, - ), - ), - ), - Center( - child: Container( - height: 60.0, - margin: EdgeInsets.only(top: 10.0), - width: MediaQuery.of(context).size.width * 0.92, // 0.9, - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Theme.of(context).dividerColor, - width: 0.9), //width: 0.7 - ), - color: Colors.white), - child: Center( - child: TabBar( - isScrollable: true, - controller: _tabController, - indicatorWeight: 5.0, - indicatorSize: TabBarIndicatorSize.tab, - labelColor: Theme.of(context).primaryColor, - labelPadding: - EdgeInsets.only(top: 4.0, left: 35.0, right: 35.0), - unselectedLabelColor: Colors.grey[800], - tabs: [ - Container( - width: MediaQuery.of(context).size.width * 0.30, - child: Center( - child: Texts(' Hospitals '), - ), - ), - Container( - width: MediaQuery.of(context).size.width * 0.30, - child: Center( - child: Texts(' Pharmacies '), - ), - ), - ], - ), - ), - ), - ), - ], + body: Column( + children: [ + TabBar( + controller: _tabController, + indicatorWeight: 3.0, + indicatorSize: TabBarIndicatorSize.tab, + labelColor: Color(0xff2B353E), + unselectedLabelColor: Color(0xff575757), + labelPadding: EdgeInsets.only(top: 15, bottom: 13, left: 20, right: 20), + labelStyle: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + ), + unselectedLabelStyle: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + ), + tabs: [Text(TranslationBase.of(context).hospitals), Text(TranslationBase.of(context).pharmacies)], ), - ), - body: Column( - children: [ - Expanded( - child: TabBarView( - physics: BouncingScrollPhysics(), - controller: _tabController, - children: [ - HospitalsPage( - findusHospitalModelList: model.FindusHospitalModelList, - ), //SendFeedbackPage(), - PharmaciesPage( - findusPharmaciesModelList: - model.FindusPharmaciesModelList, - ) //StatusFeedbackPage() - ], - ), - ) - ], - ), + Expanded( + child: TabBarView( + physics: BouncingScrollPhysics(), + controller: _tabController, + children: [ + HospitalsPage(findusHospitalModelList: model.FindusHospitalModelList), //SendFeedbackPage(), + PharmaciesPage(findusPharmaciesModelList: model.FindusPharmaciesModelList) //StatusFeedbackPage() + ], + ), + ) + ], ), ), ); diff --git a/lib/pages/ContactUs/findus/hospitrals_page.dart b/lib/pages/ContactUs/findus/hospitrals_page.dart index 2d257488..6f48deb6 100644 --- a/lib/pages/ContactUs/findus/hospitrals_page.dart +++ b/lib/pages/ContactUs/findus/hospitrals_page.dart @@ -1,19 +1,13 @@ import 'package:diplomaticquarterapp/core/model/contactus/get_hmg_locations.dart'; -import 'package:diplomaticquarterapp/core/viewModels/contactus/findus_view_model.dart'; -import 'package:diplomaticquarterapp/pages/base/base_view.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'; +import 'package:diplomaticquarterapp/widgets/hospital_location.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:giffy_dialog/giffy_dialog.dart'; import 'package:url_launcher/url_launcher.dart'; -import 'package:maps_launcher/maps_launcher.dart'; class HospitalsPage extends StatefulWidget { final List findusHospitalModelList; - HospitalsPage({Key key, this.findusHospitalModelList}); + HospitalsPage({Key? key, required this.findusHospitalModelList}); @override _HospitalsPageState createState() => _HospitalsPageState(); @@ -22,229 +16,81 @@ class HospitalsPage extends StatefulWidget { class _HospitalsPageState extends State { @override Widget build(BuildContext context) { - return AppScaffold( - isShowDecPage: false, - body: SingleChildScrollView( - child: Container( - // margin: EdgeInsets.only(left: 15,right: 15,top: 70), - margin: EdgeInsets.only(left: 15, right: 15, top: 70), - child: Column( - children: [ - ...List.generate( - widget.findusHospitalModelList.length, - (index) => Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - border: Border.all(color: Colors.white, width: 0.5), - borderRadius: BorderRadius.all(Radius.circular(5)), - color: Colors.white, - ), - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - crossAxisAlignment: - CrossAxisAlignment.center, - children: [ - InkWell( - onTap: () { - showDialog( - context: context, - builder: (_) => - AssetGiffyDialog( - title: Text( - widget - .findusHospitalModelList[ - index] - .locationName, - style: TextStyle( - fontSize: 22.0, - fontWeight: - FontWeight - .w600), - ), - image: Image.network( - widget - .findusHospitalModelList[ - index] - .projectImageURL - .toString(), - fit: BoxFit.cover, - ), - buttonCancelText: - Text('cancel'), - buttonCancelColor: - Colors.grey, - onlyCancelButton: true, - )); - }, - child: Container( - width: 70, - height: 70, - child: Image.network(widget - .findusHospitalModelList[ - index] - .projectImageURL - .toString())), - ), - Expanded( - flex: 4, - child: Container( - margin: EdgeInsets.only( - left: 5, - right: 5, - top: 10, - bottom: 1), - child: Texts( - '${widget.findusHospitalModelList[index].locationName}', - textAlign: TextAlign.start, - ))), //model.cOCItemList[index].cOCTitl - Expanded( - flex: 2, - child: Row( - crossAxisAlignment: - CrossAxisAlignment.center, - children: [ - IconButton( - icon: Icon( - Icons.location_on, - color: Theme.of(context) - .primaryColor, - size: 35, - ), - // icon: new Image.asset( - // 'assets/images/new-design/navigate.png'), - tooltip: '', - onPressed: () { - setState(() { - MapsLauncher.launchCoordinates( - double.parse(widget - .findusHospitalModelList[ - index] - .latitude), - double.parse(widget - .findusHospitalModelList[ - index] - .longitude), - widget - .findusHospitalModelList[ - index] - .locationName); - }); - }, - ), - IconButton( - icon: Icon( - Icons.phone, - color: Theme.of(context) - .primaryColor, - size: 35, - ), - // icon: new Image.asset( - // 'assets/images/new-design/call.png'), - tooltip: '', - onPressed: () { - setState(() { - // _volume += 10; - launch("tel://" + - widget - .findusHospitalModelList[ - index] - .phoneNumber); - }); - }, - ), - ], - ), - ), - ], - ), - ), - ], - ), - // Texts('${model.FindusHospitalModelList[index].locationName}'), - Divider( - height: 4.5, - color: Colors.grey[500], - ) - ], - ), - ), - )), - SizedBox( - height: 8, - ), - Container( - width: double.infinity, - height: 100, - color: Colors.white, - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - IconButton( - icon: new Image.asset( - 'assets/images/new-design/youtube.png'), - iconSize: 70, - tooltip: 'Youtube', - onPressed: () { - setState(() { - launch( - "https://www.youtube.com/c/DrsulaimanAlhabibHospitals"); - }); - }, - ), - IconButton( - icon: new Image.asset( - 'assets/images/new-design/linkedin.png'), - tooltip: 'LinkedIn', - iconSize: 70, - onPressed: () { - setState(() { - launch( - "https://www.linkedin.com/company/drsulaiman-alhabib-medical-group"); - }); - }, - ), - IconButton( - icon: new Image.asset( - 'assets/images/new-design/twitter.png'), - tooltip: 'Twitter', - iconSize: 70, - onPressed: () { - setState(() { - launch("https://twitter.com/HMG"); - }); - }, - ), - IconButton( - icon: new Image.asset( - 'assets/images/new-design/facebook.png'), - tooltip: 'facebook', - iconSize: 70, - onPressed: () { - setState(() { - launch( - "https://www.facebook.com/DrSulaimanAlHabib?ref=tn_tnmn"); - }); - }, - ), - ], + return SingleChildScrollView( + physics: BouncingScrollPhysics(), + padding: EdgeInsets.only(bottom: 21, top: 21, left: 21, right: 21), + child: Column( + children: [ + ListView.separated( + physics: NeverScrollableScrollPhysics(), + shrinkWrap: true, + padding: EdgeInsets.zero, + separatorBuilder: (context, index) => SizedBox(height: 14), + itemBuilder: (context, index) => HospitalLocation(widget.findusHospitalModelList[index]), + itemCount: widget.findusHospitalModelList.length, + ), + Container( + margin: EdgeInsets.only(top: 14), + 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.spaceEvenly, + children: [ + IconButton( + icon: new Image.asset('assets/images/new-design/youtube.png'), + iconSize: 48, + tooltip: 'Youtube', + onPressed: () { + setState(() { + launch("https://www.youtube.com/c/DrsulaimanAlhabibHospitals"); + }); + }, + ), + IconButton( + icon: new Image.asset('assets/images/new-design/linkedin.png'), + tooltip: 'LinkedIn', + iconSize: 48, + onPressed: () { + setState(() { + launch("https://www.linkedin.com/company/drsulaiman-alhabib-medical-group"); + }); + }, + ), + IconButton( + icon: new Image.asset('assets/images/new-design/twitter.png'), + tooltip: 'Twitter', + iconSize: 48, + onPressed: () { + setState(() { + launch("https://twitter.com/HMG"); + }); + }, + ), + IconButton( + icon: new Image.asset('assets/images/new-design/facebook.png'), + tooltip: 'facebook', + iconSize: 48, + onPressed: () { + setState(() { + launch("https://www.facebook.com/DrSulaimanAlHabib?ref=tn_tnmn"); + }); + }, ), - ), - ], + ], + ), ), - ), + ], ), ); } diff --git a/lib/pages/ContactUs/findus/pharmacies_page.dart b/lib/pages/ContactUs/findus/pharmacies_page.dart index 6cf94728..529319f1 100644 --- a/lib/pages/ContactUs/findus/pharmacies_page.dart +++ b/lib/pages/ContactUs/findus/pharmacies_page.dart @@ -1,20 +1,14 @@ -import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/contactus/get_hmg_locations.dart'; -import 'package:diplomaticquarterapp/core/viewModels/contactus/findus_view_model.dart'; -import 'package:diplomaticquarterapp/pages/base/base_view.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'; +import 'package:diplomaticquarterapp/widgets/hospital_location.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:giffy_dialog/giffy_dialog.dart'; -import 'package:maps_launcher/maps_launcher.dart'; import 'package:url_launcher/url_launcher.dart'; class PharmaciesPage extends StatefulWidget { final List findusPharmaciesModelList; - PharmaciesPage({Key key, this.findusPharmaciesModelList}); + PharmaciesPage({Key? key, required this.findusPharmaciesModelList}); + @override _PharmaciesPageState createState() => _PharmaciesPageState(); } @@ -22,239 +16,81 @@ class PharmaciesPage extends StatefulWidget { class _PharmaciesPageState extends State { @override Widget build(BuildContext context) { - return AppScaffold( - isShowDecPage: false, - body: SingleChildScrollView( - child: Container( - margin: EdgeInsets.only(left: 15, right: 15, top: 70), - child: Column( - children: [ - ...List.generate( - widget.findusPharmaciesModelList.length, - (index) => Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - border: Border.all(color: Colors.white, width: 0.5), - borderRadius: BorderRadius.all(Radius.circular(5)), - color: Colors.white, - ), - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - crossAxisAlignment: - CrossAxisAlignment.center, - children: [ - InkWell( - onTap: () { - showDialog( - context: context, - builder: (_) => - AssetGiffyDialog( - title: Text( - widget - .findusPharmaciesModelList[ - index] - .locationName, - style: TextStyle( - fontSize: 22.0, - fontWeight: - FontWeight - .w600), - ), - image: widget - .findusPharmaciesModelList[ - index] - .projectImageURL != - null - ? Image.network( - widget - .findusPharmaciesModelList[ - index] - .projectImageURL, - fit: BoxFit.cover, - ) - : Image.network( - 'https://hmgwebservices.com/Images/Hospitals/15.jpg', - fit: BoxFit.cover, - ), - buttonCancelText: - Text('cancel'), - // buttonCancelText:Text(model.user.projectID) , - buttonCancelColor: - Colors.grey, - onlyCancelButton: true, - )); - }, - child: Container( - width: 70, - height: 70, - child: Image.network(widget - .findusPharmaciesModelList[ - index] - .projectImageURL != - null - ? widget - .findusPharmaciesModelList[ - index] - .projectImageURL - .toString() - : 'https://hmgwebservices.com/Images/Hospitals/15.jpg')), - ), - Expanded( - flex: 4, - child: Container( - margin: EdgeInsets.only( - left: 5, right: 5), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Texts( - '${widget.findusPharmaciesModelList[index].locationName}', - textAlign: TextAlign.start, - ), - SizedBox( - height: 4, - ), - Texts( - '${widget.findusPharmaciesModelList[index].cityName}', - textAlign: TextAlign.center, - ), - ], - ), - ), - ), - //model.cOCItemList[index].cOCTitl - Expanded( - flex: 2, - child: Row( - children: [ - IconButton( - icon: Icon(Icons.location_on,color: Theme.of(context).primaryColor,size: 35,), - tooltip: '', - onPressed: () { - setState(() { - MapsLauncher.launchCoordinates( - double.parse(widget - .findusPharmaciesModelList[ - index] - .latitude), - double.parse(widget - .findusPharmaciesModelList[ - index] - .longitude), - widget - .findusPharmaciesModelList[ - index] - .locationName); - }); - }, - ), - IconButton( - icon: Icon(Icons.phone,color: Theme.of(context).primaryColor,size: 35,), - tooltip: 'I', - onPressed: () { - setState(() { - - launch("tel://" + - widget - .findusPharmaciesModelList[ - index] - .phoneNumber); - }); - }, - ), - ], - ), - ), - ], - ), - ), - ], - ), - Divider( - height: 4.5, - color: Colors.grey[500], - ) - ], - ), - ), - )), - SizedBox( - height: 8, - ), - Container( - width: double.infinity, - height: 100, - color: Colors.white, - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - IconButton( - icon: new Image.asset( - 'assets/images/new-design/youtube.png'), - iconSize: 70, - tooltip: 'Youtube', - onPressed: () { - setState(() { - // _volume += 10; - launch( - "https://www.youtube.com/c/DrsulaimanAlhabibHospitals"); - }); - }, - ), - IconButton( - icon: new Image.asset( - 'assets/images/new-design/linkedin.png'), - tooltip: 'LinkedIn', - iconSize: 70, - onPressed: () { - setState(() { - launch( - "https://www.linkedin.com/company/drsulaiman-alhabib-medical-group"); - }); - }, - ), - IconButton( - icon: new Image.asset( - 'assets/images/new-design/twitter.png'), - tooltip: 'Twitter', - iconSize: 70, - onPressed: () { - setState(() { - launch("https://twitter.com/HMG"); - }); - }, - ), - IconButton( - icon: new Image.asset( - 'assets/images/new-design/facebook.png'), - tooltip: 'facebook', - iconSize: 70, - onPressed: () { - setState(() { - launch( - "https://www.facebook.com/DrSulaimanAlHabib?ref=tn_tnmn"); - }); - }, - ), - ], + return SingleChildScrollView( + physics: BouncingScrollPhysics(), + padding: EdgeInsets.only(bottom: 21, top: 21, left: 21, right: 21), + child: Column( + children: [ + ListView.separated( + physics: NeverScrollableScrollPhysics(), + shrinkWrap: true, + padding: EdgeInsets.zero, + separatorBuilder: (context, index) => SizedBox(height: 14), + itemBuilder: (context, index) => HospitalLocation(widget.findusPharmaciesModelList[index], showCity: true), + itemCount: widget.findusPharmaciesModelList.length, + ), + Container( + margin: EdgeInsets.only(top: 14), + 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.spaceEvenly, + children: [ + IconButton( + icon: new Image.asset('assets/images/new-design/youtube.png'), + iconSize: 48, + tooltip: 'Youtube', + onPressed: () { + setState(() { + launch("https://www.youtube.com/c/DrsulaimanAlhabibHospitals"); + }); + }, + ), + IconButton( + icon: new Image.asset('assets/images/new-design/linkedin.png'), + tooltip: 'LinkedIn', + iconSize: 48, + onPressed: () { + setState(() { + launch("https://www.linkedin.com/company/drsulaiman-alhabib-medical-group"); + }); + }, + ), + IconButton( + icon: new Image.asset('assets/images/new-design/twitter.png'), + tooltip: 'Twitter', + iconSize: 48, + onPressed: () { + setState(() { + launch("https://twitter.com/HMG"); + }); + }, + ), + IconButton( + icon: new Image.asset('assets/images/new-design/facebook.png'), + tooltip: 'facebook', + iconSize: 48, + onPressed: () { + setState(() { + launch("https://www.facebook.com/DrSulaimanAlHabib?ref=tn_tnmn"); + }); + }, ), - ), - ], + ], + ), ), - ), + ], ), ); } diff --git a/lib/pages/ContactUs/widgets/card_common_contat.dart b/lib/pages/ContactUs/widgets/card_common_contat.dart index 8848e2ff..b4cfe95f 100644 --- a/lib/pages/ContactUs/widgets/card_common_contat.dart +++ b/lib/pages/ContactUs/widgets/card_common_contat.dart @@ -1,59 +1,61 @@ import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart'; import 'package:diplomaticquarterapp/pages/ContactUs/LiveChat/livechat_page.dart'; import 'package:diplomaticquarterapp/pages/ContactUs/findus/findus_page.dart'; +import 'package:diplomaticquarterapp/pages/ToDoList/ToDo.dart'; import 'package:diplomaticquarterapp/pages/feedback/feedback_home_page.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/pages/medical/balance/advance_payment_page.dart'; +import 'package:diplomaticquarterapp/pages/medical/balance/my_balance_page.dart'; +import 'package:diplomaticquarterapp/pages/medical/my_trackers/Weight/WeightHomePage.dart'; +import 'package:diplomaticquarterapp/pages/medical/my_trackers/blood_pressure/BloodPressureHomePage.dart'; +import 'package:diplomaticquarterapp/pages/medical/my_trackers/blood_suger/blood_sugar_home_page.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; - -import '../../../Constants.dart'; class CardCommonContact extends StatelessWidget { final image; final text; final subText; final type; - const CardCommonContact( - {@required this.image, - @required this.text, - @required this.subText, - @required this.type}); + final width; + final height; + final ProjectViewModel projectViewModel; + final ToDoCountProviderModel model; + + const CardCommonContact({required this.image, required this.text, required this.subText, required this.type, this.width, this.height, required this.projectViewModel, required this.model}); @override Widget build(BuildContext context) { - ProjectViewModel projectViewModel = Provider.of(context); + // ProjectViewModel projectViewModel = Provider.of(context); + // ToDoCountProviderModel model = Provider.of(context); return GestureDetector( onTap: () { navigateToSearch(context, this.type); }, child: Container( - margin: EdgeInsets.fromLTRB(9.0, 9.0, 9.0, 9.0), - decoration: BoxDecoration(boxShadow: [ - BoxShadow(color: Colors.grey[400], blurRadius: 2.0, spreadRadius: 0.0) - ], borderRadius: BorderRadius.circular(10), color: Colors.white), + 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: [ - Container( - margin: EdgeInsets.fromLTRB(10.0, 10.0, 10.0, 0.0), - child: Texts(this.text, - // overflow: TextOverflow.clip, - color:secondaryColor, - fontWeight: FontWeight.w700, - fontSize: 20.0), - ), - Container( - margin: EdgeInsets.fromLTRB(10.0, 0.0, 10.0, 0.0), - child: Texts(this.subText, - color: Colors.black, fontSize: 15.0), + Image.asset( + this.image, + width: width != null ? width : 42.0, + height: height != null ? height : 42.0, ), - Align( - alignment: projectViewModel.isArabic? Alignment.bottomLeft:Alignment.bottomRight, - child: Container( - margin: EdgeInsets.fromLTRB(10.0, 0.0, 10.0, 8.0), - child: Image.asset(this.image, width: 60.0, height: 60.0), - ), + Text( + text + "${subText.isEmpty ? "" : "\n$subText"}", + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.48, height: 20 / 16), ), ], ), @@ -62,15 +64,36 @@ class CardCommonContact extends StatelessWidget { } Future navigateToSearch(context, type) async { - if (type == 0) { Navigator.push(context, FadePage(page: FindUsPage())); } else if (type == 1) { Navigator.push(context, FadePage(page: FeedbackHomePage())); } else if (type == 2) { - //LiveChatPage Navigator.push(context, FadePage(page: LiveChatPage())); + } else if (type == 3) { + Navigator.push(context, FadePage(page: BloodSugarHomePage())); + } else if (type == 4) { + Navigator.push(context, FadePage(page: BloodPressureHomePage())); + } else if (type == 5) { + Navigator.push(context, FadePage(page: WeightHomePage())); + } else if (type == 6) { + Navigator.push(context, FadePage(page: AdvancePaymentPage())); + } else if (type == 7) { + navigateToToDoPage(context); + } else if (type == 8) { + Navigator.push(context, FadePage(page: MyBalancePage())); + } + } + navigateToToDoPage(BuildContext context) { + if (projectViewModel.isLogin) { + if (model.count != 0) { + Navigator.push(context, FadePage(page: ToDo(isShowAppBar: true))); + } else { + AppToast.showErrorToast(message: TranslationBase.of(context).upcomingEmpty); + } + } else { + Navigator.push(context, FadePage(page: ToDo(isShowAppBar: true))); } } } diff --git a/lib/pages/Covid-DriveThru/Covid-TimeSlots.dart b/lib/pages/Covid-DriveThru/Covid-TimeSlots.dart index 04a7178f..88be72dd 100644 --- a/lib/pages/Covid-DriveThru/Covid-TimeSlots.dart +++ b/lib/pages/Covid-DriveThru/Covid-TimeSlots.dart @@ -1,51 +1,59 @@ +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; import 'package:diplomaticquarterapp/models/Appointments/FreeSlot.dart'; import 'package:diplomaticquarterapp/models/Appointments/PatientShareResposne.dart'; import 'package:diplomaticquarterapp/models/Appointments/timeSlot.dart'; +import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart'; +import 'package:diplomaticquarterapp/models/CovidDriveThru/CovidTestProceduresResponse.dart'; +import 'package:diplomaticquarterapp/models/CovidDriveThru/DriveThroughTestingCenterModel.dart'; import 'package:diplomaticquarterapp/pages/Covid-DriveThru/covid-payment-alert.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; +import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; import 'package:diplomaticquarterapp/services/covid-drivethru/covid-drivethru.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/buttons/custom_text_button.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; -import 'package:table_calendar/table_calendar.dart'; +import 'package:syncfusion_flutter_calendar/calendar.dart'; class CovidTimeSlots extends StatefulWidget { - int projectID; + int? projectID; static bool areSlotsAvailable = false; - static DateTime selectedAppoDateTime; - static String selectedDate; - static String selectedTime; + static DateTime? selectedAppoDateTime; + static String? selectedDate; + static String? selectedTime; + CovidTestProceduresResponse? selectedProcedure; + DriveThroughTestingCenterModel? selectedProject; - int selectedClinicID; - int selectedDoctorID; + int? selectedClinicID; + int? selectedDoctorID; var language; - PatientShareResponse patientShareResponse; + PatientShareResponse? patientShareResponse; - CovidTimeSlots({@required this.projectID}); + CovidTimeSlots({required this.projectID, required this.selectedProcedure, required this.selectedProject}); @override _CovidTimeSlotsState createState() => _CovidTimeSlotsState(); } -class _CovidTimeSlotsState extends State - with TickerProviderStateMixin { - Map _events; - AnimationController _animationController; - CalendarController _calendarController; +class _CovidTimeSlotsState extends State with TickerProviderStateMixin { + late Map _events; + late AnimationController _animationController; + late CalendarController _calendarController; AppSharedPreferences sharedPref = new AppSharedPreferences(); @@ -60,7 +68,10 @@ class _CovidTimeSlotsState extends State dynamic freeSlotsResponse; - ScrollController _scrollController; + late ScrollController _scrollController; + + late ToDoCountProviderModel toDoProvider; + late ProjectViewModel projectViewModel; @override void initState() { @@ -74,8 +85,7 @@ class _CovidTimeSlotsState extends State _selectedDay: ['Event A0'] }; - WidgetsBinding.instance.addPostFrameCallback( - (_) => getCovidFreeSlots(context, widget.projectID)); + WidgetsBinding.instance.addPostFrameCallback((_) => getCovidFreeSlots(context, widget.projectID!)); _calendarController = CalendarController(); _animationController = AnimationController( @@ -94,297 +104,182 @@ class _CovidTimeSlotsState extends State super.dispose(); } - void _onDaySelected(DateTime day, List events, ProjectViewModel projectViewModel) { + void _onDaySelected(DateTime day, ProjectViewModel projectViewModel) { final DateFormat formatter = DateFormat('yyyy-MM-dd'); setState(() { this.selectedDate = DateUtil.getWeekDayMonthDayYearDateFormatted(day, projectViewModel.isArabic ? "ar" : "en"); openTimeSlotsPickerForDate(day, docFreeSlots); CovidTimeSlots.selectedDate = formatter.format(day); + _calendarController.selectedDate = day; print(CovidTimeSlots.selectedDate); }); } - void _onVisibleDaysChanged( - DateTime first, DateTime last, CalendarFormat format) { - print('CALLBACK: _onVisibleDaysChanged'); - } - - void _onCalendarCreated( - DateTime first, DateTime last, CalendarFormat format) { - print('CALLBACK: _onCalendarCreated'); - } - @override Widget build(BuildContext context) { - ProjectViewModel projectViewModel = Provider.of(context); + projectViewModel = Provider.of(context); + toDoProvider = Provider.of(context); return AppScaffold( appBarTitle: TranslationBase.of(context).covidTest, isShowAppBar: true, - body: SingleChildScrollView( - child: Container( - margin: EdgeInsets.fromLTRB(15.0, 15.0, 15.0, 0.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - height: 150.0, - decoration: BoxDecoration( - image: DecorationImage( - image: AssetImage( - "assets/images/new-design/covid-19-big-banner-bg.png"), - fit: BoxFit.fill, - ), - color: Colors.white.withOpacity(0.3), - borderRadius: BorderRadius.all(Radius.circular(10))), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - margin: - EdgeInsets.only(left: 15.0, right: 15.0, top: 30.0), - child: SvgPicture.asset( - 'assets/images/new-design/covid-19-car.svg', - width: 90.0, - height: 90.0), - ), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - margin: EdgeInsets.only( - left: 20.0, right: 20.0, top: 20.0), - child: Text(TranslationBase.of(context).covidTest, - style: TextStyle( - color: Colors.white, - fontWeight: FontWeight.bold, - fontSize: 24.0)), - ), - Container( - margin: EdgeInsets.only( - left: 20.0, right: 20.0, top: 10.0), - child: Text(TranslationBase.of(context).driveThru, - style: TextStyle( - color: Colors.white, fontSize: 24.0)), - ), - ], - ), - ], - ), - ), - Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10.0), - color: Colors.white), - margin: EdgeInsets.fromLTRB(0.0, 20.0, 0.0, 5.0), - padding: EdgeInsets.fromLTRB(10.0, 0.0, 10.0, 20.0), - width: MediaQuery.of(context).size.width, - // height: MediaQuery.of(context).size.height * 0.65, + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: CustomColors.appBackgroudGrey2Color, + body: Column( + children: [ + Expanded( + child: SingleChildScrollView( + child: Container( + margin: EdgeInsets.fromLTRB(15.0, 15.0, 15.0, 0.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.max, children: [ Container( - margin: EdgeInsets.all(10.0), - child: Text(TranslationBase.of(context).selectAppo, - style: - TextStyle(color: Colors.black, fontSize: 16.0)), - ), - Container( - margin: EdgeInsets.only(top: 10.0), - alignment: Alignment.center, - child: Text(selectedDate, - style: TextStyle( - fontSize: 18.0, fontWeight: FontWeight.bold)), - ), - Container( - height: 50, - margin: EdgeInsets.all(20.0), - child: ListView.builder( - controller: _scrollController, - scrollDirection: Axis.horizontal, - itemCount: dayEvents.length, - itemBuilder: (context, index) { - return Container( - margin: EdgeInsets.only(right: 10.0), - child: ButtonTheme( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(5.0), - side: BorderSide( - color: Colors.blue[400], - //Color of the border - style: BorderStyle.solid, - //Style of the border - width: 1.5, //width of the border + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.max, + children: [ + Text( + TranslationBase.of(context).selectAppo, + style: TextStyle( + color: Colors.black, + fontSize: 16.0, + letterSpacing: -0.64, + fontWeight: FontWeight.w600, + ), + ), + mHeight(12), + Container( + decoration: cardRadius(12), + child: _buildTableCalendarWithBuilders(projectViewModel), + ), + mHeight(12), + Text( + selectedDate, + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.bold, + letterSpacing: -0.64, + ), + ), + mHeight(8), + CovidTimeSlots.areSlotsAvailable + ? Container( + height: 40, + child: ListView.builder( + controller: _scrollController, + scrollDirection: Axis.horizontal, + itemCount: dayEvents.length, + itemBuilder: (context, index) { + return Container( + margin: EdgeInsets.only(right: (index == dayEvents.length - 1) ? 0 : 5.0, left: index == 0 ? 0 : 5), + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5.0), + side: BorderSide( + color: index == selectedButtonIndex ? CustomColors.green : Colors.black, //Color of the border + style: BorderStyle.solid, //Style of the border + width: 1.5, //width of the border + ), + ), + minWidth: MediaQuery.of(context).size.width * 0.2, + child: index == selectedButtonIndex ? getSelectedButton(index) : getNormalButton(index)), + ); + }, ), - ), - minWidth: - MediaQuery.of(context).size.width * 0.2, - child: index == selectedButtonIndex - ? getSelectedButton(index) - : getNormalButton(index)), - ); - }, + ) + : Center( + child: Padding( + padding: const EdgeInsets.only(left: 12.0, right: 12.0), + child: Text(TranslationBase.of(context).noSlotsError, style: TextStyle(fontSize: 14.0, fontWeight: FontWeight.w600, letterSpacing: -0.46, color: CustomColors.grey)), + )), + ], ), ), - _buildTableCalendarWithBuilders(projectViewModel), + SizedBox( + height: 100.0, + ), ], ), ), - SizedBox( - height: 100.0, - ), - ], + ), ), - ), - ), - bottomSheet: Container( - margin: EdgeInsets.all(10.0), - child: Flex( - direction: Axis.horizontal, - children: [ - Expanded( - flex: 1, - child: Container( - margin: EdgeInsets.fromLTRB(10.0, 0.0, 5.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, - disabledTextColor: Colors.white, - disabledColor: Colors.grey[500], - onPressed: () { - bookCovidTestAppointment(); - }, - child: Text(TranslationBase.of(context).bookNow, style: TextStyle(fontSize: 18.0)), + Container( + margin: EdgeInsets.zero, + decoration: cardRadius(0), + child: Container( + width: double.infinity, + 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: CustomTextButton( + backgroundColor: CustomColors.green, + elevation: 0, + onPressed: () { + bookCovidTestAppointment(); + }, + child: Text( + TranslationBase.of(context).bookAppo, + style: TextStyle(fontSize: 16.0, letterSpacing: -0.64, color: Colors.white), ), ), ), ), - ], - ), + ) + ], ), ); } Widget _buildTableCalendarWithBuilders(ProjectViewModel projectViewModel) { - return TableCalendar( - locale: projectViewModel.isArabic ? 'ar_SA' : 'en_US', - calendarController: _calendarController, - events: _events, - initialCalendarFormat: CalendarFormat.month, - startDay: DateTime.now(), - formatAnimation: FormatAnimation.slide, - startingDayOfWeek: StartingDayOfWeek.sunday, - weekendDays: [DateTime.friday, DateTime.saturday], - availableGestures: AvailableGestures.horizontalSwipe, - availableCalendarFormats: const { - CalendarFormat.month: '', - CalendarFormat.week: '', - }, - calendarStyle: CalendarStyle( - outsideDaysVisible: false, - weekendStyle: TextStyle().copyWith(color: Colors.blue[800]), - holidayStyle: TextStyle().copyWith(color: Colors.blue[800]), - ), - daysOfWeekStyle: DaysOfWeekStyle( - weekendStyle: TextStyle().copyWith(color: Colors.blue[600]), - ), - headerStyle: HeaderStyle( - centerHeaderTitle: true, - formatButtonVisible: false, - ), - builders: CalendarBuilders( - selectedDayBuilder: (context, date, _) { - return FadeTransition( - opacity: Tween(begin: 0.0, end: 1.0).animate(_animationController), - child: Container( - margin: const EdgeInsets.all(4.0), - padding: const EdgeInsets.only(top: 5.0, left: 6.0), - color: Colors.transparent, - width: 0, - height: 0, - child: Text( - '${date.day}', - style: TextStyle().copyWith(fontSize: 16.0), - ), - ), - ); - }, - todayDayBuilder: (context, date, _) { - return Container( - decoration: BoxDecoration( - shape: BoxShape.circle, - color: _calendarController.isSelected(date) - ? Colors.green[400] - : _calendarController.isToday(date) - ? Colors.brown[300] - : Colors.blue[400], - ), - width: 40.0, - height: 40.0, - child: Center( - child: Text( - '${date.day}', - style: TextStyle().copyWith( - color: Colors.white, - fontSize: 14.0, - ), - ), - ), - ); - }, - markersBuilder: (context, date, events, holidays) { - final children = []; - - if (events.isNotEmpty) { - children.add( - Positioned( - right: 4, - bottom: 4, - child: _buildEventsMarker(date, events), - ), - ); - } - - return children; - }, - ), - onDaySelected: (date, event, _) { - _onDaySelected( - date, - event, - projectViewModel - ); - _animationController.forward(from: 0.0); + return SfCalendar( + controller: _calendarController, + minDate: DateTime.now(), + showNavigationArrow: true, + headerStyle: CalendarHeaderStyle(textAlign: TextAlign.center, textStyle: TextStyle(fontSize: 14.0, fontWeight: FontWeight.w600, letterSpacing: -0.46)), + viewHeaderStyle: ViewHeaderStyle(dayTextStyle: TextStyle(fontSize: 12.0, fontWeight: FontWeight.w600, letterSpacing: -0.46, color: CustomColors.black)), + view: CalendarView.month, + todayHighlightColor: CustomColors.green, + selectionDecoration: containerColorRadiusBorderWidthCircular(Colors.transparent, 4, CustomColors.green, 2.5), + cellBorderColor: Colors.white, + dataSource: MeetingDataSource(_getDataSource()), + monthViewSettings: const MonthViewSettings(appointmentDisplayMode: MonthAppointmentDisplayMode.indicator, showTrailingAndLeadingDates: false, appointmentDisplayCount: 1), + onTap: (CalendarTapDetails details) { + _calendarController.selectedDate = details.date; + _onDaySelected(details.date!, projectViewModel); }, - onVisibleDaysChanged: _onVisibleDaysChanged, - onCalendarCreated: _onCalendarCreated, ); } + List _getDataSource() { + 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(minutes: 20)); + meetings.add(Meeting("", startTime, endTime, CustomColors.green, false, "")); + }); + return meetings; + } + openTimeSlotsPickerForDate(DateTime dateStart, List freeSlots) { dayEvents.clear(); - DateTime dateStartObj = new DateTime( - dateStart.year, dateStart.month, dateStart.day, 0, 0, 0, 0, 0); + DateTime dateStartObj = new DateTime(dateStart.year, dateStart.month, dateStart.day, 0, 0, 0, 0, 0); freeSlots.forEach((v) { if (v.start == dateStartObj) dayEvents.add(v); }); setState(() { - if (dayEvents.length != 0) + if (dayEvents.length != 0) { CovidTimeSlots.areSlotsAvailable = true; - else + selectedButtonIndex = 0; + CovidTimeSlots.selectedTime = dayEvents[selectedButtonIndex].isoTime; + } else CovidTimeSlots.areSlotsAvailable = false; - - selectedButtonIndex = 0; - - CovidTimeSlots.selectedTime = dayEvents[selectedButtonIndex].isoTime; }); } @@ -395,58 +290,59 @@ class _CovidTimeSlotsState extends State final DateFormat formatter = DateFormat('HH:mm'); final DateFormat dateFormatter = DateFormat('yyyy-MM-dd'); for (var i = 0; i < freeSlotsResponse.length; i++) { - date = - DateUtil.convertStringToDate(freeSlotsResponse[i]['FreeTimeSlots']); + date = DateUtil.convertStringToDate(freeSlotsResponse[i]['FreeTimeSlots']); slotsList.add(FreeSlot(date, ['slot'])); - docFreeSlots.add(TimeSlot( - isoTime: formatter.format(date), - start: new DateTime(date.year, date.month, date.day, 0, 0, 0, 0), - end: date)); + docFreeSlots.add(TimeSlot(isoTime: formatter.format(date), start: new DateTime(date.year, date.month, date.day, 0, 0, 0, 0), end: date)); } - _eventsParsed = - Map.fromIterable(slotsList, key: (e) => e.slot, value: (e) => e.event); + _eventsParsed = Map.fromIterable(slotsList, key: (e) => e.slot, value: (e) => e.event); setState(() { - CovidTimeSlots.selectedDate = dateFormatter.format( - DateUtil.convertStringToDate(freeSlotsResponse[0]['FreeTimeSlots'])); - selectedDate = DateUtil.getMonthDayYearDateFormatted( - DateUtil.convertStringToDate(freeSlotsResponse[0]['FreeTimeSlots'])); + CovidTimeSlots.selectedDate = dateFormatter.format(DateUtil.convertStringToDate(freeSlotsResponse[0]['FreeTimeSlots'])); + selectedDate = DateUtil.getMonthDayYearDateFormatted(DateUtil.convertStringToDate(freeSlotsResponse[0]['FreeTimeSlots'])); selectedDateJSON = freeSlotsResponse[0]['FreeTimeSlots']; }); - openTimeSlotsPickerForDate( - DateUtil.convertStringToDate(selectedDateJSON), docFreeSlots); - _calendarController - .setFocusedDay(DateUtil.convertStringToDate(selectedDateJSON)); + openTimeSlotsPickerForDate(DateUtil.convertStringToDate(selectedDateJSON), docFreeSlots); + _calendarController.selectedDate = DateUtil.convertStringToDate(selectedDateJSON); return _eventsParsed; } - Widget _buildEventsMarker(DateTime date, List events) { - return Container( - decoration: BoxDecoration( - shape: BoxShape.circle, - color: _calendarController.isSelected(date) - ? Colors.green[400] - : _calendarController.isToday(date) - ? Colors.brown[300] - : Colors.blue[400], - ), - width: 40.0, - height: 40.0, - child: Center( - child: Text( - '${date.day}', - style: TextStyle().copyWith( - color: Colors.white, - fontSize: 14.0, - ), - ), - ), - ); - } + // Widget _buildEventsMarker(DateTime date, List events) { + // return Container( + // // decoration: BoxDecoration( + // // shape: BoxShape.circle, + // // color: _calendarController.isSelected(date) + // // ? Colors.green[400] + // // : _calendarController.isToday(date) + // // ? Colors.brown[300] + // // : Colors.blue[400], + // // ), + // + // decoration: containerColorRadiusBorderWidth( + // _calendarController.isSelected(date) + // ? CustomColors.green + // : _calendarController.isToday(date) + // ? CustomColors.green.withOpacity(0.5) + // : Colors.white, + // 200, + // _calendarController.isSelected(date) ? CustomColors.green : Colors.black, + // 2), + // width: 40.0, + // height: 40.0, + // child: Center( + // child: Text( + // '${date.day}', + // style: TextStyle().copyWith( + // color: _calendarController.isSelected(date) ? Colors.white : Colors.black, + // fontSize: 13.0, + // ), + // ), + // ), + // ); + // } Widget getNormalButton(int index) { - return RaisedButton( - color: Colors.white, - textColor: new Color(0xFF60686b), + return CustomTextButton( + backgroundColor: Colors.white, + elevation: 0, onPressed: () { setState(() { selectedButtonIndex = index; @@ -454,15 +350,14 @@ class _CovidTimeSlotsState extends State print(CovidTimeSlots.selectedTime); }); }, - child: Text(dayEvents[index].isoTime, - style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold)), + child: Text(dayEvents[index].isoTime!, style: TextStyle(fontSize: 12.0, fontWeight: FontWeight.bold, color: Color(0xFF60686b))), ); } Widget getSelectedButton(int index) { - return RaisedButton( - color: Colors.blue[400], - textColor: Colors.white, + return CustomTextButton( + backgroundColor: CustomColors.green, + elevation: 0, onPressed: () { setState(() { selectedButtonIndex = index; @@ -470,36 +365,74 @@ class _CovidTimeSlotsState extends State print(CovidTimeSlots.selectedTime); }); }, - child: Text(dayEvents[index].isoTime, - style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold)), + child: Text(dayEvents[index].isoTime!, style: TextStyle(fontSize: 12.0, fontWeight: FontWeight.bold, color: Color(0xFF60686b))), ); } bookCovidTestAppointment() { - GifLoaderDialogUtils.showMyDialog(context); - DoctorList docObject = new DoctorList(); - docObject.doctorID = widget.selectedDoctorID; - docObject.clinicID = widget.selectedClinicID; - docObject.projectID = widget.projectID; - insertAppointmentCovidTest(context, docObject); + if (CovidTimeSlots.areSlotsAvailable) { + var messageEn = "This Appointment is being booked for patient " + + projectViewModel.authenticatedUserObject.user!.firstName! + + " " + + projectViewModel.authenticatedUserObject.user!.lastName! + + ", Having file number " + + projectViewModel.authenticatedUserObject.user!.patientID.toString() + + ". Please confirm!"; + var messageAr = "يتم حجز هذا الموعد المراجع " + + projectViewModel.authenticatedUserObject.user!.firstName! + + " " + + projectViewModel.authenticatedUserObject.user!.lastName! + + ", وجود رقم الملف " + + projectViewModel.authenticatedUserObject.user!.patientID.toString() + + ". يرجى تأكيد!"; + ConfirmDialog dialog = new ConfirmDialog( + context: context, + confirmMessage: projectViewModel.isArabic ? messageAr : messageEn, + okText: TranslationBase.of(context).confirm, + cancelText: TranslationBase.of(context).cancel_nocaps, + okFunction: () { + GifLoaderDialogUtils.showMyDialog(context); + DoctorList docObject = new DoctorList(); + docObject.doctorID = widget.selectedDoctorID; + docObject.clinicID = widget.selectedClinicID; + docObject.projectID = widget.projectID; + insertCovidQuestionnaire(context, docObject); + }, + cancelFunction: () => {}); + dialog.showAlertDialog(context); + } else { + AppToast.showErrorToast(message: TranslationBase.of(context).selectSlot); + } + } + + insertCovidQuestionnaire(context, DoctorList docObject) async { + DoctorsListService service = new DoctorsListService(); + List qa = await sharedPref.getObject(COVID_QA_LIST); + service.insertCovidQuestionnaire(qa, widget.projectID!, widget.selectedProject!.testTypeEnum!, projectViewModel.isArabic ? 1 : 2, widget.selectedProject!.testProcedureEnum!).then((res) { + insertAppointmentCovidTest(context, docObject); + }).catchError((err) { + print(err); + }); + } + + updateCovidQuestionnaire(context, String appoNo) async { + DoctorsListService service = new DoctorsListService(); + service.updateCovidQuestionnaire(appoNo, widget.projectID!, widget.selectedProject!.testTypeEnum!, widget.selectedProject!.testProcedureEnum!).then((res) {}).catchError((err) { + print(err); + }); } insertAppointmentCovidTest(context, DoctorList docObject) { DoctorsListService service = new DoctorsListService(); AppoitmentAllHistoryResultList appo; service - .insertAppointment( - docObject.doctorID, - docObject.clinicID, - docObject.projectID, - CovidTimeSlots.selectedTime, - CovidTimeSlots.selectedDate, - context) + .insertAppointment(docObject.doctorID!, docObject.clinicID!, docObject.projectID!, CovidTimeSlots.selectedTime!, CovidTimeSlots.selectedDate!, 0, projectViewModel.isArabic ? 1 : 2, context, + widget.selectedProcedure!.procedureID!, widget.selectedProject!.testTypeEnum!, widget.selectedProject!.testProcedureEnum) .then((res) { if (res['MessageStatus'] == 1) { - AppToast.showSuccessToast(message: "Appointment Booked Successfully"); - getPatientShare(context, res['AppointmentNo'], docObject.clinicID, - docObject.projectID, docObject); + AppToast.showSuccessToast(message: TranslationBase.of(context).bookedSuccess); + getToDoCount(); + getPatientShare(context, res['AppointmentNo'], docObject.clinicID!, docObject.projectID!, docObject); } else { GifLoaderDialogUtils.hideDialog(context); appo = new AppoitmentAllHistoryResultList(); @@ -530,8 +463,21 @@ class _CovidTimeSlotsState extends State }); } - cancelAppointment(DoctorList docObject, AppoitmentAllHistoryResultList appo, - BuildContext context) { + getToDoCount() { + toDoProvider.setState(0, 0, true, toDoProvider.notificationsCount); + ClinicListService service = new ClinicListService(); + service.getActiveAppointmentNo(context).then((res) { + print(res['AppointmentActiveNumber']); + if (res['MessageStatus'] == 1) { + toDoProvider.setState(res['AppointmentActiveNumber'], res['AncillaryOrderListCount'], true, toDoProvider.notificationsCount); + // toDoProvider.setState(res['AppointmentActiveNumber'], true, toDoProvider.notificationsCount); + } else {} + }).catchError((err) { + print(err); + }); + } + + cancelAppointment(DoctorList docObject, AppoitmentAllHistoryResultList appo, BuildContext context) { ConfirmDialog.closeAlertDialog(context); GifLoaderDialogUtils.showMyDialog(context); DoctorsListService service = new DoctorsListService(); @@ -549,15 +495,14 @@ class _CovidTimeSlotsState extends State }); } - getPatientShare(context, String appointmentNo, int clinicID, int projectID, - DoctorList docObject) { + getPatientShare(context, String appointmentNo, int clinicID, int projectID, DoctorList docObject) { + int languageID = projectViewModel.isArabic ? 1 : 2; DoctorsListService service = new DoctorsListService(); - service - .getPatientShare(appointmentNo, clinicID, projectID, context) - .then((res) { + service.getPatientShare(appointmentNo, clinicID, projectID, languageID, context).then((res) { GifLoaderDialogUtils.hideDialog(context); - print(res); - widget.patientShareResponse = new PatientShareResponse.fromJson(res); + res = res['OnlineCheckInAppointments'][0]; + widget.patientShareResponse = PatientShareResponse.fromJson(res); + updateCovidQuestionnaire(context, appointmentNo); navigateToPaymentAlert(); }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); @@ -569,8 +514,7 @@ class _CovidTimeSlotsState extends State Navigator.push( context, FadePage( - page: CovidPaymentAlert( - patientShareResponse: widget.patientShareResponse), + page: CovidPaymentAlert(patientShareResponse: widget.patientShareResponse!), ), ); } @@ -578,20 +522,13 @@ class _CovidTimeSlotsState extends State getCovidFreeSlots(BuildContext context, int projectID) { CovidDriveThruService service = new CovidDriveThruService(); GifLoaderDialogUtils.showMyDialog(context); - service.getCovidFreeSlots(context, projectID).then((res) { + service.getCovidFreeSlots(context, projectID, widget.selectedProject!.testTypeEnum!, widget.selectedProject!.testProcedureEnum!).then((res) { GifLoaderDialogUtils.hideDialog(context); if (res['MessageStatus'] == 1) { if (res['COVID19_FreeTimeSlots'].length != 0) { freeSlotsResponse = res['COVID19_FreeTimeSlots']; _getJSONSlots().then((value) => { - setState(() => { - widget.selectedClinicID = - freeSlotsResponse[0]['ClinicID'], - widget.selectedDoctorID = - freeSlotsResponse[0]['DoctorID'], - _events.clear(), - _events = value - }) + setState(() => {widget.selectedClinicID = freeSlotsResponse[0]['ClinicID'], widget.selectedDoctorID = freeSlotsResponse[0]['DoctorID'], _events.clear(), _events = value}) }); } else {} } else { @@ -599,7 +536,60 @@ class _CovidTimeSlotsState extends State AppToast.showErrorToast(message: res['ErrorEndUserMessage']); } }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err.toString()); print(err); }); } } + +class MeetingDataSource extends CalendarDataSource { + MeetingDataSource(List source) { + appointments = source; + } + + @override + DateTime getStartTime(int index) { + return _getMeetingData(index)!.from; + } + + @override + DateTime getEndTime(int index) { + return _getMeetingData(index)!.to; + } + + @override + String getSubject(int index) { + return _getMeetingData(index)!.eventName; + } + + @override + Color getColor(int index) { + return _getMeetingData(index)!.background; + } + + @override + bool isAllDay(int index) { + return _getMeetingData(index)!.isAllDay; + } + + Meeting? _getMeetingData(int index) { + final dynamic meeting = appointments![index]; + Meeting? meetingData; + if (meeting is Meeting) { + meetingData = meeting; + } + return meetingData; + } +} + +class Meeting { + Meeting(this.eventName, this.from, this.to, this.background, this.isAllDay, this.notes); + + String eventName; + DateTime from; + DateTime to; + Color background; + bool isAllDay; + String notes; +} diff --git a/lib/pages/Covid-DriveThru/covid-dirvethru-questions.dart b/lib/pages/Covid-DriveThru/covid-dirvethru-questions.dart new file mode 100644 index 00000000..334bf759 --- /dev/null +++ b/lib/pages/Covid-DriveThru/covid-dirvethru-questions.dart @@ -0,0 +1,324 @@ +import 'dart:convert'; + +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/CovidDriveThru/CovidPaymentInfoResponse.dart'; +import 'package:diplomaticquarterapp/models/CovidDriveThru/CovidTestProceduresResponse.dart'; +import 'package:diplomaticquarterapp/models/CovidDriveThru/DriveThroughTestingCenterModel.dart'; +import 'package:diplomaticquarterapp/pages/medical/labs/passport_update_page.dart'; +import 'package:diplomaticquarterapp/services/covid-drivethru/covid-drivethru.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_new.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'; + +import 'covid-payment-details.dart'; + +class CovidDirveThruQuestions extends StatefulWidget { + final String projectId; + final List proceduresList; + DriveThroughTestingCenterModel selectedProject; + + CovidDirveThruQuestions({required this.projectId, required this.proceduresList, required this.selectedProject}); + + @override + CovidDirveThruQuestionsState createState() => CovidDirveThruQuestionsState(); +} + +class CovidDirveThruQuestionsState extends State { + late List qa; + + @override + void initState() { + super.initState(); + qa = getQuestionsFromJson(); + } + + late TranslationBase localize; + late ProjectViewModel projectViewModel; + + @override + Widget build(BuildContext context) { + localize = TranslationBase.of(context); + var isArabic = localize.isArabic(); + projectViewModel = Provider.of(context); + return AppScaffold( + appBarTitle: TranslationBase.of(context).covidTest, + isShowAppBar: true, + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: CustomColors.appBackgroudGrey2Color, + body: Column( + children: [ + Expanded( + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: double.infinity, + child: Container( + decoration: cardRadius(12), + margin: EdgeInsets.zero, + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).covidBookAppo, + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 16, + letterSpacing: -0.64, + ), + ), + mHeight(6), + Row( + children: [ + Text( + TranslationBase.of(context).patientName + ":", + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 10, + letterSpacing: -0.6, + color: CustomColors.grey, + ), + ), + mWidth(3), + Text( + projectViewModel.user!.firstName! + " " + projectViewModel.user!.lastName!, + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 12, + letterSpacing: -0.48, + ), + ), + ], + ), + Row( + children: [ + Text( + TranslationBase.of(context).nationalIdNumber + ":", + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 10, + letterSpacing: -0.6, + color: CustomColors.grey, + ), + ), + mWidth(3), + Text( + projectViewModel.user!.patientIdentificationNo!, + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 12, + letterSpacing: -0.48, + ), + ), + ], + ), + ], + ), + ), + ), + ), + mHeight(12), + Text( + TranslationBase.of(context).covidQuestionnaire, + style: TextStyle( + fontSize: 16, + letterSpacing: -0.64, + fontWeight: FontWeight.bold, + ), + ), + mHeight(12), + ListView.separated( + itemCount: qa.length, + physics: NeverScrollableScrollPhysics(), + shrinkWrap: true, + itemBuilder: (ctx, idx) { + var obj = qa[idx]; + var qtext = isArabic ? obj["questionAR"] : obj["questionEN"]; + + return Padding( + padding: const EdgeInsets.symmetric(vertical: 10), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + qtext, + style: TextStyle( + fontSize: 12, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + ), + ), + Row( + children: [ + Expanded( + child: Row( + children: [ + Radio( + value: 1, + groupValue: obj["ans"], + onChanged: (newValue) { + setState(() { + obj["ans"] = newValue; + checkAllChecked(); + }); + }), + Text( + localize.yes, + style: TextStyle( + fontSize: 12, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + ), + ), + ], + ), + ), + Expanded( + child: Row( + children: [ + Radio( + value: 0, + groupValue: obj["ans"], + onChanged: (newValue) { + setState(() { + obj["ans"] = newValue; + checkAllChecked(); + }); + }), + Text( + localize.no, + style: TextStyle( + fontSize: 12, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + ), + ), + ], + ), + ) + ], + ), + ], + ), + ); + }, + separatorBuilder: (ctx, idx) => Container(), + ), + ], + ), + ), + ), + ), + Card( + margin: EdgeInsets.zero, + elevation: 0, + child: Container( + padding: EdgeInsets.all(12), + child: FractionallySizedBox( + widthFactor: 1, + child: MaterialButton( + height: 50, + elevation: 0, + color: all2 ? CustomColors.accentColor : CustomColors.grey, + disabledColor: Theme.of(context).appBarTheme.backgroundColor!.withOpacity(0.25), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), + child: Text( + localize.next, + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.bold, + letterSpacing: -0.44, + color: Colors.white, + ), + ), + onPressed: next, + ), + ), + ), + ), + ], + )); + } + + bool all2 = false; + + checkAllChecked() { + all2 = true; + qa.forEach((element) { + if (element["ans"] == 2 || element["ans"] == null) { + all2 = false; + } + }); + } + + next() async { + var sharedPref = new AppSharedPreferences(); + bool all = true; + qa.forEach((element) { + all = all && (element["ans"] == 1 || element["ans"] == 0); + }); + if (all) if (qa[0]["ans"] == 1) { + sharedPref.setObject(COVID_QA_LIST, qa); + openPassportUpdatePage(); + } else { + sharedPref.setObject(COVID_QA_LIST, qa); + getPaymentInfo(context, widget.projectId); + } + else + AppToast.showErrorToast(message: localize.pleaseSelectAllQuestionToContinue); + } + + openPassportUpdatePage() { + Navigator.push(context, FadePage(page: PassportUpdatePage())).then((value) { + print(value); + if (value != null && value == true) { + getPaymentInfo(context, widget.projectId); + } + }); + } + + List getQuestionsFromJson() { + var questionsJson = """ + [{ "id": 1, "questionEN": "Is the test intended for travel?", "questionAR": "هل تجري التحليل بغرض السفر؟", "ans": 2 }, { "id": 2, "questionEN": "Coming from outside KSA within last 2 weeks?", "questionAR": "هل قدمت من خارج المملكة خلال الأسبوعين الماضيين؟", "ans": 2 }, { "id": 3, "questionEN": "Do you currently have fever?", "questionAR": "هل تعاني حاليا من حرارة؟", "ans": 2 }, { "id": 4, "questionEN": "Did you have fever in last 2 weeks?", "questionAR": "هل عانيت من حرارة في الأسبوعين الماضيين؟", "ans": 2 }, { "id": 5, "questionEN": "Do you have a sore throat?", "questionAR": "هل لديك التهاب في الحلق؟", "ans": 2 }, { "id": 6, "questionEN": "Do you have a runny nose?", "questionAR": "هل لديك سيلان بالأنف؟" }, { "id": 7, "questionEN": "Do you have a cough?", "questionAR": "هل لديك سعال؟", "ans": 2 }, { "id": 8, "questionEN": "Do you have shortness of breath?", "questionAR": "هل تعاني من ضيق في التنفس؟", "ans": 2 }, { "id": 9, "questionEN": "Do you have nausea?", "questionAR": "هل تعاني من غثيان؟", "ans": 2 }, { "id": 10, "questionEN": "Do you have vomiting?", "questionAR": "هل تعاني من القيء؟", "ans": 2 }, { "id": 11, "questionEN": "Do you have a headache?", "questionAR": "هل تعاني من صداع في الرأس؟", "ans": 2 }, { "id": 12, "questionEN": "Do you have muscle pain?", "questionAR": "هل تعانين من آلام عضلية؟", "ans": 2 }, { "id": 13, "questionEN": "Do you have joint pain?", "questionAR": "هل تعاني من آلام المفاصل؟", "ans": 2 }, { "id": 14, "questionEN": "Do you have diarrhea?", "questionAR": "هل لديك اسهال؟", "ans": 2 } ]"""; + var map = json.decode(questionsJson) as List; + return map; + } + + getPaymentInfo(BuildContext context, String projectID) { + CovidDriveThruService service = new CovidDriveThruService(); + CovidPaymentInfoResponse covidPaymentInfoResponse = new CovidPaymentInfoResponse(); + GifLoaderDialogUtils.showMyDialog(context); + service.getCovidPaymentInformation(context, int.parse(projectID), widget.proceduresList[0].procedureID!, widget.selectedProject.testTypeEnum!, widget.selectedProject.testProcedureEnum!).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res['MessageStatus'] == 1) { + covidPaymentInfoResponse = CovidPaymentInfoResponse.fromJson(res['COVID19_PatientShare']); + Navigator.push( + context, + FadePage( + page: CovidPaymentDetails( + covidPaymentInfoResponse: covidPaymentInfoResponse, + projectID: int.parse(projectID), + proceduresList: widget.proceduresList, + selectedProject: widget.selectedProject, + ))); + } else {} + }).catchError((err) { + print(err); + }); + } +} diff --git a/lib/pages/Covid-DriveThru/covid-drivethru-location.dart b/lib/pages/Covid-DriveThru/covid-drivethru-location.dart index a8cb5048..2c0c1164 100644 --- a/lib/pages/Covid-DriveThru/covid-drivethru-location.dart +++ b/lib/pages/Covid-DriveThru/covid-drivethru-location.dart @@ -1,38 +1,57 @@ +import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/CovidDriveThru/CovidPaymentInfoResponse.dart'; +import 'package:diplomaticquarterapp/models/CovidDriveThru/CovidTestProceduresResponse.dart'; import 'package:diplomaticquarterapp/models/CovidDriveThru/DriveThroughTestingCenterModel.dart'; import 'package:diplomaticquarterapp/pages/Covid-DriveThru/covid-payment-details.dart'; import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/services/covid-drivethru/covid-drivethru.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.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/custom_text_button.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; import 'package:maps_launcher/maps_launcher.dart'; import 'package:provider/provider.dart'; +import 'covid-dirvethru-questions.dart'; + class CovidDrivethruLocation extends StatefulWidget { @override _CovidDrivethruLocationState createState() => _CovidDrivethruLocationState(); } class _CovidDrivethruLocationState extends State { - String projectDropdownValue; + String projectDropdownValue = ''; List projectsList = []; + List proceduresList = []; bool isLocationSelected = false; String projectLat = ""; String projectLong = ""; String projectName = ""; String projectID = ""; + List imagesInfo = []; + + DriveThroughTestingCenterModel? selectedProject; + final GlobalKey locationDropdownKey = GlobalKey(); - ProjectViewModel projectViewModel; + late ProjectViewModel projectViewModel; @override void initState() { - WidgetsBinding.instance - .addPostFrameCallback((_) => getProjectsList(context)); + imagesInfo.add( + ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/covid/en/0.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/covid/ar/0.png'), + ); + WidgetsBinding.instance.addPostFrameCallback((_) { + if (projectViewModel.isLogin) { + getProjectsList(context); + } + }); super.initState(); } @@ -42,209 +61,226 @@ class _CovidDrivethruLocationState extends State { return AppScaffold( appBarTitle: TranslationBase.of(context).covidTest, isShowAppBar: true, - body: SingleChildScrollView( - child: Container( - margin: EdgeInsets.fromLTRB(15.0, 15.0, 15.0, 0.0), - child: Column( - children: [ - Container( - alignment: projectViewModel.isArabic - ? Alignment.centerRight - : Alignment.centerLeft, - child: Text(TranslationBase.of(context).resultHeader, - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 22.0, - color: Colors.black)), - ), - Container( - margin: EdgeInsets.only(top: 10.0), - child: Text(TranslationBase.of(context).covidInfo, - style: TextStyle(fontSize: 16.0, color: Colors.black)), - ), - Container( - margin: EdgeInsets.only(top: 20.0), - alignment: projectViewModel.isArabic - ? Alignment.centerRight - : Alignment.centerLeft, - child: Text(TranslationBase.of(context).selectLocation, - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 18.0, - letterSpacing: 0.8, - color: Colors.grey[700])), - ), - Container( - height: 60.0, - decoration: BoxDecoration( - color: Colors.white, - border: Border.all( - color: Colors.grey[400], - width: 1.0, - ), - borderRadius: BorderRadius.circular(10), - ), - padding: EdgeInsets.all(8.0), - width: MediaQuery.of(context).size.width, - margin: EdgeInsets.only(top: 15.0), - child: DropdownButtonHideUnderline( - child: DropdownButton( - hint: new Text(TranslationBase.of(context).selectAddress), - value: projectDropdownValue, - items: projectsList.map((item) { - return new DropdownMenuItem( - value: item.iD.toString(), - child: new Text(item.projectName), - ); - }).toList(), - onChanged: (newValue) { - setState(() { - projectDropdownValue = newValue; - setProjectLocation(newValue); - }); - }, - ), - )), - isLocationSelected - ? Container( - margin: EdgeInsets.only(top: 15.0), - alignment: projectViewModel.isArabic - ? Alignment.centerRight - : Alignment.centerLeft, - child: Text(TranslationBase.of(context).selectLocation, - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 18.0, - letterSpacing: 0.8, - color: Colors.black)), - ) - : Container(), - isLocationSelected - ? Container( - margin: EdgeInsets.only(top: 5.0), - decoration: BoxDecoration( - border: Border.all(color: Colors.grey[400], width: 1.0), + imagesInfo: imagesInfo, + description: TranslationBase.of(context).covidInfo, + isShowDecPage: true, + showNewAppBarTitle: true, + showNewAppBar: true, + backgroundColor: CustomColors.appBackgroudGrey2Color, + body: Column( + children: [ + Expanded( + child: SingleChildScrollView( + child: Container( + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Padding( + padding: const EdgeInsets.only(left: 14, right: 14), + child: Column( + children: [ + Container( + alignment: projectViewModel.isArabic ? Alignment.centerRight : Alignment.centerLeft, + child: Text(TranslationBase.of(context).resultHeader, style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18.0, color: Colors.black, letterSpacing: -1.14)), + ), + Container( + margin: EdgeInsets.only(top: 6.0), + child: Text(TranslationBase.of(context).covidInfo, style: TextStyle(fontSize: 14.0, color: Colors.black, letterSpacing: -0.56)), + ), + Container( + width: double.infinity, + decoration: containerRadius(Colors.white, 12), + margin: EdgeInsets.only(top: 12), + padding: EdgeInsets.only(left: 10, right: 10, top: 12, bottom: 12), + child: Row( + children: [ + Flexible( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).selectLocation, + style: TextStyle( + fontSize: 11, + letterSpacing: -0.44, + fontWeight: FontWeight.w600, + ), + ), + Container( + height: 20, + child: DropdownButtonHideUnderline( + //Dropdown duplicate issue + child: DropdownButton( + onTap: () { + print("Clicked"); + }, + key: locationDropdownKey, + hint: new Text( + TranslationBase.of(context).selectAddress, + ), + value:selectedProject ==null || selectedProject!.projectName.isNotEmpty ?selectedProject :null, + iconSize: 0, + isExpanded: true, + style: TextStyle(fontSize: 14, letterSpacing: -0.56, color: Colors.black, fontFamily: projectViewModel.isArabic ? 'Cairo' : 'Poppins'), + items: projectsList.map((DriveThroughTestingCenterModel item) { + return new DropdownMenuItem( + value: item, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [Text(item.projectName==null ? "" : item.projectName), getCovidTestTypeImage(item)], + ), + ); + }).toList(), + onChanged: (newValue) { + setState(() { + selectedProject = newValue!; + setProjectLocation(newValue); + }); + }, + ), + ), + ), + ], + ), + ), + Icon(Icons.keyboard_arrow_down), + ], + ), + ), + ], ), - child: Image.network( - "https://maps.googleapis.com/maps/api/staticmap?center=" + - this.projectLat + - "," + - this.projectLong + - "&zoom=15&size=800x400&maptype=roadmap&markers=color:red%7C" + - this.projectLat + - "," + - this.projectLong + - "&key=AIzaSyCyDbWUM9d_sBUGIE8PcuShzPaqO08NSC8"), - ) - : Container(), - ], - ), - ), - ), - bottomSheet: Container( - height: MediaQuery.of(context).size.height * 0.15, - width: double.infinity, - child: Column( - children: [ - Container( - margin: EdgeInsets.only(top: 10.0), - child: ButtonTheme( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10.0), - ), - minWidth: MediaQuery.of(context).size.width * 0.91, - height: 45.0, - child: RaisedButton( - color: new Color(0xFFc5272d), - textColor: Colors.white, - disabledTextColor: Colors.white, - disabledColor: Colors.red[300], - onPressed: () { - getDirections(); - }, - child: Text(TranslationBase.of(context).getDirections, - style: TextStyle(fontSize: 18.0)), + ), + mHeight(20), + isLocationSelected + ? Stack( + children: [ + Container( + margin: EdgeInsets.only(top: 5.0), + child: Image.network("https://maps.googleapis.com/maps/api/staticmap?center=" + + this.projectLat + + "," + + this.projectLong + + "&zoom=15&size=800x400&maptype=roadmap&markers=color:red%7C" + + this.projectLat + + "," + + this.projectLong + + "&key=AIzaSyCyDbWUM9d_sBUGIE8PcuShzPaqO08NSC8"), + ), + Row( + mainAxisAlignment: MainAxisAlignment.end, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + InkWell( + onTap: () { + getDirections(); + }, + child: Container( + decoration: cardRadius(1000), + margin: EdgeInsets.all(12), + child: Padding( + padding: const EdgeInsets.only(left: 12, right: 12, top: 6, bottom: 6), + child: Row( + children: [ + Padding( + padding: const EdgeInsets.all(3.0), + child: SvgPicture.asset( + "assets/images/new/direction.svg", + width: 13, + height: 13, + ), + ), + mWidth(6), + Text( + TranslationBase.of(context).getDirections, + style: TextStyle( + color: Colors.black, + fontSize: 11, + letterSpacing: -0.44, + fontWeight: FontWeight.w600, + ), + ) + ], + ), + ), + ), + ), + ], + ), + ], + ) + : SizedBox( + height: MediaQuery.of(context).size.height * 0.35, + ), + mHeight(12), + ], ), ), ), - Container( - margin: EdgeInsets.fromLTRB(10.0, 5.0, 10.0, 5.0), - child: Flex( - direction: Axis.horizontal, - children: [ - Expanded( - flex: 1, - child: Container( - margin: EdgeInsets.fromLTRB(10.0, 0.0, 5.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, - disabledTextColor: Colors.white, - disabledColor: Colors.grey[500], - onPressed: () { - back(); - }, - child: Text(TranslationBase.of(context).back, - style: TextStyle(fontSize: 18.0)), - ), - ), - ), + ), + Card( + elevation: 0, + margin: EdgeInsets.zero, + child: Container( + width: double.infinity, + padding: EdgeInsets.only(left: 12, right: 12, top: 12, bottom: 12), + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), ), - Expanded( - flex: 1, - child: Container( - margin: EdgeInsets.fromLTRB(10.0, 0.0, 5.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, - disabledTextColor: Colors.white, - disabledColor: Colors.grey[500], - onPressed: () { - next(); - }, - child: Text(TranslationBase.of(context).next, - style: TextStyle(fontSize: 18.0)), - ), - ), + minWidth: MediaQuery.of(context).size.width * 0.7, + height: 45.0, + child: CustomTextButton( + backgroundColor: CustomColors.accentColor, + disabledForegroundColor: CustomColors.accentColor.withOpacity(0.38), + disabledBackgroundColor: CustomColors.accentColor.withOpacity(0.12), + elevation: 0, + onPressed: () { + next(); + }, + child: Text( + TranslationBase.of(context).next, + style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold, letterSpacing: -0.44, color: Colors.white), ), ), - ], - ), - ), - ], - ), + )), + ), + ], ), ); } + Widget getCovidTestTypeImage(DriveThroughTestingCenterModel item) { + if (item.testTypeEnum == 1) { + return Container(child: SvgPicture.asset("assets/images/new/DriveThru.svg", width: 20.0)); + } + if (item.testTypeEnum == 2) { + return Container(child: SvgPicture.asset("assets/images/new/WalkIn.svg", width: 10.0)); + } + if (item.testTypeEnum == 3) { + return Row( + children: [ + Container(child: SvgPicture.asset("assets/images/new/WalkIn.svg", width: 10.0)), + Container(padding: EdgeInsets.only(left: 5.0, right: 5.0), child: SvgPicture.asset("assets/images/new/DriveThru.svg", width: 20.0)), + ], + ); + } else { + return SizedBox(); + } + } + getDirections() { if (isLocationSelected) { - MapsLauncher.launchCoordinates(double.parse(projectLat), - double.parse(projectLong), this.projectName); + MapsLauncher.launchCoordinates(double.parse(projectLat), double.parse(projectLong), this.projectName); } else { - Utils.showErrorToast( - "Please select address from the dropdown menu to get directions"); + Utils.showErrorToast("Please select address from the dropdown menu to get directions"); } } next() { if (isLocationSelected) { - getPaymentInfo(context, projectID); + Navigator.push(context, FadePage(page: CovidDirveThruQuestions(projectId: projectID, proceduresList: proceduresList, selectedProject: selectedProject!))); } else { - Utils.showErrorToast( - "Please select address from the dropdown menu to continue"); + Utils.showErrorToast("Please select address from the dropdown menu to continue"); } } @@ -252,59 +288,69 @@ class _CovidDrivethruLocationState extends State { Navigator.of(context).popAndPushNamed(HOME); } - setProjectLocation(newValue) { - print(newValue); + setProjectLocation(DriveThroughTestingCenterModel newValue) { setState(() { - this.projectLat = - projectsList[(int.parse(newValue) - 1)].latitude.toString(); - this.projectLong = - projectsList[(int.parse(newValue) - 1)].longitude.toString(); - this.projectName = projectsList[(int.parse(newValue) - 1)].projectName; - this.projectID = - projectsList[(int.parse(newValue) - 1)].projectID.toString(); + this.projectLat = newValue.latitude.toString(); + this.projectLong = newValue.longitude.toString(); + this.projectName = newValue.projectName; + this.projectID = newValue.projectID.toString(); isLocationSelected = true; }); + getTestProcedures(context); } getPaymentInfo(BuildContext context, String projectID) { CovidDriveThruService service = new CovidDriveThruService(); + CovidPaymentInfoResponse covidPaymentInfoResponse = new CovidPaymentInfoResponse(); + GifLoaderDialogUtils.showMyDialog(context); + service.getCovidPaymentInformation(context, int.parse(projectID), proceduresList[0].procedureID!, selectedProject!.testTypeEnum!, selectedProject!.testProcedureEnum!).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res['MessageStatus'] == 1) { + setState(() { + covidPaymentInfoResponse = CovidPaymentInfoResponse.fromJson(res['COVID19_PatientShare']); + }); + Navigator.push( + context, + FadePage( + page: CovidPaymentDetails( + covidPaymentInfoResponse: covidPaymentInfoResponse, + projectID: int.parse(projectID), + proceduresList: proceduresList, + selectedProject: selectedProject!, + ))); + } else {} + }).catchError((err) { + print(err); + }); + } - CovidPaymentInfoResponse covidPaymentInfoResponse = - new CovidPaymentInfoResponse(); - + getTestProcedures(BuildContext context) { + CovidDriveThruService service = new CovidDriveThruService(); GifLoaderDialogUtils.showMyDialog(context); - service - .getCovidPaymentInformation(context, int.parse(projectID)) - .then((res) { - GifLoaderDialogUtils.hideDialog(context); - if (res['MessageStatus'] == 1) { - setState(() { - covidPaymentInfoResponse = CovidPaymentInfoResponse.fromJson( - res['COVID19_PatientShare']); - print(covidPaymentInfoResponse.procedureNameField); - }); - Navigator.push( - context, - FadePage( - page: CovidPaymentDetails( - covidPaymentInfoResponse: covidPaymentInfoResponse, - projectID: int.parse(projectID), - ))); - } else {} - }) - .catchError((err) { - print(err); + service.getCovidTestProceduresList(context, selectedProject!.testTypeEnum!, selectedProject!.testProcedureEnum!, selectedProject!.projectID!).then((res) { + if (res['MessageStatus'] == 1) { + setState(() { + res['COVID19_TestProceduresList'].forEach((v) { + proceduresList.add(new CovidTestProceduresResponse.fromJson(v)); + }); }); + print(proceduresList.length); + print(proceduresList[0].procedureName); + GifLoaderDialogUtils.hideDialog(context); + } else {} + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); } getProjectsList(BuildContext context) { CovidDriveThruService service = new CovidDriveThruService(); GifLoaderDialogUtils.showMyDialog(context); service.getCovidProjectsList(context).then((res) { - print(res); + projectsList.clear(); if (res['MessageStatus'] == 1) { - print(res); setState(() { res['List_COVID19_ProjectDriveThroughTestingCenter'].forEach((v) { projectsList.add(new DriveThroughTestingCenterModel.fromJson(v)); diff --git a/lib/pages/Covid-DriveThru/covid-payment-alert.dart b/lib/pages/Covid-DriveThru/covid-payment-alert.dart index ca6640c0..60ab52c0 100644 --- a/lib/pages/Covid-DriveThru/covid-payment-alert.dart +++ b/lib/pages/Covid-DriveThru/covid-payment-alert.dart @@ -2,19 +2,20 @@ import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/models/Appointments/PatientShareResposne.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/pages/Covid-DriveThru/covid-payment-summary.dart'; -import 'package:diplomaticquarterapp/pages/ToDoList/payment_method_select.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.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/custom_text_button.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; class CovidPaymentAlert extends StatefulWidget { PatientShareResponse patientShareResponse; - CovidPaymentAlert({@required this.patientShareResponse}); + CovidPaymentAlert({required this.patientShareResponse}); @override _CovidPaymentAlertState createState() => _CovidPaymentAlertState(); @@ -22,220 +23,142 @@ class CovidPaymentAlert extends StatefulWidget { class _CovidPaymentAlertState extends State { AppSharedPreferences sharedPref = AppSharedPreferences(); - AuthenticatedUser authUser; + late AuthenticatedUser authUser; @override Widget build(BuildContext context) { return AppScaffold( appBarTitle: TranslationBase.of(context).covidTest, isShowAppBar: true, - body: SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - height: 200.0, - color: new Color(0xFFc5272d), - child: Row( + showNewAppBarTitle: true, + showNewAppBar: true, + backgroundColor: CustomColors.appBackgroudGrey2Color, + body: Column( + children: [ + Expanded( + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( - margin: EdgeInsets.only(left: 50.0), - child: SvgPicture.asset( - 'assets/images/new-design/alert_icon.svg', - width: 80.0, - height: 80.0), - ), - Container( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.center, + color: new Color(0xFFc5272d), + padding: EdgeInsets.all(20), + child: Row( children: [ - Container( - margin: EdgeInsets.only(left: 30.0, right: 20.0), - child: Text(TranslationBase.of(context).covidAlert, - style: TextStyle( - color: Colors.white, - fontWeight: FontWeight.bold, - fontSize: 24.0)), + Icon( + Icons.warning_outlined, + color: Colors.white, ), - Container( - width: MediaQuery.of(context).size.width * 0.55, - margin: EdgeInsets.only( - left: 30.0, right: 20.0, top: 5.0), + mWidth(12), + Expanded( child: Text( - TranslationBase.of(context).covidAlertHeader, - // "Pay With-in 15 mins to confirm the appointment", - overflow: TextOverflow.clip, - style: TextStyle( - color: Colors.white, fontSize: 20.0)), - ), + TranslationBase.of(context).covidAlertHeader, + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.w600, + fontSize: 16.0, + letterSpacing: -0.64, + ), + ), + ) ], ), ), - ], - ), - ), - Container( - margin: EdgeInsets.only(left: 20.0, right: 20.0, top: 30.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - alignment: Alignment.center, - child: Text(TranslationBase.of(context).covidAlertMins, - overflow: TextOverflow.clip, - style: TextStyle( - color: new Color(0xFFc5272d), - fontSize: 24.0, - fontWeight: FontWeight.bold)), - ), - Container( - alignment: Alignment.center, - margin: EdgeInsets.only(top: 15.0), - child: Text( - TranslationBase.of(context).covidAlertInfo, - textAlign: TextAlign.center, - style: TextStyle( - color: Colors.grey[700], - fontSize: 18.0, - letterSpacing: 0.8)), - ), Container( - margin: EdgeInsets.only( - top: 40.0, bottom: 10.0, left: 0.0, right: 20.0), - child: Text(TranslationBase.of(context).appoInfo, - style: TextStyle( - fontSize: 18.0, - color: Colors.grey[700], - fontWeight: FontWeight.bold)), - ), - Container( - margin: EdgeInsets.only(left: 0.0, bottom: 20.0), - width: MediaQuery.of(context).size.width, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - color: Colors.grey[200], - boxShadow: [ - BoxShadow(color: Colors.grey, spreadRadius: 2), - ], - ), + margin: EdgeInsets.only(left: 20.0, right: 20.0, top: 30.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Container( - margin: EdgeInsets.only( - top: 15.0, bottom: 10.0, left: 20.0, right: 20.0), - child: Text(TranslationBase.of(context).covidTest, - style: TextStyle( - fontSize: 18.0, - color: Colors.black, - fontWeight: FontWeight.bold)), - ), - Container( - margin: EdgeInsets.only(bottom: 10.0), - child: Row( - children: [ - Container( - margin: - EdgeInsets.only(left: 20.0, right: 20.0), - child: Icon( - Icons.local_hospital, - size: 24, - color: Colors.grey[700], - )), - Container( - child: Text( - widget.patientShareResponse.projectName != - null - ? widget - .patientShareResponse.projectName - : "NULL", - style: TextStyle( - fontSize: 18.0, - color: Colors.grey[700])), - ), - ], - ), - ), - Container( - margin: EdgeInsets.only(bottom: 10.0), - child: Row( - children: [ - Container( - margin: - EdgeInsets.only(left: 20.0, right: 20.0), - child: Icon( - Icons.date_range, - size: 24, - color: Colors.grey[700], - )), - Container( - child: Text( - widget.patientShareResponse - .appointmentDate != - null - ? getDate(widget.patientShareResponse - .appointmentDate) - .split(" ")[0] - : "NULL", - style: TextStyle( - fontSize: 18.0, - color: Colors.grey[700])), - ), - ], + Text( + TranslationBase.of(context).covidAlertMins, + style: TextStyle( + fontSize: 19.0, + letterSpacing: -1.6, + fontWeight: FontWeight.bold, ), ), - Container( - margin: EdgeInsets.only(bottom: 10.0), - child: Row( - children: [ - Container( - margin: - EdgeInsets.only(left: 20.0, right: 20.0), - child: Icon( - Icons.access_time, - size: 24, - color: Colors.grey[700], - )), - Container( - child: Text( - widget.patientShareResponse - .appointmentDate != - null - ? getDate(widget.patientShareResponse - .appointmentDate) - .split(" ")[1] - : "NULL", - style: TextStyle( - fontSize: 18.0, - color: Colors.grey[700])), - ), - ], + Text( + TranslationBase.of(context).covidAlertInfo, + style: TextStyle( + color: Colors.grey[700], + fontSize: 14.0, + letterSpacing: -0.56, ), ), + mHeight(20), Container( - margin: EdgeInsets.only(bottom: 10.0), - child: Row( - children: [ - Container( - margin: - EdgeInsets.only(left: 20.0, right: 20.0), - child: SvgPicture.asset( - "assets/images/new-design/track_icon.svg", - width: 20.0, - height: 20.0)), - Container( - child: Text( - widget.patientShareResponse.doctorNameObj != - null - ? widget - .patientShareResponse.doctorNameObj - : "NULL", + width: double.infinity, + child: Container( + margin: EdgeInsets.zero, + decoration: cardRadius(12), + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).appoInfo, style: TextStyle( - fontSize: 18.0, - color: Colors.grey[700])), + fontSize: 16.0, + letterSpacing: -0.64, + fontWeight: FontWeight.bold, + ), + ), + mHeight(16), + Row( + children: [ + _getNormalText( + TranslationBase.of(context).hospital + ":", + ), + mWidth(6), + _getNormalText( + widget.patientShareResponse.projectName != null ? widget.patientShareResponse.projectName : "NULL", + isBold: true, + ), + ], + ), + mHeight(4), + Row( + children: [ + _getNormalText( + TranslationBase.of(context).date + ":", + ), + mWidth(6), + _getNormalText( + DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(widget.patientShareResponse.appointmentDate)), + isBold: true, + ), + ], + ), + mHeight(4), + Row( + children: [ + _getNormalText( + TranslationBase.of(context).time + ":", + ), + mWidth(6), + _getNormalText( + DateUtil.formatDateToTimeLang(DateUtil.convertStringToDate(widget.patientShareResponse.appointmentDate), false), + isBold: true, + ), + ], + ), + mHeight(4), + Row( + children: [ + _getNormalText( + TranslationBase.of(context).route + ":", + ), + mWidth(6), + _getNormalText( + widget.patientShareResponse.doctorNameObj != null ? widget.patientShareResponse.doctorNameObj : "NULL", + isBold: true, + ), + ], + ), + ], ), - ], + ), ), ), ], @@ -244,39 +167,52 @@ class _CovidPaymentAlertState extends State { ], ), ), - ], - ), - ), - bottomSheet: Container( - margin: EdgeInsets.all(10.0), - child: Flex( - direction: Axis.horizontal, - children: [ - Expanded( - flex: 1, - child: Container( - margin: EdgeInsets.fromLTRB(10.0, 0.0, 5.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, - disabledTextColor: Colors.white, - disabledColor: Colors.grey[500], - onPressed: () { - startPaymentProcess(); - }, - child: Text(TranslationBase.of(context).next, style: TextStyle(fontSize: 18.0)), + ), + Card( + margin: EdgeInsets.zero, + elevation: 0, + child: Container( + margin: EdgeInsets.all(12), + width: double.infinity, + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + minWidth: MediaQuery.of(context).size.width * 0.7, + height: 45.0, + child: CustomTextButton( + backgroundColor: CustomColors.accentColor, + disabledForegroundColor: Colors.grey[500]!.withOpacity(0.38), + disabledBackgroundColor: Colors.grey[500]!.withOpacity(0.12), + elevation: 0, + onPressed: () { + startPaymentProcess(); + }, + child: Text( + TranslationBase.of(context).next, + style: TextStyle( + fontSize: 16.0, + letterSpacing: -0.48, + color: Colors.white, + ), ), ), ), ), - ], - ), + ), + ], + ), + ); + } + + _getNormalText(text, {bool isBold = false}) { + return Text( + text, + style: TextStyle( + fontSize: isBold ? 12 : 10, + letterSpacing: -0.5, + color: isBold ? Colors.black : Colors.grey[700], + fontWeight: FontWeight.w600, ), ); } @@ -285,31 +221,31 @@ class _CovidPaymentAlertState extends State { navigateToPaymentMethod(context, widget.patientShareResponse); } - Future navigateToPaymentMethod( - context, PatientShareResponse patientShareResponse) async { + Future navigateToPaymentMethod(context, PatientShareResponse patientShareResponse) async { 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)); setState(() { authUser = data; }); } Navigator.push( - context, FadePage(page: PaymentMethod())) - .then((value) { - print(value); - if (value != null) { - Navigator.push( - context, - FadePage( - page: CovidPaymentSummary( - patientShareResponse: widget.patientShareResponse, - selectedPaymentMethod: value.toString()), - ), - ); - } - }); + context, + FadePage( + page: CovidPaymentSummary(patientShareResponse: widget.patientShareResponse, selectedPaymentMethod: "MADA"), + ), + ); + // Navigator.push(context, FadePage(page: PaymentMethod())).then((value) { + // print(value); + // if (value != null) { + // Navigator.push( + // context, + // FadePage( + // page: CovidPaymentSummary(patientShareResponse: widget.patientShareResponse, selectedPaymentMethod: value.toString()), + // ), + // ); + // } + // }); } String getDate(String appoDate) { diff --git a/lib/pages/Covid-DriveThru/covid-payment-details.dart b/lib/pages/Covid-DriveThru/covid-payment-details.dart index e6c87d0a..fe8c64dc 100644 --- a/lib/pages/Covid-DriveThru/covid-payment-details.dart +++ b/lib/pages/Covid-DriveThru/covid-payment-details.dart @@ -1,18 +1,28 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/CovidDriveThru/CovidPaymentInfoResponse.dart'; +import 'package:diplomaticquarterapp/models/CovidDriveThru/CovidTestProceduresResponse.dart'; +import 'package:diplomaticquarterapp/models/CovidDriveThru/DriveThroughTestingCenterModel.dart'; import 'package:diplomaticquarterapp/pages/Covid-DriveThru/Covid-TimeSlots.dart'; +import 'package:diplomaticquarterapp/services/covid-drivethru/covid-drivethru.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/custom_text_button.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; +import 'package:provider/provider.dart'; +import 'package:url_launcher/url_launcher.dart'; class CovidPaymentDetails extends StatefulWidget { CovidPaymentInfoResponse covidPaymentInfoResponse; int projectID; + List proceduresList; + late CovidTestProceduresResponse selectedProcedure; + DriveThroughTestingCenterModel selectedProject; - CovidPaymentDetails( - {@required this.covidPaymentInfoResponse, @required this.projectID}); + CovidPaymentDetails({required this.covidPaymentInfoResponse, required this.projectID, required this.proceduresList, required this.selectedProject}); @override _CovidPaymentDetailsState createState() => _CovidPaymentDetailsState(); @@ -21,211 +31,271 @@ class CovidPaymentDetails extends StatefulWidget { class _CovidPaymentDetailsState extends State { bool isAgree = false; + @override + void initState() { + widget.selectedProcedure = widget.proceduresList[0]; + super.initState(); + } + @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); return AppScaffold( appBarTitle: TranslationBase.of(context).covidTest, isShowAppBar: true, - body: SingleChildScrollView( - child: Container( - margin: EdgeInsets.fromLTRB(15.0, 15.0, 15.0, 0.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - height: 150.0, - decoration: BoxDecoration( - image: DecorationImage( - image: AssetImage( - "assets/images/new-design/covid-19-big-banner-bg.png"), - fit: BoxFit.fill, - ), - color: Colors.white.withOpacity(0.3), - borderRadius: BorderRadius.all(Radius.circular(10))), - child: Row( + showNewAppBarTitle: true, + showNewAppBar: true, + backgroundColor: CustomColors.appBackgroudGrey2Color, + body: Container( + // margin: EdgeInsets.fromLTRB(15.0, 15.0, 15.0, 100.0), + + child: Column( + children: [ + Expanded( + child: Padding( + padding: EdgeInsets.all(16), + child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Container( - margin: - EdgeInsets.only(left: 15.0, right: 15.0, top: 30.0), - child: SvgPicture.asset( - 'assets/images/new-design/covid-19-car.svg', - width: 90.0, - height: 90.0), + Text(TranslationBase.of(context).covidSelectProcedure, style: TextStyle(color: Colors.black, fontSize: 16.0, letterSpacing: -0.64, fontWeight: FontWeight.bold)), + ...List.generate( + widget.proceduresList.length, + (index) => Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: 1, + ), + Row( + children: [ + Expanded( + flex: 1, + child: InkWell( + onTap: () { + setState(() { + widget.selectedProcedure = widget.proceduresList[index]; + getPaymentInfo(context, widget.projectID.toString(), widget.selectedProcedure.procedureID!); + }); + }, + child: Row( + children: [ + Radio( + value: widget.proceduresList[index], + groupValue: widget.selectedProcedure, + activeColor: Colors.red[800], + toggleable: true, + onChanged: (value) { + setState(() { + widget.selectedProcedure = value!; + print(widget.selectedProcedure.procedureName); + getPaymentInfo(context, widget.projectID.toString(), widget.selectedProcedure.procedureID!); + }); + }, + ), + Text( + projectViewModel.isArabic ? widget.proceduresList[index].procedureNameN! : widget.proceduresList[index].procedureName!, + style: TextStyle( + fontSize: 12.0, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + ), + ), + ], + ), + ), + ) + ], + ), + ], + ), ), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - margin: EdgeInsets.only( - left: 20.0, right: 20.0, top: 20.0), - child: Text(TranslationBase.of(context).covidTest, - style: TextStyle( - color: Colors.white, - fontWeight: FontWeight.bold, - fontSize: 24.0)), - ), - Container( - margin: EdgeInsets.only( - left: 20.0, right: 20.0, top: 10.0), - child: Text(TranslationBase.of(context).driveThru, - style: TextStyle( - color: Colors.white, fontSize: 24.0)), + Container( + decoration: cardRadius(12), + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(TranslationBase.of(context).testFee, + style: TextStyle( + color: Colors.black, + fontSize: 16.0, + fontWeight: FontWeight.w600, + letterSpacing: -0.64, + )), + Container( + width: double.infinity, + padding: EdgeInsets.only(top: 10, bottom: 3), + child: Row( + children: [ + Expanded( + child: _getNormalText(TranslationBase.of(context).patientShareToDo), + ), + Expanded( + child: _getNormalText(widget.covidPaymentInfoResponse.patientShareField.toString(), isBold: true), + ) + ], + ), + ), + mDivider(Colors.grey[200]!), + Container( + width: double.infinity, + padding: EdgeInsets.only(top: 3, bottom: 3), + child: Row( + children: [ + Expanded( + child: _getNormalText(TranslationBase.of(context).patientTaxToDo), + ), + Expanded( + child: _getNormalText(widget.covidPaymentInfoResponse.patientTaxAmountField.toString(), isBold: true), + ) + ], + ), + ), + mDivider(Colors.grey[200]!), + Container( + width: double.infinity, + padding: EdgeInsets.only(top: 3, bottom: 3), + child: Row( + children: [ + Expanded( + child: _getNormalText(TranslationBase.of(context).patientShareTotalToDo), + ), + Expanded( + child: _getNormalText(widget.covidPaymentInfoResponse.patientShareWithTaxField.toString(), isBold: true), + ) + ], + ), + ), + ], ), - ], + ), ), - ], - ), - ), - Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10.0), - color: Colors.white), - margin: EdgeInsets.fromLTRB(0.0, 30.0, 0.0, 5.0), - padding: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 20.0), - child: Column( - children: [ Container( - alignment: Alignment.center, - margin: - EdgeInsets.only(left: 0.0, right: 20.0, top: 30.0), - child: Text(TranslationBase.of(context).testFee, - style: TextStyle( - color: Colors.black, - fontSize: 22.0, - fontWeight: FontWeight.bold)), - ), - Table( - children: [ - TableRow(children: [ - TableCell( - child: _getNormalText(TranslationBase.of(context) - .patientShareToDo)), - TableCell( - child: _getNormalText(widget - .covidPaymentInfoResponse.patientShareField - .toString())), - ]), - TableRow(children: [ - TableCell( - child: _getNormalText( - TranslationBase.of(context).patientTaxToDo)), - TableCell( - child: _getNormalText(widget - .covidPaymentInfoResponse - .patientTaxAmountField - .toString())), - ]), - TableRow(children: [ - TableCell( - child: _getNormalText(TranslationBase.of(context) - .patientShareTotalToDo)), - TableCell( - child: _getNormalText(widget - .covidPaymentInfoResponse - .patientShareWithTaxField - .toString())), - ]), - ], + margin: EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 0.0), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Checkbox( + value: isAgree, + onChanged: (value) { + setState(() { + isAgree = !isAgree; + }); + }, + activeColor: Color(0xffB8382C), + ), + Text( + TranslationBase.of(context).agreeTo, + style: TextStyle( + fontSize: 12, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + ), + ), + mWidth(3), + InkWell( + onTap: () { + launch("https://hmg.com/en/Pages/Privacy.aspx"); + }, + child: Text( + TranslationBase.of(context).termsConditoins, + style: TextStyle( + fontSize: 12, + letterSpacing: -0.48, + color: CustomColors.accentColor, + fontWeight: FontWeight.w600, + decoration: TextDecoration.underline, + ), + ), + ), + ], + ), ), - ], - ), - ), - Container( - margin: EdgeInsets.fromLTRB(0.0, 15.0, 0.0, 5.0), - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Checkbox( - value: isAgree, - onChanged: (value) { - setState(() { - isAgree = !isAgree; - }); - }, - activeColor: Colors.blue, + mFlex(1), + Text( + TranslationBase.of(context).payOptions, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 12.0, + fontWeight: FontWeight.w600, + letterSpacing: -0.46, + ), ), - Texts(TranslationBase.of(context) - .iAgreeToTheTermsAndConditions), + Container(margin: EdgeInsets.fromLTRB(20.0, 5.0, 20.0, 5.0), child: getPaymentMethods()), ], ), ), - Divider( - color: Colors.grey, - ), - Container( - alignment: Alignment.center, - margin: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 5.0), - child: Text(TranslationBase.of(context).payOptions, - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.bold, - fontFamily: "Open-Sans")), - ), - Container( - alignment: Alignment.center, - margin: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 5.0), - child: Image.asset( - "assets/images/new-design/payment_options_invoice_confirmation.png", - width: 300), - ), - ], - ), - ), - ), - bottomSheet: Container( - margin: EdgeInsets.fromLTRB(10.0, 5.0, 10.0, 20.0), - child: Flex( - direction: Axis.horizontal, - children: [ - Expanded( - flex: 1, - child: Container( - margin: EdgeInsets.fromLTRB(10.0, 0.0, 5.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, - disabledTextColor: Colors.white, - disabledColor: Colors.grey[500], - onPressed: () { - cancel(); - }, - child: Text(TranslationBase.of(context).cancel, - style: TextStyle(fontSize: 18.0)), - ), - ), - ), ), - Expanded( - flex: 1, - child: Container( - margin: EdgeInsets.fromLTRB(10.0, 0.0, 5.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, - disabledTextColor: Colors.white, - disabledColor: Colors.grey[500], - onPressed: isAgree ? next : null, - child: Text(TranslationBase.of(context).next, - style: TextStyle(fontSize: 18.0)), + Container( + width: double.infinity, + child: Card( + elevation: 0, + margin: EdgeInsets.zero, + child: Padding( + padding: const EdgeInsets.only(top: 12, bottom: 12, left: 12, right: 12), + child: Row( + children: [ + Expanded( + flex: 1, + child: Container( + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + minWidth: MediaQuery.of(context).size.width * 0.7, + height: 45.0, + child: CustomTextButton( + backgroundColor: CustomColors.accentColor, + disabledForegroundColor: Colors.grey[500]!.withOpacity(0.38), + disabledBackgroundColor: Colors.grey[500]!.withOpacity(0.12), + elevation: 0, + onPressed: () { + cancel(); + }, + child: Text( + TranslationBase.of(context).cancel_nocaps, + style: TextStyle( + fontSize: 16.0, + letterSpacing: -0.48, + color: Colors.white, + fontWeight: FontWeight.w600, + ), + ), + ), + ), + ), + ), + mWidth(12), + Expanded( + flex: 1, + child: Container( + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + minWidth: MediaQuery.of(context).size.width * 0.7, + height: 45.0, + child: CustomTextButton( + backgroundColor: CustomColors.green, + disabledForegroundColor: Colors.grey[500]!.withOpacity(0.38), + disabledBackgroundColor: Colors.grey[500]!.withOpacity(0.12), + elevation: 0, + onPressed: isAgree ? next : null, + child: Text( + TranslationBase.of(context).next, + style: TextStyle(fontSize: 16.0, letterSpacing: -0.48, fontWeight: FontWeight.w600, color: Colors.white), + ), + ), + ), + ), + ), + ], ), ), ), - ), + ) ], ), ), @@ -233,28 +303,37 @@ class _CovidPaymentDetailsState extends State { } void next() { - Navigator.push( - context, - FadePage( - page: CovidTimeSlots( - projectID: widget.projectID, - ))); + Navigator.push(context, FadePage(page: CovidTimeSlots(projectID: widget.projectID, selectedProcedure: widget.selectedProcedure, selectedProject: widget.selectedProject))); } cancel() { Navigator.pop(context); } - _getNormalText(text) { - return Container( - margin: EdgeInsets.only(top: 20.0, right: 10.0), - child: Text(text, - textAlign: TextAlign.end, - style: TextStyle( - fontSize: 15, - fontFamily: 'Open-Sans', - letterSpacing: 0.5, - color: Colors.grey[700])), + getPaymentInfo(BuildContext context, String projectID, String selectedProcedureID) { + CovidDriveThruService service = new CovidDriveThruService(); + GifLoaderDialogUtils.showMyDialog(context); + service.getCovidPaymentInformation(context, int.parse(projectID), selectedProcedureID, widget.selectedProject.testTypeEnum!, widget.selectedProject.testProcedureEnum!).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res['MessageStatus'] == 1) { + setState(() { + widget.covidPaymentInfoResponse = CovidPaymentInfoResponse.fromJson(res['COVID19_PatientShare']); + }); + } else {} + }).catchError((err) { + print(err); + }); + } + + _getNormalText(text, {bool isBold = false}) { + return Text( + text, + style: TextStyle( + fontSize: isBold ? 12 : 10, + letterSpacing: -0.5, + color: isBold ? Colors.black : Colors.grey[700], + fontWeight: FontWeight.w600, + ), ); } } diff --git a/lib/pages/Covid-DriveThru/covid-payment-summary.dart b/lib/pages/Covid-DriveThru/covid-payment-summary.dart index e71285b5..384b2422 100644 --- a/lib/pages/Covid-DriveThru/covid-payment-summary.dart +++ b/lib/pages/Covid-DriveThru/covid-payment-summary.dart @@ -1,17 +1,23 @@ +import 'dart:io'; + +import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; import 'package:diplomaticquarterapp/models/Appointments/PatientShareResposne.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; -import 'package:diplomaticquarterapp/pages/Blood/new_text_Field.dart'; import 'package:diplomaticquarterapp/pages/BookAppointment/QRCode.dart'; +import 'package:diplomaticquarterapp/pages/ToDoList/payment_method_select.dart'; +import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; +import 'package:diplomaticquarterapp/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'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.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/dragable_sheet.dart'; import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; @@ -19,28 +25,35 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; class CovidPaymentSummary extends StatefulWidget { - PatientShareResponse patientShareResponse; - - final String selectedPaymentMethod; - MyInAppBrowser browser; - AuthenticatedUser authenticatedUser; + PatientShareResponse? patientShareResponse; + String selectedPaymentMethod; + String? selectedInstallmentPlan; + MyInAppBrowser? browser; + AuthenticatedUser? authenticatedUser; AppSharedPreferences sharedPref = AppSharedPreferences(); - String transID = ""; - CovidPaymentSummary( - {@required this.patientShareResponse, this.selectedPaymentMethod}); + CovidPaymentSummary({required this.patientShareResponse, required this.selectedPaymentMethod}); @override _CovidPaymentSummaryState createState() => _CovidPaymentSummaryState(); } class _CovidPaymentSummaryState extends State { + late ProjectViewModel projectViewModel; + late String tamaraPaymentStatus; + late String tamaraOrderID; + + String transID = ""; + @override Widget build(BuildContext context) { - ProjectViewModel projectViewModel = Provider.of(context); + projectViewModel = Provider.of(context); return AppScaffold( appBarTitle: TranslationBase.of(context).covidTest, isShowAppBar: true, + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: CustomColors.appBackgroudGrey2Color, body: SingleChildScrollView( physics: ScrollPhysics(), child: Container( @@ -48,30 +61,69 @@ class _CovidPaymentSummaryState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Texts( + Text( TranslationBase.of(context).confirmThePayment, - textAlign: TextAlign.center, - fontWeight: FontWeight.w500, - fontSize: 24, + style: TextStyle( + fontSize: 19, + fontWeight: FontWeight.bold, + letterSpacing: -1.46, + ), ), SizedBox( height: 12, ), Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ + Text( + TranslationBase.of(context).totalBalance + ": ", + style: TextStyle( + fontSize: 12, + letterSpacing: -0.60, + ), + ), + Text( + '${widget.patientShareResponse!.patientShareWithTax} ' + TranslationBase.of(context).sar, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.bold, + letterSpacing: -0.60, + ), + ) + ], + ), + SizedBox( + height: 12, + ), + Row( + children: [ + Container( + width: 20, + height: 20, + decoration: containerColorRadiusBorderWidth(CustomColors.accentColor, 200, Colors.white, 4), + ), Container( height: 100.0, padding: EdgeInsets.all(7.0), - width: MediaQuery.of(context).size.width * 0.45, - child: - Image.asset(getImagePath(widget.selectedPaymentMethod)), + child: Image.asset(getImagePath(widget.selectedPaymentMethod!), width: 100, height: 100), ), - Texts( - '${widget.patientShareResponse.patientShareWithTax} ' + - TranslationBase.of(context).sar, - fontSize: 26, - bold: true, + mFlex(1), + InkWell( + onTap: () { + showDraggableDialog( + context, + PaymentMethod( + onSelectedMethod: (String metohd, [String? selectedInstallmentPlan]) { + widget.selectedPaymentMethod = metohd; + widget.selectedInstallmentPlan = selectedInstallmentPlan; + setState(() {}); + }, + patientShare: widget.patientShareResponse!.patientShareWithTax, + )); + }, + child: Text( + TranslationBase.of(context).changePayment, + style: TextStyle(fontWeight: FontWeight.w600, fontSize: 12, letterSpacing: -0.48, decoration: TextDecoration.underline, color: CustomColors.accentColor), + ), ) ], ), @@ -81,63 +133,74 @@ class _CovidPaymentSummaryState extends State { Row( children: [ Expanded( - child: Container( - margin: EdgeInsets.all(3), - child: NewTextFields( - hintText: TranslationBase.of(context).fileNumber, - initialValue: - projectViewModel.user.patientID.toString(), - isEnabled: false, - ), + flex: 1, + child: showDetail( + TranslationBase.of(context).fileNumber, + projectViewModel.user!.patientID.toString(), ), ), + mWidth(6), Expanded( - child: Container( - margin: EdgeInsets.all(3), - child: NewTextFields( - hintText: TranslationBase.of(context).name, - initialValue: projectViewModel.user.firstName, - isEnabled: false, - ), + flex: 1, + child: showDetail( + TranslationBase.of(context).name, + projectViewModel.user!.firstName.toString(), ), ), ], ), SizedBox( - height: 12, - ), - NewTextFields( - hintText: TranslationBase.of(context).mobileNumber, - initialValue: projectViewModel.user.mobileNumber, - isEnabled: false, + height: 6, ), + showDetail(TranslationBase.of(context).mobileNumber, projectViewModel.user!.mobileNumber!), SizedBox( - height: 12, - ), - NewTextFields( - hintText: TranslationBase.of(context).depositorName, - initialValue: projectViewModel.user.firstName + - " " + - projectViewModel.user.middleName + - " " + - projectViewModel.user.lastName, - isEnabled: false, + height: 6, ), + showDetail( + TranslationBase.of(context).depositorName, + projectViewModel.user!.firstName! + " " + projectViewModel.user!.middleName! + " " + projectViewModel.user!.lastName!, + ) ], ), ), ), bottomSheet: Container( - height: MediaQuery.of(context).size.height * 0.1, + color: Theme.of(context).scaffoldBackgroundColor, + margin: EdgeInsets.only(bottom: 5.0), width: double.infinity, padding: EdgeInsets.all(12), - child: SecondaryButton( - textColor: Colors.white, - color: Theme.of(context).primaryColor, - label: TranslationBase.of(context).confirm.toUpperCase(), - onTap: () { - startPaymentProcess(projectViewModel.user); + child: DefaultButton( + TranslationBase.of(context).confirm.toUpperCase(), + () { + startPaymentProcess(projectViewModel.user!); }, + color: CustomColors.green, + ), + ), + ); + } + + Widget showDetail(String title, String value) { + return Container( + width: double.infinity, + child: Container( + decoration: cardRadius(12), + margin: EdgeInsets.zero, + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title, + style: TextStyle(fontSize: 11, fontWeight: FontWeight.w600, letterSpacing: -0.64), + ), + Text( + value, + style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, letterSpacing: -0.64, color: Colors.grey), + ), + ], + ), ), ), ); @@ -145,66 +208,57 @@ class _CovidPaymentSummaryState extends State { startPaymentProcess(AuthenticatedUser authenticatedUser) { AppoitmentAllHistoryResultList appo = new AppoitmentAllHistoryResultList(); - appo.projectID = widget.patientShareResponse.projectID; - appo.clinicID = widget.patientShareResponse.clinicID; - appo.appointmentNo = widget.patientShareResponse.appointmentNo; + appo.projectID = widget.patientShareResponse!.projectID; + appo.clinicID = widget.patientShareResponse!.clinicID; + appo.appointmentNo = widget.patientShareResponse!.appointmentNo; - openPayment( - widget.selectedPaymentMethod, - authenticatedUser, - double.parse( - widget.patientShareResponse.patientShareWithTax.toString()), - widget.patientShareResponse, - appo); + openPayment(widget.selectedPaymentMethod, authenticatedUser, double.parse(widget.patientShareResponse!.patientShareWithTax.toString()), widget.patientShareResponse!, appo); } - openPayment( - String paymentMethod, - AuthenticatedUser authenticatedUser, - double amount, - PatientShareResponse patientShareResponse, - AppoitmentAllHistoryResultList appo) async { - if (paymentMethod == "ApplePay") { - // await widget.chromeBrowser.open( - // url: "https://applepay-datatrans-sample.herokuapp.com/", - // options: ChromeSafariBrowserClassOptions( - // android: AndroidChromeCustomTabsOptions( - // addDefaultShareMenuItem: false), - // ios: IOSSafariOptions(barCollapsingEnabled: true))); - } else { - widget.browser = new MyInAppBrowser( - onExitCallback: onBrowserExit, - appo: appo, - onLoadStartCallback: onBrowserLoadStart); - - widget.browser.openPaymentBrowser( - amount, - "Appointment check in", - Utils.getAppointmentTransID( - appo.projectID, appo.clinicID, appo.appointmentNo), - appo.projectID.toString(), - authenticatedUser.emailAddress, - paymentMethod, - authenticatedUser.patientType, - authenticatedUser.firstName, - authenticatedUser.patientID, - authenticatedUser, - widget.browser, - widget.patientShareResponse.isLiveCareAppointment, - widget.patientShareResponse.appointmentDate, - widget.patientShareResponse.appointmentNo, - widget.patientShareResponse.clinicID, - widget.patientShareResponse.doctorID); - } + openPayment(String paymentMethod, AuthenticatedUser authenticatedUser, num amount, PatientShareResponse patientShareResponse, AppoitmentAllHistoryResultList appo) async { + widget.browser = new MyInAppBrowser(onExitCallback: onBrowserExit, appo: appo, onLoadStartCallback: onBrowserLoadStart, context: context); + transID = Utils.getAppointmentTransID(appo.projectID, appo.clinicID, appo.appointmentNo); + widget.browser!.openPaymentBrowser( + amount, + "Covid appointment payment", + Utils.getAppointmentTransID(appo.projectID, appo.clinicID, appo.appointmentNo), + appo.projectID.toString(), + authenticatedUser.emailAddress!, + paymentMethod, + authenticatedUser.patientType, + authenticatedUser.firstName!, + authenticatedUser.patientID, + authenticatedUser, + widget.browser!, + widget.patientShareResponse!.isLiveCareAppointment!, + "2", + "", + widget.patientShareResponse!.appointmentDate, + widget.patientShareResponse!.appointmentNo, + widget.patientShareResponse!.clinicID, + widget.patientShareResponse!.doctorID, + widget.selectedInstallmentPlan); } onBrowserLoadStart(String url) { print("onBrowserLoadStart"); print(url); + if (widget.selectedPaymentMethod == "TAMARA") { + if (Platform.isAndroid) { + Uri uri = new Uri.dataFromString(url); + tamaraPaymentStatus = uri.queryParameters['status']!; + tamaraOrderID = uri.queryParameters['AuthorizePaymentId']!; + } else { + Uri uri = new Uri.dataFromString(url); + tamaraPaymentStatus = uri.queryParameters['paymentStatus']!; + tamaraOrderID = uri.queryParameters['orderId']!; + } + } + MyInAppBrowser.successURLS.forEach((element) { if (url.contains(element)) { - if (widget.browser.isOpened()) widget.browser.close(); + if (widget.browser!.isOpened()) widget.browser!.close(); MyInAppBrowser.isPaymentDone = true; return; } @@ -212,7 +266,7 @@ class _CovidPaymentSummaryState extends State { MyInAppBrowser.errorURLS.forEach((element) { if (url.contains(element)) { - if (widget.browser.isOpened()) widget.browser.close(); + if (widget.browser!.isOpened()) widget.browser!.close(); MyInAppBrowser.isPaymentDone = false; return; } @@ -221,18 +275,110 @@ class _CovidPaymentSummaryState extends State { onBrowserExit(AppoitmentAllHistoryResultList appo, bool isPaymentMade) { print("onBrowserExit Called!!!!"); - if (isPaymentMade) checkPaymentStatus(appo); + try { + if (widget.selectedPaymentMethod == "TAMARA") { + // checkTamaraPaymentStatus(Utils.getAppointmentTransID(appo.projectID, appo.clinicID, appo.appointmentNo), appo); + checkTamaraPaymentStatus(transID, appo); + // if (tamaraPaymentStatus != null && tamaraPaymentStatus.toLowerCase() == "approved") { + // updateTamaraRequestStatus("success", "14", Utils.getAppointmentTransID(appo.projectID, appo.clinicID, appo.appointmentNo), tamaraOrderID, num.parse(widget.selectedInstallmentPlan), appo); + // } else { + // updateTamaraRequestStatus("Failed", "00", Utils.getAppointmentTransID(appo.projectID, appo.clinicID, appo.appointmentNo), tamaraOrderID != null ? tamaraOrderID : "", + // num.parse(widget.selectedInstallmentPlan), appo); + // } + } else { + checkPaymentStatus(appo); + } + } catch (err) { + print(err); + } + } + + checkTamaraPaymentStatus(String orderID, AppoitmentAllHistoryResultList appo) { + GifLoaderDialogUtils.showMyDialog(context); + DoctorsListService service = new DoctorsListService(); + service.getTamaraPaymentStatus(orderID).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res["status"].toString().toLowerCase() == "success") { + updateTamaraRequestStatus("success", "14", orderID, tamaraOrderID, int.parse(widget.selectedInstallmentPlan!), appo); + } else { + updateTamaraRequestStatus("Failed", "00", transID, tamaraOrderID != null ? tamaraOrderID : "", + num.parse(widget.selectedInstallmentPlan!), appo); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + + addAdvancedNumberRequestTamara(String advanceNumber, String paymentReference, String appointmentID, AppoitmentAllHistoryResultList appo) { + DoctorsListService service = new DoctorsListService(); + service.addAdvancedNumberRequest(advanceNumber, paymentReference, appointmentID, context).then((res) {}).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + + updateTamaraRequestStatus(String responseMessage, String status, String clientRequestID, String tamaraOrderID, num selectedInstallments, AppoitmentAllHistoryResultList appo) { + GifLoaderDialogUtils.showMyDialog(context); + try { + DoctorsListService service = new DoctorsListService(); + service.updateTamaraRequestStatus(responseMessage, status, clientRequestID, tamaraOrderID, selectedInstallments).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (tamaraPaymentStatus.toLowerCase() == "approved") { + markAppointmentForTamara(appo); + addAdvancedNumberRequestTamara("Tamara-Advance-0000", tamaraOrderID, appo.appointmentNo.toString(), appo); + } + }).catchError((err) { + print(err); + AppToast.showErrorToast(message: err); + GifLoaderDialogUtils.hideDialog(context); + }); + } catch (err) { + print(err); + } + } + + markAppointmentForTamara(AppoitmentAllHistoryResultList appo) { + GifLoaderDialogUtils.showMyDialog(context); + DoctorsListService service = new DoctorsListService(); + service.markAppointmentForTamara(appo.projectID!, appo.appointmentNo.toString()).then((res) { + GifLoaderDialogUtils.hideDialog(context); + getAppoQR(context); + // autoGenerateInvoiceTamara(appo); + }).catchError((err) { + print(err); + AppToast.showErrorToast(message: err); + GifLoaderDialogUtils.hideDialog(context); + }); + } + + autoGenerateInvoiceTamara(AppoitmentAllHistoryResultList appo) { + GifLoaderDialogUtils.showMyDialog(context); + var apptData = { + "AppointmentNo": appo.appointmentNo.toString(), + "DoctorID": appo.doctorID.toString(), + "ServiceID": appo.serviceID.toString(), + "ProjectID": appo.projectID.toString(), + "ClinicID": appo.clinicID.toString(), + "AppointmentDate": appo.appointmentDate.toString(), + }; + DoctorsListService service = new DoctorsListService(); + service.autoGenerateInvoiceTamara(appo.projectID!, appo.appointmentNo.toString(), projectViewModel.user!.mobileNumber!).then((res) { + GifLoaderDialogUtils.hideDialog(context); + getAppoQR(context); + }).catchError((err) { + print(err); + AppToast.showErrorToast(message: err); + GifLoaderDialogUtils.hideDialog(context); + }); } checkPaymentStatus(AppoitmentAllHistoryResultList appo) { GifLoaderDialogUtils.showMyDialog(context); DoctorsListService service = new DoctorsListService(); - service - .checkPaymentStatus( - Utils.getAppointmentTransID( - appo.projectID, appo.clinicID, appo.appointmentNo), - context) - .then((res) { + service.checkPaymentStatus(transID, false, context).then((res) { print("Printing Payment Status Reponse!!!!"); print(res); String paymentInfo = res['Response_Message']; @@ -241,6 +387,11 @@ class _CovidPaymentSummaryState extends State { } else { GifLoaderDialogUtils.hideDialog(context); AppToast.showErrorToast(message: res['Response_Message']); + Navigator.pushAndRemoveUntil( + context, + MaterialPageRoute(builder: (context) => LandingPage()), + (Route route) => false, + ); } }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); @@ -252,13 +403,11 @@ class _CovidPaymentSummaryState extends State { createAdvancePayment(res, AppoitmentAllHistoryResultList appo) { DoctorsListService service = new DoctorsListService(); String paymentReference = res['Fort_id'].toString(); - service - .createAdvancePayment(appo, appo.projectID.toString(), res['Amount'], - res['Fort_id'], res['PaymentMethod'], context) - .then((res) { - print(res['OnlineCheckInAppointments'][0]['AdvanceNumber']); + service.createAdvancePayment(appo, appo.projectID.toString(), res['Amount'], res['Fort_id'], res['PaymentMethod'], context).then((res) { addAdvancedNumberRequest( - res['OnlineCheckInAppointments'][0]['AdvanceNumber'].toString(), + Utils.isVidaPlusProject(projectViewModel, appo.projectID!) + ? res['OnlineCheckInAppointments'][0]['AdvanceNumber_VP'].toString() + : res['OnlineCheckInAppointments'][0]['AdvanceNumber'].toString(), paymentReference, appo.appointmentNo.toString()); }).catchError((err) { @@ -268,14 +417,9 @@ class _CovidPaymentSummaryState extends State { }); } - addAdvancedNumberRequest( - String advanceNumber, String paymentReference, String appointmentID) { + addAdvancedNumberRequest(String advanceNumber, String paymentReference, String appointmentID) { DoctorsListService service = new DoctorsListService(); - service - .addAdvancedNumberRequest( - advanceNumber, paymentReference, appointmentID, context) - .then((res) { - print(res); + service.addAdvancedNumberRequest(advanceNumber, paymentReference, appointmentID, context).then((res) { getAppoQR(context); }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); @@ -286,9 +430,7 @@ class _CovidPaymentSummaryState extends State { getAppoQR(context) { DoctorsListService service = new DoctorsListService(); - service - .generateAppointmentQR(widget.patientShareResponse, context) - .then((res) { + service.generateAppointmentQR(widget.patientShareResponse!, context).then((res) { print(res); GifLoaderDialogUtils.hideDialog(context); navigateToQR(context, res['AppointmentQR']); @@ -312,22 +454,28 @@ class _CovidPaymentSummaryState extends State { String getImagePath(String paymentMethod) { switch (paymentMethod) { case "MADA": - return 'assets/images/new-design/mada.png'; - break; - case "SADAD": - return 'assets/images/new-design/sadad.png'; + return 'assets/images/new/payment/Mada.png'; break; + // case "SADAD": + // return 'assets/images/new-design/sadad.png'; + // break; case "VISA": - return 'assets/images/new-design/visa.png'; + return 'assets/images/new/payment/visa.png'; break; case "MASTERCARD": - return 'assets/images/new-design/mastercard.png'; + return 'assets/images/new/payment/Mastercard.png'; break; case "Installment": - return 'assets/images/new-design/installment.png'; + return 'assets/images/new/payment/installments.png'; + break; + case "ApplePay": + return 'assets/images/new/payment/Apple_Pay.png'; + break; + case "TAMARA": + return 'assets/images/new/payment/tamara.png'; break; } - return 'assets/images/new-design/mada.png'; + return 'assets/images/new/payment/Mada.png'; } } diff --git a/lib/pages/DrawerPages/family/add-family-member.dart b/lib/pages/DrawerPages/family/add-family-member.dart index 35b19ccd..c29c8b20 100644 --- a/lib/pages/DrawerPages/family/add-family-member.dart +++ b/lib/pages/DrawerPages/family/add-family-member.dart @@ -1,23 +1,23 @@ +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/config/size_config.dart'; import 'package:diplomaticquarterapp/core/model/family-file/add_family_file_request.dart'; -import 'package:diplomaticquarterapp/core/model/family-file/insert_share_file_request.dart'; import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; import 'package:diplomaticquarterapp/services/family_files/family_files_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'; 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/dialogs/confirm_dialog.dart'; -import 'package:diplomaticquarterapp/widgets/input/text_field.dart'; import 'package:diplomaticquarterapp/widgets/mobile-no/mobile_no.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/otp/sms-popup.dart'; import 'package:diplomaticquarterapp/widgets/progress_indicator/app_circular_progress_Indeicator.dart'; -import 'package:diplomaticquarterapp/widgets/text/app_texts_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'add-family_type.dart'; @@ -30,7 +30,7 @@ class _AddMember extends State { final util = Utils(); final nationalIDorFile = TextEditingController(); final int loginType = AddFamilyMemberType.loginType; - String mobileNo; + String? mobileNo; String countryCode = '966'; bool isButtonDisabled = true; var sharedPref = new AppSharedPreferences(); @@ -39,6 +39,8 @@ class _AddMember extends State { var familyFileProvider = FamilyFilesProvider(); var patientShareRequestID; + var patientShareResponseID; + @override void initState() { super.initState(); @@ -47,79 +49,75 @@ class _AddMember extends State { @override Widget build(BuildContext context) { return AppScaffold( - appBarTitle: TranslationBase.of(context).myFamilyFiles, - isShowAppBar: true, - body: isLoading == true - ? AppCircularProgressIndicator() - : SingleChildScrollView( - child: Container( - padding: - EdgeInsets.only(top: 10, left: 20, right: 20, bottom: 30), - height: SizeConfig.realScreenHeight * .9, + appBarTitle: TranslationBase.of(context).myFamilyFiles, + isShowAppBar: true, + showNewAppBar: true, + showNewAppBarTitle: true, + body: isLoading == true + ? AppCircularProgressIndicator() + : SingleChildScrollView( + child: Container( + padding: EdgeInsets.all(21.0), + height: SizeConfig.realScreenHeight! * .9, width: SizeConfig.realScreenWidth, - child: Column(children: [ - Expanded( - flex: 2, - child: AppText( - TranslationBase.of(context).enterNationalId, - fontSize: SizeConfig.textMultiplier * 3.5, - textAlign: TextAlign.left, - )), - Expanded( - flex: 3, - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - MobileNo( - onNumberChange: (value) => - {mobileNo = value, validateForm()}, - onCountryChange: (value) => countryCode = value), - Container( - child: TextFields( - controller: nationalIDorFile, - onChanged: (value) => {validateForm()}, - prefixIcon: Icon( - loginType == 1 - ? Icons.chrome_reader_mode - : Icons.receipt, - color: Colors.red), - padding: EdgeInsets.only( - top: 20, bottom: 20, left: 10, right: 10), - hintText: loginType == 1 - ? TranslationBase.of(context).nationalID - : TranslationBase.of(context).fileNo, - )) - ], - ), - ), - Expanded( - flex: 3, + child: Column( + children: [ + Expanded( + flex: 1, + child: Text( + loginType == 1 ? TranslationBase.of(context).enterNationalId : TranslationBase.of(context).enterFile, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64, height: 23 / 16), + )), + Expanded( + flex: 4, child: Column( - mainAxisAlignment: MainAxisAlignment.end, children: [ - Row( - children: [ - Expanded( - child: DefaultButton( - TranslationBase.of(context).add, - () => {this.addMember()}, - color: isButtonDisabled == true - ? Colors.grey - : Colors.grey[900], - textColor: Colors.white, - )) - ], + PhoneNumberSelectorWidget(onNumberChange: (value) => {mobileNo = value, validateForm()}, onCountryChange: (value) => countryCode = value), + SizedBox( + height: 12, ), + inputWidget(loginType == 1 ? TranslationBase.of(context).nationalIdNumber : TranslationBase.of(context).medicalFileNumber, "Xxxxxxxxx", nationalIDorFile), ], - )) - ]), - ))); + ), + ), + // Expanded( + // flex: 3, + // child: Column( + // mainAxisAlignment: MainAxisAlignment.end, + // children: [ + // Row( + // children: [ + // Expanded( + // child: DefaultButton( + // TranslationBase.of(context).add, + // () => {this.addMember()}, + // color: isButtonDisabled == true ? Colors.grey : CustomColors.accentColor, + // textColor: Colors.white, + // ), + // ) + // ], + // ), + // ], + // ), + // ) + ], + ), + ), + ), + bottomSheet: Container( + color: Colors.white, + padding: EdgeInsets.all(21.0), + child: DefaultButton( + TranslationBase.of(context).add, + () => {this.addMember()}, + color: isButtonDisabled == true ? Colors.grey : CustomColors.accentColor, + textColor: Colors.white, + )), + ); } void validateForm() { - if (util.validateIDBox(nationalIDorFile.text, loginType) == true && - mobileNo.length >= 9 && - util.isSAUDIIDValid(nationalIDorFile.text, loginType) == true) { + if (util.validateIDBox(nationalIDorFile.text, loginType) == true && mobileNo!.length >= 9 && util.isSAUDIIDValid(nationalIDorFile.text, loginType) == true) { setState(() { isButtonDisabled = false; }); @@ -145,10 +143,7 @@ class _AddMember extends State { request.isRegister = false; request.patientStatus = 2; loading(true); - familyFileProvider - .addFamilyFile(request) - .then((value) => manageFamily(value)) - .catchError(() { + familyFileProvider.addFamilyFile(request).then((value) => manageFamily(value)).catchError((err) { loading(false); }); } @@ -160,49 +155,54 @@ class _AddMember extends State { confirmMessage: addMemberResult['ShareFamilyFileObj']['Message'], okText: TranslationBase.of(context).confirm, cancelText: TranslationBase.of(context).cancel_nocaps, - okFunction: () => { - insertFamilyData(addMemberResult), - ConfirmDialog.closeAlertDialog(context) - }, + okFunction: () => {insertFamilyData(addMemberResult), ConfirmDialog.closeAlertDialog(context)}, cancelFunction: () => {}); dialog.showAlertDialog(context); } insertFamilyData(addMemberResult) { - var request = InsertSharePatientFileReq(); - request.responseID = addMemberResult['ShareFamilyFileObj']['ReponseID']; - request.shareFamilyPatientName = - addMemberResult['ShareFamilyFileObj']['SharedPatientName']; - request.status = 2; - if (request.patientOutSA == 1) { - request.regionID = 2; - } else { - request.regionID = 1; - } - loading(true); - familyFileProvider - .insertNewMember(request) - .then((value) => sendActivationCode(value)); + + sendActivationCode(addMemberResult, addMemberResult['ShareFamilyFileObj']['IsPatientExcluded']); + // var request = InsertSharePatientFileReq(); + // request.responseID = addMemberResult['ShareFamilyFileObj']['ReponseID']; + // request.shareFamilyPatientName = addMemberResult['ShareFamilyFileObj']['SharedPatientName']; + // request.status = 2; + // if (request.patientOutSA == 1) { + // request.regionID = 2; + // } else { + // request.regionID = 1; + // } + // loading(true); + // familyFileProvider.insertNewMember(request).then((value) => sendActivationCode(value)).catchError((err) { + // loading(false); + // AppToast.showErrorToast(message: err); + // }); } - sendActivationCode(result) { + sendActivationCode(result, bool isExcluded) { // var request = this.getCommonRequest(); loading(true); - patientShareRequestID = result['PatientShareRequestID']; - familyFileProvider - .sendActivationCode(mobileNo, countryCode, nationalIDorFile.text) - .then((result) => { - if (result != null && result['isSMSSent'] == true) - {this.startSMSService(1, result)} - // {loading(false), this.startSMSService(type)} - // else - // {loading(false)} - }); + patientShareResponseID = result['ShareFamilyFileObj']['ReponseID']; + familyFileProvider.sendActivationCode(mobileNo, countryCode, nationalIDorFile.text, patientShareResponseID, isExcluded).then((res) { + patientShareRequestID = res['PatientShareRequestID']; + if (res != null && res['isSMSSent'] == true) + { + this.startSMSService(1, res); + + }else + { + this.checkActivationCodeExcluded('0000', res); + } + + }); } + var tempType; + startSMSService(type, result) { + tempType = type; loading(false); - SMSOTP( + SMSOTP( context, type, mobileNo, @@ -210,30 +210,38 @@ class _AddMember extends State { this.checkActivationCode(value, result); }, () => { - print('Faild..'), + Navigator.pop(context), }, ).displayDialog(context); } + checkActivationCodeExcluded(value, result){ + familyFileProvider.checkActivationCode(result['LogInTokenID'], value, nationalIDorFile.text, mobileNo, patientShareRequestID, patientShareResponseID).then((result) { + SMSOTP.hideSMSBox(context); + handleFamilyRequests(); + }); + } + checkActivationCode(value, result) { - familyFileProvider - .checkActivationCode( - result['LogInTokenID'], value, nationalIDorFile.text, mobileNo) - .then((result) => { - SMSOTP.hideSMSBox(context), - handleFamilyRequests(this.patientShareRequestID, 3) - }); + Navigator.pop(context); + GifLoaderDialogUtils.showMyDialog(context); + familyFileProvider.checkActivationCode(result['LogInTokenID'], value, nationalIDorFile.text, mobileNo, patientShareRequestID, patientShareResponseID).then((result) { + SMSOTP.hideSMSBox(context); + handleFamilyRequests(); + }).catchError((err) { + Future.delayed(Duration(seconds: 1), () { + AppToast.showErrorToast(message: err); + startSMSService(tempType, result); + }); + }); } - handleFamilyRequests(id, stauts) { - familyFileProvider - .acceptAndRejectRecievedRequests(id, stauts) - .then((result) => { - sharedPref.remove(FAMILY_FILE), - Navigator.of(context).pushNamed( - MY_FAMILIY, - ) - }); + handleFamilyRequests() { + Navigator.pop(context); + sharedPref.remove(FAMILY_FILE); + Navigator.of(context).pushNamed( + MY_FAMILIY + ); } loading(flag) { @@ -241,4 +249,86 @@ class _AddMember extends State { isLoading = flag; }); } + + 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(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: TextInputType.number, + controller: _controller, + onChanged: (value) => {validateForm()}, + 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, + ), + 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/DrawerPages/family/add-family_type.dart b/lib/pages/DrawerPages/family/add-family_type.dart index 96e055b3..60e396c6 100644 --- a/lib/pages/DrawerPages/family/add-family_type.dart +++ b/lib/pages/DrawerPages/family/add-family_type.dart @@ -1,13 +1,13 @@ import 'package:diplomaticquarterapp/config/size_config.dart'; +import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/card/rounded_container.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:diplomaticquarterapp/widgets/progress_indicator/app_circular_progress_Indeicator.dart'; import 'package:diplomaticquarterapp/widgets/text/app_texts_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:diplomaticquarterapp/routes.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:diplomaticquarterapp/widgets/habib_logo_widget.dart'; class AddFamilyMemberType extends StatelessWidget { static int loginType = 0; @@ -16,139 +16,204 @@ class AddFamilyMemberType extends StatelessWidget { return AppScaffold( appBarTitle: TranslationBase.of(context).myFamilyFiles, isShowAppBar: true, + showNewAppBar: true, + showNewAppBarTitle: true, body: Padding( - padding: EdgeInsets.all(20), - child: Column( - children: [ - Expanded( - flex: 6, - child: Column( - // mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Image.asset( - 'assets/images/habib-logo.png', - height: 80, - width: 80, - ), - Padding( - padding: EdgeInsets.all(20), - child: AppText( - TranslationBase.of(context).registerInfoFamily, - fontSize: SizeConfig.textMultiplier * 3.5, - textAlign: TextAlign.left, - ), - ), - Padding( - padding: EdgeInsets.all(20), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Expanded( - child: InkWell( - onTap: () => { - AddFamilyMemberType.loginType = 1, - Navigator.of(context) - .pushNamed(ADD_FAMILY_MEMBER) - }, - child: RoundedContainer( - borderColor: Colors.grey, - showBorder: true, - child: Padding( - padding: EdgeInsets.fromLTRB( - 20, 10, 20, 10), - child: Column( - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - Image.asset( - 'assets/images/id_card_icon.png', - height: SizeConfig - .imageSizeMultiplier * - 12, - width: SizeConfig - .imageSizeMultiplier * - 15, - ), - SizedBox( - height: 20, - ), - AppText( - TranslationBase.of(context) - .nationalID, - fontSize: SizeConfig - .textMultiplier * - 2, - ) - ], - ), - )))), - Expanded( - child: InkWell( - onTap: () => { - AddFamilyMemberType.loginType = 2, - Navigator.of(context) - .pushNamed(ADD_FAMILY_MEMBER) - }, - child: RoundedContainer( - borderColor: Colors.grey, - showBorder: true, - child: Padding( - padding: EdgeInsets.fromLTRB( - 25, 10, 25, 10), - child: Column( - children: [ - Image.asset( - 'assets/images/my_file_white_icon.png', - height: SizeConfig - .imageSizeMultiplier * - 12, - width: SizeConfig - .imageSizeMultiplier * - 15, - ), - SizedBox( - height: 20, - ), - AppText( - TranslationBase.of(context) - .fileNo, - fontSize: SizeConfig - .textMultiplier * - 2, - ) - ], - ), - )))) - ], - )), - Divider( - color: Colors.grey, - height: 2, - ), - ]), - ), - // Expanded( - // flex: 2, - // child: Column( - // mainAxisAlignment: MainAxisAlignment.end, - // children: [ - // Row( - // children: [ - // Expanded( - // child: DefaultButton( - // TranslationBase.of(context).registerNow, - // () => { - // Navigator.of(context).pushNamed( - // REGISTER, - // ) - // }, - // )) - // ], - // ), - // ], - // )) - ], - ))); + padding: EdgeInsets.only(bottom: 20, left: 21, right: 21), + child: Column(children: [ + Expanded( + child: ListView( + padding: EdgeInsets.zero, + physics: BouncingScrollPhysics(), + children: [ + SizedBox(height: 21), + HabibLogoWidget(), + SizedBox(height: 21), + Text( + TranslationBase.of(context).registerInfoFamily, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64, height: 23 / 16), + ), + GridView( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, crossAxisSpacing: 13, mainAxisSpacing: 9), + physics: NeverScrollableScrollPhysics(), + padding: EdgeInsets.only(top: 25), + shrinkWrap: true, + children: [ + getButton(context, TranslationBase.of(context).nationalIdNumber, 'assets/images/new/national_id.svg', 1), + getButton(context, TranslationBase.of(context).medicalFileNumber, 'assets/images/new/medical_file.svg', 2), + ], + ), + SizedBox(height: 20), + // RichText( + // text: TextSpan( + // text: TranslationBase.of(context).forgotPassword, + // style: TextStyle(decoration: TextDecoration.underline, fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xffC9272B), letterSpacing: -0.48, height: 18 / 12), + // recognizer: TapGestureRecognizer()..onTap = () => Navigator.of(context).push(FadePage(page: ForgotPassword())), + // ), + // ), + ], + ), + ), + // SizedBox( + // height: 43, + // width: double.infinity, + // child: FlatButton( + // onPressed: () {}, + // child: Text( + // TranslationBase.of(context).registerNow, + // style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Colors.white, letterSpacing: -0.48), + // ), + // color: Color(0xffD02127), + // shape: RoundedRectangleBorder( + // borderRadius: BorderRadius.circular(6), + // ), + // ), + // ), + ]), + )); + // body: Padding( + // padding: EdgeInsets.all(20), + // child: Column( + // children: [ + // Expanded( + // flex: 6, + // child: Column( + // // mainAxisAlignment: MainAxisAlignment.spaceBetween, + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // Image.asset( + // 'assets/images/habib-logo.png', + // height: 80, + // width: 80, + // ), + // Padding( + // padding: EdgeInsets.all(20), + // child: AppText( + // TranslationBase.of(context).registerInfoFamily, + // fontSize: SizeConfig.textMultiplier * 3.5, + // textAlign: TextAlign.left, + // ), + // ), + // Padding( + // padding: EdgeInsets.all(20), + // child: Row( + // mainAxisAlignment: MainAxisAlignment.center, + // children: [ + // Expanded( + // child: InkWell( + // onTap: () => {AddFamilyMemberType.loginType = 1, Navigator.of(context).pushNamed(ADD_FAMILY_MEMBER)}, + // child: RoundedContainer( + // borderColor: Colors.grey, + // showBorder: true, + // child: Padding( + // padding: EdgeInsets.fromLTRB(20, 10, 20, 10), + // child: Column( + // mainAxisAlignment: MainAxisAlignment.center, + // children: [ + // Image.asset( + // 'assets/images/id_card_icon.png', + // height: SizeConfig.imageSizeMultiplier * 12, + // width: SizeConfig.imageSizeMultiplier * 15, + // ), + // SizedBox( + // height: 20, + // ), + // AppText( + // TranslationBase.of(context).idNo, + // fontSize: SizeConfig.textMultiplier * 2, + // ) + // ], + // ), + // )))), + // Expanded( + // child: InkWell( + // onTap: () => {AddFamilyMemberType.loginType = 2, Navigator.of(context).pushNamed(ADD_FAMILY_MEMBER)}, + // child: RoundedContainer( + // borderColor: Colors.grey, + // showBorder: true, + // child: Padding( + // padding: EdgeInsets.fromLTRB(25, 10, 25, 10), + // child: Column( + // children: [ + // Image.asset( + // 'assets/images/my_file_white_icon.png', + // height: SizeConfig.imageSizeMultiplier * 12, + // width: SizeConfig.imageSizeMultiplier * 15, + // ), + // SizedBox( + // height: 20, + // ), + // AppText( + // TranslationBase.of(context).fileNo, + // fontSize: SizeConfig.textMultiplier * 2, + // ) + // ], + // ), + // )))) + // ], + // )), + // Divider( + // color: Colors.grey, + // height: 2, + // ), + // ]), + // ), + // // Expanded( + // // flex: 2, + // // child: Column( + // // mainAxisAlignment: MainAxisAlignment.end, + // // children: [ + // // Row( + // // children: [ + // // Expanded( + // // child: DefaultButton( + // // TranslationBase.of(context).registerNow, + // // () => { + // // Navigator.of(context).pushNamed( + // // REGISTER, + // // ) + // // }, + // // )) + // // ], + // // ), + // // ], + // // )) + // ], + // ))); + } + + Widget getButton(BuildContext _context, String _title, String _icon, int _flag) { + return InkWell( + onTap: () { + AddFamilyMemberType.loginType = _flag; + Navigator.of(_context).pushNamed(ADD_FAMILY_MEMBER); + }, + 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: 38, + width: 38, + ), + Text( + _title, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.48, height: 20 / 16), + ), + ], + ), + ), + ); } } diff --git a/lib/pages/DrawerPages/family/my-family.dart b/lib/pages/DrawerPages/family/my-family.dart index 07f99b16..fa256d11 100644 --- a/lib/pages/DrawerPages/family/my-family.dart +++ b/lib/pages/DrawerPages/family/my-family.dart @@ -1,66 +1,71 @@ import 'dart:ui'; -import 'package:diplomaticquarterapp/config/size_config.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/service/AuthenticatedUserObject.dart'; import 'package:diplomaticquarterapp/core/service/medical/vital_sign_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/appointment_rate_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/extensions/string_extensions.dart'; import 'package:diplomaticquarterapp/locator.dart'; +import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; -import 'package:diplomaticquarterapp/models/Authentication/check_activation_code_response.dart' - as list; +import 'package:diplomaticquarterapp/models/Authentication/check_activation_code_response.dart' as list; import 'package:diplomaticquarterapp/models/FamilyFiles/GetAllSharedRecordByStatusResponse.dart'; -import 'package:diplomaticquarterapp/pages/BookAppointment/widgets/BranchView.dart'; -import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/models/InPatientServices/get_admission_info_response_model.dart'; +import 'package:diplomaticquarterapp/models/InPatientServices/get_admission_request_info_response_model.dart'; import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; import 'package:diplomaticquarterapp/pages/rateAppointment/rate_appointment_doctor.dart'; +import 'package:diplomaticquarterapp/routes.dart'; +import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; import 'package:diplomaticquarterapp/services/family_files/family_files_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'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/uitl/utils.dart'; -import 'package:diplomaticquarterapp/widgets/card/rounded_container.dart'; -import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.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/others/app_expandable_notifier.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:diplomaticquarterapp/widgets/others/bottom_bar.dart'; -import 'package:diplomaticquarterapp/widgets/progress_indicator/app_circular_progress_Indeicator.dart'; import 'package:diplomaticquarterapp/widgets/text/app_texts_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; -import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; -import 'package:diplomaticquarterapp/routes.dart'; +import 'package:flutter_svg/flutter_svg.dart'; import 'package:provider/provider.dart'; class MyFamily extends StatefulWidget { final bool isAppbarVisible; - MyFamily({this.isAppbarVisible = true}); + Function()? onBackClick; + + MyFamily({this.isAppbarVisible = true, this.onBackClick}); + @override _MyFamily createState() => _MyFamily(); } class _MyFamily extends State with TickerProviderStateMixin { - List imagesInfo = List(); + List imagesInfo = []; final familyFileProvider = FamilyFilesProvider(); - AppSharedPreferences sharedPref = new AppSharedPreferences(); + AppSharedPreferences sharedPref = AppSharedPreferences(); var userID; - TabController _tabController; + late TabController _tabController; int _tabIndex = 0; - AuthenticatedUserObject authenticatedUserObject = - locator(); - AppointmentRateViewModel appointmentRateViewModel = - locator(); - ProjectViewModel projectViewModel; - AuthenticatedUser user; + AuthenticatedUserObject authenticatedUserObject = locator(); + AppointmentRateViewModel appointmentRateViewModel = locator(); + late ProjectViewModel projectViewModel; + AuthenticatedUser user = AuthenticatedUser(); VitalSignService _vitalSignService = locator(); - PharmacyModuleViewModel pharmacyModuleViewModel = - locator(); - + PharmacyModuleViewModel pharmacyModuleViewModel = locator(); + late ToDoCountProviderModel toDoProvider; var isVaiable = false; + bool isSwitchUser = false; + @override void initState() { _tabController = new TabController(length: 2, vsync: this, initialIndex: 0); @@ -73,552 +78,340 @@ class _MyFamily extends State with TickerProviderStateMixin { Widget build(BuildContext context) { imagesInfo.add( ImagesInfo( - imageEn: - 'https://hmgwebservices.com/Images/MobileApp/images-info-home/family-file/en/0.png', - imageAr: - 'https://hmgwebservices.com/Images/MobileApp/images-info-home/family-file/ar/0.png'), + imageEn: 'https://hmgwebservices.com/Images/MobileApp/images-info-home/family-file/en/0.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/images-info-home/family-file/ar/0.png'), ); imagesInfo.add( ImagesInfo( - imageEn: - 'https://hmgwebservices.com/Images/MobileApp/images-info-home/family-file/en/1.png', - imageAr: - 'https://hmgwebservices.com/Images/MobileApp/images-info-home/family-file/ar/1.png'), + imageEn: 'https://hmgwebservices.com/Images/MobileApp/images-info-home/family-file/en/1.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/images-info-home/family-file/ar/1.png'), ); projectViewModel = Provider.of(context); + toDoProvider = Provider.of(context, listen: false); return AppScaffold( appBarTitle: TranslationBase.of(context).myFamilyFiles, isShowAppBar: widget.isAppbarVisible, imagesInfo: imagesInfo, + showNewAppBar: true, + showNewAppBarTitle: true, + onTap: widget.isAppbarVisible == false ? widget.onBackClick : null, + icon: "assets/images/new/bottom_nav/family_files.svg", description: TranslationBase.of(context).familyInfo, - body: Scaffold( - extendBodyBehindAppBar: true, - appBar: PreferredSize( - preferredSize: Size.fromHeight(65.0), - child: Stack( - children: [ - Positioned( - bottom: 1, - left: 0, - right: 0, - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10), - child: Container( - color: Theme.of(context) - .scaffoldBackgroundColor - .withOpacity(0.8), - height: 70.0, - ), - ), - ), - Center( - child: Container( - height: 60.0, - margin: EdgeInsets.only(top: 10.0), - width: MediaQuery.of(context).size.width * 0.92, // 0.9, + body: Column( + children: [ + TabBar( + controller: _tabController, + indicatorWeight: 3.0, + indicatorSize: TabBarIndicatorSize.tab, + labelColor: Color(0xff2B353E), + unselectedLabelColor: Color(0xff575757), + labelPadding: EdgeInsets.only(top: 15, bottom: 13, 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: [Text(TranslationBase.of(context).family), Text(TranslationBase.of(context).request)], + ), + Expanded( + child: (user != null && projectViewModel.isLogin) + ? TabBarView( + physics: BouncingScrollPhysics(), + controller: _tabController, + children: [myFamilyDetails(context), myFamilyRequest(context)], + ) + : Container(child: AppText('')), + ), + DefaultButton( + TranslationBase.of(context).addFamilyMember, + () async { + Navigator.of(context).pushNamed(ADD_FAMILY_MEMBER_TYPE); + }, + ).insideContainer, + ], + ), + ); + } + + Widget myFamilyDetails(context) { + return (familySharedRecordsList.length ?? 0) > 0 + ? ListView.separated( + padding: EdgeInsets.all(21), + itemBuilder: (context, index) { + bool isFemale = familySharedRecordsList[index].gender == 2; + if (familySharedRecordsList[index].status == 3) { + return Container( decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Theme.of(context).dividerColor, - width: 0.9), //width: 0.7 - ), - color: Colors.white), - child: Center( - child: TabBar( - isScrollable: true, - controller: _tabController, - indicatorWeight: 5.0, - //indicatorSize: TabBarIndicatorSize.label, - indicatorSize: TabBarIndicatorSize.tab, - - indicatorColor: Theme.of(context).primaryColor, - labelColor: Theme.of(context).primaryColor, - labelPadding: - EdgeInsets.only(top: 4.0, left: 35.0, right: 35.0), - unselectedLabelColor: Colors.grey[800], - tabs: [ - Container( - width: MediaQuery.of(context).size.width * 0.30, - child: Center( - child: AppText(TranslationBase.of(context).family), + borderRadius: BorderRadius.all( + Radius.circular(15), + ), + gradient: LinearGradient( + colors: isFemale + ? [ + Color(0xFFFBC8CC), + Color(0xFFFDA4B0), + ] + : [ + Color(0xFF7AB8FD), + Color(0xFF6EA8FF), + ], + begin: Alignment.topRight, + end: Alignment.bottomLeft, + ), + ), + child: Container( + width: MediaQuery.of(context).size.width, + padding: EdgeInsets.all(15), + child: Row( + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + familySharedRecordsList[index].patientName!.toLowerCase().capitalizeFirstofEach, + style: TextStyle(fontSize: 14, fontWeight: FontWeight.w700, color: isFemale ? Color(0xff5A282E) : Colors.white, letterSpacing: -0.42), + ), + Text( + TranslationBase.of(context).fileNumber + ': ' + familySharedRecordsList[index].responseID.toString(), + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w400, color: isFemale ? Color(0xff5A282E) : Colors.white, letterSpacing: -0.4, height: 16 / 10), + ), + Text( + familySharedRecordsList[index].age.toString() + ' ' + TranslationBase.of(context).years + ', ' + familySharedRecordsList[index].genderDescription!, + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w400, color: isFemale ? Color(0xff5A282E) : Colors.white, letterSpacing: -0.4, height: 16 / 10), + ), + ], ), ), - Container( - width: MediaQuery.of(context).size.width * 0.30, - child: Center( - child: AppText(TranslationBase.of(context).request), - ), + SizedBox(width: 4), + Column( + children: [ + InkWell( + onTap: () { + switchUser(familySharedRecordsList[index], context); + }, + child: Container( + decoration: BoxDecoration(color: Colors.black.withOpacity(0.1), borderRadius: BorderRadius.circular(20)), + padding: EdgeInsets.fromLTRB(10, 8, 12, 8), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SvgPicture.asset("assets/images/new-design/switch.svg", height: 16, color: isFemale ? Color(0Xff5A282E) : Colors.white), + SizedBox(width: 4), + Texts(TranslationBase.of(context).switchUser, color: isFemale ? Color(0Xff5A282E) : Colors.white, fontSize: 12, fontWeight: FontWeight.w600) + ], + ), + ), + ), + SizedBox(height: 8), + InkWell( + onTap: () { + deleteFamily(familySharedRecordsList[index], context); + }, + child: Container( + decoration: BoxDecoration(color: Colors.black.withOpacity(0.1), borderRadius: BorderRadius.circular(20)), + padding: EdgeInsets.fromLTRB(10, 8, 12, 8), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SvgPicture.asset("assets/images/new-design/delete.svg", height: 22, color: isFemale ? Color(0Xff5A282E) : Colors.white), + SizedBox(width: 4), + Texts(TranslationBase.of(context).delete, color: isFemale ? Color(0Xff5A282E) : Colors.white, fontSize: 12, fontWeight: FontWeight.w600), + ], + ), + ), + ), + ], ), ], ), ), - ), + ); + } else + return SizedBox(height: 0); + }, + separatorBuilder: (context, index) => SizedBox(height: 12), + itemCount: familySharedRecordsList.length) + : getNoDataWidget(context); + } + + int checkActive(List list) { + return list.where((o) => o.status == 3).toList().length; + } + + Widget myFamilyRequest(context) { + return ListView( + children: [ + SizedBox(height: 21), + pendingRequestView(), + SizedBox(height: 12), + sentRequestView(), + SizedBox(height: 12), + approvedRequestView(), + ], + ); + } + + Widget requestDecoratedContainerWithExpandable(String title, List columns, List rows) { + return AppExpandableNotifier( + title: title, + bodyWidget: Container( + margin: EdgeInsets.only(left: 21, right: 21, bottom: 21), + padding: EdgeInsets.only(top: 12, bottom: 12, left: 14, right: 14), + decoration: BoxDecoration( + borderRadius: BorderRadius.all( + Radius.circular(10.0), + ), + border: Border.all(width: 1, color: CustomColors.backgroudGreyColor), + boxShadow: [ + BoxShadow( + color: Color(0xff000000).withOpacity(.05), + blurRadius: 27, + offset: Offset(0, -3), ), ], + color: Colors.white), + child: Column(children: [ + Row(children: columns), + SizedBox(height: 6), + Divider(color: CustomColors.textDarkColor, height: 1, thickness: 1), + SizedBox(height: 8), + ListView.separated( + physics: NeverScrollableScrollPhysics(), + shrinkWrap: true, + padding: EdgeInsets.zero, + itemBuilder: (cxt, index) => rows[index], + separatorBuilder: (cxt, index) => SizedBox(height: 12), + itemCount: rows.length), + ]), + ), + ); + } + + Widget pendingRequestView() { + return requestDecoratedContainerWithExpandable( + TranslationBase.of(context).userViewRequest, + [ + Expanded(flex: 3, child: columnText(TranslationBase.of(context).name)), + Expanded(flex: 1, child: columnText(TranslationBase.of(context).allow)), + Expanded(flex: 1, child: columnText(TranslationBase.of(context).reject)), + ], + pendingRecordsList.map((result) { + return pendingItemView(result); + }).toList()); + } + + Widget pendingItemView(GetAllSharedRecordsByStatusList result) { + return Row( + children: [ + Expanded(flex: 3, child: rowText(result.patientName!)), + Expanded( + flex: 1, + child: Align( + alignment: Alignment.centerLeft, + child: InkWell( + child: SvgPicture.asset("assets/images/new-design/allow.svg", height: 17), + onTap: () { + acceptRemoveRequest(result.iD, 3, context); + }, + ), ), ), - body: Column( - children: [ - Expanded( - child: (user != null && projectViewModel.isLogin) - ? TabBarView( - physics: BouncingScrollPhysics(), - controller: _tabController, - children: [ - myFamilyDetails(context), - myFamilyRequest(context) - ], - ) - : Container(child: AppText('Loading..')), - ) - ], + Expanded( + flex: 1, + child: Align( + alignment: Alignment.centerLeft, + child: InkWell( + child: SvgPicture.asset("assets/images/new-design/reject.svg", height: 17), + onTap: () { + acceptRemoveRequest(result.iD, 4, context); + }, + ), + ), ), - ), + ], ); + } - // return AppScaffold( - // appBarTitle: TranslationBase.of(context).myFamilyFiles, - // isShowAppBar: widget.isAppbarVisible, - // body: SingleChildScrollView( - // child: Container( - // height: SizeConfig.screenHeight * .9, - // width: SizeConfig.realScreenWidth, - // padding: EdgeInsets.all(20), - // child: Stack( - // children: [ - // TabBar( - // controller: _tabController, - // indicatorColor: Colors.red, - // tabs: [ - // Tab( - // // padding: EdgeInsets.all(6), - // child: AppText(TranslationBase.of(context).family)), - // Tab( - // // padding: EdgeInsets.all(6), - // child: - // AppText(TranslationBase.of(context).request)), - // ], - // ), - // TabBarView( - // controller: _tabController, - // children: [ - // myFamilyDetails(context), - // myFamilyRequest(context) - // ], - // ) - // ], - // )))); + Widget sentRequestView() { + return requestDecoratedContainerWithExpandable( + TranslationBase.of(context).sentRequest, + [ + Expanded(flex: 3, child: columnText(TranslationBase.of(context).name)), + Expanded(flex: 1, child: columnText(TranslationBase.of(context).status)), + ], + sentRecordsList.map((result) { + return sentItemView(result); + }).toList()); } - Widget myFamilyDetails(context) { - return Container( - height: MediaQuery.of(context).size.height, - margin: EdgeInsets.fromLTRB(20.0, 25.0, 20.0, 0.0), - child: Column( - children: [ - Expanded( - flex: 4, - child: FutureBuilder( - future: getFamilyFiles(), // async work - builder: (BuildContext context, - AsyncSnapshot - snapshot) { - switch (snapshot.connectionState) { - case ConnectionState.waiting: - return Padding( - padding: EdgeInsets.only(top: 50), - child: Text('Loading....')); - default: - if (snapshot.hasError) - return Padding( - padding: EdgeInsets.all(10), - child: Text( - TranslationBase.of(context).noDataAvailable)); - else - return Padding( - padding: EdgeInsets.only(top: 50), - child: Column(children: [ - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Expanded( - flex: 3, - child: Text( - TranslationBase.of(context).request)), - Expanded( - flex: 2, - child: Text( - TranslationBase.of(context).switchUser, - )), - Expanded( - flex: 1, - child: Text( - TranslationBase.of(context).deleteView, - )), - ], - ), - Column( - mainAxisAlignment: MainAxisAlignment.start, - children: snapshot - .data.getAllSharedRecordsByStatusList - .map((result) { - return result.status == 3 - ? Padding( - padding: EdgeInsets.all(10), - child: Row( - children: [ - Expanded( - flex: 3, - child: Text( - result.patientName)), - Expanded( - flex: 2, - child: IconButton( - icon: Icon(Icons.group), - color: Colors.black, - onPressed: () { - switchUser( - result, context); - }, - )), - Expanded( - flex: 1, - child: IconButton( - icon: Icon( - Icons.delete, - color: Colors.black, - ), - onPressed: () { - deleteFamily( - result, context); - }, - )), - ], - )) - : SizedBox(); - }).toList()) - ])); - } - }, - ), + Widget sentItemView(GetAllSharedRecordsByStatusList result) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded(flex: 3, child: rowText(result.patientName!)), + Expanded( + flex: 1, + child: Container( + padding: EdgeInsets.only(top: 3, bottom: 3, left: 8, right: 8), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(50), + color: result.status == 3 ? Color(0xff349745) : Color(0xffD02127), ), - Expanded( - flex: 1, - child: Column( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - Row( - children: [ - Expanded( - child: DefaultButton( - TranslationBase.of(context).addFamilyMember, - () => { - Navigator.of(context) - .pushNamed(ADD_FAMILY_MEMBER_TYPE) - }, - color: Colors.grey[900], - textColor: Colors.white, - )) - ], - ), - ], + child: Text( + result.statusDescription != null ? result.statusDescription! : "", + style: TextStyle( + fontSize: 10, + color: Colors.white, + letterSpacing: -0.4, + fontWeight: FontWeight.w600, ), - ) - ], - )); + ), + ), + ), + ], + ); } - Widget myFamilyRequest(context) { - return //Padding( - // padding: const EdgeInsets.symmetric(horizontal: 10.0), - // child: - SingleChildScrollView( - child: Container( - height: MediaQuery.of(context).size.height, - margin: EdgeInsets.only(top: 65), - child: Column( - children: [ - RoundedContainer( - child: ExpansionTile( - title: Text( - TranslationBase.of(context).userViewRequest, - style: TextStyle(fontSize: 18.0, fontWeight: FontWeight.bold), - ), - children: [ - FutureBuilder( - future: getUserViewRequest(), // async work - builder: (BuildContext context, - AsyncSnapshot snapshot) { - switch (snapshot.connectionState) { - case ConnectionState.waiting: - return Padding( - padding: EdgeInsets.only(top: 50), - child: Text('Loading....')); - default: - if (snapshot.hasError) - return Padding( - padding: EdgeInsets.all(10), - child: Text(TranslationBase.of(context) - .noDataAvailable)); - else - return Column( - children: [ - // Padding(padding: EdgeInsets.only(left:10, right:10), - // child: - // Row( - // mainAxisAlignment: - // MainAxisAlignment.spaceBetween, - // children: [ - // Expanded( - // flex: 3, - // child: Text(TranslationBase.of(context) - // .request)), - // Expanded( - // flex: 2, - // child: Text( - // TranslationBase.of(context) - // .switchUser, - // )), - // Expanded( - // flex: 1, - // child: Text( - // TranslationBase.of(context) - // .deleteView, - // )), - // ], - // )), - Column(children: [ - Padding( - padding: EdgeInsets.only( - left: 10, right: 10), - child: Row(children: [ - Expanded( - flex: 3, child: AppText('Name')), - Expanded( - flex: 1, child: AppText('Allow')), - Expanded( - flex: 1, - child: AppText('Reject')), - ])), - Column( - children: familyFileProvider - .allSharedRecordsByStatusResponse - .getAllSharedRecordsByStatusList - .map((result) { - return Padding( - padding: EdgeInsets.all(10), - child: Row( - children: [ - Expanded( - flex: 3, - child: - Text(result.patientName)), - Expanded( - flex: 1, - child: IconButton( - icon: Icon( - Icons.check_circle, - color: Colors.black, - ), - onPressed: () { - acceptRemoveRequest( - result.iD, - 3, - context); - }, - )), - Expanded( - flex: 1, - child: IconButton( - icon: Icon( - Icons.delete, - color: Colors.black, - ), - onPressed: () { - acceptRemoveRequest( - result.iD, - 4, - context); - }, - )) - ], - )); - }).toList()) - ]) - ], - ); - } - }) - ], + Widget approvedRequestView() { + return requestDecoratedContainerWithExpandable( + TranslationBase.of(context).userView, + [ + Expanded(flex: 4, child: columnText(TranslationBase.of(context).name)), + Expanded(flex: 2, child: columnText(TranslationBase.of(context).delete)), + ], + approvedRecordsList.map((result) { + return approvedItemView(result); + }).toList()); + } + + Widget approvedItemView(GetAllSharedRecordsByStatusList result) { + return Row( + children: [ + Expanded(flex: 4, child: rowText(result.patientName!)), + Expanded( + flex: 2, + child: Align( + alignment: Alignment.centerLeft, + child: InkWell( + child: Icon( + Icons.delete, + color: Colors.red, + size: 22, ), + onTap: () { + acceptRemoveRequest(result.iD, 4, context); + }, ), - RoundedContainer( - child: ExpansionTile( - title: Text( - TranslationBase.of(context).sentRequest, - style: TextStyle(fontSize: 18.0, fontWeight: FontWeight.bold), - ), - children: [ - FutureBuilder( - future: getSentRequest(), // async work - builder: (BuildContext context, - AsyncSnapshot - snapshot) { - switch (snapshot.connectionState) { - case ConnectionState.waiting: - return Padding( - padding: EdgeInsets.only(top: 50), - child: Text('Loading....')); - default: - if (snapshot.hasError) - return Padding( - padding: EdgeInsets.all(10), - child: Text(TranslationBase.of(context) - .noDataAvailable)); - else - return Container( - height: SizeConfig.screenHeight * .3, - child: SingleChildScrollView( - child: Column( - children: [ - Padding( - padding: EdgeInsets.only( - left: 10, right: 10), - child: Row(children: [ - Expanded( - flex: 3, - child: AppText( - TranslationBase.of(context) - .theName)) - ])), - Column( - children: snapshot - .data.getAllSharedRecordsByStatusList - .map((result) { - return Padding( - padding: EdgeInsets.all(10), - child: Row( - children: [ - Expanded( - flex: 3, - child: Text( - result.patientName)), - Expanded( - flex: 2, - child: AppText( - result.statusDescription, - color: result.status == 3 - ? Colors.green - : Colors.red, - )), - ], - )); - }).toList(), - ) - ], - ))); - } - }) - ], - )), - RoundedContainer( - child: ExpansionTile( - title: Text( - TranslationBase.of(context).userView, - style: TextStyle(fontSize: 18.0, fontWeight: FontWeight.bold), - ), - children: [ - FutureBuilder( - future: getUserViewRequest(), // async work - builder: (BuildContext context, - AsyncSnapshot snapshot) { - switch (snapshot.connectionState) { - case ConnectionState.waiting: - return Padding( - padding: EdgeInsets.only(top: 50), - child: Text('Loading....')); - default: - if (snapshot.hasError) - return Padding( - padding: EdgeInsets.all(10), - child: Text(TranslationBase.of(context) - .noDataAvailable)); - else - return Column( - children: [ - // Padding( - // padding:EdgeInsets.only(left:10, right:10), - // child: Row( - // mainAxisAlignment: - // MainAxisAlignment.spaceBetween, - // children: [ - // Expanded( - // flex: 3, - // child: AppText( - // TranslationBase.of(context).request), - // ), - // Expanded( - // flex: 2, - // child: AppText( - // TranslationBase.of(context).switchUser, - // )), - // Expanded( - // flex: 1, - // child: AppText( - // TranslationBase.of(context).deleteView, - // )), - // ], - // )), - Column(children: [ - Padding( - padding: - EdgeInsets.only(left: 10, right: 10), - child: Row(children: [ - Expanded( - flex: 3, child: AppText('Name')), - Expanded( - flex: 1, child: AppText('Delete')), - ])), - Column( - children: familyFileProvider - .allSharedRecordsByStatusResponse - .getAllSharedRecordsByStatusList - .map((result) { - return Padding( - padding: EdgeInsets.all(10), - child: Row( - children: [ - Expanded( - flex: 3, - child: AppText( - result.patientName)), - Expanded( - flex: 1, - child: IconButton( - icon: Icon( - Icons.delete, - color: Colors.black, - ), - onPressed: () { - deactivateRequest( - result.iD, 5, context); - }, - )), - ], - )); - }).toList()) - ]) - ], - ); - } - }) - ], - )) - ], + ), ), - ), + ], ); } @@ -631,40 +424,16 @@ class _MyFamily extends State with TickerProviderStateMixin { } } - Future getFamilyFiles() async { - if (user != null) { - if (await sharedPref.getObject(FAMILY_FILE) != null) { - // print(await sharedPref.getObject(FAMILY_FILE)); - return Future.value(GetAllSharedRecordsByStatusResponse.fromJson( - await sharedPref.getObject(FAMILY_FILE))); - } else { - return familyFileProvider.getSharedRecordByStatus(); - } - } - } - - Future getUserViewRequest() async { - var user = await sharedPref.getObject(USER_PROFILE); - return familyFileProvider.getUserViewRequest(user['PatientID']); - } - - Future getSentRequest() async { - // var user = await sharedPref.getObject(USER_PROFILE); - return familyFileProvider.getUserSentRequest(); - } - 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, + builder: (cxt) => ConfirmWithMessageDialog( + message: TranslationBase.of(context).removeFamilyMember, + onTap: () { + removeFamily(family, context); + }, + ), + ); } removeFamily(GetAllSharedRecordsByStatusList family, context) { @@ -673,101 +442,118 @@ class _MyFamily extends State with TickerProviderStateMixin { Map request = {}; request['ID'] = this.userID; request['IsActive'] = false; - this - .familyFileProvider - .deativateActivateMemberFile(request) - .then((value) => refreshFamily(context)); + this.familyFileProvider.deativateActivateMemberFile(request).then((value) { + refreshFamily(context); + GifLoaderDialogUtils.hideDialog(context); + }); } - refreshFamily(context) { - GifLoaderDialogUtils.hideDialog(context); - setState(() { - sharedPref.remove(FAMILY_FILE); - }); + refreshFamily(context) async { + await sharedPref.remove(FAMILY_FILE); + await checkUserData(); } switchUser(user, context) { GifLoaderDialogUtils.showMyDialog(context); + int languageID = Provider.of(context, listen: false).isArabic ? 1 : 2; // this // .familyFileProvider // .silentLoggin(user) // .then((value) => loginAfter(value, context)); // Utils.showProgressDialog(context); - this - .familyFileProvider - .silentLoggin(user is AuthenticatedUser ? null : user, - mainUser: user is AuthenticatedUser) - .then((value) => loginAfter(value, context)) - .catchError((err) { - print(err); - AppToast.showErrorToast(message: err); + this.familyFileProvider.silentLoggin(user is AuthenticatedUser ? null : user, languageID, mainUser: user is AuthenticatedUser).then((value) => loginAfter(value, context)).catchError((err) { + print("err:$err"); + AppToast.showErrorToast(message: err.toString(), localContext: context); Navigator.of(context).pop(); }); } + checkIfIsInPatient(BuildContext context) { + bool isAdmitted = false; + bool hasAdmissionRequest = false; + GetAdmissionInfoResponseModel getAdmissionInfoResponseModel; + GetAdmissionRequestInfoResponseModel getAdmissionRequestInfoResponseModel; + ClinicListService service = new ClinicListService(); + service.checkIfInPatientAPI(context).then((res) { + if (res['MessageStatus'] == 1) { + isAdmitted = res['isAdmitted']; + hasAdmissionRequest = res['hasAdmissionRequests']; + print("IS ADMITTED: $isAdmitted"); + print("Has Admission Request: $hasAdmissionRequest"); + if (isAdmitted) { + if (res['PatientAdmittedInformation'].length != 0) { + getAdmissionInfoResponseModel = GetAdmissionInfoResponseModel.fromJson(res['PatientAdmittedInformation'][0]); + projectViewModel.setInPatientProjectID(res['PatientAdmittedInformation'][0]['ProjectID']); + projectViewModel.setInPatientAdmissionInfo(getAdmissionInfoResponseModel); + projectViewModel.setIsPatientAdmitted(true); + } + } + if (hasAdmissionRequest) { + if (res['MedicalInstruction'].length != 0) { + getAdmissionRequestInfoResponseModel = GetAdmissionRequestInfoResponseModel.fromJson(res['MedicalInstruction'][0]); + // projectViewModel.setInPatientProjectID(res['MedicalInstruction'][0]['ProjectID']); + projectViewModel.setInPatientProjectID(res['MedicalInstruction'][0]['projectId']); + projectViewModel.setInPatientAdmissionRequest(getAdmissionRequestInfoResponseModel); + projectViewModel.setPatientHasAdmissionRequest(true); + } + } + } else {} + }).catchError((err) { + projectViewModel.setIsPatientAdmitted(false); + projectViewModel.setPatientHasAdmissionRequest(false); + }); + } + loginAfter(result, context) async { - GifLoaderDialogUtils.hideDialog(context); var currentLang = await sharedPref.getString(APP_LANGUAGE); - Provider.of(context, listen: false) - .setPrivilege(privilegeList: result, isLoginChild: true); + Provider.of(AppGlobal.context, listen: false).setPrivilege(privilegeList: result, isLoginChild: true); result = list.CheckActivationCode.fromJson(result); var familyFile = await sharedPref.getObject(FAMILY_FILE); - - result = list.CheckActivationCode.fromJson(result); - var mainUser = await sharedPref.getObject(MAIN_USER); var bloodType = await sharedPref.getString(BLOOD_TYPE); + var mainUser = await sharedPref.getObject(MAIN_USER); + var loginType = await sharedPref.getInt(LAST_LOGIN); + var pushToken = await sharedPref.getString(PUSH_TOKEN); + // var oneSignalPushToken = await sharedPref.getString(ONESIGNAL_APNS_TOKEN ?? ""); this.sharedPref.clear(); if (mainUser["PatientID"] != result.list.patientID) { result.list.isFamily = true; } this.sharedPref.setString(APP_LANGUAGE, currentLang); - this.sharedPref.setObject(MAIN_USER, mainUser); - this.sharedPref.setString(APP_LANGUAGE, currentLang); - this.sharedPref.setObject(USER_PROFILE, result.list); - this.sharedPref.setObject(FAMILY_FILE, familyFile); - this.sharedPref.setObject(LOGIN_TOKEN_ID, result.logInTokenID); - this.sharedPref.setString(TOKEN, result.authenticationTokenID); - await authenticatedUserObject.getUser(getUser: true); - Provider.of(context, listen: false).user = - authenticatedUserObject.user; - Provider.of(context, listen: false) - .setUser(authenticatedUserObject.user); - - await pharmacyModuleViewModel.generatePharmacyToken().then((value) async { - if (pharmacyModuleViewModel.error.isNotEmpty) - await pharmacyModuleViewModel.createUser(); - }); + this.sharedPref.setString(BLOOD_TYPE, bloodType); + this.sharedPref.setString(PUSH_TOKEN, pushToken); + // this.sharedPref.setString(ONESIGNAL_APNS_TOKEN, oneSignalPushToken); + this.sharedPref.setInt(LAST_LOGIN, loginType ?? 1); + await this.sharedPref.setObject(MAIN_USER, mainUser); + await this.sharedPref.setObject(USER_PROFILE, result.list); + await this.sharedPref.setObject(FAMILY_FILE, familyFile); + await this.sharedPref.setObject(LOGIN_TOKEN_ID, result.logInTokenID); + await this.sharedPref.setString(TOKEN, result.authenticationTokenID); + _vitalSignService.heightCm = ""; + _vitalSignService.weightKg = ""; + Provider.of(context, listen: false).user = result.list; + Provider.of(context, listen: false).setUser(result.list); + Provider.of(context, listen: false).authenticatedUserObject.user = result.list; - appointmentRateViewModel - .getIsLastAppointmentRatedList() - .then((value) => { - //getToDoCount(), - // Utils.hideProgressDialog(), - if (appointmentRateViewModel.isHaveAppointmentNotRate) - { - Navigator.pushAndRemoveUntil( - context, - FadePage( - page: RateAppointmentDoctor(), - ), - (r) => false) - } - else - { - Navigator.pushAndRemoveUntil( - context, - FadePage( - page: LandingPage(), - ), - (r) => false) - } - }) - .catchError((err) { - print(err); - // Utils.hideProgressDialog(); - // GifLoaderDialogUtils.hideDialog(context); - }); + await this.sharedPref.remove(APPOINTMENT_HISTORY_MEDICAL); + + try { + // await appointmentRateViewModel.getIsLastAppointmentRatedList(); + checkIfIsInPatient(context); + await getToDoCount(); + if (appointmentRateViewModel.isHaveAppointmentNotRate) { + Navigator.pushAndRemoveUntil( + context, + FadePage( + page: RateAppointmentDoctor(), + ), + (r) => false); + } else { + Navigator.pushAndRemoveUntil(AppGlobal.context, MaterialPageRoute(builder: (context) => LandingPage()), (Route r) => false); + } + } catch (er) { + GifLoaderDialogUtils.hideDialog(context); + } } deactivateRequest(ID, status, context) { @@ -775,8 +561,7 @@ class _MyFamily extends State with TickerProviderStateMixin { Map request = {}; request["ID"] = ID; request["Status"] = status; - this.familyFileProvider.deactivateFamily(request).then((value) => - {GifLoaderDialogUtils.hideDialog(context), refreshFamily(context)}); + this.familyFileProvider.deactivateFamily(request).then((value) => {GifLoaderDialogUtils.hideDialog(context), refreshFamily(context)}); } acceptRemoveRequest(ID, status, context) { @@ -784,21 +569,113 @@ class _MyFamily extends State with TickerProviderStateMixin { Map request = {}; request["ID"] = ID; request["Status"] = status; - this.familyFileProvider.acceptRejectFamily(request).then((value) => - {GifLoaderDialogUtils.hideDialog(context), refreshFamily(context)}); + this.familyFileProvider.acceptRejectFamily(request).then((value) async { + await refreshFamily(context); + await GifLoaderDialogUtils.hideDialog(context); + }); } checkUserData() async { if (await this.sharedPref.getObject(USER_PROFILE) != null) { - var data = AuthenticatedUser.fromJson( - await this.sharedPref.getObject(USER_PROFILE)); - - var data2 = AuthenticatedUser.fromJson( - await this.sharedPref.getObject(MAIN_USER)); - print(data2); + var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE)); + await getFamilyFiles(); setState(() { this.user = data; }); } } + + List familySharedRecordsList = []; + List pendingRecordsList = []; + List approvedRecordsList = []; + List sentRecordsList = []; + + Future getFamilyFiles() async { + int languageID = projectViewModel.isArabic ? 1 : 2; + GetAllSharedRecordsByStatusResponse? familySharedRecords; + if (await sharedPref.getObject(FAMILY_FILE) != null) { + familySharedRecords = GetAllSharedRecordsByStatusResponse.fromJson(await sharedPref.getObject(FAMILY_FILE)); + } + GifLoaderDialogUtils.showMyDialog(context); + try { + if (familySharedRecords == null) { + familySharedRecords = await familyFileProvider.getSharedRecordByStatus(languageID); + } + familySharedRecordsList = []; + sentRecordsList = []; + familySharedRecords!.getAllSharedRecordsByStatusList!.forEach((element) { + if (element.status == 3) { + familySharedRecordsList.add(element); + } + sentRecordsList.add(element); + }); + approvedRecordsList = []; + pendingRecordsList = []; + GetAllSharedRecordsByStatusResponse pendingAndApprovedRecords = await getUserViewRequest(languageID); + + pendingAndApprovedRecords.getAllSharedRecordsByStatusList!.forEach((element) { + print(element.toJson()); + if (element.status == 2) { + pendingRecordsList.add(element); + } else if (element.status == 3) { + approvedRecordsList.add(element); + } + }); + GifLoaderDialogUtils.hideDialog(context); + } catch (ex) { + familySharedRecords = GetAllSharedRecordsByStatusResponse(getAllSharedRecordsByStatusList: []); + GifLoaderDialogUtils.hideDialog(context); + } + } + + Future getUserViewRequest(int languageID) async { + var user = await sharedPref.getObject(USER_PROFILE); + return familyFileProvider.getUserViewRequest(user['PatientID'], languageID); + } + + Future getSentRequest() async { + // var user = await sharedPref.getObject(USER_PROFILE); + return familyFileProvider.getUserSentRequest(); + } + + getToDoCount() async { + toDoProvider.setState(0, 0, true, toDoProvider.notificationsCount); + ClinicListService service = ClinicListService(); + try { + var res = await service.getActiveAppointmentNo(context); + print(res['AppointmentActiveNumber']); + if (res['MessageStatus'] == 1 && res['AppointmentActiveNumber'] != null) { + // toDoProvider.setState(res['AppointmentActiveNumber'], true, toDoProvider.notificationsCount); + toDoProvider.setState(res['AppointmentActiveNumber'], res['AncillaryOrderListCount'], true, toDoProvider.notificationsCount); + } else {} + } catch (ex) { + print("getToDoCount:$ex"); + } + } + + Widget columnText(String title) { + return Text( + title, + // textAlign: TextAlign.left, + style: TextStyle( + fontSize: 12, + color: CustomColors.textDarkColor, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + ), + ); + } + + Widget rowText(String title) { + return Text( + title, + // textAlign: TextAlign.left, + style: TextStyle( + fontSize: 10, + color: CustomColors.textColor, + letterSpacing: -0.4, + fontWeight: FontWeight.w600, + ), + ); + } } diff --git a/lib/pages/DrawerPages/notifications/notification_details_page.dart b/lib/pages/DrawerPages/notifications/notification_details_page.dart index 3858c940..8b670190 100644 --- a/lib/pages/DrawerPages/notifications/notification_details_page.dart +++ b/lib/pages/DrawerPages/notifications/notification_details_page.dart @@ -1,25 +1,40 @@ import 'package:diplomaticquarterapp/core/model/notifications/get_notifications_response_model.dart'; -import 'package:diplomaticquarterapp/core/viewModels/notifications_view_model.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/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/progress_indicator/app_circular_progress_Indeicator.dart'; import 'package:flutter/material.dart'; +import 'package:youtube_player_flutter/youtube_player_flutter.dart'; -class NotificationsDetailsPage extends StatelessWidget { +class NotificationsDetailsPage extends StatefulWidget { final GetNotificationsResponseModel notification; - NotificationsDetailsPage({this.notification}); + NotificationsDetailsPage({required this.notification}); + + @override + State createState() => _NotificationsDetailsPageState(); +} + +class _NotificationsDetailsPageState extends State { + late YoutubePlayerController _controller; + + @override + void initState() { + _controller = YoutubePlayerController( + initialVideoId: getVideoURL(), + flags: YoutubePlayerFlags( + autoPlay: true, + mute: false, + ), + ); + super.initState(); + } getDateForm(String date) { DateTime d = DateUtil.convertStringToDate(date); String monthName = DateUtil.getMonth(d.month).toString(); TimeOfDay timeOfDay = TimeOfDay(hour: d.hour, minute: d.minute); - String minute = timeOfDay.minute < 10 - ? timeOfDay.minute.toString().padLeft(2, '0') - : timeOfDay.minute.toString(); + String minute = timeOfDay.minute < 10 ? timeOfDay.minute.toString().padLeft(2, '0') : timeOfDay.minute.toString(); String hour = '${timeOfDay.hourOfPeriod}:$minute'; if (timeOfDay.period == DayPeriod.am) { @@ -32,71 +47,93 @@ class NotificationsDetailsPage extends StatelessWidget { return monthName + ',${d.day},${d.year}, $hour'; } + String getVideoURL() { + if (widget.notification.videoURL != null && widget.notification.notificationType == "2") { + String videoId; + videoId = YoutubePlayer.convertUrlToId(widget.notification.videoURL)!; + print(videoId); // BBAyRBTfsOU + return videoId; + }else{ + return ""; + } + } + @override Widget build(BuildContext context) { - return BaseView( - builder: (_, model, widget) => AppScaffold( - isShowAppBar: true, - appBarTitle: TranslationBase.of(context).notificationDetails, - body: SingleChildScrollView( - child: Center( - child: FractionallySizedBox( - widthFactor: 0.9, - child: Column( - children: [ - SizedBox( - height: 25, - ), - Container( - // margin: EdgeInsets.only(left: 30), - width: double.infinity, - color: Colors.grey[400], - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Texts( - getDateForm(notification.createdOn), - fontSize: 16, - ), - ), - ), - SizedBox( - height: 15, - ), - if (notification.messageTypeData.length != 0) - FractionallySizedBox( - widthFactor: 0.9, - child: Image.network(notification.messageTypeData, - loadingBuilder: (BuildContext context, Widget child, - ImageChunkEvent loadingProgress) { - if (loadingProgress == null) return child; - return Center( - child: SizedBox( - width: 40.0, - height: 40.0, - child: AppCircularProgressIndicator(), - ), - ); - }, - fit: BoxFit - .fill) //Image.network(notification.messageTypeData), - ), - SizedBox( - height: 15, - ), - Row( - children: [ - Expanded( - child: Center( - child: Texts(notification.message), - ), - ), - ], - ), - ], - ), + return AppScaffold( + isShowAppBar: true, + showNewAppBar: true, + showNewAppBarTitle: true, + isShowDecPage: false, + appBarTitle: TranslationBase.of(context).notificationDetails, + body: ListView( + physics: BouncingScrollPhysics(), + padding: EdgeInsets.all(21), + children: [ + Text( + DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(widget.notification.createdOn!)) + + " " + + DateUtil.formatDateToTimeLang(DateUtil.convertStringToDate(widget.notification.createdOn!), false), + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + color: Color(0xff2E303A), + letterSpacing: -0.64, + ), + ), + SizedBox(height: 18), + Text( + widget.notification.message ?? "", + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + color: Color(0xff575757), + letterSpacing: -0.48, ), ), - ), + if (widget.notification.notificationType == "2") + Padding( + padding: const EdgeInsets.only(top: 18), + child: YoutubePlayer( + controller: _controller, + showVideoProgressIndicator: true, + ), + ), + if (widget.notification.messageTypeData != null) + if (widget.notification.messageTypeData!.length != 0 && widget.notification.notificationType != "2") + Padding( + padding: const EdgeInsets.only(top: 18), + child: Image.network(widget.notification.messageTypeData!, loadingBuilder: (BuildContext context, Widget child, ImageChunkEvent? loadingProgress) { + if (loadingProgress == null) return child; + return Center( + child: SizedBox( + width: 40.0, + height: 40.0, + child: AppCircularProgressIndicator(), + ), + ); + }, fit: BoxFit.fill), + ), + SizedBox(height: 18), + // Text( + // widget.notification.message!.trim(), + // style: TextStyle( + // fontSize: 12, + // fontWeight: FontWeight.w600, + // color: Color(0xff575757), + // letterSpacing: -0.48, + // ), + // ), + // Text( + // widget.notification.message.trim(), + // style: TextStyle( + // fontSize: 12, + // fontWeight: FontWeight.w600, + // color: Color(0xff575757), + // letterSpacing: -0.48, + // ), + // ), + ], ), ); } diff --git a/lib/pages/DrawerPages/notifications/notifications_page.dart b/lib/pages/DrawerPages/notifications/notifications_page.dart index 9745609d..b5373131 100644 --- a/lib/pages/DrawerPages/notifications/notifications_page.dart +++ b/lib/pages/DrawerPages/notifications/notifications_page.dart @@ -1,145 +1,155 @@ +import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/core/model/notifications/get_notifications_request_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/notifications_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/DrawerPages/notifications/notification_details_page.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.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/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 'package:font_awesome_flutter/font_awesome_flutter.dart'; +import 'package:provider/provider.dart'; // ignore: must_be_immutable class NotificationsPage extends StatelessWidget { - getDateForm(String date) { - DateTime d = DateUtil.convertStringToDate(date); - String monthName = DateUtil.getMonth(d.month).toString(); - TimeOfDay timeOfDay = TimeOfDay(hour: d.hour, minute: d.minute); - String minute = timeOfDay.minute < 10 - ? timeOfDay.minute.toString().padLeft(2, '0') - : timeOfDay.minute.toString(); - - String hour = '${timeOfDay.hourOfPeriod}:$minute'; - if (timeOfDay.period == DayPeriod.am) { - hour = hour + "AM"; - } else { - { - hour = hour + "PM"; - } - } - - //DayPeriod.am - return monthName + ',${d.day},${d.year}, $hour'; - } - int currentIndex = 0; @override Widget build(BuildContext context) { - var prescriptionReport; + ProjectViewModel projectViewModel = Provider.of(context); + AppGlobal.context = context; return BaseView( onModelReady: (model) { - GetNotificationsRequestModel getNotificationsRequestModel = - new GetNotificationsRequestModel( - currentPage: currentIndex, - pagingSize: 14, - notificationStatusID: 2); + GetNotificationsRequestModel getNotificationsRequestModel = new GetNotificationsRequestModel(currentPage: currentIndex, pagingSize: 14, notificationStatusID: 2); model.getNotifications(getNotificationsRequestModel, context); }, builder: (_, model, widget) => AppScaffold( isShowAppBar: true, + showNewAppBar: true, + showNewAppBarTitle: true, appBarTitle: TranslationBase.of(context).notifications, baseViewModel: model, - body: 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, - margin: EdgeInsets.only( - top: 5, left: 10, right: 10, bottom: 5), - padding: EdgeInsets.all(8.0), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.all( - Radius.circular(10.0), + body: ListView.separated( + physics: BouncingScrollPhysics(), + itemBuilder: (context, index) { + if (index == model.notifications.length) { + return 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: Padding( + padding: const EdgeInsets.only(top: 12, bottom: 12), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + Icons.notifications_active, + color: CustomColors.accentColor, + size: 24, ), - border: Border.all( - color: notification.isRead - ? Colors.grey[200] - : Theme.of(context).primaryColor, - width: 0.5), + SizedBox(width: 8), + Text(TranslationBase.of(context).moreNotifications, + style: TextStyle(color: CustomColors.accentColor, fontWeight: FontWeight.w600, letterSpacing: -0.42, decoration: TextDecoration.underline)), + ], + ), + ), + ); + } + return InkWell( + onTap: () async { + if (!model.notifications[index].isRead!) { + model.markAsRead(model.notifications[index].id); + } + Navigator.push( + context, + FadePage( + page: NotificationsDetailsPage( + notification: model.notifications[index], ), - child: Row( - children: [ + ), + ); + }, + child: Container( + width: double.infinity, + padding: EdgeInsets.fromLTRB(15.0, 14, 21, 12), + decoration: BoxDecoration( + color: model.notifications[index].isRead! ? Theme.of(context).scaffoldBackgroundColor : CustomColors.accentColor.withOpacity(0.05), + border: projectViewModel.isArabic + ? Border( + right: BorderSide( + color: model.notifications[index].isRead! ? Theme.of(context).scaffoldBackgroundColor : CustomColors.accentColor, + width: 6.0, + ), + ) + : Border( + left: BorderSide( + color: model.notifications[index].isRead! ? Theme.of(context).scaffoldBackgroundColor : CustomColors.accentColor, + width: 6.0, + ), + ), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ Expanded( - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts(getDateForm(notification.createdOn)), - SizedBox( - height: 5, - ), - Row( - children: [ - Expanded( - child: Texts(notification.message)), - if (notification.messageType == "image") - Icon(FontAwesomeIcons.images) - ], - ), - SizedBox( - height: 5, - ), - ], + child: Text( + DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(model.notifications[index].createdOn!)) + + " " + + DateUtil.formatDateToTimeLang(DateUtil.convertStringToDate(model.notifications[index].createdOn!), false), + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + color: Color(0xff2E303A), + letterSpacing: -0.64, ), ), ), - SizedBox( - width: 15, - ), + if (model.notifications[index].messageType == "image") + Icon( + FontAwesomeIcons.image, + color: Color(0xffC9C9C9), + ) ], ), - ), - ), - ) - .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'), + SizedBox(height: 4), + Text( + model.notifications[index].message!.trim(), + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + color: Color(0xff575757), + letterSpacing: -0.48, + ), ), - ), - )), + ], + ), + ), + ); + }, + separatorBuilder: (context, index) { + return Column( + children: [ + Divider( + color: Color(0xffEFEFEF), + thickness: 2.0, + height: 1, + ), + ], + ); + }, + itemCount: model.notifications.length + 1), ), ); } diff --git a/lib/pages/ErService/AmbulanceReq.dart b/lib/pages/ErService/AmbulanceReq.dart index 1d4e78ee..afcf4e58 100644 --- a/lib/pages/ErService/AmbulanceReq.dart +++ b/lib/pages/ErService/AmbulanceReq.dart @@ -1,18 +1,14 @@ +import 'dart:ui'; + import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; import 'package:diplomaticquarterapp/core/viewModels/er/am_request_view_model.dart'; -import 'package:diplomaticquarterapp/core/viewModels/medical/prescriptions_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; -import 'package:diplomaticquarterapp/pages/medical/prescriptions/prescriptions_history_page.dart'; -import 'package:diplomaticquarterapp/pages/medical/prescriptions/prescriptions_page.dart'; -import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; -import 'package:diplomaticquarterapp/widgets/others/OrderLogItem.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'dart:ui'; 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:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; import 'AmbulanceRequestIndexPages/AmbulanceRequestIndex.dart'; import 'OrderLogPage.dart'; @@ -22,10 +18,9 @@ class AmbulanceReq extends StatefulWidget { _AmbulanceReqState createState() => _AmbulanceReqState(); } -class _AmbulanceReqState extends State - with SingleTickerProviderStateMixin { - TabController _tabController; - List imagesInfo = List(); +class _AmbulanceReqState extends State with SingleTickerProviderStateMixin { + late TabController _tabController; + List imagesInfo =[]; @override void initState() { @@ -41,101 +36,62 @@ class _AmbulanceReqState extends State @override Widget build(BuildContext context) { - imagesInfo.add(ImagesInfo( - imageEn: - 'https://hmgwebservices.com/Images/MobileApp/Ambulance/en/0.png', - imageAr: - 'https://hmgwebservices.com/Images/MobileApp/Ambulance/ar/0.png')); + ProjectViewModel projectViewModel = Provider.of(context); + imagesInfo.add(ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/Ambulance/en/0.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/Ambulance/ar/0.png')); return BaseView( - onModelReady: (model) => model.getAmRequestOrders(), + onModelReady: (model) => model.getAmRequestOrders(projectViewModel.isArabic ? 1 : 2), builder: (_, model, widget) => AppScaffold( isShowAppBar: true, + showNewAppBarTitle: true, + showNewAppBar: true, appBarTitle: TranslationBase.of(context).transportationService, description: TranslationBase.of(context).infoAmbulance, imagesInfo: imagesInfo, baseViewModel: model, - body: Scaffold( - extendBodyBehindAppBar: true, - appBar: PreferredSize( - preferredSize: Size.fromHeight(65.0), - child: Stack( - children: [ - Positioned( - bottom: 1, - left: 0, - right: 0, - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10), - child: Container( - color: Theme.of(context) - .scaffoldBackgroundColor - .withOpacity(0.8), - height: 70.0, - ), - ), - ), - Center( - child: Container( - height: 60.0, - margin: EdgeInsets.only(top: 10.0), - width: MediaQuery.of(context).size.width * 0.90, - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Theme.of(context).dividerColor, - width: 0.7), - ), - color: Colors.white), - child: Center( - child: TabBar( - isScrollable: true, - controller: _tabController, - indicatorWeight: 5.0, - indicatorSize: TabBarIndicatorSize.label, - labelColor: Theme.of(context).primaryColor, - labelPadding: - EdgeInsets.only(top: 4.0, left: 18.0, right: 18.0), - unselectedLabelColor: Colors.grey[800], - tabs: [ - Container( - width: MediaQuery.of(context).size.width * 0.40, - child: Center( - child: Texts(TranslationBase.of(context).transportationService), - ), - ), - Container( - width: MediaQuery.of(context).size.width * 0.30, - child: Center( - child: Texts(TranslationBase.of(context).ordersLog), - ), - ), - ], - ), - ), - ), - ), + body: Column( + children: [ + TabBar( + isScrollable: false, + controller: _tabController, + indicatorWeight: 3.0, + indicatorSize: TabBarIndicatorSize.tab, + labelColor: Color(0xff2B353E), + unselectedLabelColor: Color(0xff575757), + labelPadding: EdgeInsets.only(top: 15, bottom: 13, left: 20, right: 20), + labelStyle: TextStyle( + fontFamily: projectViewModel.isArabic ? 'Cairo' : 'Poppins', + fontSize: 15, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + ), + unselectedLabelStyle: TextStyle( + fontFamily: projectViewModel.isArabic ? 'Cairo' : 'Poppins', + fontSize: 15, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + ), + tabs: [ + Text(TranslationBase.of(context).transportationService), + Text(TranslationBase.of(context).ordersLog), ], ), - ), - body: Column( - children: [ - Expanded( - child: TabBarView( - physics: BouncingScrollPhysics(), - controller: _tabController, - children: [ - AmbulanceRequestIndexPage( - amRequestViewModel: model, - ), - OrderLogPage( - amRequestViewModel: model, - ) - ], - ), - ) - ], - ), + Expanded( + child: TabBarView( + physics: NeverScrollableScrollPhysics(), + controller: _tabController, + children: [ + AmbulanceRequestIndexPage( + amRequestViewModel: model, + tabController: _tabController, + ), + OrderLogPage( + amRequestViewModel: model, + ) + ], + ), + ) + ], ), ), ); diff --git a/lib/pages/ErService/AmbulanceRequestIndexPages/AmbulanceRequestIndex.dart b/lib/pages/ErService/AmbulanceRequestIndexPages/AmbulanceRequestIndex.dart index f36eadc5..fc4155ca 100644 --- a/lib/pages/ErService/AmbulanceRequestIndexPages/AmbulanceRequestIndex.dart +++ b/lib/pages/ErService/AmbulanceRequestIndexPages/AmbulanceRequestIndex.dart @@ -1,13 +1,21 @@ +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/er/AmbulanceRequestOrdersModel.dart'; import 'package:diplomaticquarterapp/core/model/er/PatientER.dart'; +import 'package:diplomaticquarterapp/core/model/er/PatientER_RC.dart'; import 'package:diplomaticquarterapp/core/viewModels/er/am_request_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/ErService/widgets/StepsWidget.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/others/OrderLogItem.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/ConfirmWithMessageDialog.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'; import 'BillAmount.dart'; import 'PickupLocation.dart'; @@ -16,110 +24,306 @@ import 'Summary.dart'; class AmbulanceRequestIndexPage extends StatefulWidget { final AmRequestViewModel amRequestViewModel; - - AmbulanceRequestIndexPage({Key key, this.amRequestViewModel}); + final TabController tabController; + AmbulanceRequestIndexPage({Key? key, required this.amRequestViewModel, required this.tabController}); @override - _AmbulanceRequestIndexPageState createState() => - _AmbulanceRequestIndexPageState(); + _AmbulanceRequestIndexPageState createState() => _AmbulanceRequestIndexPageState(); } class _AmbulanceRequestIndexPageState extends State { int currentIndex = 0; - PageController pageController; + late PageController pageController; PatientER _patientER = PatientER(); + PatientER_RC _patientER_RC = PatientER_RC(); + + TransportationDetails transportationDetails = new TransportationDetails(); + + late int status; + late String _statusDisp; + late Color _color; + _changeCurrentTab(int tab) { setState(() { currentIndex = tab; }); - pageController.animateToPage(tab, - duration: Duration(milliseconds: 800), curve: Curves.easeOutQuart); + pageController.animateToPage(tab, duration: Duration(milliseconds: 800), curve: Curves.easeOutQuart); } @override void initState() { super.initState(); pageController = new PageController(); + _patientER_RC.transportationDetails = transportationDetails; } @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + + AmbulanceRequestOrdersModel order = widget.amRequestViewModel.pendingAmbulanceRequestOrder ?? AmbulanceRequestOrdersModel(); + + if(widget.amRequestViewModel.pendingAmbulanceRequestOrder != null) { + int status = order.statusId!; + _statusDisp = order.statusText!; + 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 AppScaffold( - body: widget.amRequestViewModel.pickUpRequestPresOrder != null - ? Column( - children: [ - SizedBox( - height: 80, - ), - Container( - margin: EdgeInsets.only(left: 18, right: 18), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(2), + body: widget.amRequestViewModel.pendingAmbulanceRequestOrder != null && order != null + ? SingleChildScrollView( + child: Column( + children: [ + SizedBox( + height: 10, ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - OrderLogItem( - title: TranslationBase.of(context).reqId, - value: widget.amRequestViewModel.pickUpRequestPresOrder - .presOrderID - .toString(), - ), - OrderLogItem( - title: TranslationBase.of(context).status, - value: widget.amRequestViewModel.pickUpRequestPresOrder - .ambulateDescription, - ), - OrderLogItem( - title: TranslationBase.of(context).pickupDate, - value: DateUtil.getDayMonthYearDateFormatted( - DateUtil.convertStringToDate(widget - .amRequestViewModel - .pickUpRequestPresOrder - .lastEditDate)), - ), - OrderLogItem( - title: TranslationBase.of(context).pickupLocation, - value: widget.amRequestViewModel.pickUpRequestPresOrder - .pickupLocationName, + Container( + margin: EdgeInsets.all(21), + decoration: BoxDecoration( + color: _color, + borderRadius: BorderRadius.all( + Radius.circular(10.0), ), - OrderLogItem( - title: TranslationBase.of(context).dropoffLocation, - value: widget.amRequestViewModel.pickUpRequestPresOrder - .dropoffLocationName, + 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: 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), + ), ), - OrderLogItem( - title: TranslationBase.of(context).transportMethod, - value: widget - .amRequestViewModel.pickUpRequestPresOrder.title, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + _statusDisp, + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: _color, letterSpacing: -0.4, height: 16 / 10), + ), + SizedBox(height: 6), + Text( + '${TranslationBase.of(context).requestID}: ${order.iD}', + 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).pickupDate + ": ", + style: TextStyle(fontSize: 10, fontWeight: FontWeight.w600, color: Color(0xff575757), letterSpacing: -0.4, height: 16 / 10), + ), + Expanded( + child: Text( + DateUtil.getDayMonthYearDateFormatted(DateTime.tryParse(order.created!)!), + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.48, height: 16 / 10), + ), + ), + ], + ), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).transportMethod + ": ", + style: TextStyle(fontSize: 10, fontWeight: FontWeight.w600, color: Color(0xff575757), letterSpacing: -0.4, height: 16 / 10), + ), + Expanded( + child: Text( + order.serviceText!, + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.48, height: 16 / 10), + ), + ), + ], + ), + SizedBox( + height: 20.0, + ), + ], + ), + ), + Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + SizedBox(height: 12), + if (order.statusId == 1 || order.statusId == 2) + InkWell( + onTap: () { + showConfirmMessage(widget.amRequestViewModel, order.iD!, context); + }, + 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), + ), + ), + ), + ], + ), + ], + ), + Row( + children: [ + Container( + margin: projectViewModel.isArabic ? EdgeInsets.only(left: 10.0) : EdgeInsets.only(right: 10.0), + width: 8, + height: 8, + decoration: containerRadius( + CustomColors.textColor, + 100, + ), + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).pickupLocation + ": ", + style: TextStyle(fontSize: 10, fontWeight: FontWeight.w600, color: Color(0xff575757), letterSpacing: -0.4, height: 16 / 10), + ), + Container( + width: MediaQuery.of(context).size.width * 0.7, + child: Text( + order.pickupLocation!.trim().toString(), + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.48), + ), + ), + ], + ), + ], + ), + Container( + height: 20.0, + width: 1.0, + color: CustomColors.grey2, + margin: const EdgeInsets.only(left: 3.0, right: 3.0), + ), + Row( + children: [ + Container( + margin: projectViewModel.isArabic ? EdgeInsets.only(left: 10.0) : EdgeInsets.only(right: 10.0), + width: 8, + height: 8, + decoration: containerRadius( + CustomColors.accentColor, + 100, + ), + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).dropoffLocation + ": ", + style: TextStyle(fontSize: 10, fontWeight: FontWeight.w600, color: Color(0xff575757), letterSpacing: -0.4, height: 16 / 10), + ), + Text( + order.dropOffLocation!.trim().toString(), + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.48), + ), + ], + ), + ], + ), + ], ), - Container( - padding: EdgeInsets.all(10), - width: double.maxFinite, - margin: EdgeInsets.only(bottom: 4, left: 4, right: 4), - decoration: BoxDecoration( - borderRadius: BorderRadius.only( - bottomRight: Radius.circular(12), - bottomLeft: Radius.circular(12), - ), - color: Colors.white), - child: SecondaryButton( - color: Colors.red[900], - textColor: Colors.white, - label: TranslationBase.of(context).cancel, - onTap: () { - widget.amRequestViewModel.updatePressOrder( - presOrderID: widget.amRequestViewModel - .pickUpRequestPresOrder.presOrderID); - }, - ), - ) - ], + ), ), - ), - ], + + // Container( + // margin: EdgeInsets.only(left: 18, right: 18), + // decoration: BoxDecoration( + // color: Colors.white, + // borderRadius: BorderRadius.circular(2), + // ), + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // OrderLogItem( + // title: TranslationBase.of(context).reqId, + // value: widget.amRequestViewModel.pendingAmbulanceRequestOrder.iD.toString(), + // ), + // OrderLogItem( + // title: TranslationBase.of(context).status, + // value: widget.amRequestViewModel.pendingAmbulanceRequestOrder.statusText, + // ), + // OrderLogItem( + // title: TranslationBase.of(context).pickupDate, + // value: DateUtil.getDayMonthYearDateFormatted(DateTime.tryParse(widget.amRequestViewModel.pendingAmbulanceRequestOrder.created)), + // ), + // OrderLogItem( + // title: TranslationBase.of(context).pickupLocation, + // value: widget.amRequestViewModel.pendingAmbulanceRequestOrder.pickupLocation, + // ), + // OrderLogItem( + // title: TranslationBase.of(context).dropoffLocation, + // value: widget.amRequestViewModel.pendingAmbulanceRequestOrder.dropOffLocation, + // ), + // OrderLogItem( + // title: TranslationBase.of(context).transportMethod, + // value: widget.amRequestViewModel.pendingAmbulanceRequestOrder.serviceText, + // ), + // Container( + // padding: EdgeInsets.all(10), + // width: double.maxFinite, + // margin: EdgeInsets.only(bottom: 4, left: 4, right: 4), + // decoration: BoxDecoration( + // borderRadius: BorderRadius.only( + // bottomRight: Radius.circular(12), + // bottomLeft: Radius.circular(12), + // ), + // color: Colors.white), + // child: SecondaryButton( + // color: Colors.red[900], + // textColor: Colors.white, + // label: TranslationBase.of(context).cancel, + // onTap: () { + // widget.amRequestViewModel.updatePressOrder(presOrderID: widget.amRequestViewModel.pendingAmbulanceRequestOrder.iD); + // }, + // ), + // ) + // ], + // ), + // ), + ], + ), ) : Column( children: [ @@ -142,22 +346,28 @@ class _AmbulanceRequestIndexPageState extends State { SelectTransportationMethod( changeCurrentTab: _changeCurrentTab, patientER: _patientER, + patientER_RC: _patientER_RC, amRequestViewModel: widget.amRequestViewModel, ), PickupLocation( changeCurrentTab: _changeCurrentTab, patientER: _patientER, + patientER_RC: _patientER_RC, amRequestViewModel: widget.amRequestViewModel, ), - BillAmount( - changeCurrentTab: _changeCurrentTab, - patientER: _patientER, - amRequestViewModel: widget.amRequestViewModel, - ), + Container(), + // BillAmount( + // changeCurrentTab: _changeCurrentTab, + // patientER: _patientER, + // patientER_RC: _patientER_RC, + // amRequestViewModel: widget.amRequestViewModel, + // ), Summary( changeCurrentTab: _changeCurrentTab, patientER: _patientER, + patientER_RC: _patientER_RC, amRequestViewModel: widget.amRequestViewModel, + tabController: widget.tabController, ), ], ), @@ -166,4 +376,26 @@ class _AmbulanceRequestIndexPageState extends State { ), ); } + + void showConfirmMessage(AmRequestViewModel model, int presOrderID, BuildContext context) { + showDialog( + context: context, + builder: (cxt) => ConfirmWithMessageDialog( + message: TranslationBase.of(context).cancelOrderMsg, + onTap: () { + Future.delayed(new Duration(milliseconds: 300)).then((value) async { + // GifLoaderDialogUtils.showMyDialog(context); + await model.updatePressOrder(presOrderID: presOrderID); + if (model.state == ViewState.ErrorLocal) { + Utils.showErrorToast(model.error); + // GifLoaderDialogUtils.hideDialog(context); + } else { + AppToast.showSuccessToast(message: TranslationBase.of(context).processDoneSuccessfully); + // GifLoaderDialogUtils.hideDialog(context); + } + }); + }, + )); + return; + } } diff --git a/lib/pages/ErService/AmbulanceRequestIndexPages/BillAmount.dart b/lib/pages/ErService/AmbulanceRequestIndexPages/BillAmount.dart index 59528df6..0371fd24 100644 --- a/lib/pages/ErService/AmbulanceRequestIndexPages/BillAmount.dart +++ b/lib/pages/ErService/AmbulanceRequestIndexPages/BillAmount.dart @@ -1,25 +1,22 @@ import 'package:diplomaticquarterapp/core/enum/Ambulate.dart'; import 'package:diplomaticquarterapp/core/model/er/PatientER.dart'; +import 'package:diplomaticquarterapp/core/model/er/PatientER_RC.dart'; import 'package:diplomaticquarterapp/core/viewModels/er/am_request_view_model.dart'; -import 'package:diplomaticquarterapp/pages/Blood/new_text_Field.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.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_svg/flutter_svg.dart'; class BillAmount extends StatefulWidget { final Function changeCurrentTab; final PatientER patientER; + final PatientER_RC patientER_RC; final AmRequestViewModel amRequestViewModel; - BillAmount( - {Key key, - this.changeCurrentTab, - this.patientER, - this.amRequestViewModel}); + BillAmount({Key? key, required this.changeCurrentTab, required this.patientER, required this.patientER_RC, required this.amRequestViewModel}); @override _BillAmountState createState() => _BillAmountState(); @@ -27,23 +24,19 @@ class BillAmount extends StatefulWidget { class _BillAmountState extends State { Ambulate _ambulate = Ambulate.None; - String note =""; - + String note = ""; @override void initState() { - - if(widget.patientER.ambulate!=null) - { - setState(() { - _ambulate = widget.patientER.ambulate; - note = widget.patientER.requesterNote; - }); - } + // if (widget.patientER_RC.transportationDetails.ambulate != null) { + // setState(() { + // _ambulate = widget.patientER.ambulate; + // note = widget.patientER.requesterNote; + // }); + // } super.initState(); } - @override Widget build(BuildContext context) { return AppScaffold( @@ -52,280 +45,253 @@ class _BillAmountState extends State { body: SingleChildScrollView( physics: BouncingScrollPhysics(), child: Container( - margin: EdgeInsets.only(left: 12, right: 12), + margin: EdgeInsets.only(left: 12, right: 12, top: 12), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Texts(TranslationBase.of(context).billAmount), + Text(TranslationBase.of(context).billAmount, style: TextStyle(fontSize: 16.0, letterSpacing: -0.64, fontWeight: FontWeight.w600)), SizedBox( height: 10, ), - Table( - border: TableBorder.symmetric( - inside: BorderSide(width: 1.0, color: Colors.grey[300]), - outside: BorderSide(width: 1.0, color: Colors.grey[300])), - children: [ - TableRow( + Container( + decoration: cardRadius(12), + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( - height: MediaQuery.of(context).size.height * 0.09, - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.only( - topLeft: Radius.circular(10.0), - ), - ), - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Texts( - TranslationBase.of(context).patientShareB, - textAlign: TextAlign.start, - color: Colors.black, - fontSize: 15, - ), + width: double.infinity, + padding: EdgeInsets.only(top: 10, bottom: 3), + child: Row( + children: [ + Expanded( + child: _getNormalText(TranslationBase.of(context).patientShareToDo), + ), + Expanded( + child: _getNormalText(TranslationBase.of(context).sar + ' ${widget.patientER_RC.patientERTransportationMethod!.price}', isBold: true), + ) + ], ), ), + mDivider(Colors.grey[200]!), Container( - height: MediaQuery.of(context).size.height * 0.09, - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.only( - topRight: Radius.circular(10.0), - ), - ), - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Texts( - TranslationBase.of(context).sar+' ${widget.patientER.patientERTransportationMethod.price}', - color: Colors.black, - textAlign: TextAlign.start, - fontSize: 15, - ), - ), - ), - ], - ), - TableRow( - children: [ - Container( - color: Colors.white, - height: MediaQuery.of(context).size.height * 0.09, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Texts( - TranslationBase.of(context).patientShareTax, - color: Colors.black, - fontSize: 15, - textAlign: TextAlign.start, - ), + width: double.infinity, + padding: EdgeInsets.only(top: 3, bottom: 3), + child: Row( + children: [ + Expanded( + child: _getNormalText(TranslationBase.of(context).patientTaxToDo), + ), + Expanded( + child: _getNormalText(TranslationBase.of(context).sar + ' ${widget.patientER_RC.patientERTransportationMethod!.priceVAT}', isBold: true), + ) + ], ), ), + mDivider(Colors.grey[200]!), Container( - height: MediaQuery.of(context).size.height * 0.09, - color: Colors.white, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Texts( - TranslationBase.of(context).sar+' ${widget.patientER.patientERTransportationMethod.vAT}', - color: Colors.black, - fontSize: 15, - textAlign: TextAlign.start, - ), + width: double.infinity, + padding: EdgeInsets.only(top: 3, bottom: 3), + child: Row( + children: [ + Expanded( + child: _getNormalText(TranslationBase.of(context).patientShareTotalToDo), + ), + Expanded( + child: Row( + children: [ + SvgPicture.asset("assets/images/new/Saudi_Riyal_Symbol.svg", width: 16, height: 16), + mWidth(6), + _getNormalText(TranslationBase.of(context).sar + ' ${widget.patientER_RC.patientERTransportationMethod!.priceTotal}', isBold: true, isTotal: true), + ], + ), + ) + ], ), ), ], ), - TableRow( - children: [ - Container( - height: MediaQuery.of(context).size.height * 0.09, - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.only( - bottomLeft: Radius.circular(10.0), - ), - ), - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Texts( - TranslationBase.of(context).patientShareTotal, - color: Colors.black, - fontSize: 15, - textAlign: TextAlign.start, - bold: true, - ), - ), - ), - Container( - height: MediaQuery.of(context).size.height * 0.09, - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.only( - bottomRight: Radius.circular(10.0), - ), - ), - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Texts( - TranslationBase.of(context).sar+' ${widget.patientER.patientERTransportationMethod.totalPrice}', - color: Colors.black, - fontSize: 15, - textAlign: TextAlign.start, - ), - ), - ), - ], - ), - ], + ), ), SizedBox( height: 10, ), - Texts(TranslationBase.of(context).selectAmbulate,bold: true,), - SizedBox(height: 5,), + Text(TranslationBase.of(context).selectAmbulate, style: TextStyle(fontSize: 16.0, letterSpacing: -0.64, fontWeight: FontWeight.w600)), + SizedBox( + height: 5, + ), Row( children: [ - Expanded( - child: InkWell( - onTap: () { - setState(() { - _ambulate = Ambulate.Wheelchair; - }); - }, - child: Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: - Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), - child: ListTile( - title: Text(TranslationBase.of(context).wheelchair), - leading: Radio( - value: Ambulate.Wheelchair, - groupValue: _ambulate, - onChanged: (value) { - setState(() { - _ambulate = value; - }); - }, - ), + InkWell( + onTap: () { + setState(() { + _ambulate = Ambulate.Wheelchair; + }); + }, + child: Container( + width: MediaQuery.of(context).size.width * 0.9, + child: ListTile( + contentPadding: EdgeInsets.only(left: 0.0, right: 0.0), + title: Row( + children: [ + Radio( + value: Ambulate.Wheelchair, + groupValue: _ambulate, + onChanged: (value) { + setState(() { + _ambulate = value!; + }); + }, + ), + Text( + TranslationBase.of(context).wheelchair, + style: TextStyle( + fontSize: 12.0, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + ), + ), + ], ), ), ), ), - Expanded( - child: InkWell( - onTap: () { - setState(() { - _ambulate = Ambulate.Walker; - }); - }, - child: Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: - Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), - child: ListTile( - title: Text(TranslationBase.of(context).walker), - leading: Radio( - value: Ambulate.Walker, - groupValue: _ambulate, - - onChanged: (value) { - setState(() { - _ambulate = value; - }); - }, - ), + ], + ), + Row( + children: [ + InkWell( + onTap: () { + setState(() { + _ambulate = Ambulate.Walker; + }); + }, + child: Container( + width: MediaQuery.of(context).size.width * 0.9, + child: ListTile( + contentPadding: EdgeInsets.only(left: 0.0, right: 0.0), + title: Row( + children: [ + Radio( + value: Ambulate.Walker, + groupValue: _ambulate, + onChanged: (value) { + setState(() { + _ambulate = value!; + }); + }, + ), + Text( + TranslationBase.of(context).walker, + style: TextStyle( + fontSize: 12.0, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + ), + ), + ], ), ), ), ), ], ), - SizedBox(height: 5,), Row( children: [ - Expanded( - child: InkWell( - onTap: () { - setState(() { - _ambulate = Ambulate.Stretcher; - }); - }, - child: Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: - Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), - child: ListTile( - title: Text(TranslationBase.of(context).stretcher), - leading: Radio( - value: Ambulate.Stretcher, - groupValue: _ambulate, - - onChanged: (value) { - setState(() { - _ambulate = value; - }); - }, - ), + InkWell( + onTap: () { + setState(() { + _ambulate = Ambulate.Stretcher; + }); + }, + child: Container( + width: MediaQuery.of(context).size.width * 0.9, + child: ListTile( + contentPadding: EdgeInsets.only(left: 0.0, right: 0.0), + title: Row( + children: [ + Radio( + value: Ambulate.Stretcher, + groupValue: _ambulate, + onChanged: (value) { + setState(() { + _ambulate = value!; + }); + }, + ), + Text( + TranslationBase.of(context).stretcher, + style: TextStyle( + fontSize: 12.0, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + ), + ), + ], ), ), ), ), - Expanded( - child: InkWell( - onTap: () { - setState(() { - _ambulate = Ambulate.None; - }); - }, - child: Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: - Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), - child: ListTile( - title: Text(TranslationBase.of(context).none), - leading: Radio( - value: Ambulate.None, - groupValue: _ambulate, - - onChanged: (value) { - setState(() { - _ambulate = value; - }); - }, - ), + ], + ), + Row( + children: [ + InkWell( + onTap: () { + setState(() { + _ambulate = Ambulate.None; + }); + }, + child: Container( + width: MediaQuery.of(context).size.width * 0.9, + child: ListTile( + contentPadding: EdgeInsets.only(left: 0.0, right: 0.0), + title: Row( + children: [ + Radio( + value: Ambulate.None, + groupValue: _ambulate, + onChanged: (value) { + setState(() { + _ambulate = value!; + }); + }, + ), + Text( + TranslationBase.of(context).none, + style: TextStyle( + fontSize: 12.0, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + ), + ), + ], ), ), ), ), ], ), - SizedBox(height: 12,), - NewTextFields( - hintText: TranslationBase.of(context).notes, - initialValue: note, - onChanged: (value){ - setState(() { - note = value; - }); - }, + SizedBox( + height: 12, + ), + Container( + decoration: cardRadius(10), + child: Padding( + padding: EdgeInsets.all(8.0), + child: TextField( + maxLines: 5, + decoration: InputDecoration.collapsed( + hintText: TranslationBase.of(context).notes, hintStyle: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64, height: 23 / 16)), + onChanged: (value) { + setState(() { + note = value; + }); + }, + ), + ), ), - SizedBox( height: 100, ), @@ -334,23 +300,38 @@ class _BillAmountState extends State { ), ), bottomSheet: Container( - padding: EdgeInsets.all(15), - width: double.maxFinite, - height: 90, - child: SecondaryButton( - color: Colors.grey[800], - textColor: Colors.white, - onTap: () { + color: Theme.of(context).scaffoldBackgroundColor, + padding: EdgeInsets.all(12.0), + child: DefaultButton( + TranslationBase.of(context).next, + () { setState(() { - widget.patientER.ambulate = _ambulate; - widget.patientER.requesterNote = note; - widget.patientER.selectedAmbulate = _ambulate.selectAmbulateNumber(); + widget.patientER_RC.transportationDetails!.ambulate = _ambulate.selectAmbulateNumber(); + widget.patientER_RC.transportationDetails!.ambulateTitle = _ambulate.getAmbulateTitle(context); + widget.patientER_RC.transportationDetails!.notes = note; + // widget.patientER.selectedAmbulate = _ambulate.selectAmbulateNumber(); widget.changeCurrentTab(3); }); }, - label: TranslationBase.of(context).next, + // label: TranslationBase.of(context).next, ), ), ); } + + _getNormalText(text, {bool isBold = false, bool isTotal = false}) { + return Text( + text, + style: TextStyle( + fontSize: isBold + ? isTotal + ? 16 + : 12 + : 10, + letterSpacing: -0.5, + color: isBold ? Colors.black : Colors.grey[700], + fontWeight: FontWeight.w600, + ), + ); + } } diff --git a/lib/pages/ErService/AmbulanceRequestIndexPages/PickupLocation.dart b/lib/pages/ErService/AmbulanceRequestIndexPages/PickupLocation.dart index b0c541f9..d0beeab7 100644 --- a/lib/pages/ErService/AmbulanceRequestIndexPages/PickupLocation.dart +++ b/lib/pages/ErService/AmbulanceRequestIndexPages/PickupLocation.dart @@ -1,25 +1,29 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/er/PatientER.dart'; +import 'package:diplomaticquarterapp/core/model/er/PatientER_RC.dart'; import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/er/am_request_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; -import 'package:diplomaticquarterapp/pages/Blood/dialogs/SelectHospitalDialog.dart'; -import 'package:diplomaticquarterapp/pages/ErService/widgets/AppointmentCard.dart'; +import 'package:diplomaticquarterapp/models/ambulanceRequest/locationDetails.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/ProgressDialog.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/location_util.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/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/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/pickupLocation/PickupLocationFromMap.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:font_awesome_flutter/font_awesome_flutter.dart'; -import 'package:geolocator/geolocator.dart'; -import 'package:google_maps_place_picker/google_maps_place_picker.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:provider/provider.dart'; import '../AvailableAppointmentsPage.dart'; @@ -28,13 +32,10 @@ enum HaveAppointment { YES, NO } class PickupLocation extends StatefulWidget { final Function changeCurrentTab; final PatientER patientER; + final PatientER_RC patientER_RC; final AmRequestViewModel amRequestViewModel; - PickupLocation( - {Key key, - this.changeCurrentTab, - this.patientER, - this.amRequestViewModel}); + PickupLocation({Key? key, required this.changeCurrentTab, required this.patientER, required this.patientER_RC, required this.amRequestViewModel}); @override _PickupLocationState createState() => _PickupLocationState(); @@ -43,82 +44,115 @@ class PickupLocation extends StatefulWidget { class _PickupLocationState extends State { bool _isInsideHome = false; HaveAppointment _haveAppointment = HaveAppointment.NO; - double _latitude; - double _longitude; - AppoitmentAllHistoryResultList myAppointment; - HospitalsModel _selectedHospital; - PickResult _result; + + // double _latitude; + // double _longitude; + AppoitmentAllHistoryResultList? myAppointment; + HospitalsModel? _selectedHospital; + LocationDetails? _result; + + LocationUtils? locationUtils; + late ProjectViewModel projectViewModel; @override void initState() { super.initState(); - _getCurrentLocation(); + locationUtils = new LocationUtils(isShowConfirmDialog: true, context: context); + WidgetsBinding.instance.addPostFrameCallback((_) => locationUtils!.getCurrentLocation()); + setState(() {}); } - _getCurrentLocation() async { - await getLastKnownPosition().then((value) { - _latitude = value.latitude; - _longitude = value.longitude; - }).catchError((e) { - _longitude = 0; - _latitude = 0; - }); - } + // _getCurrentLocation() async { + // await Geolocator.getLastKnownPosition().then((value) { + // _latitude = value.latitude; + // _longitude = value.longitude; + // }).catchError((e) { + // _longitude = 0; + // _latitude = 0; + // }); + // } @override Widget build(BuildContext context) { + projectViewModel = Provider.of(context); return AppScaffold( isShowAppBar: false, isShowDecPage: false, body: SingleChildScrollView( physics: BouncingScrollPhysics(), child: Container( - margin: EdgeInsets.only(left: 12, right: 12), + margin: EdgeInsets.only(left: 12, right: 12, top: 12), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - if (widget.patientER.direction == 1) + if (widget.patientER_RC.transportationDetails!.direction == 0) Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Texts(TranslationBase.of(context).pickupLocation), + Text(TranslationBase.of(context).pickupLocation, style: TextStyle(fontSize: 16.0, letterSpacing: -0.64, fontWeight: FontWeight.w600)), SizedBox( height: 15, ), - InkWell( - onTap: () { - Navigator.push( - context, - FadePage( - page: PickupLocationFromMap( - latitude: _latitude, - longitude: _longitude, - onPick: (value) { - setState(() { - _result = value; - }); - }, - )), - ); - }, - child: Container( - padding: EdgeInsets.all(12), - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, + 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: () { + if (projectViewModel.latitude != null && projectViewModel.longitude != null) { + Navigator.push( + context, + FadePage( + page: PickupLocationFromMap( + latitude: projectViewModel.latitude ?? 0, + longitude: projectViewModel.longitude ?? 0, + onPick: (value) { + setState(() { + _result = value; + }); + }, + )), + ); + } else { + locationUtils!.getCurrentLocation(); + } + }, child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( - child: Texts(getSelectFromMapName(context))), - Icon( - FontAwesomeIcons.mapMarkerAlt, - size: 24, - color: Colors.black, - ) + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).selectMap, + style: TextStyle( + fontSize: 11, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.44, + ), + ), + Text( + getSelectFromMapName(context), + style: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: Color(0xff2B353E), + letterSpacing: -0.44, + ), + ), + ], + ), + ), + Icon(Icons.arrow_drop_down), ], ), ), @@ -126,7 +160,7 @@ class _PickupLocationState extends State { SizedBox( height: 12, ), - Texts(TranslationBase.of(context).pickupSpot), + Text(TranslationBase.of(context).pickupSpot, style: TextStyle(fontSize: 16.0, letterSpacing: -0.64, fontWeight: FontWeight.w600)), SizedBox( height: 5, ), @@ -137,21 +171,27 @@ class _PickupLocationState extends State { }); }, child: Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), child: ListTile( - title: Texts(TranslationBase.of(context).insideHome), - leading: Checkbox( - value: _isInsideHome, - onChanged: (value) { - setState(() { - _isInsideHome = value; - }); - }, + contentPadding: EdgeInsets.only(left: 0.0, right: 0.0), + title: Row( + children: [ + Checkbox( + value: _isInsideHome, + onChanged: (value) { + setState(() { + _isInsideHome = value!; + }); + }, + ), + Text( + TranslationBase.of(context).insideHome, + style: TextStyle( + fontSize: 12.0, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + ), + ), + ], ), ), ), @@ -159,7 +199,7 @@ class _PickupLocationState extends State { SizedBox( height: 12, ), - Texts(TranslationBase.of(context).haveAppo), + Text(TranslationBase.of(context).haveAppo, style: TextStyle(fontSize: 16.0, letterSpacing: -0.64, fontWeight: FontWeight.w600)), SizedBox( height: 5, ), @@ -176,26 +216,31 @@ class _PickupLocationState extends State { } }, child: Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: - Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), child: ListTile( - title: Texts(TranslationBase.of(context).yes), - leading: Radio( - value: HaveAppointment.YES, - groupValue: _haveAppointment, - onChanged: (value) { - if (myAppointment == null) { - getAppointment(); - setState(() { - _haveAppointment = value; - }); - } - }, + contentPadding: EdgeInsets.only(left: 0.0, right: 0.0), + title: Row( + children: [ + Radio( + value: HaveAppointment.YES, + groupValue: _haveAppointment, + onChanged: (value) { + if (myAppointment == null) { + getAppointment(); + setState(() { + _haveAppointment = value!; + }); + } + }, + ), + Text( + TranslationBase.of(context).yes, + style: TextStyle( + fontSize: 12.0, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + ), + ), + ], ), ), ), @@ -206,28 +251,33 @@ class _PickupLocationState extends State { onTap: () { setState(() { _haveAppointment = HaveAppointment.NO; - myAppointment = null; + myAppointment = AppoitmentAllHistoryResultList(); }); }, child: Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: - Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), child: ListTile( - title: Texts(TranslationBase.of(context).no), - leading: Radio( - value: HaveAppointment.NO, - groupValue: _haveAppointment, - onChanged: (value) { - setState(() { - _haveAppointment = value; - myAppointment = null; - }); - }, + contentPadding: EdgeInsets.only(left: 0.0, right: 0.0), + title: Row( + children: [ + Radio( + value: HaveAppointment.NO, + groupValue: _haveAppointment, + onChanged: (value) { + setState(() { + _haveAppointment = value!; + myAppointment = AppoitmentAllHistoryResultList(); + }); + }, + ), + Text( + TranslationBase.of(context).no, + style: TextStyle( + fontSize: 12.0, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + ), + ), + ], ), ), ), @@ -242,74 +292,131 @@ class _PickupLocationState extends State { SizedBox( height: 12, ), - AppointmentCard( - appointment: myAppointment, - ) + DoctorCard( + isInOutPatient: myAppointment!.isInOutPatient, + name: myAppointment!.doctorTitle! + " " + myAppointment!.doctorNameObj!, + profileUrl: myAppointment!.doctorImageURL, + subName: myAppointment!.clinicName, + isLiveCareAppointment: myAppointment!.isLiveCareAppointment, + date: DateUtil.convertStringToDate(myAppointment!.appointmentDate!), + isSortByClinic: false, + rating: myAppointment!.actualDoctorRate! + 0.0, + appointmentTime: myAppointment!.isLiveCareAppointment! + ? DateUtil.convertStringToDate(myAppointment!.appointmentDate!).toString().split(" ")[1].substring(0, 5) + : myAppointment!.startTime!.substring(0, 5), + remainingTimeInMinutes: null), ], ), SizedBox( height: 12, ), - Texts(TranslationBase.of(context).dropoffLocation), + if (_haveAppointment == HaveAppointment.NO) Text(TranslationBase.of(context).dropoffLocation, style: TextStyle(fontSize: 16.0, letterSpacing: -0.64, fontWeight: FontWeight.w600)), SizedBox( height: 8, ), - - InkWell( - onTap: () { - confirmSelectHospitalDialog( - widget.amRequestViewModel.hospitals); - }, - child: Container( - padding: EdgeInsets.all(12), + if (_haveAppointment == HaveAppointment.NO) + Container( + padding: EdgeInsets.only(left: 16, right: 16, bottom: 15, top: 15), + alignment: Alignment.center, decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: Border.all(color: Colors.grey, width: 0.5), + borderRadius: BorderRadius.circular(12), color: Colors.white, + border: Border.all( + color: Color(0xffefefef), + width: 1, + ), ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Texts(getHospitalName( - TranslationBase.of(context).pickupLocation)), - Icon( - Icons.arrow_drop_down, - size: 24, - color: Colors.black, - ) - ], + child: InkWell( + onTap: () { + confirmSelectHospitalDialog(widget.amRequestViewModel.hospitals); + }, + child: Row( + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).selectHospital, + style: TextStyle( + fontSize: 11, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.44, + ), + ), + Text( + getHospitalName(""), + style: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: Color(0xff2B353E), + letterSpacing: -0.44, + ), + ), + ], + ), + ), + Icon(Icons.arrow_drop_down), + ], + ), ), ), - ), ], ), - if (widget.patientER.direction == 0) + if (widget.patientER_RC.transportationDetails!.direction == 1) Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Texts(TranslationBase.of(context).pickupLocation), + Text(TranslationBase.of(context).pickupLocation, style: TextStyle(fontSize: 16.0, letterSpacing: -0.64, fontWeight: FontWeight.w600)), SizedBox( height: 15, ), - InkWell( - onTap: () { - confirmSelectHospitalDialog( - widget.amRequestViewModel.hospitals); - }, - child: Container( - padding: EdgeInsets.all(12), - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, + Container( + padding: EdgeInsets.only(left: 16, right: 16, bottom: 15, top: 15), + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + color: Colors.white, + border: Border.all( + color: Color(0xffefefef), + width: 1, ), + ), + child: InkWell( + onTap: () { + confirmSelectHospitalDialog(widget.amRequestViewModel.hospitals); + }, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Texts(getHospitalName( - TranslationBase.of(context).pickupLocation)), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).selectHospital, + style: TextStyle( + fontSize: 11, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.44, + ), + ), + Text( + getHospitalName(""), + style: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: Color(0xff2B353E), + letterSpacing: -0.44, + ), + ), + ], + ), + ), Icon( Icons.arrow_drop_down, size: 24, @@ -322,197 +429,269 @@ class _PickupLocationState extends State { SizedBox( height: 12, ), - Texts(TranslationBase.of(context).dropoffLocation), + Text(TranslationBase.of(context).dropoffLocation, style: TextStyle(fontSize: 16.0, letterSpacing: -0.64, fontWeight: FontWeight.w600)), SizedBox( height: 8, ), - InkWell( - onTap: () { - Navigator.push( - context, - FadePage( - page: PickupLocationFromMap( - latitude: _latitude, - longitude: _longitude, - onPick: (value) { - setState(() { - _result = value; - }); - }, - ), - ), - ); - }, - child: Container( - padding: EdgeInsets.all(12), - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, + Container( + padding: EdgeInsets.only(left: 16, right: 16, bottom: 15, top: 15), + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + color: Colors.white, + border: Border.all( + color: Color(0xffefefef), + width: 1, ), + ), + child: InkWell( + onTap: () { + if (projectViewModel.latitude != null && projectViewModel.longitude != null) { + Navigator.push( + context, + FadePage( + page: PickupLocationFromMap( + latitude: projectViewModel.latitude, + longitude: projectViewModel.longitude, + onPick: (value) { + setState(() { + _result = value; + }); + }, + ), + ), + ); + } else { + locationUtils!.getCurrentLocation(); + } + }, child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( - child: Texts(getSelectFromMapName(context))), - Icon( - FontAwesomeIcons.mapMarkerAlt, - size: 24, - color: Colors.black, - ) + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).selectMap, + style: TextStyle( + fontSize: 11, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.44, + ), + ), + Text( + getSelectFromMapName(context), + style: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: Color(0xff2B353E), + letterSpacing: -0.44, + ), + ), + ], + ), + ), + Icon(Icons.arrow_drop_down), ], ), ), ), ], ), + // SizedBox( + // height: 45, + // ), + // if (myAppointment != null) + // SizedBox( + // height: 100, + // ), + Container( + margin: EdgeInsets.only(top: 12), + decoration: cardRadius(12), + padding: EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(TranslationBase.of(context).billAmount + " : ", style: TextStyle(fontSize: 16.0, letterSpacing: -0.64, fontWeight: FontWeight.w600)), + SizedBox(height: 16.0), + Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text(TranslationBase.of(context).patientShareTotalToDo, style: TextStyle(fontSize: 13.0, letterSpacing: -0.64, fontWeight: FontWeight.w600)), + Row( + children: [ + projectViewModel.isArabic ? Container() : SvgPicture.asset("assets/images/new/Saudi_Riyal_Symbol.svg", width: 16, height: 16), + mWidth(6), + Text( + (widget.patientER_RC.transportationDetails!.tripType == 1 + ? ' ${widget.patientER_RC.patientERTransportationMethod!.priceTotal}' + : ' ${(widget.patientER_RC.patientERTransportationMethod!.priceTotal * 2)}'), + style: TextStyle(fontSize: 16.0, letterSpacing: -0.64, fontWeight: FontWeight.bold), + ), + mWidth(6), + projectViewModel.isArabic ? SvgPicture.asset("assets/images/new/Saudi_Riyal_Symbol.svg", width: 16, height: 16) : Container(), + ], + ), + ], + ) + ], + ), + ), SizedBox( - height: 45, + height: 100, ), - if (myAppointment != null) - SizedBox( - height: 100, - ), ], ), ), ), bottomSheet: Container( - padding: EdgeInsets.all(15), - width: double.maxFinite, - height: 90, - child: SecondaryButton( - color: Colors.grey[800], - textColor: Colors.white, - onTap: () { - if (_result == null || _selectedHospital == null) - AppToast.showErrorToast( - message: TranslationBase.of(context).selectAll); - else - setState(() { - widget.patientER.pickupSpot = _isInsideHome ? 1 : 0; - if (widget.patientER.direction == 0) { - widget.patientER.pickupLocationLattitude = - _result.geometry.location.lat.toString(); - widget.patientER.pickupLocationLongitude = - _result.geometry.location.lng.toString(); - widget.patientER.dropoffLocationLattitude = - _selectedHospital.latitude; - widget.patientER.dropoffLocationLongitude = - _selectedHospital.longitude; - } else { - widget.patientER.pickupLocationLattitude = - _selectedHospital.latitude; - widget.patientER.pickupLocationLongitude = - _selectedHospital.longitude; - widget.patientER.dropoffLocationLattitude = - _result.geometry.location.lat.toString(); - widget.patientER.dropoffLocationLongitude = - _result.geometry.location.lng.toString(); - } + color: Theme.of(context).scaffoldBackgroundColor, + padding: EdgeInsets.all(12.0), + child: Row( + children: [ + Expanded( + flex: 1, + child: DefaultButton( + TranslationBase.of(context).back, + () { + widget.changeCurrentTab(0); + }, + ), + ), + SizedBox(width: 12.0), + Expanded( + flex: 1, + child: DefaultButton( + TranslationBase.of(context).next, + () { + if (_result == null || _selectedHospital == null) + AppToast.showErrorToast(message: TranslationBase.of(context).selectAll); + else + setState(() { + widget.patientER_RC.transportationDetails!.pickupSpot = _isInsideHome ? 1 : 0; + if (widget.patientER_RC.transportationDetails!.direction == 0) { + // To Hospital + widget.patientER_RC.transportationDetails!.dropoffLatitude = _result!.lat.toStringAsFixed(6); + widget.patientER_RC.transportationDetails!.dropoffLongitude = _result!.long.toStringAsFixed(6); + widget.patientER_RC.transportationDetails!.pickupLatitude = _selectedHospital!.latitude; + widget.patientER_RC.transportationDetails!.pickupLongitude = _selectedHospital!.longitude; + } else { + // From Hospital + widget.patientER_RC.transportationDetails!.pickupLatitude = _selectedHospital!.latitude; + widget.patientER_RC.transportationDetails!.pickupLongitude = _selectedHospital!.longitude; + widget.patientER_RC.transportationDetails!.dropoffLatitude = _result!.lat.toStringAsFixed(6); + widget.patientER_RC.transportationDetails!.dropoffLongitude = _result!.long.toStringAsFixed(6); + } - widget.patientER.latitude = - widget.patientER.pickupLocationLattitude; - widget.patientER.longitude = - widget.patientER.pickupLocationLongitude; - widget.patientER.dropoffLocationName = _selectedHospital.name; - widget.patientER.createdBy = - widget.amRequestViewModel.user.patientID; - widget.patientER.isOutPatient = - widget.amRequestViewModel.user.outSA; - widget.patientER.patientIdentificationID = - widget.amRequestViewModel.user.patientIdentificationNo; - widget.patientER.pickupDateTime = - DateUtil.convertDateToStringLocation(DateTime.now()); - widget.patientER.pickupLocationName = _result.formattedAddress; - widget.patientER.projectID = - widget.amRequestViewModel.user.projectID; - widget.patientER.requesterFileNo = - widget.amRequestViewModel.user.patientID; - widget.patientER.requesterIsOutSA = false; - widget.patientER.lineItemNo = 0; - widget.patientER.requesterMobileNo = - widget.amRequestViewModel.user.mobileNumber; + widget.patientER_RC.transportationDetails!.dropoffLocationName = widget.patientER_RC.transportationDetails!.direction == 1 ? _result!.formattedAddress : _selectedHospital!.name; - if (_haveAppointment == HaveAppointment.YES) { - widget.patientER.appointmentNo = - myAppointment.appointmentNo.toString(); - widget.patientER.appointmentClinicName = - myAppointment.clinicName; - widget.patientER.appointmentDoctorName = - myAppointment.doctorNameObj; - widget.patientER.appointmentBranch = - myAppointment.projectName; - widget.patientER.appointmentTime = - myAppointment.appointmentDate; - widget.patientER.haveAppointment = true; - } else { - widget.patientER.appointmentNo = "0"; - widget.patientER.appointmentClinicName = null; - widget.patientER.appointmentDoctorName = null; - widget.patientER.appointmentBranch = null; - widget.patientER.appointmentTime = null; - widget.patientER.haveAppointment = false; - } + widget.patientER_RC.patientIdentificationID = widget.amRequestViewModel.user.patientIdentificationNo; + widget.patientER_RC.transportationDetails!.pickupDateTime = DateUtil.convertDateToStringLocation(DateTime.now()); + widget.patientER_RC.transportationDetails!.pickupLocationName = widget.patientER_RC.transportationDetails!.direction == 1 ? _selectedHospital!.name : _result!.formattedAddress; + widget.patientER_RC.projectID = widget.amRequestViewModel.user.projectID; + widget.patientER_RC.patientID = widget.amRequestViewModel.user.patientID; + widget.patientER_RC.transportationDetails!.requesterIsOutSA = false; + widget.patientER_RC.transportationDetails!.requesterMobileNo = widget.amRequestViewModel.user.mobileNumber; + widget.patientER_RC.transportationDetails!.requesterFileNo = widget.amRequestViewModel.user.patientID; - widget.patientER.pickupSpot = _isInsideHome ? 1 : 0; - widget.changeCurrentTab(2); - }); - }, - label: TranslationBase.of(context).next, + if (_haveAppointment == HaveAppointment.YES) { + widget.patientER_RC.transportationDetails!.appointmentNo = myAppointment!.appointmentNo.toString(); + widget.patientER_RC.transportationDetails!.appointmentClinicName = myAppointment!.clinicName; + widget.patientER_RC.transportationDetails!.appointmentDoctorName = myAppointment!.doctorNameObj; + widget.patientER_RC.transportationDetails!.appointmentBranch = myAppointment!.projectName; + widget.patientER_RC.transportationDetails!.appointmentTime = myAppointment!.appointmentDate; + widget.patientER_RC.transportationDetails!.haveAppointment = 1; + widget.patientER_RC.transportationDetails!.dropoffLatitude = myAppointment!.latitude; + widget.patientER_RC.transportationDetails!.dropoffLongitude = myAppointment!.longitude; + widget.patientER_RC.transportationDetails!.dropoffLocationName = myAppointment!.projectName; + } else { + widget.patientER_RC.transportationDetails!.appointmentNo = "0"; + widget.patientER_RC.transportationDetails!.appointmentClinicName = ""; + widget.patientER_RC.transportationDetails!.appointmentDoctorName = ""; + widget.patientER_RC.transportationDetails!.appointmentBranch = ""; + widget.patientER_RC.transportationDetails!.appointmentTime = ""; + widget.patientER_RC.transportationDetails!.haveAppointment = 0; + } + + widget.patientER_RC.transportationDetails!.pickupSpot = _isInsideHome ? 1 : 0; + + widget.patientER_RC.transportationDetails!.ambulate = 3; + widget.patientER_RC.transportationDetails!.ambulateTitle = "none"; + widget.patientER_RC.transportationDetails!.notes = ""; + + widget.changeCurrentTab(3); + }); + }, + color: CustomColors.green, + ), + ), + ], ), ), ); } + 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; - }); + builder: (cxt) => RadioSelectionDialog( + listData: list, + selectedIndex: _selectedHospitalIndex, + isScrollable: true, + onValueSelected: (index) { + _selectedHospitalIndex = index; + _selectedHospital = hospitals[index]; + setState(() {}); }, ), ); } String getHospitalName(String title) { - return _selectedHospital == null ? title : _selectedHospital.name; + return _selectedHospital == null ? title : _selectedHospital!.name!; } String getSelectFromMapName(context) { return _result != null - ? _result.formattedAddress - : TranslationBase.of(context).selectMap; + ? _result!.formattedAddress != null + ? _result!.formattedAddress! + : "" + : ""; } getAppointment() { GifLoaderDialogUtils.showMyDialog(context); widget.amRequestViewModel.getAppointmentHistory().then((value) { - if (widget.amRequestViewModel.state == ViewState.Error || - widget.amRequestViewModel.state == ViewState.ErrorLocal) { + if (widget.amRequestViewModel.state == ViewState.Error || widget.amRequestViewModel.state == ViewState.ErrorLocal) { AppToast.showErrorToast(message: widget.amRequestViewModel.error); - } else if (widget - .amRequestViewModel.appoitmentAllHistoryResultList.length > - 0) { + } else if (widget.amRequestViewModel.appoitmentAllHistoryResultList.length > 0) { GifLoaderDialogUtils.hideDialog(context); Navigator.push( context, FadePage( page: AvailableAppointmentsPage( - appointmentsAllHistoryList: - widget.amRequestViewModel.appoitmentAllHistoryResultList, + appointmentsAllHistoryList: widget.amRequestViewModel.appoitmentAllHistoryResultList, ), ), ).then((value) { if (value != null) setState(() { myAppointment = value; + HospitalsModel hospitalsModel = HospitalsModel(); + hospitalsModel.name = myAppointment!.projectName; + hospitalsModel.iD = myAppointment!.projectID; + hospitalsModel.mainProjectID = myAppointment!.projectID; + hospitalsModel.latitude = myAppointment!.latitude; + hospitalsModel.longitude = myAppointment!.longitude; + _selectedHospital = hospitalsModel; }); else { ProgressDialogUtil.hideProgressDialog(context); @@ -526,8 +705,7 @@ class _PickupLocationState extends State { setState(() { _haveAppointment = HaveAppointment.NO; }); - AppToast.showErrorToast( - message: TranslationBase.of(context).noAppointment); + AppToast.showErrorToast(message: TranslationBase.of(context).noAppointment); } }).catchError((e) { GifLoaderDialogUtils.hideDialog(context); diff --git a/lib/pages/ErService/AmbulanceRequestIndexPages/SelectTransportationMethod.dart b/lib/pages/ErService/AmbulanceRequestIndexPages/SelectTransportationMethod.dart index 63d915d1..1dac66a0 100644 --- a/lib/pages/ErService/AmbulanceRequestIndexPages/SelectTransportationMethod.dart +++ b/lib/pages/ErService/AmbulanceRequestIndexPages/SelectTransportationMethod.dart @@ -1,39 +1,37 @@ import 'package:diplomaticquarterapp/core/enum/OrderService.dart'; import 'package:diplomaticquarterapp/core/model/er/PatientER.dart'; +import 'package:diplomaticquarterapp/core/model/er/PatientER_RC.dart'; import 'package:diplomaticquarterapp/core/model/er/get_all_transportation_method_list_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/er/am_request_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +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/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; import 'package:provider/provider.dart'; enum Direction { ToHospital, FromHospital } + enum Way { OneWay, TwoWays } class SelectTransportationMethod extends StatefulWidget { final Function changeCurrentTab; final PatientER patientER; + final PatientER_RC patientER_RC; final AmRequestViewModel amRequestViewModel; - SelectTransportationMethod( - {Key key, - this.changeCurrentTab, - this.patientER, - this.amRequestViewModel}); + SelectTransportationMethod({Key? key, required this.changeCurrentTab, required this.patientER, required this.patientER_RC, required this.amRequestViewModel}); @override - _SelectTransportationMethodState createState() => - _SelectTransportationMethodState(); + _SelectTransportationMethodState createState() => _SelectTransportationMethodState(); } -class _SelectTransportationMethodState - extends State { - PatientERTransportationMethod _erTransportationMethod = - PatientERTransportationMethod(); +class _SelectTransportationMethodState extends State { + PatientERTransportationMethod _erTransportationMethod = PatientERTransportationMethod(); Direction _direction = Direction.FromHospital; Way _way = Way.OneWay; @@ -42,17 +40,21 @@ class _SelectTransportationMethodState @override void initState() { super.initState(); - if (widget.patientER.direction != null) { - _direction = widget.patientER.direction == 0 - ? Direction.ToHospital - : Direction.FromHospital; - _way = widget.patientER.tripType == 1 ? Way.OneWay : Way.TwoWays; - _erTransportationMethod = widget.amRequestViewModel - .amRequestModeList[(widget.patientER.selectedAmbulate - 1)]; + // if (widget.patientER.direction != null) { + // _direction = widget.patientER.direction == 0 ? Direction.ToHospital : Direction.FromHospital; + // _way = widget.patientER.tripType == 1 ? Way.OneWay : Way.TwoWays; + // _erTransportationMethod = widget.amRequestViewModel.amRequestModeList[(widget.patientER.selectedAmbulate - 1)]; + // } else { + // if (widget.amRequestViewModel.amRequestModeList.length != 0) _erTransportationMethod = widget.amRequestViewModel.amRequestModeList[widget.amRequestViewModel.amRequestModeList.length - 1]; + // } + + //RC API Revamp + if (widget.patientER_RC.transportationDetails!.direction != null) { + _direction = widget.patientER_RC.transportationDetails!.direction == 0 ? Direction.ToHospital : Direction.FromHospital; + _way = widget.patientER_RC.transportationDetails!.tripType == 1 ? Way.OneWay : Way.TwoWays; + _erTransportationMethod = widget.amRequestViewModel.amRequestModeList[(widget.patientER_RC.transportationDetails!.ambulate! - 1)]; } else { - if (widget.amRequestViewModel.amRequestModeList.length != 0) - _erTransportationMethod = widget.amRequestViewModel.amRequestModeList[ - widget.amRequestViewModel.amRequestModeList.length - 1]; + if (widget.amRequestViewModel.amRequestModeList.length != 0) _erTransportationMethod = widget.amRequestViewModel.amRequestModeList[widget.amRequestViewModel.amRequestModeList.length - 1]; } } @@ -72,63 +74,85 @@ class _SelectTransportationMethodState SizedBox( height: 12, ), - Texts(TranslationBase.of(context).transportHeading), - ...List.generate( - widget.amRequestViewModel.amRequestModeList.length, - (index) => InkWell( - onTap: () { - setState(() { - _erTransportationMethod = - widget.amRequestViewModel.amRequestModeList[index]; - }); - }, - child: Container( - margin: EdgeInsets.all(5), - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), - child: Row( - children: [ - Expanded( - flex: 3, - child: ListTile( - title: Texts(projectViewModel.isArabic - ? widget.amRequestViewModel - .amRequestModeList[index].titleAR - : widget.amRequestViewModel - .amRequestModeList[index].title), - leading: Radio( - value: widget - .amRequestViewModel.amRequestModeList[index], - groupValue: _erTransportationMethod, - onChanged: (value) { - setState(() { - _erTransportationMethod = value; - }); - }, - ), + Text(TranslationBase.of(context).transportHeading, style: TextStyle(fontSize: 16.0, letterSpacing: -0.64, fontWeight: FontWeight.w600)), + Container( + margin: EdgeInsets.only(top: 12), + decoration: cardRadius(12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ...List.generate( + widget.amRequestViewModel.amRequestModeList.length, + (index) => InkWell( + onTap: () { + setState(() { + _erTransportationMethod = widget.amRequestViewModel.amRequestModeList[index]; + }); + }, + child: Container( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + flex: 4, + child: ListTile( + contentPadding: EdgeInsets.only(left: 0.0, right: 0.0), + title: Row( + children: [ + Radio( + value: widget.amRequestViewModel.amRequestModeList[index], + groupValue: _erTransportationMethod, + onChanged: (value) { + setState(() { + _erTransportationMethod = value!; + }); + }, + ), + Flexible( + child: Text( + projectViewModel.isArabic ? widget.amRequestViewModel.amRequestModeList[index].textN! : widget.amRequestViewModel.amRequestModeList[index].text!, + style: TextStyle( + fontSize: 12.0, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + ), + ), + ), + ], + ), + ), + ), + Expanded( + flex: 1, + child: Row( + children: [ + projectViewModel.isArabic ? Container() : SvgPicture.asset("assets/images/new/Saudi_Riyal_Symbol.svg", width: 16, height: 16), + mWidth(6), + Text( + ' ${widget.amRequestViewModel.amRequestModeList[index].priceTotal}', + style: TextStyle( + fontSize: 12.0, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + ), + ), + mWidth(6), + projectViewModel.isArabic ? SvgPicture.asset("assets/images/new/Saudi_Riyal_Symbol.svg", width: 16, height: 16) : Container(), + ], + ), + ) + ], ), ), - Expanded( - flex: 1, - child: Texts(TranslationBase.of(context).sar + - ' ${widget.amRequestViewModel.amRequestModeList[index].price}'), - ) - ], + ), ), - ), + ], ), ), SizedBox( height: 12, ), - Texts(TranslationBase.of(context).directionHeading), - SizedBox( - height: 5, - ), + Text(TranslationBase.of(context).directionHeading, style: TextStyle(fontSize: 16.0, letterSpacing: -0.64, fontWeight: FontWeight.w600)), Container( width: double.maxFinite, child: Row( @@ -144,22 +168,26 @@ class _SelectTransportationMethodState }, child: Container( width: double.maxFinite, - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), child: ListTile( - title: Texts(TranslationBase.of(context).toHospital), - leading: Radio( - value: Direction.ToHospital, - groupValue: _direction, - onChanged: (value) { - setState(() { - _direction = value; - }); - }, + contentPadding: EdgeInsets.only(left: 0.0, right: 0.0), + title: Row( + children: [ + Radio( + value: Direction.ToHospital, + groupValue: _direction, + onChanged: (value) { + setState(() { + _direction = value!; + }); + }, + ), + Text(TranslationBase.of(context).toHospital, + style: TextStyle( + fontSize: 12.0, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + )), + ], ), ), ), @@ -174,23 +202,26 @@ class _SelectTransportationMethodState }, child: Container( width: double.maxFinite, - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), child: ListTile( - title: - Texts(TranslationBase.of(context).fromHospital), - leading: Radio( - value: Direction.FromHospital, - groupValue: _direction, - onChanged: (value) { - setState(() { - _direction = value; - }); - }, + contentPadding: EdgeInsets.only(left: 0.0, right: 0.0), + title: Row( + children: [ + Radio( + value: Direction.FromHospital, + groupValue: _direction, + onChanged: (value) { + setState(() { + _direction = value!; + }); + }, + ), + Text(TranslationBase.of(context).fromHospital, + style: TextStyle( + fontSize: 12.0, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + )), + ], ), ), ), @@ -206,12 +237,11 @@ class _SelectTransportationMethodState SizedBox( height: 8, ), - Texts(TranslationBase.of(context).directionHeading), + Text(TranslationBase.of(context).wayHeading, style: TextStyle(fontSize: 16.0, letterSpacing: -0.64, fontWeight: FontWeight.w600)), SizedBox( height: 5, ), Container( - margin: EdgeInsets.only(bottom:65 ), child: Row( children: [ Expanded( @@ -222,24 +252,26 @@ class _SelectTransportationMethodState }); }, child: Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: - Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), child: ListTile( - title: - Texts(TranslationBase.of(context).oneDirec), - leading: Radio( - value: Way.OneWay, - groupValue: _way, - onChanged: (value) { - setState(() { - _way = value; - }); - }, + contentPadding: EdgeInsets.only(left: 0.0, right: 0.0), + title: Row( + children: [ + Radio( + value: Way.OneWay, + groupValue: _way, + onChanged: (value) { + setState(() { + _way = value!; + }); + }, + ), + Text(TranslationBase.of(context).oneDirec, + style: TextStyle( + fontSize: 12.0, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + )), + ], ), ), ), @@ -253,24 +285,28 @@ class _SelectTransportationMethodState }); }, child: Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: - Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), child: ListTile( - title: - Texts(TranslationBase.of(context).twoDirec), - leading: Radio( - value: Way.TwoWays, - groupValue: _way, - onChanged: (value) { - setState(() { - _way = value; - }); - }, + contentPadding: EdgeInsets.only(left: 0.0, right: 0.0), + title: Row( + children: [ + Radio( + value: Way.TwoWays, + groupValue: _way, + onChanged: (value) { + setState(() { + _way = value!; + }); + }, + ), + Text( + TranslationBase.of(context).twoDirec, + style: TextStyle( + fontSize: 12.0, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + ), + ), + ], ), ), ), @@ -279,52 +315,101 @@ class _SelectTransportationMethodState ], ), ), - SizedBox( - height: 30, - ), + // SizedBox( + // height: 30, + // ), ], ), + Container( + margin: EdgeInsets.only(top: 12), + decoration: cardRadius(12), + padding: EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(TranslationBase.of(context).billAmount + " : ", style: TextStyle(fontSize: 16.0, letterSpacing: -0.64, fontWeight: FontWeight.w600)), + SizedBox(height: 16.0), + Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text(TranslationBase.of(context).patientShareTotalToDo, style: TextStyle(fontSize: 13.0, letterSpacing: -0.64, fontWeight: FontWeight.w600)), + Row( + children: [ + projectViewModel.isArabic ? Container() : SvgPicture.asset("assets/images/new/Saudi_Riyal_Symbol.svg", width: 16, height: 16), + mWidth(6), + Text( + (_way == Way.OneWay ? ' ${_erTransportationMethod.priceTotal}' : ' ${(_erTransportationMethod.priceTotal * 2)}'), + style: TextStyle(fontSize: 16.0, letterSpacing: -0.64, fontWeight: FontWeight.bold), + ), + mWidth(6), + projectViewModel.isArabic ? SvgPicture.asset("assets/images/new/Saudi_Riyal_Symbol.svg", width: 16, height: 16) : Container(), + ], + ), + ], + ) + ], + ), + ), SizedBox( - height: 15, + height: 100, ), ], ), ), ), bottomSheet: Container( - padding: EdgeInsets.all(15), - width: double.maxFinite, - height: 90, - child: SecondaryButton( - color: Colors.grey[800], - textColor: Colors.white, - onTap: () { - setState(() { - widget.patientER.transportationMethodId = (widget - .amRequestViewModel.amRequestModeList - .indexOf(_erTransportationMethod) + - 1); - widget.patientER.direction = - _direction == Direction.ToHospital ? 1 : 0; - widget.patientER.tripType = _way == Way.TwoWays ? 0 : 1; - widget.patientER.selectedAmbulate = (widget - .amRequestViewModel.amRequestModeList - .indexOf(_erTransportationMethod) + - 1); - widget.patientER.patientERTransportationMethod = - _erTransportationMethod; - widget.patientER.orderServiceID = - _orderService.getIdOrderService(); - widget.patientER.pickupUrgency = 1; - widget.patientER.lineItemNo = 1; - widget.patientER.cost = _erTransportationMethod.price; - widget.patientER.vAT = _erTransportationMethod.vAT ?? 0; - widget.patientER.totalPrice = - _erTransportationMethod.totalPrice; - widget.changeCurrentTab(1); - }); - }, - label: TranslationBase.of(context).next, + color: Theme.of(context).scaffoldBackgroundColor, + padding: EdgeInsets.all(12.0), + child: Row( + children: [ + Expanded( + flex: 1, + child: DefaultButton( + TranslationBase.of(context).back, + () { + Navigator.pop(context); + }, + )), + SizedBox(width: 12.0), + Expanded( + flex: 1, + child: DefaultButton( + TranslationBase.of(context).next, + () { + setState(() { + // widget.patientER.transportationMethodId = (widget.amRequestViewModel.amRequestModeList.indexOf(_erTransportationMethod) + 1); + // widget.patientER.direction = _direction == Direction.ToHospital ? 1 : 0; + // widget.patientER.tripType = _way == Way.TwoWays ? 0 : 1; + // widget.patientER.selectedAmbulate = (widget.amRequestViewModel.amRequestModeList.indexOf(_erTransportationMethod) + 1); + // widget.patientER.patientERTransportationMethod = _erTransportationMethod; + // widget.patientER.orderServiceID = _orderService.getIdOrderService(); + // widget.patientER.pickupUrgency = 1; + // widget.patientER.lineItemNo = 1; + // widget.patientER.cost = _erTransportationMethod.price.toDouble(); + // widget.patientER.vAT = _erTransportationMethod.priceVAT ?? 0; + // widget.patientER.totalPrice = _erTransportationMethod.priceTotal.toDouble(); + // widget.changeCurrentTab(1); + + // widget.patientER_RC.transportationDetails.id = (widget.amRequestViewModel.amRequestModeList.indexOf(_erTransportationMethod) + 1); + widget.patientER_RC.transportationDetails!.direction = _direction == Direction.ToHospital ? 0 : 1; + widget.patientER_RC.transportationDetails!.tripType = _way == Way.TwoWays ? 0 : 1; + widget.patientER_RC.transportationDetails!.ambulate = (widget.amRequestViewModel.amRequestModeList.indexOf(_erTransportationMethod) + 1); + widget.patientER_RC.transportationDetails!.transportationType = _erTransportationMethod.iD.toString(); + widget.patientER_RC.patientERTransportationMethod = _erTransportationMethod; + widget.patientER_RC.transportationDetails!.pickupUrgency = 1; + // widget.patientER.orderServiceID = _orderService.getIdOrderService(); + // widget.patientER.lineItemNo = 1; + // widget.patientER.cost = _erTransportationMethod.price.toDouble(); + // widget.patientER.vAT = _erTransportationMethod.priceVAT ?? 0; + // widget.patientER.totalPrice = _erTransportationMethod.priceTotal.toDouble(); + widget.changeCurrentTab(1); + }); + }, + color: CustomColors.green, + ), + ), + ], ), ), ); diff --git a/lib/pages/ErService/AmbulanceRequestIndexPages/Summary.dart b/lib/pages/ErService/AmbulanceRequestIndexPages/Summary.dart index 4ddfaaa3..86442ce6 100644 --- a/lib/pages/ErService/AmbulanceRequestIndexPages/Summary.dart +++ b/lib/pages/ErService/AmbulanceRequestIndexPages/Summary.dart @@ -1,19 +1,26 @@ import 'package:diplomaticquarterapp/core/model/er/PatientER.dart'; +import 'package:diplomaticquarterapp/core/model/er/PatientER_RC.dart'; import 'package:diplomaticquarterapp/core/viewModels/er/am_request_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.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/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:diplomaticquarterapp/core/enum/Ambulate.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:provider/provider.dart'; +import 'package:url_launcher/url_launcher.dart'; class Summary extends StatefulWidget { - final Function changeCurrentTab; + final Function(int)? changeCurrentTab; final PatientER patientER; + final PatientER_RC patientER_RC; final AmRequestViewModel amRequestViewModel; + final TabController tabController; - Summary({Key key, this.changeCurrentTab, this.patientER, this.amRequestViewModel}); + Summary({Key? key, required this.changeCurrentTab, required this.patientER, required this.patientER_RC, required this.amRequestViewModel, required this.tabController}); @override _SummaryState createState() => _SummaryState(); @@ -22,93 +29,206 @@ class Summary extends StatefulWidget { class _SummaryState extends State { @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); return AppScaffold( isShowDecPage: false, isShowAppBar: false, body: SingleChildScrollView( child: Container( - margin: EdgeInsets.only(left: 12, right: 12), + margin: EdgeInsets.only(left: 12, right: 12, top: 12), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Texts(TranslationBase.of(context).RRTSummary), - SizedBox(height: 5,), + Text(TranslationBase.of(context).RRTSummary, style: TextStyle(fontSize: 16.0, letterSpacing: -0.64, fontWeight: FontWeight.w600)), + SizedBox( + height: 5, + ), Container( width: double.infinity, padding: EdgeInsets.all(10), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(12), - ), + // margin: EdgeInsets.only(top: 12), + decoration: cardRadius(12), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Texts(TranslationBase.of(context).transportMethod,color: Colors.grey,), - Texts('${widget.patientER.patientERTransportationMethod.title}',bold: true,), - SizedBox(height: 8,), - - Texts(TranslationBase.of(context).directions,color: Colors.grey,), - Texts(widget.patientER.direction ==0? TranslationBase.of(context).toHospital:TranslationBase.of(context).fromHospital,bold: true,), - SizedBox(height: 8,), - - Texts(TranslationBase.of(context).pickupLocation,color: Colors.grey,), - Texts('${widget.patientER.pickupLocationName}',bold: true,), - SizedBox(height: 8,), - - Texts(TranslationBase.of(context).dropoffLocation,color: Colors.grey,), - Texts('${widget.patientER.dropoffLocationName}',bold: true,), - SizedBox(height: 8,), - - Texts(TranslationBase.of(context).selectAmbulate,color: Colors.grey,), - Texts('${widget.patientER.ambulate.getAmbulateTitle(context)}',bold: true,), - SizedBox(height: 8,), - - Texts(TranslationBase.of(context).notes,color: Colors.grey,), - Texts('${widget.patientER.requesterNote?? '---'}',bold: true,), - SizedBox(height: 8,), + _getNormalText(TranslationBase.of(context).transportMethod), + projectViewModel.isArabic + ? _getNormalText( + '${widget.patientER_RC.patientERTransportationMethod!.textN}', + isBold: true, + ) + : _getNormalText( + '${widget.patientER_RC.patientERTransportationMethod!.text}', + isBold: true, + ), + SizedBox( + height: 8, + ), + _getNormalText(TranslationBase.of(context).directions), + _getNormalText( + widget.patientER_RC.transportationDetails!.direction == 0 ? TranslationBase.of(context).toHospital : TranslationBase.of(context).fromHospital, + isBold: true, + ), + SizedBox( + height: 8, + ), + _getNormalText( + TranslationBase.of(context).pickupLocation, + ), + _getNormalText( + '${widget.patientER_RC.transportationDetails!.pickupLocationName}', + isBold: true, + ), + SizedBox( + height: 8, + ), + _getNormalText(TranslationBase.of(context).dropoffLocation), + _getNormalText( + '${widget.patientER_RC.transportationDetails!.dropoffLocationName}', + isBold: true, + ), + SizedBox( + height: 8, + ), + _getNormalText(TranslationBase.of(context).way), + _getNormalText( + widget.patientER_RC.transportationDetails!.tripType == 0 ? TranslationBase.of(context).twoDirec : TranslationBase.of(context).oneDirec, + isBold: true, + ), + SizedBox( + height: 8, + ), + // // _getNormalText(TranslationBase.of(context).notes), + // // _getNormalText( + // // '${widget.patientER_RC.transportationDetails.notes ?? '---'}', + // // isBold: true, + // // ), + // SizedBox( + // height: 8, + // ), ], ), ), - SizedBox(height: 20,), - Texts(TranslationBase.of(context).billAmount,textAlign: TextAlign.start,), - SizedBox(height: 5,), + // SizedBox( + // height: 20, + // ), + // Text(TranslationBase.of(context).billAmount, style: TextStyle(fontSize: 16.0, letterSpacing: -0.64, fontWeight: FontWeight.w600)), + // SizedBox( + // height: 5, + // ), Container( - - height: 55, - padding: EdgeInsets.all(10), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(8) + margin: EdgeInsets.only(top: 12), + decoration: cardRadius(12), + padding: EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(TranslationBase.of(context).billAmount + " : ", style: TextStyle(fontSize: 16.0, letterSpacing: -0.64, fontWeight: FontWeight.w600)), + SizedBox(height: 16.0), + Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text(TranslationBase.of(context).patientShareTotalToDo, style: TextStyle(fontSize: 13.0, letterSpacing: -0.64, fontWeight: FontWeight.w600)), + Row( + children: [ + projectViewModel.isArabic ? Container() : SvgPicture.asset("assets/images/new/Saudi_Riyal_Symbol.svg", width: 16, height: 16), + mWidth(6), + Text( + (widget.patientER_RC.transportationDetails!.tripType == 1 + ? ' ${widget.patientER_RC.patientERTransportationMethod!.priceTotal}' + : ' ${(widget.patientER_RC.patientERTransportationMethod!.priceTotal * 2)}'), + style: TextStyle(fontSize: 16.0, letterSpacing: -0.64, fontWeight: FontWeight.bold), + ), + mWidth(6), + projectViewModel.isArabic ? SvgPicture.asset("assets/images/new/Saudi_Riyal_Symbol.svg", width: 16, height: 16) : Container(), + ], + ), + ], + ) + ], ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + ), + Container( + margin: EdgeInsets.only(top: 12), + decoration: cardRadius(12), + padding: EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Texts(TranslationBase.of(context).patientShareTotal+':'), - Texts(TranslationBase.of(context).sar+' ${widget.patientER.patientERTransportationMethod.totalPrice}') + Text(TranslationBase.of(context).contactRRT + " : ", style: TextStyle(fontSize: 16.0, letterSpacing: -0.64, fontWeight: FontWeight.w600)), + SizedBox(height: 16.0), + InkWell( + onTap: () { + launchUrl( + Uri.parse("tel://0115259555"), + ); + }, + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text("0115259555", style: TextStyle(fontSize: 16.0, letterSpacing: -0.64, fontWeight: FontWeight.bold)), + Icon( + Icons.headset_mic_rounded, + size: 30.0, + ) + ], + ), + ) ], ), ), - SizedBox(height: 130), - - + SizedBox(height: 80), ], ), ), ), bottomSheet: Container( - padding: EdgeInsets.all(15), - width: double.maxFinite, - height: 90, - child:SecondaryButton( - color: Colors.grey[800], - textColor: Colors.white, - label: TranslationBase.of(context).send, - onTap: () async { - await widget.amRequestViewModel.insertERPressOrder(patientER: widget.patientER); - - } + color: Theme.of(context).scaffoldBackgroundColor, + padding: EdgeInsets.all(12.0), + child: Row( + children: [ + Expanded( + flex: 1, + child: DefaultButton( + TranslationBase.of(context).back, + () { + widget.changeCurrentTab!(1); + }, + ), + ), + SizedBox(width: 12.0), + Expanded( + flex: 1, + child: DefaultButton( + TranslationBase.of(context).submit, + () async { + await widget.amRequestViewModel.insertERPressOrder(patientER: widget.patientER_RC); + widget.tabController.animateTo(1); + }, + color: CustomColors.green, + ), + ), + ], ), ), ); } + + _getNormalText(text, {bool isBold = false, bool isTotal = false}) { + return Text( + text, + style: TextStyle( + fontSize: isBold + ? isTotal + ? 16 + : 12 + : 10, + letterSpacing: -0.5, + color: isBold ? Colors.black : Colors.grey[700], + fontWeight: FontWeight.w600, + ), + ); + } } diff --git a/lib/pages/ErService/AvailableAppointmentsPage.dart b/lib/pages/ErService/AvailableAppointmentsPage.dart index 7180d5dd..58d23080 100644 --- a/lib/pages/ErService/AvailableAppointmentsPage.dart +++ b/lib/pages/ErService/AvailableAppointmentsPage.dart @@ -1,6 +1,7 @@ import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; -import 'package:diplomaticquarterapp/pages/ErService/widgets/AppointmentCard.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/medical/doctor_card.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -8,30 +9,44 @@ import 'package:flutter/material.dart'; class AvailableAppointmentsPage extends StatelessWidget { final List appointmentsAllHistoryList; - const AvailableAppointmentsPage({Key key, this.appointmentsAllHistoryList}) - : super(key: key); + const AvailableAppointmentsPage({Key? key, required this.appointmentsAllHistoryList}) : super(key: key); @override Widget build(BuildContext context) { return AppScaffold( isShowAppBar: true, - appBarTitle: 'Available Appointments', + appBarTitle: TranslationBase.of(context).myAppointmentsList, + showNewAppBar: true, + backgroundColor: Color(0xffF8F8F8), + showNewAppBarTitle: true, body: SingleChildScrollView( child: Container( + padding: EdgeInsets.only(bottom: 14, top: 14, left: 21, right: 21), child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ - Texts('Available Appointments'), SizedBox( height: 12, ), ...List.generate( appointmentsAllHistoryList.length, (index) => InkWell( - onTap: (){ + onTap: () { Navigator.pop(context, appointmentsAllHistoryList[index]); }, - child: AppointmentCard(appointment: appointmentsAllHistoryList[index],), + child: DoctorCard( + isInOutPatient: appointmentsAllHistoryList[index].isInOutPatient, + name: appointmentsAllHistoryList[index].doctorTitle! + " " + appointmentsAllHistoryList[index].doctorNameObj!, + profileUrl: appointmentsAllHistoryList[index].doctorImageURL, + subName: appointmentsAllHistoryList[index].clinicName, + isLiveCareAppointment: appointmentsAllHistoryList[index].isLiveCareAppointment, + date: DateUtil.convertStringToDate(appointmentsAllHistoryList[index].appointmentDate!), + isSortByClinic: false, + rating: appointmentsAllHistoryList[index].actualDoctorRate! + 0.0, + appointmentTime: appointmentsAllHistoryList[index].isLiveCareAppointment! + ? DateUtil.convertStringToDate(appointmentsAllHistoryList[index].appointmentDate!).toString().split(" ")[1].substring(0, 5) + : appointmentsAllHistoryList[index].startTime!.substring(0, 5), + remainingTimeInMinutes: null), ), ) ], @@ -41,5 +56,3 @@ class AvailableAppointmentsPage extends StatelessWidget { ); } } - - diff --git a/lib/pages/ErService/EROnlineCheckIn/EROnlineCheckInBookAppointment.dart b/lib/pages/ErService/EROnlineCheckIn/EROnlineCheckInBookAppointment.dart new file mode 100644 index 00000000..946f6003 --- /dev/null +++ b/lib/pages/ErService/EROnlineCheckIn/EROnlineCheckInBookAppointment.dart @@ -0,0 +1,203 @@ +import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/pages/ErService/EROnlineCheckIn/EROnlineCheckInPaymentDetails.dart'; +import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class EROnlineCheckInBookAppointment extends StatefulWidget { + const EROnlineCheckInBookAppointment(); + + @override + State createState() => _EROnlineCheckInBookAppointmentState(); +} + +class _EROnlineCheckInBookAppointmentState extends State with SingleTickerProviderStateMixin { + late ProjectViewModel projectViewModel; + List projectsList = []; + final GlobalKey projectDropdownKey = GlobalKey(); + HospitalsModel? selectedHospital; + String projectDropdownValue = ""; + + @override + void initState() { + WidgetsBinding.instance.addPostFrameCallback((_) { + getProjectsList(); + }); + super.initState(); + } + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + return AppScaffold( + isShowAppBar: true, + appBarTitle: TranslationBase.of(context).emergency + " ${TranslationBase.of(context).checkinOptions}", + isShowDecPage: false, + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: Color(0xffF8F8F8), + body: Padding( + padding: EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + InkWell( + onTap: () { + openDropdown(projectDropdownKey); + }, + child: Container( + width: double.infinity, + decoration: containerRadius(Colors.white, 12), + padding: EdgeInsets.only(left: 10, right: 10, top: 12, bottom: 12), + child: Row( + children: [ + Flexible( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).selectHospital, + style: TextStyle( + fontSize: 11, + letterSpacing: -0.44, + fontWeight: FontWeight.w600, + ), + ), + Container( + height: 18, + child: DropdownButtonHideUnderline( + child: DropdownButton( + key: projectDropdownKey, + hint: new Text(TranslationBase.of(context).selectHospital), + value: selectedHospital, + iconSize: 0, + isExpanded: true, + style: TextStyle(fontSize: 14, letterSpacing: -0.56, color: Colors.black), + items: projectsList.map((item) { + return new DropdownMenuItem( + value: item, + child: new Text(item.name! + " - " + item.distanceInKilometers.toString() + " " + TranslationBase.of(context).km), + ); + }).toList(), + onChanged: (newValue) async { + setState(() { + selectedHospital = newValue; + projectDropdownValue = newValue!.mainProjectID.toString(); + }); + }, + ), + ), + ), + ], + ), + ), + Icon(Icons.keyboard_arrow_down), + ], + ), + ), + ), + mHeight(16), + Container( + width: double.infinity, + decoration: containerRadius(Colors.white, 12), + padding: EdgeInsets.only(left: 10, right: 10, top: 12, bottom: 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).clinicName, + style: TextStyle( + fontSize: 11, + letterSpacing: -0.44, + fontWeight: FontWeight.w600, + ), + ), + Text( + "ER Clinic", + style: TextStyle(fontSize: 14, letterSpacing: -0.56, color: Colors.black), + ), + ], + ), + ), + ], + ), + ), + bottomSheet: Container( + height: 80, + color: CustomColors.white, + padding: EdgeInsets.fromLTRB(12.0, 12.0, 12.0, 25.0), + child: DefaultButton( + TranslationBase.of(context).bookAppo, + () { + if (projectDropdownValue == "" || selectedHospital == null) { + AppToast.showErrorToast(message: TranslationBase.of(context).selectHospital); + } else { + Navigator.push( + context, + FadePage( + page: EROnlineCheckInPaymentDetails( + projectID: selectedHospital!.iD, + isERBookAppointment: true, + projectName: selectedHospital!.name ?? "", + ), + ), + ); + } + }, + color: CustomColors.accentColor, + ), + ), + ); + } + + getProjectsList() { + int languageID = projectViewModel.isArabic ? 1 : 2; + GifLoaderDialogUtils.showMyDialog(context); + ClinicListService service = new ClinicListService(); + List projectsListLocal = []; + service.getProjectsList(languageID, context).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res['MessageStatus'] == 1) { + setState(() { + res['ListProject'].forEach((v) { + projectsListLocal.add(new HospitalsModel.fromJson(v)); + }); + projectsList = projectsListLocal; + }); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } + + void openDropdown(GlobalKey key) { + GestureDetector? detector; + void searchForGestureDetector(BuildContext element) { + element.visitChildElements((element) { + if (element.widget != null && element.widget is GestureDetector) { + detector = element.widget as GestureDetector?; + // return false; + } else { + searchForGestureDetector(element); + } + // return true; + }); + } + + searchForGestureDetector(key.currentContext!); + assert(detector != null); + detector!.onTap!(); + } +} diff --git a/lib/pages/ErService/EROnlineCheckIn/EROnlineCheckInHome.dart b/lib/pages/ErService/EROnlineCheckIn/EROnlineCheckInHome.dart new file mode 100644 index 00000000..d1ecc3ad --- /dev/null +++ b/lib/pages/ErService/EROnlineCheckIn/EROnlineCheckInHome.dart @@ -0,0 +1,556 @@ +import 'package:barcode_scan2/barcode_scan2.dart'; +import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/pages/ErService/EROnlineCheckIn/EROnlineCheckInBookAppointment.dart'; +import 'package:diplomaticquarterapp/pages/ErService/EROnlineCheckIn/EROnlineCheckInNFCQRCLocation.dart'; +import 'package:diplomaticquarterapp/pages/ErService/EROnlineCheckIn/EROnlineCheckInPaymentDetails.dart'; +import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; +import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; +import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/location_util.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/bottom_options/bottom_sheet.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:diplomaticquarterapp/widgets/nfc/nfc_reader_sheet.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_nfc_kit/flutter_nfc_kit.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:provider/provider.dart'; + +class EROnlineCheckInHomePage extends StatefulWidget { + const EROnlineCheckInHomePage(); + + @override + State createState() => _EROnlineCheckInHomePageState(); +} + +class _EROnlineCheckInHomePageState extends State with SingleTickerProviderStateMixin { + late ProjectViewModel projectViewModel; + bool _supportsNFC = false; + bool isPatientArrived = false; + + late LocationUtils locationUtils; + + @override + void initState() { + locationUtils = new LocationUtils(isShowConfirmDialog: true, context: context); + WidgetsBinding.instance.addPostFrameCallback((_) { + // checkIfPatientHasArrived(); + if (projectViewModel.isLogin) checkPatientERAdvanceBalance(); + }); + super.initState(); + } + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + FlutterNfcKit.nfcAvailability.then((value) { + _supportsNFC = (value == NFCAvailability.available); + }); + return AppScaffold( + isShowAppBar: true, + appBarTitle: TranslationBase.of(context).emergency + " ${TranslationBase.of(context).checkinOptions}", + isShowDecPage: true, + showNewAppBar: true, + showNewAppBarTitle: true, + description: TranslationBase.of(context).HHCNotAuthMsg, + imagesInfo: [ImagesInfo(imageAr: 'https://hmgwebservices.com/Images/MobileApp/HHC/ar/0.png', imageEn: 'https://hmgwebservices.com/Images/MobileApp/HHC/en/0.png')], + backgroundColor: Color(0xffF8F8F8), + body: SingleChildScrollView( + child: Padding( + padding: EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10), bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10)), + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.1), + spreadRadius: 5, + blurRadius: 7, + offset: Offset(0, 3), // changes position of shadow + ), + ], + ), + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Icon( + Icons.check_circle, + size: 50, + color: CustomColors.green, + ), + mHeight(6), + Text( + TranslationBase.of(context).whatIsOnlineCheckIn, + maxLines: 1, + style: TextStyle( + fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12), + Text( + TranslationBase.of(context).EROnlineCheckInDesc1, + style: TextStyle(fontSize: 13, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: CustomColors.textDarkColor, letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(16), + // Text( + // TranslationBase.of(context).EROnlineCheckInHow, + // maxLines: 1, + // style: TextStyle( + // fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + // ), + // Text( + // "Online check-in lets patients fill out forms, share insurance details, and book appointments online, making their visit smoother and quicker.", + // style: TextStyle(fontSize: 14, color: CustomColors.textDarkColor, letterSpacing: -1.44, height: 35 / 24), + // ), + ], + ), + ), + ), + mHeight(24), + Container( + width: double.infinity, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10), bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10)), + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.1), + spreadRadius: 5, + blurRadius: 7, + offset: Offset(0, 3), // changes position of shadow + ), + ], + ), + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Container( + width: 35, + height: 35, + decoration: BoxDecoration( + color: CustomColors.green, + borderRadius: BorderRadius.circular(50), + ), + child: Center( + child: Text( + "1", + style: TextStyle(fontSize: 22, fontWeight: FontWeight.w700, color: CustomColors.white, letterSpacing: -1.44, height: 35 / 24), + ), + ), + ), + mWidth(12), + SvgPicture.asset( + "assets/images/new/tap.svg", + width: 35, + height: 35, + ), + ], + ), + Padding( + padding: const EdgeInsets.only(left: 50, right: 50), + child: Text( + TranslationBase.of(context).EROnlineCheckInTapOn, + maxLines: 1, + style: TextStyle( + fontSize: 20, + fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), + fontWeight: FontWeight.w700, + color: Color(0xff2B353E), + letterSpacing: -1.44, + height: 35 / 24), + ), + ), + Padding( + padding: const EdgeInsets.only(left: 50, right: 50), + child: Text( + TranslationBase.of(context).EROnlineCheckInTapOnCheckIn, + style: TextStyle(fontSize: 13, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w600, color: CustomColors.textDarkColor, letterSpacing: -1.44, height: 35 / 24), + ), + ), + mHeight(16), + Row( + children: [ + Container( + width: 35, + height: 35, + decoration: BoxDecoration( + color: CustomColors.green, + borderRadius: BorderRadius.circular(50), + ), + child: Center( + child: Text( + "2", + style: TextStyle(fontSize: 22, fontWeight: FontWeight.w700, color: CustomColors.white, letterSpacing: -1.44, height: 35 / 24), + ), + ), + ), + mWidth(12), + SvgPicture.asset( + "assets/images/new/NFC_Hold.svg", + width: 35, + height: 35, + ), + ], + ), + Padding( + padding: const EdgeInsets.only(left: 50, right: 50), + child: Text( + TranslationBase.of(context).EROnlineCheckInHoldPhone, + maxLines: 1, + style: TextStyle( + fontSize: 20, + fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), + fontWeight: FontWeight.w700, + color: Color(0xff2B353E), + letterSpacing: -1.44, + height: 35 / 24), + ), + ), + Padding( + padding: const EdgeInsets.only(left: 50, right: 50), + child: Text( + TranslationBase.of(context).EROnlineCheckInHoldPhoneInstruction, + style: TextStyle(fontSize: 13, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w600, color: CustomColors.textDarkColor, letterSpacing: -1.44, height: 35 / 24), + ), + ), + mHeight(16), + Row( + children: [ + Container( + width: 35, + height: 35, + decoration: BoxDecoration( + color: CustomColors.green, + borderRadius: BorderRadius.circular(50), + ), + child: Center( + child: Text( + "3", + style: TextStyle(fontSize: 22, fontWeight: FontWeight.w700, color: CustomColors.white, letterSpacing: -1.44, height: 35 / 24), + ), + ), + ), + mWidth(12), + SvgPicture.asset( + "assets/images/new/hourglass.svg", + width: 35, + height: 35, + ), + ], + ), + Padding( + padding: const EdgeInsets.only(left: 50, right: 50), + child: Text( + TranslationBase.of(context).EROnlineCheckInWaitTurn, + maxLines: 1, + style: TextStyle( + fontSize: 20, + fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), + fontWeight: FontWeight.w700, + color: Color(0xff2B353E), + letterSpacing: -1.44, + height: 35 / 24), + ), + ), + Padding( + padding: const EdgeInsets.only(left: 50, right: 50), + child: Text( + TranslationBase.of(context).EROnlineCheckInWaitTurnInstruction, + style: TextStyle(fontSize: 13, color: CustomColors.textDarkColor, fontWeight: FontWeight.w600, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), letterSpacing: -1.44, height: 35 / 24), + ), + ), + ], + ), + ), + ), + ], + ), + ), + ), + bottomSheet: Container( + height: projectViewModel.isLogin ? 80 : 1, + color: CustomColors.white, + padding: EdgeInsets.fromLTRB(12.0, 12.0, 12.0, 25.0), + child: isPatientArrived + ? Container( + child: DefaultButton( + TranslationBase.of(context).arrived, + () { + // showMyBottomSheet(context, + // callBackFunc: () {}, + // child: Padding( + // padding: const EdgeInsets.all(21.0), + // child: Column( + // children: [ + // Text(TranslationBase.of(context).scanQRHospital, + // style: TextStyle( + // fontSize: 20, + // fontWeight: FontWeight.w600, + // letterSpacing: -0.48, + // )), + // mHeight(21), + // GridView( + // physics: const NeverScrollableScrollPhysics(), + // shrinkWrap: true, + // gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + // crossAxisCount: (MediaQuery.of(context).size.width < 550) ? 3 : 5, childAspectRatio: 1 / 1, crossAxisSpacing: 8, mainAxisSpacing: 12), + // children: [ + // attendanceMethod(TranslationBase.of(context).scanNFC, "assets/images/nfc/contactless.svg", true, () { + // if (_supportsNFC) { + // Future.delayed(const Duration(milliseconds: 500), () { + // showNfcReader(context, onNcfScan: (String nfcId) { + // Future.delayed(const Duration(milliseconds: 100), () { + // print(nfcId); + // getProjectIDFromNFC(nfcId, true); + // // Navigator.push(context, FadePage(page: EROnlineCheckInPaymentDetails())); + // }); + // }, onCancel: () { + // Navigator.of(context).pop(); + // }); + // }); + // } else { + // //NFCNotSupported + // AppToast.showErrorToast(message: TranslationBase.of(context).NFCNotSupported); + // } + // }), + // attendanceMethod(TranslationBase.of(context).pharmaLiveCareScanQR, "assets/images/new/services/qr_code.svg", true, () async { + // String onlineCheckInQRCode = (await BarcodeScanner.scan().then((value) => value.rawContent)); + // if (onlineCheckInQRCode != "") { + // print(onlineCheckInQRCode); + // getProjectIDFromNFC(onlineCheckInQRCode, true); + // // sendNfcCheckInRequest(onlineCheckInQRCode, 2); + // } else {} + // }), + // attendanceMethod(TranslationBase.of(context).checkInViaLocation, "assets/images/new/services/location.svg", true, () {}) + // ], + // ), + // ], + // ), + // )); + + // Navigator.push(context, FadePage(page: EROnlineCheckInNFCQRLocation(projectID: 15))).then((value) {}); + + if (_supportsNFC) { + Future.delayed(const Duration(milliseconds: 500), () { + showNfcReader(context, onNcfScan: (String nfcId) { + Future.delayed(const Duration(milliseconds: 100), () { + print(nfcId); + getProjectIDFromNFC(nfcId, true); + // Navigator.push(context, FadePage(page: EROnlineCheckInPaymentDetails())); + }); + }, onCancel: () { + Navigator.of(context).pop(); + }); + }); + } else { + //NFCNotSupported + AppToast.showErrorToast(message: TranslationBase.of(context).NFCNotSupported); + } + }, + color: CustomColors.accentColor, + ), + ) + : Row( + children: [ + // Expanded( + // flex: 1, + // child: DefaultButton( + // TranslationBase.of(context).checkinOptions, + // () { + // // Navigator.push(context, FadePage(page: EROnlineCheckInNFCQRLocation(projectID: 15))).then((value) {}); + // + // if (_supportsNFC) { + // Future.delayed(const Duration(milliseconds: 500), () { + // showNfcReader(context, onNcfScan: (String nfcId) { + // Future.delayed(const Duration(milliseconds: 100), () { + // print(nfcId); + // getProjectIDFromNFC(nfcId, false); + // }); + // }, onCancel: () { + // Navigator.of(context).pop(); + // }); + // }); + // } else { + // //NFCNotSupported + // AppToast.showErrorToast(message: TranslationBase.of(context).NFCNotSupported, localContext: context); + // } + // }, + // color: CustomColors.green, + // ), + // ), + // mWidth(12), + Expanded( + flex: 1, + child: DefaultButton( + TranslationBase.of(context).bookAppo, + () { + Navigator.push(context, FadePage(page: EROnlineCheckInBookAppointment())); + }, + color: CustomColors.accentColor, + ), + ), + ], + ), + ), + ); + } + + void getProjectIDFromNFC(String nfcID, bool isArrived) { + GifLoaderDialogUtils.showMyDialog(context); + ClinicListService ancillaryOrdersService = new ClinicListService(); + ancillaryOrdersService.getProjectIDFromNFC(nfcID).then((response) { + if (response["GetProjectByNFC"].length != 0) { + print(response["GetProjectByNFC"]); + int projectID = response['GetProjectByNFC'][0]["ProjectID"]; + String projectName = response['GetProjectByNFC'][0]["ProjectName"]; + GifLoaderDialogUtils.hideDialog(context); + if (isArrived) { + autoGenerateInvoiceER(projectID); + } else { + Navigator.push( + context, + FadePage( + page: EROnlineCheckInPaymentDetails( + projectID: projectID, + isERBookAppointment: false, + projectName: projectName, + ), + ), + ); + } + } else { + AppToast.showErrorToast(message: "Invalid NFC Card Scanned."); + } + }).catchError((err) { + AppToast.showErrorToast(message: err.toString()); + GifLoaderDialogUtils.hideDialog(context); + }); + } + + autoGenerateInvoiceER(int projectID) { + GifLoaderDialogUtils.showMyDialog(context); + DoctorsListService service = new DoctorsListService(); + service.autoGenerateInvoiceERClinic(projectID, 4, null, null, null, null, null, null, true).then((res) { + GifLoaderDialogUtils.hideDialog(context); + _showMyDialog(TranslationBase.of(context).ERCheckInSuccess, context); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + + Future _showMyDialog(String message, BuildContext context) async { + return showDialog( + context: context, + barrierDismissible: true, // user must tap button! + builder: (BuildContext context) { + return AlertDialog( + title: const Text('Alert'), + content: SingleChildScrollView( + child: ListBody( + children: [ + Text(message), + ], + ), + ), + actions: [ + TextButton( + child: const Text('OK'), + onPressed: () { + Navigator.of(context).pop(); + Navigator.pushAndRemoveUntil(context, MaterialPageRoute(builder: (context) => LandingPage()), (Route r) => false); + }, + ), + ], + ); + }, + ); + } + + void checkIfPatientHasArrived() { + GifLoaderDialogUtils.showMyDialog(context); + ClinicListService ancillaryOrdersService = new ClinicListService(); + ancillaryOrdersService.checkIfPatientHasArrived(15, 10).then((response) { + print(response["IsPatientArrivedResponse"]); + isPatientArrived = response['IsPatientArrivedResponse']["IsPatientArrived"]; + GifLoaderDialogUtils.hideDialog(context); + // erOnlineCheckInPaymentDetailsResponse = EROnlineCheckInPaymentDetailsResponse.fromJson(response["ResponsePatientShare"]); + setState(() {}); + }).catchError((err) { + AppToast.showErrorToast(message: err.toString()); + GifLoaderDialogUtils.hideDialog(context); + }); + } + + Widget markCheckInWidget() { + return GridView( + physics: const NeverScrollableScrollPhysics(), + shrinkWrap: true, + padding: const EdgeInsets.only(bottom: 0, top: 21), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: (MediaQuery.of(context).size.width < 550) ? 3 : 5, childAspectRatio: 1 / 1, crossAxisSpacing: 8, mainAxisSpacing: 8), + children: [], + ); + } + + Widget attendanceMethod(String title, String image, bool isEnabled, VoidCallback onPress) => InkWell( + onTap: () { + Navigator.pop(context); + onPress(); + }, + child: Container( + decoration: containerColorRadiusBorderWidth(Colors.white, 15, CustomColors.darkGreyColor, 1), + clipBehavior: Clip.antiAlias, + padding: const EdgeInsets.only(left: 10, right: 10, top: 14, bottom: 14), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded(child: SvgPicture.asset(image, color: Colors.black, alignment: Alignment.topLeft)), + Text( + title, + style: TextStyle(color: Colors.black, fontSize: 14, letterSpacing: -0.68, fontWeight: FontWeight.bold), + ), + // title.toText17(isBold: true, color: Colors.white), + ], + ), + ), + ); + + // .onPress( + // () { + // if (!isEnabled) return; + // onPress(); + // }, + // ); + + void checkPatientERAdvanceBalance() { + locationUtils.getCurrentLocation(); + GifLoaderDialogUtils.showMyDialog(context); + ClinicListService ancillaryOrdersService = new ClinicListService(); + ancillaryOrdersService.checkPatientERAdvanceBalance(10).then((response) { + print(response["BalanceAmount"]); + isPatientArrived = response['BalanceAmount'] > 0; + GifLoaderDialogUtils.hideDialog(context); + setState(() {}); + }).catchError((err) { + AppToast.showErrorToast(message: err.toString()); + GifLoaderDialogUtils.hideDialog(context); + }); + } +} diff --git a/lib/pages/ErService/EROnlineCheckIn/EROnlineCheckInNFCQRCLocation.dart b/lib/pages/ErService/EROnlineCheckIn/EROnlineCheckInNFCQRCLocation.dart new file mode 100644 index 00000000..d3f1e20f --- /dev/null +++ b/lib/pages/ErService/EROnlineCheckIn/EROnlineCheckInNFCQRCLocation.dart @@ -0,0 +1,374 @@ +import 'dart:typed_data'; + +import 'package:barcode_scan2/barcode_scan2.dart'; +import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/model/privilege/ProjectDetailListModel.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/locator.dart'; +import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; +import 'package:diplomaticquarterapp/models/Appointments/PatientShareResposne.dart'; +import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; +import 'package:diplomaticquarterapp/models/header_model.dart'; +import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; +import 'package:diplomaticquarterapp/routes.dart'; +import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; +import 'package:diplomaticquarterapp/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/location_util.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/custom_text_button.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/medical/medical_profile_item.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; +import 'package:diplomaticquarterapp/widgets/new_design/doctor_header.dart'; +import 'package:diplomaticquarterapp/widgets/nfc/nfc_reader_sheet.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_nfc_kit/flutter_nfc_kit.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:provider/provider.dart'; + +class EROnlineCheckInNFCQRLocation extends StatefulWidget { + // late PatientShareResponse? patientShareResponse; + // late AppoitmentAllHistoryResultList? appointment; + // late String? appoQR; + // AuthenticatedUser? authUser; + // AppSharedPreferences sharedPref = AppSharedPreferences(); + + int projectID; + + EROnlineCheckInNFCQRLocation({required this.projectID}); + + @override + _EROnlineCheckInNFCQRLocationState createState() => _EROnlineCheckInNFCQRLocationState(); +} + +class _EROnlineCheckInNFCQRLocationState extends State { + late Uint8List _bytes; + bool _supportsNFC = false; + late BuildContext _context; + + late ProjectViewModel projectViewModel; + late LocationUtils locationUtils; + ProjectDetailListModel projectDetailListModel = ProjectDetailListModel(); + + @override + void initState() { + super.initState(); + } + + startNFCScan() { + Future.delayed(const Duration(milliseconds: 500), () { + showNfcReader(context, onNcfScan: (String nfcId) { + Future.delayed(const Duration(milliseconds: 100), () { + sendNfcCheckInRequest(nfcId, 2); + }); + }, onCancel: () { + // Navigator.of(context).pop(); + }); + }); + } + + startQRCodeScan() async { + String onlineCheckInQRCode = (await BarcodeScanner.scan().then((value) => value.rawContent)); + if (onlineCheckInQRCode != "") { + sendNfcCheckInRequest(onlineCheckInQRCode, 2); + } else {} + } + + startLocationCheckIn() async { + GifLoaderDialogUtils.showMyDialog(context); + locationUtils = new LocationUtils(isShowConfirmDialog: true, context: context); + locationUtils.getCurrentLocation(callBack: (value) { + projectDetailListModel = Utils.getProjectDetailObj(projectViewModel, widget.projectID); + double dist = Utils.distance(value.latitude, value.longitude, double.parse(projectDetailListModel.latitude!), double.parse(projectDetailListModel.longitude!)).ceilToDouble() * 1000; + print(dist); + if (dist <= projectDetailListModel.geofenceRadius!) { + sendNfcCheckInRequest(projectDetailListModel.checkInQrCode!, 2); + } else { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: TranslationBase.of(context).locationCheckInError); + } + }); + } + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + _context = context; + FlutterNfcKit.nfcAvailability.then((value) { + _supportsNFC = (value == NFCAvailability.available); + }); + List checkInOptionsList = getCheckInOptionsList(context); + return AppScaffold( + appBarTitle: TranslationBase.of(context).onlineCheckIn, + isShowAppBar: true, + showNewAppBar: true, + showNewAppBarTitle: true, + body: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // DoctorHeader( + // headerModel: HeaderModel( + // widget.appointment!.doctorTitle! + " " + widget.appointment!.doctorNameObj!, + // widget.appointment!.doctorID ?? 0, + // widget.appointment!.doctorImageURL!, + // widget.appointment!.doctorSpeciality!, + // "", + // widget.appointment!.projectName!, + // DateUtil.convertStringToDate(widget.appointment!.appointmentDate!), + // widget.appointment!.isLiveCareAppointment! + // ? DateUtil.convertStringToDate(widget.appointment!.appointmentDate!).toString().split(" ")[1].substring(0, 5) + // : widget.appointment!.startTime!.substring(0, 5), + // "null", + // widget.appointment!.doctorRate, + // widget.appointment!.actualDoctorRate, + // widget.appointment!.noOfPatientsRate, + // "", + // ), + // isShowName: true, + // isNeedToShowButton: false, + // buttonTitle: '', + // onTap: () {}, + // onRatingAndReviewTap: () {}, + // ), + InkWell( + child: Container( + margin: EdgeInsets.only(top: 30.0), + padding: EdgeInsets.all(8), + child: SvgPicture.asset( + "assets/images/nfc/contactless.svg", + width: 80.0, + height: 80.0, + ), + ), + onTap: () { + showNfcReader(context, onNcfScan: (String nfcId) { + Future.delayed(const Duration(milliseconds: 100), () { + sendNfcCheckInRequest(nfcId, 2); + }); + }, onCancel: () { + // Navigator.of(context).pop(); + }); + }, + ), + Row( + children: [ + Expanded( + child: Container( + width: double.infinity, + margin: EdgeInsets.only(top: 15.0, bottom: 10.0, left: 20.0, right: 20.0), + child: Text(TranslationBase.of(context).scanQRHospital, + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + )), + ), + ), + ], + ), + mHeight(21), + Padding( + padding: EdgeInsets.only(left: 21, right: 21), + child: GridView.builder( + shrinkWrap: true, + primary: false, + physics: NeverScrollableScrollPhysics(), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, childAspectRatio: 2 / 2, crossAxisSpacing: 12, mainAxisSpacing: 12), + padding: EdgeInsets.zero, + itemCount: checkInOptionsList.length, + itemBuilder: (BuildContext context, int index) { + return checkInOptionsList[index]; + }, + ), + ), + ], + ), + ), + // bottomSheet: Container( + // color: CustomColors.appBackgroudGreyColor, + // padding: EdgeInsets.all(21), + // // height: 45.0, + // child: Row( + // children: [ + // Expanded( + // flex: 1, + // child: ButtonTheme( + // shape: RoundedRectangleBorder( + // borderRadius: BorderRadius.circular(10.0), + // ), + // height: 45.0, + // child: CustomTextButton( + // backgroundColor: CustomColors.green, + // elevation: 0, + // onPressed: () { + // startNFCScan(); + // }, + // child: Text(TranslationBase.of(context).scanNFC, + // style: TextStyle( + // fontSize: 18.0, + // color: Colors.white, + // )), + // ), + // ), + // ), + // ], + // ), + // ), + ); + } + + List getCheckInOptionsList(BuildContext context) { + List optionsList = []; + + optionsList.add( + InkWell( + onTap: () { + if (projectViewModel.havePrivilege(102)) { + startLocationCheckIn(); + } + }, + child: MedicalProfileItem( + title: TranslationBase.of(context).checkInViaLocation, + imagePath: 'location.svg', + subTitle: "", + isEnable: projectViewModel.havePrivilege(102), + width: 70.0, + height: 70.0, + ), + ), + ); + + optionsList.add( + InkWell( + onTap: () { + if (projectViewModel.havePrivilege(79)) { + startQRCodeScan(); + } + }, + child: MedicalProfileItem( + title: TranslationBase.of(context).pharmaLiveCareScanQR, + imagePath: 'qr_code.svg', + subTitle: "", + isEnable: projectViewModel.havePrivilege(79), + width: 80.0, + height: 80.0, + ), + ), + ); + + optionsList.add( + InkWell( + onTap: () { + if (projectViewModel.havePrivilege(80) && _supportsNFC) { + startNFCScan(); + } else { + Utils.showErrorToast(TranslationBase.of(context).NFCNotSupported); + } + }, + child: MedicalProfileItem( + title: TranslationBase.of(context).scanNFC, + imagePath: 'contactless.svg', + subTitle: "", + isEnable: projectViewModel.havePrivilege(80), + width: 80.0, + height: 80.0, + ), + ), + ); + + return optionsList; + } + + Future navigateToHome(context) async { + Navigator.of(context).pushNamed(HOME); + } + + getPatientShare(context, String appointmentNo, int clinicID, int projectID, DoctorList docObject) {} + + String getDate(String appoDate) { + var appoDateFormatted = ""; + + var dateObj = DateUtil.convertStringToDate(appoDate); + + setState(() { + appoDateFormatted = DateUtil.getWeekDay(dateObj.weekday) + + ", " + + dateObj.day.toString() + + " " + + DateUtil.getMonth(dateObj.month) + + " " + + dateObj.year.toString() + + ", " + + dateObj.hour.toString() + + ":" + + dateObj.minute.toString() + + ":00"; + }); + + return appoDateFormatted; + } + + String getDoctorSpeciality(List docSpecial) { + String docSpeciality = ""; + if (docSpecial != null && docSpecial.length != 0) { + docSpecial.forEach((v) { + docSpeciality = docSpeciality + v + "\n"; + }); + } + return docSpeciality; + } + + sendNfcCheckInRequest(String nfcId, int checkInBy) { + GifLoaderDialogUtils.showMyDialog(context); + + DoctorsListService service = new DoctorsListService(); + + // service.sendCheckinNfcRequest(widget!.patientShareResponse!.appointmentNo!, nfcId, widget.patientShareResponse!.projectID!, checkInBy, widget.patientShareResponse!.clinicID!, context).then((res) { + // print(res); + // + // GifLoaderDialogUtils.hideDialog(context); + // _showMyDialog(res["SuccessMsg"], this.context); + // }).catchError((err) { + // GifLoaderDialogUtils.hideDialog(context); + // print(err); + // _showMyDialog(err, this.context); + // }); + } + + Future _showMyDialog(String message, BuildContext context) async { + return showDialog( + context: context, + barrierDismissible: true, // user must tap button! + builder: (BuildContext context) { + return AlertDialog( + title: const Text('Alert'), + content: SingleChildScrollView( + child: ListBody( + children: [ + Text(message), + ], + ), + ), + actions: [ + TextButton( + child: const Text('OK'), + onPressed: () { + Navigator.of(context).pop(); + Navigator.pushAndRemoveUntil(context, MaterialPageRoute(builder: (context) => LandingPage()), (Route r) => false); + }, + ), + ], + ); + }, + ); + } +} diff --git a/lib/pages/ErService/EROnlineCheckIn/EROnlineCheckInPaymentDetails.dart b/lib/pages/ErService/EROnlineCheckIn/EROnlineCheckInPaymentDetails.dart new file mode 100644 index 00000000..560d6d9b --- /dev/null +++ b/lib/pages/ErService/EROnlineCheckIn/EROnlineCheckInPaymentDetails.dart @@ -0,0 +1,663 @@ +import 'dart:developer'; + +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/enum/PayfortEnums.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; +import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; +import 'package:diplomaticquarterapp/models/Clinics/EROnlineCheckInPaymentDetailsResponse.dart'; +import 'package:diplomaticquarterapp/models/LiveCare/ApplePayInsertRequest.dart'; +import 'package:diplomaticquarterapp/pages/ToDoList/payment_method_select.dart'; +import 'package:diplomaticquarterapp/pages/insurance/insurance_update_screen.dart'; +import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; +import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; +import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; +import 'package:diplomaticquarterapp/services/livecare_services/livecare_provider.dart'; +import 'package:diplomaticquarterapp/services/payfort_services/payfort_project_details_resp_model.dart'; +import 'package:diplomaticquarterapp/services/payfort_services/payfort_view_model.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:diplomaticquarterapp/widgets/dragable_sheet.dart'; +import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:provider/provider.dart'; + +class EROnlineCheckInPaymentDetails extends StatefulWidget { + int projectID = 0; + bool isERBookAppointment = false; + String projectName = ""; + + EROnlineCheckInPaymentDetails({required this.projectID, required this.isERBookAppointment, required this.projectName}); + + @override + State createState() => _EROnlineCheckInPaymentDetailsState(); +} + +class _EROnlineCheckInPaymentDetailsState extends State with SingleTickerProviderStateMixin { + late ProjectViewModel projectViewModel; + EROnlineCheckInPaymentDetailsResponse? erOnlineCheckInPaymentDetailsResponse; + String? selectedPaymentMethod; + String? selectedInstallmentPlan; + String transID = ""; + late MyInAppBrowser browser; + + @override + void initState() { + WidgetsBinding.instance.addPostFrameCallback((_) { + getEROnlineCheckInPaymentDetails(); + }); + super.initState(); + } + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + return AppScaffold( + isShowAppBar: true, + appBarTitle: TranslationBase.of(context).emergency + " ${TranslationBase.of(context).checkinOptions}", + isShowDecPage: false, + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: Color(0xffF8F8F8), + body: Padding( + padding: EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: double.infinity, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10), bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10)), + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.1), + spreadRadius: 5, + blurRadius: 7, + offset: Offset(0, 3), // changes position of shadow + ), + ], + ), + child: Padding( + padding: EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).patientInfo, + style: TextStyle( + fontSize: 18, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12), + Row( + children: [ + Text( + TranslationBase.of(context).patientName + ":", + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 12, + letterSpacing: -0.6, + color: CustomColors.grey, + ), + ), + mWidth(3), + Text( + projectViewModel.user.firstName! + " " + projectViewModel.user.lastName!, + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 14, + letterSpacing: -0.48, + ), + ), + ], + ), + Row( + children: [ + Text( + TranslationBase.of(context).mrn + ":", + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 12, + letterSpacing: -0.6, + color: CustomColors.grey, + ), + ), + mWidth(3), + Text( + projectViewModel.user.patientID.toString(), + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 14, + letterSpacing: -0.48, + ), + ), + ], + ), + ], + ), + ), + ), + mHeight(24), + Container( + width: double.infinity, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10), bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10)), + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.1), + spreadRadius: 5, + blurRadius: 7, + offset: Offset(0, 3), // changes position of shadow + ), + ], + ), + child: Padding( + padding: EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "ER Visit Details", + style: TextStyle( + fontSize: 18, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12), + Row( + children: [ + Text( + TranslationBase.of(context).hospital + ":", + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 12, + letterSpacing: -0.6, + color: CustomColors.grey, + ), + ), + mWidth(3), + Text( + widget.projectName, + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 14, + letterSpacing: -0.48, + ), + ), + ], + ), + Row( + children: [ + Text( + TranslationBase.of(context).clinicName + ":", + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 12, + letterSpacing: -0.6, + color: CustomColors.grey, + ), + ), + mWidth(3), + Text( + "ER Clinic", + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 14, + letterSpacing: -0.48, + ), + ), + ], + ), + Row( + children: [ + Text( + "Time Check-In" + ":", + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 12, + letterSpacing: -0.6, + color: CustomColors.grey, + ), + ), + mWidth(3), + Text( + DateUtil.getMonthDayYearDateFormatted(DateTime.now()), + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 14, + letterSpacing: -0.48, + ), + ), + ], + ), + ], + ), + ), + ) + ], + ), + ), + bottomSheet: erOnlineCheckInPaymentDetailsResponse != null + ? Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10), bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10)), + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.5), + spreadRadius: 5, + blurRadius: 7, + offset: Offset(0, 3), // changes position of shadow + ), + ], + ), + padding: EdgeInsets.only(left: 21, right: 21, top: 15, bottom: 15), + width: double.infinity, + // color: Colors.white, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox(height: 12), + Text( + TranslationBase.of(context).YouCanPayByTheFollowingOptions, + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + SizedBox( + width: MediaQuery.of(context).size.width * 0.75, + child: getPaymentMethods(), + ), + + _amountView(TranslationBase.of(context).patientShareTotalToDo, erOnlineCheckInPaymentDetailsResponse!.patientShareWithTax.toString(), isBold: true, isTotal: true), + SizedBox(height: 12), + Column(children: [ + DefaultButton( + TranslationBase.of(context).payNow.toUpperCase(), + () { + makePayment(); + }, + color: CustomColors.green, + disabledColor: CustomColors.grey2, + ), + erOnlineCheckInPaymentDetailsResponse!.isCash == true + ? Column( + children: [ + mHeight(10.0), + Text( + TranslationBase.of(context).cashAmountUpdateInsurance, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2E303A), + ), + ), + mHeight(5.0), + DefaultButton( + TranslationBase.of(context).updateInsuranceText, + () { + Navigator.pop(context, null); + Navigator.pushAndRemoveUntil( + context, + MaterialPageRoute(builder: (context) => LandingPage()), + (Route route) => false, + ); + Navigator.push(context, FadePage(page: InsuranceUpdate())); + }, + color: Color(0xffEAA118), + textColor: Colors.white, + ), + ], + ) : SizedBox() + ], + )]), + ) + : Container(), + ); + } + + makePayment() { + showDraggableDialog( + context, + PaymentMethod( + onSelectedMethod: (String method, [String? selectedInstallmentPlan]) { + selectedPaymentMethod = method; + this.selectedInstallmentPlan = selectedInstallmentPlan; + if (selectedPaymentMethod == "ApplePay") { + if (projectViewModel.havePrivilege(103)) { + startApplePay(); + } else { + AppoitmentAllHistoryResultList appo = new AppoitmentAllHistoryResultList(); + appo.projectID = widget.projectID; + openPayment(selectedPaymentMethod!, projectViewModel.user, erOnlineCheckInPaymentDetailsResponse!.patientShareWithTax!, AppoitmentAllHistoryResultList()); + } + } else { + openPayment(selectedPaymentMethod!, projectViewModel.user, erOnlineCheckInPaymentDetailsResponse!.patientShareWithTax!, AppoitmentAllHistoryResultList()); + } + }, + patientShare: erOnlineCheckInPaymentDetailsResponse!.patientShareWithTax, + isFromAdvancePayment: false, + ), + ); + } + + openPayment(String paymentMethod, AuthenticatedUser authenticatedUser, num amount, AppoitmentAllHistoryResultList appo) { + transID = Utils.getAdvancePaymentTransID(widget.projectID, projectViewModel.user.patientID!); + + browser = new MyInAppBrowser(onExitCallback: onBrowserExit, appo: appo, onLoadStartCallback: onBrowserLoadStart); + + browser.openPaymentBrowser(amount, "ER Online Check-In Payment", transID, widget.projectID.toString(), authenticatedUser.emailAddress!, paymentMethod, authenticatedUser.patientType, + authenticatedUser.firstName!, authenticatedUser.patientID, authenticatedUser, browser, false, "3", "", context); + } + + onBrowserLoadStart(String url) { + print("onBrowserLoadStart"); + print(url); + + MyInAppBrowser.successURLS.forEach((element) { + if (url.contains(element)) { + if (browser.isOpened()) browser.close(); + MyInAppBrowser.isPaymentDone = true; + return; + } + }); + + MyInAppBrowser.errorURLS.forEach((element) { + if (url.contains(element)) { + if (browser.isOpened()) browser.close(); + MyInAppBrowser.isPaymentDone = false; + return; + } + }); + } + + onBrowserExit(AppoitmentAllHistoryResultList appo, bool isPaymentMade) { + print("onBrowserExit Called!!!!"); + checkPaymentStatus(appo); + } + + void startApplePay() async { + transID = Utils.getAdvancePaymentTransID(widget.projectID, projectViewModel.user.patientID!); + + print("TransactionID: $transID"); + GifLoaderDialogUtils.showMyDialog(context); + + LiveCareService service = new LiveCareService(); + ApplePayInsertRequest applePayInsertRequest = new ApplePayInsertRequest(); + + PayfortProjectDetailsRespModel? payfortProjectDetailsRespModel; + await context.read().getProjectDetailsForPayfort(projectId: widget.projectID, serviceId: ServiceTypeEnum.appointmentPayment.getIdFromServiceEnum()).then((value) { + payfortProjectDetailsRespModel = value!; + }); + + applePayInsertRequest.clientRequestID = transID; + applePayInsertRequest.clinicID = 0; + applePayInsertRequest.currency = projectViewModel.user.outSA == 1 ? "AED" : "SAR"; + // applePayInsertRequest.customerEmail = projectViewModel.authenticatedUserObject.user.emailAddress; + applePayInsertRequest.customerEmail = "CustID_${projectViewModel.user.patientID}@HMG.com"; + applePayInsertRequest.customerID = projectViewModel.user.patientID; + applePayInsertRequest.customerName = projectViewModel.user.firstName! + " " + projectViewModel.user.lastName!; + applePayInsertRequest.deviceToken = await AppSharedPreferences().getString(PUSH_TOKEN); + applePayInsertRequest.voipToken = await AppSharedPreferences().getString(ONESIGNAL_APNS_TOKEN); + applePayInsertRequest.doctorID = 0; + applePayInsertRequest.projectID = widget.projectID.toString(); + applePayInsertRequest.serviceID = ServiceTypeEnum.advancePayment.getIdFromServiceEnum().toString(); + applePayInsertRequest.channelID = 3; + applePayInsertRequest.patientID = projectViewModel.user.patientID; + applePayInsertRequest.patientTypeID = projectViewModel.user.patientType; + applePayInsertRequest.patientOutSA = projectViewModel.user.outSA; + applePayInsertRequest.appointmentDate = null; + applePayInsertRequest.appointmentNo = 0; + applePayInsertRequest.orderDescription = "ER Online Check-In Payment"; + applePayInsertRequest.liveServiceID = "0"; + applePayInsertRequest.latitude = "0.0"; + applePayInsertRequest.longitude = "0.0"; + applePayInsertRequest.amount = erOnlineCheckInPaymentDetailsResponse!.patientShareWithTax.toString(); + applePayInsertRequest.isSchedule = "0"; + applePayInsertRequest.language = projectViewModel.isArabic ? 'ar' : 'en'; + applePayInsertRequest.languageID = projectViewModel.isArabic ? 1 : 2; + applePayInsertRequest.userName = projectViewModel.user.patientID; + applePayInsertRequest.responseContinueURL = "http://hmg.com/Documents/success.html"; + applePayInsertRequest.backClickUrl = "http://hmg.com/Documents/success.html"; + applePayInsertRequest.paymentOption = "ApplePay"; + + applePayInsertRequest.isMobSDK = true; + applePayInsertRequest.merchantReference = transID; + applePayInsertRequest.merchantIdentifier = payfortProjectDetailsRespModel!.merchantIdentifier; + applePayInsertRequest.commandType = "PURCHASE"; + applePayInsertRequest.signature = payfortProjectDetailsRespModel!.signature; + applePayInsertRequest.accessCode = payfortProjectDetailsRespModel!.accessCode; + applePayInsertRequest.shaRequestPhrase = payfortProjectDetailsRespModel!.shaRequest; + applePayInsertRequest.shaResponsePhrase = payfortProjectDetailsRespModel!.shaResponse; + applePayInsertRequest.returnURL = ""; + + service.applePayInsertRequest(applePayInsertRequest, context).then((res) async { + if (res["MessageStatus"] == 1) { + await context.read().initiateApplePayWithPayfort( + customerName: projectViewModel.user.firstName! + " " + projectViewModel.user.lastName!, + // customerEmail: projectViewModel.authenticatedUserObject.user.emailAddress, + customerEmail: "CustID_${projectViewModel.user.patientID}@HMG.com", + orderDescription: "ER Online Check-In Payment", + orderAmount: erOnlineCheckInPaymentDetailsResponse!.patientShareWithTax, + merchantReference: transID, + payfortProjectDetailsRespModel: payfortProjectDetailsRespModel, + currency: projectViewModel.user.outSA == 1 ? "AED" : "SAR", + onFailed: (failureResult) async { + GifLoaderDialogUtils.hideDialog(context); + log("failureResult: ${failureResult.message.toString()}"); + AppToast.showErrorToast(message: failureResult.message.toString()); + }, + onSuccess: (successResult) async { + log("Payfort: ${successResult.responseMessage}"); + await context.read().addPayfortApplePayResponse(projectViewModel.user.patientID!, result: successResult); + GifLoaderDialogUtils.hideDialog(context); + checkPaymentStatus(AppoitmentAllHistoryResultList()); + }, + projectId: widget.projectID, + serviceTypeEnum: ServiceTypeEnum.appointmentPayment, + ); + } else { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: "An error occurred while processing your request"); + } + }).catchError((err) { + print(err); + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + }); + } + + checkPaymentStatus(AppoitmentAllHistoryResultList appo) { + GifLoaderDialogUtils.showMyDialog(context); + DoctorsListService service = new DoctorsListService(); + service.checkPaymentStatus(transID, false, context).then((res) { + String paymentInfo = res['Response_Message']; + if (paymentInfo == 'Success') { + GifLoaderDialogUtils.hideDialog(context); + if (widget.isERBookAppointment) { + // createAdvancePayment(res, appo); + ER_createAdvancePayment(res, appo); + } else { + autoGenerateInvoiceER(res); + } + } else { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: res['Response_Message']); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + + ER_createAdvancePayment(payment_res, AppoitmentAllHistoryResultList appo) { + GifLoaderDialogUtils.showMyDialog(context); + DoctorsListService service = new DoctorsListService(); + String paymentReference = payment_res['Fort_id'].toString(); + service.ER_createAdvancePayment(appo, widget.projectID.toString(), payment_res['Amount'], payment_res['Fort_id'], payment_res['PaymentMethod'], context).then((res) { + GifLoaderDialogUtils.hideDialog(context); + addAdvancedNumberRequest( + // Utils.isVidaPlusProject(projectViewModel, widget.projectID) + // ? res['OnlineCheckInAppointments'][0]['AdvanceNumber_VP'].toString() + // : res['OnlineCheckInAppointments'][0]['AdvanceNumber'].toString(), + res['ER_AdvancePaymentResponse']['AdvanceNumber'].toString(), + paymentReference, + 0, + appo, + payment_res); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + + createAdvancePayment(paymentRes, AppoitmentAllHistoryResultList appo) { + GifLoaderDialogUtils.showMyDialog(context); + DoctorsListService service = new DoctorsListService(); + String paymentReference = paymentRes['Fort_id'].toString(); + service.HIS_createAdvancePayment(appo, widget.projectID.toString(), paymentRes['Amount'], paymentRes['Fort_id'], paymentRes['PaymentMethod'], projectViewModel.user.patientType, + projectViewModel.user.firstName! + " " + projectViewModel.user.lastName!, projectViewModel.user.patientID, context) + .then((res) { + addAdvancedNumberRequest( + Utils.isVidaPlusProject(projectViewModel, widget.projectID) + ? res['OnlineCheckInAppointments'][0]['AdvanceNumber_VP'].toString() + : res['OnlineCheckInAppointments'][0]['AdvanceNumber'].toString(), + paymentReference, + 0, + appo, + paymentRes); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + + addAdvancedNumberRequest(String advanceNumber, String paymentReference, dynamic appointmentID, AppoitmentAllHistoryResultList appo, paymentRes) { + GifLoaderDialogUtils.showMyDialog(context); + DoctorsListService service = new DoctorsListService(); + service.addAdvancedNumberRequest(advanceNumber, paymentReference, appointmentID, context).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (widget.isERBookAppointment) { + AppToast.showSuccessToast(message: "Your appointment has been booked successfully. Please perform Check-In once you arrive at the hospital."); + // Navigator.pop(context); + // Navigator.pop(context); + // Navigator.pop(context); + Navigator.pushAndRemoveUntil(context, MaterialPageRoute(builder: (context) => LandingPage()), (Route r) => false); + } else { + autoGenerateInvoiceER(paymentRes); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err.toString()); + print(err); + }); + } + + autoGenerateInvoiceER(res) { + GifLoaderDialogUtils.showMyDialog(context); + DoctorsListService service = new DoctorsListService(); + service.autoGenerateInvoiceERClinic(widget.projectID, 4, res['Fort_id'], res['Amount'], res['PaymentMethod'], res['CardNumber'], res['Merchant_Reference'], res['RRN'], false).then((res) { + GifLoaderDialogUtils.hideDialog(context); + _showMyDialog(TranslationBase.of(context).ERCheckInSuccess, context); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + + Future _showMyDialog(String message, BuildContext context) async { + return showDialog( + context: context, + barrierDismissible: true, // user must tap button! + builder: (BuildContext context) { + return AlertDialog( + title: const Text('Alert'), + content: SingleChildScrollView( + child: ListBody( + children: [ + Text(message), + ], + ), + ), + actions: [ + TextButton( + child: const Text('OK'), + onPressed: () { + Navigator.of(context).pop(); + Navigator.pushAndRemoveUntil(context, MaterialPageRoute(builder: (context) => LandingPage()), (Route r) => false); + }, + ), + ], + ); + }, + ); + } + + getEROnlineCheckInPaymentDetails() { + GifLoaderDialogUtils.showMyDialog(context); + ClinicListService ancillaryOrdersService = new ClinicListService(); + ancillaryOrdersService.getEROnlineCheckInPaymentDetails(widget.projectID, 10).then((response) { + erOnlineCheckInPaymentDetailsResponse = EROnlineCheckInPaymentDetailsResponse.fromJson(response["ResponsePatientShare"]); + GifLoaderDialogUtils.hideDialog(context); + setState(() {}); + }).catchError((err) { + AppToast.showErrorToast(message: err.toString()); + GifLoaderDialogUtils.hideDialog(context); + }); + } + + _amountView(String title, String value, {bool isBold = false, bool isTotal = false}) { + return Padding( + padding: const EdgeInsets.only(top: 10, bottom: 10), + child: Row(children: [ + Expanded( + child: _getNormalText(title), + ), + Expanded( + child: Row( + children: [ + projectViewModel.isArabic ? Container() : SvgPicture.asset("assets/images/new/Saudi_Riyal_Symbol.svg", width: 16, height: 16), + mWidth(6), + _getNormalText(value, isBold: isBold, isTotal: isTotal), + mWidth(6), + projectViewModel.isArabic ? SvgPicture.asset("assets/images/new/Saudi_Riyal_Symbol.svg", width: 16, height: 16) : Container(), + ], + ), + ), + ]), + ); + } + + _getNormalText(text, {bool isBold = false, bool isTotal = false}) { + return Text( + text, + style: TextStyle( + fontSize: isBold + ? isTotal + ? 16 + : 12 + : 11, + letterSpacing: -0.5, + color: isBold ? Color(0xff2E303A) : Color(0xff575757), + fontWeight: isTotal ? FontWeight.bold : FontWeight.w600, + ), + ); + } +} diff --git a/lib/pages/ErService/EdOnline/ConfirmExitPageDialog.dart b/lib/pages/ErService/EdOnline/ConfirmExitPageDialog.dart deleted file mode 100644 index 1144e587..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'; - -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 7395b901..47d31a21 100644 --- a/lib/pages/ErService/EdOnline/DdServicesPage.dart +++ b/lib/pages/ErService/EdOnline/DdServicesPage.dart @@ -1,17 +1,15 @@ import 'package:diplomaticquarterapp/core/model/er/TriageInformationRequest.dart'; import 'package:diplomaticquarterapp/core/model/er/TriageQuestionsModel.dart'; -import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.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'; - import 'EdOnlineAgreementPage.dart'; import 'EdOnlineNotesPage.dart'; import 'EdOnlineQuestionsPage.dart'; import 'EdOnlineSelectedHospitalPage.dart'; import 'EdPaymentInformationPage.dart'; -import 'ConfirmExitPageDialog.dart'; class DdServicesPage extends StatefulWidget { @override @@ -19,61 +17,35 @@ class DdServicesPage extends StatefulWidget { } class _DdServicesPageState extends State { - PageController pageController; + late PageController pageController; bool isAgree = false; TriageInformationRequest triageInformationRequest = new TriageInformationRequest(); - List selectedQuestions = List(); + List selectedQuestions =[]; @override void initState() { super.initState(); pageController = new PageController(); - } _changePageViewIndex(int tab) { setState(() { pageController.jumpToPage(tab); - pageController.animateToPage(tab, - duration: Duration(milliseconds: 800), curve: Curves.easeOutQuart); + pageController.animateToPage(tab, duration: Duration(milliseconds: 800), curve: Curves.easeOutQuart); }); } @override Widget build(BuildContext context) { ProjectViewModel projectViewModel = Provider.of(context); - return Scaffold( - appBar: AppBar( - elevation: 0, - textTheme: TextTheme( - headline6: TextStyle( - color: Theme.of(context).textTheme.headline1.color, - fontWeight: FontWeight.bold), - ), - title: Text( - 'ED Online', - style: TextStyle( - fontWeight: FontWeight.bold, - color: Theme.of(context).textTheme.headline1.color, - fontFamily: projectViewModel.isArabic ? 'Cairo' : 'WorkSans'), - // bold: true, - // color: Colors.white, - ), - leading: Builder( - builder: (BuildContext context) { - return IconButton( - icon: Icon(Icons.arrow_back), - color: Theme.of(context).textTheme.headline1.color, - onPressed: () { - showConfirmMessage(context); - }, - ); - }, - ), - centerTitle: true, - ), + return AppScaffold( + appBarTitle: 'ED Online', + showNewAppBarTitle: true, + isShowDecPage: true, + isShowAppBar: true, + showNewAppBar: true, body: PageView( physics: NeverScrollableScrollPhysics(), controller: pageController, @@ -90,31 +62,18 @@ class _DdServicesPageState extends State { EdOnlineQuestionsPage( changePageViewIndex: _changePageViewIndex, selectedQuestions: selectedQuestions, + selectedHospital: triageInformationRequest.selectedHospital, ), EdOnlineNotesPage( changePageViewIndex: _changePageViewIndex, selectedQuestions: selectedQuestions, triageInformationRequest: triageInformationRequest, ), - EdPaymentInformationPage(selectedHospital: triageInformationRequest.selectedHospital,) + EdPaymentInformationPage( + selectedHospital: triageInformationRequest.selectedHospital, + ) ], ), ); } - - void showConfirmMessage( - BuildContext context, - ) { - showDialog( - context: context, - child: ConfirmExitPageDialog( - onTapYes: () { - Navigator.pop(context); - }, - onTapNo: () { - Navigator.pop(context); - }, - ), - ); - } } diff --git a/lib/pages/ErService/EdOnline/EdOnlineAgreementPage.dart b/lib/pages/ErService/EdOnline/EdOnlineAgreementPage.dart index 950dc2e0..d0e01f57 100644 --- a/lib/pages/ErService/EdOnline/EdOnlineAgreementPage.dart +++ b/lib/pages/ErService/EdOnline/EdOnlineAgreementPage.dart @@ -7,10 +7,10 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; class EdOnlineAgreementPage extends StatefulWidget { - final HospitalsModel selectedHospital; - final Function changePageViewIndex; + final HospitalsModel? selectedHospital; + final Function? changePageViewIndex; bool isAgree; - EdOnlineAgreementPage({Key key, this.selectedHospital, this.changePageViewIndex,this.isAgree}) : super(key: key); + EdOnlineAgreementPage({Key? key, this.selectedHospital, this.changePageViewIndex,required this.isAgree}) : super(key: key); @override _EdOnlineAgreementPageState createState() => _EdOnlineAgreementPageState(); @@ -38,7 +38,7 @@ class _EdOnlineAgreementPageState extends State { Checkbox( value: widget.isAgree, activeColor: Colors.red[800], - onChanged: (bool newValue) { + onChanged: (bool? newValue) { setState(() { widget.isAgree = !widget.isAgree; }); @@ -72,7 +72,7 @@ class _EdOnlineAgreementPageState extends State { textColor: Colors.white, color: Theme.of(context).primaryColor, label: TranslationBase.of(context).back.toUpperCase(), - onTap: () => widget.changePageViewIndex(0), + onTap: () => widget.changePageViewIndex!(0), ), ), ), @@ -85,7 +85,7 @@ class _EdOnlineAgreementPageState extends State { color: Theme.of(context).primaryColor, label: TranslationBase.of(context).next.toUpperCase(), disabled: !widget.isAgree, - onTap: () => widget.changePageViewIndex(2), + onTap: () => widget.changePageViewIndex!(2), ), ), ), diff --git a/lib/pages/ErService/EdOnline/EdOnlineNotesPage.dart b/lib/pages/ErService/EdOnline/EdOnlineNotesPage.dart index 45df4041..2ed77c2e 100644 --- a/lib/pages/ErService/EdOnline/EdOnlineNotesPage.dart +++ b/lib/pages/ErService/EdOnline/EdOnlineNotesPage.dart @@ -1,7 +1,6 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/er/TriageInformationRequest.dart'; import 'package:diplomaticquarterapp/core/model/er/TriageQuestionsModel.dart'; -import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/er/EdOnlineViewModel.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/Blood/new_text_Field.dart'; @@ -14,26 +13,24 @@ 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_datetime_picker/flutter_datetime_picker.dart'; +import 'package:flutter_datetime_picker_plus/flutter_datetime_picker_plus.dart'; import 'package:provider/provider.dart'; class EdOnlineNotesPage extends StatefulWidget { - final List selectedQuestions; - final Function changePageViewIndex; - TriageInformationRequest triageInformationRequest; - EdOnlineNotesPage( - {Key key, this.selectedQuestions, this.changePageViewIndex,this.triageInformationRequest}) - ; + final List? selectedQuestions; + final Function? changePageViewIndex; + TriageInformationRequest? triageInformationRequest; + + EdOnlineNotesPage({Key? key, this.selectedQuestions, this.changePageViewIndex, this.triageInformationRequest}); @override _EdOnlineNotesPageState createState() => _EdOnlineNotesPageState(); } class _EdOnlineNotesPageState extends State { - TextEditingController _chiefComplaintsTextController = - TextEditingController(); + TextEditingController _chiefComplaintsTextController = TextEditingController(); TextEditingController _noteTextController = TextEditingController(); - DateTime selectedTime; + late DateTime selectedTime; final _formKey = GlobalKey(); @override @@ -84,13 +81,11 @@ class _EdOnlineNotesPageState extends State { padding: EdgeInsets.all(12), width: double.infinity, // height: 65, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - color: Colors.white), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), color: Colors.white), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Texts(selectedTime == null ?TranslationBase.of(context).errorExpectedArrivalTime:TranslationBase.of(context).expectedArrivalTime), + Texts(selectedTime == null ? TranslationBase.of(context).errorExpectedArrivalTime : TranslationBase.of(context).expectedArrivalTime), Texts(getDate(context)), ], ), @@ -117,42 +112,44 @@ class _EdOnlineNotesPageState extends State { children: [ Expanded( child: Container( - margin: EdgeInsets.only(left: 5,right: 5), + margin: EdgeInsets.only(left: 5, right: 5), child: SecondaryButton( textColor: Colors.white, color: Theme.of(context).primaryColor, label: TranslationBase.of(context).back.toUpperCase(), - onTap: () => widget.changePageViewIndex(2), + onTap: () => widget.changePageViewIndex!(2), ), ), ), - SizedBox(width: 10,), + SizedBox( + width: 10, + ), Expanded( child: Container( - margin: EdgeInsets.only(left: 5,right: 5), + margin: EdgeInsets.only(left: 5, right: 5), child: SecondaryButton( textColor: Colors.white, color: Theme.of(context).primaryColor, label: TranslationBase.of(context).save.toUpperCase(), disabled: selectedTime == null, onTap: () async { - if (_formKey.currentState.validate()) { + if (_formKey.currentState!.validate()) { GifLoaderDialogUtils.showMyDialog(context); - model.saveQuestionsInformation( - chiefComplaint: - _chiefComplaintsTextController.text.toString(), - notes: _noteTextController.text.toString(), - selectedQuestions: widget.selectedQuestions, - projectId: widget.triageInformationRequest.projectID,selectedTime: selectedTime).then((value) { + model + .saveQuestionsInformation( + chiefComplaint: _chiefComplaintsTextController.text.toString(), + notes: _noteTextController.text.toString(), + selectedQuestions: widget.selectedQuestions, + projectId: widget.triageInformationRequest!.projectID!, + selectedTime: selectedTime) + .then((value) { GifLoaderDialogUtils.hideDialog(context); - if(model.state == ViewState.ErrorLocal) + if (model.state == ViewState.ErrorLocal) AppToast.showErrorToast(message: model.error); - else - { - widget.changePageViewIndex(4); - } - - }).catchError((onError){ + else { + widget.changePageViewIndex!(4); + } + }).catchError((onError) { GifLoaderDialogUtils.hideDialog(context); AppToast.showErrorToast(message: onError.toString()); }); diff --git a/lib/pages/ErService/EdOnline/EdOnlineQuestionsPage.dart b/lib/pages/ErService/EdOnline/EdOnlineQuestionsPage.dart index e3eb1c4c..e5d819b1 100644 --- a/lib/pages/ErService/EdOnline/EdOnlineQuestionsPage.dart +++ b/lib/pages/ErService/EdOnline/EdOnlineQuestionsPage.dart @@ -1,30 +1,31 @@ +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/er/TriageQuestionsModel.dart'; import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/er/EdOnlineViewModel.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/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/custom_text_button.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; // ignore: must_be_immutable class EdOnlineQuestionsPage extends StatefulWidget { - final HospitalsModel selectedHospital; - final Function changePageViewIndex; - List selectedQuestions; - - EdOnlineQuestionsPage({Key key, this.selectedHospital,this.selectedQuestions, this.changePageViewIndex}); + final HospitalsModel? selectedHospital; + final Function? changePageViewIndex; + List? selectedQuestions; + EdOnlineQuestionsPage({Key? key, this.selectedHospital, this.selectedQuestions, this.changePageViewIndex}); @override _EdOnlineQuestionsPageState createState() => _EdOnlineQuestionsPageState(); } class _EdOnlineQuestionsPageState extends State { - - @override Widget build(BuildContext context) { return BaseView( @@ -37,90 +38,158 @@ class _EdOnlineQuestionsPageState extends State { children: [ ...List.generate( model.triageQuestionsModelList.length, - (index) => - InkWell( - onTap: (){ - setState(() { - if (widget.selectedQuestions - .contains(model.triageQuestionsModelList[index])) { - widget.selectedQuestions - .remove(model.triageQuestionsModelList[index]); - } else { - widget.selectedQuestions - .add(model.triageQuestionsModelList[index]); - } - }); - }, - child: Row( - children: [ - Checkbox( - value: widget.selectedQuestions.contains(model.triageQuestionsModelList[index]), - activeColor: Colors.red[800], - onChanged: (bool newValue) { - setState(() { - if (widget.selectedQuestions - .contains(model.triageQuestionsModelList[index])) { - widget.selectedQuestions - .remove(model.triageQuestionsModelList[index]); - } else { - widget.selectedQuestions - .add(model.triageQuestionsModelList[index]); - } - }); - }), - Expanded( - child: Padding( - padding: const EdgeInsets.all(20.0), - child: Texts( - model.triageQuestionsModelList[index].question, - fontSize: 15, - ), - ), + (index) => InkWell( + onTap: () { + setState(() { + if (widget.selectedQuestions!.contains(model.triageQuestionsModelList[index])) { + widget.selectedQuestions!.remove(model.triageQuestionsModelList[index]); + } else { + widget.selectedQuestions!.add(model.triageQuestionsModelList[index]); + } + }); + }, + child: Container( + margin: EdgeInsets.only(bottom: 10.0), + child: Row( + children: [ + Checkbox( + value: widget.selectedQuestions!.contains(model.triageQuestionsModelList[index]), + activeColor: Color(0xffD02127), + tristate: false, + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + onChanged: (bool? newValue) { + setState(() { + if (widget.selectedQuestions!.contains(model.triageQuestionsModelList[index])) { + widget.selectedQuestions!.remove(model.triageQuestionsModelList[index]); + } else { + widget.selectedQuestions!.add(model.triageQuestionsModelList[index]); + } + }); + }), + SizedBox(width: 6), + Expanded( + child: Text( + model.triageQuestionsModelList[index].question!, + overflow: TextOverflow.clip, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.64), ), - ], - ), + ), + ], ), - + ), + ), ), - SizedBox(height: 80,) + SizedBox( + height: 120, + ) ], ), ), - bottomSheet: Padding( - padding: const EdgeInsets.all(8.0), + bottomSheet: Container( + color: CustomColors.appBackgroudGreyColor, child: Container( - height: 56, + color: CustomColors.appBackgroudGreyColor, + margin: EdgeInsets.all(14), + height: 45.0, child: Row( - children: [ + mainAxisAlignment: MainAxisAlignment.end, + children: [ Expanded( - child: Container( - margin: EdgeInsets.only(left: 5,right: 5), - child: SecondaryButton( - textColor: Colors.white, - color: Theme.of(context).primaryColor, - label: TranslationBase.of(context).back.toUpperCase(), - onTap: () => widget.changePageViewIndex(1), + flex: 1, + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + height: 45.0, + child: CustomTextButton( + backgroundColor: Color(0xffc5272d), + disabledForegroundColor: Color(0xFFbcc2c4).withOpacity(0.38), + disabledBackgroundColor: Color(0xFFbcc2c4).withOpacity(0.12), + elevation: 0, + onPressed: () { + widget.changePageViewIndex!(0); + }, + child: Text(TranslationBase.of(context).back, style: TextStyle(fontSize: 16.0, color: Colors.white)), ), ), ), - SizedBox(width: 10,), + mWidth(7), Expanded( - child: Container( - margin: EdgeInsets.only(left: 5,right: 5), - child: SecondaryButton( - textColor: Colors.white, - color: Theme.of(context).primaryColor, - label: TranslationBase.of(context).next.toUpperCase(), - disabled: widget.selectedQuestions.isEmpty, - onTap: () => widget.changePageViewIndex(3), + flex: 1, + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + height: 45.0, + child: CustomTextButton( + backgroundColor: CustomColors.green, + disabledForegroundColor: Color(0xFFbcc2c4).withOpacity(0.38), + disabledBackgroundColor: Color(0xFFbcc2c4).withOpacity(0.12), + elevation: 0, + onPressed: widget.selectedQuestions!.isEmpty + ? null + : () { + GifLoaderDialogUtils.showMyDialog(context); + model + .saveQuestionsInformation( + chiefComplaint: "", notes: "", selectedQuestions: widget.selectedQuestions, projectId: widget.selectedHospital!.iD, selectedTime: DateTime.now()) + .then((value) { + GifLoaderDialogUtils.hideDialog(context); + if (model.state == ViewState.ErrorLocal) + AppToast.showErrorToast(message: model.error); + else { + widget.changePageViewIndex!(4); + } + }).catchError((onError) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: onError.toString()); + }); + // widget.changePageViewIndex(4); + }, + child: Text(TranslationBase.of(context).next, style: TextStyle(fontSize: 16.0, color: Colors.white)), ), ), ), - ], ), ), ), + // Padding( + // padding: const EdgeInsets.all(8.0), + // child: Container( + // height: 56, + // child: Row( + // children: [ + // Expanded( + // child: Container( + // margin: EdgeInsets.only(left: 5, right: 5), + // child: SecondaryButton( + // textColor: Colors.white, + // color: Theme.of(context).primaryColor, + // label: TranslationBase.of(context).back.toUpperCase(), + // onTap: () => widget.changePageViewIndex(1), + // ), + // ), + // ), + // SizedBox( + // width: 10, + // ), + // Expanded( + // child: Container( + // margin: EdgeInsets.only(left: 5, right: 5), + // child: SecondaryButton( + // textColor: Colors.white, + // color: Theme.of(context).primaryColor, + // label: TranslationBase.of(context).next.toUpperCase(), + // disabled: widget.selectedQuestions.isEmpty, + // onTap: () => widget.changePageViewIndex(3), + // ), + // ), + // ), + // ], + // ), + // ), + // ), ), ); } diff --git a/lib/pages/ErService/EdOnline/EdOnlineSelectedHospitalPage.dart b/lib/pages/ErService/EdOnline/EdOnlineSelectedHospitalPage.dart index 34c41040..c41c2fc2 100644 --- a/lib/pages/ErService/EdOnline/EdOnlineSelectedHospitalPage.dart +++ b/lib/pages/ErService/EdOnline/EdOnlineSelectedHospitalPage.dart @@ -1,22 +1,26 @@ import 'package:diplomaticquarterapp/core/model/er/TriageInformationRequest.dart'; import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/er/EdOnlineViewModel.dart'; +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/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.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/cupertino.dart'; import 'package:flutter/material.dart'; - -import '../../../Constants.dart'; - +import 'package:provider/provider.dart'; +import 'package:url_launcher/url_launcher.dart'; class EdOnlineSelectedHospitalPage extends StatefulWidget { final Function changePageViewIndex; TriageInformationRequest triageInformationRequest; EdOnlineSelectedHospitalPage( - {Key key, this.changePageViewIndex,this.triageInformationRequest}) + {Key? key, + required this.changePageViewIndex, + required this.triageInformationRequest}) : super(key: key); @override @@ -26,77 +30,169 @@ class EdOnlineSelectedHospitalPage extends StatefulWidget { class _EdOnlineSelectedHospitalPageState extends State { + HospitalsModel? selectedProject; + final GlobalKey locationDropdownKey = GlobalKey(); + late ProjectViewModel projectViewModel; + int _selected = 0; + @override Widget build(BuildContext context) { + projectViewModel = Provider.of(context); return BaseView( - onModelReady: (model) => model.getHospitals(), + onModelReady: (model) => model.getHospitals(projectViewModel.isArabic ? 1 : 2), builder: (_, model, w) => AppScaffold( baseViewModel: model, body: SingleChildScrollView( physics: BouncingScrollPhysics(), child: Column( children: [ - ...List.generate( - model.hospitals.length, - (index) => Column( - crossAxisAlignment: CrossAxisAlignment.start, + Container( + margin: EdgeInsets.all(12.0), + child: Text(TranslationBase.of(context).onlineCheckInAgreement, + style: TextStyle( + fontSize: 14.0, + color: Colors.black, + letterSpacing: -0.56)), + ), + Container( + width: double.infinity, + decoration: containerRadius(Colors.white, 12), + margin: EdgeInsets.all(12.0), + padding: + EdgeInsets.only(left: 10, right: 10, top: 12, bottom: 12), + child: Row( children: [ - SizedBox( - height: 2, - ), - Row( - children: [ - Expanded( - flex: 1, - child: InkWell( - onTap: () { - setState(() { - widget.triageInformationRequest.selectedHospital = model.hospitals[index]; - widget.triageInformationRequest.projectID = model.hospitals[index].iD; - }); - }, - child: ListTile( - title: Text(model.hospitals[index].name + - ' ${model.hospitals[index].distanceInKilometers} ' + - TranslationBase.of(context).km), - leading: Radio( - value: model.hospitals[index], - groupValue: widget.triageInformationRequest.selectedHospital, - activeColor: secondaryColor, - onChanged: (value) { - setState(() { - widget.triageInformationRequest.selectedHospital = model.hospitals[index]; - widget.triageInformationRequest.projectID = model.hospitals[index].iD; - }); + Flexible( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).selectLocation, + style: TextStyle( + fontSize: 11, + letterSpacing: -0.44, + fontWeight: FontWeight.w600, + ), + ), + Container( + height: 20, + child: DropdownButtonHideUnderline( + child: DropdownButton( + onTap: () { + print("Clicked"); + }, + key: locationDropdownKey, + hint: new Text( + TranslationBase.of(context).selectHospital, + ), + value: selectedProject, + iconSize: 0, + isExpanded: true, + style: TextStyle( + fontSize: 14, + letterSpacing: -0.56, + color: Colors.black, + fontFamily: projectViewModel.isArabic + ? 'Cairo' + : 'Poppins'), + items: + model.hospitals.map((HospitalsModel item) { + return DropdownMenuItem( + value: item, + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text(item.name! + + " - " + + item.distanceInKilometers + .toString() + + " " + + TranslationBase.of(context).km_) + ], + ), + ); + }).toList(), + onChanged: (HospitalsModel? newValue) { + if (newValue != null) { + setState(() { + selectedProject = newValue; + widget.triageInformationRequest + .selectedHospital = selectedProject; + }); + } }, ), ), ), - ) - ], + ], + ), ), - SizedBox( - height: 5.0, + Icon(Icons.keyboard_arrow_down), + ], + ), + ), + 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), + InkWell( + onTap: () { + launch("https://hmg.com/en/Pages/Privacy.aspx"); + }, + child: Text( + TranslationBase.of(context).termsConditoins, + style: new TextStyle( + fontSize: 12.0, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + color: CustomColors.accentColor, + ), + ), ), ], ), - ) + ), ], ), ), bottomSheet: Container( - height: 76, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: SecondaryButton( - // textColor: Colors.white, - color: Theme.of(context).primaryColor, - label: TranslationBase.of(context).next.toUpperCase(), - disabled: widget.triageInformationRequest.selectedHospital==null, - onTap: () => widget.changePageViewIndex(1)), + color: CustomColors.appBackgroudGreyColor, + padding: EdgeInsets.all(12.0), + child: DefaultButton( + TranslationBase.of(context).next, + (widget.triageInformationRequest.selectedHospital == null || + _selected == 0) + ? null + : () { + widget.changePageViewIndex(2); + }, + color: CustomColors.green, + disabledColor: CustomColors.grey2, ), ), ), ); } + + void onRadioChanged(int? value) { + setState(() { + _selected = value!; + }); + } } diff --git a/lib/pages/ErService/EdOnline/EdPaymentInformationPage.dart b/lib/pages/ErService/EdOnline/EdPaymentInformationPage.dart index c510196b..705a6e59 100644 --- a/lib/pages/ErService/EdOnline/EdPaymentInformationPage.dart +++ b/lib/pages/ErService/EdOnline/EdPaymentInformationPage.dart @@ -1,112 +1,244 @@ +import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/er/EdOnlineViewModel.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/ToDoList/payment_method_select.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.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'; class EdPaymentInformationPage extends StatefulWidget { - final HospitalsModel selectedHospital; + final HospitalsModel? selectedHospital; + + const EdPaymentInformationPage({Key? key, this.selectedHospital}) : super(key: key); - const EdPaymentInformationPage({Key key, this.selectedHospital}) : super(key: key); @override - _EdPaymentInformationPageState createState() => - _EdPaymentInformationPageState(); + _EdPaymentInformationPageState createState() => _EdPaymentInformationPageState(); } class _EdPaymentInformationPageState extends State { + late MyInAppBrowser browser; + late ProjectViewModel projectViewModel; + String transID = ""; + @override Widget build(BuildContext context) { + projectViewModel = Provider.of(context); return BaseView( - onModelReady: (model) => model.getPatientPaymentInformation(), + onModelReady: (model) async => await model.getPatientPaymentInformation(), builder: (_, model, w) => AppScaffold( baseViewModel: model, body: SingleChildScrollView( physics: BouncingScrollPhysics(), child: Column( children: [ - Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10.0), - color: Colors.white), - margin: EdgeInsets.fromLTRB(0.0, 30.0, 0.0, 5.0), - padding: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 20.0), - child: Column( - children: [ - Container( - alignment: Alignment.center, - margin: - EdgeInsets.only(left: 0.0, right: 20.0, top: 30.0), - child: Text(TranslationBase.of(context).testFee, + model.erPatientShareModel != null ? Container( + decoration: cardRadius(12), + margin: EdgeInsets.fromLTRB(12.0, 30.0, 12.0, 5.0), + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(TranslationBase.of(context).payment, style: TextStyle( - color: Colors.black, - fontSize: 22.0, - fontWeight: FontWeight.bold)), - ), - if(model.erPatientShareModel!=null) - Table( - children: [ - TableRow(children: [ - TableCell( - child: - Texts(TranslationBase.of(context).testFee)), - TableCell( - child: Texts(model - .erPatientShareModel.patientShare - .toStringAsFixed(2))), - ]), - TableRow(children: [ - TableCell( - child: Texts( - TranslationBase.of(context).patientTaxToDo)), - TableCell( - child: Texts(model - .erPatientShareModel.patientTaxAmount - .toStringAsFixed(2))), - ]), - TableRow(children: [ - TableCell( - child: Texts(TranslationBase.of(context) - .patientShareTotalToDo)), - TableCell( - child: Texts(model - .erPatientShareModel.patientShareWithTax - .toStringAsFixed(2))), - ]), - ], - ), - ], + color: Colors.black, + fontSize: 16.0, + fontWeight: FontWeight.w600, + letterSpacing: -0.64, + )), + Container( + width: double.infinity, + padding: EdgeInsets.only(top: 10, bottom: 3), + child: Row( + children: [ + Expanded( + child: _getNormalText(TranslationBase.of(context).patientShareToDo), + ), + Expanded( + child: _getNormalText(model.erPatientShareModel!.patientShare!.toStringAsFixed(2) ?? "0", isBold: true), + ) + ], + ), + ), + mDivider(Colors.grey[200]!), + Container( + width: double.infinity, + padding: EdgeInsets.only(top: 3, bottom: 3), + child: Row( + children: [ + Expanded( + child: _getNormalText(TranslationBase.of(context).patientTaxToDo), + ), + Expanded( + child: _getNormalText(model.erPatientShareModel!.patientTaxAmount!.toStringAsFixed(2) ?? "0", isBold: true), + ) + ], + ), + ), + mDivider(Colors.grey[200]!), + Container( + width: double.infinity, + padding: EdgeInsets.only(top: 3, bottom: 3), + child: Row( + children: [ + Expanded( + child: _getNormalText(TranslationBase.of(context).patientShareTotalToDo), + ), + Expanded( + child: _getNormalText(model.erPatientShareModel!.patientShareWithTax!.toStringAsFixed(2) ?? "0", isBold: true), + ) + ], + ), + ), + ], + ), + ), + ) : Container(), + mHeight(50.0), + Text( + TranslationBase.of(context).payOptions, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 12.0, + fontWeight: FontWeight.w600, + letterSpacing: -0.46, ), ), + Container(margin: EdgeInsets.fromLTRB(20.0, 5.0, 20.0, 5.0), child: getPaymentMethods()), ], ), ), bottomSheet: Container( - height: 76, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: SecondaryButton( - color: Theme.of(context).primaryColor, - label: TranslationBase.of(context).next.toUpperCase(), - onTap: () { - Navigator.push(context, FadePage(page: PaymentMethod())).then( - (value) { - //TODO Haroun call API here - }, - ); - }, - ), + color: CustomColors.appBackgroudGreyColor, + padding: EdgeInsets.all(12.0), + child: DefaultButton( + TranslationBase.of(context).payNow.toUpperCase(), + () { + Navigator.push(context, FadePage(page: PaymentMethod( + onSelectedMethod: (String metohd, [String? selectedInstallmentPlan]) { + setState(() {}); + }, patientShare: model.erPatientShareModel!.patientShareWithTax!, isFromAdvancePayment: true, + ))).then( + (value) { + print(value); + if (value != null) { + AppoitmentAllHistoryResultList appo = new AppoitmentAllHistoryResultList(); + appo.projectID = widget.selectedHospital!.iD; + openPayment(value[0], projectViewModel.user, model.erPatientShareModel!.patientShareWithTax!, appo); + } + }, + ); + }, + color: CustomColors.green, + disabledColor: CustomColors.grey2, ), ), ), ); } + _getNormalText(text, {bool isBold = false}) { + return Text( + text, + style: TextStyle( + fontSize: isBold ? 12 : 10, + letterSpacing: -0.5, + color: isBold ? Colors.black : Colors.grey[700], + fontWeight: FontWeight.w600, + ), + ); + } + + openPayment(String paymentMethod, AuthenticatedUser authenticatedUser, num amount, AppoitmentAllHistoryResultList appo) { + browser = new MyInAppBrowser(onExitCallback: onBrowserExit, appo: appo, onLoadStartCallback: onBrowserLoadStart); + transID = Utils.getAdvancePaymentTransID(widget.selectedHospital!.iD, projectViewModel.user!.patientID!); + browser.openPaymentBrowser(amount, "ER Online Check-In", transID, appo.projectID.toString(), authenticatedUser.emailAddress!, paymentMethod, authenticatedUser.patientType, + authenticatedUser.firstName!, authenticatedUser.patientID, authenticatedUser, browser, false, "3", "", context); + } + + onBrowserLoadStart(String url) { + print("onBrowserLoadStart"); + print(url); + MyInAppBrowser.successURLS.forEach((element) { + if (url.contains(element)) { + if (browser.isOpened()) browser.close(); + MyInAppBrowser.isPaymentDone = true; + return; + } + }); + MyInAppBrowser.errorURLS.forEach((element) { + if (url.contains(element)) { + if (browser.isOpened()) browser.close(); + MyInAppBrowser.isPaymentDone = false; + return; + } + }); + } + + onBrowserExit(AppoitmentAllHistoryResultList appo, bool isPaymentMade) { + print("onBrowserExit Called!!!!"); + checkPaymentStatus(appo); + } + + checkPaymentStatus(AppoitmentAllHistoryResultList appo) { + DoctorsListService service = new DoctorsListService(); + GifLoaderDialogUtils.showMyDialog(AppGlobal.context); + service.checkPaymentStatus(transID, false, AppGlobal.context).then((res) { + GifLoaderDialogUtils.hideDialog(AppGlobal.context); + String paymentInfo = res['Response_Message']; + if (paymentInfo == 'Success') { + ER_createAdvancePayment(res, appo); + } else { + AppToast.showErrorToast(message: res['Response_Message']); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(AppGlobal.context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + + ER_createAdvancePayment(payment_res, AppoitmentAllHistoryResultList appo) { + DoctorsListService service = new DoctorsListService(); + GifLoaderDialogUtils.showMyDialog(AppGlobal.context); + service.ER_createAdvancePayment(appo, appo.projectID.toString(), payment_res['Amount'], payment_res['Fort_id'], payment_res['PaymentMethod'], AppGlobal.context).then((res) { + GifLoaderDialogUtils.hideDialog(AppGlobal.context); + ER_InsertEROnlinePaymentDetails(payment_res, appo); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(AppGlobal.context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + + ER_InsertEROnlinePaymentDetails(payment_res, AppoitmentAllHistoryResultList appo) { + DoctorsListService service = new DoctorsListService(); + GifLoaderDialogUtils.showMyDialog(AppGlobal.context); + service.ER_InsertEROnlinePaymentDetails(appo, appo.projectID.toString(), payment_res['Amount'], payment_res['Fort_id'], payment_res['PaymentMethod'], AppGlobal.context).then((res) { + GifLoaderDialogUtils.hideDialog(AppGlobal.context); + AppToast.showSuccessToast(message: TranslationBase.of(context).success); + Navigator.of(context).pop(); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(AppGlobal.context); + AppToast.showErrorToast(message: err); + print(err); + }); + } } diff --git a/lib/pages/ErService/ErOptions.dart b/lib/pages/ErService/ErOptions.dart index e0ff3ed4..9253dd52 100644 --- a/lib/pages/ErService/ErOptions.dart +++ b/lib/pages/ErService/ErOptions.dart @@ -1,115 +1,106 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/pages/ErService/rapid-response-team/rrt-main-screen.dart'; import 'package:diplomaticquarterapp/uitl/location_util.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'; - import 'package:flutter/material.dart'; -import '../../uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/pages/ErService/widgets/card_common.dart'; +import 'package:provider/provider.dart'; +import '../../uitl/translations_delegate_base.dart'; import 'AmbulanceReq.dart'; import 'EdOnline/DdServicesPage.dart'; -import 'EdOnline/EdOnlineSelectedHospitalPage.dart'; import 'NearestEr.dart'; class ErOptions extends StatefulWidget { final bool isAppbar; - const ErOptions({Key key, this.isAppbar}) : super(key: key); - + const ErOptions({Key? key, required this.isAppbar}) : super(key: key); @override _ErOptionsState createState() => _ErOptionsState(); } class _ErOptionsState extends State { - LocationUtils locationUtils; + late LocationUtils locationUtils; + late ProjectViewModel projectViewModel; @override void initState() { - locationUtils = - new LocationUtils(isShowConfirmDialog: true, context: context); - WidgetsBinding.instance - .addPostFrameCallback((_) => locationUtils.getCurrentLocation()); + locationUtils = new LocationUtils(isShowConfirmDialog: true, context: context); + WidgetsBinding.instance.addPostFrameCallback((_) => locationUtils.getCurrentLocation()); super.initState(); } + @override Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + final rrtLocked = projectViewModel.havePrivilege(68); + return AppScaffold( isShowAppBar: widget.isAppbar, - appBarTitle: TranslationBase.of(context).bookAppo, - body: Container( - margin: EdgeInsets.fromLTRB(10.0, 20.0, 10.0, 10.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - - Container( - margin: EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 10.0), - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Expanded( - child: CardCommonEr( - image: 'assets/images/new-design/AM.PNG', - text: TranslationBase.of(context).ambulancerequest, - subText: TranslationBase.of(context).requestA, - onTap: (){ - Navigator.push( - context, - FadePage( - page: AmbulanceReq())); - }, - - ), - ), - Expanded( - child: CardCommonEr( - image: 'assets/images/new-design/emergency_icon.png', - text: TranslationBase.of(context).nearester, - subText: TranslationBase.of(context).locationa, - onTap:(){ - Navigator.push( - context, - FadePage( - page: NearestEr())); - }), - - ) - ], - ), + appBarTitle: TranslationBase.of(context).emergencyServices, + isShowDecPage: false, + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: Color(0xffF8F8F8), + body: GridView( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, childAspectRatio: 2 / 2, crossAxisSpacing: 12, mainAxisSpacing: 12), + physics: NeverScrollableScrollPhysics(), + padding: EdgeInsets.all(21), + shrinkWrap: true, + children: [ + InkWell( + onTap: () { + if (projectViewModel.havePrivilege(63)) Navigator.push(context, FadePage(page: AmbulanceReq())); + }, + child: MedicalProfileItem( + title: TranslationBase.of(context).ambulancerequest, + imagePath: 'assets/images/new-design/AM.PNG', + subTitle: TranslationBase.of(context).requestA, + isPngImage: true, + isEnable: projectViewModel.havePrivilege(63), ), - Container( - margin: EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 10.0), - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Expanded( - child: CardCommonEr( - image: 'assets/images/new-design/AM.PNG', - text:'ED service', - subText: 'ED service', - onTap: (){ - Navigator.push( - context, - FadePage( - page: DdServicesPage())); - }, - - ), - ), - Expanded( - child: Container(), - ) - ], - ), + ), + InkWell( + onTap: () { + Navigator.push(context, FadePage(page: NearestEr())); + }, + child: MedicalProfileItem( + title: TranslationBase.of(context).nearester, + imagePath: 'assets/images/new-design/emergency_icon.png', + subTitle: TranslationBase.of(context).locationa, + isPngImage: true, ), - ], - ), + ), + InkWell( + onTap: () { + if (rrtLocked) Navigator.push(context, FadePage(page: RRTMainScreen())); + }, + child: MedicalProfileItem( + title: TranslationBase.of(context).RRTTitle, + imagePath: 'assets/images/new-design/AM.PNG', + subTitle: TranslationBase.of(context).RRTSubTitle, + isPngImage: true, + isEnable: rrtLocked, + ), + ), + InkWell( + onTap: () { + if (projectViewModel.havePrivilege(81)) Navigator.push(context, FadePage(page: DdServicesPage())); + // Navigator.push(context, FadePage(page: DdServicesPage())); + }, + child: MedicalProfileItem( + title: "ED", + imagePath: 'assets/images/new-design/AM.PNG', + subTitle: TranslationBase.of(context).service, + isPngImage: true, + isEnable: projectViewModel.havePrivilege(81), + ), + ), + ], ), ); } } - diff --git a/lib/pages/ErService/NearestEr.dart b/lib/pages/ErService/NearestEr.dart index eaf0d4ef..20b664d9 100644 --- a/lib/pages/ErService/NearestEr.dart +++ b/lib/pages/ErService/NearestEr.dart @@ -1,22 +1,45 @@ -import 'package:diplomaticquarterapp/core/viewModels/er/near_hospital_view_model.dart'; -import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +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/uitl/location_util.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:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; + import '../../uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/pages/ErService/widgets/card_common.dart'; -import 'widgets/card_position.dart'; -class NearestEr extends StatelessWidget { +class NearestEr extends StatefulWidget { static const String _url = "assets/images/"; - int appointmentNo; - int projectID; + int? appointmentNo; + int? projectID; + + NearestEr({ this.appointmentNo, this.projectID}); + + @override + _NearestErState createState() => _NearestErState(); +} + +class _NearestErState extends State { + List projectAvgERWaitingTimeModelList =[]; - NearestEr({this.appointmentNo, this.projectID}); + late bool isDataLoaded; + late LocationUtils locationUtils; + + @override + void initState() { + isDataLoaded = false; + locationUtils = new LocationUtils(isShowConfirmDialog: true, context: context); + WidgetsBinding.instance.addPostFrameCallback((_) { + locationUtils.getCurrentLocation(); + getERList(); + }); + super.initState(); + } @override Widget build(BuildContext context) { @@ -24,84 +47,73 @@ class NearestEr extends StatelessWidget { final double itemHeight = (size.height - kToolbarHeight - 24) / 2; final double itemWidth = size.width / 2; - return BaseView( - onModelReady: appointmentNo != null && projectID != null - ? (model) => model.getProjectAvgERWaitingTimeOrders( - id: appointmentNo, projectID: projectID) - : (model) => model.getProjectAvgERWaitingTimeOrders(), - builder: (_, mode, widget) => AppScaffold( - isShowAppBar: true, - appBarTitle: TranslationBase.of(context).NearestEr, - baseViewModel: mode, - body: mode.ProjectAvgERWaitingTimeModeList.length > 0 - ? Container( - child: ListView( + return AppScaffold( + isShowAppBar: true, + isShowDecPage: false, + showNewAppBarTitle: true, + showNewAppBar: true, + appBarTitle: TranslationBase.of(context).NearestEr, + body: isDataLoaded != null + ? isDataLoaded + ? ListView( + padding: EdgeInsets.all(21), + physics: BouncingScrollPhysics(), 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), - shrinkWrap: true, - padding: const EdgeInsets.all(4.0), - children: List.generate(7, (index) { - return Container( - child: CardPosition( - text: mode - .ProjectAvgERWaitingTimeModeList[index] - .projectName - .toString(), - image: - 'assets/images/new-design/find_us_icon.png', - subText: mode - .ProjectAvgERWaitingTimeModeList[index] - .distanceInKilometers - .toString(), - type: mode - .ProjectAvgERWaitingTimeModeList[index].iD - .toString(), - telephone: mode - .ProjectAvgERWaitingTimeModeList[index] - .phoneNumber - .toString(), - networkImage: mode - .ProjectAvgERWaitingTimeModeList[index] - .projectImageURL - .toString(), - latitude: mode - .ProjectAvgERWaitingTimeModeList[index] - .latitude, - longitude: mode - .ProjectAvgERWaitingTimeModeList[index] - .longitude, - projectname: mode - .ProjectAvgERWaitingTimeModeList[index] - .projectName, - cardSize: itemWidth, - ), - ); - }), - ), + 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: 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; + print(projectAvgERWaitingTimeModelList[index].phonenumber); + 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(), ); } + + getERList() async { + GifLoaderDialogUtils.showMyDialog(context); + ErService service = new ErService(); + service.getProjectAvgERWaitingTimeOrders().then((response) { + if (response != null && response['MessageStatus'] == 1) { + setState(() { + projectAvgERWaitingTimeModelList.clear(); + response['List_ProjectAvgERWaitingTime'].forEach((vital) { + projectAvgERWaitingTimeModelList.add(ProjectAvgERWaitingTime.fromJson(vital)); + }); + isDataLoaded = true; + }); + GifLoaderDialogUtils.hideDialog(context); + } else { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: TranslationBase.of(context).serviceNotAvailable); + isDataLoaded = false; + } + }).catchError((err) { + print(err); + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err.toString()); + }); + } } diff --git a/lib/pages/ErService/OrderLogPage.dart b/lib/pages/ErService/OrderLogPage.dart index 7d2a4a5b..a551bda6 100644 --- a/lib/pages/ErService/OrderLogPage.dart +++ b/lib/pages/ErService/OrderLogPage.dart @@ -1,86 +1,260 @@ -import 'package:diplomaticquarterapp/core/model/er/PatientAllPresOrders.dart'; +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/er/AmbulanceRequestOrdersModel.dart'; import 'package:diplomaticquarterapp/core/viewModels/er/am_request_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.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/widgets/buttons/secondary_button.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; -import 'package:diplomaticquarterapp/widgets/others/OrderLogItem.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/ConfirmWithMessageDialog.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; class OrderLogPage extends StatelessWidget { final AmRequestViewModel amRequestViewModel; - OrderLogPage({Key key, @required this.amRequestViewModel}); + OrderLogPage({Key? key, required this.amRequestViewModel}); @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + + void showConfirmMessage(AmRequestViewModel model, int presOrderID, BuildContext context) { + showDialog( + context: context, + builder: (cxt) => ConfirmWithMessageDialog( + message: TranslationBase.of(context).cancelOrderMsg, + onTap: () { + Future.delayed(new Duration(milliseconds: 300)).then((value) async { + // GifLoaderDialogUtils.showMyDialog(context); + await model.updatePressOrder(presOrderID: presOrderID); + if (model.state == ViewState.ErrorLocal) { + Utils.showErrorToast(model.error); + // GifLoaderDialogUtils.hideDialog(context); + } else { + AppToast.showSuccessToast(message: TranslationBase.of(context).processDoneSuccessfully); + // GifLoaderDialogUtils.hideDialog(context); + } + }); + }, + )); + return; + } + return Container( - margin: EdgeInsets.all(10), + // margin: EdgeInsets.all(10), padding: EdgeInsets.all(8), - child: ListView.builder( - itemCount: amRequestViewModel.patientAllPresOrdersList.length, - itemBuilder: (context, index) => Container( - margin: EdgeInsets.all(8), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(2), - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - OrderLogItem( - title: TranslationBase.of(context).reqId, - value: amRequestViewModel.patientAllPresOrdersList[index].iD - .toString(), - ), - OrderLogItem( - title: TranslationBase.of(context).orderStatus, - value: amRequestViewModel - .patientAllPresOrdersList[index].description, - ), - OrderLogItem( - title: TranslationBase.of(context).pickupDate, - value: DateUtil.getDayMonthYearDateFormatted( - DateUtil.convertStringToDate(amRequestViewModel - .patientAllPresOrdersList[index].createdOn)), - ), - OrderLogItem( - title: TranslationBase.of(context).pickupLocation, - value: amRequestViewModel - .patientAllPresOrdersList[index].pickupLocationName, - ), - OrderLogItem( - title: TranslationBase.of(context).dropoffLocation, - value: amRequestViewModel - .patientAllPresOrdersList[index].dropoffLocationName, - ), - if(amRequestViewModel.patientAllPresOrdersList[index].status==1) - Container( - padding: EdgeInsets.all(10), - width: double.maxFinite, - margin: EdgeInsets.only(bottom: 4,left: 4,right: 4), + child: amRequestViewModel.patientAmbulanceRequestOrdersList.length > 0 + ? ListView.builder( + padding: EdgeInsets.all(21), + reverse: false, + itemCount: amRequestViewModel.patientAmbulanceRequestOrdersList.length, + itemBuilder: (context, index) { + AmbulanceRequestOrdersModel order = amRequestViewModel.patientAmbulanceRequestOrdersList.reversed.toList()[index]; + + int status = order.statusId!; + String _statusDisp = order.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 Container( + margin: EdgeInsets.only(bottom: 12.0), decoration: BoxDecoration( - borderRadius: BorderRadius.only( - bottomRight: Radius.circular(12), - bottomLeft: Radius.circular(12), + color: _color, + borderRadius: BorderRadius.all( + Radius.circular(10.0), + ), + boxShadow: [ + BoxShadow( + color: Color(0xff000000).withOpacity(.05), + blurRadius: 27, + offset: Offset(0, -3), ), - color: Colors.white + ], ), - child: SecondaryButton( - color: Colors.red[900], - textColor: Colors.white, - label: TranslationBase.of(context).cancel, - onTap: () { - amRequestViewModel.updatePressOrder(presOrderID:amRequestViewModel.pickUpRequestPresOrder.presOrderID ); - - }, + child: Container( + margin: EdgeInsets.only(left: projectViewModel.isArabic ? 0 : 6, right: projectViewModel.isArabic ? 6 : 0), + padding: EdgeInsets.symmetric(vertical: 13, 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, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + _statusDisp, + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: _color, letterSpacing: -0.4, height: 16 / 10), + ), + SizedBox(height: 6), + Text( + '${TranslationBase.of(context).requestID}: ${order.iD}', + 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).pickupDate + ": ", + style: TextStyle(fontSize: 10, fontWeight: FontWeight.w600, color: Color(0xff575757), letterSpacing: -0.4, height: 16 / 10), + ), + Expanded( + child: Text( + DateUtil.getDayMonthYearDateFormatted(DateTime.tryParse(order.created!)!), + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.48, height: 16 / 10), + ), + ), + ], + ), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).transportMethod + ": ", + style: TextStyle(fontSize: 10, fontWeight: FontWeight.w600, color: Color(0xff575757), letterSpacing: -0.4, height: 16 / 10), + ), + Expanded( + child: Text( + order.serviceText!, + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.48, height: 16 / 10), + ), + ), + ], + ), + SizedBox( + height: 13.0, + ), + ], + ), + ), + Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + SizedBox(height: 12), + if (order.statusId == 1 || order.statusId == 2) + InkWell( + onTap: () { + showConfirmMessage(amRequestViewModel, order.iD!, context); + }, + 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), + ), + ), + ), + ], + ), + ], + ), + Row( + children: [ + Container( + margin: projectViewModel.isArabic ? EdgeInsets.only(left: 10.0) : EdgeInsets.only(right: 10.0), + width: 8, + height: 8, + decoration: containerRadius( + CustomColors.textColor, + 100, + ), + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).pickupLocation + ": ", + style: TextStyle(fontSize: 10, fontWeight: FontWeight.w600, color: Color(0xff575757), letterSpacing: -0.4, height: 16 / 10), + ), + Container( + width: MediaQuery.of(context).size.width * 0.7, + child: Text( + order.pickupLocation!.trim().toString(), + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.48, overflow: TextOverflow.clip), + ), + ), + ], + ), + ], + ), + Container( + height: 20.0, + width: 1.0, + color: CustomColors.grey2, + margin: const EdgeInsets.only(left: 3.0, right: 3.0), + ), + Row( + children: [ + Container( + margin: projectViewModel.isArabic ? EdgeInsets.only(left: 10.0) : EdgeInsets.only(right: 10.0), + width: 8, + height: 8, + decoration: containerRadius( + CustomColors.accentColor, + 100, + ), + ), + Expanded(child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).dropoffLocation + ": ", + style: TextStyle(fontSize: 10, fontWeight: FontWeight.w600, color: Color(0xff575757), letterSpacing: -0.4, height: 16 / 10), + ), + Text( + order.dropOffLocation!.trim().toString(), + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.48), overflow: TextOverflow.ellipsis, + ), + ], + )), + ], + ), + ], + ), ), - ) - ], - ), - ), - ), + ); + }) + : getNoDataWidget(context), ); } + + String getDate(String date) { + return date.split("T")[0]; + } } diff --git a/lib/pages/ErService/rapid-response-team/rrt-agreement-page.dart b/lib/pages/ErService/rapid-response-team/rrt-agreement-page.dart new file mode 100644 index 00000000..8be47868 --- /dev/null +++ b/lib/pages/ErService/rapid-response-team/rrt-agreement-page.dart @@ -0,0 +1,48 @@ +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'; + +class RRTAgreementPage extends StatelessWidget{ + late TranslationBase localize; + + @override + Widget build(BuildContext context) { + localize = TranslationBase.of(context); + + return AppScaffold( + appBarTitle: localize.userAgreement, + isShowAppBar: true, + showHomeAppBarIcon: false, + body: SingleChildScrollView( + padding: EdgeInsets.all(20), + child: Column( + children: [ + Text(localize.rrtUserAgreementTitle, style: TextStyle(color: Colors.black, fontWeight: FontWeight.w500, fontSize: 22), maxLines: 100, textAlign: TextAlign.center), + SizedBox(height: 20), + text(localize.rrtUserAgreementP1), + text(localize.rrtUserAgreementP2), + text(localize.rrtUserAgreementP3) + ], + ), + ) + ); + } + + Widget text(String string)=> Padding( + padding: const EdgeInsets.symmetric(vertical: 15), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + clipBehavior: Clip.hardEdge, + width: 10, height: 10, + decoration: BoxDecoration(borderRadius: BorderRadius.circular(20), color: Colors.black) + ), + SizedBox(width: 20), + Expanded(child: Text(string, style: TextStyle(color: Colors.black87, fontSize: 18), maxLines: 100, textAlign: TextAlign.justify)), + ], + ), + ); + +} \ No newline at end of file diff --git a/lib/pages/ErService/rapid-response-team/rrt-logs-page.dart b/lib/pages/ErService/rapid-response-team/rrt-logs-page.dart new file mode 100644 index 00000000..314abf9a --- /dev/null +++ b/lib/pages/ErService/rapid-response-team/rrt-logs-page.dart @@ -0,0 +1,63 @@ +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/GetCMCAllOrdersResponseModel.dart'; +import 'package:diplomaticquarterapp/core/viewModels/er/rrt-view-model.dart'; +import 'package:diplomaticquarterapp/pages/ErService/rapid-response-team/rrt-main-screen.dart'; +import 'package:diplomaticquarterapp/pages/ErService/rapid-response-team/rrt-order-list-item.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +class RRTLogPage extends StatefulWidget { + final List orders; + + const RRTLogPage({required this.orders}); + + @override + State createState() => RRTLogPageState(); +} + +class RRTLogPageState extends State { + late RRTViewModel viewModel; + + @override + void initState() { + setState(() {}); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return BaseView( + onModelReady: (vm) => { + viewModel = vm, + }, + builder: (ctx, vm, widgetState) { + return widget.orders.length > 0 + ? ListView.builder( + itemCount: widget.orders.length, + padding: EdgeInsets.all(21), + itemBuilder: (ctx, idx) { + var order = widget.orders.reversed.toList()[idx]; + return RRTLogListItem(order, onCancel: deleteOrder); + }) + : getNoDataWidget(context); + }); + } + + deleteOrder(GetCMCAllOrdersResponseModel order) async { + GifLoaderDialogUtils.showMyDialog(context); + var success = await viewModel.cancelOrderRC(order); + + if (success) { + viewModel.setState(ViewState.Busy); + await viewModel.getAllOrdersRC(); + viewModel.setState(ViewState.Idle); + Navigator.popUntil(context, (route) => Utils.route(route, equalsTo: RRTMainScreen)); + Navigator.push(context, FadePage(page: RRTMainScreen())); + } + } +} \ No newline at end of file diff --git a/lib/pages/ErService/rapid-response-team/rrt-main-screen.dart b/lib/pages/ErService/rapid-response-team/rrt-main-screen.dart new file mode 100644 index 00000000..83451428 --- /dev/null +++ b/lib/pages/ErService/rapid-response-team/rrt-main-screen.dart @@ -0,0 +1,140 @@ +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/models/rrt/service_price.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'; +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(); +} + +class RRTMainScreenState extends State with SingleTickerProviderStateMixin { + int currentIndex = 0; + late TabController tabController; + PageController pageController = PageController(initialPage: 0, keepPage: true); + + late RRTViewModel viewModel; + late bool loadingData; + + List imagesInfo =[]; + + late ProjectViewModel projectViewModel; + + @override + void initState() { + super.initState(); + imagesInfo.add(ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/RRT/en/0.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/RRT/ar/0.png')); + tabController = TabController(length: 2, vsync: this); + } + + late TranslationBase localize; + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + localize = TranslationBase.of(context); + + return AppScaffold( + appBarTitle: localize.rapidResponseTeam, + isShowAppBar: true, + showNewAppBar: true, + showNewAppBarTitle: true, + description: TranslationBase.of(context).rrtDDetails, + imagesInfo: imagesInfo, + body: BaseView( + onModelReady: (vm) async { + viewModel = vm; + loadingData = true; + await vm.loadRequiredData(projectViewModel.isArabic ? 1 : 2).then((value) {}).whenComplete(() => setState(() => loadingData = false)); + }, + builder: (ctx, vm, widget) => content(), + )); + } + + Widget content() { + if (loadingData == true) { + return Center(child: CircularProgressIndicator()); + // else if(viewModel.state == ViewState.Error) + + } else if (viewModel.rrtServiceData != null && viewModel.rrtProcedureList != null) { + return Column( + children: [tabBar(), Expanded(child: contentPager())], + ); + } else { + return Container( + alignment: Alignment.center, + child: Text( + localize.somethingWentWrongTryLater, + style: TextStyle(color: Colors.red), + maxLines: 5, + ), + ); + } + } + + Widget tabBar() => Container( + margin: EdgeInsets.all(0.0), + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(10)), + 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, + ), + 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.backgroundColor), + ), + ), + Tab( + child: Text( + localize.orderLog, + style: TextStyle(color: Theme.of(context).appBarTheme.backgroundColor!), + ), + ), + ]), + ); + + Widget contentPager() => PageView( + onPageChanged: onPageChanged, + controller: pageController, + children: [ + RRTRequestPage(servicePrice: viewModel.rrtServiceData.servicePrice, pendingOrders: viewModel.rrtServiceData.pendingOrders, viewModel: viewModel), + RRTLogPage(orders: viewModel.rrtServiceData.completedOrders), + ], + ); + + void onPageChanged(int index) { + pageController.animateToPage(index, duration: Duration(milliseconds: 200), curve: Curves.easeInOut); + tabController.animateTo(index); + } +} 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 new file mode 100644 index 00000000..50df1033 --- /dev/null +++ b/lib/pages/ErService/rapid-response-team/rrt-order-list-item.dart @@ -0,0 +1,242 @@ +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'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/core/viewModels/er/rrt-view-model.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/pages/ErService/rapid-response-team/rrt-main-screen.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +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 GetCMCAllOrdersResponseModel? order; + final Function(GetCMCAllOrdersResponseModel)? onCancel; + + RRTLogListItem(this.order, {this.onCancel}); + + @override + State createState() => RRTLogListItemState(); + late BuildContext _context; +} + +class RRTLogListItemState extends State { + late RRTViewModel viewModel; + late TranslationBase localize; + + @override + Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + + localize = TranslationBase.of(context); + int status = widget.order!.statusId!; + String _statusDisp = widget.order!.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 BaseView( + onModelReady: (vm) => { + viewModel = vm, + }, + builder: (ctx, vm, widgetState) { + return Container( + margin: EdgeInsets.all(5), + decoration: BoxDecoration( + color: _color, + 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( + _statusDisp, + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: _color, letterSpacing: -0.4, height: 16 / 10), + ), + SizedBox(height: 6), + Text( + '${TranslationBase.of(context).requestID}: ${widget.order!.iD}', + 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).locationa + ": ", + // style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff575757), letterSpacing: -0.4, height: 16 / 10), + // ), + // Expanded( + // child: Text( + // widget.order.projectName.toString(), + // style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.56), + // ), + // ), + // ], + // ), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + localize.pickupDate + ": ", + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff575757), letterSpacing: -0.4, height: 16 / 10), + ), + Expanded( + child: Text( + DateUtil.getDayMonthYearDateFormatted(DateTime.tryParse(widget.order!.created!)!), + style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.56), + ), + ), + ], + ), + ], + ), + ), + Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text( + 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!.statusId == 1 || widget.order!.statusId == 2) + InkWell( + onTap: () { + //onCancel(order); + cancelOrders(widget.order); + }, + 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), + ), + ), + ), + ], + ), + ], + ), + ), + ); + }); + + // return Container( + // padding: EdgeInsets.all(15), + // margin: EdgeInsets.symmetric(horizontal: 15, vertical: 10), + // decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(15), boxShadow: [BoxShadow(color: Colors.grey.withOpacity(0.25), spreadRadius: 1, blurRadius: 3)]), + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.stretch, + // children: [ + // _contentItem(label: localize.reqId, value: order.iD.toString()), + // _item_content_seperator, + // _contentItem(label: localize.status, value: projectViewModel.isArabic ? order.descriptionN.toString() : order.description.toString()), //order.getStatusName(localize)), + // _item_content_seperator, + // _contentItem(label: localize.pickupDate, value: order.getFormattedDateTime()), + // _item_content_seperator, + // _contentItem(label: localize.location, value: order.getNearestProjectDescription()), + // _item_content_seperator, + // SizedBox(height: 10), + // if (order.status == 1 || order.status == 2) Container(child: cancelButton()) + // ], + // ), + // ); + } + + // Widget _contentItem({@required String label, String value}) { + // return Container( + // padding: EdgeInsets.symmetric(vertical: 10), + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // Text( + // label, + // style: TextStyle(color: Theme.of(_context).appBarTheme.color, fontSize: 9, letterSpacing: 1), + // ), + // SizedBox( + // height: 5, + // ), + // Text( + // value, + // style: TextStyle(color: Theme.of(_context).appBarTheme.color, fontWeight: FontWeight.bold, fontSize: 14), + // ), + // ], + // ), + // ); + // } + + // Widget cancelButton() => MaterialButton( + // height: 45, + // color: Color(0xFFc5272d), + // shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), + // onPressed: () => onCancel(order), + // child: Text( + // localize.cancel, + // style: TextStyle(color: Colors.white, fontSize: 13), + // ), + // ); + cancelOrders(order) async { + GifLoaderDialogUtils.showMyDialog(context); + var success = await viewModel.cancelOrderRC(order); + + if (success) { + viewModel.setState(ViewState.Busy); + 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-pickup-address-page.dart b/lib/pages/ErService/rapid-response-team/rrt-pickup-address-page.dart new file mode 100644 index 00000000..dd5ce2fa --- /dev/null +++ b/lib/pages/ErService/rapid-response-team/rrt-pickup-address-page.dart @@ -0,0 +1,353 @@ +import 'dart:async'; + +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/customer_addresses_service.dart'; +import 'package:diplomaticquarterapp/core/viewModels/er/rrt-view-model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/rrt/RRTProcedureList.dart'; +import 'package:diplomaticquarterapp/models/rrt/service_price.dart'; +import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/location_page.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/widgets/reminder_dialog.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/location_util.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/app_map/google_huawei_map.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/select_location_dialog.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:geolocator/geolocator.dart'; +import 'package:google_maps_flutter/google_maps_flutter.dart'; +import 'package:permission_handler/permission_handler.dart'; +import 'package:provider/provider.dart'; + +import 'rrt-place-order.dart'; + +class RRTRequestPickupAddressPage extends StatefulWidget { + final ServicePrice servicePrice; + final VidaProcedureList selectedProcedure; + + RRTRequestPickupAddressPage({required this.servicePrice, required this.selectedProcedure}); + + @override + State createState() => RRTRequestPickupAddressPageState(); +} + +class RRTRequestPickupAddressPageState extends State with SingleTickerProviderStateMixin { + bool acceptTerms = false; + + bool mapIdle = true; + Completer mapController = Completer(); + + static CameraPosition cameraPosition = CameraPosition( + target: LatLng(37.42796133580664, -122.085749655962), + zoom: 17, + ); + + late LatLng currentPostion; + List myAddresses = []; + AddressInfo selectedAddress = new AddressInfo(); + StreamController addressStreamController = StreamController(); + late Stream addressStream; + StreamController addressLoadingStreamController = StreamController(); + late Stream addressLoadingStream; + + // AddressInfo _selectedAddress; + double latitude = 0; + double longitude = 0; + late AppMap appMap; + bool showCurrentLocation = false; + AppSharedPreferences sharedPref = AppSharedPreferences(); + late LocationUtils locationUtils; + + @override + void initState() { + super.initState(); + locationUtils = new LocationUtils(isShowConfirmDialog: true, context: context); + WidgetsBinding.instance.addPostFrameCallback((_) => locationUtils.getCurrentLocation()); + + appMap = AppMap( + cameraPosition.toMap() as Map, + //Changed by Aamir + onCameraMove: _updatePosition!, + + onMapCreated: () { + _getUserLocation(); + setState(() {}); + }, + ); + } + + setLatitudeAndLongitude({bool isSetState = false, String? latLong}) async { + if (latLong == null) { + if (myAddresses.isEmpty) { + setState(() { + showCurrentLocation = true; + }); + } else { + latLong = myAddresses[myAddresses.length - 1].latLong; + } + } + + if (!showCurrentLocation) { + List latLongArr = latLong!.split(','); + + latitude = double.parse(latLongArr[0]); + longitude = double.parse(latLongArr[1]); + currentPostion = LatLng(latitude, longitude); + setMap(); + } + } + + setMap() { + setState(() { + cameraPosition = CameraPosition( + target: currentPostion, + zoom: 16, + ); + appMap.moveTo(cameraPostion: cameraPosition); + selectedAddress.latLong = currentPostion.latitude.toString() + "," + currentPostion.longitude.toString(); + }); + } + + void loadAddresses() async { + await viewModel.getCustomerInfo(); + + if (viewModel.addressesList.isNotEmpty) setState(() {}); + } + + late TranslationBase localize; + late RRTViewModel viewModel; + + @override + Widget build(BuildContext context) { + localize = TranslationBase.of(context); + ProjectViewModel projectViewModel = Provider.of(context); + + addressStreamController.sink.add(0); + + return BaseView( + onModelReady: (vm) { + viewModel = vm; + loadAddresses(); + myAddresses = viewModel.addressesList; + }, + builder: (ctx, vm, widget) => AppScaffold( + appBarTitle: localize.pickupLocation, + isShowAppBar: true, + showNewAppBar: true, + showNewAppBarTitle: true, + baseViewModel: viewModel, + body: Column( + children: [ + Container( + margin: EdgeInsets.only(left: 12, right: 12, bottom: 12, top: 12), + decoration: cardRadius(12), + child: Container( + child: InkWell( + onTap: () => confirmSelectLocationDialog(myAddresses), + child: Container( + padding: EdgeInsets.all(8), + width: double.infinity, + // height: 65, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: Colors.white, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Text( + getAddressName(), + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 12, + letterSpacing: -0.45, + ), + ), + ), + Icon(Icons.arrow_drop_down) + ], + ), + ), + ), + height: 50, + width: double.infinity, + ), + ), + InkWell( + onTap: () async { + Navigator.push( + context, + FadePage( + page: LocationPage( + // latitude: latitude, + // longitude: longitude, + ), + ), + ); + }, + child: Padding( + padding: EdgeInsets.only(left: 12, right: 12, bottom: 16, top: 8), + child: Row( + children: [ + Icon(Icons.add_circle_outline_sharp), + mWidth(12), + Text( + TranslationBase.of(context).addNewAddress, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + letterSpacing: -0.46, + ), + ), + ], + ), + ), + ), + Expanded( + child: Stack( + alignment: Alignment.center, + children: [ + if (appMap != null) appMap, + Icon( + Icons.place, + color: CustomColors.accentColor, + size: 50, + ), + ], + ), + ), + Padding( + padding: const EdgeInsets.only(left: 20, right: 20, top: 14, bottom: 14), + child: continueButton(), + ), + ], + ))); + } + + void _updatePosition() { + latitude = cameraPosition.target.latitude; + longitude = cameraPosition.target.longitude; + selectedAddress.latLong = latitude.toString() + "," + longitude.toString(); + } + + Widget centerTargetPoint() { + double size = mapIdle ? 20 : 30; + double margin = mapIdle ? 3 : 10; + return Center( + child: Container( + width: size, + height: size, + decoration: BoxDecoration(borderRadius: BorderRadius.circular(20), border: Border.all(width: 2, color: Theme.of(context).appBarTheme.backgroundColor!)), + child: Container(margin: EdgeInsets.all(margin), decoration: BoxDecoration(color: Theme.of(context).appBarTheme.backgroundColor, borderRadius: BorderRadius.circular(20))), + ), + ); + } + + Widget continueButton() { + return Padding( + padding: const EdgeInsets.all(0.0), + child: DefaultButton(TranslationBase.of(context).continues, () { + Navigator.push( + context, + FadePage( + page: RRTPlaceOrderPage( + selectedAddress: selectedAddress, + servicePrice: widget.servicePrice, + selectedProcedure: widget.selectedProcedure, + ))); + }), + ); + } + + void confirmSelectLocationDialog(List addresses) { + showDialog( + context: context, + builder: (cxt) => SelectLocationDialog( + addresses: addresses, + selectedAddress: selectedAddress, + onValueSelected: (value) { + showCurrentLocation = false; + setLatitudeAndLongitude(latLong: value.latLong); + + setState(() { + selectedAddress = value; + }); + }, + ), + ); + } + + String getAddressName() { + if (selectedAddress != null && selectedAddress.address1 != null) + return selectedAddress.address1!; + else + return TranslationBase.of(context).selectAddress; + } + + moveToLocation(LatLng location, {bool animate = true}) async { + await Future.delayed(Duration(milliseconds: 200)); + cameraPosition = CameraPosition( + target: location, + zoom: 16.4746, + ); + if (animate) + (await mapController.future).animateCamera( + CameraUpdate.newCameraPosition(cameraPosition), + ); + else + (await mapController.future).moveCamera( + CameraUpdate.newCameraPosition(cameraPosition), + ); + } + + void _getUserLocation() async { + + LocationSettings locationSettings = LocationSettings( + accuracy: LocationAccuracy.low + ); + + if (await this.sharedPref.getDouble(USER_LAT) != null && await this.sharedPref.getDouble(USER_LONG) != null) { + var lat = await this.sharedPref.getDouble(USER_LAT); + var long = await this.sharedPref.getDouble(USER_LONG); + latitude = lat; + longitude = long; + currentPostion = LatLng(lat, long); + setMap(); + } else { + if (await Permission.location.request().isGranted) { + var position = await GeolocatorPlatform.instance.getCurrentPosition(locationSettings: locationSettings); + currentPostion = LatLng(position.latitude, position.longitude); + latitude = position.latitude; + longitude = position.longitude; + setMap(); + } else { + requestPermissions().then( + (value) async { + if (value[Permission.location]!.isGranted) { + var position = await GeolocatorPlatform.instance.getCurrentPosition(locationSettings: locationSettings); + currentPostion = LatLng(position.latitude, position.longitude); + latitude = position.latitude; + longitude = position.longitude; + setMap(); + } + }, + ); + } + } + } + + goToCurrentLocation() async { + Geolocator.getCurrentPosition().then((value) { + selectedAddress = AddressInfo(latLong: '${value.latitude},${value.longitude}'); + moveToLocation(LatLng(value.latitude, value.longitude)); + }); + } +} diff --git a/lib/pages/ErService/rapid-response-team/rrt-place-order.dart b/lib/pages/ErService/rapid-response-team/rrt-place-order.dart new file mode 100644 index 00000000..6384f2fa --- /dev/null +++ b/lib/pages/ErService/rapid-response-team/rrt-place-order.dart @@ -0,0 +1,253 @@ +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/customer_addresses_service.dart'; +import 'package:diplomaticquarterapp/core/viewModels/er/rrt-view-model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/rrt/RRTProcedureList.dart'; +import 'package:diplomaticquarterapp/models/rrt/RRTRequestModel.dart'; +import 'package:diplomaticquarterapp/models/rrt/service_price.dart'; +import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/Dialog/confirm_dialog.dart'; +import 'package:diplomaticquarterapp/pages/ErService/rapid-response-team/rrt-main-screen.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/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:diplomaticquarterapp/widgets/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:google_maps_flutter/google_maps_flutter.dart'; +import 'package:provider/provider.dart'; + +class RRTPlaceOrderPage extends StatelessWidget { + late TranslationBase localize; + RRTViewModel? viewModel; + AddressInfo selectedAddress; + final ServicePrice servicePrice; + final VidaProcedureList selectedProcedure; + + RRTPlaceOrderPage({required this.selectedAddress, required this.servicePrice, required this.selectedProcedure}); + + TextEditingController noteController = TextEditingController(text: ''); + late BuildContext _context; + + late ProjectViewModel projectViewModel; + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + _context = context; + localize = TranslationBase.of(context); + var lat = selectedAddress.latLong!.split(',').first; + var lng = selectedAddress.latLong!.split(',').last; + + return BaseView( + onModelReady: (vm) => viewModel = vm, + builder: (ctx, vm, wState) { + return AppScaffold( + appBarTitle: localize.rapidResponseTeam, + isShowAppBar: true, + showNewAppBarTitle: true, + showNewAppBar: true, + body: SingleChildScrollView( + padding: EdgeInsets.all(20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Text( + localize.selectedLocation, + style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18), + ), + selectedAddressField(), + AspectRatio( + aspectRatio: 3 / 1, + child: ClipRRect( + clipBehavior: Clip.hardEdge, + borderRadius: BorderRadius.circular(10), + child: Image.network( + "https://maps.googleapis.com/maps/api/staticmap?center=$lat,$lng &zoom=17&size=800x600&maptype=roadmap&markers=color:red%7C$lat,$lng&key=AIzaSyCyDbWUM9d_sBUGIE8PcuShzPaqO08NSC8", + fit: BoxFit.cover, + ), + ), + ), + SizedBox( + height: 10, + ), + Container( + height: 85, + margin: EdgeInsets.symmetric(vertical: 5), + padding: EdgeInsets.symmetric(horizontal: 15, vertical: 10), + decoration: BoxDecoration( + color: Colors.white, borderRadius: BorderRadius.circular(10), boxShadow: [BoxShadow(blurRadius: 5, spreadRadius: 2, offset: Offset(2, 2), color: Colors.grey.withOpacity(0.25))]), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + localize.patientShareWithTax, + style: TextStyle(fontSize: 13), + ), + SizedBox( + height: 5, + ), + Row( + children: [ + projectViewModel!.isArabic ? Container() : SvgPicture.asset("assets/images/new/Saudi_Riyal_Symbol.svg", width: 18, height: 18), + mWidth(6), + Text( + "${selectedProcedure.patientShareWithTax ?? '- - -'}", + style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18), + ), + mWidth(6), + projectViewModel!.isArabic ? SvgPicture.asset("assets/images/new/Saudi_Riyal_Symbol.svg", width: 18, height: 18) : Container(), + ], + ), + ], + ), + ), + Container( + height: 70, + margin: EdgeInsets.symmetric(vertical: 5), + padding: EdgeInsets.symmetric(horizontal: 0, vertical: 10), + decoration: BoxDecoration( + color: Colors.white, borderRadius: BorderRadius.circular(10), boxShadow: [BoxShadow(blurRadius: 5, spreadRadius: 2, offset: Offset(2, 2), color: Colors.grey.withOpacity(0.25))]), + child: TextField( + controller: noteController, + style: TextStyle(fontSize: 18.0), + decoration: InputDecoration( + filled: true, + fillColor: Colors.white, + labelText: localize.notes, + contentPadding: const EdgeInsets.only(left: 14.0, bottom: 8.0, top: 8.0), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: Colors.white), + borderRadius: BorderRadius.circular(10), + ), + enabledBorder: UnderlineInputBorder( + borderSide: BorderSide(color: Colors.white), + borderRadius: BorderRadius.circular(10), + ), + )), + ), + ], + ), + ), + bottomSheet: submitButton(context), + ); + }, + ); + } + + Widget selectedAddressField() { + var address = "${selectedAddress.address1 ?? ''} ${selectedAddress.address2 ?? ''}"; + return selectedAddress.address1 != null + ? Container( + margin: EdgeInsets.symmetric(vertical: 10), + child: MaterialButton( + height: 50, + color: Colors.white, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), + onPressed: () {}, + child: Row( + children: [ + Expanded(child: Text(address, style: TextStyle(color: Colors.black87, fontSize: 12, letterSpacing: 1))), + Icon( + Icons.location_on_rounded, + size: 30, + color: Colors.black, + ) + ], + ), + ), + ) + : SizedBox(); + } + + Widget submitButton(BuildContext context) { + return Container( + color: Theme.of(context).scaffoldBackgroundColor, + child: Padding( + padding: const EdgeInsets.all(15), + child: DefaultButton( + localize.submit, + () => placeOrder(), + color: CustomColors.green, + ), + ), + ); + } + + placeOrder() async { + if (selectedAddress != null && selectedAddress.latLong != null && selectedAddress.latLong!.isNotEmpty && selectedAddress.latLong!.split(',').length > 1) { + GifLoaderDialogUtils.showMyDialog(_context); + + RRTRequestModel rrtRequestModel = new RRTRequestModel(); + Procedures procedures = new Procedures(); + rrtRequestModel.procedures = []; + + Map params = {}; + var cordinates = selectedAddress.latLong!.split(','); + var latlng = LatLng(double.parse(cordinates.first), double.parse(cordinates.last)); + + procedures.serviceID = selectedProcedure.procedureID; + + rrtRequestModel.latitude = latlng.latitude; + rrtRequestModel.longitude = latlng.longitude; + rrtRequestModel.additionalDetails = noteController.text; + rrtRequestModel.nationality = projectViewModel.user!.nationalityID; + rrtRequestModel.paymentAmount = selectedProcedure.patientShareWithTax; + rrtRequestModel.nearestProjectId = 0; + rrtRequestModel.patientId = projectViewModel.user!.patientID; + rrtRequestModel.patientOutSa = projectViewModel.user!.outSA; + rrtRequestModel.procedures!.add(procedures); + + // params['latitude'] = latlng.latitude; + // params['longitude'] = latlng.longitude; + // params['additionalDetails'] = noteController.text; + // params['nationality'] = projectViewModel.user.nationalityID; + // params['paymentAmount'] = selectedProcedure.patientShareWithTax; + // params['procedureId'] = selectedProcedure.procedureID; + + await viewModel!.createOrderRC(rrtRequestModel.toJson()); + + GifLoaderDialogUtils.hideDialog(_context); + + if (viewModel!.createdRequestNo != null) { + showCMCConfirmDialog( + _context, + viewModel!.createdRequestNo.toString(), + onClick: () { + Navigator.pop(_context); + Navigator.pop(_context); + gotoRRTRoot(); + }, + ); + } + + // if (requestId != null) { + // AlertDialogBox( + // context: _context, + // title: '', + // confirmMessage: localize.rrtOrderSuccessMessage, + // okText: localize.ok, + // okFunction: () { + // AlertDialogBox.closeAlertDialog(_context); + // gotoRRTRoot(); + // }).showAlertDialog(_context); + // } + } else { + AppToast.showErrorToast(message: 'Invalid location selected'); + } + } + + gotoRRTRoot() async { + viewModel!.setState(ViewState.Busy); + 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 new file mode 100644 index 00000000..0420bb54 --- /dev/null +++ b/lib/pages/ErService/rapid-response-team/rrt-request-page.dart @@ -0,0 +1,433 @@ +import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/GetCMCAllOrdersResponseModel.dart'; +import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/customer_addresses_service.dart'; +import 'package:diplomaticquarterapp/core/viewModels/er/rrt-view-model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/rrt/RRTProcedureList.dart'; +import 'package:diplomaticquarterapp/models/rrt/service_price.dart'; +import 'package:diplomaticquarterapp/pages/ErService/rapid-response-team/rrt-order-list-item.dart'; +import 'package:diplomaticquarterapp/pages/ErService/rapid-response-team/rrt-pickup-address-page.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/pages/medical/reports/user_agreement_page.dart'; +import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:provider/provider.dart'; + +class RRTRequestPage extends StatefulWidget { + final List pendingOrders; + final ServicePrice servicePrice; + RRTViewModel viewModel; + + RRTRequestPage({required this.pendingOrders, required this.servicePrice, required this.viewModel}); + + @override + State createState() => RRTRequestPageState(); +} + +class RRTRequestPageState extends State { + bool acceptTerms = false; + late VidaProcedureList selectedProcedure; + + ProjectViewModel? projectViewModel; + + @override + void initState() { + // getProcedureDetails(); + super.initState(); + } + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + return BaseView( + onModelReady: (vm) { + // viewModel = vm; + selectedProcedure = widget.viewModel.rrtProcedureList[0]; + }, + builder: (ctx, vm, widgetState) { + if (widget.pendingOrders.isNotEmpty) + return currentOrderContent(); + else + return requestContent(); + }, + ); + } + + Widget requestContent() { + return Column( + children: [ + Expanded( + child: ListView( + padding: EdgeInsets.symmetric(horizontal: 20, vertical: 15), + children: [ + serviceDescription(context), + SizedBox(height: 20), + Container( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ...List.generate( + widget.viewModel.rrtProcedureList.length, + (index) => Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: 1, + ), + Row( + children: [ + Expanded( + flex: 1, + child: InkWell( + onTap: () { + setState(() { + selectedProcedure = widget.viewModel.rrtProcedureList[index]; + // getPaymentInfo(context, widget.projectID.toString(), widget.selectedProcedure.procedureID); + }); + }, + child: Row( + children: [ + Radio( + value: widget.viewModel.rrtProcedureList[index], + groupValue: selectedProcedure, + activeColor: Colors.red[800], + toggleable: true, + onChanged: (value) { + setState(() { + selectedProcedure = value!; + print(selectedProcedure.procedureName); + // getPaymentInfo(context, widget.projectID.toString(), widget.selectedProcedure.procedureID); + }); + }, + ), + Expanded( + child: Text( + // projectViewModel.isArabic ? widget.proceduresList[index].procedureNameN : widget.proceduresList[index].procedureName, + widget.viewModel.rrtProcedureList[index].procedureName!, + style: TextStyle( + fontSize: 12.0, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + ), + ), + ), + ], + ), + ), + ) + ], + ), + ], + ), + ), + ], + ), + ), + priceTable(context), + acceptPolicy(), + Container(height: 0.5, color: Theme.of(context).appBarTheme.backgroundColor), // Seperator + + Container( + padding: EdgeInsets.only(top: 20, bottom: 5), + alignment: Alignment.center, + child: Text(TranslationBase.of(context).youCanPayByTheFollowingOptions, + style: TextStyle(fontSize: 13, color: Theme.of(context).appBarTheme.backgroundColor, fontWeight: FontWeight.w500), maxLines: 2)), + + Container(margin: EdgeInsets.only(left: 15.0, right: 15.0, top: 10.0), child: getPaymentMethods()) + ], + ), + ), + actionButtons() + ], + ); + } + + Widget currentOrderContent() { + var orders = widget.pendingOrders; + return ListView.builder( + itemCount: orders.length, + padding: EdgeInsets.all(21), + itemBuilder: (ctx, idx) { + var order = orders[idx]; + return RRTLogListItem(order, onCancel: deleteOrder); + }); + } + + Widget serviceDescription(BuildContext context) => Padding( + padding: const EdgeInsets.symmetric(horizontal: 10), + child: Text( + TranslationBase.of(context).rrtDDetails, + textAlign: TextAlign.justify, + style: TextStyle(fontSize: 14.0, letterSpacing: -0.64, color: CustomColors.textColor, fontWeight: FontWeight.w300), + ), + ); + + Widget priceTable(BuildContext context) { + var radius = Radius.circular(8); + String amount = selectedProcedure.patientShare.toString(); + String vat = selectedProcedure.patientTaxAmount.toString(); + String total = selectedProcedure.patientShareWithTax.toString(); + return Container( + decoration: cardRadius(12), + padding: EdgeInsets.all(12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).billAmount, + 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: Row( + children: [ + projectViewModel!.isArabic ? Container() : SvgPicture.asset("assets/images/new/Saudi_Riyal_Symbol.svg", width: 16, height: 16), + mWidth(6), + Text( + amount, + style: TextStyle( + fontSize: 12, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + ), + ), + mWidth(6), + projectViewModel!.isArabic ? SvgPicture.asset("assets/images/new/Saudi_Riyal_Symbol.svg", width: 16, height: 16) : Container(), + ], + ), + ), + ], + ), + 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: Row( + children: [ + projectViewModel!.isArabic ? Container() : SvgPicture.asset("assets/images/new/Saudi_Riyal_Symbol.svg", width: 16, height: 16), + mWidth(6), + Text( + vat, + style: TextStyle( + fontSize: 12, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + ), + ), + mWidth(6), + projectViewModel!.isArabic ? SvgPicture.asset("assets/images/new/Saudi_Riyal_Symbol.svg", width: 16, height: 16) : Container(), + ], + ), + ), + ], + ), + mHeight(4), + mDivider(CustomColors.lightGreyColor), + mHeight(4), + Row( + children: [ + Expanded( + child: Text( + TranslationBase.of(context).patientShareTotalToDo, + style: TextStyle( + fontSize: 14, + letterSpacing: -0.4, + color: CustomColors.textColor, + fontWeight: FontWeight.bold, + ), + ), + ), + Expanded( + child: Row( + children: [ + projectViewModel!.isArabic ? Container() : SvgPicture.asset("assets/images/new/Saudi_Riyal_Symbol.svg", width: 14, height: 14), + mWidth(6), + Text( + total, + style: TextStyle(fontSize: 14, letterSpacing: -0.48, fontWeight: FontWeight.bold, color: CustomColors.black), + ), + mWidth(6), + projectViewModel!.isArabic ? SvgPicture.asset("assets/images/new/Saudi_Riyal_Symbol.svg", width: 16, height: 16) : Container(), + ], + ), + ), + ], + ), + ], + ), + ); + // Column( + // crossAxisAlignment: CrossAxisAlignment.stretch, + // children: [ + // Container( + // height: 30, + // decoration: BoxDecoration(color: Theme.of(context).appBarTheme.color, borderRadius: BorderRadius.only(topLeft: radius, topRight: radius)), + // child: Center(child: Text(TranslationBase.of(context).approximateServiceFee, style: TextStyle(color: Colors.white, fontSize: 12, fontWeight: FontWeight.w500, letterSpacing: 1))), + // ), + // pricingRow(label: TranslationBase.of(context).patientShare, value: '$amount ${TranslationBase.of(context).sar}'), + // Container(height: 0.5, color: Theme.of(context).appBarTheme.color), + // pricingRow(label: TranslationBase.of(context).patientTaxToDo, value: '$vat ${TranslationBase.of(context).sar}'), + // Container(height: 0.5, color: Theme.of(context).appBarTheme.color), + // pricingRow(label: TranslationBase.of(context).patientShareWithTax, value: '$total ${TranslationBase.of(context).sar}', labelBold: true), + // Container(height: 0.5, color: Theme.of(context).appBarTheme.color), + // ], + // ); + } + + Widget pricingRow({required String label, required String value, bool labelBold = false, bool valueBold = false}) { + return Container( + height: 35, + margin: EdgeInsets.symmetric(horizontal: 10), + child: Row( + children: [ + Text(label, style: TextStyle(fontSize: 12, color: CustomColors.textColor, fontWeight: labelBold ? FontWeight.bold : FontWeight.normal)), + Spacer(), + Container( + height: 35, + color: Theme.of(context).appBarTheme.backgroundColor, + width: 0.5, + ), + Container( + alignment: Alignment.center, + width: MediaQuery.of(context).size.width * 0.25, + child: Text(value, style: TextStyle(fontSize: 12, color: CustomColors.textColor, fontWeight: valueBold ? FontWeight.bold : FontWeight.normal))), + ], + ), + ); + } + + Widget acceptPolicy() { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 10), + child: Row( + children: [ + Checkbox( + value: acceptTerms, + onChanged: (v) { + setState(() => acceptTerms = v!); + }), + SizedBox(width: 10), + Expanded(child: Text(TranslationBase.of(context).iAcceptTermsConditions, style: TextStyle(fontSize: 12, color: CustomColors.textColor), maxLines: 2)), + Container( + alignment: Alignment.center, + width: MediaQuery.of(context).size.width * 0.25, + child: TextButton( + child: Text(TranslationBase.of(context).clickHere, style: TextStyle(fontSize: 12, color: Colors.blue, fontWeight: FontWeight.w400)), + onPressed: () { + Navigator.push( + context, + FadePage( + page: UserAgreementContent(), + ), + ); + }), + ) + ], + ), + ); + } + + Widget paymentOptions() => Container( + height: 30, + alignment: Alignment.center, + child: Image.asset( + "assets/payment_options/payment_options.png", + fit: BoxFit.fill, + )); + + Widget actionButtons() { + return Container( + margin: EdgeInsets.all(15), + child: Row( + children: [ + Expanded( + child: DefaultButton( + TranslationBase.of(context).next, + () { + if (acceptTerms && selectedProcedure != null) + goToPickupAddress(); + else + AppToast.showErrorToast(message: TranslationBase.of(context).pleaseAcceptTerms); + }, + color: acceptTerms ? CustomColors.accentColor : Colors.grey, + ), + ), + ], + ), + ); + } + + getProcedureDetails() { + GifLoaderDialogUtils.showMyDialog(context); + DoctorsListService service = new DoctorsListService(); + service.getRRTProcedures(15, projectViewModel!.isArabic ? 1 : 2).then((res) { + GifLoaderDialogUtils.hideDialog(context); + print(res['Vida_ProcedureList']); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + + goToPickupAddress() async { + Navigator.push( + context, + FadePage( + page: RRTRequestPickupAddressPage( + servicePrice: widget.servicePrice, + selectedProcedure: selectedProcedure, + ))); + } + + deleteOrder(GetCMCAllOrdersResponseModel order) async { + GifLoaderDialogUtils.showMyDialog(context); + var success = await widget.viewModel.cancelOrderRC(order); + GifLoaderDialogUtils.hideDialog(context); + if (success) + setState(() { + widget.pendingOrders.remove(order); + }); + await widget.viewModel.getAllOrdersRC(); + } +} diff --git a/lib/pages/ErService/widgets/AppointmentCard.dart b/lib/pages/ErService/widgets/AppointmentCard.dart index 0437c32f..3dd13ce9 100644 --- a/lib/pages/ErService/widgets/AppointmentCard.dart +++ b/lib/pages/ErService/widgets/AppointmentCard.dart @@ -8,7 +8,7 @@ import 'package:flutter/material.dart'; class AppointmentCard extends StatelessWidget { final AppoitmentAllHistoryResultList appointment; - const AppointmentCard({Key key, this.appointment}) : super(key: key); + const AppointmentCard({Key? key, required this.appointment}) : super(key: key); @override Widget build(BuildContext context) { return Container( @@ -22,8 +22,8 @@ class AppointmentCard extends StatelessWidget { child: Row( children: [ LargeAvatar( - url: appointment.doctorImageURL, - name: appointment.doctorNameObj, + url: appointment.doctorImageURL!, + name: appointment.doctorNameObj!, ), Expanded( child: Padding( @@ -35,7 +35,7 @@ class AppointmentCard extends StatelessWidget { SizedBox(height: 4,), Texts(appointment.projectName), Texts(appointment.clinicName), - Texts(DateUtil.getMonthDayYearDateFormatted(DateUtil.convertStringToDate(appointment.bookDate))), + Texts(DateUtil.getMonthDayYearDateFormatted(DateUtil.convertStringToDate(appointment.bookDate!))), ], ), ), diff --git a/lib/pages/ErService/widgets/StepsWidget.dart b/lib/pages/ErService/widgets/StepsWidget.dart index 56b3de6b..97acd38f 100644 --- a/lib/pages/ErService/widgets/StepsWidget.dart +++ b/lib/pages/ErService/widgets/StepsWidget.dart @@ -1,5 +1,7 @@ import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -8,220 +10,335 @@ class StepsWidget extends StatelessWidget { final int index; final Function changeCurrentTab; - StepsWidget({Key key, this.index, this.changeCurrentTab}); + StepsWidget({Key? key, required this.index, required this.changeCurrentTab}); @override Widget build(BuildContext context) { - ProjectViewModel projectViewModel = Provider.of(context); - return projectViewModel.isArabic? - Stack( - children: [ - Container( - height: 50, - width: MediaQuery.of(context).size.width, - color: Colors.transparent, - child: Center( - child: Divider( - color: Colors.grey, - height: 0.75, - thickness: 0.75, + return Container( + width: double.infinity, + padding: EdgeInsets.only(left: 12, right: 12, bottom: 12), + child: Row( + children: [ + Expanded( + child: showProgress( + title: TranslationBase.of(context).transportation, + status: index == 0 + ? TranslationBase.of(context).inPrgress + : index > 0 + ? TranslationBase.of(context).completed + : TranslationBase.of(context).locked, + color: index == 0 ? CustomColors.orange : CustomColors.green, ), ), - ), - Positioned( - top: 10, - right: 0, - child: InkWell( - onTap: () => changeCurrentTab(0), - child: Container( - width: 35, - height: 35, - decoration: BoxDecoration( - border: index > 0 ? null:Border.all(color: Colors.black,width: 0.75), - shape: BoxShape.circle, - color: index == 0 ? Colors.grey[800] : index > 0 ?Colors.green: Colors.white, - ), - child: Center( - child: Texts( - '1', - color: index == 0 ? Colors.white : index > 0 ?Colors.white: Colors.grey[800], - ), - ), + Expanded( + child: showProgress( + title: TranslationBase.of(context).locationa, + status: index == 1 + ? TranslationBase.of(context).inPrgress + : index > 1 + ? TranslationBase.of(context).completed + : TranslationBase.of(context).locked, + color: index == 1 + ? CustomColors.orange + : index > 1 + ? CustomColors.green + : CustomColors.grey2, ), ), - ), - Positioned( - top: 10, - right: MediaQuery.of(context).size.width * 0.3, - child: InkWell( - onTap: () => index >= 2 ? changeCurrentTab(1) : null, - child: Container( - width: 35, - height: 35, - decoration: BoxDecoration( - border: index > 1 ? null:Border.all(color: Colors.black,width: 0.75), - shape: BoxShape.circle, - color: index == 1 ? Colors.grey[800] : index > 1 ?Colors.green: Colors.white, - ), - child: Center( - child: Texts( - '2', - color: index == 1? Colors.white : index > 1 ?Colors.white: Colors.grey[800], - ), - ), - ), + // Expanded( + // child: showProgress( + // title: TranslationBase.of(context).otherInfo, + // status: index == 2 + // ? TranslationBase.of(context).inPrgress + // : index > 2 + // ? TranslationBase.of(context).completed + // : TranslationBase.of(context).locked, + // color: index == 2 + // ? CustomColors.orange + // : index > 2 + // ? CustomColors.green + // : CustomColors.grey2, + // ), + // ), + showProgress( + title: TranslationBase.of(context).RRTSummary, + status: index == 3 ? TranslationBase.of(context).inPrgress : TranslationBase.of(context).locked, + color: index == 3 + ? CustomColors.orange + : index > 4 + ? CustomColors.green + : CustomColors.grey2, + isNeedBorder: false, ), - ), - Positioned( - top: 10, - right: MediaQuery.of(context).size.width * 0.6, - child: InkWell( - onTap: () => index >= 3 ? changeCurrentTab(2) : null, - child: Container( - width: 35, - height: 35, - decoration: BoxDecoration( - shape: BoxShape.circle, - border: index > 2 ? null:Border.all(color: Colors.black,width: 0.75), - color: index == 2 ? Colors.grey[800] : index > 1 ?Colors.green: Colors.white, - ), - child: Center( - child: Texts( - '3', - color: index == 2? Colors.white : index > 1 ?Colors.white: Colors.grey[800], - ), - ), - ), - ), - ), - Positioned( - top: 10, - left: 0, - child: InkWell( - onTap: () => index == 2 ?changeCurrentTab(3):null, - child: Container( - width: 35, - height: 35, - decoration: BoxDecoration( - border: Border.all(color: Colors.black,width: 0.75), + ], + ), + ); - shape: BoxShape.circle, - color: index == 3 ? Colors.grey[800] : Colors.white, - ), - child: Center( - child: Texts( - '4', - color: index == 3 ? Colors.white : Colors.grey[800], - ), - ), - ), - ), - ), - ], - ): - Stack( + // return projectViewModel.isArabic? + // Stack( + // children: [ + // Container( + // height: 50, + // width: MediaQuery.of(context).size.width, + // color: Colors.transparent, + // child: Center( + // child: Divider( + // color: Colors.grey, + // height: 0.75, + // thickness: 0.75, + // ), + // ), + // ), + // Positioned( + // top: 10, + // right: 0, + // child: InkWell( + // onTap: () => changeCurrentTab(0), + // child: Container( + // width: 35, + // height: 35, + // decoration: BoxDecoration( + // border: index > 0 ? null:Border.all(color: Colors.black,width: 0.75), + // shape: BoxShape.circle, + // color: index == 0 ? Colors.grey[800] : index > 0 ?Colors.green: Colors.white, + // ), + // child: Center( + // child: Texts( + // '1', + // color: index == 0 ? Colors.white : index > 0 ?Colors.white: Colors.grey[800], + // ), + // ), + // ), + // ), + // ), + // Positioned( + // top: 10, + // right: MediaQuery.of(context).size.width * 0.3, + // child: InkWell( + // onTap: () => index >= 2 ? changeCurrentTab(1) : null, + // child: Container( + // width: 35, + // height: 35, + // decoration: BoxDecoration( + // border: index > 1 ? null:Border.all(color: Colors.black,width: 0.75), + // shape: BoxShape.circle, + // color: index == 1 ? Colors.grey[800] : index > 1 ?Colors.green: Colors.white, + // ), + // child: Center( + // child: Texts( + // '2', + // color: index == 1? Colors.white : index > 1 ?Colors.white: Colors.grey[800], + // ), + // ), + // ), + // ), + // ), + // Positioned( + // top: 10, + // right: MediaQuery.of(context).size.width * 0.6, + // child: InkWell( + // onTap: () => index >= 3 ? changeCurrentTab(2) : null, + // child: Container( + // width: 35, + // height: 35, + // decoration: BoxDecoration( + // shape: BoxShape.circle, + // border: index > 2 ? null:Border.all(color: Colors.black,width: 0.75), + // color: index == 2 ? Colors.grey[800] : index > 1 ?Colors.green: Colors.white, + // ), + // child: Center( + // child: Texts( + // '3', + // color: index == 2? Colors.white : index > 1 ?Colors.white: Colors.grey[800], + // ), + // ), + // ), + // ), + // ), + // Positioned( + // top: 10, + // left: 0, + // child: InkWell( + // onTap: () => index == 2 ?changeCurrentTab(3):null, + // child: Container( + // width: 35, + // height: 35, + // decoration: BoxDecoration( + // border: Border.all(color: Colors.black,width: 0.75), + // + // shape: BoxShape.circle, + // color: index == 3 ? Colors.grey[800] : Colors.white, + // ), + // child: Center( + // child: Texts( + // '4', + // color: index == 3 ? Colors.white : Colors.grey[800], + // ), + // ), + // ), + // ), + // ), + // ], + // ): + // Stack( + // children: [ + // Container( + // height: 50, + // width: MediaQuery.of(context).size.width, + // color: Colors.transparent, + // child: Center( + // child: Divider( + // color: Colors.grey, + // height: 0.75, + // thickness: 0.75, + // ), + // ), + // ), + // Positioned( + // top: 10, + // left: 0, + // child: InkWell( + // onTap: () => changeCurrentTab(0), + // child: Container( + // width: 35, + // height: 35, + // decoration: BoxDecoration( + // border: index > 0 ? null:Border.all(color: Colors.black,width: 0.75), + // shape: BoxShape.circle, + // color: index == 0 ? Colors.grey[800] : index > 0 ?Colors.green: Colors.white, + // ), + // child: Center( + // child: Texts( + // '1', + // color: index == 0 ? Colors.white : index > 0 ?Colors.white: Colors.grey[800], + // ), + // ), + // ), + // ), + // ), + // Positioned( + // top: 10, + // left: MediaQuery.of(context).size.width * 0.3, + // child: InkWell( + // onTap: () => index >= 2 ? changeCurrentTab(1) : null, + // child: Container( + // width: 35, + // height: 35, + // decoration: BoxDecoration( + // border: index > 1 ? null:Border.all(color: Colors.black,width: 0.75), + // shape: BoxShape.circle, + // color: index == 1 ? Colors.grey[800] : index > 1 ?Colors.green: Colors.white, + // ), + // child: Center( + // child: Texts( + // '2', + // color: index == 1? Colors.white : index > 1 ?Colors.white: Colors.grey[800], + // ), + // ), + // ), + // ), + // ), + // Positioned( + // top: 10, + // left: MediaQuery.of(context).size.width * 0.6, + // child: InkWell( + // onTap: () => index >= 3 ? changeCurrentTab(2) : null, + // child: Container( + // width: 35, + // height: 35, + // decoration: BoxDecoration( + // shape: BoxShape.circle, + // border: index > 2 ? null:Border.all(color: Colors.black,width: 0.75), + // color: index == 2 ? Colors.grey[800] : index > 1 ?Colors.green: Colors.white, + // ), + // child: Center( + // child: Texts( + // '3', + // color: index == 2? Colors.white : index > 1 ?Colors.white: Colors.grey[800], + // ), + // ), + // ), + // ), + // ), + // Positioned( + // top: 10, + // right: 0, + // child: InkWell( + // onTap: () => index == 2 ?changeCurrentTab(3):null, + // child: Container( + // width: 35, + // height: 35, + // decoration: BoxDecoration( + // border: Border.all(color: Colors.black,width: 0.75), + // + // shape: BoxShape.circle, + // color: index == 3 ? Colors.grey[800] : Colors.white, + // ), + // child: Center( + // child: Texts( + // '4', + // color: index == 3 ? Colors.white : Colors.grey[800], + // ), + // ), + // ), + // ), + // ), + // ], + // ); + } + + Widget showProgress({required String title, required String status, required Color color, bool isNeedBorder = true}) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Container( - height: 50, - width: MediaQuery.of(context).size.width, - color: Colors.transparent, - child: Center( - child: Divider( - color: Colors.grey, - height: 0.75, - thickness: 0.75, - ), - ), - ), - Positioned( - top: 10, - left: 0, - child: InkWell( - onTap: () => changeCurrentTab(0), - child: Container( - width: 35, - height: 35, - decoration: BoxDecoration( - border: index > 0 ? null:Border.all(color: Colors.black,width: 0.75), - shape: BoxShape.circle, - color: index == 0 ? Colors.grey[800] : index > 0 ?Colors.green: Colors.white, - ), - child: Center( - child: Texts( - '1', - color: index == 0 ? Colors.white : index > 0 ?Colors.white: Colors.grey[800], + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Container( + width: 26, + height: 26, + decoration: containerRadius(color, 200), + child: Icon( + Icons.done, + color: Colors.white, + size: 16, + ), ), - ), + if (isNeedBorder) + Expanded( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: mDivider(Colors.grey), + )), + ], ), - ), - ), - Positioned( - top: 10, - left: MediaQuery.of(context).size.width * 0.3, - child: InkWell( - onTap: () => index >= 2 ? changeCurrentTab(1) : null, - child: Container( - width: 35, - height: 35, - decoration: BoxDecoration( - border: index > 1 ? null:Border.all(color: Colors.black,width: 0.75), - shape: BoxShape.circle, - color: index == 1 ? Colors.grey[800] : index > 1 ?Colors.green: Colors.white, - ), - child: Center( - child: Texts( - '2', - color: index == 1? Colors.white : index > 1 ?Colors.white: Colors.grey[800], - ), + mHeight(8), + Text( + title, + style: TextStyle( + fontSize: 11, + fontWeight: FontWeight.w600, + letterSpacing: -0.44, ), ), - ), - ), - Positioned( - top: 10, - left: MediaQuery.of(context).size.width * 0.6, - child: InkWell( - onTap: () => index >= 3 ? changeCurrentTab(2) : null, - child: Container( - width: 35, - height: 35, - decoration: BoxDecoration( - shape: BoxShape.circle, - border: index > 2 ? null:Border.all(color: Colors.black,width: 0.75), - color: index == 2 ? Colors.grey[800] : index > 1 ?Colors.green: Colors.white, - ), - child: Center( - child: Texts( - '3', - color: index == 2? Colors.white : index > 1 ?Colors.white: Colors.grey[800], + mHeight(2), + Container( + padding: EdgeInsets.all(5), + decoration: containerRadius(color.withOpacity(0.2), 4), + child: Text( + status, + style: TextStyle( + fontSize: 8, + fontWeight: FontWeight.w600, + letterSpacing: -0.32, + color: color, ), ), ), - ), - ), - Positioned( - top: 10, - right: 0, - child: InkWell( - onTap: () => index == 2 ?changeCurrentTab(3):null, - child: Container( - width: 35, - height: 35, - decoration: BoxDecoration( - border: Border.all(color: Colors.black,width: 0.75), - - shape: BoxShape.circle, - color: index == 3 ? Colors.grey[800] : Colors.white, - ), - child: Center( - child: Texts( - '4', - color: index == 3 ? Colors.white : Colors.grey[800], - ), - ), - ), - ), - ), + ], + ) ], ); } diff --git a/lib/pages/ErService/widgets/card_common.dart b/lib/pages/ErService/widgets/card_common.dart deleted file mode 100644 index 6b396dc9..00000000 --- a/lib/pages/ErService/widgets/card_common.dart +++ /dev/null @@ -1,60 +0,0 @@ -//import 'package:diplomaticquarterapp/pages/BookAppointment/Search.dart'; -import 'package:diplomaticquarterapp/pages/BookAppointment/Search.dart'; -import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; -import 'package:flutter/material.dart'; - -import '../AmbulanceReq.dart'; -import '../NearestEr.dart'; - -class CardCommonEr extends StatelessWidget { - final image; - final text; - final subText; - - final Function onTap; - const CardCommonEr( - {@required this.image, - @required this.text, - @required this.subText, - @required this.onTap}); - - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: () => onTap(), - child: Container( - margin: EdgeInsets.fromLTRB(9.0, 9.0, 9.0, 9.0), - decoration: BoxDecoration(boxShadow: [ - BoxShadow(color: Colors.grey[400], blurRadius: 2.0, spreadRadius: 0.0) - ], borderRadius: BorderRadius.circular(10), color: Colors.white), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - margin: EdgeInsets.fromLTRB(10.0, 10.0, 10.0, 0.0), - child: Text(this.text, - overflow: TextOverflow.clip, - style: TextStyle( - color: new Color(0xFFc5272d), - letterSpacing: 1.0, - fontSize: 20.0)), - ), - Container( - margin: EdgeInsets.fromLTRB(10.0, 0.0, 10.0, 0.0), - child: Text(this.subText, - overflow: TextOverflow.clip, - style: TextStyle( - color: Colors.black, letterSpacing: 1.0, fontSize: 15.0)), - ), - Container( - alignment: Alignment.bottomRight, - margin: EdgeInsets.fromLTRB(0.0, 0.0, 10.0, 8.0), - child: Image.asset(this.image, width: 60.0, height: 60.0), - ), - ], - ), - ), - ); - } - -} diff --git a/lib/pages/ErService/widgets/card_position.dart b/lib/pages/ErService/widgets/card_position.dart deleted file mode 100644 index 69ccaffe..00000000 --- a/lib/pages/ErService/widgets/card_position.dart +++ /dev/null @@ -1,113 +0,0 @@ -//import 'package:diplomaticquarterapp/pages/BookAppointment/Search.dart'; -import 'package:diplomaticquarterapp/config/size_config.dart'; -import 'package:diplomaticquarterapp/pages/BookAppointment/Search.dart'; -import 'package:flutter/material.dart'; -import 'package:giffy_dialog/giffy_dialog.dart'; -import 'package:url_launcher/url_launcher.dart'; -import 'package:maps_launcher/maps_launcher.dart'; - - -import '../NearestEr.dart'; - -class CardPosition extends StatelessWidget { - final image; - final text; - final subText; - final type; - final telephone; - final networkImage; - final latitude; - final longitude; - final projectname; - final cardSize; - - const CardPosition( - { - @required this.image, - @required this.text, - @required this.subText, - @required this.type, - @required this.telephone, - @required this.networkImage , - @required this.latitude, - @required this.longitude, - @required this.projectname , - @required this.cardSize , - }); - - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: () { - navigateToSearch(context, this.type,this.telephone,this.networkImage,this.latitude,this.longitude,this.projectname); - - }, - child: Container( - // width:MediaQuery.of(context).size.width * 0.47,//165, - margin: EdgeInsets.fromLTRB(8.0, 8.0, 8.0, 8.0), - decoration: BoxDecoration(boxShadow: [ - BoxShadow(color: Colors.grey[400], blurRadius: 2.0, spreadRadius: 0.0) - ], borderRadius: BorderRadius.circular(10), color: Colors.white), - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Container( - height: cardSize * 0.2 - 8, - margin: EdgeInsets.fromLTRB(8.0, 8.0, 8.0, 0.0), - child: Text(this.text, - overflow: TextOverflow.clip, - style: TextStyle( - color: Colors.black, - letterSpacing: 1.0, - fontSize: 2 * SizeConfig.textMultiplier)), - ), - Container( - height: cardSize * 0.5 - 8, - alignment: Alignment.center, - margin: EdgeInsets.fromLTRB(0.0, 0.0, 8.0, 8.0), - child: Image.asset(this.image, width: 60.0, height: cardSize * 0.4), - ), - Container( - margin: EdgeInsets.fromLTRB(8.0, 0.0, 8.0, 0.0), - height: cardSize * 0.2 - 8, - child: Text(this.subText, - overflow: TextOverflow.clip, - style: TextStyle( - color: Color(0xFFc5272d), letterSpacing: 1.0, fontSize: 15.0)), - ), - - ], - ), - ), - ); - } - - Future navigateToSearch(context, type,telephone,networkImage,latitude,longitude,projectname) async { - - - - - showDialog( - context: context,builder: (_) => AssetGiffyDialog( - title: Text(projectname, - style: TextStyle( - fontSize: 22.0, fontWeight: FontWeight.w600), - ),image:Image.network(networkImage, fit: BoxFit.cover,), - - buttonOkText:Text("LOCATION"), - buttonOkColor: Colors.grey, - buttonCancelText:Text('CAll') , - buttonCancelColor: Colors.grey, - onOkButtonPressed: () { MapsLauncher.launchCoordinates(double.parse(latitude),double.parse(longitude),projectname);}, - onCancelButtonPressed :() {launch("tel://" +telephone);} - - - - - ) ); - - } - - } - - diff --git a/lib/pages/InPatientServices/admission_notice.dart b/lib/pages/InPatientServices/admission_notice.dart new file mode 100644 index 00000000..313d4551 --- /dev/null +++ b/lib/pages/InPatientServices/admission_notice.dart @@ -0,0 +1,218 @@ +import 'package:auto_size_text/auto_size_text.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/custom_text_button.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/medical/medical_profile_item.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class AdmissionNotice extends StatefulWidget { + const AdmissionNotice(); + + @override + State createState() => _AdmissionNoticeState(); +} + +class _AdmissionNoticeState extends State { + late ProjectViewModel projectViewModel; + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + List inPatientServiceList = getAdmissionNoticeServicesList(context); + return AppScaffold( + isShowAppBar: true, + isShowDecPage: false, + showNewAppBarTitle: true, + showNewAppBar: true, + appBarTitle: TranslationBase.of(context).admissionNoticeTitle, + body: Container( + margin: EdgeInsets.all(20.0), + child: Column( + children: [ + Padding( + padding: EdgeInsets.only(left: 12, right: 12), + child: GridView.builder( + shrinkWrap: true, + primary: false, + physics: NeverScrollableScrollPhysics(), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, childAspectRatio: 2 / 2, crossAxisSpacing: 12, mainAxisSpacing: 12), + padding: EdgeInsets.zero, + itemCount: inPatientServiceList.length, + itemBuilder: (BuildContext context, int index) { + return inPatientServiceList[index]; + }, + ), + ), + ], + ), + ), + ); + } + + List getAdmissionNoticeServicesList(BuildContext context) { + List serviceList = []; + + serviceList.add( + InkWell( + onTap: () { + // openBirthNotificationsPage(context); + viewModalBottomSheet(); + }, + child: MedicalProfileItem( + title: TranslationBase.of(context).admissionNoticeTitle, + imagePath: 'admission.svg', + subTitle: TranslationBase.of(context).insuranceSubtitle, + width: 50.0, + height: 40.0, + isInPatient: true, + ), + ), + ); + + return serviceList; + } + + void viewModalBottomSheet() { + showModalBottomSheet( + context: context, + builder: (context) { + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: const EdgeInsets.only(left: 20, right: 20, top: 20), + child: Text( + "Admission Card", + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold, + fontSize: 21, + letterSpacing: -0.25, + height: 25 / 17, + ), + ), + ), + Container( + padding: EdgeInsets.all(16.0), + height: 250, + child: Container( + decoration: cardRadius(20, color: Color(0xFFF2B353E)), + clipBehavior: Clip.antiAlias, + margin: EdgeInsets.zero, + child: Container( + width: double.infinity, + height: double.infinity, + clipBehavior: Clip.antiAlias, + margin: EdgeInsets.zero, + decoration: projectViewModel.isArabic + ? containerBottomRightRadiusWithGradientForAr(MediaQuery.of(context).size.width / 4) + : containerBottomRightRadiusWithGradient(MediaQuery.of(context).size.width / 4), + child: Card( + color: Colors.transparent, + margin: EdgeInsets.zero, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + mFlex(2), + Padding( + padding: const EdgeInsets.only(left: 20, right: 20), + child: Text( + projectViewModel.authenticatedUserObject.user.firstName! + " " + projectViewModel.authenticatedUserObject.user.lastName!, + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 17, + letterSpacing: -0.25, + height: 25 / 17, + ), + ), + ), + Padding( + padding: const EdgeInsets.only(left: 20, right: 20), + child: Text( + TranslationBase.of(context).roomNo + " " + (projectViewModel.isPatientAdmitted ? projectViewModel.getAdmissionInfoResponseModel.roomID! : "Not assigned yet"), + style: TextStyle( + color: Colors.white, + fontSize: 15, + letterSpacing: -0.25, + height: 25 / 17, + ), + ), + ), + mFlex(2), + Padding( + padding: const EdgeInsets.only(left: 20, right: 20), + child: Text( + projectViewModel.isPatientAdmitted + ? projectViewModel.getAdmissionInfoResponseModel.doctorName ?? "" + : projectViewModel.getAdmissionRequestInfoResponseModel.doctorName ?? "", + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 17, + letterSpacing: -0.25, + height: 25 / 17, + ), + ), + ), + // mFlex(2), + Padding( + padding: const EdgeInsets.only(left: 20, right: 20), + child: Text( + TranslationBase.of(context).clinic + + ": " + + (projectViewModel.isPatientAdmitted + ? projectViewModel.getAdmissionInfoResponseModel.clinicName!.toString() + : projectViewModel.getAdmissionRequestInfoResponseModel.clinicName!), + style: TextStyle( + color: Colors.white, + fontSize: 15, + letterSpacing: -0.25, + height: 25 / 17, + ), + ), + ), + Padding( + padding: const EdgeInsets.only(left: 20, right: 20), + child: Text( + TranslationBase.of(context).hospital + + ": " + + (projectViewModel.isPatientAdmitted + ? projectViewModel.getAdmissionInfoResponseModel.projectName!.toString() + : projectViewModel.getAdmissionRequestInfoResponseModel.projectName!), + style: TextStyle( + color: Colors.white, + fontSize: 15, + letterSpacing: -0.25, + height: 25 / 17, + ), + ), + ), + mFlex(1), + ], + ), + ), + ), + ), + ), + Padding( + padding: const EdgeInsets.only(left: 20, right: 20, bottom: 30), + child: DefaultButton( + TranslationBase.of(context).close.toUpperCase(), + () { + Navigator.pop(context); + }, + color: CustomColors.accentColor, + disabledColor: CustomColors.grey2, + ), + ), + ], + ); + }); + } +} diff --git a/lib/pages/InPatientServices/birth_notification.dart b/lib/pages/InPatientServices/birth_notification.dart new file mode 100644 index 00000000..6d8e60c5 --- /dev/null +++ b/lib/pages/InPatientServices/birth_notification.dart @@ -0,0 +1,305 @@ +import 'dart:convert'; + +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/pages/insurance/AttachInsuranceCardImageDialog.dart'; +import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class BirthNotification extends StatefulWidget { + const BirthNotification({Key? key}) : super(key: key); + + @override + State createState() => _BirthNotificationState(); +} + +class _BirthNotificationState extends State { + TextEditingController motherMRN = new TextEditingController(); + TextEditingController motherName = new TextEditingController(); + TextEditingController fatherName = new TextEditingController(); + TextEditingController fatherNameAR = new TextEditingController(); + TextEditingController babyName = new TextEditingController(); + TextEditingController babyNameAR = new TextEditingController(); + TextEditingController contactNumber = new TextEditingController(); + + late ProjectViewModel projectViewModel; + + List images = []; + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + motherMRN.text = projectViewModel.user.patientID.toString(); + motherName.text = projectViewModel.user.firstName! + " " + projectViewModel.user.lastName!; + contactNumber.text = projectViewModel.user.mobileNumber!; + return AppScaffold( + isShowAppBar: true, + isShowDecPage: false, + showNewAppBarTitle: true, + showNewAppBar: true, + appBarTitle: TranslationBase.of(context).birthNotificationTitle + " " + TranslationBase.of(context).birthNotificationSubTitle, + body: SingleChildScrollView( + child: Container( + width: MediaQuery.of(context).size.width, + decoration: containerRadius(Colors.white, 12), + margin: EdgeInsets.all(21.0), + padding: const EdgeInsets.all(21.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).enterDetailBelow + " :", + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + mHeight(16), + inputWidget(TranslationBase.of(context).mothersMRN, "", motherMRN, isEnable: false), + mHeight(16), + inputWidget(TranslationBase.of(context).mothersName, "", motherName, isEnable: false), + mHeight(16), + inputWidget(TranslationBase.of(context).fathersNameEN, "", fatherName), + mHeight(16), + inputWidget(TranslationBase.of(context).fathersNameAR, "", fatherNameAR), + mHeight(16), + inputWidget(TranslationBase.of(context).babysNameEN, "", babyName), + mHeight(16), + inputWidget(TranslationBase.of(context).babysNameAR, "", babyNameAR), + mHeight(16), + inputWidget(TranslationBase.of(context).contactNumber, "", contactNumber), + mHeight(16), + DefaultButton( + TranslationBase.of(context).scanID, + () { + confirmAttachInsuranceCardImageDialogDialog( + context: context, name: projectViewModel.user.firstName! + " " + projectViewModel.user.lastName!, fileNo: projectViewModel.user.patientID.toString()); + }, + color: CustomColors.accentColor, + disabledColor: CustomColors.grey2, + ), + if (images.isNotEmpty) mHeight(16), + if (images.isNotEmpty) + Padding( + padding: const EdgeInsets.only(top: 16.0, bottom: 16.0), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Image.memory( + base64Decode(images[0]), + width: 80.0, + height: 80.0, + fit: BoxFit.cover, + ), + Text( + "image 1.png", + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + InkWell( + onTap: () { + setState(() { + images.clear(); + }); + }, + child: Icon( + Icons.delete_sharp, + color: Colors.red[300], + ), + ) + ], + ), + ), + mHeight(16), + Text( + "● " + TranslationBase.of(context).birthNotificationNotes1, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + mHeight(16), + Text( + "● " + TranslationBase.of(context).birthNotificationNotes2, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + mHeight(16), + Text( + "● " + TranslationBase.of(context).birthNotificationNotes3, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + mHeight(100.0), + // DefaultButton( + // TranslationBase.of(context).submit, + // (fatherNameAR.text.isEmpty || fatherName.text.isEmpty || babyNameAR.text.isEmpty || babyName.text.isEmpty) ? null : () { + // submitBirthNotification(); + // }, + // color: CustomColors.accentColor, + // disabledColor: CustomColors.grey2, + // ), + ], + ), + ), + ), + bottomSheet: Container( + color: Colors.white, + width: double.infinity, + padding: EdgeInsets.all(20), + child: DefaultButton( + TranslationBase.of(context).submit, + (fatherNameAR.text.isEmpty || fatherName.text.isEmpty || babyNameAR.text.isEmpty || babyName.text.isEmpty || images.isEmpty) + ? null + : () { + submitBirthNotification(); + }, + color: CustomColors.accentColor, + disabledColor: CustomColors.grey2, + ), + ), + ); + } + + void submitBirthNotification() { + ClinicListService service = new ClinicListService(); + GifLoaderDialogUtils.showMyDialog(context); + service + .submitBirthNotification( + projectViewModel.user.patientID!, projectViewModel.inPatientProjectID, fatherNameAR.text, fatherName.text, babyNameAR.text, babyName.text, contactNumber.text, images[0], context) + .then((res) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showSuccessToast(message: TranslationBase.of(context).processDoneSuccessfully); + Navigator.of(context).pop(); + }).catchError((err) { + print(err); + }); + } + + void confirmAttachInsuranceCardImageDialogDialog({required BuildContext context, required String name, required String fileNo}) { + showDialog( + context: context, + builder: (cxt) => AttachInsuranceCardImageDialog( + fileNo: fileNo, + name: name, + image: (file, image) async { + images.clear(); + images.add(image); + setState(() {}); + }, + isBirthNotification: true, + ), + ); + } + + 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(12), + 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: TextInputType.name, + 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, + hintStyle: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: Color(0xff575757), + 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/InPatientServices/components/inpatient_paid_advance_payment.dart b/lib/pages/InPatientServices/components/inpatient_paid_advance_payment.dart new file mode 100644 index 00000000..1d9755fb --- /dev/null +++ b/lib/pages/InPatientServices/components/inpatient_paid_advance_payment.dart @@ -0,0 +1,107 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/InPatientServices/get_inpatient_advance_history_response_model.dart'; +import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.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'; +import 'package:diplomaticquarterapp/widgets/my_rich_text.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class InPatientPaidAdvancePayment extends StatefulWidget { + const InPatientPaidAdvancePayment({Key? key}) : super(key: key); + + @override + State createState() => _InPatientPaidAdvancePaymentState(); +} + +class _InPatientPaidAdvancePaymentState extends State { + late ProjectViewModel projectViewModel; + InPatientAdvanceHistoryResponseModel inPatientAdvanceHistoryResponseModel = InPatientAdvanceHistoryResponseModel(); + + @override + void initState() { + super.initState(); + WidgetsBinding.instance.addPostFrameCallback((_) { + getInPatientAdvancePaymentHistory(); + }); + } + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + return Padding( + padding: const EdgeInsets.all(16.0), + child: inPatientAdvanceHistoryResponseModel != null && inPatientAdvanceHistoryResponseModel.responseInpatientAdvanceInfo != null + ? ListView.separated( + itemCount: inPatientAdvanceHistoryResponseModel.responseInpatientAdvanceInfo!.length, + itemBuilder: (BuildContext context, int index) { + return Container( + decoration: cardRadius(12), + padding: EdgeInsets.all(12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + MyRichText( + TranslationBase.of(context).admissionNo + ": ", inPatientAdvanceHistoryResponseModel.responseInpatientAdvanceInfo![index].admissionNo.toString(), projectViewModel.isArabic), + MyRichText(TranslationBase.of(context).admissionReqNo + ": ", inPatientAdvanceHistoryResponseModel.responseInpatientAdvanceInfo![index].admissionReqNo.toString(), + projectViewModel.isArabic), + MyRichText( + TranslationBase.of(context).date + ": ", + DateUtil.formatDateToDate(DateUtil.convertStringToDate(inPatientAdvanceHistoryResponseModel.responseInpatientAdvanceInfo![index].createdOn), false), + projectViewModel.isArabic), + MyRichText( + TranslationBase.of(context).amount_ + ": ", inPatientAdvanceHistoryResponseModel.responseInpatientAdvanceInfo![index].requestedAmount.toString(), projectViewModel.isArabic), + MyRichText(TranslationBase.of(context).status + ": ", getStatus(inPatientAdvanceHistoryResponseModel.responseInpatientAdvanceInfo![index]), projectViewModel.isArabic), + ], + ), + ); + }, + separatorBuilder: (BuildContext context, int index) { + return SizedBox( + height: 12.0, + ); + }, + ) + : getNoDataWidget(context), + ); + } + + String getStatus(ResponseInpatientAdvanceInfo responseInpatientAdvanceInfo) { + switch (responseInpatientAdvanceInfo.status) { + case 1: + return "Hold"; + break; + case 2: + return "Active"; + break; + case 4: + return "Cancelled"; + break; + default: + return ""; + } + } + + void getInPatientAdvancePaymentHistory() { + ClinicListService service = new ClinicListService(); + GifLoaderDialogUtils.showMyDialog(context); + service + .getInPatientAdvancePaymentHistory( + projectViewModel.inPatientProjectID, + projectViewModel.isPatientAdmitted ? projectViewModel.getAdmissionInfoResponseModel.admissionNo! : 0, + projectViewModel.isPatientAdmitted ? projectViewModel.getAdmissionInfoResponseModel.admissionRequestNo! : projectViewModel.getAdmissionRequestInfoResponseModel.admissionRequestNo!, + context) + .then((res) { + GifLoaderDialogUtils.hideDialog(context); + inPatientAdvanceHistoryResponseModel = InPatientAdvanceHistoryResponseModel.fromJson(res["responseInpatient"]); + setState(() {}); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } + +} diff --git a/lib/pages/InPatientServices/components/inpatient_pending_advance_payment.dart b/lib/pages/InPatientServices/components/inpatient_pending_advance_payment.dart new file mode 100644 index 00000000..9df2c92f --- /dev/null +++ b/lib/pages/InPatientServices/components/inpatient_pending_advance_payment.dart @@ -0,0 +1,297 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/InPatientServices/get_inpatient_advance_requests_response_model.dart'; +import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:provider/provider.dart'; +import 'package:share_plus/share_plus.dart'; +import 'package:url_launcher/url_launcher.dart'; + +class InPatientPendingAdvancePayment extends StatefulWidget { + InPatientAdvanceResponseModel inPatientAdvanceResponseModel; + bool isHasData; + + InPatientPendingAdvancePayment({required this.isHasData, required this.inPatientAdvanceResponseModel}); + + @override + State createState() => _InPatientPendingAdvancePaymentState(); +} + +class _InPatientPendingAdvancePaymentState extends State { + late ProjectViewModel projectViewModel; + InAppBrowser browser = new InAppBrowser(); + + var _InAppBrowserOptions = InAppBrowserClassOptions( + inAppWebViewGroupOptions: InAppWebViewGroupOptions( + crossPlatform: InAppWebViewOptions(useShouldOverrideUrlLoading: true, transparentBackground: false), + ios: IOSInAppWebViewOptions(applePayAPIEnabled: true, isFraudulentWebsiteWarningEnabled: false)), + crossPlatform: InAppBrowserOptions(hideUrlBar: true, toolbarTopBackgroundColor: Colors.white), + android: AndroidInAppBrowserOptions(), + ios: + IOSInAppBrowserOptions(hideToolbarBottom: true, toolbarBottomBackgroundColor: Colors.white, closeButtonColor: Colors.white, presentationStyle: IOSUIModalPresentationStyle.OVER_FULL_SCREEN)); + + @override + void initState() { + // browser = new InAppBrowser(onLoadStartCallback: onBrowserLoadStart); + super.initState(); + } + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + return Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: double.infinity, + child: Container( + decoration: cardRadius(12), + margin: EdgeInsets.zero, + child: Padding( + padding: const EdgeInsets.all(12.0), + child: widget.isHasData && widget.inPatientAdvanceResponseModel!.responseInpatientAdvanceInfo != null + ? Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Payment request for: ", + // TranslationBase.of(context).covidBookAppo, + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 16, + letterSpacing: -0.64, + ), + ), + mHeight(6), + Row( + children: [ + Text( + TranslationBase.of(context).patientName + ":", + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 10, + letterSpacing: -0.6, + color: CustomColors.grey, + ), + ), + mWidth(3), + Text( + projectViewModel.user.firstName! + " " + projectViewModel.user.lastName!, + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 12, + letterSpacing: -0.48, + ), + ), + ], + ), + Row( + children: [ + Text( + TranslationBase.of(context).identificationNumber + ":", + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 10, + letterSpacing: -0.6, + color: CustomColors.grey, + ), + ), + mWidth(3), + Text( + projectViewModel.user.patientIdentificationNo!, + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 12, + letterSpacing: -0.48, + ), + ), + ], + ), + Row( + children: [ + Text( + TranslationBase.of(context).mrn + ":", + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 10, + letterSpacing: -0.6, + color: CustomColors.grey, + ), + ), + mWidth(3), + Text( + projectViewModel.user.patientID.toString(), + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 12, + letterSpacing: -0.48, + ), + ), + ], + ), + ], + ) + : getNoDataWidget(context), + ), + ), + ), + mHeight(12), + // Expanded(child: Container()), + widget.isHasData + ? Container( + decoration: cardRadius(12.0), + margin: EdgeInsets.zero, + padding: EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + TranslationBase.of(context).patientShareTotalToDo, + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 16, + letterSpacing: -0.64, + ), + ), + Row( + children: [ + SvgPicture.asset("assets/images/new/Saudi_Riyal_Symbol.svg", width: 16, height: 16), + mWidth(6), + Text( + "${widget.inPatientAdvanceResponseModel.responseInpatientAdvanceInfo![0].requestedAmount}", + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 24, + letterSpacing: -0.64, + ), + ), + ], + ), + ], + ), + SizedBox(height: 12), + Text( + TranslationBase.of(context).YouCanPayByTheFollowingOptions, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + SizedBox(height: 12), + SizedBox( + width: MediaQuery.of(context).size.width * 0.75, + child: getPaymentMethods(), + ), + SizedBox(height: 12), + DefaultButton( + TranslationBase.of(context).payNow.toUpperCase(), + () { + getInPatientPaymentLink(false); + }, + // : null, + color: CustomColors.green, + disabledColor: CustomColors.grey2, + ), + SizedBox(height: 12), + Text( + TranslationBase.of(context).copyLinkTxt, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + SizedBox(height: 12), + DefaultButton( + TranslationBase.of(context).copyLink.toUpperCase(), + () { + getInPatientPaymentLink(true); + }, + svgIcon: "assets/images/new/copy.svg", + color: CustomColors.accentColor, + disabledColor: CustomColors.grey2, + ), + ], + ), + ) + : Container(), + ], + ), + ); + } + + onBrowserLoadStart(String url) { + MyInAppBrowser.successURLS.forEach((element) { + if (url.contains(element)) { + if (browser.isOpened()) browser.close(); + MyInAppBrowser.isPaymentDone = true; + return; + } + }); + + MyInAppBrowser.errorURLS.forEach((element) { + if (url.contains(element)) { + if (browser.isOpened()) browser.close(); + MyInAppBrowser.isPaymentDone = false; + return; + } + }); + } + + void getInPatientPaymentLink(bool isCopy) { + ClinicListService service = new ClinicListService(); + GifLoaderDialogUtils.showMyDialog(context); + int orderID = int.parse(DateTime.now().microsecondsSinceEpoch.toString().substring(7, 15)); + int clinicID = projectViewModel.isPatientAdmitted ? projectViewModel.getAdmissionInfoResponseModel.clinicID! : 17; + service + .getInPatientPaymentLink( + widget.inPatientAdvanceResponseModel.responseInpatientAdvanceInfo![0].paymentRequestID!, + projectViewModel.inPatientProjectID, + // projectViewModel.getAdmissionInfoResponseModel.admissionNo!, + projectViewModel.isPatientAdmitted ? projectViewModel.getAdmissionInfoResponseModel.admissionRequestNo! : projectViewModel.getAdmissionRequestInfoResponseModel.admissionRequestNo!, + orderID, + projectViewModel.user.firstName! + " " + projectViewModel.user.lastName!, + projectViewModel.user.emailAddress!, + widget.inPatientAdvanceResponseModel.responseInpatientAdvanceInfo![0].requestedAmount!, + projectViewModel.user.patientIdentificationNo!, + clinicID, + widget.inPatientAdvanceResponseModel.responseInpatientAdvanceInfo![0].paymentRequestID!, + ) + .then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res["MessageStatus"] == 1) { + String paymentLink = res["PaymentUrl"]; + print(paymentLink); + if (isCopy) { + Share.share(paymentLink); + } else { + Uri uri = Uri.parse(paymentLink); + launchUrl(uri, mode: LaunchMode.externalApplication); + // this.browser.openUrlRequest(urlRequest: URLRequest(url: WebUri.uri(Uri.parse(paymentLink))), options: _InAppBrowserOptions); + } + } else { + AppToast.showErrorToast(message: res["endUserMessage"]); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } +} diff --git a/lib/pages/InPatientServices/general_instructions.dart b/lib/pages/InPatientServices/general_instructions.dart new file mode 100644 index 00000000..5837b167 --- /dev/null +++ b/lib/pages/InPatientServices/general_instructions.dart @@ -0,0 +1,93 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/InPatientServices/get_general_instructions_response_model.dart'; +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'; +import 'package:provider/provider.dart'; + +class GeneralInstructions extends StatelessWidget { + List getGeneralInstructionsList; + late ProjectViewModel projectViewModel; + + GeneralInstructions({required this.getGeneralInstructionsList}); + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + return AppScaffold( + isShowAppBar: true, + isShowDecPage: false, + showNewAppBarTitle: true, + showNewAppBar: true, + appBarTitle: TranslationBase.of(context).InPatientServicesHeader, + body: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: const EdgeInsets.all(21.0), + child: Text(TranslationBase.of(context).generalInstructions, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 21.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + )), + ), + Expanded( + child: Container( + width: MediaQuery.of(context).size.width, + child: Card( + elevation: 0.0, + margin: EdgeInsets.only(left: 16.0, right: 16.0, bottom: 16.0), + color: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + side: BorderSide(color: Colors.transparent, width: 0.0), + ), + child: Padding( + padding: EdgeInsets.all(16.0), + child: Container( + child: ListView.separated( + itemCount: getGeneralInstructionsList.length, + itemBuilder: (BuildContext context, int index) { + return Container( + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + child: SvgPicture.asset("assets/images/new-design/ionic-ios-checkmark-circle.svg"), + ), + Container( + width: MediaQuery.of(context).size.width * 0.75, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text(projectViewModel.isArabic ? getGeneralInstructionsList[index].textN! : getGeneralInstructionsList[index].text!, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + )), + ), + ], + )); + }, + separatorBuilder: (BuildContext context, int index) { + return Padding( + padding: const EdgeInsets.only(left: 14, right: 14), + child: mHeight(16.0), + ); + }, + )), + ), + ), + ), + ) + ], + )); + } +} diff --git a/lib/pages/InPatientServices/help_PRO.dart b/lib/pages/InPatientServices/help_PRO.dart new file mode 100644 index 00000000..61bd03c8 --- /dev/null +++ b/lib/pages/InPatientServices/help_PRO.dart @@ -0,0 +1,174 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.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'; +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:provider/provider.dart'; + +class HelpPRO extends StatefulWidget { + const HelpPRO({Key? key}) : super(key: key); + + @override + State createState() => _HelpPROState(); +} + +class _HelpPROState extends State { + TextEditingController assistText = new TextEditingController(); + late ProjectViewModel projectViewModel; + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + return AppScaffold( + isShowAppBar: true, + isShowDecPage: false, + showNewAppBarTitle: true, + showNewAppBar: true, + appBarTitle: TranslationBase.of(context).patientRelationOffice, + body: SingleChildScrollView( + child: Container( + width: MediaQuery.of(context).size.width, + decoration: containerRadius(Colors.white, 12), + margin: EdgeInsets.all(21.0), + padding: const EdgeInsets.all(21.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).assistYou, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + mHeight(16), + inputWidget(TranslationBase.of(context).enterDetails, "", assistText), + mHeight(16), + DefaultButton( + TranslationBase.of(context).send, + () { + if (assistText.text.isNotEmpty) { + callReceivePrescriptionAPI(context); + } else { + Utils.showErrorToast(TranslationBase.of(context).emptyMessage); + } + }, + ), + ], + ), + ), + ), + ); + } + + 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(12), + 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: TextInputType.name, + 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, + hintStyle: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: Color(0xff575757), + 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), + ], + ), + ), + ); + } + + void callReceivePrescriptionAPI(BuildContext context) { + ClinicListService service = new ClinicListService(); + GifLoaderDialogUtils.showMyDialog(context); + service + .insertInPatientOrder(projectViewModel.getAdmissionInfoResponseModel, 1, (projectViewModel.user.firstName! + " " + projectViewModel.user.lastName!), + (projectViewModel.user.firstNameN! + " " + projectViewModel.user.lastNameN!), projectViewModel.user.mobileNumber!, assistText.text, context) + .then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res['MessageStatus'] == 1) { + AppToast.showSuccessToast(message: TranslationBase.of(context).successSendReport); + Navigator.of(context).pop(); + } else { + AppToast.showErrorToast(message: res['ErrorEndUserMessage'], localContext: context); + Navigator.of(context).pop(); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } +} diff --git a/lib/pages/InPatientServices/inpatient_advance_payment.dart b/lib/pages/InPatientServices/inpatient_advance_payment.dart new file mode 100644 index 00000000..453dc114 --- /dev/null +++ b/lib/pages/InPatientServices/inpatient_advance_payment.dart @@ -0,0 +1,77 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/InPatientServices/get_inpatient_advance_requests_response_model.dart'; +import 'package:diplomaticquarterapp/pages/InPatientServices/components/inpatient_paid_advance_payment.dart'; +import 'package:diplomaticquarterapp/pages/InPatientServices/components/inpatient_pending_advance_payment.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class InPatientAdvancePayment extends StatefulWidget { + InPatientAdvanceResponseModel? inPatientAdvanceResponseModel; + bool? isHasData; + + InPatientAdvancePayment({this.isHasData, this.inPatientAdvanceResponseModel}); + + @override + State createState() => _InPatientAdvancePaymentState(); +} + +class _InPatientAdvancePaymentState extends State with SingleTickerProviderStateMixin { + late TabController _tabController; + late ProjectViewModel projectViewModel; + + @override + void initState() { + _tabController = TabController(length: 2, vsync: this); + super.initState(); + } + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + return AppScaffold( + isShowAppBar: true, + isShowDecPage: false, + showNewAppBarTitle: true, + showNewAppBar: true, + appBarTitle: TranslationBase.of(context).advancePayment, + body: Column( + children: [ + TabBar( + controller: _tabController, + indicatorWeight: 3.0, + indicatorSize: TabBarIndicatorSize.tab, + labelColor: Color(0xff2B353E), + unselectedLabelColor: Color(0xff575757), + labelPadding: EdgeInsets.only(top: 15, bottom: 13, left: 20, right: 20), + physics: const NeverScrollableScrollPhysics(), + 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: [Text(TranslationBase.of(context).pending), Text(TranslationBase.of(context).history)], + ), + Expanded( + child: TabBarView( + physics: BouncingScrollPhysics(), + controller: _tabController, + children: [ + InPatientPendingAdvancePayment(isHasData: widget.isHasData!, inPatientAdvanceResponseModel: widget.inPatientAdvanceResponseModel!), + InPatientPaidAdvancePayment(), + ], + ), + ) + ], + ), + ); + } +} diff --git a/lib/pages/InPatientServices/inpatient_general_consent.dart b/lib/pages/InPatientServices/inpatient_general_consent.dart new file mode 100644 index 00000000..a03e318c --- /dev/null +++ b/lib/pages/InPatientServices/inpatient_general_consent.dart @@ -0,0 +1,528 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/custom_text_button.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class InPatientGeneralConsent extends StatelessWidget { + late ProjectViewModel projectViewModel; + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + return AppScaffold( + isShowAppBar: true, + isShowDecPage: false, + showNewAppBarTitle: true, + showNewAppBar: true, + appBarTitle: TranslationBase.of(context).InPatientServicesHeader, + body: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: const EdgeInsets.all(21.0), + child: Text( + TranslationBase.of(context).generalConsent, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 21.0, + fontWeight: FontWeight.bold, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + Expanded( + child: SingleChildScrollView( + child: Container( + width: MediaQuery.of(context).size.width, + child: Card( + elevation: 0.0, + margin: EdgeInsets.only(left: 16.0, right: 16.0, bottom: 16.0), + color: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + side: BorderSide(color: Colors.transparent, width: 0.0), + ), + child: Padding( + padding: EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).generalConsent1, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(24.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).hospitalRules, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 21.0, + fontWeight: FontWeight.bold, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(12.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).generalConsent2, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(24.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).communicationConsent, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 21.0, + fontWeight: FontWeight.bold, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(12.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).generalConsent3, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(24.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).releaseConsent, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 21.0, + fontWeight: FontWeight.bold, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(12.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).generalConsent4, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(12.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).generalConsent5, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(24.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).valuables, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 21.0, + fontWeight: FontWeight.bold, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(12.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).generalConsent6, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(24.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).financialConsent, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 21.0, + fontWeight: FontWeight.bold, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(12.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).generalConsent7, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(24.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).dataSharingConsent, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 21.0, + fontWeight: FontWeight.bold, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(12.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).generalConsent8, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(24.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).permissionLeaveConsent, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 21.0, + fontWeight: FontWeight.bold, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(12.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).generalConsent9, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(24.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).observeConsent, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 21.0, + fontWeight: FontWeight.bold, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(12.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).generalConsent10, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(24.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).noGuaranteeConsent, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 21.0, + fontWeight: FontWeight.bold, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(12.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).generalConsent11, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(24.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).disputeConsent, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 21.0, + fontWeight: FontWeight.bold, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(12.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).generalConsent12, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(24.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).patientsRightsConsent, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 21.0, + fontWeight: FontWeight.bold, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(12.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).generalConsent13, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(24.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).acknowledgementConsent, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 21.0, + fontWeight: FontWeight.bold, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + mHeight(12.0), + Container( + width: MediaQuery.of(context).size.width * 0.85, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text( + TranslationBase.of(context).generalConsent14, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + ), + ], + ), + ), + ), + ), + ), + ), + Padding( + padding: const EdgeInsets.only(left: 21.0, right: 21.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Expanded( + flex: 1, + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + height: 45.0, + child: CustomTextButton( + backgroundColor: Color(0xffc5272d), + elevation: 0, + onPressed: () { + acceptRejectConsent(context, 0); + }, + child: Text(TranslationBase.of(context).reject, style: TextStyle(fontSize: 16.0, color: Colors.white)), + ), + ), + ), + mWidth(7), + Expanded( + flex: 1, + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + height: 45.0, + child: CustomTextButton( + backgroundColor: CustomColors.green, + elevation: 0, + onPressed: () { + acceptRejectConsent(context, 1); + }, + child: Text(TranslationBase.of(context).acceptLbl, style: TextStyle(fontSize: 16.0, color: Colors.white)), + ), + ), + ), + ], + ), + ), + ], + ), + ); + } + + void acceptRejectConsent(BuildContext context, int status) { + ClinicListService service = new ClinicListService(); + GifLoaderDialogUtils.showMyDialog(context); + service + .insertForGeneralAdmissionConsent( + projectViewModel.user.patientID!, + projectViewModel.isPatientAdmitted ? projectViewModel.getAdmissionInfoResponseModel.admissionRequestNo! : projectViewModel.getAdmissionRequestInfoResponseModel.admissionRequestNo!, + projectViewModel.isPatientAdmitted ? projectViewModel.getAdmissionInfoResponseModel.clinicID! : projectViewModel.getAdmissionRequestInfoResponseModel.clinicId!, + projectViewModel.isPatientAdmitted ? projectViewModel.getAdmissionInfoResponseModel.projectID! : projectViewModel.getAdmissionRequestInfoResponseModel.projectId!, + status, + context) + .then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res["MessageStatus"] == 1) { + AppToast.showSuccessToast(message: res["SuccessMsg"] ?? TranslationBase.of(context).success); + Navigator.of(context); + } else { + AppToast.showErrorToast(message: res["endUserMessage"]); + } + Navigator.pop(context); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } +} diff --git a/lib/pages/InPatientServices/inpatient_home.dart b/lib/pages/InPatientServices/inpatient_home.dart new file mode 100644 index 00000000..9987d501 --- /dev/null +++ b/lib/pages/InPatientServices/inpatient_home.dart @@ -0,0 +1,423 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/InPatientServices/get_general_instructions_response_model.dart'; +import 'package:diplomaticquarterapp/pages/InPatientServices/admission_notice.dart'; +import 'package:diplomaticquarterapp/pages/InPatientServices/birth_notification.dart'; +import 'package:diplomaticquarterapp/pages/InPatientServices/general_instructions.dart'; +import 'package:diplomaticquarterapp/pages/InPatientServices/help_PRO.dart'; +import 'package:diplomaticquarterapp/pages/InPatientServices/inpatient_advance_payment.dart'; +import 'package:diplomaticquarterapp/pages/InPatientServices/inpatient_general_consent.dart'; +import 'package:diplomaticquarterapp/pages/InPatientServices/meal_plan.dart'; +import 'package:diplomaticquarterapp/pages/InPatientServices/medical_instructions.dart'; +import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; +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/data_display/medical/medical_profile_item.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/alert_dialog.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:url_launcher/url_launcher.dart'; + +import '../../models/InPatientServices/get_inpatient_advance_requests_response_model.dart'; +import '../../models/InPatientServices/get_medical_instructions_response_model.dart'; + +class InPatientServicesHome extends StatefulWidget { + @override + State createState() => _InPatientServicesHomeState(); +} + +class _InPatientServicesHomeState extends State { + late ProjectViewModel projectViewModel; + InPatientAdvanceResponseModel inPatientAdvanceResponseModel = InPatientAdvanceResponseModel(); + bool isReceivePrescriptionEnabled = false; + + @override + void initState() { + super.initState(); + WidgetsBinding.instance.addPostFrameCallback((_) { + checkDischargeMedications(context); + }); + } + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + List inPatientServiceList = getInPatientServicesList(context); + return AppScaffold( + isShowAppBar: true, + isShowDecPage: false, + showNewAppBarTitle: true, + showNewAppBar: true, + appBarTitle: TranslationBase.of(context).InPatientServicesHeader, + body: Container( + margin: EdgeInsets.all(20.0), + child: Column( + children: [ + Padding( + padding: EdgeInsets.only(left: 12, right: 12), + child: GridView.builder( + shrinkWrap: true, + primary: false, + physics: NeverScrollableScrollPhysics(), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, childAspectRatio: 2 / 2, crossAxisSpacing: 12, mainAxisSpacing: 12), + padding: EdgeInsets.zero, + itemCount: inPatientServiceList.length, + itemBuilder: (BuildContext context, int index) { + return inPatientServiceList[index]; + }, + ), + ), + ], + ), + ), + ); + } + + List getInPatientServicesList(BuildContext context) { + List serviceList = []; + + serviceList.add( + InkWell( + onTap: () { + openPatientGeneralConsent(); + }, + child: MedicalProfileItem( + title: TranslationBase.of(context).generalConsentTitle, + imagePath: 'general_instructions.svg', + subTitle: TranslationBase.of(context).generalConsentSubTitle, + width: 50.0, + height: 40.0, + isInPatient: true, + isEnable: true, + ), + ), + ); + + serviceList.add( + InkWell( + onTap: () { + if (projectViewModel.isPatientAdmitted ? true : checkAdmissionRequestDate()) openGeneralInstructions(context); + }, + child: MedicalProfileItem( + title: TranslationBase.of(context).generalInstructionsTitle, + imagePath: 'general_instructions.svg', + subTitle: TranslationBase.of(context).generalInstructionsSubTitle, + width: 50.0, + height: 40.0, + isInPatient: true, + isEnable: projectViewModel.isPatientAdmitted ? true : checkAdmissionRequestDate(), + ), + ), + ); + + serviceList.add( + InkWell( + onTap: () { + if (projectViewModel.isPatientAdmitted ? true : checkAdmissionRequestDate()) openMedicalInstructions(context); + }, + child: MedicalProfileItem( + title: TranslationBase.of(context).medicalInstructionsTitle, + imagePath: 'medical_instructions.svg', + subTitle: TranslationBase.of(context).medicalInstructionsSubTitle, + width: 50.0, + height: 40.0, + isInPatient: true, + isEnable: projectViewModel.isPatientAdmitted ? true : checkAdmissionRequestDate(), + ), + ), + ); + + serviceList.add( + InkWell( + onTap: () { + if (projectViewModel.isPatientAdmitted) { + Navigator.push(context, FadePage(page: MealPlanPage())); + } else { + AppToast.showErrorToast(message: "This service is only available to admitted patients"); + } + }, + child: MedicalProfileItem( + title: TranslationBase.of(context).mealPlanTitle, + imagePath: 'meal_plan.svg', + subTitle: TranslationBase.of(context).mealPlanSubTitle, + width: 50.0, + height: 40.0, + isInPatient: true, + isEnable: projectViewModel.isPatientAdmitted), + ), + ); + + serviceList.add( + InkWell( + onTap: () { + openBirthNotificationsPage(context); + }, + child: MedicalProfileItem( + title: TranslationBase.of(context).birthNotificationTitle, + imagePath: 'birth_notification.svg', + subTitle: TranslationBase.of(context).birthNotificationSubTitle, + width: 50.0, + height: 40.0, + isInPatient: true, + ), + ), + ); + + // serviceList.add( + // InkWell( + // onTap: () { + // // Navigator.push(context, FadePage(page: AdvancePaymentPage())); + // }, + // child: MedicalProfileItem( + // title: TranslationBase.of(context).admissionNoticeTitle, + // imagePath: 'admission_notice.svg', + // subTitle: TranslationBase.of(context).admissionNoticeSubTitle, + // width: 50.0, + // height: 40.0, + // isInPatient: true, + // ), + // ), + // ); + + serviceList.add( + InkWell( + onTap: () { + getInPatientAdvancePaymentRequests(context); + }, + child: MedicalProfileItem( + title: TranslationBase.of(context).advancePayment, + imagePath: 'advance_payment.svg', + subTitle: TranslationBase.of(context).payment, + width: 50.0, + height: 40.0, + isInPatient: true, + ), + ), + ); + + serviceList.add( + InkWell( + onTap: () { + Navigator.push(context, FadePage(page: AdmissionNotice())); + // if (isReceivePrescriptionEnabled) receivePrescriptionAPI(context); + }, + child: MedicalProfileItem( + title: TranslationBase.of(context).admissionNoticeTitle, + imagePath: 'admission_notice.svg', + subTitle: TranslationBase.of(context).admissionNoticeSubTitle, + width: 50.0, + height: 40.0, + isInPatient: true, + isEnable: true), + ), + ); + + serviceList.add( + InkWell( + onTap: () { + // Navigator.push(context, FadePage(page: AdvancePaymentPage())); + if (isReceivePrescriptionEnabled) receivePrescriptionAPI(context); + }, + child: MedicalProfileItem( + title: TranslationBase.of(context).receive, + imagePath: 'receive_prescription.svg', + subTitle: TranslationBase.of(context).prescriptions, + width: 50.0, + height: 40.0, + isInPatient: true, + isEnable: isReceivePrescriptionEnabled), + ), + ); + + serviceList.add( + InkWell( + onTap: () { + checkCurrentTime(context); + }, + child: MedicalProfileItem( + title: TranslationBase.of(context).help, + imagePath: 'help_pro.svg', + subTitle: TranslationBase.of(context).PRO, + width: 50.0, + height: 40.0, + isInPatient: true, + ), + ), + ); + + return serviceList; + } + + void receivePrescriptionAPI(BuildContext context) { + AlertDialogBox( + context: context, + confirmMessage: TranslationBase.of(context).successSendReport, + okText: TranslationBase.of(context).ok, + okFunction: () { + AlertDialogBox.closeAlertDialog(context); + callReceivePrescriptionAPI(context); + }).showAlertDialog(context); + + // ConfirmDialog dialog = new ConfirmDialog( + // context: context, + // confirmMessage: TranslationBase.of(context).successSendReport, + // okText: TranslationBase.of(context).ok, + // cancelText: TranslationBase.of(context).cancel_nocaps, + // okFunction: () { + // Navigator.of(context).pop(); + // }, + // cancelFunction: () => {}); + // dialog.showAlertDialog(context); + } + + void checkDischargeMedications(BuildContext context) { + ClinicListService service = new ClinicListService(); + GifLoaderDialogUtils.showMyDialog(context); + service.getDischargeMedicationOrder(projectViewModel.getAdmissionInfoResponseModel).then((res) { + setState(() { + if (res["PatientHasDischargeMedicineList"].length != 0) { + isReceivePrescriptionEnabled = true; + } + }); + GifLoaderDialogUtils.hideDialog(context); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } + + void callReceivePrescriptionAPI(BuildContext context) { + ClinicListService service = new ClinicListService(); + GifLoaderDialogUtils.showMyDialog(context); + service + .insertInPatientOrder(projectViewModel.getAdmissionInfoResponseModel, 2, (projectViewModel.user.firstName! + " " + projectViewModel.user.lastName!), + (projectViewModel.user.firstNameN! + " " + projectViewModel.user.lastNameN!), projectViewModel.user.mobileNumber!, "I need my medicines", context) + .then((res) { + GifLoaderDialogUtils.hideDialog(context); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } + + void openBirthNotificationsPage(BuildContext context) { + ClinicListService service = new ClinicListService(); + GifLoaderDialogUtils.showMyDialog(context); + service + .getBirthNotification( + projectViewModel.user.patientID!, + projectViewModel.isPatientAdmitted ? projectViewModel.getAdmissionInfoResponseModel.projectID! : projectViewModel.getAdmissionRequestInfoResponseModel.projectId!, + projectViewModel.isArabic ? 1 : 2, + context) + .then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res["MessageStatus"] == 1) { + Navigator.push(context, FadePage(page: BirthNotification())); + } else { + AppToast.showErrorToast(message: res["endUserMessage"], localContext: context); + } + }).catchError((err) { + print(err); + }); + } + + void openPatientGeneralConsent() { + Navigator.push(context, FadePage(page: InPatientGeneralConsent())); + } + + void openGeneralInstructions(BuildContext context) { + ClinicListService service = new ClinicListService(); + GifLoaderDialogUtils.showMyDialog(context); + service.getGeneralInstructions(projectViewModel.inPatientProjectID, projectViewModel.isArabic ? 1 : 2, context).then((res) { + if (res['generalInstructions'].length != 0) { + List getGeneralInstructionsList = []; + res['generalInstructions'].forEach((v) { + getGeneralInstructionsList.add(new GetGeneralInstructions.fromJson(v)); + }); + GifLoaderDialogUtils.hideDialog(context); + Navigator.push(context, FadePage(page: GeneralInstructions(getGeneralInstructionsList: getGeneralInstructionsList))); + } else { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: TranslationBase.of(context).noGeneralInstructions); + } + }).catchError((err) { + print(err); + }); + } + + void openMedicalInstructions(BuildContext context) { + ClinicListService service = new ClinicListService(); + GifLoaderDialogUtils.showMyDialog(context); + service.getMedicalInstructions(projectViewModel.inPatientProjectID, projectViewModel.isArabic ? 1 : 2, context).then((res) { + if (res['MedicalInstruction'] != null && res['MedicalInstruction'].length != 0) { + List getMedicalInstructionsList = []; + res['MedicalInstruction'].forEach((v) { + getMedicalInstructionsList.add(new GetMedicalInstructions.fromJson(v)); + }); + GifLoaderDialogUtils.hideDialog(context); + Navigator.push(context, FadePage(page: MedicalInstructionsPage(getMedicalInstructionsList: getMedicalInstructionsList))); + } else { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: TranslationBase.of(context).noMedicalInstructions); + } + }).catchError((err) { + print(err); + }); + } + + void getInPatientAdvancePaymentRequests(BuildContext context) { + ClinicListService service = new ClinicListService(); + GifLoaderDialogUtils.showMyDialog(context); + service + .getInPatientAdvancePaymentRequests( + projectViewModel.isPatientAdmitted ? projectViewModel.getAdmissionInfoResponseModel.projectID! : projectViewModel.getAdmissionRequestInfoResponseModel.projectId!, + projectViewModel.isPatientAdmitted ? projectViewModel.getAdmissionInfoResponseModel.admissionNo! : 0, + projectViewModel.isPatientAdmitted ? projectViewModel.getAdmissionInfoResponseModel.admissionRequestNo! : projectViewModel.getAdmissionRequestInfoResponseModel.admissionRequestNo!, + projectViewModel.isArabic ? 1 : 2, + context) + .then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res["MessageStatus"] == 1) { + if (res['responseInpatient'] != null && res['responseInpatient']['responseInpatientAdvanceInfo'] != null && res['responseInpatient']['responseInpatientAdvanceInfo'].length != 0) { + inPatientAdvanceResponseModel = InPatientAdvanceResponseModel.fromJson(res["responseInpatient"]); + Navigator.push(context, + FadePage(page: InPatientAdvancePayment(isHasData: inPatientAdvanceResponseModel.responseInpatientAdvanceInfo != null, inPatientAdvanceResponseModel: inPatientAdvanceResponseModel))); + } else { + AppToast.showErrorToast(message: TranslationBase.of(context).noData); + } + } else { + Navigator.push(context, + FadePage(page: InPatientAdvancePayment(isHasData: inPatientAdvanceResponseModel.responseInpatientAdvanceInfo != null, inPatientAdvanceResponseModel: inPatientAdvanceResponseModel))); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } + + void checkCurrentTime(BuildContext context) { + if (DateTime.now().hour >= 7 && DateTime.now().hour <= 22) { + Navigator.push(context, FadePage(page: HelpPRO())); + } else { + ConfirmDialog dialog = new ConfirmDialog( + context: context, + confirmMessage: TranslationBase.of(context).proErrorMessage, + okText: TranslationBase.of(context).callNow, + cancelText: TranslationBase.of(context).cancel_nocaps, + okFunction: () => {ConfirmDialog.closeAlertDialog(context), launchUrl(Uri.parse("tel://" + "011 525 9553"))}, + cancelFunction: () => {}); + dialog.showAlertDialog(context); + } + } + + bool checkAdmissionRequestDate() { + if (DateUtil.convertStringToDate(projectViewModel.getAdmissionRequestInfoResponseModel.expectedAdmissionDate).difference(DateTime.now()).inHours > 24) { + return false; + } + return true; + } +} diff --git a/lib/pages/InPatientServices/meal_plan.dart b/lib/pages/InPatientServices/meal_plan.dart new file mode 100644 index 00000000..4e300900 --- /dev/null +++ b/lib/pages/InPatientServices/meal_plan.dart @@ -0,0 +1,641 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/InPatientServices/get_admitted_patient_response_model.dart'; +import 'package:diplomaticquarterapp/models/InPatientServices/get_meal_items_schedule_response_model.dart'; +import 'package:diplomaticquarterapp/models/InPatientServices/get_meals_schedule_response_model.dart'; +import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/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/avatar/large_avatar.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:diplomaticquarterapp/widgets/my_rich_text.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_expandable_notifier.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class MealPlanPage extends StatefulWidget { + const MealPlanPage({Key? key}) : super(key: key); + + @override + State createState() => _MealPlanPageState(); +} + +class _MealPlanPageState extends State { + late ProjectViewModel projectViewModel; + GetAdmittedPatientsResponseModel getAdmittedPatientsResponseModel = GetAdmittedPatientsResponseModel(); + List getMealsScheduleResponseModelList = []; + + List getMealItemsScheduleResponseModelBreakfast = []; + List getMealItemsScheduleResponseModelLunch = []; + List getMealItemsScheduleResponseModelDinner = []; + + List _getMealItemsScheduleResponseModelBreakfast = []; + List _getMealItemsScheduleResponseModelLunch = []; + List _getMealItemsScheduleResponseModelDinner = []; + + int currentDay = 0; + int currentWeek = 0; + + int selectedMealScheduleID = 0; + + final ValueNotifier isFasting = ValueNotifier(false); + bool isFastingVal = false; + + @override + void initState() { + super.initState(); + WidgetsBinding.instance.addPostFrameCallback((_) { + getAdmittedPatientDetails(); + }); + } + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + return AppScaffold( + isShowAppBar: true, + isShowDecPage: false, + showNewAppBarTitle: true, + showNewAppBar: true, + appBarTitle: TranslationBase.of(context).mealPlanTitle, + body: SingleChildScrollView( + child: Padding( + padding: EdgeInsets.all(21.0), + child: getMealsScheduleResponseModelList.length != 0 + ? Column( + children: [ + Container( + decoration: containerRadius((getMealsScheduleResponseModelList[0].isShow)! ? Colors.white : Colors.grey[300]!, 12), + child: AppExpandableNotifier( + title: "Breakfast TAT: " + DateUtil.convertTime(getMealsScheduleResponseModelList[0].tATTime!), + isTitleSingleLine: false, + widgetColor: Colors.transparent, + isExpand: getMealsScheduleResponseModelList[0].isShow!, + isDisabled: !getMealsScheduleResponseModelList[0].isShow!, + bodyWidget: Column( + children: [ + getDivider(), + ListView.separated( + physics: BouncingScrollPhysics(), + shrinkWrap: true, + itemBuilder: (context, index) { + return Container( + padding: EdgeInsets.all(21.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(_getMealItemsScheduleResponseModelBreakfast[index].filterName!, + style: TextStyle(fontWeight: FontWeight.w600, fontSize: 18.0, letterSpacing: -0.64, color: CustomColors.darkGrey)), + SizedBox( + height: 12.0, + ), + ListView.separated( + physics: NeverScrollableScrollPhysics(), + shrinkWrap: true, + itemBuilder: (context, index2) { + return Container( + child: Row( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ValueListenableBuilder( + valueListenable: _getMealItemsScheduleResponseModelBreakfast[index].selectedItemID, + builder: (context, val, child) { + return Radio( + value: _getMealItemsScheduleResponseModelBreakfast[index].getMealItemsScheduleResponseModelList[index2].itemID, + groupValue: _getMealItemsScheduleResponseModelBreakfast[index].selectedItemID.value, + activeColor: Colors.red[800], + onChanged: (value) { + _getMealItemsScheduleResponseModelBreakfast[index].selectedItemID.value = value!; + }, + ); + }), + LargeAvatar( + name: _getMealItemsScheduleResponseModelBreakfast[index].getMealItemsScheduleResponseModelList[index2].description, + url: "https://www.pumpkinnspice.com/wp-content/uploads/2016/03/easy-breakfast-quesadillas-11-683x1024.jpg", + width: 60, + height: 60, + radius: 5, + disableProfileView: true, + ), + SizedBox(width: 11), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + MyRichText( + "", + projectViewModel.isArabic + ? _getMealItemsScheduleResponseModelBreakfast[index].getMealItemsScheduleResponseModelList[index2].descriptionN! + : _getMealItemsScheduleResponseModelBreakfast[index].getMealItemsScheduleResponseModelList[index2].description!, + projectViewModel.isArabic), + ], + ), + ), + ], + ), + ); + }, + separatorBuilder: (context, index) { + return Padding( + padding: EdgeInsets.all(16.0), + child: Divider( + height: 1.5, + thickness: 1.0, + color: Colors.grey.shade200, + ), + ); + }, + itemCount: _getMealItemsScheduleResponseModelBreakfast[index].getMealItemsScheduleResponseModelList.length), + ], + ), + ); + }, + separatorBuilder: (context, index) { + return Padding( + padding: EdgeInsets.only(left: 15, right: 15), + child: Divider( + height: 1.5, + thickness: 1.0, + color: Colors.grey.shade200, + ), + ); + }, + itemCount: _getMealItemsScheduleResponseModelBreakfast.length), + ], + ), + ), + ), + mHeight(21), + Container( + decoration: containerRadius(getMealsScheduleResponseModelList[1].isShow! ? Colors.white : Colors.grey[300]!, 12), + child: AppExpandableNotifier( + title: "Lunch TAT: " + DateUtil.convertTime(getMealsScheduleResponseModelList[1].tATTime!), + isTitleSingleLine: false, + widgetColor: Colors.transparent, + isExpand: getMealsScheduleResponseModelList[1].isShow!, + isDisabled: !getMealsScheduleResponseModelList[1].isShow!, + bodyWidget: Column( + children: [ + getDivider(), + ListView.separated( + physics: BouncingScrollPhysics(), + shrinkWrap: true, + itemBuilder: (context, index) { + return Container( + padding: EdgeInsets.all(21.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(_getMealItemsScheduleResponseModelLunch[index].filterName!, + style: TextStyle(fontWeight: FontWeight.w600, fontSize: 18.0, letterSpacing: -0.64, color: CustomColors.darkGrey)), + SizedBox( + height: 12.0, + ), + ListView.separated( + physics: NeverScrollableScrollPhysics(), + shrinkWrap: true, + itemBuilder: (context, index2) { + return Container( + child: Row( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ValueListenableBuilder( + valueListenable: _getMealItemsScheduleResponseModelLunch[index].selectedItemID, + builder: (context, val, child) { + return Radio( + value: _getMealItemsScheduleResponseModelLunch[index].getMealItemsScheduleResponseModelList[index2].itemID, + groupValue: _getMealItemsScheduleResponseModelLunch[index].selectedItemID.value, + activeColor: Colors.red[800], + onChanged: (value) { + _getMealItemsScheduleResponseModelLunch[index].selectedItemID.value = value!; + }, + ); + }), + LargeAvatar( + name: _getMealItemsScheduleResponseModelLunch[index].getMealItemsScheduleResponseModelList[index2].description, + url: "https://www.pumpkinnspice.com/wp-content/uploads/2016/03/easy-breakfast-quesadillas-11-683x1024.jpg", + width: 60, + height: 60, + radius: 5, + disableProfileView: true, + ), + SizedBox(width: 11), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + MyRichText( + "", + projectViewModel.isArabic + ? _getMealItemsScheduleResponseModelLunch[index].getMealItemsScheduleResponseModelList[index2].descriptionN! + : _getMealItemsScheduleResponseModelLunch[index].getMealItemsScheduleResponseModelList[index2].description!, + projectViewModel.isArabic), + ], + ), + ), + ], + ), + ); + }, + separatorBuilder: (context, index) { + return Padding( + padding: EdgeInsets.all(16.0), + child: Divider( + height: 1.5, + thickness: 1.0, + color: Colors.grey.shade200, + ), + ); + }, + itemCount: _getMealItemsScheduleResponseModelLunch[index].getMealItemsScheduleResponseModelList.length), + ], + ), + ); + }, + separatorBuilder: (context, index) { + return Padding( + padding: EdgeInsets.only(left: 15, right: 15), + child: Divider( + height: 1.5, + thickness: 1.0, + color: Colors.grey.shade200, + ), + ); + }, + itemCount: _getMealItemsScheduleResponseModelLunch.length), + ], + ), + ), + ), + mHeight(21), + Container( + decoration: containerRadius(getMealsScheduleResponseModelList[2].isShow! ? Colors.white : Colors.grey[300]!, 12), + child: AppExpandableNotifier( + title: "Dinner TAT: " + DateUtil.convertTime(getMealsScheduleResponseModelList[2].tATTime!), + isTitleSingleLine: false, + widgetColor: Colors.transparent, + isExpand: getMealsScheduleResponseModelList[2].isShow!, + isDisabled: !getMealsScheduleResponseModelList[2].isShow!, + bodyWidget: Column( + children: [ + getDivider(), + ListView.separated( + physics: BouncingScrollPhysics(), + shrinkWrap: true, + itemBuilder: (context, index) { + return Container( + padding: EdgeInsets.all(21.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(_getMealItemsScheduleResponseModelDinner[index].filterName!, + style: TextStyle(fontWeight: FontWeight.w600, fontSize: 18.0, letterSpacing: -0.64, color: CustomColors.darkGrey)), + SizedBox( + height: 12.0, + ), + ListView.separated( + physics: NeverScrollableScrollPhysics(), + shrinkWrap: true, + itemBuilder: (context, index2) { + return Container( + child: Row( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ValueListenableBuilder( + valueListenable: _getMealItemsScheduleResponseModelDinner[index].selectedItemID, + builder: (context, val, child) { + return Radio( + value: _getMealItemsScheduleResponseModelDinner[index].getMealItemsScheduleResponseModelList[index2].itemID, + groupValue: _getMealItemsScheduleResponseModelDinner[index].selectedItemID.value, + activeColor: Colors.red[800], + onChanged: (value) { + _getMealItemsScheduleResponseModelDinner[index].selectedItemID.value = value!; + }, + ); + }), + LargeAvatar( + name: _getMealItemsScheduleResponseModelDinner[index].getMealItemsScheduleResponseModelList[index2].description, + url: "https://www.pumpkinnspice.com/wp-content/uploads/2016/03/easy-breakfast-quesadillas-11-683x1024.jpg", + width: 60, + height: 60, + radius: 5, + disableProfileView: true, + ), + SizedBox(width: 11), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + MyRichText( + "", + projectViewModel.isArabic + ? _getMealItemsScheduleResponseModelDinner[index].getMealItemsScheduleResponseModelList[index2].descriptionN! + : _getMealItemsScheduleResponseModelDinner[index].getMealItemsScheduleResponseModelList[index2].description!, + projectViewModel.isArabic), + ], + ), + ), + ], + ), + ); + }, + separatorBuilder: (context, index) { + return Padding( + padding: EdgeInsets.all(16.0), + child: Divider( + height: 1.5, + thickness: 1.0, + color: Colors.grey.shade200, + ), + ); + }, + itemCount: _getMealItemsScheduleResponseModelDinner[index].getMealItemsScheduleResponseModelList.length), + ], + ), + ); + }, + separatorBuilder: (context, index) { + return Padding( + padding: EdgeInsets.only(left: 15, right: 15), + child: Divider( + height: 1.5, + thickness: 1.0, + color: Colors.grey.shade200, + ), + ); + }, + itemCount: _getMealItemsScheduleResponseModelDinner.length), + ], + ), + ), + ), + ], + ) + : Container(), + ), + ), + bottomSheet: Container( + color: Colors.white, + width: double.infinity, + padding: EdgeInsets.all(20), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + ValueListenableBuilder( + valueListenable: isFasting, + builder: (context, val, child) { + return Checkbox( + onChanged: (bool? value) { + isFasting.value = value!; + isFastingVal = value; + }, + value: isFastingVal, + activeColor: Color(0xFFc5272d), + ); + }), + Text( + TranslationBase.of(context).isFasting, + style: TextStyle( + fontSize: 14, + letterSpacing: -0.48, + ), + ), + ], + ), + mHeight(12), + DefaultButton( + TranslationBase.of(context).placeOrder, + () { + placeOrder(); + }, + color: Color(0xff359846), + disabledColor: Colors.grey, + ), + ], + ), + ), + ); + } + + void placeOrder() { + List selectedItemIDs = []; + + if (_getMealItemsScheduleResponseModelBreakfast.isNotEmpty) { + _getMealItemsScheduleResponseModelBreakfast.forEach((element) { + selectedItemIDs.add(element.selectedItemID.value.toString()); + }); + } + + if (_getMealItemsScheduleResponseModelLunch.isNotEmpty) { + _getMealItemsScheduleResponseModelLunch.forEach((element) { + selectedItemIDs.add(element.selectedItemID.value.toString()); + }); + } + + if (_getMealItemsScheduleResponseModelDinner.isNotEmpty) { + _getMealItemsScheduleResponseModelDinner.forEach((element) { + selectedItemIDs.add(element.selectedItemID.value.toString()); + }); + } + ClinicListService service = new ClinicListService(); + GifLoaderDialogUtils.showMyDialog(context); + service + .placeMealPlanOrder(getAdmittedPatientsResponseModel.projectID!, selectedMealScheduleID, selectedItemIDs.join(","), projectViewModel.user.patientID!, + getAdmittedPatientsResponseModel.admissionNo!, getAdmittedPatientsResponseModel.isHasCompanion!, isFastingVal, context) + .then((res) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showSuccessToast(message: "Your meal order has been received successfully"); + Navigator.pop(context); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } + + Widget getDivider() { + return Padding( + padding: EdgeInsets.only(left: 15, right: 15), + child: Divider( + height: 1.5, + thickness: 2.0, + color: Colors.black, + ), + ); + } + + void getAdmittedPatientDetails() { + ClinicListService service = new ClinicListService(); + GifLoaderDialogUtils.showMyDialog(context); + service.getAdmittedPatientDetails(projectViewModel.user.patientID!, projectViewModel.inPatientProjectID, projectViewModel.getAdmissionInfoResponseModel.admissionNo!, 0, 0, 0, context).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res["List_MOP_AdmittedPatients"] != null && res["List_MOP_AdmittedPatients"].length != 0) { + print(res["List_MOP_AdmittedPatients"]); + getAdmittedPatientsResponseModel = new GetAdmittedPatientsResponseModel.fromJson(res["List_MOP_AdmittedPatients"][0]); + print(getAdmittedPatientsResponseModel.dietType); + getCurrentWeekIDAndDay(getAdmittedPatientsResponseModel.dietType!); + } else { + AppToast.showErrorToast(message: "No data found for admitted patient"); + getCurrentWeekIDAndDay(1); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } + + void getCurrentWeekIDAndDay(int dietType) { + ClinicListService service = new ClinicListService(); + GifLoaderDialogUtils.showMyDialog(context); + service.getCurrentWeekIDAndDay(context).then((res) { + GifLoaderDialogUtils.hideDialog(context); + currentDay = res["CurrentDay"]; + currentWeek = res["CurrentWeek"]; + getMealsOfScheduleID(dietType); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } + + void getMealsOfScheduleID(int dietType) { + ClinicListService service = new ClinicListService(); + GifLoaderDialogUtils.showMyDialog(context); + service.getMealsOfScheduleID(projectViewModel.inPatientProjectID, projectViewModel.getAdmissionInfoResponseModel.admissionNo!, dietType, currentWeek, currentDay, context).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res["List_MOP_MealsOfScheduleID_Mobile"] != null && res["List_MOP_MealsOfScheduleID_Mobile"].length != 0) { + res['List_MOP_MealsOfScheduleID_Mobile'].forEach((scheduleItem) { + getMealsScheduleResponseModelList.add(GetMealsScheduleResponseModel.fromJson(scheduleItem)); + }); + if (getMealsScheduleResponseModelList[0].isShow!) { + selectedMealScheduleID = getMealsScheduleResponseModelList[0].scheduleID!; + getDefaultItemsOfScheduleID(getMealsScheduleResponseModelList[0].scheduleID!, 1); + } + if (getMealsScheduleResponseModelList[1].isShow!) { + selectedMealScheduleID = getMealsScheduleResponseModelList[1].scheduleID!; + getDefaultItemsOfScheduleID(getMealsScheduleResponseModelList[1].scheduleID!, 2); + } + if (getMealsScheduleResponseModelList[2].isShow!) { + selectedMealScheduleID = getMealsScheduleResponseModelList[2].scheduleID!; + getDefaultItemsOfScheduleID(getMealsScheduleResponseModelList[2].scheduleID!, 3); + } + } else { + AppToast.showErrorToast(message: "No meal schedule found for admitted patient"); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } + + void getDefaultItemsOfScheduleID(int scheduleID, int mealType) { + ClinicListService service = new ClinicListService(); + GifLoaderDialogUtils.showMyDialog(context); + service.getDefaultItemsOfScheduleID(projectViewModel.inPatientProjectID, scheduleID, context).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res["List_MOP_DefaultItemsOfMealModel"] != null && res["List_MOP_DefaultItemsOfMealModel"].length != 0) { + if (mealType == 1) { + res['List_MOP_DefaultItemsOfMealModel'].forEach((scheduleItem) { + getMealItemsScheduleResponseModelBreakfast.add(GetMealItemsScheduleResponseModel.fromJson(scheduleItem)); + }); + sortMealsByCategoryBreakfast(); + } + if (mealType == 2) { + res['List_MOP_DefaultItemsOfMealModel'].forEach((scheduleItem) { + getMealItemsScheduleResponseModelLunch.add(GetMealItemsScheduleResponseModel.fromJson(scheduleItem)); + }); + sortMealsByCategoryLunch(); + } + if (mealType == 3) { + res['List_MOP_DefaultItemsOfMealModel'].forEach((scheduleItem) { + getMealItemsScheduleResponseModelDinner.add(GetMealItemsScheduleResponseModel.fromJson(scheduleItem)); + }); + sortMealsByCategoryDinner(); + } + } else { + AppToast.showErrorToast(message: "No meal items found for admitted patient"); + } + setState(() {}); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } + + void sortMealsByCategoryBreakfast() { + getMealItemsScheduleResponseModelBreakfast.forEach((element) { + List breakfastMealItems = _getMealItemsScheduleResponseModelBreakfast + .where((elementClinic) => elementClinic.filterName == (projectViewModel.isArabic ? element.categoryDescriptionN : element.categoryDescription)) + .toList(); + if (breakfastMealItems.length != 0) { + _getMealItemsScheduleResponseModelBreakfast[_getMealItemsScheduleResponseModelBreakfast.indexOf(breakfastMealItems[0])].getMealItemsScheduleResponseModelList.add(element); + } else { + _getMealItemsScheduleResponseModelBreakfast + .add(GetMealItemsScheduleResponseModelList(filterName: projectViewModel.isArabic ? element.categoryDescriptionN : element.categoryDescription, getMealItemsScheduleResponseModel: element)); + } + }); + + _getMealItemsScheduleResponseModelBreakfast.forEach((element) { + element.getMealItemsScheduleResponseModelList.forEach((elementInner) { + if (elementInner.isDefault!) { + element.selectedItemID.value = elementInner.itemID!; + } + }); + }); + } + + void sortMealsByCategoryLunch() { + getMealItemsScheduleResponseModelLunch.forEach((element) { + List breakfastMealItems = _getMealItemsScheduleResponseModelLunch + .where((elementClinic) => elementClinic.filterName == (projectViewModel.isArabic ? element.categoryDescriptionN : element.categoryDescription)) + .toList(); + if (breakfastMealItems.length != 0) { + _getMealItemsScheduleResponseModelLunch[_getMealItemsScheduleResponseModelLunch.indexOf(breakfastMealItems[0])].getMealItemsScheduleResponseModelList.add(element); + } else { + _getMealItemsScheduleResponseModelLunch + .add(GetMealItemsScheduleResponseModelList(filterName: projectViewModel.isArabic ? element.categoryDescriptionN : element.categoryDescription, getMealItemsScheduleResponseModel: element)); + } + }); + + _getMealItemsScheduleResponseModelLunch.forEach((element) { + element.getMealItemsScheduleResponseModelList.forEach((elementInner) { + if (elementInner.isDefault!) { + element.selectedItemID.value = elementInner.itemID!; + } + }); + }); + } + + void sortMealsByCategoryDinner() { + getMealItemsScheduleResponseModelDinner.forEach((element) { + List breakfastMealItems = _getMealItemsScheduleResponseModelDinner + .where((elementClinic) => elementClinic.filterName == (projectViewModel.isArabic ? element.categoryDescriptionN : element.categoryDescription)) + .toList(); + if (breakfastMealItems.length != 0) { + _getMealItemsScheduleResponseModelDinner[_getMealItemsScheduleResponseModelDinner.indexOf(breakfastMealItems[0])].getMealItemsScheduleResponseModelList.add(element); + } else { + _getMealItemsScheduleResponseModelDinner + .add(GetMealItemsScheduleResponseModelList(filterName: projectViewModel.isArabic ? element.categoryDescriptionN : element.categoryDescription, getMealItemsScheduleResponseModel: element)); + } + }); + _getMealItemsScheduleResponseModelDinner.forEach((element) { + element.getMealItemsScheduleResponseModelList.forEach((elementInner) { + if (elementInner.isDefault!) { + element.selectedItemID.value = elementInner.itemID!; + } + }); + }); + } +} diff --git a/lib/pages/InPatientServices/medical_instructions.dart b/lib/pages/InPatientServices/medical_instructions.dart new file mode 100644 index 00000000..bbab1b5f --- /dev/null +++ b/lib/pages/InPatientServices/medical_instructions.dart @@ -0,0 +1,100 @@ +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/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:provider/provider.dart'; + +import '../../models/InPatientServices/get_medical_instructions_response_model.dart'; + +class MedicalInstructionsPage extends StatefulWidget { + List getMedicalInstructionsList; + + MedicalInstructionsPage({required this.getMedicalInstructionsList}); + + @override + State createState() => _MedicalInstructionsPageState(); +} + +class _MedicalInstructionsPageState extends State { + late ProjectViewModel projectViewModel; + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + return AppScaffold( + isShowAppBar: true, + isShowDecPage: false, + showNewAppBarTitle: true, + showNewAppBar: true, + appBarTitle: TranslationBase.of(context).InPatientServicesHeader, + body: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: const EdgeInsets.all(21.0), + child: Text(TranslationBase.of(context).medicalInstructions, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 21.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + )), + ), + Expanded( + child: Container( + width: MediaQuery.of(context).size.width, + child: Card( + elevation: 0.0, + margin: EdgeInsets.only(left: 16.0, right: 16.0, bottom: 16.0), + color: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + side: BorderSide(color: Colors.transparent, width: 0.0), + ), + child: Padding( + padding: EdgeInsets.all(16.0), + child: Container( + child: ListView.separated( + itemCount: widget.getMedicalInstructionsList[0].medicaLInstructionsField!.length, + itemBuilder: (BuildContext context, int index) { + return Container( + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + child: SvgPicture.asset("assets/images/new-design/ionic-ios-checkmark-circle.svg"), + ), + Container( + width: MediaQuery.of(context).size.width * 0.75, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text(widget.getMedicalInstructionsList[0].medicaLInstructionsField![index].descriptionField!, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + )), + ), + ], + )); + }, + separatorBuilder: (BuildContext context, int index) { + return Padding( + padding: const EdgeInsets.only(left: 14, right: 14), + child: mHeight(16.0), + ); + }, + )), + ), + ), + ), + ) + ], + )); + } +} diff --git a/lib/pages/MyAppointments/AppointmentDetails.dart b/lib/pages/MyAppointments/AppointmentDetails.dart index 9848b394..9805a691 100644 --- a/lib/pages/MyAppointments/AppointmentDetails.dart +++ b/lib/pages/MyAppointments/AppointmentDetails.dart @@ -1,226 +1,299 @@ +import 'dart:collection'; + +import 'package:device_calendar/device_calendar.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorRateDetails.dart'; +import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart'; +import 'package:diplomaticquarterapp/models/header_model.dart'; import 'package:diplomaticquarterapp/pages/BookAppointment/BookConfirm.dart'; import 'package:diplomaticquarterapp/pages/BookAppointment/components/DocAvailableAppointments.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/waiting_appointment/waiting_appointment_info.dart'; +import 'package:diplomaticquarterapp/pages/MyAppointments/SchedulePage.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; +import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/CalendarUtils.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/widgets/buttons/custom_text_button.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; +import 'package:diplomaticquarterapp/widgets/new_design/doctor_header.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_rating_bar/flutter_rating_bar.dart'; import 'package:provider/provider.dart'; -import 'package:rating_bar/rating_bar.dart'; import 'widgets/AppointmentActions.dart'; class AppointmentDetails extends StatefulWidget { AppoitmentAllHistoryResultList appo; static bool isLoading = false; - + dynamic doctorSchedule; static bool showFooterButton = false; + final int? parentIndex; - AppointmentDetails({@required this.appo}); + AppointmentDetails({required this.appo, this.parentIndex, this.doctorSchedule}); @override _AppointmentDetailsState createState() => _AppointmentDetailsState(); } -class _AppointmentDetailsState extends State - with SingleTickerProviderStateMixin { - static TabController _tabController; +class _AppointmentDetailsState extends State with SingleTickerProviderStateMixin { + static TabController? _tabController; + + AppSharedPreferences sharedPref = AppSharedPreferences(); + List doctorDetailsList = []; - List doctorDetailsList = List(); + ToDoCountProviderModel? toDoProvider; + ProjectViewModel? projectViewModel; + + DoctorList doctorList = new DoctorList(); @override void initState() { - _tabController = new TabController(length: 2, vsync: this); AppointmentDetails.showFooterButton = false; + if (widget.doctorSchedule != null) { + _tabController = new TabController(length: 2, vsync: this, initialIndex: 1); + widget.appo.appointmentDate = widget.doctorSchedule['Date']; + } else { + _tabController = new TabController(length: 2, vsync: this); + } + doctorList.doctorID = widget.appo.doctorID; + doctorList.clinicID = widget.appo.clinicID; + doctorList.projectID = widget.appo.projectID; + setTab(); super.initState(); } - @override void dispose() { super.dispose(); - _tabController.dispose(); + _tabController!.dispose(); AppointmentDetails.showFooterButton = false; } @override Widget build(BuildContext context) { - ProjectViewModel projectViewModel = Provider.of(context); + projectViewModel = Provider.of(context); + + toDoProvider = Provider.of(context); + return AppScaffold( - appBarTitle: widget.appo.doctorNameObj, + appBarTitle: widget.appo!.doctorNameObj!, isShowAppBar: true, - bottomSheet: AppointmentDetails.showFooterButton - ? Container( - width: MediaQuery.of(context).size.width, - height: 50.0, - margin: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.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, - disabledTextColor: Colors.white, - disabledColor: new Color(0xFFbcc2c4), - onPressed: goToBookConfirm, - child: Text(TranslationBase.of(context).bookNow, - style: TextStyle(fontSize: 18.0)), - ), - ), - ) - : null, - body: Container( - color: new Color(0xFFf6f6f6), - child: SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - color: Colors.white, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - margin: EdgeInsets.only(top: 20.0), - alignment: Alignment.center, - child: ClipRRect( - borderRadius: BorderRadius.circular(100.0), - child: Image.network(widget.appo.doctorImageURL, - fit: BoxFit.fill, height: 120.0, width: 120.0), - ), - ), - Container( - margin: - EdgeInsets.only(top: 10.0, left: 10.0, right: 10.0), - alignment: Alignment.center, - child: Text( - widget.appo.doctorTitle + - " " + - widget.appo.doctorNameObj, - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 20.0, - color: Colors.grey[900], - letterSpacing: 1.0)), - ), - Container( - margin: EdgeInsets.only(top: 10.0), - alignment: Alignment.center, - child: Text(getDoctorSpeciality(widget.appo.doctorSpeciality), - style: TextStyle( - fontSize: 12.0, - color: Colors.grey[900], - letterSpacing: 1.0)), - ), - Container( - margin: EdgeInsets.only(top: 5.0), - alignment: Alignment.center, - child: RatingBar.readOnly( - initialRating: widget.appo.actualDoctorRate.toDouble(), - size: 35.0, - filledColor: Colors.yellow[700], - emptyColor: Colors.grey[500], - isHalfAllowed: true, - halfFilledIcon: Icons.star_half, - filledIcon: Icons.star, - emptyIcon: Icons.star, - ), - ), - InkWell( - onTap: () { - getDoctorRatingsDetails(); - }, - child: Container( - margin: EdgeInsets.only(top: 5.0), - alignment: Alignment.center, - child: Text( - "(" + - widget.appo.noOfPatientsRate.toString() + - " " + - TranslationBase.of(context).reviews + - ")", - style: TextStyle( - fontSize: 14.0, - color: Colors.blue[800], - letterSpacing: 1.0, - decoration: TextDecoration.underline, - )), - ), - ), - Container( - alignment: Alignment.center, - child: Text(DateUtil.getWeekDayMonthDayYearDateFormatted( - DateUtil.convertStringToDate( - widget.appo.appointmentDate), - projectViewModel.isArabic ? "ar" : "en")), - ), - Container( - alignment: Alignment.center, - child: Text(widget.appo.startTime.substring(0, 5)), - ), - Container( - margin: EdgeInsets.only(top: 10.0), - child: Divider( - color: Colors.grey[500], - ), - ), - TabBar( - onTap: (index) { - setState(() { - index == 1 - ? AppointmentDetails.showFooterButton = true - : AppointmentDetails.showFooterButton = false; - print(AppointmentDetails.showFooterButton); - }); - }, - tabs: [ - Tab( - child: Text(TranslationBase.of(context).appoActions, - style: TextStyle(color: Colors.black))), - Tab( - child: Text(TranslationBase.of(context).availableAppo, - style: TextStyle(color: Colors.black)), + showNewAppBar: true, + backgroundColor: Colors.white, + showNewAppBarTitle: true, + bottomSheet: _bottomButtons(), + body: SingleChildScrollView( + physics: BouncingScrollPhysics(), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + DoctorHeader( + headerModel: HeaderModel( + widget.appo.doctorTitle! + " " + widget.appo.doctorNameObj!, + widget.appo.doctorID!, + widget.appo.doctorImageURL!, + widget.appo.doctorSpeciality!, + "", + widget.appo.projectName ?? "", + DateUtil.convertStringToDate(widget.appo.appointmentDate!), + widget.appo.isLiveCareAppointment! ? DateUtil.convertStringToDate(widget.appo.appointmentDate!).toString().split(" ")[1].substring(0, 5) : widget.appo.startTime!.substring(0, 5), + "", + widget.appo.doctorRate, + widget.appo.actualDoctorRate, + widget.appo.noOfPatientsRate, + "", + decimalDoctorRate: widget.appo.decimalDoctorRate.toString() + //model.user.emailAddress, + ), + isNeedToShowButton: (widget.appo.clinicID == 17 || + widget.appo.clinicID == 47 || + widget.appo.clinicID == 23 || + widget.appo.clinicID == 265 || + widget.appo.clinicID == 134 || + widget.appo.clinicID == 253 || + widget.appo.isExecludeDoctor! || + widget.appo.isLiveCareAppointment!) + ? false + : true, + buttonTitle: TranslationBase.of(context).schedule, + buttonIcon: 'assets/images/new/Boo_ Appointment.svg', + showConfirmMessageDialog: false, + onRatingAndReviewTap: getDoctorRatingsDetails, + onTap: () { + Navigator.push( + context, + FadePage( + page: SchedulePage(doctorList: doctorList, appo: widget.appo), + ), + ).then((value) { + setState(() { + if (_tabController!.index == 0) { + _tabController!.animateTo((_tabController!.index + 1) % 2); + this.enableFooterButton(); + } + widget.doctorSchedule = value; + }); + }); + }, + ), + SizedBox(height: 10), + Material( + color: Color(0xffF8F8F8), + child: TabBar( + onTap: (index) { + setState(() { + if (index == 1) { + if ( + // widget.appo.clinicID == 17 || + widget.appo.clinicID == 47 || + widget.appo.clinicID == 23 || + widget.appo.clinicID == 253 || + widget.appo.clinicID == 265 || + widget.appo.clinicID == 134 || + widget.appo.clinicID == 253 || + widget.appo.isExecludeDoctor! || + widget.appo.isLiveCareAppointment!) { + _tabController!.index = _tabController!.previousIndex; + AppointmentDetails.showFooterButton = false; + } else { + AppointmentDetails.showFooterButton = true; + } + } + }); + }, + tabs: [ + Tab(child: Text(TranslationBase.of(context).appoActions, style: TextStyle(color: Colors.black))), + // widget.appo.clinicID == 17 || + widget.appo.clinicID == 23 || + widget.appo.clinicID == 47 || + widget.appo.clinicID == 265 || + widget.appo.clinicID == 253 || + widget.appo.clinicID == 134 || + widget.appo!.isExecludeDoctor! || + widget.appo!.isLiveCareAppointment! + ? Tab( + child: Text(TranslationBase.of(context).availableAppo, style: TextStyle(color: Colors.grey)), ) - ], - controller: _tabController, - ), - ], - ), + : Tab( + child: Text(TranslationBase.of(context).availableAppo, style: TextStyle(color: Colors.black)), + ) + ], + controller: _tabController, ), - Container( - height: MediaQuery.of(context).size.height * 0.87, - child: TabBarView( - physics: NeverScrollableScrollPhysics(), - children: [ - AppointmentActions( - appo: widget.appo, - tabController: _tabController, - enableFooterButton: enableFooterButton), - DocAvailableAppointments( - doctor: getDoctorObject(), - isLiveCareAppointment: - widget.appo.isLiveCareAppointment) - ], - controller: _tabController, - ), + ), + Container( + height: MediaQuery.of(context).size.height * 0.87, + color: Color(0xffF8F8F8), + child: TabBarView( + physics: NeverScrollableScrollPhysics(), + children: [ + AppointmentActions(appo: widget.appo, tabController: _tabController!, enableFooterButton: enableFooterButton, projectViewModel: projectViewModel!), + DocAvailableAppointments(doctor: getDoctorObject(), doctorSchedule: widget.doctorSchedule, isLiveCareAppointment: widget.appo.isLiveCareAppointment!) + ], + controller: _tabController, ), - ], - ), + ), + ], ), ), ); } + Widget _bottomButtons() { + if (widget.parentIndex == null) { + return SizedBox(); + } else { + List list = []; + if (widget.parentIndex == 0 && _tabController!.index == 0 && widget.appo.patientStatusType != 43) { + list.add( + Expanded( + child: DefaultButton( + TranslationBase.of(context).cancelAppointment, + () { + ConfirmDialog dialog = new ConfirmDialog( + context: context, + confirmMessage: TranslationBase.of(context).cancelAppoMsg, + okText: TranslationBase.of(context).confirm, + cancelText: TranslationBase.of(context).cancel_nocaps, + okFunction: cancelAppointment, + cancelFunction: () => {}); + dialog.showAlertDialog(context); + }, + color: CustomColors.accentColor, + textColor: CustomColors.white, + ), + ), + ); + list.add( + SizedBox(width: 8), + ); + list.add( + Expanded( + child: DefaultButton( + TranslationBase.of(context).confirm, + confirmAppointment, + color: Color(0xff359846), + ), + ), + ); + } else if (widget.parentIndex == 1 && _tabController!.index == 0) { + list.add( + Expanded( + child: DefaultButton( + TranslationBase.of(context).cancelAppointment, + () { + ConfirmDialog dialog = new ConfirmDialog( + context: context, + confirmMessage: TranslationBase.of(context).cancelAppoMsg, + okText: TranslationBase.of(context).confirm, + cancelText: TranslationBase.of(context).cancel_nocaps, + okFunction: cancelAppointment, + cancelFunction: () => {}); + dialog.showAlertDialog(context); + }, + color: CustomColors.accentColor, + // textColor: Color(0xff000000), + ), + ), + ); + } else if (_tabController!.index == 1) { + list.add( + Expanded( + child: DefaultButton( + TranslationBase.of(context).reviewAppointment, + goToBookConfirm, + // DocAvailableAppointments.areSlotsAvailable ? goToBookConfirm : null, + color: Color(0xFFD02127), + disabledColor: Color(0xff28323A).withOpacity(0.3), + ), + ), + ); + } + if (list.isEmpty) { + return SizedBox(); + } else + return Container( + color: Colors.white, + padding: EdgeInsets.only(top: 16, bottom: 16, right: 21, left: 21), + child: Row( + mainAxisSize: MainAxisSize.min, + children: list, + ), + ); + } + } + void enableFooterButton() { setState(() { AppointmentDetails.showFooterButton = true; @@ -228,27 +301,74 @@ class _AppointmentDetailsState extends State } void goToBookConfirm() { - if (DocAvailableAppointments.areSlotsAvailable) - navigateToBookConfirm(context); - else - AppToast.showErrorToast(message: "Please select Time Slot to continue"); + if (DocAvailableAppointments.selectedTime == TranslationBase.of(context).waitingAppointment) { + canPayForWalkInAppointment(); + } else { + if (DocAvailableAppointments.areSlotsAvailable) + navigateToBookConfirm(context); + else + AppToast.showErrorToast(message: TranslationBase.of(context).selectSlot); + } + } + + canPayForWalkInAppointment() { + DoctorsListService service = new DoctorsListService(); + GifLoaderDialogUtils.showMyDialog(context); + service.canPayForWalkInAppointment(widget.appo.clinicID!, widget.appo.projectID!, widget.appo.doctorID!).then((res) { + GifLoaderDialogUtils.hideDialog(context); + navigateToWaitingAppointment(context); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err, localContext: context); + print(err); + }); + } + + Future navigateToWaitingAppointment(context) async { + DoctorList doctor = new DoctorList(); + doctor.name = widget.appo.doctorNameObj; + doctor.clinicID = widget.appo.clinicID; + doctor.projectID = widget.appo.projectID; + doctor.doctorID = widget.appo.doctorID; + doctor.clinicName = widget.appo.clinicName; + doctor.projectName = widget.appo.projectName; + doctor.doctorTitle = widget.appo.doctorTitle; + doctor.doctorImageURL = widget.appo.doctorImageURL; + doctor.speciality = widget.appo.doctorSpeciality; + doctor.nationalityFlagURL = ""; + doctor.doctorRate = widget.appo.doctorRate; + doctor.noOfPatientsRate = widget.appo.noOfPatientsRate; + + projectViewModel?.setWaitingAppointmentProjectID(widget.appo.projectID!); + projectViewModel?.setWaitingAppointmentDoctor(doctor); + Navigator.push( + context, + FadePage( + page: WaitingAppointmentInfo(), + ), + ); } Future navigateToBookConfirm(context) async { Navigator.push( - context, - FadePage( - page: BookConfirm( - doctor: getDoctorObject(), - isLiveCareAppointment: widget.appo.isLiveCareAppointment, - selectedDate: DocAvailableAppointments.selectedDate, - selectedTime: DocAvailableAppointments.selectedTime))); + context, + FadePage( + page: BookConfirm( + doctor: getDoctorObject(), + isLiveCareAppointment: widget.appo.isLiveCareAppointment!, + selectedDate: DocAvailableAppointments.selectedDate!, + selectedTime: DocAvailableAppointments.selectedTime!, + initialSlotDuration: 0, + isWalkinAppointment: false, + ), + ), + ); } - getDoctorRatingsDetails() { + void getDoctorRatingsDetails() { GifLoaderDialogUtils.showMyDialog(context); DoctorsListService service = new DoctorsListService(); - service.getDoctorsRatingDetails(widget.appo.doctorID, context).then((res) { + service.getDoctorsRatingDetails(widget.appo.doctorID, projectViewModel!.isArabic ? 1 : 2, context).then((res) { GifLoaderDialogUtils.hideDialog(context); if (res['MessageStatus'] == 1) { doctorDetailsList.clear(); @@ -286,70 +406,74 @@ class _AppointmentDetailsState extends State child: Column( children: [ Container( - alignment: Alignment.center, width: MediaQuery.of(context).size.width, - color: Theme.of(context).primaryColor, margin: EdgeInsets.only(bottom: 5.0), padding: EdgeInsets.all(10.0), - child: Text( - TranslationBase.of(context).doctorRating, - style: TextStyle( - fontSize: 22.0, color: Colors.white))), + child: Text(TranslationBase.of(context).doctorRating, style: TextStyle(fontSize: 22.0, color: Colors.black))), Container( - margin: EdgeInsets.only(top: 0.0), - child: Text( - this - .widget - .appo - .actualDoctorRate - .ceilToDouble() - .toString(), - style: TextStyle( - fontSize: 32.0, color: Colors.black))), + margin: EdgeInsets.only(top: 0.0), child: Text(this.widget.appo.actualDoctorRate!.ceilToDouble().toString(), style: TextStyle(fontSize: 32.0, color: Colors.black))), Container( - margin: EdgeInsets.only(top: 5.0), - alignment: Alignment.center, - child: RatingBar.readOnly( - initialRating: - this.widget.appo.actualDoctorRate.toDouble(), - size: 35.0, - filledColor: Colors.yellow[700], - emptyColor: Colors.grey[500], - isHalfAllowed: true, - halfFilledIcon: Icons.star_half, - filledIcon: Icons.star, - emptyIcon: Icons.star, - ), - ), + margin: EdgeInsets.only(top: 5.0), + alignment: Alignment.center, + child: + // RatingBar.readOnly( + // initialRating: this.widget.appo.actualDoctorRate.toDouble(), + // size: 35.0, + // filledColor: Colors.yellow[700], + // emptyColor: Colors.grey[500], + // isHalfAllowed: true, + // halfFilledIcon: Icons.star_half, + // filledIcon: Icons.star, + // emptyIcon: Icons.star, + // ), + RatingBar( + initialRating: this.widget.appo.actualDoctorRate!.toDouble(), + direction: Axis.horizontal, + allowHalfRating: true, + itemCount: 5, + itemSize: 20, + ignoreGestures: true, + ratingWidget: RatingWidget( + full: Icon( + Icons.star, + color: CustomColors.accentColor, + ), + half: Icon( + Icons.star_half, + color: CustomColors.accentColor, + ), + empty: Icon( + Icons.star, + color: CustomColors.accentColor, + ), + ), + tapOnlyMode: true, + unratedColor: Colors.grey[500], + itemPadding: EdgeInsets.symmetric(horizontal: 4.0), + onRatingUpdate: (rating) { + print(rating); + }, + )), Container( margin: EdgeInsets.only(top: 10.0), - child: Text( - this.widget.appo.noOfPatientsRate.toString() + - " " + - TranslationBase.of(context).reviews, - style: TextStyle( - fontSize: 14.0, color: Colors.black))), + child: Text(this.widget.appo.noOfPatientsRate.toString() + " " + TranslationBase.of(context).reviews, style: TextStyle(fontSize: 14.0, color: Colors.black))), Container( margin: EdgeInsets.only(top: 10.0), child: Row( children: [ Container( width: 100.0, - margin: EdgeInsets.only( - top: 10.0, left: 15.0, right: 15.0), - child: Text( - TranslationBase.of(context).excellent, - style: TextStyle( - fontSize: 13.0, - color: Colors.black))), - Container( - margin: EdgeInsets.only(top: 10.0), - child: SizedBox( - width: getRatingWidth( - doctorDetailsList[0].patientNumber), - height: 6.0, - child: Container( - color: Colors.green[700], + margin: EdgeInsets.only(top: 10.0, left: 15.0, right: 15.0), + child: Text(TranslationBase.of(context).excellent, style: TextStyle(fontSize: 13.0, color: Colors.black))), + Expanded( + child: Container( + margin: EdgeInsets.only(top: 10.0), + child: SizedBox( + width: getRatingWidth(doctorDetailsList[0].patientNumber), + height: 6.0, + child: Container( + color: Colors.green[700], + ), ), ), ), @@ -361,18 +485,12 @@ class _AppointmentDetailsState extends State children: [ Container( width: 100.0, - margin: EdgeInsets.only( - top: 10.0, left: 15.0, right: 15.0), - child: Text( - TranslationBase.of(context).v_good, - style: TextStyle( - fontSize: 13.0, - color: Colors.black))), + margin: EdgeInsets.only(top: 10.0, left: 15.0, right: 15.0), + child: Text(TranslationBase.of(context).v_good, style: TextStyle(fontSize: 13.0, color: Colors.black))), Container( margin: EdgeInsets.only(top: 10.0), child: SizedBox( - width: getRatingWidth( - doctorDetailsList[1].patientNumber), + width: getRatingWidth(doctorDetailsList[1].patientNumber), height: 6.0, child: Container( color: Color(0xffB7B723), @@ -387,18 +505,12 @@ class _AppointmentDetailsState extends State children: [ Container( width: 100.0, - margin: EdgeInsets.only( - top: 10.0, left: 15.0, right: 15.0), - child: Text( - TranslationBase.of(context).good, - style: TextStyle( - fontSize: 13.0, - color: Colors.black))), + margin: EdgeInsets.only(top: 10.0, left: 15.0, right: 15.0), + child: Text(TranslationBase.of(context).good, style: TextStyle(fontSize: 13.0, color: Colors.black))), Container( margin: EdgeInsets.only(top: 10.0), child: SizedBox( - width: getRatingWidth( - doctorDetailsList[2].patientNumber), + width: getRatingWidth(doctorDetailsList[2].patientNumber), height: 6.0, child: Container( color: Color(0xffEBA727), @@ -413,18 +525,12 @@ class _AppointmentDetailsState extends State children: [ Container( width: 100.0, - margin: EdgeInsets.only( - top: 10.0, left: 15.0, right: 15.0), - child: Text( - TranslationBase.of(context).average, - style: TextStyle( - fontSize: 13.0, - color: Colors.black))), + margin: EdgeInsets.only(top: 10.0, left: 15.0, right: 15.0), + child: Text(TranslationBase.of(context).average, style: TextStyle(fontSize: 13.0, color: Colors.black))), Container( margin: EdgeInsets.only(top: 10.0), child: SizedBox( - width: getRatingWidth( - doctorDetailsList[3].patientNumber), + width: getRatingWidth(doctorDetailsList[3].patientNumber), height: 6.0, child: Container( color: Color(0xffEB7227), @@ -439,19 +545,12 @@ class _AppointmentDetailsState extends State children: [ Container( width: 100.0, - margin: EdgeInsets.only( - top: 10.0, left: 15.0, right: 15.0), - child: Text( - TranslationBase.of(context) - .below_average, - style: TextStyle( - fontSize: 13.0, - color: Colors.black))), + margin: EdgeInsets.only(top: 10.0, left: 15.0, right: 15.0), + child: Text(TranslationBase.of(context).below_average, style: TextStyle(fontSize: 13.0, color: Colors.black))), Container( margin: EdgeInsets.only(top: 10.0), child: SizedBox( - width: getRatingWidth( - doctorDetailsList[4].patientNumber), + width: getRatingWidth(doctorDetailsList[4].patientNumber), height: 6.0, child: Container( color: Color(0xffE20C0C), @@ -461,9 +560,7 @@ class _AppointmentDetailsState extends State ], ), ), - Container( - margin: EdgeInsets.only(top: 40.0), - child: Divider()), + Container(margin: EdgeInsets.only(top: 40.0), child: Divider()), Container( margin: EdgeInsets.only(top: 0.0), child: Align( @@ -474,20 +571,15 @@ class _AppointmentDetailsState extends State ), minWidth: MediaQuery.of(context).size.width, height: 40.0, - child: RaisedButton( + child: CustomTextButton( elevation: 0.0, - color: Colors.white, - textColor: Colors.red, - hoverColor: Colors.transparent, - focusColor: Colors.transparent, - highlightColor: Colors.transparent, - disabledColor: new Color(0xFFbcc2c4), + backgroundColor: Colors.white, + disabledForegroundColor: new Color(0xFFbcc2c4).withOpacity(0.38), + disabledBackgroundColor: new Color(0xFFbcc2c4).withOpacity(0.12), onPressed: () { Navigator.of(context).pop(); }, - child: Text( - TranslationBase.of(context).cancel, - style: TextStyle(fontSize: 18.0)), + child: Text(TranslationBase.of(context).cancel, style: TextStyle(fontSize: 18.0, color: Colors.red)), ), ), ), @@ -505,23 +597,19 @@ class _AppointmentDetailsState extends State barrierDismissible: true, barrierLabel: '', context: context, - pageBuilder: (context, animation1, animation2) {}); + pageBuilder: (context, animation1, animation2) { + return SizedBox(); + }); } double getRatingWidth(int patientNumber) { - var width = (patientNumber / this.widget.appo.noOfPatientsRate) * 100; + var width = (patientNumber / this.widget.appo.noOfPatientsRate!) * 100; return width; } String getDate(String date) { DateTime dateObj = DateUtil.convertStringToDate(date); - return DateUtil.getWeekDay(dateObj.weekday) + - ", " + - dateObj.day.toString() + - " " + - DateUtil.getMonth(dateObj.month) + - " " + - dateObj.year.toString(); + return DateUtil.getWeekDay(dateObj.weekday) + ", " + dateObj.day.toString() + " " + DateUtil.getMonth(dateObj.month) + " " + dateObj.year.toString(); } String getDoctorSpeciality(List docSpecial) { @@ -547,4 +635,97 @@ class _AppointmentDetailsState extends State docObj.doctorImageURL = widget.appo.doctorImageURL; return docObj; } + + void openSchedule() { + Navigator.push( + context, + FadePage( + page: SchedulePage( + doctorList: getDoctorObject(), + appo: widget.appo, + ))); + } + + setTab() async { + var scheduleDoctor = await sharedPref.getObject(DOCTOR_SCHEDULE_DATE_SEL); + if (scheduleDoctor != null) widget.appo.appointmentDate = scheduleDoctor['Date']; + } + + confirmAppointment() { + GifLoaderDialogUtils.showMyDialog(context); + DoctorsListService service = new DoctorsListService(); + service.confirmAppointment(widget.appo.appointmentNo!, widget.appo.clinicID!, widget.appo.projectID!, widget.appo.isLiveCareAppointment!, context).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res['MessageStatus'] == 1) { + AppToast.showSuccessToast(message: res['ErrorEndUserMessage']); + Navigator.of(context).pop(); + projectViewModel!.analytics.appointment.appointment_details_confirm(appointment: widget.appo); + } else { + AppToast.showErrorToast(message: res['ErrorEndUserMessage']); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } + + checkIfHasReminder() async { + CalendarUtils calendarUtils = await CalendarUtils.getInstance(); + + DateTime startEventsDate = DateUtil.convertStringToDate(widget.appo.appointmentDate!); + DateTime endEventsDate = DateUtil.convertStringToDate(widget.appo.appointmentDate!); + RetrieveEventsParams params = new RetrieveEventsParams(startDate: startEventsDate, endDate: endEventsDate); + if (calendarUtils.calendars.length > 1) { + calendarUtils.calendars.forEach((calender) { + calendarUtils.retrieveEvents(calender.id!, params).then((value) { + Result> events = value; + events.data!.forEach((element) { + if (element.title!.contains(widget.appo.doctorNameObj!)) calendarUtils.deleteEvent(calender, element); + }); + }); + }); + } else { + await calendarUtils.retrieveEvents(calendarUtils.calendars[0].id!, params).then((value) { + Result> events = value; + events.data!.forEach((element) { + if (element.title!.contains(widget.appo.doctorNameObj!)) calendarUtils.deleteEvent(calendarUtils.calendars[0], element); + }); + }); + } + } + + cancelAppointment() { + ConfirmDialog.closeAlertDialog(context); + GifLoaderDialogUtils.showMyDialog(context); + DoctorsListService service = new DoctorsListService(); + service.cancelAppointment(widget.appo, context).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res['MessageStatus'] == 1) { + checkIfHasReminder(); + getToDoCount(); + AppToast.showSuccessToast(message: res['ErrorEndUserMessage']); + Navigator.of(context).pop(); + projectViewModel!.analytics.appointment.appointment_details_cancel(appointment: widget.appo); + } else { + AppToast.showErrorToast(message: res['ErrorEndUserMessage']); + } + projectViewModel!.analytics.appointment.appointment_details_cancel(appointment: widget.appo, appointment_type: widget.appo!.isLiveCareAppointment! ? "livecare" : "regular"); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } + + getToDoCount() { + toDoProvider!.setState(0, 0, true, toDoProvider!.notificationsCount); + ClinicListService service = new ClinicListService(); + service.getActiveAppointmentNo(context).then((res) { + if (res['MessageStatus'] == 1) { + // toDoProvider.setState(res['AppointmentActiveNumber'], true, toDoProvider.notificationsCount); + toDoProvider!.setState(res['AppointmentActiveNumber'], res['AncillaryOrderListCount'], true, toDoProvider!.notificationsCount); + } else {} + }).catchError((err) { + print(err); + }); + } } diff --git a/lib/pages/MyAppointments/MyAppointments.dart b/lib/pages/MyAppointments/MyAppointments.dart index 5ed0fef4..44d06899 100644 --- a/lib/pages/MyAppointments/MyAppointments.dart +++ b/lib/pages/MyAppointments/MyAppointments.dart @@ -5,147 +5,133 @@ 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/Appointments/AppoimentAllHistoryResultList.dart'; +import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart'; import 'package:diplomaticquarterapp/pages/MyAppointments/models/AppointmentType.dart'; -import 'package:diplomaticquarterapp/pages/MyAppointments/widgets/AppointmentCardView.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; +import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.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/widgets/data_display/medical/doctor_card.dart'; +import 'package:diplomaticquarterapp/widgets/new_design/my_tab_view.dart'; import 'package:diplomaticquarterapp/widgets/others/app_expandable_notifier.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import 'AppointmentDetails.dart'; + class MyAppointments extends StatefulWidget { - List appoList = []; + @override + _MyAppointmentsState createState() => _MyAppointmentsState(); +} + +class _MyAppointmentsState extends State with SingleTickerProviderStateMixin { + List upcomingAppoList = []; + List arrivedAppoListNew = []; List bookedAppoList = []; List confirmedAppoList = []; List arrivedAppoList = []; - List _patientBookedAppointmentListHospital = List(); - List _patientConfirmedAppointmentListHospital = - List(); - List _patientArrivedAppointmentListHospital = List(); - - List _patientBookedAppointmentListClinic = List(); - List _patientConfirmedAppointmentListClinic = List(); - List _patientArrivedAppointmentListClinic = List(); + List _patientBookedAppointmentListHospital = []; + List _patientConfirmedAppointmentListHospital = []; + List _patientArrivedAppointmentListHospital = []; - @override - _MyAppointmentsState createState() => _MyAppointmentsState(); -} + List _patientBookedAppointmentListClinic = []; + List _patientConfirmedAppointmentListClinic = []; + List _patientArrivedAppointmentListClinic = []; -class _MyAppointmentsState extends State - with SingleTickerProviderStateMixin { - TabController _tabController; + List _patientBookedAndConfirmedAppointmentListHospital = []; + List _patientBookedAndConfirmedAppointmentListClinic = []; bool isDataLoaded = false; var sharedPref = new AppSharedPreferences(); - AuthenticatedUserObject authenticatedUserObject = - locator(); + AuthenticatedUserObject authenticatedUserObject = locator(); - List imagesInfo = List(); + List imagesInfo = []; - FilterType filterType; + FilterType? filterType; + + int _currentPage = 1; + + ToDoCountProviderModel? toDoProvider; + ProjectViewModel? projectViewModel; @override void initState() { - _tabController = new TabController(length: 3, vsync: this); filterType = FilterType.Clinic; WidgetsBinding.instance.addPostFrameCallback((_) { - if (Provider.of(context, listen: false).isLogin) - getPatientAppointmentHistory(); + if (Provider.of(context, listen: false).isLogin) getPatientAppointmentHistory(true, false); }); imagesInfo.add(ImagesInfo( - imageEn: - 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-appointment/en/0.png', - imageAr: - 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-appointment/ar/0.png')); + imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-appointment/en/0.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-appointment/ar/0.png')); imagesInfo.add(ImagesInfo( - imageEn: - 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-appointment/en/1.png', - imageAr: - 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-appointment/ar/1.png')); + imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-appointment/en/1.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-appointment/ar/1.png')); super.initState(); } + @override + void dispose() { + super.dispose(); + } + @override Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + toDoProvider = Provider.of(context); return AppScaffold( - appBarTitle: TranslationBase.of(context).myAppointments, + appBarTitle: TranslationBase.of(context).myAppointmentsList, isShowAppBar: true, imagesInfo: imagesInfo, + showNewAppBar: true, + backgroundColor: Color(0xffF8F8F8), + showNewAppBarTitle: true, + showDropDown: false, + dropdownIndexValue: _currentPage, + dropDownIndexChange: (index) { + setState(() { + _currentPage = index!; + }); + }, + dropDownList: [ + // TranslationBase.of(context).booked, + TranslationBase.of(context).upcoming, + TranslationBase.of(context).arrived, + ], description: TranslationBase.of(context).infoMyAppointments, body: Container( child: Column(children: [ - TabBar( - tabs: [ - Tab( - child: Text(TranslationBase.of(context).booked, - style: TextStyle(color: Colors.black))), - Tab( - child: Text(TranslationBase.of(context).confirmed, - style: TextStyle(color: Colors.black)), - ), - Tab( - child: Text(TranslationBase.of(context).arrived, - style: TextStyle(color: Colors.black)), - ) - ], - controller: _tabController, - ), - Divider( - color: Colors.grey[600], - thickness: 0.5, - ), Row( - children: [ - Expanded( - flex: 1, - child: InkWell( - onTap: () => setFilterType(FilterType.Clinic), - child: ListTile( - title: Text(TranslationBase.of(context).clinic), - leading: Radio( - value: FilterType.Clinic, - groupValue: filterType, - activeColor: Color(0xffB8382C), - onChanged: (FilterType value) { - setFilterType(value); - }, - ), - ), - ), - ), - Expanded( - flex: 1, - child: InkWell( - onTap: () => setFilterType(FilterType.Hospital), - child: ListTile( - title: Text(TranslationBase.of(context).hospital), - leading: Radio( - value: FilterType.Hospital, - groupValue: filterType, - activeColor: Color(0xffB8382C), - onChanged: (FilterType value) => setFilterType(value), - ), - ), - ), - ) + children: [ + MyTabView(TranslationBase.of(context).byClinic, FilterType.Clinic, filterType!, () { + setFilterType(FilterType.Clinic); + }), + MyTabView(TranslationBase.of(context).byHospital, FilterType.Hospital, filterType!, () { + setFilterType(FilterType.Hospital); + }), ], ), + SizedBox(height: 20), + Padding( + padding: EdgeInsets.only(left: 21, right: 21), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + myRadioButton(TranslationBase.of(context).upcoming, 1), + // myRadioButton(TranslationBase.of(context).upcoming, 1), + myRadioButton(TranslationBase.of(context).arrived, 2), + ], + ), + ), isDataLoaded ? Expanded( - child: new TabBarView( - physics: NeverScrollableScrollPhysics(), - children: [ - getBookedAppointments(), - getConfirmedAppointments(), - getArrivedAppointments() - ], - controller: _tabController, + child: IndexedStack( + index: _currentPage, + children: [getBookedAppointments(), getBookedAndConfirmedAppointments(), getArrivedAppointments()], ), ) : Container(), @@ -154,37 +140,43 @@ class _MyAppointmentsState extends State ); } - getPatientAppointmentHistory() { + getPatientAppointmentHistory(bool isForUpcoming, bool isForArrived) { + int? languageID = projectViewModel!.isArabic ? 1 : 2; GifLoaderDialogUtils.showMyDialog(context); DoctorsListService service = new DoctorsListService(); - widget.appoList.clear(); - widget.bookedAppoList.clear(); - widget.confirmedAppoList.clear(); - widget.arrivedAppoList.clear(); - widget._patientBookedAppointmentListHospital.clear(); - widget._patientConfirmedAppointmentListHospital.clear(); - widget._patientArrivedAppointmentListHospital.clear(); + upcomingAppoList.clear(); + arrivedAppoListNew.clear(); + + bookedAppoList.clear(); + confirmedAppoList.clear(); + arrivedAppoList.clear(); + + _patientBookedAppointmentListHospital.clear(); + _patientConfirmedAppointmentListHospital.clear(); + _patientArrivedAppointmentListHospital.clear(); + + _patientBookedAppointmentListClinic.clear(); + _patientConfirmedAppointmentListClinic.clear(); + _patientArrivedAppointmentListClinic.clear(); - widget._patientBookedAppointmentListClinic.clear(); - widget._patientConfirmedAppointmentListClinic.clear(); - widget._patientArrivedAppointmentListClinic.clear(); + _patientBookedAndConfirmedAppointmentListHospital.clear(); + _patientBookedAndConfirmedAppointmentListClinic.clear(); - service.getPatientAppointmentHistory(false, context).then((res) { - print(res['AppoimentAllHistoryResultList'].length); + service.getPatientAppointmentHistory(false, languageID, context, isForUpcomming: isForUpcoming, IsForArrived: isForArrived).then((res) { GifLoaderDialogUtils.hideDialog(context); setState(() { if (res['MessageStatus'] == 1) { - // setState(() { if (res['AppoimentAllHistoryResultList'].length != 0) { - // isDataLoaded = true; res['AppoimentAllHistoryResultList'].forEach((v) { - widget.appoList - .add(new AppoitmentAllHistoryResultList.fromJson(v)); + if (isForArrived) { + arrivedAppoListNew.add(new AppoitmentAllHistoryResultList.fromJson(v)); + } else { + upcomingAppoList.add(new AppoitmentAllHistoryResultList.fromJson(v)); + } }); - sortAppointmentList(); + sortAppointmentList(isForUpcoming, isForArrived); } else {} - // }); } else { AppToast.showErrorToast(message: res['ErrorEndUserMessage']); } @@ -194,7 +186,20 @@ class _MyAppointmentsState extends State GifLoaderDialogUtils.hideDialog(context); print(err); AppToast.showErrorToast(message: err); - Navigator.of(context).pop(); + }); + getToDoCount(); + } + + getToDoCount() { + toDoProvider!.setState(0, 0, true, "0"); + ClinicListService service = new ClinicListService(); + service.getActiveAppointmentNo(context).then((res) { + if (res['MessageStatus'] == 1) { + // toDoProvider.setState(res['AppointmentActiveNumber'], true, "0"); + toDoProvider!.setState(res['AppointmentActiveNumber'], res['AncillaryOrderListCount'], true, "0"); + } else {} + }).catchError((err) { + print(err); }); } @@ -210,242 +215,185 @@ class _MyAppointmentsState extends State return AppointmentType.isBooked(appo); } - sortAppointmentList() { - widget.appoList.forEach((v) { - if (isBooked(v)) { - widget.bookedAppoList.add(v); - } + sortAppointmentList(bool isForUpcoming, bool isForArrived) { + if (isForArrived) { + arrivedAppoListNew.forEach((v) { + if (isBooked(v)) { + bookedAppoList.add(v); + } - if (isConfirmed(v)) { - widget.confirmedAppoList.add(v); - } + if (isConfirmed(v)) { + confirmedAppoList.add(v); + } - if (isArrived(v)) { - widget.arrivedAppoList.add(v); - } - }); + if (isArrived(v)) { + arrivedAppoList.add(v); + } + }); + } else { + upcomingAppoList.forEach((v) { + if (isBooked(v)) { + bookedAppoList.add(v); + } - widget.bookedAppoList.forEach((element) { - List doctorByClinic = - widget._patientBookedAppointmentListClinic - .where( - (elementClinic) => - elementClinic.filterName == element.clinicName, - ) - .toList(); + if (isConfirmed(v)) { + confirmedAppoList.add(v); + } + + if (isArrived(v)) { + arrivedAppoList.add(v); + } + }); + } + + bookedAppoList.forEach((element) { + List doctorByClinic = _patientBookedAppointmentListClinic + .where( + (elementClinic) => elementClinic.filterName == element.clinicName, + ) + .toList(); if (doctorByClinic.length != 0) { - widget - ._patientBookedAppointmentListClinic[widget - ._patientBookedAppointmentListClinic - .indexOf(doctorByClinic[0])] - .patientDoctorAppointmentList - .add(element); + _patientBookedAppointmentListClinic[_patientBookedAppointmentListClinic.indexOf(doctorByClinic[0])].patientDoctorAppointmentList!.add(element); } else { - widget._patientBookedAppointmentListClinic.add(PatientAppointmentList( - filterName: element.clinicName, patientDoctorAppointment: element)); + _patientBookedAppointmentListClinic.add(PatientAppointmentList(filterName: element.clinicName, patientDoctorAppointment: element)); } - List doctorByHospital = - widget._patientBookedAppointmentListHospital - .where( - (elementClinic) => - elementClinic.filterName == element.projectName, - ) - .toList(); + List doctorByHospital = _patientBookedAppointmentListHospital + .where( + (elementClinic) => elementClinic.filterName == element.projectName, + ) + .toList(); if (doctorByHospital.length != 0) { - widget - ._patientBookedAppointmentListHospital[widget - ._patientBookedAppointmentListHospital - .indexOf(doctorByHospital[0])] - .patientDoctorAppointmentList - .add(element); + _patientBookedAppointmentListHospital[_patientBookedAppointmentListHospital.indexOf(doctorByHospital[0])].patientDoctorAppointmentList!.add(element); } else { - widget._patientBookedAppointmentListHospital.add(PatientAppointmentList( - filterName: element.projectName, - patientDoctorAppointment: element)); + _patientBookedAppointmentListHospital.add(PatientAppointmentList(filterName: element.projectName, patientDoctorAppointment: element)); } }); - widget.confirmedAppoList.forEach((element) { - List doctorByClinic = - widget._patientConfirmedAppointmentListClinic - .where( - (elementClinic) => - elementClinic.filterName == element.clinicName, - ) - .toList(); + confirmedAppoList.forEach((element) { + List doctorByClinic = _patientConfirmedAppointmentListClinic + .where( + (elementClinic) => elementClinic.filterName == element.clinicName, + ) + .toList(); if (doctorByClinic.length != 0) { - widget - ._patientConfirmedAppointmentListClinic[widget - ._patientConfirmedAppointmentListClinic - .indexOf(doctorByClinic[0])] - .patientDoctorAppointmentList - .add(element); + _patientConfirmedAppointmentListClinic[_patientConfirmedAppointmentListClinic.indexOf(doctorByClinic[0])].patientDoctorAppointmentList!.add(element); } else { - widget._patientConfirmedAppointmentListClinic.add( - PatientAppointmentList( - filterName: element.clinicName, - patientDoctorAppointment: element)); + _patientConfirmedAppointmentListClinic.add(PatientAppointmentList(filterName: element.clinicName, patientDoctorAppointment: element)); } - List doctorByHospital = - widget._patientConfirmedAppointmentListHospital - .where( - (elementClinic) => - elementClinic.filterName == element.projectName, - ) - .toList(); + List doctorByHospital = _patientConfirmedAppointmentListHospital + .where( + (elementClinic) => elementClinic.filterName == element.projectName, + ) + .toList(); if (doctorByHospital.length != 0) { - widget - ._patientConfirmedAppointmentListHospital[widget - ._patientConfirmedAppointmentListHospital - .indexOf(doctorByHospital[0])] - .patientDoctorAppointmentList - .add(element); + _patientConfirmedAppointmentListHospital[_patientConfirmedAppointmentListHospital.indexOf(doctorByHospital[0])].patientDoctorAppointmentList!.add(element); } else { - widget._patientConfirmedAppointmentListHospital.add( - PatientAppointmentList( - filterName: element.projectName, - patientDoctorAppointment: element)); + _patientConfirmedAppointmentListHospital.add(PatientAppointmentList(filterName: element.projectName, patientDoctorAppointment: element)); } + + //Merging Booked & Confirmed Appointments into Upcoming Tab + // _patientBookedAndConfirmedAppointmentListHospital.addAll(_patientConfirmedAppointmentListHospital); + // _patientBookedAndConfirmedAppointmentListClinic.addAll(_patientConfirmedAppointmentListClinic); }); - widget.arrivedAppoList.forEach((element) { - List doctorByClinic = - widget._patientArrivedAppointmentListClinic - .where( - (elementClinic) => - elementClinic.filterName == element.clinicName, - ) - .toList(); + arrivedAppoList.forEach((element) { + List doctorByClinic = _patientArrivedAppointmentListClinic + .where( + (elementClinic) => elementClinic.filterName == element.clinicName, + ) + .toList(); if (doctorByClinic.length != 0) { - widget - ._patientArrivedAppointmentListClinic[widget - ._patientArrivedAppointmentListClinic - .indexOf(doctorByClinic[0])] - .patientDoctorAppointmentList - .add(element); + _patientArrivedAppointmentListClinic[_patientArrivedAppointmentListClinic.indexOf(doctorByClinic[0])].patientDoctorAppointmentList!.add(element); } else { - widget._patientArrivedAppointmentListClinic.add(PatientAppointmentList( - filterName: element.clinicName, patientDoctorAppointment: element)); + _patientArrivedAppointmentListClinic.add(PatientAppointmentList(filterName: element.clinicName, patientDoctorAppointment: element)); } - List doctorByHospital = - widget._patientArrivedAppointmentListHospital - .where( - (elementClinic) => - elementClinic.filterName == element.projectName, - ) - .toList(); + List doctorByHospital = _patientArrivedAppointmentListHospital + .where( + (elementClinic) => elementClinic.filterName == element.projectName, + ) + .toList(); if (doctorByHospital.length != 0) { - widget - ._patientArrivedAppointmentListHospital[widget - ._patientArrivedAppointmentListHospital - .indexOf(doctorByHospital[0])] - .patientDoctorAppointmentList - .add(element); + _patientArrivedAppointmentListHospital[_patientArrivedAppointmentListHospital.indexOf(doctorByHospital[0])].patientDoctorAppointmentList!.add(element); } else { - widget._patientArrivedAppointmentListHospital.add( - PatientAppointmentList( - filterName: element.projectName, - patientDoctorAppointment: element)); + _patientArrivedAppointmentListHospital.add(PatientAppointmentList(filterName: element.projectName, patientDoctorAppointment: element)); } - openAppointmentsTab(); + // openAppointmentsTab(); }); + + //Merging Booked & Confirmed Appointments into Upcoming Tab + _patientBookedAndConfirmedAppointmentListHospital.addAll(_patientBookedAppointmentListHospital); + _patientBookedAndConfirmedAppointmentListClinic.addAll(_patientBookedAppointmentListClinic); + + _patientBookedAndConfirmedAppointmentListHospital.addAll(_patientConfirmedAppointmentListHospital); + _patientBookedAndConfirmedAppointmentListClinic.addAll(_patientConfirmedAppointmentListClinic); + } openAppointmentsTab() async { var flag = await this.sharedPref.getInt(IS_SEARCH_APPO); - + int? index; if (flag == 1) { - _tabController.index = 0; + index = 0; } else if (flag == 2) { - _tabController.index = 1; + index = 1; } else if (flag == 3) { - _tabController.index = 2; + index = 2; } else { - if (widget._patientBookedAppointmentListClinic.length != 0) { - _tabController.index = 0; - } else if (widget._patientConfirmedAppointmentListClinic.length != 0) { - _tabController.index = 1; - } else if (widget._patientArrivedAppointmentListClinic.length != 0) { - _tabController.index = 2; - return; + if (_patientBookedAppointmentListClinic.length != 0) { + index = 0; + } else if (_patientConfirmedAppointmentListClinic.length != 0) { + index = 1; + } else if (_patientArrivedAppointmentListClinic.length != 0) { + index = 2; + // return; } } + + _currentPage = index!; } Widget getBookedAppointments() { + // return _getAppointment(bookedAppoList.length, (filterType == FilterType.Clinic) ? _patientBookedAppointmentListClinic : _patientBookedAppointmentListHospital); + return Container(); + } + + Widget getBookedAndConfirmedAppointments() { + return _getAppointment( + (bookedAppoList.length + confirmedAppoList.length), (filterType == FilterType.Clinic) ? _patientBookedAndConfirmedAppointmentListClinic : _patientBookedAndConfirmedAppointmentListHospital); + } + + Widget _getAppointment(int _listLength, List _list) { return Container( child: Container( - child: widget.bookedAppoList.length != 0 - ? SingleChildScrollView( - physics: BouncingScrollPhysics(), - child: Column( - children: [ - ...List.generate( - filterType == FilterType.Clinic - ? widget._patientBookedAppointmentListClinic.length - : widget._patientBookedAppointmentListHospital.length, - (index) => AppExpandableNotifier( - title: filterType == FilterType.Clinic - ? widget - ._patientBookedAppointmentListClinic[index] - .filterName - : widget - ._patientBookedAppointmentListHospital[index] - .filterName, - bodyWidget: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: filterType == FilterType.Clinic - ? widget - ._patientBookedAppointmentListClinic[index] - .patientDoctorAppointmentList - .map((doctor) { - return AppointmentCard( - appo: doctor, - onReloadAppointmentHistory: - getPatientAppointmentHistory, - ); - }).toList() - : widget - ._patientBookedAppointmentListHospital[ - index] - .patientDoctorAppointmentList - .map((doctor) { - return AppointmentCard( - appo: doctor, - onReloadAppointmentHistory: - getPatientAppointmentHistory, - ); - }).toList(), - )), - ) - ], - ), - ) + child: _listLength != 0 + ? _appointmentExpandableList(_list) : Container( child: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ - Image.asset( - "assets/images/new-design/noAppointmentIcon.png"), + Image.asset("assets/images/new-design/noAppointmentIcon.png"), Container( margin: EdgeInsets.only(top: 10.0), - child: Text(TranslationBase.of(context).noBookedAppo, - style: TextStyle( - fontSize: 16.0, - )), + child: Text( + _currentPage == 0 + ? TranslationBase.of(context).noBookedAppo + : (_currentPage == 1 ? TranslationBase.of(context).noUpcomingAppointment : TranslationBase.of(context).noArrivedAppo), + style: TextStyle( + fontSize: 16.0, + ), + ), ), ], ), @@ -455,144 +403,83 @@ class _MyAppointmentsState extends State ); } + Widget _appointmentExpandableList(List _patientAppointmentList) { + return ListView.separated( + addAutomaticKeepAlives: true, + physics: BouncingScrollPhysics(), + padding: EdgeInsets.only(top: 12), + separatorBuilder: (context, index) { + return Container( + height: 12, + margin: EdgeInsets.only(left: 21, right: 21), + // color: Color(0xffD9D9D9), + ); + }, + itemBuilder: (context, index) { + List _appointmentAllHistoryResultList = _patientAppointmentList[index].patientDoctorAppointmentList!; + return AppExpandableNotifier( + title: _patientAppointmentList[index].filterName, + bodyWidget: ListView.separated( + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + padding: EdgeInsets.only(bottom: 14, top: 14, left: 21, right: 21), + itemBuilder: (context, _index) { + AppoitmentAllHistoryResultList _appointmentResult = _appointmentAllHistoryResultList[_index]; + bool _isSortByClinic = filterType == FilterType.Clinic; + + return DoctorCard( + onTap: () => Navigator.push( + context, + FadePage( + page: AppointmentDetails( + appo: _appointmentResult, + // parentIndex: _currentPage, + parentIndex: _appointmentResult.patientStatusType == 42 ? 1 : 0, + ), + ), + ).then((value) { + if (_currentPage == 1) { + getPatientAppointmentHistory(true, false); + } + if (_currentPage == 2) { + getPatientAppointmentHistory(false, true); + } + }), + isInOutPatient: _appointmentResult.isInOutPatient, + name: _appointmentResult.doctorTitle! + " " + _appointmentResult.doctorNameObj!, + projectID: _appointmentResult.projectID!, + // billNo: _appointmentResult.invoiceNo, + profileUrl: _appointmentResult.doctorImageURL, + subName: _isSortByClinic ? _appointmentResult.projectName : _appointmentResult.clinicName, + isLiveCareAppointment: _appointmentResult.isLiveCareAppointment, + date: DateUtil.convertStringToDate(_appointmentResult.appointmentDate!), + isSortByClinic: _isSortByClinic, + rating: _appointmentResult.actualDoctorRate + 0.0, + appointmentTime: _appointmentResult.isLiveCareAppointment! + ? DateUtil.convertStringToDate(_appointmentResult.appointmentDate).toString().split(" ")[1].substring(0, 5) + : _appointmentResult.startTime!.substring(0, 5), + // appointmentTime: _appointmentResult.startTime.substring(0, 5), + remainingTimeInMinutes: (_appointmentResult.patientStatusType == AppointmentType.BOOKED || _appointmentResult.patientStatusType == AppointmentType.CONFIRMED) + ? _appointmentResult.remaniningHoursTocanPay + : null + + //projectViewModel.isArabic ? DateUtil.getMonthDayYearDateFormattedAr(labOrder.orderDate) : DateUtil.getMonthDayYearDateFormatted(labOrder.orderDate), + ); + }, + separatorBuilder: (context, index) => SizedBox(height: 14), + itemCount: _appointmentAllHistoryResultList.length), + ); + }, + itemCount: _patientAppointmentList.length, + ); + } + Widget getConfirmedAppointments() { - return widget.confirmedAppoList.length != 0 - ? Container( - margin: EdgeInsets.only(top: 10.0), - child: SingleChildScrollView( - physics: BouncingScrollPhysics(), - child: Column( - children: [ - ...List.generate( - filterType == FilterType.Clinic - ? widget._patientConfirmedAppointmentListClinic.length - : widget - ._patientConfirmedAppointmentListHospital.length, - (index) => AppExpandableNotifier( - title: filterType == FilterType.Clinic - ? widget - ._patientConfirmedAppointmentListClinic[index] - .filterName - : widget - ._patientConfirmedAppointmentListHospital[index] - .filterName, - bodyWidget: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: filterType == FilterType.Clinic - ? widget - ._patientConfirmedAppointmentListClinic[index] - .patientDoctorAppointmentList - .map((doctor) { - return AppointmentCard( - appo: doctor, - onReloadAppointmentHistory: - getPatientAppointmentHistory, - ); - }).toList() - : widget - ._patientConfirmedAppointmentListHospital[ - index] - .patientDoctorAppointmentList - .map((doctor) { - return AppointmentCard( - appo: doctor, - onReloadAppointmentHistory: - getPatientAppointmentHistory, - ); - }).toList(), - )), - ) - ], - ), - ), - ) - : Container( - child: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Image.asset("assets/images/new-design/noAppointmentIcon.png"), - Container( - margin: EdgeInsets.only(top: 10.0), - child: Text(TranslationBase.of(context).noConfirmedAppo, - style: TextStyle( - fontSize: 16.0, - )), - ), - ], - ), - ), - ); + return _getAppointment(confirmedAppoList.length, (filterType == FilterType.Clinic) ? _patientConfirmedAppointmentListClinic : _patientConfirmedAppointmentListHospital); } Widget getArrivedAppointments() { - return widget.arrivedAppoList.length != 0 - ? Container( - margin: EdgeInsets.only(top: 10.0), - child: SingleChildScrollView( - physics: BouncingScrollPhysics(), - child: Column( - children: [ - ...List.generate( - filterType == FilterType.Clinic - ? widget._patientArrivedAppointmentListClinic.length - : widget._patientArrivedAppointmentListHospital.length, - (index) => AppExpandableNotifier( - title: filterType == FilterType.Clinic - ? widget._patientArrivedAppointmentListClinic[index] - .filterName - : widget._patientArrivedAppointmentListHospital[index] - .filterName, - bodyWidget: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: filterType == FilterType.Clinic - ? widget._patientArrivedAppointmentListClinic[index] - .patientDoctorAppointmentList - .map((doctor) { - return AppointmentCard( - appo: doctor, - onReloadAppointmentHistory: - getPatientAppointmentHistory, - ); - }).toList() - : widget - ._patientArrivedAppointmentListHospital[index] - .patientDoctorAppointmentList - .map((doctor) { - return AppointmentCard( - appo: doctor, - onReloadAppointmentHistory: - getPatientAppointmentHistory, - ); - }).toList(), - ), - ), - ) - ], - ), - ), - ) - : Container( - child: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Image.asset("assets/images/new-design/noAppointmentIcon.png"), - Container( - margin: EdgeInsets.only(top: 10.0), - child: Text(TranslationBase.of(context).noArrivedAppo, - style: TextStyle( - fontSize: 16.0, - )), - ), - ], - ), - ), - ); + return _getAppointment(arrivedAppoList.length, (filterType == FilterType.Clinic) ? _patientArrivedAppointmentListClinic : _patientArrivedAppointmentListHospital); } setFilterType(FilterType filterType) { @@ -600,4 +487,55 @@ class _MyAppointmentsState extends State this.filterType = filterType; }); } + + Widget myRadioButton(String _label, int _value) { + return InkWell( + onTap: () { + setState(() { + _currentPage = _value; + if (_value == 1) { + getPatientAppointmentHistory(true, false); + } + if (_value == 2) { + getPatientAppointmentHistory(false, true); + } + }); + }, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox( + width: 22, + height: 22, + child: Radio( + value: _value, + activeColor: _value == _currentPage ? Color(0xffD02127) : Color(0xffE8E8E8), + groupValue: _currentPage, + onChanged: (index) { + setState(() { + _currentPage = index!; + if (_value == 1) { + getPatientAppointmentHistory(true, false); + } + if (_value == 2) { + getPatientAppointmentHistory(false, true); + } + }); + }, + ), + ), + SizedBox(width: 10), + Text( + _label, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + color: Color(0xff575757), + letterSpacing: -0.56, + ), + ), + ], + ), + ); + } } diff --git a/lib/pages/MyAppointments/SchedulePage.dart b/lib/pages/MyAppointments/SchedulePage.dart new file mode 100644 index 00000000..a307c868 --- /dev/null +++ b/lib/pages/MyAppointments/SchedulePage.dart @@ -0,0 +1,535 @@ +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/viewModels/medical/medical_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; +import 'package:diplomaticquarterapp/pages/MyAppointments/models/DoctorScheduleResponse.dart'; +import 'package:diplomaticquarterapp/pages/MyAppointments/widgets/indicator.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.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/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class SchedulePage extends StatefulWidget { + DoctorList? doctorList; + AppoitmentAllHistoryResultList? appo; + + SchedulePage({ + this.appo, + this.doctorList, + }); + + @override + _SchedulePageState createState() => _SchedulePageState(); +} + +class _SchedulePageState extends State { + DoctorsListService? service; + PageController _pageController = PageController(); + double currentPage = 0; + int selectedindex = 0; + List weeks = []; + List doctorScheduleResponse = []; + int weekMS = 604800 * 1000; + DoctorList? doctorList; + List freeSlots = []; + bool isPageChange = false; + + AppSharedPreferences sharedPref = AppSharedPreferences(); + + @override + void initState() { + this.doctorList = widget.doctorList; + + super.initState(); + } + + @override + Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + return BaseView( + onModelReady: (model) => model.getDoctorSchedule(doctorList!), + allowAny: true, + builder: (_, model, widget) => BaseView( + onModelReady: (model2) => model2.getFreeSlots(doctorList!), + allowAny: true, + builder: (_, model2, widget2) { + if (model2.freeSlots.length > 0 && isPageChange == false && model2.state == ViewState.Idle) { + this.freeSlots = model2.freeSlots; + this.doctorScheduleResponse = model.getDoctorScheduleList; + + this.generateWeeksSchedules(); + } else if (model2.freeSlots.length == 0 && model2.state == ViewState.Idle) { + AppToast.showErrorToast(message: TranslationBase.of(context).emptySchedule, localContext: context); + Navigator.pop(context); + } + return AppScaffold( + appBarTitle: TranslationBase.of(context).schedule, + showNewAppBar: true, + showNewAppBarTitle: true, + isShowAppBar: true, + baseViewModel: model2, + isShowDecPage: false, + body: SizedBox( + height: MediaQuery.of(context).size.height, + child: Stack( + children: [ + Container( + margin: EdgeInsets.only(top: 40), + child: PageView.builder( + controller: _pageController, + itemCount: weeks.length, + onPageChanged: (index) { + setState(() { + isPageChange = true; + this.currentPage = index.toDouble(); + }); + }, + itemBuilder: (context, index) { + return Container( + child: ListView.builder( + itemCount: weeks[index].length, + itemBuilder: (context, index2) => InkWell( + onTap: () { + final weekDay = weeks[index][index2]['DayName']; + openBookAppointment(weeks[index][index2]); + projectViewModel.analytics.appointment.book_appointment_date_selection(appointment_type: 'regular', day: weekDay, doctor: doctorList!); + }, + child: Row( + children: [ + Expanded( + flex: 1, + child: Padding( + padding: projectViewModel.isArabic ? EdgeInsets.only(right: 17) : EdgeInsets.only(left: 17), + child: Row(children: [ + Column( + children: [ + Texts( + weeks[index][index2]['DayName'], + fontSize: 13, + fontWeight: projectViewModel.isArabic ? FontWeight.w600 : FontWeight.w500, + ), + Texts( + getDayMonths( + DateUtil.convertStringToDate( + weeks[index][index2]['Date'], + ), + ), + fontWeight: FontWeight.bold, + fontSize: 18, + ) + ], + ) + ])), + ), + Expanded( + flex: 3, + child: ClipRRect( + borderRadius: const BorderRadius.all(Radius.circular(20.0)), + child: Container( + padding: EdgeInsets.only(left: 10, right: 10, top: 15, bottom: 20), + margin: EdgeInsets.only(left: 20, right: 20, top: 7, bottom: 7), + decoration: BoxDecoration(boxShadow: [ + DateUtil.convertStringToDate(weeks[index][index2]['Date']).toString().substring(0, 10) == DateTime.now().toString().substring(0, 10) + ? BoxShadow(color: Colors.green, offset: Offset(projectViewModel.isArabic ? 5 : -5, 0)) + : BoxShadow( + color: Colors.grey[100]!, + blurRadius: 5, + spreadRadius: 4, + offset: Offset(0, 10), + ), + ], borderRadius: const BorderRadius.all(Radius.circular(10.0)), color: Colors.white), + child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ + DateUtil.convertStringToDate(weeks[index][index2]['Date']).toString().substring(0, 10) == DateTime.now().toString().substring(0, 10) + ? Texts( + TranslationBase.of(context).today, + color: Colors.green, + fontWeight: FontWeight.w600, + fontSize: 12, + marginTop: 0, + ) + : SizedBox(), + Row( + children: [ + Expanded( + child: Text( + weeks[index][index2]['WorkingHours'], + style: TextStyle( + fontWeight: FontWeight.w600, + ), + ), + ), + Icon(Icons.arrow_forward, size: 16.0), + ], + ) + ]))), + ), + ], + )))); + }, + )), + PageViewIndicator( + isActive: true, + currentPage: this.currentPage, + length: weeks.length, + ) + ], + ))); + })); + } + + generateWeeksSchedules() { + this.weeks.clear(); + for (var i = 0; i < 8; i++) { + var weekSchedule = generateNewWeekSchedule(i); + this.markWeekFreeDays(weekSchedule); + this.weeks.add(weekSchedule); + } + //print(this.weeks); + } + + markWeekFreeDays(schedule) { + for (var workDay in schedule) { + workDay['fullDay'] = !this.hasFreeSlot(workDay['Date']); + } + } + + generateNewWeekSchedule(weekIndex) { + var weekMSOffset = weekIndex * weekMS; + + var newWeekSchedule = []; + for (var workDay in this.doctorScheduleResponse) { + Map newWorkDay = Map(); + newWorkDay['Date'] = DateUtil.convertDateMSToJsonDate(DateUtil.convertStringToDate(workDay.date!).millisecondsSinceEpoch + weekMSOffset); + newWorkDay['DayName'] = workDay.dayName; + newWorkDay['WorkingHours'] = workDay.workingHours; + newWeekSchedule.add(newWorkDay); + } + return newWeekSchedule; + } + + hasFreeSlot(String jsonDate) { + var date = DateUtil.convertStringToDate(jsonDate); + var scheduleDay = date; + for (var event in this.freeSlots) { + var date = DateUtil.convertStringToDate(event); + var nDate = DateTime(date.year, date.month, date.day); + + if (nDate.millisecondsSinceEpoch == scheduleDay.millisecondsSinceEpoch) { + return true; + } + } + return false; + } + + String getDayMonths(DateTime dateTime) { + String dateFormat = '${dateTime.day} ${DateUtil.getMonth(dateTime.month).toString().substring(0, 3)}'; + return dateFormat; + } + + openBookAppointment(selectedDate) { + //sharedPref.setObject(DOCTOR_SCHEDULE_DATE_SEL, selectedDate); + Navigator.of(context).pop(selectedDate); + // Navigator.push( + // context, + // FadePage( + // page: AppointmentDetails( + // appo: widget.appo, + // doctorSchedule: selectedDate, + // ), + // ), + // ); + } +} + +// import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; +// import 'package:diplomaticquarterapp/pages/MyAppointments/AppointmentDetails.dart'; +// +// import 'package:diplomaticquarterapp/pages/MyAppointments/models/DoctorScheduleResponse.dart'; +// import 'package:diplomaticquarterapp/pages/MyAppointments/widgets/indicator.dart'; +// import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; +// import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +// import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +// import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +// import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +// import 'package:flutter/material.dart'; +// import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +// import 'package:diplomaticquarterapp/core/viewModels/medical/medical_view_model.dart'; +// import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +// import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; +// import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +// import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; +// import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +// import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +// import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +// import 'package:provider/provider.dart'; +// import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +// +// class SchedulePage extends StatefulWidget { +// DoctorList doctorList; +// AppoitmentAllHistoryResultList appo; +// SchedulePage({ +// this.appo, +// this.doctorList, +// }); +// @override +// _SchedulePageState createState() => _SchedulePageState(); +// } +// +// class _SchedulePageState extends State { +// DoctorsListService service; +// PageController _pageController = PageController(); +// double currentPage = 0; +// int selectedindex = 0; +// List weeks = []; +// List doctorScheduleResponse = []; +// int weekMS = 604800 * 1000; +// DoctorList doctorList; +// List freeSlots = []; +// bool isPageChange = false; +// +// AppSharedPreferences sharedPref = AppSharedPreferences(); +// @override +// void initState() { +// this.doctorList = widget.doctorList; +// +// super.initState(); +// } +// +// @override +// Widget build(BuildContext context) { +// ProjectViewModel projectViewModel = Provider.of(context); +// return BaseView( +// onModelReady: (model) => model.getDoctorSchedule(doctorList), +// allowAny: true, +// builder: (_, model, widget) => BaseView( +// onModelReady: (model2) => model2.getFreeSlots(doctorList), +// allowAny: true, +// builder: (_, model2, widget2) { +// if (model2.freeSlots.length > 0 && isPageChange == false && model2.state == ViewState.Idle) { +// this.freeSlots = model2.freeSlots; +// this.doctorScheduleResponse = model.getDoctorScheduleList; +// +// this.generateWeeksSchedules(); +// } else if (model2.freeSlots.length == 0 && model2.state == ViewState.Idle) { +// AppToast.showErrorToast(message: TranslationBase.of(context).emptySchedule); +// Navigator.pop(context); +// } +// return AppScaffold( +// appBarTitle: TranslationBase.of(context).schedule, +// showNewAppBar: true, +// showNewAppBarTitle: true, +// isShowAppBar: true, +// backgroundColor: Color(0xffF7F7F7), +// baseViewModel: model2, +// isShowDecPage: false, +// body: Column( +// children: [ +// SizedBox(height: 21), +// PageViewIndicator( +// isActive: true, +// currentPage: this.currentPage, +// length: weeks.length, +// ), +// Expanded( +// child: PageView.builder( +// controller: _pageController, +// itemCount: weeks.length, +// onPageChanged: (index) { +// setState(() { +// isPageChange = true; +// this.currentPage = index.toDouble(); +// }); +// }, +// itemBuilder: (context, index) { +// return ListView.separated( +// itemCount: weeks[index].length, +// padding: EdgeInsets.all(21), +// separatorBuilder: (context, index) => SizedBox(height: 12), +// itemBuilder: (context, index2) { +// bool isToday = DateUtil.convertStringToDate(weeks[index][index2]['Date']).toString().substring(0, 10) == DateTime.now().toString().substring(0, 10); +// Color toDayColor = isToday ? Color(0xff359846) : Colors.white; +// return InkWell( +// onTap: () { +// openBookAppointment(weeks[index][index2]); +// }, +// child: Row( +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// Expanded( +// flex: 1, +// child: Column( +// mainAxisSize: MainAxisSize.min, +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// Text( +// weeks[index][index2]['DayName'], +// style: TextStyle( +// fontSize: 13, +// fontWeight: FontWeight.w600, +// color: Color(0xff2E303A), +// letterSpacing: -0.52, +// ), +// ), +// Text( +// getDayMonths(DateUtil.convertStringToDate(weeks[index][index2]['Date'])), +// style: TextStyle( +// fontSize: 18, +// fontWeight: FontWeight.w700, +// color: Color(0xff2E303A), +// letterSpacing: -0.72, +// ), +// ), +// ], +// ), +// ), +// Expanded( +// flex: 3, +// child: Container( +// decoration: BoxDecoration( +// color: toDayColor, +// borderRadius: BorderRadius.all( +// Radius.circular(10.0), +// ), +// 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: 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), +// ), +// ), +// child: Row( +// crossAxisAlignment: CrossAxisAlignment.center, +// children: [ +// Expanded( +// child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ +// if (isToday) +// Text( +// TranslationBase.of(context).today, +// style: TextStyle( +// fontSize: 12, +// fontWeight: FontWeight.w600, +// color: toDayColor, +// letterSpacing: -0.48, +// ), +// ), +// Row( +// children: [ +// Expanded( +// child: Text( +// weeks[index][index2]['WorkingHours'], +// style: TextStyle( +// fontSize: 13, +// fontWeight: FontWeight.w600, +// color: Color(0xff2E303A), +// letterSpacing: -0.56, +// ), +// ), +// ), +// ], +// ) +// ]), +// ), +// Icon(Icons.arrow_forward, color: Color(0xff2B353E)), +// ], +// ), +// ), +// ), +// ), +// ], +// ), +// ); +// }); +// }, +// ), +// ), +// ], +// ), +// ); +// }), +// ); +// } +// +// generateWeeksSchedules() { +// this.weeks.clear(); +// for (var i = 0; i < 8; i++) { +// var weekSchedule = generateNewWeekSchedule(i); +// this.markWeekFreeDays(weekSchedule); +// this.weeks.add(weekSchedule); +// } +// //print(this.weeks); +// } +// +// markWeekFreeDays(schedule) { +// for (var workDay in schedule) { +// workDay['fullDay'] = !this.hasFreeSlot(workDay['Date']); +// } +// } +// +// generateNewWeekSchedule(weekIndex) { +// var weekMSOffset = weekIndex * weekMS; +// +// var newWeekSchedule = []; +// for (var workDay in this.doctorScheduleResponse) { +// Map newWorkDay = Map(); +// newWorkDay['Date'] = DateUtil.convertDateMSToJsonDate(DateUtil.convertStringToDate(workDay.date).millisecondsSinceEpoch + weekMSOffset); +// newWorkDay['DayName'] = workDay.dayName; +// newWorkDay['WorkingHours'] = workDay.workingHours; +// newWeekSchedule.add(newWorkDay); +// } +// return newWeekSchedule; +// } +// +// hasFreeSlot(String jsonDate) { +// var date = DateUtil.convertStringToDate(jsonDate); +// var scheduleDay = date; +// for (var event in this.freeSlots) { +// var date = DateUtil.convertStringToDate(event); +// var nDate = DateTime(date.year, date.month, date.day); +// +// if (nDate.millisecondsSinceEpoch == scheduleDay.millisecondsSinceEpoch) { +// return true; +// } +// } +// return false; +// } +// +// String getDayMonths(DateTime dateTime) { +// String dateFormat = '${dateTime.day} ${DateUtil.getMonth(dateTime.month).toString().substring(0, 3)}'; +// return dateFormat; +// } +// +// openBookAppointment(selectedDate) { +// //sharedPref.setObject(DOCTOR_SCHEDULE_DATE_SEL, selectedDate); +// Navigator.of(context).pop(selectedDate); +// // Navigator.push( +// // context, +// // FadePage( +// // page: AppointmentDetails( +// // appo: widget.appo, +// // doctorSchedule: selectedDate, +// // ), +// // ), +// // ); +// } +// } diff --git a/lib/pages/MyAppointments/VisitTicket.dart b/lib/pages/MyAppointments/VisitTicket.dart index 6f1dbdf8..fd12e95b 100644 --- a/lib/pages/MyAppointments/VisitTicket.dart +++ b/lib/pages/MyAppointments/VisitTicket.dart @@ -1,3 +1,4 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; import 'package:diplomaticquarterapp/pages/BookAppointment/widgets/DoctorView.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; @@ -7,6 +8,7 @@ import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/progress_indicator/app_circular_progress_Indeicator.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; class VisitTicket extends StatefulWidget { List appoList = []; @@ -17,6 +19,7 @@ class VisitTicket extends StatefulWidget { class _VisitTicketState extends State { bool isLoading = false; + ProjectViewModel? projectViewModel; @override void initState() { @@ -26,6 +29,7 @@ class _VisitTicketState extends State { @override Widget build(BuildContext context) { + projectViewModel = Provider.of(context); return AppScaffold( appBarTitle: TranslationBase.of(context).todoList, body: isLoading == false @@ -48,11 +52,11 @@ class _VisitTicketState extends State { } getPatientAppointmentCurfewHistory(BuildContext context) { + int languageID = projectViewModel!.isArabic ? 1 : 2; DoctorsListService service = new DoctorsListService(); GifLoaderDialogUtils.showMyDialog(context); - service.getPatientAppointmentHistory(true, context).then((res) { + service.getPatientAppointmentHistory(true, languageID, context).then((res) { GifLoaderDialogUtils.hideDialog(context); - print(res['AppoimentAllHistoryResultList']); if (res['MessageStatus'] == 1) { setState(() { if (res['AppoimentAllHistoryResultList'].length != 0) { diff --git a/lib/pages/MyAppointments/models/ArrivedButtons.dart b/lib/pages/MyAppointments/models/ArrivedButtons.dart index 136bd30f..5cac41dd 100644 --- a/lib/pages/MyAppointments/models/ArrivedButtons.dart +++ b/lib/pages/MyAppointments/models/ArrivedButtons.dart @@ -6,50 +6,50 @@ class ArrivedButtons { { "title": TranslationBase.of(AppGlobal.context).medicines, "subtitle": TranslationBase.of(AppGlobal.context).medicinesSubtitle, - "icon": "assets/images/new-design/medicine_prescriptions_icon.png", - "caller": "prescriptions" + "icon": "medicine_prescription.svg", + "caller": "prescriptions", }, { "title": TranslationBase.of(AppGlobal.context).radiology, "subtitle": TranslationBase.of(AppGlobal.context).radiologySubtitle, - "icon": "assets/images/new-design/radiology_service_icon.png", - "caller": "radiology" + "icon": 'radiology.svg', + "caller": "radiology", }, { "title": TranslationBase.of(AppGlobal.context).lab, "subtitle": TranslationBase.of(AppGlobal.context).labSubtitle, - "icon": "assets/images/new-design/lab_result_icon.png", - "caller": "labResult" + "icon": 'lab_result.svg', + "caller": "labResult", }, { "title": TranslationBase.of(AppGlobal.context).vitalSigns, "subtitle": TranslationBase.of(AppGlobal.context).vitalSignsSubtitle, - "icon": "assets/images/new-design/vital_signs.png", - "caller": "VitalSigns" + "icon": 'vital_signs.svg', + "caller": "VitalSigns", }, { "title": TranslationBase.of(AppGlobal.context).raise, "subtitle": TranslationBase.of(AppGlobal.context).complaint, - "icon": "assets/images/new-design/Complaint_icon.png", - "caller": "insertComplaint" + "icon": "raise_comp.svg", + "caller": "insertComplaint", }, { "title": TranslationBase.of(AppGlobal.context).insuranceApproval, - "subtitle": TranslationBase.of(AppGlobal.context).insuranceSubtitle, - "icon": "assets/images/new-design/insurance_approvals_icon.png", - "caller": "Insurance" + "subtitle": TranslationBase.of(AppGlobal.context).insuranceApprovalSubtitle, + "icon": 'insurance_approval.svg', + "caller": "Insurance", }, { "title": TranslationBase.of(AppGlobal.context).askDoctor, - "subtitle": TranslationBase.of(AppGlobal.context).askYourSubtitle, - "icon": "assets/images/new-design/ask_doctor_icon.png", - "caller": "askDoc" + "subtitle": TranslationBase.of(AppGlobal.context).service, + "icon": 'ask_doctor.svg', + "caller": "askDoc", }, { - "title": TranslationBase.of(AppGlobal.context).appoSurvey, - "subtitle": TranslationBase.of(AppGlobal.context).service, - "icon": "assets/images/new-design/survey.png", - "caller": "Survey" + "title": TranslationBase.of(AppGlobal.context).service, + "subtitle": TranslationBase.of(AppGlobal.context).appoSurvey, + "icon": "survey.svg", + "caller": "Survey", } ]; -} \ No newline at end of file +} diff --git a/lib/pages/MyAppointments/models/AskDocRequestTypeModel.dart b/lib/pages/MyAppointments/models/AskDocRequestTypeModel.dart index 6b276ef0..491d3f7a 100644 --- a/lib/pages/MyAppointments/models/AskDocRequestTypeModel.dart +++ b/lib/pages/MyAppointments/models/AskDocRequestTypeModel.dart @@ -1,24 +1,24 @@ class AskDocRequestType { - String setupID; - int parameterGroup; - int parameterType; - int parameterCode; - String description; - String descriptionN; - String alias; - String aliasN; - String prefix; - String suffix; - String isColorCodingRequired; - String backColor; - String foreColor; - bool isBuiltIn; - bool isActive; - int createdBy; - String createdOn; - String editedBy; - String editedOn; - String rowVer; + String? setupID; + int? parameterGroup; + int? parameterType; + int? parameterCode; + String? description; + String? descriptionN; + String? alias; + String? aliasN; + String? prefix; + String? suffix; + String? isColorCodingRequired; + String? backColor; + String? foreColor; + bool? isBuiltIn; + bool? isActive; + int? createdBy; + String? createdOn; + String? editedBy; + String? editedOn; + String? rowVer; AskDocRequestType( {this.setupID, diff --git a/lib/pages/MyAppointments/models/BookedButtons.dart b/lib/pages/MyAppointments/models/BookedButtons.dart index 709b3b1f..39aed7cc 100644 --- a/lib/pages/MyAppointments/models/BookedButtons.dart +++ b/lib/pages/MyAppointments/models/BookedButtons.dart @@ -3,41 +3,43 @@ import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; class BookedButtons { var buttons = [ - { - "title": TranslationBase.of(AppGlobal.context).confirm, - "subtitle": TranslationBase.of(AppGlobal.context).appointment, - "icon": "assets/images/new-design/confirm_icon.png", - "caller": "confirmAppointment" - }, + // { + // "title": TranslationBase.of(AppGlobal.context).confirm, + // "subtitle": TranslationBase.of(AppGlobal.context).appointment, + // "icon": "assets/images/new-design/confirm_icon.png", + // "caller": "confirmAppointment", + // }, { "title": TranslationBase.of(AppGlobal.context).reschedule, "subtitle": TranslationBase.of(AppGlobal.context).appointment, - "icon": "assets/images/new-design/reschedule_icon.png", - "caller": "openReschedule" - }, - { - "title": TranslationBase.of(AppGlobal.context).cancel_nocaps, - "subtitle": TranslationBase.of(AppGlobal.context).appointment, - "icon": "assets/images/new-design/cancel_icon.png", - "caller": "onCancelAppointment" + "icon": "reschedule.svg", + "caller": "openReschedule", }, + // { + // "title": TranslationBase.of(AppGlobal.context).cancel_nocaps, + // "subtitle": TranslationBase.of(AppGlobal.context).appointment, + // "icon": "assets/images/new-design/cancel_icon.png", + // "caller": "onCancelAppointment", + // }, { "title": TranslationBase.of(AppGlobal.context).raise, "subtitle": TranslationBase.of(AppGlobal.context).complaint, - "icon": "assets/images/new-design/Complaint_icon.png", - "caller": "insertComplaint" + "icon": "raise_comp.svg", + "caller": "insertComplaint", }, { "title": TranslationBase.of(AppGlobal.context).add, "subtitle": TranslationBase.of(AppGlobal.context).reminder, - "icon": "assets/images/new-design/reminder_icon.png", - "caller": "addReminder" + "icon": "add_reminder.svg", + "caller": "addReminder", }, { "title": TranslationBase.of(AppGlobal.context).hospital, "subtitle": TranslationBase.of(AppGlobal.context).location, - "icon": "assets/images/new-design/location_icon.png", - "caller": "navigateToProject" - } + "icon": "hosp_location.svg", + "caller": "navigateToProject", + }, + {"title": TranslationBase.of(AppGlobal.context).online, "subtitle": TranslationBase.of(AppGlobal.context).payment, "icon": "online_payment.svg", "caller": "goToTodoList"}, + // {"title": TranslationBase.of(AppGlobal.context).clinic, "subtitle": TranslationBase.of(AppGlobal.context).locationa, "icon": "hosp_location.svg", "caller": "goToNavigation"} ]; } diff --git a/lib/pages/MyAppointments/models/BookedButtonsAllowCheckIn.dart b/lib/pages/MyAppointments/models/BookedButtonsAllowCheckIn.dart index 9548b7c8..1062eaf3 100644 --- a/lib/pages/MyAppointments/models/BookedButtonsAllowCheckIn.dart +++ b/lib/pages/MyAppointments/models/BookedButtonsAllowCheckIn.dart @@ -7,43 +7,43 @@ class BookedButtonsAllowCheckIn { "title": TranslationBase.of(AppGlobal.context).confirm, "subtitle": TranslationBase.of(AppGlobal.context).appointment, "icon": "assets/images/new-design/confirm_icon.png", - "caller": "confirmAppointment" + "caller": "confirmAppointment", }, { "title": TranslationBase.of(AppGlobal.context).reschedule, "subtitle": TranslationBase.of(AppGlobal.context).appointment, - "icon": "assets/images/new-design/reschedule_icon.png", - "caller": "openReschedule" + "icon": "reschedule.svg", + "caller": "openReschedule", }, { "title": TranslationBase.of(AppGlobal.context).cancel_nocaps, "subtitle": TranslationBase.of(AppGlobal.context).appointment, "icon": "assets/images/new-design/cancel_icon.png", - "caller": "onCancelAppointment" + "caller": "onCancelAppointment", }, { "title": TranslationBase.of(AppGlobal.context).raise, "subtitle": TranslationBase.of(AppGlobal.context).complaint, - "icon": "assets/images/new-design/Complaint_icon.png", - "caller": "insertComplaint" + "icon": "raise_comp.svg", + "caller": "insertComplaint", }, { "title": TranslationBase.of(AppGlobal.context).add, "subtitle": TranslationBase.of(AppGlobal.context).reminder, "icon": "assets/images/new-design/reminder_icon.png", - "caller": "addReminder" + "caller": "addReminder", }, { "title": TranslationBase.of(AppGlobal.context).hospital, "subtitle": TranslationBase.of(AppGlobal.context).location, "icon": "assets/images/new-design/location_icon.png", - "caller": "navigateToProject" + "caller": "navigateToProject", }, { "title": TranslationBase.of(AppGlobal.context).online, "subtitle": TranslationBase.of(AppGlobal.context).payment, "icon": "assets/images/new-design/check-in.png", - "caller": "goToTodoList" + "caller": "goToTodoList", } ]; } diff --git a/lib/pages/MyAppointments/models/ConfirmedButtons.dart b/lib/pages/MyAppointments/models/ConfirmedButtons.dart index b02021c7..d49723e9 100644 --- a/lib/pages/MyAppointments/models/ConfirmedButtons.dart +++ b/lib/pages/MyAppointments/models/ConfirmedButtons.dart @@ -3,47 +3,23 @@ import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; class ConfirmedButtons { var buttons = [ - { - "title": TranslationBase.of(AppGlobal.context).reschedule, - "subtitle": TranslationBase.of(AppGlobal.context).appointment, - "icon": "assets/images/new-design/reschedule_icon.png", - "caller": "openReschedule" - }, - { - "title": TranslationBase.of(AppGlobal.context).cancel_nocaps, - "subtitle": TranslationBase.of(AppGlobal.context).appointment, - "icon": "assets/images/new-design/cancel_icon.png", - "caller": "onCancelAppointment" - }, - { - "title": TranslationBase.of(AppGlobal.context).raise, - "subtitle": TranslationBase.of(AppGlobal.context).complaint, - "icon": "assets/images/new-design/Complaint_icon.png", - "caller": "insertComplaint" - }, - { - "title": TranslationBase.of(AppGlobal.context).add, - "subtitle": TranslationBase.of(AppGlobal.context).reminder, - "icon": "assets/images/new-design/reminder_icon.png", - "caller": "addReminder" - }, - { - "title": TranslationBase.of(AppGlobal.context).hospital, - "subtitle": TranslationBase.of(AppGlobal.context).location, - "icon": "assets/images/new-design/location_icon.png", - "caller": "navigateToProject" - }, + {"title": TranslationBase.of(AppGlobal.context).reschedule, "subtitle": TranslationBase.of(AppGlobal.context).appointment, "icon": "reschedule.svg", "caller": "openReschedule"}, + // { + // "title": TranslationBase.of(AppGlobal.context).cancel_nocaps, + // "subtitle": TranslationBase.of(AppGlobal.context).appointment, + // "icon": "assets/images/new-design/cancel_icon.png", + // "caller": "onCancelAppointment" + // }, + {"title": TranslationBase.of(AppGlobal.context).raise, "subtitle": TranslationBase.of(AppGlobal.context).complaint, "icon": "raise_comp.svg", "caller": "insertComplaint"}, + {"title": TranslationBase.of(AppGlobal.context).add, "subtitle": TranslationBase.of(AppGlobal.context).reminder, "icon": "add_reminder.svg", "caller": "addReminder"}, + {"title": TranslationBase.of(AppGlobal.context).hospital, "subtitle": TranslationBase.of(AppGlobal.context).location, "icon": "hosp_location.svg", "caller": "navigateToProject"}, // { // "title": "Generate", // "subtitle": "Visit Ticket", // "icon": "assets/images/new-design/generate_visit_ticket.png", // "caller": "visitTicket" // }, - { - "title": TranslationBase.of(AppGlobal.context).online, - "subtitle": TranslationBase.of(AppGlobal.context).payment, - "icon": "assets/images/new-design/check-in.png", - "caller": "goToTodoList" - } + {"title": TranslationBase.of(AppGlobal.context).online, "subtitle": TranslationBase.of(AppGlobal.context).payment, "icon": "online_payment.svg", "caller": "goToTodoList"}, + // {"title": TranslationBase.of(AppGlobal.context).clinic, "subtitle": TranslationBase.of(AppGlobal.context).locationa, "icon": "hosp_location.svg", "caller": "goToNavigation"} ]; } diff --git a/lib/pages/MyAppointments/models/ConfirmedButtonsAllowCheckIn.dart b/lib/pages/MyAppointments/models/ConfirmedButtonsAllowCheckIn.dart index 07ba333e..ed97a418 100644 --- a/lib/pages/MyAppointments/models/ConfirmedButtonsAllowCheckIn.dart +++ b/lib/pages/MyAppointments/models/ConfirmedButtonsAllowCheckIn.dart @@ -6,38 +6,38 @@ class ConfirmedButtonsAllowCheckIn { { "title": TranslationBase.of(AppGlobal.context).reschedule, "subtitle": TranslationBase.of(AppGlobal.context).appointment, - "icon": "assets/images/new-design/reschedule_icon.png", - "caller": "openReschedule" - }, - { - "title": TranslationBase.of(AppGlobal.context).cancel_nocaps, - "subtitle": TranslationBase.of(AppGlobal.context).appointment, - "icon": "assets/images/new-design/cancel_icon.png", - "caller": "onCancelAppointment" + "icon": "reschedule.svg", + "caller": "openReschedule", }, + // { + // "title": TranslationBase.of(AppGlobal.context).cancel_nocaps, + // "subtitle": TranslationBase.of(AppGlobal.context).appointment, + // "icon": "assets/images/new-design/cancel_icon.png", + // "caller": "onCancelAppointment", + // }, { "title": TranslationBase.of(AppGlobal.context).raise, "subtitle": TranslationBase.of(AppGlobal.context).complaint, - "icon": "assets/images/new-design/Complaint_icon.png", - "caller": "insertComplaint" + "icon": "raise_comp.svg", + "caller": "insertComplaint", }, { "title": TranslationBase.of(AppGlobal.context).add, "subtitle": TranslationBase.of(AppGlobal.context).reminder, - "icon": "assets/images/new-design/reminder_icon.png", - "caller": "addReminder" + "icon": "reminder_icon.svg", + "caller": "addReminder", }, { "title": TranslationBase.of(AppGlobal.context).hospital, "subtitle": TranslationBase.of(AppGlobal.context).location, - "icon": "assets/images/new-design/location_icon.png", - "caller": "navigateToProject" + "icon": "hosp_location.svg", + "caller": "navigateToProject", }, { "title": TranslationBase.of(AppGlobal.context).online, "subtitle": TranslationBase.of(AppGlobal.context).payment, - "icon": "assets/images/new-design/check-in.png", - "caller": "goToTodoList" + "icon": "online_payment.svg", + "caller": "goToTodoList", } ]; } diff --git a/lib/pages/MyAppointments/models/DoctorScheduleResponse.dart b/lib/pages/MyAppointments/models/DoctorScheduleResponse.dart new file mode 100644 index 00000000..f299bcd0 --- /dev/null +++ b/lib/pages/MyAppointments/models/DoctorScheduleResponse.dart @@ -0,0 +1,32 @@ +class DoctorScheduleResponse { + String? clinicName; + String? date; + String? dayName; + String? projectName; + String? workingHours; + + DoctorScheduleResponse( + {this.clinicName, + this.date, + this.dayName, + this.projectName, + this.workingHours}); + + DoctorScheduleResponse.fromJson(Map json) { + clinicName = json['ClinicName']; + date = json['Date']; + dayName = json['DayName']; + projectName = json['ProjectName']; + workingHours = json['WorkingHours']; + } + + Map toJson() { + final Map data = new Map(); + data['ClinicName'] = this.clinicName; + data['Date'] = this.date; + data['DayName'] = this.dayName; + data['ProjectName'] = this.projectName; + data['WorkingHours'] = this.workingHours; + return data; + } +} diff --git a/lib/pages/MyAppointments/widgets/AppointmentActions.dart b/lib/pages/MyAppointments/widgets/AppointmentActions.dart index b335c740..f519353c 100644 --- a/lib/pages/MyAppointments/widgets/AppointmentActions.dart +++ b/lib/pages/MyAppointments/widgets/AppointmentActions.dart @@ -1,10 +1,18 @@ +import 'dart:io'; + +import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; import 'package:diplomaticquarterapp/core/model/labs/patient_lab_orders.dart'; -import 'package:diplomaticquarterapp/core/model/prescriptions/prescription_report_enh.dart'; +import 'package:diplomaticquarterapp/core/model/prescriptions/Prescriptions.dart'; import 'package:diplomaticquarterapp/core/model/radiology/final_radiology.dart'; +import 'package:diplomaticquarterapp/core/viewModels/feedback/feedback_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/locator.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; +import 'package:diplomaticquarterapp/models/Appointments/SearchInfoModel.dart'; import 'package:diplomaticquarterapp/models/Appointments/appoDetailsButtons.dart'; import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/DentalComplaints.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/widgets/reminder_dialog.dart'; import 'package:diplomaticquarterapp/pages/MyAppointments/models/AppointmentType.dart'; import 'package:diplomaticquarterapp/pages/MyAppointments/models/ArrivedButtons.dart'; import 'package:diplomaticquarterapp/pages/MyAppointments/models/AskDocRequestTypeModel.dart'; @@ -12,23 +20,31 @@ import 'package:diplomaticquarterapp/pages/MyAppointments/models/BookedButtons.d import 'package:diplomaticquarterapp/pages/MyAppointments/models/BookedButtonsAllowCheckIn.dart'; import 'package:diplomaticquarterapp/pages/MyAppointments/models/ConfirmedButtons.dart'; import 'package:diplomaticquarterapp/pages/MyAppointments/models/ConfirmedButtonsAllowCheckIn.dart'; -import 'package:diplomaticquarterapp/pages/MyAppointments/widgets/PrescriptionReport.dart'; import 'package:diplomaticquarterapp/pages/MyAppointments/widgets/askDocDialog.dart'; -import 'package:diplomaticquarterapp/pages/MyAppointments/widgets/reminder_dialog.dart'; +import 'package:diplomaticquarterapp/pages/ToDoList/ToDo.dart'; import 'package:diplomaticquarterapp/pages/feedback/feedback_home_page.dart'; import 'package:diplomaticquarterapp/pages/insurance/insurance_approval_screen.dart'; import 'package:diplomaticquarterapp/pages/medical/labs/laboratory_result_page.dart'; +import 'package:diplomaticquarterapp/pages/medical/prescriptions/prescription_items_page.dart'; import 'package:diplomaticquarterapp/pages/medical/radiology/radiology_details_page.dart'; import 'package:diplomaticquarterapp/pages/medical/vital_sign/vital_sign_details_screen.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; -import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; +import 'package:diplomaticquarterapp/uitl/app-permissions.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/penguin_method_channel.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/medical/medical_profile_item.dart'; import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; +import 'package:huawei_hmsavailability/huawei_hmsavailability.dart'; +import 'package:huawei_map/huawei_map.dart' as hmsMap; +import 'package:intl/intl.dart'; +import 'package:map_launcher/map_launcher.dart'; +import 'package:permission_handler/permission_handler.dart'; import 'package:provider/provider.dart'; import 'package:url_launcher/url_launcher.dart'; @@ -36,12 +52,10 @@ class AppointmentActions extends StatefulWidget { AppoitmentAllHistoryResultList appo; TabController tabController; final Function enableFooterButton; - MyInAppBrowser browser; + MyInAppBrowser? browser; + final ProjectViewModel? projectViewModel; - AppointmentActions( - {@required this.appo, - @required this.tabController, - @required this.enableFooterButton}); + AppointmentActions({required this.appo, required this.tabController, required this.enableFooterButton, this.projectViewModel}); @override _AppointmentActionsState createState() => _AppointmentActionsState(); @@ -49,185 +63,156 @@ class AppointmentActions extends StatefulWidget { class _AppointmentActionsState extends State { List appoButtonsList = []; - - ToDoCountProviderModel toDoProvider; + static bool isHuawei = false; + HmsApiAvailability hmsApiAvailability = HmsApiAvailability(); @override void initState() { _getAppointmentActionButtons(); + checkIsHuawei(); super.initState(); } @override Widget build(BuildContext context) { ProjectViewModel projectViewModel = Provider.of(context); - toDoProvider = Provider.of(context); - var size = MediaQuery.of(context).size; - final double itemHeight = projectViewModel.isArabic - ? ((size.height - kToolbarHeight - 24) * 0.5) / 2 - : ((size.height - kToolbarHeight - 24) * 0.45) / 2; - final double itemWidth = size.width / 2; - - return Container( - margin: EdgeInsets.all(5.0), - child: CustomScrollView( - primary: false, - physics: NeverScrollableScrollPhysics(), - slivers: [ - SliverPadding( - padding: const EdgeInsets.fromLTRB(15, 0, 15, 0), - sliver: SliverGrid.count( - crossAxisCount: 2, - childAspectRatio: (itemWidth / itemHeight), - children: appoButtonsList - .map((e) => GestureDetector( - onTap: () { - _handleButtonClicks(e); - }, - child: Column( - mainAxisSize: MainAxisSize.max, - children: [ - Container( - // height: 100.0, - margin: EdgeInsets.all(7.0), - padding: EdgeInsets.only(bottom: 4.0), - decoration: BoxDecoration( - boxShadow: [ - BoxShadow( - color: Colors.grey[400], - blurRadius: 2.0, - spreadRadius: 0.0) - ], - borderRadius: BorderRadius.circular(10), - color: Colors.white), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - children: [ - Container( - margin: - EdgeInsets.fromLTRB(5.0, 5.0, 5.0, 0.0), - child: Text(e.title, - overflow: TextOverflow.clip, - style: TextStyle( - color: new Color(0xffB8382C), - letterSpacing: 1.0, - fontSize: 18.0)), - ), - Container( - margin: - EdgeInsets.fromLTRB(5.0, 0.0, 5.0, 0.0), - child: Text(e.subtitle, - overflow: TextOverflow.clip, - style: TextStyle( - color: Colors.black, - letterSpacing: 1.0, - fontSize: 15.0)), - ), - Container( - alignment: projectViewModel.isArabic - ? Alignment.bottomLeft - : Alignment.bottomRight, - margin: projectViewModel.isArabic - ? EdgeInsets.fromLTRB( - 10.0, 7.0, 0.0, 8.0) - : EdgeInsets.fromLTRB( - 0.0, 7.0, 10.0, 8.0), - child: Image.asset(e.icon, - width: 45.0, height: 45.0), - ), - ], - ), - ), - ], - ), - )) - .toList(), - ), + ToDoCountProviderModel model = Provider.of(context); + + return GridView.builder( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, crossAxisSpacing: 13, mainAxisSpacing: 9), + physics: NeverScrollableScrollPhysics(), + padding: EdgeInsets.all(21), + shrinkWrap: true, + itemBuilder: (context, index) { + // bool shouldEnable = ((widget.appo.clinicID == 17 || widget.appo.clinicID == 47) || (widget.appo.isLiveCareAppointment && appoButtonsList[index].caller == "askDoc") || appoButtonsList[index].caller == "openReschedule"); + bool shouldEnable = (((widget.appo.clinicID == 47 || widget.appo.clinicID == 134 || widget.appo.clinicID == 253) && appoButtonsList[index].caller == "openReschedule") || + (widget.appo.isLiveCareAppointment! && appoButtonsList[index].caller == "askDoc") || + (Utils.isVidaPlusProject(projectViewModel, widget.appo.projectID) && + widget.appo.clinicID == 10 && + (appoButtonsList[index].caller == "prescriptions" || appoButtonsList[index].caller == "radiology" || appoButtonsList[index].caller == "labResult"))); + return InkWell( + onTap: shouldEnable + ? null + : () { + _handleButtonClicks(appoButtonsList[index], model); + }, + child: MedicalProfileItem( + title: appoButtonsList[index].title!, + imagePath: appoButtonsList[index].icon!, + subTitle: appoButtonsList[index].subtitle!, + hasBadge: true, + isEnable: !shouldEnable, + imgColor: Color(0xff28323A), + isPngImage: appoButtonsList[index].icon!.contains(".png") ? true : false, ), - ], - ), + ); + }, + itemCount: appoButtonsList.length, ); } - _handleButtonClicks(AppoDetailsButton) { - print(AppoDetailsButton.caller); - + _handleButtonClicks(AppoDetailsButton, ToDoCountProviderModel model) { switch (AppoDetailsButton.caller) { case "openReschedule": widget.tabController.animateTo((widget.tabController.index + 1) % 2); setState(() { - print("Reschedule"); widget.enableFooterButton(); }); + locator().appointment.appointment_detail_action(appointment: widget.appo, action: 'reschedule appointment'); break; - - case "onCancelAppointment": - ConfirmDialog dialog = new ConfirmDialog( - context: context, - confirmMessage: TranslationBase.of(context).cancelAppoMsg, - okText: TranslationBase.of(context).confirm, - cancelText: TranslationBase.of(context).cancel_nocaps, - okFunction: () => {cancelAppointment()}, - cancelFunction: () => {}); - dialog.showAlertDialog(context); - break; - - case "confirmAppointment": - confirmAppointment(); - break; - case "navigateToProject": - openMap(double.parse(widget.appo.latitude), - double.parse(widget.appo.longitude)); + openMap(double.parse(widget.appo.latitude!), double.parse(widget.appo.longitude!)); + locator().appointment.appointment_detail_action(appointment: widget.appo, action: 'hospital location'); break; - case "addReminder": - showReminderDialog(widget.appo); + GAnalytics.APPOINTMENT_DETAIL_FLOW_TYPE = 'my appointment'; + showReminderDialog( + context, + DateFormat("dd MMM yyyy hh:mm") + .parse(DateUtil.formatDateToDate(DateUtil.convertStringToDate(widget.appo.appointmentDate!), widget.projectViewModel!.isArabic) + " " + widget.appo.startTime!), + //DateUtil.convertStringToDate(widget.appo.appointmentDate), + widget.appo.doctorNameObj!, + widget.appo.appointmentNo.toString(), + DateUtil.formatDateToDate(DateUtil.convertStringToDate(widget.appo.appointmentDate!), widget.projectViewModel!.isArabic), + // DateUtil.formatDateToTime(DateUtil.convertStringToDate(widget.appo.appointmentDate)), + widget.appo.startTime!, + onSuccess: () { + AppToast.showSuccessToast(message: TranslationBase.of(context).reminderSuccess); + }, + ); + locator().appointment.appointment_detail_action(appointment: widget.appo, action: 'add reminder'); break; - case "goToTodoList": - Navigator.of(context).pop(); + // Navigator.of(context).pop(); + navigateToToDoPage(context, model); + locator().appointment.appointment_detail_action(appointment: widget.appo, action: 'todo list'); break; - case "askDoc": askYourDoc(); + locator().appointment.appointment_detail_action(appointment: widget.appo, action: 'ask doctor'); break; - case "radiology": openAppointmentRadiology(); + locator().appointment.appointment_detail_action(appointment: widget.appo, action: 'radiology'); break; - case "labResult": openAppointmentLabResults(); + locator().appointment.appointment_detail_action(appointment: widget.appo, action: 'lab result'); break; - case "prescriptions": openPrescriptionReport(); + locator().appointment.appointment_detail_action(appointment: widget.appo, action: 'prescriptions'); break; - case "Survey": rateAppointment(); + locator().appointment.appointment_detail_action(appointment: widget.appo, action: 'survey'); break; - case "Insurance": - navigateToInsuranceApprovals(widget.appo.appointmentNo); + navigateToInsuranceApprovals(widget.appo.appointmentNo!); + locator().appointment.appointment_detail_action(appointment: widget.appo, action: 'insurance'); break; case "VitalSigns": - navigateToVitalSigns(widget.appo.appointmentNo, widget.appo.projectID); + navigateToVitalSigns(widget.appo.appointmentNo!, widget.appo.projectID!); + locator().appointment.appointment_detail_action(appointment: widget.appo, action: 'vital sign'); break; case "insertComplaint": navigateToInsertComplaint(); + locator().appointment.appointment_detail_action(appointment: widget.appo, action: 'raise complaint'); + break; + + case "goToNavigation": + initPenguinSDK(); + locator().appointment.appointment_detail_action(appointment: widget.appo, action: 'navigate to clinic'); break; } } + initPenguinSDK() async { + NavigationClinicDetails data = NavigationClinicDetails(); + data.clinicId = widget.appo.clinicID.toString(); + // data.clinicId = "49"; + data.patientId = widget.appo.patientID.toString(); + data.projectId = widget.appo.projectID.toString(); + final bool permited = await AppPermission.askPenguinPermissions(); + if (!permited) { + Map statuses = await [ + Permission.location, + Permission.bluetooth, + Permission.bluetoothConnect, + Permission.bluetoothScan, + Permission.activityRecognition, + ].request().whenComplete(() { + PenguinMethodChannel().launch("penguin", widget.projectViewModel!.isArabic ? "ar" : "en", widget.projectViewModel!.authenticatedUserObject.user.patientID.toString(), details: data); + }); + } + } + _getAppointmentActionButtons() { if (widget.appo != null) { if (isConfirmed()) { - if (widget.appo.isOnlineCheckedIN) { + if (widget.appo.isOnlineCheckedIN!) { _getConfirmedCheckInAppoActionsList(); } else { _getConfirmedAppoActionsList(); @@ -236,7 +221,7 @@ class _AppointmentActionsState extends State { print("isConfirmed Null"); } if (isBooked()) { - if (widget.appo.isOnlineCheckedIN) { + if (widget.appo.isOnlineCheckedIN!) { _getBookedCheckInAppoActionsList(); } else { _getBookedAppoActionsList(); @@ -267,14 +252,14 @@ class _AppointmentActionsState extends State { } bool isCheckedIn() { - return widget.appo.isOnlineCheckedIN; + return widget.appo.isOnlineCheckedIN!; } bool isBooked() { return AppointmentType.isBooked(widget.appo); } - Future> _getBookedAppoActionsList() async { + Future?>? _getBookedAppoActionsList() async { print("_getBookedAppoActionsList"); BookedButtons bookedButtons = new BookedButtons(); print(bookedButtons.buttons); @@ -292,10 +277,9 @@ class _AppointmentActionsState extends State { }); } - Future> _getBookedCheckInAppoActionsList() async { + Future?>? _getBookedCheckInAppoActionsList() async { print("_getBookedCheckInAppoActionsList"); - BookedButtonsAllowCheckIn bookedButtonsAllowCheckIn = - new BookedButtonsAllowCheckIn(); + BookedButtonsAllowCheckIn bookedButtonsAllowCheckIn = new BookedButtonsAllowCheckIn(); print(bookedButtonsAllowCheckIn.buttons); List buttonsList = []; for (var i = 0; i < bookedButtonsAllowCheckIn.buttons.length; i++) { @@ -311,7 +295,7 @@ class _AppointmentActionsState extends State { }); } - Future> _getConfirmedAppoActionsList() async { + Future?> _getConfirmedAppoActionsList() async { print("_getConfirmedAppoActionsList"); ConfirmedButtons confirmedButtons = new ConfirmedButtons(); print(confirmedButtons.buttons); @@ -329,10 +313,9 @@ class _AppointmentActionsState extends State { }); } - Future> _getConfirmedCheckInAppoActionsList() async { + Future?> _getConfirmedCheckInAppoActionsList() async { print("_getConfirmedAllowCheckInAppoActionsList"); - ConfirmedButtonsAllowCheckIn confirmedButtonsAllowCheckIn = - new ConfirmedButtonsAllowCheckIn(); + ConfirmedButtonsAllowCheckIn confirmedButtonsAllowCheckIn = new ConfirmedButtonsAllowCheckIn(); print(confirmedButtonsAllowCheckIn.buttons); List buttonsList = []; for (var i = 0; i < confirmedButtonsAllowCheckIn.buttons.length; i++) { @@ -348,7 +331,7 @@ class _AppointmentActionsState extends State { }); } - Future> _getArrivedAppoActionsList() async { + Future?> _getArrivedAppoActionsList() async { print("_getArrivedAppoActionsList"); ArrivedButtons arrivedButtons = new ArrivedButtons(); print(arrivedButtons.buttons); @@ -366,7 +349,7 @@ class _AppointmentActionsState extends State { }); } - Future> _getArrivedInvoiceAppoActionsList() async { + Future?> _getArrivedInvoiceAppoActionsList() async { print("_getArrivedInvoiceAppoActionsList"); ArrivedButtons arrivedButtons = new ArrivedButtons(); List buttonsList = []; @@ -383,56 +366,63 @@ class _AppointmentActionsState extends State { }); } - cancelAppointment() { - ConfirmDialog.closeAlertDialog(context); - GifLoaderDialogUtils.showMyDialog(context); - DoctorsListService service = new DoctorsListService(); - service.cancelAppointment(widget.appo, context).then((res) { - GifLoaderDialogUtils.hideDialog(context); - print(res); - if (res['MessageStatus'] == 1) { - getToDoCount(); - AppToast.showSuccessToast(message: res['ErrorEndUserMessage']); - Navigator.of(context).pop(); - } else { - AppToast.showErrorToast(message: res['ErrorEndUserMessage']); - } - }).catchError((err) { - GifLoaderDialogUtils.hideDialog(context); - print(err); - }); - } - - getToDoCount() { - toDoProvider.setState(0, true); - ClinicListService service = new ClinicListService(); - service.getActiveAppointmentNo(context).then((res) { - print(res['AppointmentActiveNumber']); - if (res['MessageStatus'] == 1) { - toDoProvider.setState(res['AppointmentActiveNumber'], true); - } else {} - }).catchError((err) { - print(err); - }); - } + // cancelAppointment() { + // ConfirmDialog.closeAlertDialog(context); + // GifLoaderDialogUtils.showMyDialog(context); + // DoctorsListService service = new DoctorsListService(); + // service.cancelAppointment(widget.appo, context).then((res) { + // GifLoaderDialogUtils.hideDialog(context); + // print(res); + // if (res['MessageStatus'] == 1) { + // getToDoCount(); + // AppToast.showSuccessToast(message: res['ErrorEndUserMessage']); + // Navigator.of(context).pop(); + // } else { + // AppToast.showErrorToast(message: res['ErrorEndUserMessage']); + // } + // }).catchError((err) { + // GifLoaderDialogUtils.hideDialog(context); + // print(err); + // }); + // } + + // getToDoCount() { + // toDoProvider.setState(0, true); + // ClinicListService service = new ClinicListService(); + // service.getActiveAppointmentNo(context).then((res) { + // print(res['AppointmentActiveNumber']); + // if (res['MessageStatus'] == 1) { + // toDoProvider.setState(res['AppointmentActiveNumber'], true); + // } else {} + // }).catchError((err) { + // print(err); + // }); + // } openAppointmentLabResults() { + int languageID = widget.projectViewModel!.isArabic ? 1 : 2; GifLoaderDialogUtils.showMyDialog(context); DoctorsListService service = new DoctorsListService(); PatientLabOrders patientLabOrders = new PatientLabOrders(); - service - .getPatientLabOrdersByAppoNo(widget.appo.appointmentNo, - widget.appo.projectID, widget.appo.clinicID, context) - .then((res) { + service.getPatientLabOrdersByAppoNo(widget.appo.appointmentNo, widget.appo.projectID, widget.appo.clinicID, languageID, context).then((res) { print(res['ListLabResultsByAppNo']); GifLoaderDialogUtils.hideDialog(context); if (res['ListLabResultsByAppNo'] != null) { - patientLabOrders.orderNo = - res['ListLabResultsByAppNo'][0]['OrderNo'].toString(); - patientLabOrders.invoiceNo = - res['ListLabResultsByAppNo'][0]['InvoiceNo'].toString(); + patientLabOrders.orderNo = res['ListLabResultsByAppNo'][0]['OrderNo'].toString(); + patientLabOrders.invoiceNo = res['ListLabResultsByAppNo'][0]['InvoiceNo'].toString(); + patientLabOrders.invoiceType = res['ListLabResultsByAppNo'][0]['InvoiceType'].toString(); patientLabOrders.clinicID = widget.appo.clinicID; + patientLabOrders.clinicDescription = widget.appo.clinicName; patientLabOrders.projectID = widget.appo.projectID.toString(); + patientLabOrders.doctorName = widget.appo.doctorNameObj; + patientLabOrders.doctorImageURL = widget.appo.doctorImageURL; + patientLabOrders.speciality = widget.appo.doctorSpeciality; + patientLabOrders.projectName = widget.appo.projectName; + patientLabOrders.orderDate = DateUtil.convertStringToDate(widget.appo.appointmentDate!); + patientLabOrders.doctorRate = widget.appo.doctorRate; + patientLabOrders.actualDoctorRate = widget.appo.actualDoctorRate; + patientLabOrders.noOfPatientsRate = widget.appo.noOfPatientsRate; + print(patientLabOrders.invoiceNo); print(patientLabOrders.orderNo); navigateToLabResults(patientLabOrders); @@ -447,145 +437,115 @@ class _AppointmentActionsState extends State { } openAppointmentRadiology() { + int languageID = widget.projectViewModel!.isArabic! ? 1 : 2; GifLoaderDialogUtils.showMyDialog(context); DoctorsListService service = new DoctorsListService(); FinalRadiology finalRadiology = new FinalRadiology(); - service - .getPatientRadOrders(widget.appo.appointmentNo.toString(), context) - .then((res) { + service.getPatientRadOrders(widget.appo.appointmentNo.toString(), widget.appo.projectID, languageID, context).then((res) { GifLoaderDialogUtils.hideDialog(context); if (res['FinalRadiologyList'] != null) { print(res['FinalRadiologyList']); - finalRadiology = - new FinalRadiology.fromJson(res['FinalRadiologyList'][0]); + finalRadiology = new FinalRadiology.fromJson(res['FinalRadiologyList'][0]); print(finalRadiology.reportData); navigateToRadiologyDetails(finalRadiology); } else { - AppToast.showErrorToast(message: res['ErrorEndUserMessage']); + AppToast.showErrorToast(message: TranslationBase.of(context).noResultFound); } }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); print(err); - AppToast.showErrorToast(message: err); + AppToast.showErrorToast(message: TranslationBase.of(context).noResultFound, localContext: context); }); } openPrescriptionReport() { - GifLoaderDialogUtils.showMyDialog(context); - List prescriptionReportEnhList = List(); - DoctorsListService service = new DoctorsListService(); - service.getPatientPrescriptionReports(widget.appo, context).then((res) { - GifLoaderDialogUtils.hideDialog(context); - if (res['ListPRM'].length != 0) { - res['ListPRM'].forEach((report) { - prescriptionReportEnhList.add(PrescriptionReportEnh.fromJson(report)); - }); - print(prescriptionReportEnhList.length); - navigateToMedicinePrescriptionReport( - prescriptionReportEnhList, res['ListPRM']); - } else { - AppToast.showErrorToast(message: TranslationBase.of(context).noRecords); - } - }).catchError((err) { - print(err); - GifLoaderDialogUtils.hideDialog(context); - AppToast.showErrorToast(message: err); - }); + Prescriptions prescriptions = new Prescriptions(); + + prescriptions.doctorName = widget.appo.doctorNameObj; + prescriptions.appointmentNo = widget.appo.appointmentNo; + prescriptions.clinicID = widget.appo.clinicID; + prescriptions.projectID = widget.appo.projectID; + prescriptions.doctorImageURL = widget.appo.doctorImageURL; + prescriptions.speciality = widget.appo.doctorSpeciality; + prescriptions.name = widget.appo.projectName; + prescriptions.episodeID = widget.appo.episodeID; + prescriptions.setupID = widget.appo.setupID; + prescriptions.appointmentDate = widget.appo.appointmentDate; + prescriptions.nationalityFlagURL = "https://hmgwebservices.com/Images/flag/SAU.png"; + prescriptions.doctorRate = widget.appo.doctorRate; + prescriptions.actualDoctorRate = widget.appo.actualDoctorRate; + prescriptions.noOfPatientsRate = widget.appo.noOfPatientsRate; + prescriptions.isInOutPatient = widget.appo.isInOutPatient; + prescriptions.doctorID = widget.appo.doctorID; + + navigateToMedicinePrescriptionReport(prescriptions); } - Future navigateToMedicinePrescriptionReport( - List prescriptionReportEnhList, - dynamic listPres) async { - Navigator.push( - context, - FadePage( - page: PrescriptionReportPage( - prescriptionReportEnhList: prescriptionReportEnhList, - listPres: listPres, - appo: widget.appo))); + Future navigateToMedicinePrescriptionReport(Prescriptions prescriptions) async { + Navigator.push(context, FadePage(page: PrescriptionItemsPage(prescriptions: prescriptions))); } Future navigateToLabResults(PatientLabOrders patientLabOrders) async { - Navigator.push( - context, - FadePage( - page: LaboratoryResultPage(patientLabOrders: patientLabOrders))) - .then((value) {}); + Navigator.push(context, FadePage(page: LaboratoryResultPage(patientLabOrders: patientLabOrders))).then((value) {}); } Future navigateToRadiologyDetails(FinalRadiology finalRadiology) async { - Navigator.push( - context, - FadePage( - page: RadiologyDetailsPage(finalRadiology: finalRadiology))) - .then((value) {}); + Navigator.push(context, FadePage(page: RadiologyDetailsPage(finalRadiology: finalRadiology))).then((value) {}); } static Future openMap(double latitude, double longitude) async { - String googleUrl = - 'https://www.google.com/maps/search/?api=1&query=$latitude,$longitude'; - if (await canLaunch(googleUrl)) { - await launch(googleUrl); - } else { - throw 'Could not open the map.'; - } + await MapLauncher.showMarker( + mapType: Platform.isAndroid + ? isHuawei == true + ? MapType.petal + : MapType.google + : MapType.apple, + coords: Coords(latitude, longitude), + title: "Sulaiman Al Habib", + description: "Appointment Location", + ); } - showReminderDialog(AppoitmentAllHistoryResultList appo) { - 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: ReminderDialog( - eventId: appo.appointmentNo.toString(), - title: "Doctor Appointment", - description: "You have an appointment with " + - appo.doctorTitle + - " " + - appo.doctorNameObj, - startDate: appo.appointmentDate, - endDate: appo.appointmentDate, - location: appo.projectName, - ), - ), - ); - }, - transitionDuration: Duration(milliseconds: 500), - barrierDismissible: true, - barrierLabel: '', - context: context, - pageBuilder: (context, animation1, animation2) {}); + checkIsHuawei() async { + if (Platform.isAndroid) { + await hmsApiAvailability.isHMSAvailable().then((value) { + isHuawei = value == 0 ? true : false; + hmsMap.HuaweiMapInitializer.initializeMap(); + }); + print(isHuawei); + } } askYourDoc() { GifLoaderDialogUtils.showMyDialog(context); + int languageID = Provider.of(context, listen: false).isArabic ? 1 : 2; + DoctorsListService service = new DoctorsListService(); - service.isAllowedToAskDoctor(widget.appo.doctorID, context).then((res) { - GifLoaderDialogUtils.hideDialog(context); - print(res['PatientDoctorAppointmentResultList']); - if (res['PatientDoctorAppointmentResultList'].length != 0) { - getCallRequestType(); - } else { - AppToast.showErrorToast( - message: TranslationBase.of(context).askDocNotAllowed); - } - }).catchError((err) { - GifLoaderDialogUtils.hideDialog(context); - print(err); - AppToast.showErrorToast(message: err); + service.isAllowedToAskDoctor(widget.appo.doctorID!, languageID, context).then((res) { + int languageID = Provider.of(context, listen: false).isArabic ? 1 : 2; + service.isAllowedToAskDoctor(widget.appo.doctorID, languageID, context).then((res) { + GifLoaderDialogUtils.hideDialog(context); + print(res['PatientDoctorAppointmentResultList']); + if (res['PatientDoctorAppointmentResultList'].length != 0) { + getCallRequestType(); + } else { + AppToast.showErrorToast(message: TranslationBase.of(context).askDocNotAllowed, localContext: context); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + AppToast.showErrorToast(message: err); + }); }); } getCallRequestType() { + int languageID = Provider.of(context, listen: false).isArabic ? 1 : 2; GifLoaderDialogUtils.showMyDialog(context); DoctorsListService service = new DoctorsListService(); - service.getCallRequestType(context).then((res) { + service.getCallRequestType(languageID, context).then((res) { GifLoaderDialogUtils.hideDialog(context); - List requestData = new List(); + List requestData = []; res['ListReqTypes'].forEach((element) { requestData.add(new AskDocRequestType.fromJson(element)); }); @@ -600,39 +560,36 @@ class _AppointmentActionsState extends State { showAskDocRequestDialog(List requestData) { 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: AskDocDialog(requestData: requestData), - ), - ); - }, - transitionDuration: Duration(milliseconds: 500), - barrierDismissible: true, - barrierLabel: '', - context: context, - pageBuilder: (context, animation1, animation2) {}) - .then((value) { + 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: AskDocDialog(requestData: requestData), + ), + ); + }, + transitionDuration: Duration(milliseconds: 500), + barrierDismissible: true, + barrierLabel: '', + context: context, + pageBuilder: (context, animation1, animation2) => SizedBox()).then((value) { print("Dialog Closed"); print(value); if (value != null) { - sendAskDocRequest(value); + sendAskDocRequest(value as int); } }); } sendAskDocRequest(int requestType) { + int languageID = Provider.of(context, listen: false).isArabic ? 1 : 2; GifLoaderDialogUtils.showMyDialog(context); DoctorsListService service = new DoctorsListService(); - service - .sendAskDocCallRequest(widget.appo, requestType.toString(), context) - .then((res) { + + service.sendAskDocCallRequest(widget.appo, requestType.toString(), languageID, context).then((res) { GifLoaderDialogUtils.hideDialog(context); if (res['MessageStatus'] == 1) { AppToast.showSuccessToast(message: "Request Sent Successfully"); @@ -646,29 +603,25 @@ class _AppointmentActionsState extends State { }); } - confirmAppointment() { - GifLoaderDialogUtils.showMyDialog(context); - DoctorsListService service = new DoctorsListService(); - service - .confirmAppointment(widget.appo.appointmentNo, widget.appo.clinicID, - widget.appo.projectID, widget.appo.isLiveCareAppointment, context) - .then((res) { - GifLoaderDialogUtils.hideDialog(context); - if (res['MessageStatus'] == 1) { - AppToast.showSuccessToast(message: res['ErrorEndUserMessage']); - Navigator.of(context).pop(); - } else { - AppToast.showErrorToast(message: res['ErrorEndUserMessage']); - } - }).catchError((err) { - GifLoaderDialogUtils.hideDialog(context); - print(err); - }); - } + // confirmAppointment() { + // GifLoaderDialogUtils.showMyDialog(context); + // DoctorsListService service = new DoctorsListService(); + // service.confirmAppointment(widget.appo.appointmentNo, widget.appo.clinicID, widget.appo.projectID, widget.appo.isLiveCareAppointment, context).then((res) { + // GifLoaderDialogUtils.hideDialog(context); + // if (res['MessageStatus'] == 1) { + // AppToast.showSuccessToast(message: res['ErrorEndUserMessage']); + // Navigator.of(context).pop(); + // } else { + // AppToast.showErrorToast(message: res['ErrorEndUserMessage']); + // } + // }).catchError((err) { + // GifLoaderDialogUtils.hideDialog(context); + // print(err); + // }); + // } navigateToInsuranceApprovals(int appoNo) { - Navigator.push( - context, FadePage(page: InsuranceApproval(appointmentNo: appoNo))); + Navigator.push(context, FadePage(page: InsuranceApproval(appointmentNo: appoNo))); } navigateToVitalSigns(int appoNo, int projectID) { @@ -683,15 +636,67 @@ class _AppointmentActionsState extends State { } navigateToInsertComplaint() { - Navigator.push(context, FadePage(page: FeedbackHomePage())); + Navigator.push( + context, + FadePage( + page: FeedbackHomePage( + messageType: MessageType.ComplaintOnAnAppointment, + appointment: widget.appo, + ))); + } + + navigateToToDoPage(BuildContext context, ToDoCountProviderModel model) { + if (widget.projectViewModel!.isLogin) { + // if (model.count != 0) { + getPatientAppointmentHistoryWithAppo(); + } + // else { + // AppToast.showErrorToast(message: TranslationBase.of(context).upcomingEmpty); + // } + else { + Navigator.push( + context, + FadePage( + page: ToDo( + isShowAppBar: true, + isFromMyAppointments: true, + appointment: widget.appo, + ))); + } + } + + getPatientAppointmentHistoryWithAppo() { + GifLoaderDialogUtils.showMyDialog(context); + DoctorsListService service = new DoctorsListService(); + int languageID = Provider.of(context, listen: false).isArabic ? 1 : 2; + service.getPatientAppointmentHistoryWithAppoNo(widget.appo.appointmentNo, languageID).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res['MessageStatus'] == 1) { + AppoitmentAllHistoryResultList appo = new AppoitmentAllHistoryResultList.fromJson(res['AppoimentAllHistoryResultList'][0]); + Navigator.push( + context, + FadePage( + page: ToDo( + isShowAppBar: true, + isFromMyAppointments: true, + appointment: appo, + ), + ), + ); + } else { + AppToast.showErrorToast(message: res['ErrorEndUserMessage']); + } + }).catchError((err) { + print(err); + GifLoaderDialogUtils.hideDialog(context); + err != null ?? AppToast.showErrorToast(message: err); + }); } rateAppointment() { - widget.browser = new MyInAppBrowser(); - widget.browser.openBrowser('http://hmg.com/SitePages/pso.aspx?p=' + - widget.appo.projectID.toString() + - '.' + - widget.appo.appointmentNo.toString() + - '&c=1'); + widget.browser = new MyInAppBrowser(onExitCallback: () {}); + var url = 'http://hmg.com/SitePages/pso.aspx?p=' + widget.appo.projectID.toString() + '.' + widget.appo.appointmentNo.toString() + '&c=1'; + print(url); + launch(url); } } diff --git a/lib/pages/MyAppointments/widgets/AppointmentCardView.dart b/lib/pages/MyAppointments/widgets/AppointmentCardView.dart index 51e18ff4..aec449b1 100644 --- a/lib/pages/MyAppointments/widgets/AppointmentCardView.dart +++ b/lib/pages/MyAppointments/widgets/AppointmentCardView.dart @@ -1,6 +1,8 @@ +import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; import 'package:diplomaticquarterapp/pages/MyAppointments/models/AppointmentType.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; @@ -8,8 +10,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_countdown_timer/countdown_timer_controller.dart'; import 'package:flutter_countdown_timer/current_remaining_time.dart'; import 'package:flutter_countdown_timer/flutter_countdown_timer.dart'; +import 'package:flutter_rating_bar/flutter_rating_bar.dart'; import 'package:provider/provider.dart'; -import 'package:rating_bar/rating_bar.dart'; import '../AppointmentDetails.dart'; @@ -18,14 +20,14 @@ class AppointmentCard extends StatefulWidget { final Function onReloadAppointmentHistory; AppointmentCard( - {@required this.appo, @required this.onReloadAppointmentHistory}); + {required this.appo, required this.onReloadAppointmentHistory}); @override _ApointmentCardState createState() => _ApointmentCardState(); } class _ApointmentCardState extends State { - CountdownTimerController controller; + CountdownTimerController? controller; @override void initState() { @@ -61,9 +63,9 @@ class _ApointmentCardState extends State { height: projectViewModel.isArabic ? 165 : 140, decoration: BoxDecoration( //Colors.red[900] Color(0xff404545) - color: widget.appo.isLiveCareAppointment + color: widget.appo.isLiveCareAppointment! ? Color(0xff404545) - : !widget.appo.isInOutPatient + : !widget.appo.isInOutPatient! ? Colors.red[900] : Theme.of(context).primaryColor, borderRadius: BorderRadius.only( @@ -85,9 +87,9 @@ class _ApointmentCardState extends State { quarterTurns: 3, child: Center( child: Text( - widget.appo.isLiveCareAppointment + widget.appo.isLiveCareAppointment! ? TranslationBase.of(context).liveCare.toUpperCase() - : !widget.appo.isInOutPatient + : !widget.appo.isInOutPatient! ? TranslationBase.of(context) .inPatient .toUpperCase() @@ -103,7 +105,7 @@ class _ApointmentCardState extends State { ), ClipRRect( borderRadius: BorderRadius.circular(100.0), - child: Image.network(widget.appo.doctorImageURL, + child: Image.network(widget.appo.doctorImageURL!, fit: BoxFit.fill, height: 60.0, width: 60.0), ), Expanded( @@ -114,16 +116,16 @@ class _ApointmentCardState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - widget.appo.doctorTitle + + widget.appo.doctorTitle! + " " + - widget.appo.doctorNameObj, + widget.appo.doctorNameObj!, style: TextStyle( fontSize: 14.0, color: Colors.grey[700], letterSpacing: 1.0)), Container( margin: EdgeInsets.only(top: 3.0), - child: Text(widget.appo.clinicName, + child: Text(widget.appo.clinicName!, style: TextStyle( fontSize: 12.0, color: Colors.grey[600], @@ -131,7 +133,7 @@ class _ApointmentCardState extends State { ), Container( margin: EdgeInsets.only(top: 3.0), - child: Text(widget.appo.projectName, + child: Text(widget.appo.projectName!, style: TextStyle( fontSize: 12.0, color: Colors.grey[600], @@ -142,7 +144,7 @@ class _ApointmentCardState extends State { child: Text( DateUtil.getWeekDayMonthDayYearDateFormatted( DateUtil.convertStringToDate( - widget.appo.appointmentDate), + widget.appo.appointmentDate!), projectViewModel.isArabic ? "ar" : "en") .trim(), style: TextStyle( @@ -154,16 +156,35 @@ class _ApointmentCardState extends State { mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisSize: MainAxisSize.max, children: [ - RatingBar.readOnly( - initialRating: - widget.appo.actualDoctorRate.toDouble(), - size: 20.0, - filledColor: Colors.yellow[700], - emptyColor: Colors.grey[500], - isHalfAllowed: true, - halfFilledIcon: Icons.star_half, - filledIcon: Icons.star, - emptyIcon: Icons.star, + // RatingBar.readOnly( + // initialRating: + // widget.appo.actualDoctorRate.toDouble(), + // size: 20.0, + // filledColor: Colors.yellow[700], + // emptyColor: Colors.grey[500], + // isHalfAllowed: true, + // halfFilledIcon: Icons.star_half, + // filledIcon: Icons.star, + // emptyIcon: Icons.star, + // ), + RatingBar( + initialRating: widget.appo.actualDoctorRate!.toDouble(), + direction: Axis.horizontal, + allowHalfRating: true, + itemCount: 5, + itemSize: 20, + ignoreGestures: true, + ratingWidget: RatingWidget( + full: Icon(Icons.star, color: CustomColors.accentColor,), + half: Icon(Icons.star_half, color: CustomColors.accentColor,), + empty: Icon(Icons.star, color: CustomColors.accentColor,), + ), + tapOnlyMode: true, + unratedColor: Colors.grey[500], + itemPadding: EdgeInsets.symmetric(horizontal: 4.0), + onRatingUpdate: (rating) { + print(rating); + }, ), Container( transform: @@ -189,13 +210,13 @@ class _ApointmentCardState extends State { controller: new CountdownTimerController( endTime: DateTime.now() .millisecondsSinceEpoch + - (widget.appo.remaniningHoursTocanPay * + (widget.appo.remaniningHoursTocanPay! * 1000) * 60), - widgetBuilder: (_, CurrentRemainingTime time) { + widgetBuilder: (_, CurrentRemainingTime? time) { return time != null ? Text( - '${time.days}:${time.hours}:${time.min}:${time.sec} ' + + '${time.days != null ? time.days : "0"}:${time.hours != null ? time.hours : "0"}:${time.min}:${time.sec} ' + TranslationBase.of(context) .upcomingTimeLeft, style: TextStyle( @@ -237,6 +258,7 @@ class _ApointmentCardState extends State { } Future navigateToAppointmentDetails(context, appo) async { + GAnalytics.APPOINTMENT_DETAIL_FLOW_TYPE = 'my appointment'; Navigator.push(context, FadePage(page: AppointmentDetails(appo: appo))) .then((value) { widget.onReloadAppointmentHistory(); diff --git a/lib/pages/MyAppointments/widgets/PrescriptionReport.dart b/lib/pages/MyAppointments/widgets/PrescriptionReport.dart index 213e28e1..9f9588c1 100644 --- a/lib/pages/MyAppointments/widgets/PrescriptionReport.dart +++ b/lib/pages/MyAppointments/widgets/PrescriptionReport.dart @@ -1,5 +1,6 @@ import 'package:diplomaticquarterapp/core/model/prescriptions/prescription_report.dart'; import 'package:diplomaticquarterapp/core/model/prescriptions/prescription_report_enh.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; import 'package:diplomaticquarterapp/pages/medical/prescriptions/prescription_details_page.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; @@ -10,30 +11,30 @@ 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 'package:provider/provider.dart'; class PrescriptionReportPage extends StatefulWidget { List prescriptionReportEnhList; dynamic listPres; AppoitmentAllHistoryResultList appo; - PrescriptionReportPage( - {@required this.prescriptionReportEnhList, - @required this.listPres, - @required this.appo}); + PrescriptionReportPage({required this.prescriptionReportEnhList, required this.listPres, required this.appo}); @override _PrescriptionReportState createState() => _PrescriptionReportState(); } class _PrescriptionReportState extends State { + ProjectViewModel? projectViewModel; + @override void initState() { - print(widget.prescriptionReportEnhList.length); super.initState(); } @override Widget build(BuildContext context) { + projectViewModel = Provider.of(context); return AppScaffold( isShowAppBar: true, appBarTitle: 'Items', @@ -42,8 +43,7 @@ class _PrescriptionReportState extends State { child: ListView.builder( itemBuilder: (context, index) => InkWell( onTap: () { - navigateToPrescriptionDetails( - widget.prescriptionReportEnhList[index]); + navigateToPrescriptionDetails(widget.prescriptionReportEnhList[index]); }, child: Container( width: double.infinity, @@ -54,14 +54,14 @@ class _PrescriptionReportState extends State { borderRadius: BorderRadius.all( Radius.circular(10.0), ), - border: Border.all(color: Colors.grey[200], width: 0.5), + border: Border.all(color: Colors.grey[200]!, width: 0.5), ), child: Row( children: [ ClipRRect( borderRadius: BorderRadius.all(Radius.circular(5)), child: Image.network( - widget.prescriptionReportEnhList[index].imageSRCUrl, + widget.prescriptionReportEnhList[index]!.imageSRCUrl!, fit: BoxFit.cover, width: 60, height: 70, @@ -70,12 +70,10 @@ class _PrescriptionReportState extends State { Expanded( child: Padding( padding: const EdgeInsets.all(8.0), - child: Center( - child: Texts(widget - .prescriptionReportEnhList[index].itemDescription)), + child: Center(child: Texts(widget.prescriptionReportEnhList[index].itemDescription)), )), Icon( - Icons.arrow_forward_ios, + Icons.arrow_forward, size: 18, color: Colors.grey[500], ) @@ -98,7 +96,7 @@ class _PrescriptionReportState extends State { child: Button( label: 'Send Copy', onTap: () { - sendPrescriptionReportEmail(); + sendPrescriptionReportEmail(true); }, ), ), @@ -114,13 +112,10 @@ class _PrescriptionReportState extends State { ); } - sendPrescriptionReportEmail() { + sendPrescriptionReportEmail(bool isDownload) { DoctorsListService service = new DoctorsListService(); GifLoaderDialogUtils.showMyDialog(context); - service - .sendPrescriptionEmail(widget.appo.appointmentDate, widget.appo.setupID, - widget.listPres, context) - .then((res) { + service.sendPrescriptionEmail(widget.appo.appointmentDate!, widget.appo.setupID!, projectViewModel!.isArabic ? 1 : 2, widget.listPres, isDownload, context).then((res) { GifLoaderDialogUtils.hideDialog(context); AppToast.showSuccessToast(message: 'A copy has been sent to the e-mail'); }).catchError((err) { @@ -143,8 +138,7 @@ class _PrescriptionReportState extends State { prescriptionReport.frequency = prescriptionReportEnh.frequency; prescriptionReport.frequencyN = prescriptionReportEnh.frequency; - prescriptionReport.doseDailyQuantity = - prescriptionReportEnh.doseDailyQuantity; + prescriptionReport.doseDailyQuantity = prescriptionReportEnh.doseDailyQuantity; prescriptionReport.days = prescriptionReportEnh.days; diff --git a/lib/pages/MyAppointments/widgets/askDocDialog.dart b/lib/pages/MyAppointments/widgets/askDocDialog.dart index 15af9ae7..d341dadf 100644 --- a/lib/pages/MyAppointments/widgets/askDocDialog.dart +++ b/lib/pages/MyAppointments/widgets/askDocDialog.dart @@ -1,17 +1,18 @@ import 'package:diplomaticquarterapp/pages/MyAppointments/models/AskDocRequestTypeModel.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/custom_text_button.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:flutter/material.dart'; import 'custom_radio.dart'; class AskDocDialog extends StatefulWidget { - List requestData; static int selectedParameterCode = 0; - AskDocDialog({@required this.requestData}); + AskDocDialog({required this.requestData}); @override _AskDocDialogState createState() => _AskDocDialogState(); @@ -22,70 +23,47 @@ class _AskDocDialogState extends State { Widget build(BuildContext context) { return Container( child: Dialog( - shape: - RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.0)), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.0)), child: Container( height: MediaQuery.of(context).size.height * 0.77, width: 450.0, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - children: [ - Container( - margin: EdgeInsets.all(20.0), - child: Text(TranslationBase.of(context).requestType, - style: TextStyle( - fontSize: 20.0, - fontWeight: FontWeight.bold, - fontFamily: "Open-Sans-Bold")), - ), - Container( - transform: Matrix4.translationValues(0.0, -30.0, 0.0), - child: CustomRadio(requestData: widget.requestData), - ), - Container( - width: MediaQuery.of(context).size.width, - height: 40.0, - margin: EdgeInsets.only(left: 30.0, top: 0.0, right: 30.0), - child: RaisedButton( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10.0), - side: BorderSide(color: Colors.blue)), - color: Colors.blue, - onPressed: () { - if(AskDocDialog.selectedParameterCode != 0) - Navigator.pop(context, AskDocDialog.selectedParameterCode); - else - AppToast.showErrorToast(message: "Please select request type to continue"); - }, - child: Text(TranslationBase.of(context).confirm, - style: TextStyle( - color: Colors.white, - fontWeight: FontWeight.bold, - fontFamily: 'Open-Sans-Bold')), - ), - ), - Container( - width: MediaQuery.of(context).size.width, - margin: EdgeInsets.only(left: 100.0, top: 20.0, right: 100.0), - child: OutlineButton( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10.0)), - color: Colors.red, - borderSide: BorderSide(color: Colors.red), - highlightColor: Colors.red, - highlightedBorderColor: Colors.red, - onPressed: () { - Navigator.pop(context, null); - }, - child: Text(TranslationBase.of(context).cancel_nocaps, - style: TextStyle( - color: Colors.red, - fontWeight: FontWeight.bold, - fontFamily: 'Open-Sans-Bold')), - ), - ), - ]), + child: Column(crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.max, children: [ + Container( + margin: EdgeInsets.all(20.0), + child: Text(TranslationBase.of(context).requestType, style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold, fontFamily: "Open-Sans-Bold")), + ), + Container( + transform: Matrix4.translationValues(0.0, -30.0, 0.0), + child: CustomRadio(requestData: widget.requestData), + ), + Container( + width: MediaQuery.of(context).size.width, + height: 40.0, + margin: EdgeInsets.only(left: 30.0, top: 0.0, right: 30.0), + child: CustomTextButton( + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0), side: BorderSide(color: Colors.blue)), + backgroundColor: Colors.blue, + elevation: 0, + onPressed: () { + if (AskDocDialog.selectedParameterCode != 0) + Navigator.pop(context, AskDocDialog.selectedParameterCode); + else + AppToast.showErrorToast(message: "Please select request type to continue"); + }, + child: Text(TranslationBase.of(context).confirm, style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontFamily: 'Open-Sans-Bold')), + ), + ), + Container( + width: MediaQuery.of(context).size.width, + margin: EdgeInsets.only(left: 100.0, top: 20.0, right: 100.0), + child: DefaultButton( + TranslationBase.of(context).cancel_nocaps, + () { + Navigator.pop(context, null); + }, + ), + ), + ]), ), ), ); diff --git a/lib/pages/MyAppointments/widgets/custom_radio.dart b/lib/pages/MyAppointments/widgets/custom_radio.dart index b21e34ec..3ed0a18a 100644 --- a/lib/pages/MyAppointments/widgets/custom_radio.dart +++ b/lib/pages/MyAppointments/widgets/custom_radio.dart @@ -1,11 +1,12 @@ import 'package:diplomaticquarterapp/pages/MyAppointments/models/AskDocRequestTypeModel.dart'; import 'package:diplomaticquarterapp/pages/MyAppointments/widgets/askDocDialog.dart'; import 'package:diplomaticquarterapp/pages/MyAppointments/widgets/reminder_dialog.dart'; +import 'package:diplomaticquarterapp/pages/MyAppointments/widgets/reminder_dialog_prescription.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:flutter/material.dart'; class CustomRadio extends StatefulWidget { - List requestData; + List? requestData; CustomRadio({this.requestData}); @@ -16,7 +17,7 @@ class CustomRadio extends StatefulWidget { } class CustomRadioState extends State { - List sampleData = new List(); + List? sampleData = []; @override void initState() { @@ -24,19 +25,14 @@ class CustomRadioState extends State { WidgetsBinding.instance.addPostFrameCallback((_) { if (widget.requestData != null) { - widget.requestData.forEach((element) { - sampleData.add(new RadioModel( - false, element.description, element.parameterCode)); + widget.requestData!.forEach((element) { + sampleData!.add(new RadioModel(false, element.description!, element.parameterCode!)); }); } else { - sampleData.add(new RadioModel( - false, TranslationBase.of(context).appoReminder30, 30)); - sampleData.add(new RadioModel( - false, TranslationBase.of(context).appoReminder60, 60)); - sampleData.add(new RadioModel( - false, TranslationBase.of(context).appoReminder90, 90)); - sampleData.add(new RadioModel( - false, TranslationBase.of(context).appoReminder120, 120)); + sampleData!.add(new RadioModel(false, TranslationBase.of(context).appoReminder30, 30)); + sampleData!.add(new RadioModel(false, TranslationBase.of(context).appoReminder60, 60)); + sampleData!.add(new RadioModel(false, TranslationBase.of(context).appoReminder90, 90)); + sampleData!.add(new RadioModel(false, TranslationBase.of(context).appoReminder120, 120)); } }); } @@ -47,26 +43,24 @@ class CustomRadioState extends State { children: [ ListView.builder( shrinkWrap: true, - itemCount: sampleData.length, + itemCount: sampleData!.length, itemBuilder: (BuildContext context, int index) { return new InkWell( //highlightColor: Colors.red, splashColor: Colors.transparent, onTap: () { setState(() { - sampleData.forEach((element) => element.isSelected = false); - sampleData[index].isSelected = true; + sampleData!.forEach((element) => element.isSelected = false); + sampleData![index].isSelected = true; if (widget.requestData != null) { - AskDocDialog.selectedParameterCode = - sampleData[index].duration; - print(AskDocDialog.selectedParameterCode); + AskDocDialog.selectedParameterCode = sampleData![index].duration; } else { - ReminderDialog.selectedDuration = - sampleData[index].duration * 60000; + ReminderDialog.selectedDuration = sampleData![index].duration * 60000; + PrescriptionReminderDialog.selectedDuration = sampleData![index].duration * 60000; } }); }, - child: new RadioItem(sampleData[index]), + child: new RadioItem(sampleData![index]), ); }, ), @@ -91,14 +85,11 @@ class RadioItem extends StatelessWidget { height: 30.0, width: 30.0, child: new Center( - child: Image.asset("assets/images/new-design/check_icon.png", - width: 15.0, height: 15.0), + child: Image.asset("assets/images/new-design/check_icon.png", width: 15.0, height: 15.0), ), decoration: new BoxDecoration( color: _item.isSelected ? Colors.blue : Colors.transparent, - border: new Border.all( - width: 1.0, - color: _item.isSelected ? Colors.blue : Colors.grey), + border: new Border.all(width: 1.0, color: _item.isSelected ? Colors.blue : Colors.grey), borderRadius: const BorderRadius.all(const Radius.circular(50.0)), ), ), diff --git a/lib/pages/MyAppointments/widgets/indicator.dart b/lib/pages/MyAppointments/widgets/indicator.dart new file mode 100644 index 00000000..37cb0fac --- /dev/null +++ b/lib/pages/MyAppointments/widgets/indicator.dart @@ -0,0 +1,48 @@ +import 'package:flutter/material.dart'; + +class PageViewIndicator extends StatelessWidget { + final bool isActive; + final int length; + final double currentPage; + PageViewIndicator({ + required this.isActive, + required this.length, + required this.currentPage, + }); + + @override + Widget build(BuildContext context) { + return _indicator(this.isActive); + } + + Widget _indicator(bool isActive) { + return Positioned( + top: 20, + left: 0, + right: 0, + child: Container( + margin: EdgeInsets.only(top: 0), + child: Row( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + for (int i = 0; i < length; i++) + if (i == currentPage) ...[circleBar(true)] else circleBar(false), + ], + ), + ), + ); + } + + Widget circleBar(bool isActive) { + return AnimatedContainer( + duration: Duration(milliseconds: 150), + margin: EdgeInsets.symmetric(horizontal: 4), + height: isActive ? 12 : 12, + width: isActive ? 12 : 12, + decoration: BoxDecoration( + color: isActive ? Color(0xffD02127) : Color(0xffD0D0D0), + borderRadius: BorderRadius.all(Radius.circular(12))), + ); + } +} diff --git a/lib/pages/MyAppointments/widgets/reminder_dialog.dart b/lib/pages/MyAppointments/widgets/reminder_dialog.dart index 0db8cda4..f7cfe802 100644 --- a/lib/pages/MyAppointments/widgets/reminder_dialog.dart +++ b/lib/pages/MyAppointments/widgets/reminder_dialog.dart @@ -1,8 +1,9 @@ -import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; import 'package:diplomaticquarterapp/pages/MyAppointments/widgets/custom_radio.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/custom_text_button.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:flutter/material.dart'; import 'package:manage_calendar_events/manage_calendar_events.dart'; @@ -16,7 +17,7 @@ class ReminderDialog extends StatefulWidget { final String endDate; final String location; - ReminderDialog({@required this.eventId, @required this.title, @required this.description, @required this.startDate, @required this.endDate, @required this.location}); + ReminderDialog({required this.eventId, required this.title, required this.description, required this.startDate, required this.endDate, required this.location}); @override _ReminderDialogState createState() => _ReminderDialogState(); @@ -29,65 +30,45 @@ class _ReminderDialogState extends State { Widget build(BuildContext context) { return Container( child: Dialog( - shape: - RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.0)), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.0)), child: Container( // height: MediaQuery.of(context).size.height * 0.57, width: 450.0, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - Container( - margin: EdgeInsets.all(20.0), - child: Text(TranslationBase.of(context).setReminder, - style: TextStyle( - fontSize: 20.0, - fontWeight: FontWeight.bold)), - ), - Container( - transform: Matrix4.translationValues(0.0, -30.0, 0.0), - child: CustomRadio(), - ), - Container( - width: MediaQuery.of(context).size.width, - height: 40.0, - margin: EdgeInsets.only(left: 30.0, top: 0.0, right: 30.0), - child: RaisedButton( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10.0), - side: BorderSide(color: Colors.blue)), - color: Colors.blue, - onPressed: () { - print(ReminderDialog.selectedDuration); - createCalendarEvent(); - }, - child: Text(TranslationBase.of(context).confirm, - style: TextStyle( - color: Colors.white, - fontWeight: FontWeight.bold)), - ), - ), - Container( - width: MediaQuery.of(context).size.width, - margin: EdgeInsets.only(left: 100.0, top: 20.0, right: 100.0, bottom: 20.0), - child: OutlineButton( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10.0)), - color: Colors.red, - borderSide: BorderSide(color: Colors.red), - highlightColor: Colors.red, - highlightedBorderColor: Colors.red, - onPressed: () { - Navigator.of(context).pop(); - }, - child: Text(TranslationBase.of(context).cancel_nocaps, - style: TextStyle( - color: Colors.red, - fontWeight: FontWeight.bold)), - ), - ), - ]), + child: Column(crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ + Container( + margin: EdgeInsets.all(20.0), + child: Text(TranslationBase.of(context).setReminder, style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), + ), + Container( + transform: Matrix4.translationValues(0.0, -30.0, 0.0), + child: CustomRadio(), + ), + Container( + width: MediaQuery.of(context).size.width, + height: 40.0, + margin: EdgeInsets.only(left: 30.0, top: 0.0, right: 30.0), + child: CustomTextButton( + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0), side: BorderSide(color: Colors.blue)), + backgroundColor: Colors.blue, + elevation: 0, + onPressed: () { + print(ReminderDialog.selectedDuration); + createCalendarEvent(); + }, + child: Text(TranslationBase.of(context).confirm, style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold)), + ), + ), + Container( + width: MediaQuery.of(context).size.width, + margin: EdgeInsets.only(left: 100.0, top: 20.0, right: 100.0, bottom: 20.0), + child: DefaultButton( + TranslationBase.of(context).cancel_nocaps, + () { + Navigator.of(context).pop(); + }, + ), + ), + ]), ), ), ); @@ -95,10 +76,10 @@ class _ReminderDialogState extends State { createCalendarEvent() { _myPlugin.hasPermissions().then((value) { - if (!value) { + if (!value!) { _myPlugin.requestPermissions(); } else { - _myPlugin.getCalendars().then((value) => {print(value.length)}); + _myPlugin.getCalendars().then((value) => {print(value!.length)}); } }); @@ -106,21 +87,17 @@ class _ReminderDialogState extends State { eventId: widget.eventId, title: widget.title, description: widget.description, - startDate: DateUtil.convertStringToDate(widget.startDate) - .subtract( - new Duration(microseconds: ReminderDialog.selectedDuration)), + startDate: DateUtil.convertStringToDate(widget.startDate).subtract(new Duration(microseconds: ReminderDialog.selectedDuration)), endDate: DateUtil.convertStringToDate(widget.endDate), location: widget.location, duration: new Duration(minutes: 15).inMinutes, isAllDay: false, hasAlarm: true); - _myPlugin - .createEvent(calendarId: "207749556", event: calendarEvent) - .then((value) { + _myPlugin.createEvent(calendarId: "207749556", event: calendarEvent).then((value) { print("Cal event"); print(value); - if (int.parse(value) == int.parse(widget.eventId)) { + if (int.parse(value!) == int.parse(widget.eventId)) { AppToast.showSuccessToast(message: TranslationBase.of(context).reminderSuccess); } Navigator.of(context).pop(); diff --git a/lib/pages/MyAppointments/widgets/reminder_dialog_prescription.dart b/lib/pages/MyAppointments/widgets/reminder_dialog_prescription.dart new file mode 100644 index 00000000..fb11338d --- /dev/null +++ b/lib/pages/MyAppointments/widgets/reminder_dialog_prescription.dart @@ -0,0 +1,120 @@ +import 'package:diplomaticquarterapp/pages/MyAppointments/widgets/custom_radio.dart'; +import 'package:diplomaticquarterapp/uitl/CalendarUtils.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/custom_text_button.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:flutter/material.dart'; + +class PrescriptionReminderDialog extends StatefulWidget { + static var selectedDuration; + + final String eventId; + final String title; + final String description; + final DateTime startDate; + final DateTime endDate; + final String location; + final int days; + + List _scheduleList =[]; + + PrescriptionReminderDialog({ + required this.eventId, + required this.title, + required this.description, + required this.startDate, + required this.endDate, + required this.location, + required this.days, + }); + + @override + _ReminderDialogState createState() => _ReminderDialogState(); +} + +class _ReminderDialogState extends State { + @override + Widget build(BuildContext context) { + return Container( + child: Dialog( + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.0)), + child: Container( + // height: MediaQuery.of(context).size.height * 0.57, + width: 450.0, + child: Column(crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ + Container( + margin: EdgeInsets.all(20.0), + child: Text(TranslationBase.of(context).setReminder, style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), + ), + Container( + transform: Matrix4.translationValues(0.0, -30.0, 0.0), + child: CustomRadio(), + ), + Container( + width: MediaQuery.of(context).size.width, + height: 40.0, + margin: EdgeInsets.only(left: 30.0, top: 0.0, right: 30.0), + child: CustomTextButton( + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0), side: BorderSide(color: Colors.blue)), + backgroundColor: Colors.blue, + elevation: 0, + onPressed: () { + createOrUpdateEvents(); + }, + child: Text(TranslationBase.of(context).confirm, style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold)), + ), + ), + Container( + width: MediaQuery.of(context).size.width, + margin: EdgeInsets.only(left: 100.0, top: 20.0, right: 100.0, bottom: 20.0), + child: DefaultButton( + TranslationBase.of(context).cancel_nocaps, + () { + Navigator.of(context).pop(); + }, + ), + // OutlineButton( + // shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0)), + // color: Colors.red, + // borderSide: BorderSide(color: Colors.red), + // highlightColor: Colors.red, + // highlightedBorderColor: Colors.red, + // onPressed: () { + // Navigator.of(context).pop(); + // }, + // child: Text(TranslationBase.of(context).cancel_nocaps, style: TextStyle(color: Colors.red, fontWeight: FontWeight.bold)), + // ), + ), + ]), + ), + ), + ); + } + + createOrUpdateEvents() async { + Navigator.pop(context); + + for (int count = 0; count < widget.days; count++) { + widget._scheduleList.add(DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day)); + } + + List scheduleDateTime = calculateDaysInterval(widget.startDate.subtract(new Duration(microseconds: PrescriptionReminderDialog.selectedDuration)), widget.endDate); + + CalendarUtils calendarUtils = await CalendarUtils.getInstance(); + + calendarUtils.createOrUpdateEvents(scheduleList: widget._scheduleList, description: widget.description, title: widget.title, scheduleDateTime: scheduleDateTime); + + AppToast.showSuccessToast(message: TranslationBase.of(context).reminderSuccess); + } + + List calculateDaysInterval(DateTime startDate, DateTime endDate) { + List days = []; + for (int i = 0; i <= endDate.difference(startDate).inDays; i++) { + widget._scheduleList.forEach((element) { + days.add(startDate.add(Duration(days: i, hours: element.hour, minutes: element.minute))); + }); + } + return days; + } +} diff --git a/lib/pages/TestPage.dart b/lib/pages/TestPage.dart index 8ec70237..5c787014 100644 --- a/lib/pages/TestPage.dart +++ b/lib/pages/TestPage.dart @@ -26,8 +26,8 @@ class TestPageState extends State{ } void location(){ - LocationUtils().getCurrentLocation(callBack: (latLng){ - debugPrint(latLng.toString()); + LocationUtils(context: context,isShowConfirmDialog: false).getCurrentLocation(callBack: (latLng){ + print(latLng.toString()); }); } diff --git a/lib/pages/ToDoList/ObGyne/ObGyne-TimeSlots.dart b/lib/pages/ToDoList/ObGyne/ObGyne-TimeSlots.dart new file mode 100644 index 00000000..9660a616 --- /dev/null +++ b/lib/pages/ToDoList/ObGyne/ObGyne-TimeSlots.dart @@ -0,0 +1,545 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; +import 'package:diplomaticquarterapp/models/Appointments/FreeSlot.dart'; +import 'package:diplomaticquarterapp/models/Appointments/OBGyneProcedureListResponse.dart'; +import 'package:diplomaticquarterapp/models/Appointments/timeSlot.dart'; +import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart'; +import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; +import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; +import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/app_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/buttons/custom_text_button.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; +import 'package:provider/provider.dart'; +import 'package:syncfusion_flutter_calendar/calendar.dart'; + +class ObGyneTimeSlots extends StatefulWidget { + int projectID; + static bool areSlotsAvailable = false; + static late DateTime selectedAppoDateTime; + static late String selectedDate; + static late String selectedTime; + + late int? selectedClinicID; + late int? selectedDoctorID; + + late OBGyneProcedureListResponse? obGyneProcedureListResponse; + + var language; + + ObGyneTimeSlots({required this.projectID, this.selectedClinicID, this.selectedDoctorID, this.obGyneProcedureListResponse}); + + @override + _CovidTimeSlotsState createState() => _CovidTimeSlotsState(); +} + +class _CovidTimeSlotsState extends State with TickerProviderStateMixin { + Map? _events; + AnimationController? _animationController; + CalendarController? _calendarController; + + AppSharedPreferences sharedPref = new AppSharedPreferences(); + + var selectedDate = ""; + dynamic selectedDateJSON; + dynamic jsonFreeSlots; + + List docFreeSlots = []; + List dayEvents = []; + + int selectedButtonIndex = 0; + + dynamic freeSlotsResponse; + + ScrollController? _scrollController; + + ToDoCountProviderModel? toDoProvider; + ProjectViewModel? projectViewModel; + + @override + void initState() { + final _selectedDay = DateTime.now(); + + _scrollController = new ScrollController(); + + _events = { + _selectedDay: ['Event A0'] + }; + + WidgetsBinding.instance.addPostFrameCallback((_) => getCovidFreeSlots(context, widget.projectID)); + + _calendarController = CalendarController(); + _animationController = AnimationController( + vsync: this, + duration: const Duration(milliseconds: 50), + ); + + _animationController!.forward(); + super.initState(); + } + + @override + void dispose() { + _animationController!.dispose(); + _calendarController!.dispose(); + super.dispose(); + } + + void _onDaySelected(DateTime day, ProjectViewModel projectViewModel) { + final DateFormat formatter = DateFormat('yyyy-MM-dd'); + setState(() { + this.selectedDate = DateUtil.getWeekDayMonthDayYearDateFormatted(day, projectViewModel.isArabic ? "ar" : "en"); + openTimeSlotsPickerForDate(day, docFreeSlots); + ObGyneTimeSlots.selectedDate = formatter.format(day); + _calendarController!.selectedDate = day; + print(ObGyneTimeSlots.selectedDate); + }); + } + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + toDoProvider = Provider.of(context); + return AppScaffold( + appBarTitle: TranslationBase.of(context).bookAppo, + isShowAppBar: true, + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: CustomColors.appBackgroudGrey2Color, + body: Column( + children: [ + Expanded( + child: SingleChildScrollView( + child: Container( + margin: EdgeInsets.fromLTRB(15.0, 15.0, 15.0, 0.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.max, + children: [ + Text( + TranslationBase.of(context).selectAppo, + style: TextStyle( + color: Colors.black, + fontSize: 16.0, + letterSpacing: -0.64, + fontWeight: FontWeight.w600, + ), + ), + mHeight(12), + Container( + decoration: cardRadius(12), + child: _buildTableCalendarWithBuilders(projectViewModel!), + ), + mHeight(12), + Text( + selectedDate, + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.bold, + letterSpacing: -0.64, + ), + ), + mHeight(8), + ObGyneTimeSlots.areSlotsAvailable + ? Container( + height: 40, + child: ListView.builder( + controller: _scrollController, + scrollDirection: Axis.horizontal, + itemCount: dayEvents.length, + itemBuilder: (context, index) { + return Container( + margin: EdgeInsets.only(right: (index == dayEvents.length - 1) ? 0 : 5.0, left: index == 0 ? 0 : 5), + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5.0), + side: BorderSide( + color: index == selectedButtonIndex ? CustomColors.green : Colors.black, //Color of the border + style: BorderStyle.solid, //Style of the border + width: 1.5, //width of the border + ), + ), + minWidth: MediaQuery.of(context).size.width * 0.2, + child: index == selectedButtonIndex ? getSelectedButton(index) : getNormalButton(index)), + ); + }, + ), + ) + : Center( + child: Padding( + padding: const EdgeInsets.only(left: 12.0, right: 12.0), + child: Text(TranslationBase.of(context).noSlotsError, style: TextStyle(fontSize: 14.0, fontWeight: FontWeight.w600, letterSpacing: -0.46, color: CustomColors.grey)), + )), + ], + ), + ), + SizedBox( + height: 100.0, + ), + ], + ), + ), + ), + ), + Container( + margin: EdgeInsets.zero, + decoration: cardRadius(0), + child: Container( + width: double.infinity, + 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: CustomTextButton( + backgroundColor: CustomColors.green, + disabledForegroundColor: Colors.grey[500]!.withOpacity(0.38), + disabledBackgroundColor: Colors.grey[500]!.withOpacity(0.12), + elevation: 0, + onPressed: () { + bookCovidTestAppointment(); + }, + child: Text( + TranslationBase.of(context).bookAppo, + style: TextStyle(fontSize: 16.0, letterSpacing: -0.64, color: Colors.white), + ), + ), + ), + ), + ) + ], + ), + ); + } + + Widget _buildTableCalendarWithBuilders(ProjectViewModel projectViewModel) { + return SfCalendar( + controller: _calendarController, + minDate: DateTime.now(), + showNavigationArrow: true, + headerStyle: CalendarHeaderStyle(textAlign: TextAlign.center, textStyle: TextStyle(fontSize: 14.0, fontWeight: FontWeight.w600, letterSpacing: -0.46)), + viewHeaderStyle: ViewHeaderStyle(dayTextStyle: TextStyle(fontSize: 12.0, fontWeight: FontWeight.w600, letterSpacing: -0.46, color: CustomColors.black)), + view: CalendarView.month, + todayHighlightColor: CustomColors.green, + selectionDecoration: containerColorRadiusBorderWidthCircular(Colors.transparent, 4, CustomColors.green, 2.5), + cellBorderColor: Colors.white, + dataSource: MeetingDataSource(_getDataSource()), + monthViewSettings: const MonthViewSettings(appointmentDisplayMode: MonthAppointmentDisplayMode.indicator, showTrailingAndLeadingDates: false, appointmentDisplayCount: 1), + onTap: (CalendarTapDetails details) { + _calendarController!.selectedDate = details.date; + _onDaySelected(details.date!, projectViewModel); + }, + ); + } + + List _getDataSource() { + 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(minutes: 20)); + meetings.add(Meeting("", startTime, endTime, CustomColors.green, false, "")); + }); + return meetings; + } + + openTimeSlotsPickerForDate(DateTime dateStart, List freeSlots) { + dayEvents.clear(); + DateTime dateStartObj = new DateTime(dateStart.year, dateStart.month, dateStart.day, 0, 0, 0, 0, 0); + + freeSlots.forEach((v) { + if (v.start == dateStartObj) dayEvents.add(v); + }); + + setState(() { + if (dayEvents.length != 0) { + ObGyneTimeSlots.areSlotsAvailable = true; + selectedButtonIndex = 0; + ObGyneTimeSlots.selectedTime = dayEvents![selectedButtonIndex]!.isoTime!; + } else + ObGyneTimeSlots.areSlotsAvailable = false; + }); + } + + Future> _getJSONSlots() async { + Map _eventsParsed; + List slotsList = []; + DateTime date; + final DateFormat formatter = DateFormat('HH:mm'); + final DateFormat dateFormatter = DateFormat('yyyy-MM-dd'); + for (var i = 0; i < freeSlotsResponse.length; i++) { + date = DateUtil.convertStringToDate(freeSlotsResponse[i]); + slotsList.add(FreeSlot(date, ['slot'])); + docFreeSlots.add(TimeSlot(isoTime: formatter.format(date), start: new DateTime(date.year, date.month, date.day, 0, 0, 0, 0), end: date)); + } + _eventsParsed = Map.fromIterable(slotsList, key: (e) => e.slot, value: (e) => e.event); + setState(() { + ObGyneTimeSlots.selectedDate = dateFormatter.format(DateUtil.convertStringToDate(freeSlotsResponse[0])); + selectedDate = DateUtil.getMonthDayYearDateFormatted(DateUtil.convertStringToDate(freeSlotsResponse[0])); + selectedDateJSON = freeSlotsResponse[0]; + }); + openTimeSlotsPickerForDate(DateUtil.convertStringToDate(selectedDateJSON), docFreeSlots); + _calendarController!.selectedDate = DateUtil.convertStringToDate(selectedDateJSON); + return _eventsParsed; + } + + Widget getNormalButton(int index) { + return CustomTextButton( + backgroundColor: Colors.white, + elevation: 0, + onPressed: () { + setState(() { + selectedButtonIndex = index; + ObGyneTimeSlots.selectedTime = dayEvents[index].isoTime!; + print(ObGyneTimeSlots.selectedTime); + }); + }, + child: Text(dayEvents[index].isoTime!, style: TextStyle(fontSize: 12.0, fontWeight: FontWeight.bold, color: Color(0xFF60686b))), + ); + } + + Widget getSelectedButton(int index) { + return CustomTextButton( + backgroundColor: CustomColors.green, + elevation: 0, + onPressed: () { + setState(() { + selectedButtonIndex = index; + ObGyneTimeSlots.selectedTime = dayEvents[index].isoTime!; + print(ObGyneTimeSlots.selectedTime); + }); + }, + child: Text(dayEvents[index].isoTime!, style: TextStyle(fontSize: 12.0, fontWeight: FontWeight.bold, color: Colors.white)), + ); + } + + bookCovidTestAppointment() { + if (ObGyneTimeSlots.areSlotsAvailable) { + GifLoaderDialogUtils.showMyDialog(context); + DoctorList docObject = new DoctorList(); + docObject.doctorID = widget.selectedDoctorID; + docObject.clinicID = widget.selectedClinicID; + docObject.projectID = widget.projectID; + insertAppointmentCovidTest(context, docObject); + } else { + AppToast.showErrorToast(message: TranslationBase.of(context).selectSlot); + } + } + + // updateCovidQuestionnaire(context, String appoNo) async { + // DoctorsListService service = new DoctorsListService(); + // service.updateCovidQuestionnaire(appoNo, widget.projectID, widget.selectedProject.testTypeEnum, widget.selectedProject.testProcedureEnum).then((res) {}).catchError((err) { + // print(err); + // }); + // } + + insertAppointmentCovidTest(context, DoctorList docObject) { + DoctorsListService service = new DoctorsListService(); + AppoitmentAllHistoryResultList appo; + service + .insertAppointment(docObject.doctorID!, docObject.clinicID!, docObject.projectID!, ObGyneTimeSlots.selectedTime, ObGyneTimeSlots.selectedDate, 0, projectViewModel!.isArabic ? 1 : 2, context, + widget.obGyneProcedureListResponse!.procedureId) + .then((res) { + if (res['MessageStatus'] == 1) { + AppToast.showSuccessToast(message: TranslationBase.of(context).bookedSuccess); + updateObGyneAppointment(res['AppointmentNo']); + getToDoCount(); + // getPatientShare(context, res['AppointmentNo'], docObject.clinicID, docObject.projectID, docObject); + } else { + GifLoaderDialogUtils.hideDialog(context); + appo = new AppoitmentAllHistoryResultList(); + appo.appointmentNo = res['SameClinicApptList'][0]['AppointmentNo']; + appo.clinicID = res['SameClinicApptList'][0]['DoctorID']; + appo.projectID = res['SameClinicApptList'][0]['ProjectID']; + appo.endTime = res['SameClinicApptList'][0]['EndTime']; + appo.startTime = res['SameClinicApptList'][0]['StartTime']; + appo.doctorID = res['SameClinicApptList'][0]['DoctorID']; + appo.isLiveCareAppointment = false; + appo.originalClinicID = 0; + appo.originalProjectID = 0; + appo.appointmentDate = res['SameClinicApptList'][0]['AppointmentDate']; + + ConfirmDialog dialog = new ConfirmDialog( + context: context, + confirmMessage: res['ErrorEndUserMessage'], + okText: TranslationBase.of(context).confirm, + cancelText: TranslationBase.of(context).cancel_nocaps, + okFunction: () => {cancelAppointment(docObject, appo, context)}, + cancelFunction: () => {}); + dialog.showAlertDialog(context); + } + }).catchError((err) { + AppToast.showErrorToast(message: err); + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } + + updateObGyneAppointment(String appoNo) { + DoctorsListService service = new DoctorsListService(); + service + .updateObGyneAppointment(widget.obGyneProcedureListResponse!.episodeID!, int.parse(appoNo), widget.obGyneProcedureListResponse!.orderNo!, widget.obGyneProcedureListResponse!.procedureId!, + widget.obGyneProcedureListResponse!.lineItemNo!, widget.obGyneProcedureListResponse!.uniqueRowID!, projectViewModel!.isArabic ? 1 : 2) + .then((res) {}) + .catchError((err) { + print(err); + }); + } + + getToDoCount() { + toDoProvider!.setState(0, 0, true, toDoProvider!.notificationsCount); + ClinicListService service = new ClinicListService(); + service.getActiveAppointmentNo(context).then((res) { + GifLoaderDialogUtils.hideDialog(context); + print(res['AppointmentActiveNumber']); + if (res['MessageStatus'] == 1) { + // toDoProvider.setState(res['AppointmentActiveNumber'], true, toDoProvider.notificationsCount); + toDoProvider!.setState(res['AppointmentActiveNumber'], res['AncillaryOrderListCount'], true, toDoProvider!.notificationsCount); + } else {} + Navigator.pushAndRemoveUntil( + context, + MaterialPageRoute(builder: (context) => LandingPage()), + (Route route) => false, + ); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } + + cancelAppointment(DoctorList docObject, AppoitmentAllHistoryResultList appo, BuildContext context) { + ConfirmDialog.closeAlertDialog(context); + GifLoaderDialogUtils.showMyDialog(context); + DoctorsListService service = new DoctorsListService(); + service.cancelAppointment(appo, context).then((res) { + if (res['MessageStatus'] == 1) { + // Future.delayed(new Duration(milliseconds: 1500), () { + insertAppointmentCovidTest(context, docObject); + // }); + } else { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: res['ErrorEndUserMessage']); + } + }).catchError((err) { + print(err); + }); + } + + // getPatientShare(context, String appointmentNo, int clinicID, int projectID, DoctorList docObject) { + // DoctorsListService service = new DoctorsListService(); + // service.getPatientShare(appointmentNo, clinicID, projectID, context).then((res) { + // GifLoaderDialogUtils.hideDialog(context); + // print(res); + // widget.patientShareResponse = new PatientShareResponse.fromJson(res); + // // updateCovidQuestionnaire(context, appointmentNo); + // navigateToPaymentAlert(); + // }).catchError((err) { + // GifLoaderDialogUtils.hideDialog(context); + // print(err); + // }); + // } + // + // navigateToPaymentAlert() { + // Navigator.push( + // context, + // FadePage( + // page: CovidPaymentAlert(patientShareResponse: widget.patientShareResponse), + // ), + // ); + // } + + getCovidFreeSlots(BuildContext context, int projectID) { + DoctorsListService service = new DoctorsListService(); + GifLoaderDialogUtils.showMyDialog(context); + service.getDoctorFreeSlots(widget.selectedDoctorID!, widget.selectedClinicID!, widget.projectID, false, context).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res['MessageStatus'] == 1) { + if (res['FreeTimeSlots'].length != 0) { + print(res['FreeTimeSlots']); + freeSlotsResponse = res['FreeTimeSlots']; + _getJSONSlots().then((value) => { + setState(() => { + _events!.clear(), + _events = value, + // if (widget.doctorSchedule != null) + // {_onDaySelected(DateUtil.convertStringToDate(widget.doctorSchedule['Date'])), _calendarController.selectedDate = DateUtil.convertStringToDate(widget.doctorSchedule['Date'])} + }) + }); + } else {} + } else { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: res['ErrorEndUserMessage']); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err.toString()); + print(err); + }); + } +} + +class MeetingDataSource extends CalendarDataSource { + MeetingDataSource(List source) { + appointments = source; + } + + @override + DateTime getStartTime(int index) { + return _getMeetingData(index)!.from!; + } + + @override + DateTime getEndTime(int index) { + return _getMeetingData(index)!.to!; + } + + @override + String getSubject(int index) { + return _getMeetingData(index)!.eventName; + } + + @override + Color getColor(int index) { + return _getMeetingData(index)!.background; + } + + @override + bool isAllDay(int index) { + return _getMeetingData(index)!.isAllDay; + } + + Meeting? _getMeetingData(int index) { + final dynamic meeting = appointments![index]; + Meeting? meetingData; + if (meeting is Meeting) { + meetingData = meeting; + } + return meetingData!; + } +} + +class Meeting { + Meeting(this.eventName, this.from, this.to, this.background, this.isAllDay, this.notes); + + String eventName; + DateTime from; + DateTime to; + Color background; + bool isAllDay; + String notes; +} diff --git a/lib/pages/ToDoList/ToDo.dart b/lib/pages/ToDoList/ToDo.dart index 79bcd94b..c5d99320 100644 --- a/lib/pages/ToDoList/ToDo.dart +++ b/lib/pages/ToDoList/ToDo.dart @@ -1,427 +1,586 @@ +import 'dart:developer'; +import 'dart:io'; + +import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/enum/PayfortEnums.dart'; 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/Appointments/AppoimentAllHistoryResultList.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; +import 'package:diplomaticquarterapp/models/Appointments/OBGyneProcedureListResponse.dart'; import 'package:diplomaticquarterapp/models/Appointments/PatientShareResposne.dart'; import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; +import 'package:diplomaticquarterapp/models/LiveCare/ApplePayInsertRequest.dart'; +import 'package:diplomaticquarterapp/models/anicllary-orders/ancillary_order_list_model.dart'; +import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/ancillary-orders/ancillaryOrdersDetails.dart'; +import 'package:diplomaticquarterapp/pages/Blood/blood_donation_appointment_terms_conditions.dart'; import 'package:diplomaticquarterapp/pages/BookAppointment/QRCode.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/SearchResults.dart'; import 'package:diplomaticquarterapp/pages/MyAppointments/AppointmentDetails.dart'; import 'package:diplomaticquarterapp/pages/ToDoList/payment_method_select.dart'; import 'package:diplomaticquarterapp/pages/ToDoList/widgets/paymentDialog.dart'; -import 'package:diplomaticquarterapp/routes.dart'; +import 'package:diplomaticquarterapp/pages/insurance/insurance_update_screen.dart'; +import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; +import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; +import 'package:diplomaticquarterapp/services/livecare_services/livecare_provider.dart'; +import 'package:diplomaticquarterapp/services/payfort_services/payfort_project_details_resp_model.dart'; +import 'package:diplomaticquarterapp/services/payfort_services/payfort_view_model.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/app-permissions.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/penguin_method_channel.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/avatar/large_avatar.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/medical/doctor_card.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart'; +import 'package:diplomaticquarterapp/widgets/my_rich_text.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_expandable_notifier.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_countdown_timer/countdown_timer_controller.dart'; import 'package:flutter_countdown_timer/current_remaining_time.dart'; import 'package:flutter_countdown_timer/flutter_countdown_timer.dart'; +import 'package:flutter_rating_bar/flutter_rating_bar.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:permission_handler/permission_handler.dart'; import 'package:provider/provider.dart'; -import 'package:rating_bar/rating_bar.dart'; class ToDo extends StatefulWidget { - PatientShareResponse patientShareResponse; - List appoList = []; + PatientShareResponse? patientShareResponse; var languageID; - MyInAppBrowser browser; - bool isShowAppBar = true; + // MyInAppBrowser? browser; + bool? isShowAppBar = true; + Function()? onBackClick; + bool? isFromMyAppointments; + AppoitmentAllHistoryResultList? appointment; - ToDo({@required this.isShowAppBar}); + ToDo({required this.isShowAppBar, this.onBackClick, this.isFromMyAppointments = false, this.appointment}); @override _ToDoState createState() => _ToDoState(); } -class _ToDoState extends State { +class _ToDoState extends State with SingleTickerProviderStateMixin { AppSharedPreferences sharedPref = AppSharedPreferences(); - AuthenticatedUser authUser; - AuthenticatedUserObject authenticatedUserObject = - locator(); + List imagesInfo = []; + late ToDoCountProviderModel toDoProvider; + late CountdownTimerController controller; + + late ProjectViewModel projectViewModel; + late TabController _tabController; - List imagesInfo = List(); + String selectedPaymentMethod = ""; + String selectedInstallments = ""; + late String tamaraPaymentStatus; + late String tamaraOrderID; - ToDoCountProviderModel toDoProvider; - CountdownTimerController controller; + bool dataLoaded = false; + + bool isInsured = false; + bool isEligible = false; + bool isCash = false; + MyInAppBrowser? browser; + + List appoList = []; + List ancillaryLists = []; + List obGyneAppoList = []; + String? transID; @override void initState() { widget.patientShareResponse = new PatientShareResponse(); + _tabController = TabController(length: 2, vsync: this); WidgetsBinding.instance.addPostFrameCallback((_) { - if (authenticatedUserObject.isLogin) getPatientData(); + getPatientAppointmentHistory(); + getAncillaryOrders(); }); super.initState(); - imagesInfo.add(ImagesInfo( - imageEn: - 'https://hmgwebservices.com/Images/MobileApp/images-info-home/todo/en/0.png', - imageAr: - 'https://hmgwebservices.com/Images/MobileApp/images-info-home/todo/ar/0.png')); + imagesInfo + .add(ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/images-info-home/todo/en/0.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/images-info-home/todo/ar/0.png')); int endTime = DateTime.now().millisecondsSinceEpoch + 1000 * 30; controller = CountdownTimerController(endTime: endTime); } + @override + void dispose() { + super.dispose(); + // getToDoCount(); + _tabController.dispose(); + } + @override Widget build(BuildContext context) { toDoProvider = Provider.of(context); - ProjectViewModel projectViewModel = Provider.of(context); + projectViewModel = Provider.of(context); return AppScaffold( appBarTitle: TranslationBase.of(context).todoList, imagesInfo: imagesInfo, - isShowAppBar: widget.isShowAppBar, + isShowAppBar: widget.isShowAppBar!, isShowDecPage: true, + showNewAppBar: true, + showNewAppBarTitle: true, + icon: "assets/images/new/bottom_nav/todo.svg", description: TranslationBase.of(context).infoTodo, - body: SingleChildScrollView( - child: Column( - children: [ - Container( - child: ListView.builder( - scrollDirection: Axis.vertical, - shrinkWrap: true, - physics: ScrollPhysics(), - padding: EdgeInsets.all(0.0), - itemCount: widget.appoList.length, - itemBuilder: (context, index) { - return Container( - margin: EdgeInsets.all(10.0), - child: Column( - children: [ - Container( - child: Card( - margin: EdgeInsets.fromLTRB(8.0, 0.0, 8.0, 8.0), - color: Colors.white, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - ), - child: Container( - width: MediaQuery.of(context).size.width, - padding: EdgeInsets.all(10.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - children: [ - Row( - children: [ - Image.asset( - "assets/images/new-design/time_icon.png", - width: 20.0, - height: 20.0), - Container( - margin: EdgeInsets.only( - left: 10.0, right: 10.0), - child: Text( - DateUtil.getWeekDayMonthDayYearDateFormatted( - DateUtil.convertStringToDate( - widget.appoList[index] - .appointmentDate), - projectViewModel.isArabic - ? "ar" - : "en") + - " " + - widget.appoList[index].startTime - .substring(0, 5), - style: TextStyle(fontSize: 10.0)), - ), - !widget.appoList[index] - .isLiveCareAppointment - ? Image.asset( - "assets/images/new-design/hospital_address_icon.png", - width: 20.0, - height: 20.0) - : Container(), - Container( - margin: EdgeInsets.only( - left: 5.0, right: 5.0), - child: widget.appoList[index] - .isLiveCareAppointment - ? Container() - : Text( - widget.appoList[index] - .projectName != - null - ? widget.appoList[index] - .projectName - : "-", - overflow: TextOverflow.clip, - maxLines: 2, - style: - TextStyle(fontSize: 10.0)), - ), - ], - ), - Container( - margin: EdgeInsets.only(top: 5.0), - child: Divider( - color: Colors.grey[500], - ), - ), - Flex( - direction: Axis.horizontal, - children: [ - Expanded( - flex: 1, - child: Container( - height: MediaQuery.of(context) - .size - .height * - 0.1, - margin: EdgeInsets.only(top: 5.0), - child: ClipRRect( - borderRadius: - BorderRadius.circular(100.0), - child: Image.network( - widget.appoList[index] - .doctorImageURL, - fit: BoxFit.fill), + onTap: widget!.onBackClick, + backgroundColor: CustomColors.appBackgroudGrey2Color, + body: Column( + children: [ + TabBar( + controller: _tabController, + indicatorWeight: 3.0, + indicatorSize: TabBarIndicatorSize.tab, + labelColor: Color(0xff2B353E), + unselectedLabelColor: Color(0xff575757), + labelPadding: EdgeInsets.only(top: 15, bottom: 13, 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: [Text(TranslationBase.of(context).appointments), Text(TranslationBase.of(context).orders)], + onTap: (index) { + if (index == 1) { + getOBGyneOrdersList(); + } + }, + ), + Expanded( + child: TabBarView( + physics: BouncingScrollPhysics(), + controller: _tabController, + children: [ + SingleChildScrollView( + child: Column( + children: [ + Container( + margin: EdgeInsets.only(top: 12), + child: AppExpandableNotifier( + isExpand: true, + hasCounter: true, + counter: appoList.length.toString(), + title: TranslationBase.of(context).appointments, + bodyWidget: appoList.length != 0 + ? ListView.builder( + scrollDirection: Axis.vertical, + shrinkWrap: true, + physics: ScrollPhysics(), + padding: EdgeInsets.all(0.0), + itemCount: appoList.length, + itemBuilder: (context, index) { + return Container( + width: double.infinity, + margin: EdgeInsets.only(left: 12.0, right: 12.0, top: 12.0), + decoration: cardRadius(12), + padding: EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + flex: 2, + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(top: 4.0), + child: appoList[index].clinicID == 265 + ? Container( + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: SvgPicture.asset("assets/images/new/CoronaIcon.svg", width: 35.0, height: 35.0), + ) + : appoList[index].isLiveCareAppointment! + ? SvgPicture.asset("assets/images/new/virtual.svg") + : SvgPicture.asset("assets/images/new/hospital-visit.svg"), + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(left: 8.0, right: 8.0), + child: Text( + appoList[index].clinicID == 265 + ? TranslationBase.of(context).covidTestTodo + : appoList[index].isLiveCareAppointment! + ? TranslationBase.of(context).liveCareAppo + : TranslationBase.of(context).walkinAppo, + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.48)), + ), + Padding( + padding: const EdgeInsets.only(left: 8.0, right: 8.0), + child: CountdownTimer( + controller: + new CountdownTimerController(endTime: DateTime.now().millisecondsSinceEpoch + (appoList[index].remaniningHoursTocanPay! * 1000) * 60), + widgetBuilder: (_, CurrentRemainingTime? time) { + return time != null + ? Text( + '${time.days != null ? time.days : "0"}:${time.hours != null ? time.hours.toString().length == 1 ? "0" + time.hours.toString() : time.hours : "00"}:${time.min}:${time.sec} \n' + + TranslationBase.of(context).upcomingTimeLeft, + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: CustomColors.accentColor, letterSpacing: -0.48)) + : Container(); + }, + ), + ), + ], + ), + ], + ), + ), + Expanded( + child: Container( + child: InkWell( + onTap: () { + performNextAction(appoList[index]); + }, + child: Container( + padding: EdgeInsets.symmetric(vertical: 8, horizontal: 14), + decoration: BoxDecoration( + color: getNextActionButtonColor(appoList[index].nextAction), + border: Border.all(color: Colors.white, width: 1), + borderRadius: BorderRadius.circular(6), + ), + child: Text( + getNextActionText(appoList[index].nextAction), + textAlign: TextAlign.center, + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Colors.white, letterSpacing: -0.4), + ), + ), + ), + ), + ), + ], ), - ), - ), - Expanded( - flex: 3, - child: Container( - margin: EdgeInsets.only( - top: 10.0, - left: 20.0, - right: 20.0), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, + Padding( + padding: const EdgeInsets.only(top: 8.0), + child: Text( + appoList[index].doctorTitle! + " " + appoList[index].doctorNameObj!, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.64, height: 25 / 16), + ), + ), + Row( + mainAxisSize: MainAxisSize.min, children: [ - Text( - widget.appoList[index] - .doctorTitle + - " " + - widget.appoList[index] - .doctorNameObj, - style: TextStyle( - fontSize: 14.0, - color: Colors.black, - fontWeight: - FontWeight.bold, - letterSpacing: 1.0)), - Container( - margin: EdgeInsets.only( - top: 3.0, bottom: 3.0), - child: Text( - getDoctorSpeciality(widget - .appoList[index] - .doctorSpeciality) - .trim(), - style: TextStyle( - fontSize: 12.0, - color: Colors.grey[600], - letterSpacing: 1.0)), + LargeAvatar( + name: appoList[index].doctorTitle! + " " + appoList[index].doctorNameObj!, + url: appoList[index].doctorImageURL, + width: 52, + height: 52, + ), + SizedBox(width: 11), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + MyRichText(TranslationBase.of(context).clinic + ": ", appoList[index].clinicName!, projectViewModel.isArabic), + // MyRichText(TranslationBase.of(context).appointmentDate + ": ", + // DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(appoList[index].appointmentDate)) + " " + appoList[index].startTime.substring(0, 5), projectViewModel.isArabic), + + // Timezone changes + appoList[index].isLiveCareAppointment! + ? MyRichText( + TranslationBase.of(context).appointmentDate + ": ", + DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(appoList[index].appointmentDate)) + + " " + + DateUtil.convertStringToDate(appoList[index].appointmentDate).toString().split(" ")[1].substring(0, 5), + projectViewModel.isArabic) + : MyRichText( + TranslationBase.of(context).appointmentDate + ": ", + DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(appoList[index].appointmentDate)) + + " " + + appoList[index].startTime!.substring(0, 5), + projectViewModel.isArabic), + + MyRichText(TranslationBase.of(context).branch, appoList[index].projectName!, projectViewModel.isArabic), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + mainAxisSize: MainAxisSize.max, + children: [ + RatingBar( + initialRating: appoList[index].actualDoctorRate.toDouble(), + itemSize: 16.0, + glowColor: Color(0XFFD02127), + unratedColor: Color(0XFFD02127), + ignoreGestures: true, + ratingWidget: RatingWidget( + full: Icon( + Icons.star, + color: CustomColors.accentColor, + ), + half: Icon( + Icons.star_half, + color: CustomColors.accentColor, + ), + empty: Icon( + Icons.star, + color: CustomColors.accentColor, + ), + ), + tapOnlyMode: true, + allowHalfRating: true, + onRatingUpdate: (double value) {}, + // : Icons.star_half, + // ic: Icons.star, + // emptyIcon: Icons.star_border, itemBuilder: (BuildContext context, int index) { }, + ), + ], + ), + ], + ), ), - Row( - mainAxisAlignment: - MainAxisAlignment - .spaceBetween, - mainAxisSize: MainAxisSize.max, - children: [ - RatingBar.readOnly( - initialRating: widget - .appoList[index] - .actualDoctorRate - .toDouble(), - size: 20.0, - filledColor: - Colors.yellow[700], - emptyColor: - Colors.grey[500], - isHalfAllowed: true, - halfFilledIcon: - Icons.star_half, - filledIcon: Icons.star, - emptyIcon: Icons.star, + ], + ), + Padding( + padding: const EdgeInsets.only(top: 12.0), + child: Text( + getNextActionDescription(appoList[index].nextAction), + style: TextStyle(fontSize: 10, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.48, height: 25 / 16), + ), + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + InkWell( + onTap: () { + navigateToAppointmentDetails(context, appoList[index]); + }, + child: Padding( + padding: const EdgeInsets.only(top: 0.0), + child: Text( + TranslationBase.of(context).moreDetails, + style: TextStyle( + fontSize: 10, + fontWeight: FontWeight.w600, + color: CustomColors.accentColor, + letterSpacing: -0.48, + height: 25 / 16, + decoration: TextDecoration.underline), ), - ], + ), ), - Container( - child: CountdownTimer( - controller: new CountdownTimerController( - endTime: DateTime.now() - .millisecondsSinceEpoch + - (widget - .appoList[ - index] - .remaniningHoursTocanPay * - 1000) * - 60), - widgetBuilder: (_, - CurrentRemainingTime - time) { - return time != null - ? Text( - '${time.days != null ? time.days : "0"}:${time.hours.toString().length == 1 ? "0" + time.hours.toString() : time.hours}:${time.min}:${time.sec} ' + - TranslationBase.of( - context) - .upcomingTimeLeft, - style: TextStyle( - fontSize: 12.0, - color: Color( - 0xff40ACC9))) - : Container(); + if (projectViewModel.isIndoorNavigationEnabled && projectViewModel.havePrivilege(107) && appoList[index].projectID == 130) + InkWell( + onTap: () { + NavigationClinicDetails data = NavigationClinicDetails(); + data.clinicId = appoList[index].clinicID.toString(); + // data.clinicId = "46"; + data.patientId = appoList[index].patientID.toString(); + data.projectId = appoList[index].projectID.toString(); + initPenguinSDK(data); }, + child: Column( + children: [ + SvgPicture.asset( + "assets/images/new/Indoor_nav_appo.svg", + ), + Text( + TranslationBase.of(context).clinicLocation, + style: TextStyle( + fontSize: 10, + fontWeight: FontWeight.w600, + color: CustomColors.accentColor, + letterSpacing: -0.48, + height: 25 / 16, + decoration: TextDecoration.underline), + ), + ], + ), ), + ], + ), + ], + ), + ); + }, + ) + : getNoDataWidget(context), + ), + ), + Container( + margin: EdgeInsets.only(top: 12), + child: AppExpandableNotifier( + isExpand: true, + hasCounter: true, + counter: (ancillaryLists.isNotEmpty) ? ancillaryLists[0].ancillaryOrderList!.length.toString() : "0", + title: TranslationBase.of(context).anicllaryOrders, + bodyWidget: ancillaryLists.length != 0 + ? Container( + padding: EdgeInsets.all(12), + child: ListView.separated( + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + reverse: true, + itemBuilder: (context, index) { + return DoctorCard( + onTap: () => ancillaryOrdersDetails(ancillaryLists[0].ancillaryOrderList![index], ancillaryLists[0].projectID), + isInOutPatient: true, + name: TranslationBase.of(context).dr.toString() + " " + (ancillaryLists[0].ancillaryOrderList![index].doctorName ?? ""), + billNo: ancillaryLists[0].ancillaryOrderList![index].orderNo.toString(), + profileUrl: "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png", + subName: ancillaryLists[0].projectName, + isLiveCareAppointment: false, + date: DateUtil.convertStringToDate(ancillaryLists[0].ancillaryOrderList![index].orderDate), + isSortByClinic: true, + ); + }, + itemCount: ancillaryLists[0].ancillaryOrderList!.length, + separatorBuilder: (context, index) => SizedBox(height: 14), + ), + ) + : getNoDataWidget(context), + )), + ], + ), + ), + Container( + child: obGyneAppoList.length != 0 + ? ListView.builder( + scrollDirection: Axis.vertical, + shrinkWrap: true, + physics: ScrollPhysics(), + padding: EdgeInsets.all(0.0), + itemCount: obGyneAppoList.length, + itemBuilder: (context, index) { + return Container( + width: double.infinity, + margin: EdgeInsets.only(left: 12.0, right: 12.0, top: 12.0), + decoration: cardRadius(12), + padding: EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(top: 0.0), + child: Container( + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: SvgPicture.asset("assets/images/new/ultrasound.svg", width: 20.0, height: 20.0), + ), + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(left: 8.0, right: 8.0), + child: Text(TranslationBase.of(context).walkinAppo, + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.48)), ), ], ), - ), + ], ), - Expanded( - flex: 1, + Container( child: InkWell( - onTap: () => performNextAction( - widget.appoList[index]), + onTap: () { + getOBGyneDoctorsList(obGyneAppoList[index].projectID!, obGyneAppoList[index].setupID!, obGyneAppoList[index]); + }, child: Container( - margin: EdgeInsets.only(top: 20.0), - child: Column( - children: [ - Image.asset( - getNextActionImage(widget - .appoList[index] - .nextAction), - width: 50.0, - height: 50.0), - Container( - margin: - EdgeInsets.only(top: 5.0), - child: Text( - getNextActionText(widget - .appoList[index] - .nextAction), - textAlign: - TextAlign.center, - style: TextStyle( - fontSize: 12.0)), - ) - ], + padding: EdgeInsets.symmetric(vertical: 8, horizontal: 14), + decoration: BoxDecoration( + color: CustomColors.green, + border: Border.all(color: Colors.white, width: 1), + borderRadius: BorderRadius.circular(6), + ), + child: Text( + TranslationBase.of(context).bookNow, + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Colors.white, letterSpacing: -0.4), ), ), ), - ) + ), ], ), - Divider( - color: Colors.grey[500], + Padding( + padding: const EdgeInsets.only(top: 8.0), + child: Text( + TranslationBase.of(context).dr + " " + obGyneAppoList[index].doctorName!, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.64, height: 25 / 16), + ), ), - Flex( - direction: Axis.horizontal, + Row( + mainAxisSize: MainAxisSize.min, children: [ - Expanded( - flex: 2, - child: Container( - child: Text( - getNextActionDescription(widget - .appoList[index].nextAction), - style: TextStyle( - fontSize: 12.0, - color: Colors.grey[700])), - ), + LargeAvatar( + name: TranslationBase.of(context).dr + " " + obGyneAppoList[index].doctorName!, + url: "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png", + width: 52, + height: 52, ), + SizedBox(width: 11), Expanded( - flex: 1, - child: GestureDetector( - onTap: () { - navigateToAppointmentDetails( - context, - widget.appoList[index]); - }, - child: Container( - child: Text( - TranslationBase.of(context) - .upcomingDetails, - textAlign: TextAlign.end, - style: TextStyle( - fontSize: 12.0, - color: - new Color(0xFF40ACC9), - decoration: TextDecoration - .underline)), - ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + MyRichText(TranslationBase.of(context).clinic + ": ", obGyneAppoList[index].clinicDescription!, projectViewModel.isArabic), + MyRichText( + TranslationBase.of(context).orderDate + ": ", + DateUtil.getDayMonthYearHourMinuteDateFormatted(DateUtil.convertStringToDate(obGyneAppoList[index].orderDate)).split(" ")[0], + projectViewModel.isArabic), + MyRichText(TranslationBase.of(context).branch, obGyneAppoList[index].projectDescription!, projectViewModel.isArabic), + ], ), - ) + ), ], ), ], ), - ), - ), - ), - Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.only( - bottomLeft: Radius.circular(10.0), - bottomRight: Radius.circular(10.0)), - color: Color(0xff20bc44), - ), - height: 30.0, - margin: projectViewModel.isArabic - ? EdgeInsets.fromLTRB(160.0, 0.0, 30.0, 0.0) - : EdgeInsets.fromLTRB(20.0, 0.0, 160.0, 0.0), - transform: Matrix4.translationValues(0.0, -8.0, 0.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - widget.appoList[index].isLiveCareAppointment - ? Container( - margin: EdgeInsets.fromLTRB( - 5.0, 0.0, 5.0, 0.0), - child: Image.asset( - "assets/images/new-design/video.png"), - ) - : Container( - margin: EdgeInsets.fromLTRB( - 5.0, 0.0, 5.0, 0.0), - child: Image.asset( - "assets/images/new-design/walkin.png"), - ), - widget.appoList[index].isLiveCareAppointment - ? Container( - child: Text( - TranslationBase.of(context).videoAppo, - style: TextStyle( - color: Colors.white, - fontWeight: FontWeight.bold, - fontSize: 11.0)), - ) - : Container( - child: Text( - TranslationBase.of(context) - .walkinAppo, - style: TextStyle( - color: Colors.white, - fontWeight: FontWeight.bold, - fontSize: 11.0)), - ) - ], - ), - ), - ], - ), - ); - }, - ), - ), - SizedBox( - height: 120.0, + ); + }, + ) + : getNoDataWidget(context), + ), + ], ), - ], - ), + ), + SizedBox( + height: 20.0, + ), + ], ), ); } + initPenguinSDK(NavigationClinicDetails data) async { + final bool permited = await AppPermission.askPenguinPermissions(); + if (!permited) { + Map statuses = await [ + Permission.location, + Permission.bluetooth, + Permission.bluetoothConnect, + Permission.bluetoothScan, + Permission.activityRecognition, + ].request().whenComplete(() { + PenguinMethodChannel().launch("penguin", projectViewModel.isArabic ? "ar" : "en", projectViewModel.authenticatedUserObject.user.patientID.toString(), details: data); + }); + } + } + String getNextActionImage(nextAction) { switch (nextAction) { case 0: @@ -432,33 +591,28 @@ class _ToDoState extends State { break; case 15: - return widget.languageID == 'ar' - ? "assets/images/new-design/pay_online_button_arabic_disabled.png" - : "assets/images/new-design/pay_online_button_disabled.png"; + return projectViewModel.isArabic ? "assets/images/new-design/pay_online_button_arabic_disabled.png" : "assets/images/new-design/pay_online_button_disabled.png"; break; case 20: - return widget.languageID == 'ar' - ? "assets/images/new-design/pay_online_button_arabic.png" - : "assets/images/new-design/pay_online_button.png"; + return projectViewModel.isArabic ? "assets/images/new-design/pay_online_button_arabic.png" : "assets/images/new-design/pay_online_button.png"; break; case 30: - return "assets/images/new-design/qr_code_button.png"; + return "assets/images/new-design/NFCIcon_option2.png"; break; - case 40: return "assets/images/new-design/video_call_instruction.png"; break; - case 50: return "assets/images/new-design/confirm_button.png"; break; - case 60: return "assets/images/new-design/waiting_for_doctor.png"; break; - + case 90: + return "assets/images/new-design/NFCIcon_option2.png"; + break; default: return ""; } @@ -466,20 +620,82 @@ class _ToDoState extends State { performNextAction(AppoitmentAllHistoryResultList appo) { switch (appo.nextAction) { + case 0: + // getAppoQR(context, appo); + break; case 10: confirmAppointment(appo); break; + case 15: + AppToast.showErrorToast(message: TranslationBase.of(context).upcomingPaymentPending); + break; case 20: getPatientShare(context, appo); + // checkPatientNphiesEligibility(context, appo); break; case 30: getAppoQR(context, appo); break; + case 40: + openInstructions(appo); + break; + case 50: confirmAppointment(appo); break; case 60: break; + case 90: + getAppoQR(context, appo); + break; + } + } + + openInstructions(AppoitmentAllHistoryResultList appo) { + if (appo.clinicID == 134) { + Navigator.of(context).push(FadePage(page: BloodDonationAppointmentTermsConditions())); + } + } + + Color getNextActionButtonColor(nextAction) { + switch (nextAction) { + case 0: + return CustomColors.accentColor; + break; + case 10: + return CustomColors.green; + break; + + case 15: + return CustomColors.grey2; + break; + + case 20: + return CustomColors.green; + break; + + case 30: + return CustomColors.accentColor; + break; + + case 40: + return CustomColors.green; + break; + + case 50: + return CustomColors.green; + break; + + case 60: + return CustomColors.orange; + break; + + case 90: + return CustomColors.accentColor; + break; + + default: + return CustomColors.green; } } @@ -516,6 +732,10 @@ class _ToDoState extends State { return TranslationBase.of(context).waitingForDoctor; break; + case 90: + return TranslationBase.of(context).checkinOptions; + break; + default: return ""; } @@ -539,7 +759,11 @@ class _ToDoState extends State { break; case 30: - return TranslationBase.of(context).upcomingQR; + return TranslationBase.of(context).upcomingQRNFC; + break; + + case 90: + return TranslationBase.of(context).upcomingQRNFC; break; case 40: @@ -560,8 +784,7 @@ class _ToDoState extends State { } getLanguageID() async { - var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); setState(() { widget.languageID = languageID; }); @@ -598,37 +821,115 @@ class _ToDoState extends State { return docSpeciality; } - Future navigateToAppointmentDetails(context, appo) async { - Navigator.push( - context, - FadePage( - page: AppointmentDetails(appo: appo))) - .then((value) { + Future navigateToAppointmentDetails(context, AppoitmentAllHistoryResultList appo) async { + GAnalytics.APPOINTMENT_DETAIL_FLOW_TYPE = 'todo list'; + Navigator.push(context, FadePage(page: AppointmentDetails(appo: appo, parentIndex: appo.patientStatusType == 42 ? 1 : 0))).then((value) { getPatientAppointmentHistory(); }); + projectViewModel.analytics.todoList.to_do_list_more_details(appo); + } + + getOBGyneOrdersList() { + GifLoaderDialogUtils.showMyDialog(context); + DoctorsListService service = new DoctorsListService(); + service.getOBGyneOrdersList(context).then((res) { + obGyneAppoList.clear(); + GifLoaderDialogUtils.hideDialog(context); + if (res['MessageStatus'] == 1) { + setState(() { + if (res['HIS_OBGYNEProcedureGet_List'].length != 0) { + obGyneAppoList.clear(); + res['HIS_OBGYNEProcedureGet_List'].forEach((v) { + obGyneAppoList.add(new OBGyneProcedureListResponse.fromJson(v)); + }); + } else { + // Navigator.of(context).popAndPushNamed(HOME); + } + }); + } else { + AppToast.showErrorToast(message: res['ErrorEndUserMessage']); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); } - getPatientAppointmentHistory() { + getOBGyneDoctorsList(int projectID, String setupID, OBGyneProcedureListResponse obGyneProcedureListResponse) { GifLoaderDialogUtils.showMyDialog(context); DoctorsListService service = new DoctorsListService(); - service.getPatientAppointmentHistory(true, context).then((res) { - widget.appoList.clear(); + List doctorsList = []; + List _patientDoctorAppointmentListHospital = []; + service.getOBGyneDoctorsList(projectID, setupID, projectViewModel.isArabic ? 1 : 2, context).then((res) { GifLoaderDialogUtils.hideDialog(context); + print(res['HIS_ObgyneUltrasoundDoctorsList'][0]); if (res['MessageStatus'] == 1) { setState(() { - if (res['AppoimentAllHistoryResultList'].length != 0) { - widget.appoList.clear(); - res['AppoimentAllHistoryResultList'].forEach((v) { - widget.appoList - .add(new AppoitmentAllHistoryResultList.fromJson(v)); + if (res['HIS_ObgyneUltrasoundDoctorsList'].length != 0) { + res['HIS_ObgyneUltrasoundDoctorsList'].forEach((v) { + doctorsList.add(new DoctorList.fromJson(v)); + }); + print(doctorsList.length); + 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)); + } }); + navigateToSearchResults(context, doctorsList, _patientDoctorAppointmentListHospital, obGyneProcedureListResponse); } else { - Navigator.of(context).popAndPushNamed(HOME); + // Navigator.of(context).popAndPushNamed(HOME); } }); } else { AppToast.showErrorToast(message: res['ErrorEndUserMessage']); } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } + + navigateToSearchResults(context, List docList, List patientDoctorAppointmentListHospital, OBGyneProcedureListResponse obGyneProcedureListResponse) { + Navigator.push( + context, + FadePage( + page: SearchResults( + isLiveCareAppointment: false, + isObGyneAppointment: true, + doctorsList: docList, + isDoctorSearchResult: false, + patientDoctorAppointmentListHospital: patientDoctorAppointmentListHospital, + obGyneProcedureListResponse: obGyneProcedureListResponse))); + } + + getAncillaryOrders() { + DoctorsListService service = new DoctorsListService(); + service.getAncillaryOrders().then((res) { + if (res['MessageStatus'] == 1) { + if (res['AncillaryOrderList'].length != 0) { + res['AncillaryOrderList'].forEach((v) { + ancillaryLists.add(new AncillaryOrdersListModel.fromJson(v)); + }); + } + // if (res['AncillaryOrderList'].length != 0) { + // res['AncillaryOrderList'].forEach((item) { + // ancillaryLists.add(AncillaryOrdersListModel.fromJson(item)); + // }); + // } + // dataLoaded = true; + // if (widget.isFromMyAppointments) { + // performNextAction(widget.appointment); + // widget.isFromMyAppointments = false; + // } + setState(() {}); + } else { + AppToast.showErrorToast(message: res['ErrorEndUserMessage']); + } }).catchError((err) { print(err); GifLoaderDialogUtils.hideDialog(context); @@ -636,19 +937,145 @@ class _ToDoState extends State { }); } + getPatientAppointmentHistory() async { + int languageID = projectViewModel.isArabic ? 1 : 2; + GifLoaderDialogUtils.showMyDialog(context); + DoctorsListService service = new DoctorsListService(); + service.getPatientAppointmentHistory(true, languageID, context).then((res) { + appoList.clear(); + GifLoaderDialogUtils.hideDialog(context); + if (res['MessageStatus'] == 1) { + if (res['AppoimentAllHistoryResultList'].length != 0) { + appoList.clear(); + res['AppoimentAllHistoryResultList'].forEach((v) { + appoList.add(new AppoitmentAllHistoryResultList.fromJson(v)); + }); + } + // if (res['AncillaryOrderList'].length != 0) { + // res['AncillaryOrderList'].forEach((item) { + // ancillaryLists.add(AncillaryOrdersListModel.fromJson(item)); + // }); + // } + dataLoaded = true; + if (widget.isFromMyAppointments!) { + performNextAction(widget.appointment!); + widget.isFromMyAppointments = false; + } + setState(() {}); + } else { + AppToast.showErrorToast(message: res['ErrorEndUserMessage']); + } + }).catchError((err) { + print(err); + GifLoaderDialogUtils.hideDialog(context); + err != null ?? AppToast.showErrorToast(message: err); + }); + getToDoCount(); + } + + getToDoCount() { + toDoProvider.setState(0, 0, true, "0"); + ClinicListService service = new ClinicListService(); + service.getActiveAppointmentNo(context).then((res) { + if (res['MessageStatus'] == 1) { + toDoProvider.setState(res['AppointmentActiveNumber'], res['AncillaryOrderListCount'], true, "0"); + } else {} + }).catchError((err) { + print(err); + }); + } + + checkPatientNphiesEligibility(context, AppoitmentAllHistoryResultList appo) { + DoctorsListService service = new DoctorsListService(); + GifLoaderDialogUtils.showMyDialog(context); + service.checkPatientNphiesEligibility(appo.projectID).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res["isNphiesMatchedWithVida"]) { + getPatientShare(context, appo); + // getToDoCount(); + } else { + ConfirmDialog dialog = new ConfirmDialog( + isDissmissable: false, + context: context, + confirmMessage: res['ErrorEndUserMessage'], + okText: "Update insurance", + cancelText: "Continue as cash", + okFunction: () => {openUpdateInsurance()}, + cancelFunction: () => {continueAsCash(appo, false)}); + dialog.showAlertDialog(context); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } + + void openUpdateInsurance() { + Navigator.pushAndRemoveUntil(context, MaterialPageRoute(builder: (context) => LandingPage()), (Route r) => false); + Navigator.push(context, FadePage(page: InsuranceUpdate())); + } + + void continueAsCash(AppoitmentAllHistoryResultList appo, bool isLiveCareAppointment) { + DoctorsListService service = new DoctorsListService(); + GifLoaderDialogUtils.showMyDialog(context); + service.convertPatientToCash(appo.projectID!).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res["MessageStatus"] == 1) { + if (isLiveCareAppointment) { + getLiveCareAppointmentPatientShare(context, service, appo); + } else { + getPatientShare(context, appo); + } + // getToDoCount(); + } else { + AppToast.showErrorToast(message: res["ErrorEndUserMessage"]); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + getPatientShare(context, AppoitmentAllHistoryResultList appo) { + int languageID = projectViewModel.isArabic ? 1 : 2; + String errorMsg = ""; DoctorsListService service = new DoctorsListService(); - if (appo.isLiveCareAppointment) { + if (appo.isLiveCareAppointment!) { getLiveCareAppointmentPatientShare(context, service, appo); } else { GifLoaderDialogUtils.showMyDialog(context); - service - .getPatientShare(appo.appointmentNo.toString(), appo.clinicID, - appo.projectID, context) - .then((res) { + service.getPatientShare(appo.appointmentNo.toString(), appo.clinicID, appo.projectID, languageID, context).then((res) { GifLoaderDialogUtils.hideDialog(context); - widget.patientShareResponse = new PatientShareResponse.fromJson(res); - openPaymentDialog(appo, widget.patientShareResponse); + if (res['OnlineCheckInAppointments'].length != 0) { + widget.patientShareResponse = new PatientShareResponse.fromJson(res['OnlineCheckInAppointments'][0]); + } + isInsured = res["IsInsured"]; + isEligible = res["IsEligible"]; + isCash = res["IsCash"]; + + if (isCash) { + openPaymentDialog(appo, widget.patientShareResponse!); + } else { + if (isInsured && isEligible) { + openPaymentDialog(appo, widget.patientShareResponse!); + } else { + if (isInsured && !isEligible) { + errorMsg = TranslationBase.of(context).invalidEligibility; + } else { + errorMsg = TranslationBase.of(context).invalidInsurance; + } + ConfirmDialog dialog = new ConfirmDialog( + isDissmissable: false, + context: context, + confirmMessage: errorMsg, + okText: TranslationBase.of(context).updateInsuranceText, + cancelText: TranslationBase.of(context).continueCash, + okFunction: () => {openUpdateInsurance()}, + cancelFunction: () => {continueAsCash(appo, false)}); + dialog.showAlertDialog(context); + } + } }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); AppToast.showErrorToast(message: err); @@ -657,17 +1084,41 @@ class _ToDoState extends State { } } - getLiveCareAppointmentPatientShare(context, DoctorsListService service, - AppoitmentAllHistoryResultList appo) { + getLiveCareAppointmentPatientShare(context, DoctorsListService service, AppoitmentAllHistoryResultList appo) { + String errorMsg = ""; GifLoaderDialogUtils.showMyDialog(context); - service - .getLiveCareAppointmentPatientShare(appo.appointmentNo.toString(), - appo.clinicID, appo.projectID, context) - .then((res) { - print(res); + service.getLiveCareAppointmentPatientShare(appo.appointmentNo.toString(), appo.clinicID, appo.projectID, projectViewModel.isArabic ? 1 : 2, context).then((res) { GifLoaderDialogUtils.hideDialog(context); widget.patientShareResponse = new PatientShareResponse.fromJson(res); - openPaymentDialog(appo, widget.patientShareResponse); + + isInsured = res["IsInsured"]; + isEligible = res["IsEligible"]; + isCash = res["IsCash"]; + + if (isCash) { + openPaymentDialog(appo, widget.patientShareResponse!); + } else { + if (isInsured && isEligible) { + openPaymentDialog(appo, widget.patientShareResponse!); + } else { + if (isInsured && !isEligible) { + errorMsg = TranslationBase.of(context).invalidEligibility; + } else { + errorMsg = TranslationBase.of(context).invalidInsurance; + } + ConfirmDialog dialog = new ConfirmDialog( + isDissmissable: false, + context: context, + confirmMessage: errorMsg, + okText: TranslationBase.of(context).updateInsuranceText, + cancelText: TranslationBase.of(context).continueCash, + okFunction: () => {openUpdateInsurance()}, + cancelFunction: () => {continueAsCash(appo, true)}); + dialog.showAlertDialog(context); + } + } + + // openPaymentDialog(appo, widget.patientShareResponse!); }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); AppToast.showErrorToast(message: err); @@ -676,7 +1127,7 @@ class _ToDoState extends State { } getAppoQR(context, AppoitmentAllHistoryResultList appo) { - GifLoaderDialogUtils.showMyDialog(context); + // GifLoaderDialogUtils.showMyDialog(context); PatientShareResponse patientShareResponse = new PatientShareResponse(); patientShareResponse.doctorNameObj = appo.doctorNameObj; @@ -688,136 +1139,247 @@ class _ToDoState extends State { patientShareResponse.projectID = appo.projectID; patientShareResponse.isFollowup = appo.isFollowup; + // FlutterNfcKit.nfcAvailability.then((value) { + // if (value == NFCAvailability.available) { + // PatientShareResponse patientShareResponse = new PatientShareResponse(); + patientShareResponse.doctorNameObj = appo.doctorNameObj; + patientShareResponse.doctorSpeciality = appo.doctorSpeciality; + patientShareResponse.projectName = appo.projectName; + patientShareResponse.appointmentDate = appo.appointmentDate; + patientShareResponse.appointmentNo = appo.appointmentNo; + patientShareResponse.clinicID = appo.clinicID; + patientShareResponse.projectID = appo.projectID; + patientShareResponse.isFollowup = appo.isFollowup; + navigateToQR(context, "", patientShareResponse, appo); + projectViewModel.analytics.todoList.to_do_list_check_in(appo); + // } else { + // Utils.showErrorToast(TranslationBase.of(context).NFCNotSupported); + // } + // }); + projectViewModel.analytics.todoList.to_do_list_check_in(appo); + DoctorsListService service = new DoctorsListService(); - service.generateAppointmentQR(patientShareResponse, context).then((res) { - GifLoaderDialogUtils.hideDialog(context); - print(res); - navigateToQR(context, res['AppointmentQR'], patientShareResponse); - }).catchError((err) { - GifLoaderDialogUtils.hideDialog(context); + service.generateAppointmentQR(patientShareResponse, context).then((res) {}).catchError((err) { print(err); }); } - Future navigateToQR( - context, String appoQR, PatientShareResponse patientShareResponse) async { - Navigator.push( - context, - FadePage( - page: QRCode( - patientShareResponse: patientShareResponse, - appoQR: appoQR, - ))).then((value) { + Future navigateToQR(context, String appoQR, PatientShareResponse patientShareResponse, AppoitmentAllHistoryResultList appintment) async { + Navigator.push(context, FadePage(page: QRCode(patientShareResponse: patientShareResponse, appoQR: appoQR, appointment: appintment))).then((value) { getPatientAppointmentHistory(); }); } - openPaymentDialog(AppoitmentAllHistoryResultList appo, - PatientShareResponse patientShareResponse) { + openPaymentDialog(AppoitmentAllHistoryResultList appo, PatientShareResponse patientShareResponse) { showGeneralDialog( - barrierColor: Colors.black.withOpacity(0.5), - transitionBuilder: (context, a1, a2, widget) { - final curvedValue = - Curves.easeInOutBack.transform(a1.value) - 1.0; - return Transform( - transform: - Matrix4.translationValues(0.0, curvedValue * 200, 0.0), - child: Opacity( - opacity: a1.value, - child: PaymentDialog( - appo: appo, patientShareResponse: patientShareResponse), - ), - ); - }, - transitionDuration: Duration(milliseconds: 500), - barrierDismissible: false, - barrierLabel: '', - context: context, - pageBuilder: (context, animation1, animation2) {}) - .then((value) { - print(value); - + barrierColor: Colors.black.withOpacity(0.5), + transitionBuilder: (context, a1, a2, widget) { + final curvedValue = Curves.easeInOutBack.transform(a1.value) - 1.0; + return Transform( + transform: Matrix4.translationValues(0.0, curvedValue * 200, 0.0), + child: Opacity( + opacity: a1.value, + child: PaymentDialog( + appo: appo, + patientShareResponse: patientShareResponse, + isCashPatient: isCash, + onPaymentMethodSelected: () {}, + ), + ), + ); + }, + transitionDuration: Duration(milliseconds: 500), + barrierDismissible: false, + barrierLabel: '', + context: context, + pageBuilder: (context, animation1, animation2) => SizedBox()).then((value) { if (value != null) { - navigateToPaymentMethod(context, value, appo); + navigateToPaymentMethod(context, value as PatientShareResponse, appo); + projectViewModel.analytics.todoList.to_do_list_confirm_payment_details(appo); + } else { + projectViewModel.analytics.todoList.to_do_list_cancel_payment_details(appo); } }); + projectViewModel.analytics.todoList.to_do_list_pay_now(appo); } - openPayment( - String paymentMethod, - AuthenticatedUser authenticatedUser, - double amount, - PatientShareResponse patientShareResponse, - AppoitmentAllHistoryResultList appo) { - widget.browser = new MyInAppBrowser( - onExitCallback: onBrowserExit, - appo: appo, - onLoadStartCallback: onBrowserLoadStart); - - widget.browser.openPaymentBrowser( + openPayment(List paymentMethod, AuthenticatedUser authenticatedUser, num amount, PatientShareResponse patientShareResponse, AppoitmentAllHistoryResultList appo) { + browser = new MyInAppBrowser(onExitCallback: onBrowserExit, appo: appo, onLoadStartCallback: onBrowserLoadStart, context: context); + transID = Utils.getAppointmentTransID(appo.projectID, appo.clinicID, appo.appointmentNo); + browser?.openPaymentBrowser( amount, "Appointment check in", - Utils.getAppointmentTransID( - appo.projectID, appo.clinicID, appo.appointmentNo), + transID!, appo.projectID.toString(), - authenticatedUser.emailAddress, - paymentMethod, + authenticatedUser.emailAddress!, + paymentMethod[0]!, authenticatedUser.patientType, - authenticatedUser.firstName, + authenticatedUser.firstName!, authenticatedUser.patientID, authenticatedUser, - widget.browser, - appo.isLiveCareAppointment, + browser!, + appo.isLiveCareAppointment ?? false, + "2", + appo.isLiveCareAppointment! ? widget.patientShareResponse!.clinicID.toString() : "", + context, appo.appointmentDate, appo.appointmentNo, appo.clinicID, - appo.doctorID); + appo.doctorID, + paymentMethod[1]); } onBrowserLoadStart(String url) { print("onBrowserLoadStart"); print(url); + if (selectedPaymentMethod == "TAMARA") { + if (Platform.isAndroid) { + Uri uri = new Uri.dataFromString(url); + tamaraPaymentStatus = uri.queryParameters['status']!; + tamaraOrderID = uri.queryParameters['AuthorizePaymentId']!; + } else { + Uri uri = new Uri.dataFromString(url); + tamaraPaymentStatus = uri.queryParameters['paymentStatus']!; + tamaraOrderID = uri.queryParameters['orderId']!; + } + } + + // if(selectedPaymentMethod != "TAMARA") { MyInAppBrowser.successURLS.forEach((element) { if (url.contains(element)) { - if (widget.browser.isOpened()) widget.browser.close(); + browser?.close(); MyInAppBrowser.isPaymentDone = true; return; } }); + // } + // if(selectedPaymentMethod != "TAMARA") { MyInAppBrowser.errorURLS.forEach((element) { if (url.contains(element)) { - if (widget.browser.isOpened()) widget.browser.close(); + browser?.close(); MyInAppBrowser.isPaymentDone = false; return; } }); + // } } onBrowserExit(AppoitmentAllHistoryResultList appo, bool isPaymentMade) { print("onBrowserExit Called!!!!"); - if (isPaymentMade) checkPaymentStatus(appo); + if (selectedPaymentMethod == "TAMARA") { + checkTamaraPaymentStatus(transID!, appo); + // if (tamaraPaymentStatus != null && tamaraPaymentStatus.toLowerCase() == "approved") { + // updateTamaraRequestStatus("success", "14", Utils.getAppointmentTransID(appo.projectID, appo.clinicID, appo.appointmentNo), tamaraOrderID, num.parse(selectedInstallments), appo); + // } else { + // updateTamaraRequestStatus("Failed", "00", Utils.getAppointmentTransID(appo.projectID, appo.clinicID, appo.appointmentNo), tamaraOrderID, num.parse(selectedInstallments), appo); + // } + } else { + checkPaymentStatus(appo); + } + } + + checkTamaraPaymentStatus(String orderID, AppoitmentAllHistoryResultList appo) { + GifLoaderDialogUtils.showMyDialog(context); + DoctorsListService service = new DoctorsListService(); + service.getTamaraPaymentStatus(orderID).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res["status"].toString().toLowerCase() == "success") { + updateTamaraRequestStatus("success", "14", orderID, res["tamara_order_id"], int.parse(selectedInstallments!), appo); + } else { + updateTamaraRequestStatus("Failed", "00", transID!, tamaraOrderID != null ? tamaraOrderID : "", int.parse(selectedInstallments), appo); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + + addAdvancedNumberRequestTamara(String advanceNumber, String paymentReference, String appointmentID, AppoitmentAllHistoryResultList appo) { + DoctorsListService service = new DoctorsListService(); + service.addAdvancedNumberRequest(advanceNumber, paymentReference, appointmentID, context).then((res) {}).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + + updateTamaraRequestStatus(String responseMessage, String status, String clientRequestID, String tamaraOrderID, int selectedInstallments, AppoitmentAllHistoryResultList appo) { + GifLoaderDialogUtils.showMyDialog(context); + try { + DoctorsListService service = new DoctorsListService(); + service.updateTamaraRequestStatus(responseMessage, status, clientRequestID, tamaraOrderID, selectedInstallments).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (tamaraPaymentStatus.toLowerCase() == "approved") { + markAppointmentForTamara(appo); + addAdvancedNumberRequestTamara("Tamara-Advance-0000", tamaraOrderID, appo.appointmentNo.toString(), appo); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + AppToast.showErrorToast(message: err); + }); + } catch (err) { + print(err); + } + } + + markAppointmentForTamara(AppoitmentAllHistoryResultList appo) { + GifLoaderDialogUtils.showMyDialog(context); + var apptData = { + "AppointmentNo": appo.appointmentNo.toString(), + "DoctorID": appo.doctorID.toString(), + "ServiceID": appo.serviceID.toString(), + "ProjectID": appo.projectID.toString(), + "ClinicID": appo.clinicID.toString(), + "AppointmentDate": appo.appointmentDate.toString(), + }; + DoctorsListService service = new DoctorsListService(); + service.markAppointmentForTamara(appo.projectID!, appo.appointmentNo.toString()).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (appo.isLiveCareAppointment!) + addVIDARequestInsert("0", tamaraOrderID, appo); + else + getAppoQR(context, appo); + }).catchError((err) { + print(err); + AppToast.showErrorToast(message: err); + GifLoaderDialogUtils.hideDialog(context); + }); } checkPaymentStatus(AppoitmentAllHistoryResultList appo) { + String txn_ref; + num? amount; + String? payment_method; + final currency = projectViewModel.user!.outSA == 0 ? "sar" : 'aed'; GifLoaderDialogUtils.showMyDialog(context); DoctorsListService service = new DoctorsListService(); - service - .checkPaymentStatus( - Utils.getAppointmentTransID( - appo.projectID, appo.clinicID, appo.appointmentNo), - context) - .then((res) { + service.checkPaymentStatus(transID!, false, context).then((res) { GifLoaderDialogUtils.hideDialog(context); String paymentInfo = res['Response_Message']; if (paymentInfo == 'Success') { + txn_ref = res['Merchant_Reference']; + amount = res['Amount']; + payment_method = res['PaymentMethod']; createAdvancePayment(res, appo); + projectViewModel.analytics.appointment.payment_success( + appointment_type: 'regular', payment_method: payment_method, clinic: appo.clinicName, hospital: appo.projectName, txn_amount: "$amount", txn_currency: currency, txn_number: txn_ref); } else { AppToast.showErrorToast(message: res['Response_Message']); + projectViewModel.analytics.appointment.payment_fail( + appointment_type: 'regular', + payment_method: payment_method!, + clinic: appo.clinicName, + hospital: appo.projectName, + txn_amount: "$amount!", + txn_currency: currency, + error_type: res['Response_Message']); } }).catchError((err) { - GifLoaderDialogUtils.hideDialog(context); + if (mounted) GifLoaderDialogUtils.hideDialog(context); print(err); }); } @@ -826,14 +1388,12 @@ class _ToDoState extends State { GifLoaderDialogUtils.showMyDialog(context); DoctorsListService service = new DoctorsListService(); String paymentReference = res['Fort_id'].toString(); - service - .createAdvancePayment(appo, appo.projectID.toString(), res['Amount'], - res['Fort_id'], res['PaymentMethod'], context) - .then((res) { + service.createAdvancePayment(appo, appo.projectID.toString(), res['Amount'], res['Fort_id'], res['PaymentMethod'], context).then((res) { GifLoaderDialogUtils.hideDialog(context); - print(res['OnlineCheckInAppointments'][0]); addAdvancedNumberRequest( - res['OnlineCheckInAppointments'][0]['AdvanceNumber'].toString(), + Utils.isVidaPlusProject(projectViewModel, appo.projectID!) + ? res['OnlineCheckInAppointments'][0]['AdvanceNumber_VP'].toString() + : res['OnlineCheckInAppointments'][0]['AdvanceNumber'].toString(), paymentReference, appo.appointmentNo.toString(), appo, @@ -844,21 +1404,13 @@ class _ToDoState extends State { }); } - addAdvancedNumberRequest( - String advanceNumber, - String paymentReference, - String appointmentID, - AppoitmentAllHistoryResultList appo, - dynamic apptData) { + addAdvancedNumberRequest(String advanceNumber, String paymentReference, String appointmentID, AppoitmentAllHistoryResultList appo, dynamic apptData) { GifLoaderDialogUtils.showMyDialog(context); DoctorsListService service = new DoctorsListService(); - service - .addAdvancedNumberRequest( - advanceNumber, paymentReference, appointmentID, context) - .then((res) { + service.addAdvancedNumberRequest(advanceNumber, paymentReference, appointmentID, context).then((res) { GifLoaderDialogUtils.hideDialog(context); - if (appo.isLiveCareAppointment) - addVIDARequestInsert(advanceNumber, paymentReference, apptData); + if (appo.isLiveCareAppointment!) + addVIDARequestInsert(advanceNumber, paymentReference, appo); else getAppoQR(context, appo); }).catchError((err) { @@ -867,78 +1419,153 @@ class _ToDoState extends State { }); } - addVIDARequestInsert( - String advanceNumber, String paymentReference, dynamic apptData) { + addVIDARequestInsert(String advanceNumber, String paymentReference, AppoitmentAllHistoryResultList appo) { GifLoaderDialogUtils.showMyDialog(context); DoctorsListService service = new DoctorsListService(); service - .addVIDARequest(advanceNumber, paymentReference, apptData, context) + .insertVIDARequest(appo.appointmentNo, appo.clinicID, appo.projectID, appo.serviceID, appo.doctorID, appo.appointmentDate!, transID!, projectViewModel.isArabic ? 1 : 2, context) .then((res) { GifLoaderDialogUtils.hideDialog(context); - print(res); + getPatientAppointmentHistory(); }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); print(err); }); } - getPatientData() async { - AppSharedPreferences sharedPref = AppSharedPreferences(); - if (await sharedPref.getObject(USER_PROFILE) != null) { - var data = - AuthenticatedUser.fromJson(await sharedPref.getObject(USER_PROFILE)); - setState(() { - print(data); - authUser = data; - }); - getPatientAppointmentHistory(); - } - } - - Future navigateToPaymentMethod( - context, - PatientShareResponse patientShareResponse, - AppoitmentAllHistoryResultList appo) async { - if (await this.sharedPref.getObject(USER_PROFILE) != null) { - var data = AuthenticatedUser.fromJson( - await this.sharedPref.getObject(USER_PROFILE)); - setState(() { - authUser = data; - }); - } - + Future navigateToPaymentMethod(context, PatientShareResponse patientShareResponse, AppoitmentAllHistoryResultList appo) async { Navigator.push( - context, FadePage(page: PaymentMethod())) + context, + FadePage( + page: PaymentMethod( + onSelectedMethod: (String metohd, [String? selectedInstallmentPlan]) { + setState(() {}); + }, + patientShare: widget.patientShareResponse!.patientShareWithTax))) .then((value) { print(value); + selectedPaymentMethod = value[0] ?? ""; + selectedInstallments = value[1] ?? ""; getPatientAppointmentHistory(); if (value != null) { - openPayment( - value, - authUser, - double.parse(patientShareResponse.patientShareWithTax.toString()), - patientShareResponse, - appo); + final appType = appo.isLiveCareAppointment! ? 'livecare' : 'regular'; + if (selectedPaymentMethod == "ApplePay") { + if (projectViewModel.havePrivilege(103)) { + startApplePay(appo, patientShareResponse); + } else { + openPayment(value, projectViewModel.user, double.parse(patientShareResponse.patientShareWithTax.toString()), patientShareResponse, appo); + } + } else { + openPayment(value, projectViewModel.user, double.parse(patientShareResponse.patientShareWithTax.toString()), patientShareResponse, appo); + } + projectViewModel.analytics.appointment.payment_method(appointment_type: appType, clinic: appo.clinicName, payment_method: value[0], payment_type: 'appointment'); } }); } + void startApplePay(AppoitmentAllHistoryResultList appo, PatientShareResponse patientShareResponse) async { + transID = Utils.getAppointmentTransID(appo.projectID, appo.clinicID, appo.appointmentNo); + print("TransactionID: $transID"); + GifLoaderDialogUtils.showMyDialog(context); + + LiveCareService service = new LiveCareService(); + ApplePayInsertRequest applePayInsertRequest = new ApplePayInsertRequest(); + + PayfortProjectDetailsRespModel? payfortProjectDetailsRespModel; + await context.read().getProjectDetailsForPayfort(projectId: appo.projectID, serviceId: ServiceTypeEnum.appointmentPayment.getIdFromServiceEnum()).then((value) { + payfortProjectDetailsRespModel = value; + }); + + applePayInsertRequest.clientRequestID = transID; + applePayInsertRequest.clinicID = appo.clinicID; + applePayInsertRequest.currency = projectViewModel.user.outSA == 1 ? "AED" : "SAR"; + // applePayInsertRequest.customerEmail = projectViewModel.authenticatedUserObject.user.emailAddress; + applePayInsertRequest.customerEmail = "CustID_${projectViewModel.user.patientID}@HMG.com"; + applePayInsertRequest.customerID = projectViewModel.user.patientID; + applePayInsertRequest.customerName = projectViewModel.user.firstName! + " " + projectViewModel.user.lastName!; + applePayInsertRequest.deviceToken = await AppSharedPreferences().getString(PUSH_TOKEN); + applePayInsertRequest.voipToken = await AppSharedPreferences().getString(ONESIGNAL_APNS_TOKEN); + applePayInsertRequest.doctorID = appo.doctorID; + applePayInsertRequest.projectID = appo.projectID.toString(); + applePayInsertRequest.serviceID = ServiceTypeEnum.appointmentPayment.getIdFromServiceEnum().toString(); + applePayInsertRequest.channelID = 3; + applePayInsertRequest.patientID = projectViewModel.user.patientID; + applePayInsertRequest.patientTypeID = projectViewModel.user.patientType; + applePayInsertRequest.patientOutSA = projectViewModel.user.outSA; + applePayInsertRequest.appointmentDate = appo.appointmentDate; + applePayInsertRequest.appointmentNo = appo.appointmentNo; + applePayInsertRequest.orderDescription = "Appointment Payment"; + applePayInsertRequest.liveServiceID = "0"; + applePayInsertRequest.latitude = "0.0"; + applePayInsertRequest.longitude = "0.0"; + applePayInsertRequest.amount = patientShareResponse.patientShareWithTax.toString(); + applePayInsertRequest.isSchedule = appo.isLiveCareAppointment! ? "1" : "0"; + applePayInsertRequest.language = projectViewModel.isArabic ? 'ar' : 'en'; + applePayInsertRequest.languageID = projectViewModel.isArabic ? 1 : 2; + applePayInsertRequest.userName = projectViewModel.user.patientID; + applePayInsertRequest.responseContinueURL = "http://hmg.com/Documents/success.html"; + applePayInsertRequest.backClickUrl = "http://hmg.com/Documents/success.html"; + applePayInsertRequest.paymentOption = "ApplePay"; + + applePayInsertRequest.isMobSDK = true; + applePayInsertRequest.merchantReference = transID; + applePayInsertRequest.merchantIdentifier = payfortProjectDetailsRespModel!.merchantIdentifier; + applePayInsertRequest.commandType = "PURCHASE"; + applePayInsertRequest.signature = payfortProjectDetailsRespModel!.signature; + applePayInsertRequest.accessCode = payfortProjectDetailsRespModel!.accessCode; + applePayInsertRequest.shaRequestPhrase = payfortProjectDetailsRespModel!.shaRequest; + applePayInsertRequest.shaResponsePhrase = payfortProjectDetailsRespModel!.shaResponse; + applePayInsertRequest.returnURL = ""; + + service.applePayInsertRequest(applePayInsertRequest, context).then((res) async { + if (res["MessageStatus"] == 1) { + await context.read().initiateApplePayWithPayfort( + customerName: projectViewModel.user.firstName! + " " + projectViewModel.user.lastName!, + // customerEmail: projectViewModel.authenticatedUserObject.user.emailAddress, + customerEmail: "CustID_${projectViewModel.user.patientID}@HMG.com", + orderDescription: "Appointment Payment", + orderAmount: double.parse(patientShareResponse.patientShareWithTax.toString()), + merchantReference: transID, + payfortProjectDetailsRespModel: payfortProjectDetailsRespModel, + currency: projectViewModel.user.outSA == 1 ? "AED" : "SAR", + onFailed: (failureResult) async { + GifLoaderDialogUtils.hideDialog(context); + log("failureResult: ${failureResult.message.toString()}"); + AppToast.showErrorToast(message: failureResult.message.toString()); + }, + onSuccess: (successResult) async { + log("Payfort: ${successResult.responseMessage}"); + await context.read().addPayfortApplePayResponse(projectViewModel.user.patientID!, result: successResult); + checkPaymentStatus(appo); + }, + projectId: appo.projectID, + serviceTypeEnum: ServiceTypeEnum.appointmentPayment, + ); + } else { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: "An error occurred while processing your request"); + } + }).catchError((err) { + print(err); + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err.toString()); + }); + } + confirmAppointment(AppoitmentAllHistoryResultList appo) { GifLoaderDialogUtils.showMyDialog(context); DoctorsListService service = new DoctorsListService(); - service - .confirmAppointment(appo.appointmentNo, appo.clinicID, appo.projectID, - appo.isLiveCareAppointment, context) - .then((res) { + service.confirmAppointment(appo.appointmentNo!, appo.clinicID!, appo.projectID!, appo.isLiveCareAppointment!, context).then((res) { GifLoaderDialogUtils.hideDialog(context); if (res['MessageStatus'] == 1) { AppToast.showSuccessToast(message: res['ErrorEndUserMessage']); - if (appo.isLiveCareAppointment) { + if (appo.isLiveCareAppointment!) { insertLiveCareVIDARequest(appo); } else { getPatientAppointmentHistory(); } + projectViewModel.analytics.todoList.to_do_list_confirm_appointment(appo); } else { AppToast.showErrorToast(message: res['ErrorEndUserMessage']); } @@ -952,8 +1579,8 @@ class _ToDoState extends State { GifLoaderDialogUtils.showMyDialog(context); DoctorsListService service = new DoctorsListService(); service - .insertVIDARequest(appo.appointmentNo, appo.clinicID, appo.projectID, - appo.serviceID, appo.doctorID, context) + .insertVIDARequest(appo.appointmentNo, appo.clinicID, appo.projectID, appo.serviceID, appo.doctorID, appo.appointmentDate!, + Utils.getAppointmentTransID(appo.projectID, appo.clinicID, appo.appointmentNo), projectViewModel.isArabic ? 1 : 2, context) .then((res) { GifLoaderDialogUtils.hideDialog(context); if (res['MessageStatus'] == 1) { @@ -967,4 +1594,13 @@ class _ToDoState extends State { GifLoaderDialogUtils.hideDialog(context); }); } + + ancillaryOrdersDetails(item, projectId) { + Navigator.push( + context, + FadePage( + page: AnicllaryOrdersDetails(item.appointmentNo, item.orderNo, projectId), + ), + ); + } } diff --git a/lib/pages/ToDoList/payment_method_select.dart b/lib/pages/ToDoList/payment_method_select.dart index 9a22eada..5adcb90f 100644 --- a/lib/pages/ToDoList/payment_method_select.dart +++ b/lib/pages/ToDoList/payment_method_select.dart @@ -1,207 +1,374 @@ +import 'dart:async'; +import 'dart:io'; + +import 'package:diplomaticquarterapp/core/model/my_balance/tamara_installment_details.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.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'; +import 'package:diplomaticquarterapp/widgets/buttons/custom_text_button.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:provider/provider.dart'; class PaymentMethod extends StatefulWidget { + Function onSelectedMethod; + bool? isShowInstallments; + num? patientShare; + bool? isFromAdvancePayment; + + PaymentMethod({required this.onSelectedMethod, this.isShowInstallments = false, this.patientShare, this.isFromAdvancePayment = false}); + @override _PaymentMethodState createState() => _PaymentMethodState(); } class _PaymentMethodState extends State { String selectedPaymentMethod = "MADA"; + TamaraInstallmentDetails? tamaraInstallmentDetails; + String? selectedInstallmentPlan; + + num minTamaraLimit = 0; + num maxTamaraLimit = 0; + + ProjectViewModel? projectViewModel; + + @override + void initState() { + WidgetsBinding.instance.addPostFrameCallback((_) { + getTamaraPaymentDetails(); + }); + super.initState(); + } @override Widget build(BuildContext context) { + projectViewModel = Provider.of(context); return AppScaffold( appBarTitle: TranslationBase.of(context).paymentMethod, isShowAppBar: true, + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: CustomColors.appBackgroudGrey2Color, body: Container( margin: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0), child: SingleChildScrollView( child: Container( child: Column( mainAxisSize: MainAxisSize.max, - crossAxisAlignment: CrossAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( - margin: EdgeInsets.fromLTRB(0.0, 15.0, 0.0, 0.0), - alignment: Alignment.center, - child: Text(TranslationBase.of(context).selectPaymentOption, - style: TextStyle( - fontSize: 26.0, fontWeight: FontWeight.bold)), + margin: EdgeInsets.fromLTRB(4, 15.0, 4, 0.0), + child: Text(TranslationBase.of(context).selectPaymentOption, style: TextStyle(fontSize: 18.0, fontWeight: FontWeight.bold)), ), - Container( - margin: EdgeInsets.only(top: 25.0), - child: Flex( - direction: Axis.horizontal, - children: [ - Expanded( - child: Container( - child: InkWell( - onTap: () { - updateSelectedPaymentMethod("MADA"); - }, - 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 == "MADA" - ? BorderSide( - color: Colors.green, width: 5.0) - : BorderSide( - color: Colors.transparent, width: 0.0), + if (projectViewModel!.havePrivilege(86)) + Container( + width: double.infinity, + child: InkWell( + onTap: () { + updateSelectedPaymentMethod("MADA"); + }, + 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: selectedPaymentMethod == "MADA" ? 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(selectedPaymentMethod == "MADA" ? CustomColors.accentColor : Colors.transparent, 100, Colors.grey, 0.5), ), - child: Container( - height: 120.0, + mWidth(12), + Container( + height: 70.0, + width: 70.0, padding: EdgeInsets.all(7.0), - width: MediaQuery.of(context).size.width * 0.45, - child: Image.asset( - "assets/images/new-design/mada.png"), + child: Image.asset("assets/images/new/payment/Mada.png"), ), - ), + mFlex(1), + if (selectedPaymentMethod == "MADA") + 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, + ), + ), + ), + ], ), ), ), - Expanded( - child: Container( - child: InkWell( - onTap: () { - updateSelectedPaymentMethod("VISA"); - }, - 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 == "VISA" - ? BorderSide( - color: Colors.green, width: 5.0) - : BorderSide( - color: Colors.transparent, width: 0.0), + ), + ), + if (projectViewModel!.havePrivilege(87)) + Container( + width: double.infinity, + child: InkWell( + onTap: () { + updateSelectedPaymentMethod("VISA"); + }, + 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: selectedPaymentMethod == "VISA" ? 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(selectedPaymentMethod == "VISA" ? CustomColors.accentColor : Colors.transparent, 100, Colors.grey, 0.5), ), - child: Container( - height: 120.0, + mWidth(12), + Container( + height: 60.0, padding: EdgeInsets.all(7.0), - width: MediaQuery.of(context).size.width * 0.45, - child: Image.asset( - "assets/images/new-design/visa.png"), + width: 60, + child: Image.asset("assets/images/new/payment/visa.png"), ), - ), + mFlex(1), + if (selectedPaymentMethod == "VISA") + 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.only(top: 25.0), - child: Flex( - direction: Axis.horizontal, - children: [ - Expanded( - child: Container( - child: InkWell( - onTap: () { - updateSelectedPaymentMethod("MASTERCARD"); - }, - 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 == "MASTERCARD" - ? BorderSide( - color: Colors.green, width: 5.0) - : BorderSide( - color: Colors.transparent, width: 0.0), + if (projectViewModel!.havePrivilege(88)) + Container( + width: double.infinity, + child: InkWell( + onTap: () { + updateSelectedPaymentMethod("MASTERCARD"); + }, + 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: selectedPaymentMethod == "MASTERCARD" ? 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(selectedPaymentMethod == "MASTERCARD" ? CustomColors.accentColor : Colors.transparent, 100, Colors.grey, 0.5), ), - child: Container( - height: 120.0, + mWidth(12), + Container( + height: 60.0, padding: EdgeInsets.all(7.0), - width: MediaQuery.of(context).size.width * 0.45, - child: Image.asset( - "assets/images/new-design/mastercard.png"), + width: 60, + child: Image.asset("assets/images/new/payment/Mastercard.png"), ), - ), + mFlex(1), + if (selectedPaymentMethod == "MASTERCARD") + 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, + ), + ), + ), + ], ), ), ), - Expanded( - child: Container( - child: InkWell( - onTap: () { - updateSelectedPaymentMethod("Installment"); - }, - 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 == "Installment" - ? BorderSide( - color: Colors.green, width: 5.0) - : BorderSide( - color: Colors.transparent, width: 0.0), + ), + ), + if (projectViewModel!.havePrivilege(90) && !widget.isFromAdvancePayment! && widget.patientShare! >= minTamaraLimit && widget.patientShare! <= maxTamaraLimit) + Container( + width: double.infinity, + child: InkWell( + onTap: () { + updateSelectedPaymentMethod("TAMARA"); + }, + 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: selectedPaymentMethod == "TAMARA" ? 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(selectedPaymentMethod == "TAMARA" ? CustomColors.accentColor : Colors.transparent, 100, Colors.grey, 0.5), ), - child: Container( - height: 120.0, - padding: EdgeInsets.all(7.0), - width: MediaQuery.of(context).size.width * 0.45, - child: Image.asset( - "assets/images/new-design/installment.png"), + mWidth(12), + Container( + height: 60.0, + padding: EdgeInsets.all(0.0), + width: 60, + child: projectViewModel!.isArabic ? Image.asset("assets/images/new/payment/tamara_ar.png") : Image.asset("assets/images/new/payment/tamara_en.png"), ), - ), + mFlex(1), + if (selectedPaymentMethod == "TAMARA") + 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.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), + if (widget.isShowInstallments! && projectViewModel!.havePrivilege(91)) + Container( + width: double.infinity, + child: InkWell( + onTap: () { + updateSelectedPaymentMethod("Installment"); + }, + 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: selectedPaymentMethod == "Installment" ? 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(selectedPaymentMethod == "Installment" ? CustomColors.accentColor : Colors.transparent, 100, Colors.grey, 0.5), ), - child: Container( - height: 120.0, - padding: EdgeInsets.all(20.0), - child: SvgPicture.asset( - "assets/images/new-design/applepay.svg"), + mWidth(12), + Container( + height: 60.0, + padding: EdgeInsets.all(7.0), + width: 90, + // child: Image.asset("assets/images/new/payment/installments.png"), + child: SvgPicture.asset("assets/images/new/payment/instalmt.svg"), ), - ), + mFlex(1), + if (selectedPaymentMethod == "Installment") + 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, + ), + ), + ), + ], ), ), ), - Expanded( - child: Container(), - ), - ], + ), ), - ), + (Platform.isIOS && projectViewModel!.havePrivilege(89)) + ? Container( + width: double.infinity, + child: InkWell( + onTap: () { + updateSelectedPaymentMethod("ApplePay"); + }, + 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: selectedPaymentMethod == "ApplePay" ? 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(selectedPaymentMethod == "ApplePay" ? CustomColors.accentColor : Colors.transparent, 100, Colors.grey, 0.5), + ), + mWidth(12), + Container( + height: 60.0, + padding: EdgeInsets.all(7.0), + width: 60, + child: SvgPicture.asset( + "assets/images/new/payment/Apple_Pay.svg", + ), + ), + mFlex(1), + if (selectedPaymentMethod == "ApplePay") + 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(), SizedBox( height: 150.0, ), @@ -211,27 +378,130 @@ class _PaymentMethodState extends State { ), ), bottomSheet: Container( - width: MediaQuery.of(context).size.width, - height: 50.0, - margin: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 20.0), - child: ButtonTheme( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10.0), - ), - minWidth: MediaQuery.of(context).size.height * 0.1, - height: 45.0, - child: RaisedButton( - color: new Color(0xFF60686b), - textColor: Colors.white, - disabledTextColor: Colors.white, - disabledColor: new Color(0xFFbcc2c4), - onPressed: () { - Navigator.pop(context, selectedPaymentMethod); - }, - child: Text(TranslationBase.of(context).confirm, - style: TextStyle(fontSize: 18.0)), - ), - ), + padding: EdgeInsets.all(16), + color: Colors.white, + child: selectedPaymentMethod == "TAMARA" + ? Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text(TranslationBase.of(context).selectTamaraPlan, style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold)), + Container( + height: 60.0, + padding: EdgeInsets.all(0.0), + width: 60, + child: SvgPicture.asset("assets/images/new/payment/tamara.svg"), + ), + ], + ), + ), + if (tamaraInstallmentDetails != null) + Column( + children: [ + ...List.generate( + tamaraInstallmentDetails!.supportedInstalments!.length, + (index) => Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: 1, + ), + Row( + children: [ + Expanded( + flex: 1, + child: InkWell( + onTap: () { + setState(() { + selectedInstallmentPlan = tamaraInstallmentDetails!.supportedInstalments![index].instalments.toString(); + // getPaymentInfo(context, widget.projectID.toString(), widget.selectedProcedure.procedureID); + }); + }, + child: Row( + children: [ + Radio( + value: tamaraInstallmentDetails!.supportedInstalments![index].instalments.toString(), + groupValue: selectedInstallmentPlan, + activeColor: Colors.red[800], + toggleable: true, + onChanged: (value) { + setState(() { + selectedInstallmentPlan = value; + print(selectedInstallmentPlan); + }); + }, + ), + Text( + tamaraInstallmentDetails!.supportedInstalments![index].instalments.toString() + " " + TranslationBase.of(context).installments, + style: TextStyle( + fontSize: 12.0, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + ), + ), + ], + ), + ), + ) + ], + ), + ], + ), + ), + Container( + width: MediaQuery.of(context).size.width, + height: 50.0, + color: Colors.white, + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + minWidth: MediaQuery.of(context).size.height * 0.1, + height: 45.0, + child: CustomTextButton( + backgroundColor: CustomColors.green, + disabledForegroundColor: Color(0xFFbcc2c4).withOpacity(0.38), + disabledBackgroundColor: Color(0xFFbcc2c4).withOpacity(0.12), + elevation: 0, + onPressed: () { + widget.onSelectedMethod!(selectedPaymentMethod, selectedInstallmentPlan); + Navigator.pop(context, [selectedPaymentMethod, selectedInstallmentPlan]); + }, + child: Text(TranslationBase.of(context).confirm.toUpperCase(), style: TextStyle(fontSize: 14.0, fontWeight: FontWeight.w600, color: Colors.white)), + ), + ), + ), + ], + ), + ], + ) + : Container( + width: MediaQuery.of(context).size.width, + height: 50.0, + color: Colors.white, + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + minWidth: MediaQuery.of(context).size.height * 0.1, + height: 45.0, + child: CustomTextButton( + backgroundColor: CustomColors.green, + disabledForegroundColor: Color(0xFFbcc2c4).withOpacity(0.38), + disabledBackgroundColor: Color(0xFFbcc2c4).withOpacity(0.12), + elevation: 0, + onPressed: () { + widget.onSelectedMethod!(selectedPaymentMethod, selectedInstallmentPlan); + Navigator.pop(context, [selectedPaymentMethod, selectedInstallmentPlan]); + }, + child: Text(TranslationBase.of(context).confirm.toUpperCase(), style: TextStyle(fontSize: 14.0, fontWeight: FontWeight.w600, color: Colors.white)), + ), + ), + ), ), ); } @@ -240,5 +510,24 @@ class _PaymentMethodState extends State { setState(() { selectedPaymentMethod = selectedMethod; }); + // if (selectedMethod == "TAMARA") { + // getTamaraPaymentDetails(); + // } + } + + getTamaraPaymentDetails() { + GifLoaderDialogUtils.showMyDialog(context); + DoctorsListService service = new DoctorsListService(); + service.getTamaraPaymentDetails(context).then((Map res) { + tamaraInstallmentDetails = TamaraInstallmentDetails.fromJson(res); + minTamaraLimit = tamaraInstallmentDetails!.supportedInstalments![0].minLimit!.amount!; + maxTamaraLimit = tamaraInstallmentDetails!.supportedInstalments![0].maxLimit!.amount!; + selectedInstallmentPlan = tamaraInstallmentDetails!.supportedInstalments![0].instalments.toString(); + GifLoaderDialogUtils.hideDialog(context); + setState(() {}); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); } } diff --git a/lib/pages/ToDoList/widgets/paymentDialog.dart b/lib/pages/ToDoList/widgets/paymentDialog.dart index 7c461815..0f05dab0 100644 --- a/lib/pages/ToDoList/widgets/paymentDialog.dart +++ b/lib/pages/ToDoList/widgets/paymentDialog.dart @@ -1,16 +1,26 @@ +import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/locator.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; import 'package:diplomaticquarterapp/models/Appointments/PatientShareResposne.dart'; +import 'package:diplomaticquarterapp/pages/insurance/insurance_update_screen.dart'; +import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; +import 'package:diplomaticquarterapp/theme/colors.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/defaultButton.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; class PaymentDialog extends StatefulWidget { - AppoitmentAllHistoryResultList appo; - PatientShareResponse patientShareResponse; + bool isCashPatient = false; + late AppoitmentAllHistoryResultList appo; + late PatientShareResponse? patientShareResponse; - final Function onPaymentMethodSelected; + late final Function onPaymentMethodSelected; - PaymentDialog({@required this.appo, @required this.onPaymentMethodSelected, this.patientShareResponse}); + PaymentDialog({required this.appo, required this.onPaymentMethodSelected, this.patientShareResponse, this.isCashPatient = false}); @override _PaymentDialogState createState() => _PaymentDialogState(); @@ -19,162 +29,120 @@ class PaymentDialog extends StatefulWidget { class _PaymentDialogState extends State { @override Widget build(BuildContext context) { - return Container( - child: Dialog( - shape: - RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.0)), - child: Container( - height: 550.0, - width: 450.0, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.max, + return Dialog( + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.0)), + child: Container( + //height: 550.0, + width: 450.0, + padding: EdgeInsets.all(21), + child: Column(crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ + Text( + TranslationBase.of(context).invoiceDetails, + style: TextStyle( + fontSize: 24.0, + fontWeight: FontWeight.w600, + letterSpacing: -1.14, + color: Color(0xff2B353E), + ), + ), + Text(widget.appo.doctorTitle! + " " + widget.appo.doctorNameObj!, style: TextStyle(color: Color(0xff2E303A), fontSize: 16.0, fontWeight: FontWeight.w600, letterSpacing: -0.64)), + Text(getDate(widget.appo.appointmentDate!), style: getTextStyle()), + Text(widget.appo.projectName!, style: getTextStyle()), + Divider( + color: Colors.grey, + ), + Table( + children: [ + TableRow(decoration: BoxDecoration(), children: [ + TableCell(child: _getNormalText(TranslationBase.of(context).patientShareToDo)), + TableCell(child: _getNormalText(widget.patientShareResponse!.patientShare!.toString())), + ]), + TableRow(children: [ + TableCell(child: _getNormalText(TranslationBase.of(context).patientTaxToDo)), + TableCell(child: _getNormalText(widget.patientShareResponse!.patientTaxAmount!.toString())), + ]), + TableRow(children: [ + TableCell(child: _getNormalText(TranslationBase.of(context).patientShareTotalToDo)), + TableCell(child: _getNormalText(widget.patientShareResponse!.patientShareWithTax!.toString())), + ]), + ], + ), + Divider(color: Colors.grey), + Text( + TranslationBase.of(context).YouCanPayByTheFollowingOptions, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2E303A), + ), + ), + getPaymentMethods(), + SizedBox(height: 12), + Text( + TranslationBase.of(context).appoPaymentConfirm, + style: TextStyle(fontSize: 14.0, color: CustomColors.accentColor, fontWeight: FontWeight.w600, letterSpacing: -0.56), + ), + SizedBox(height: 12), + Container( + alignment: Alignment.center, + child: Row( + // direction: Axis.horizontal, children: [ - Container( - margin: EdgeInsets.fromLTRB(20.0, 20.0, 20.0, 5.0), - child: Text("Invoice Detail", - style: TextStyle( - fontSize: 25.0, - fontWeight: FontWeight.bold, - fontFamily: "Open-Sans-Bold")), - ), - Divider( - color: Colors.grey, - ), - Container( - margin: EdgeInsets.fromLTRB(20.0, 5.0, 20.0, 5.0), - child: Text("Appointment Details", - style: TextStyle( - fontSize: 15.0, - fontWeight: FontWeight.bold, - fontFamily: "Open-Sans-Bold")), - ), - Container( - margin: EdgeInsets.fromLTRB(20.0, 5.0, 20.0, 5.0), - child: Text( - widget.appo.doctorTitle + " " + widget.appo.doctorNameObj, - style: TextStyle( - color: Colors.grey[700], - fontSize: 15.0, - fontWeight: FontWeight.bold, - fontFamily: "Open-Sans-Bold")), - ), - Container( - margin: EdgeInsets.fromLTRB(20.0, 5.0, 20.0, 5.0), - child: Text(getDate(widget.appo.appointmentDate), - style: getTextStyle()), - ), - Container( - margin: EdgeInsets.fromLTRB(20.0, 5.0, 20.0, 5.0), - child: Text(widget.appo.projectName, style: getTextStyle()), - ), - Divider( - color: Colors.grey, - ), - Container( - margin: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 5.0), - child: Table( - children: [ - TableRow(children: [ - TableCell( - child: _getNormalText( - TranslationBase.of(context).patientShareToDo)), - TableCell( - child: _getNormalText(widget - .patientShareResponse.patientShare - .toString())), - ]), - TableRow(children: [ - TableCell( - child: _getNormalText( - TranslationBase.of(context).patientTaxToDo)), - TableCell( - child: _getNormalText(widget - .patientShareResponse.patientTaxAmount - .toString())), - ]), - TableRow(children: [ - TableCell( - child: _getNormalText(TranslationBase.of(context) - .patientShareTotalToDo)), - TableCell( - child: _getNormalText(widget - .patientShareResponse.patientShareWithTax - .toString())), - ]), - ], + Expanded( + child: DefaultButton( + TranslationBase.of(context).cancel_nocaps, + () { + Navigator.pop(context, null); + }, + color: CustomColors.accentColor, + textColor: Colors.white, ), ), - Container( - alignment: Alignment.center, - margin: EdgeInsets.fromLTRB(20.0, 20.0, 20.0, 5.0), - child: Text("You can pay by following options: ", - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.bold, - fontFamily: "Open-Sans")), - ), - Container( - alignment: Alignment.center, - margin: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 5.0), - child: Image.asset( - "assets/images/new-design/payment_options_invoice_confirmation.png", - width: 300), + mWidth(10.0), + Expanded( + child: DefaultButton( + TranslationBase.of(context).confirm, + () { + Navigator.pop(context, widget.patientShareResponse); + }, + color: CustomColors.green, + textColor: Colors.white, + ), ), - Container( - alignment: Alignment.center, - margin: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 15.0), - child: Text( - "Are You Sure You Want To Make payment for this Appointment?", - textAlign: TextAlign.center, + ], + ), + ), + widget.isCashPatient + ? Column( + children: [ + mHeight(10.0), + Text( + TranslationBase.of(context).cashAmountUpdateInsurance, style: TextStyle( - fontSize: 14.0, - color: Colors.red[700], - fontFamily: "Open-Sans")), - ), - Divider( - color: Colors.grey, - ), - Container( - alignment: Alignment.center, - height: 40.0, - child: Flex( - direction: Axis.horizontal, - children: [ - Expanded( - child: InkWell( - onTap: () { - Navigator.pop(context, null); - }, - child: Container( - child: Text("Cancel", - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 18.0, color: Colors.red[700])), - ), - ), - ), - Expanded( - child: InkWell( - onTap: () { - Navigator.pop(context, widget.patientShareResponse); -// widget.onPaymentMethodSelected(); - }, - child: Container( - child: Text("Ok", - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 18.0, - )), - ), - ), + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2E303A), ), - ], - ), - ), - ]), - ), + ), + mHeight(5.0), + DefaultButton( + TranslationBase.of(context).updateInsuranceText, + () { + Navigator.pop(context, null); + Navigator.pushAndRemoveUntil( + context, + MaterialPageRoute(builder: (context) => LandingPage()), + (Route route) => false, + ); + Navigator.push(context, FadePage(page: InsuranceUpdate())); + }, + color: Color(0xffEAA118), + textColor: Colors.white, + ), + ], + ) + : Container(), + ]), ), ); } @@ -182,39 +150,17 @@ class _PaymentDialogState extends State { _getNormalText(text) { return Container( margin: EdgeInsets.only(top: 10.0, right: 10.0), - child: Text(text, - textAlign: TextAlign.end, - style: TextStyle( - fontSize: 15, - fontFamily: 'Open-Sans', - letterSpacing: 0.5, - color: Colors.grey[700])), + child: Text(text, style: TextStyle(fontSize: 13, letterSpacing: 0.5, color: Color(0xff2E303A))), ); } TextStyle getTextStyle() { - return TextStyle( - color: Colors.grey[700], fontSize: 15.0, fontFamily: "Open-Sans-Bold"); + return TextStyle(color: Color(0xff575757), fontSize: 13.0, fontWeight: FontWeight.w600); } -// Future navigateToPaymentMethod(context) async { -// Navigator.push( -// context, MaterialPageRoute(builder: (context) => PaymentMethod())); -// } - String getDate(String date) { DateTime dateObj = DateUtil.convertStringToDate(date); - return DateUtil.getWeekDay(dateObj.weekday) + - ", " + - dateObj.day.toString() + - " " + - DateUtil.getMonth(dateObj.month) + - " " + - dateObj.year.toString() + - " " + - dateObj.hour.toString() + - ":" + - getMinute(dateObj); + return DateUtil.getDayMonthYearDateFormatted(dateObj) + " " + dateObj.hour.toString() + ":" + getMinute(dateObj); } String getMinute(DateTime dateObj) { diff --git a/lib/pages/ToDoList/widgets/upcomingCard.dart b/lib/pages/ToDoList/widgets/upcomingCard.dart index 6610ed33..fa3e4a39 100644 --- a/lib/pages/ToDoList/widgets/upcomingCard.dart +++ b/lib/pages/ToDoList/widgets/upcomingCard.dart @@ -1,20 +1,17 @@ -import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; -import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; -import 'package:diplomaticquarterapp/pages/MyAppointments/AppointmentDetails.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; -import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/avatar/large_avatar.dart'; +import 'package:diplomaticquarterapp/widgets/my_rich_text.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_rating_bar/flutter_rating_bar.dart'; import 'package:flutter_svg/flutter_svg.dart'; -import 'package:rating_bar/rating_bar.dart'; +import 'package:provider/provider.dart'; class TodoListCard extends StatefulWidget { - AppoitmentAllHistoryResultList appo; - var languageID; - final VoidCallback onListUpdated; - - TodoListCard({@required this.appo, this.onListUpdated}); + TodoListCard(); @override _TodoListCardState createState() => _TodoListCardState(); @@ -25,333 +22,147 @@ class _TodoListCardState extends State { @override void initState() { -// widget.onListUpdated(); super.initState(); } @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); return Container( + width: double.infinity, 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), - ), - child: Container( - width: MediaQuery.of(context).size.width, - padding: EdgeInsets.all(10.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - children: [ + decoration: cardRadius(12), + padding: EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ Row( - children: [ - Image.asset("assets/images/new-design/time_icon.png", - width: 20.0, height: 20.0), - Container( - margin: EdgeInsets.only(left: 10.0, right: 30.0), - child: Text(getDate(widget.appo.appointmentDate), - style: TextStyle(fontSize: 12.0)), + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(top: 4.0), + child: SvgPicture.asset("assets/images/new/virtual.svg"), ), - widget.appo.isLiveCareAppointment - ? SvgPicture.asset( - "assets/images/new-design/liveCare_logo_icon.svg", - width: 20.0, - height: 20.0) - : Image.asset( - "assets/images/new-design/hospital_address_icon.png", - width: 20.0, - height: 20.0), - Container( - margin: EdgeInsets.only(left: 10.0, right: 10.0), - child: widget.appo.isLiveCareAppointment - ? Text(TranslationBase.of(context).upcomingLivecare, - style: TextStyle(fontSize: 12.0)) - : Text(widget.appo.projectName, - style: TextStyle(fontSize: 12.0)), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(left: 8.0, right: 8.0), + child: Text(TranslationBase.of(context).videoAppo, style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.48)), + ), + Padding( + padding: const EdgeInsets.only(left: 8.0, right: 8.0), + child: Text("01:23:22 " + TranslationBase.of(context).upcomingTimeLeft, style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: CustomColors.accentColor, letterSpacing: -0.48)), + ), + ], ), ], ), Container( - margin: EdgeInsets.only(top: 5.0), - child: Divider( - color: Colors.grey[500], - ), - ), - Flex( - direction: Axis.horizontal, - children: [ - Expanded( - flex: 1, - child: Container( - height: MediaQuery.of(context).size.height * 0.1, - margin: EdgeInsets.only(top: 5.0), - child: ClipRRect( - borderRadius: BorderRadius.circular(100.0), - child: Image.network(widget.appo.doctorImageURL, - fit: BoxFit.fill), - ), + child: InkWell( + onTap: () { + // showConfirmMessage(model, order); + }, + child: Container( + padding: EdgeInsets.symmetric(vertical: 8, horizontal: 14), + decoration: BoxDecoration( + color: CustomColors.green, + border: Border.all(color: Colors.white, width: 1), + borderRadius: BorderRadius.circular(6), ), - ), - Expanded( - flex: 3, - child: Container( - margin: - EdgeInsets.only(top: 20.0, left: 20.0, right: 20.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - widget.appo.doctorTitle + - " " + - widget.appo.doctorNameObj, - style: TextStyle( - fontSize: 14.0, - color: Colors.black, - fontWeight: FontWeight.bold, - letterSpacing: 1.0)), - Container( - margin: EdgeInsets.only(top: 3.0, bottom: 3.0), - child: Text( - getDoctorSpeciality( - widget.appo.doctorSpeciality) - .trim(), - style: TextStyle( - fontSize: 12.0, - color: Colors.grey[600], - letterSpacing: 1.0)), - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - mainAxisSize: MainAxisSize.max, - children: [ - RatingBar.readOnly( - initialRating: 4.0, - size: 20.0, - filledColor: Colors.yellow[700], - emptyColor: Colors.grey[500], - isHalfAllowed: true, - halfFilledIcon: Icons.star_half, - filledIcon: Icons.star, - emptyIcon: Icons.star, - ), - ], - ), - ], - ), + child: Text( + TranslationBase.of(context).confirm, + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Colors.white, letterSpacing: -0.4), ), ), - Expanded( - flex: 1, - child: Container( - margin: EdgeInsets.only(top: 20.0), - child: Column( - children: [ - Image.asset( - getNextActionImage(widget.appo.nextAction), - width: 50.0, - height: 50.0), - Container( - margin: EdgeInsets.only(top: 5.0), - child: Text( - getNextActionText(widget.appo.nextAction), - textAlign: TextAlign.center, - style: TextStyle(fontSize: 12.0)), - ) - ], - ), - ), - ) - ], + ), ), - Divider( - color: Colors.grey[500], + ], + ), + Padding( + padding: const EdgeInsets.only(top: 8.0), + child: Text( + "Raed Mubarak Bin Ghanem", + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.64, height: 25 / 16), + ), + ), + Row( + mainAxisSize: MainAxisSize.min, + children: [ + LargeAvatar( + name: "Raed Mubarak Bin Ghanem", + url: "https://hmgwebservices.com/Images/MobileImages/TAKHSUSI/158210.png", + width: 52, + height: 52, ), - Flex( - direction: Axis.horizontal, - children: [ - Expanded( - flex: 2, - child: Container( - child: Text( - getNextActionDescription(widget.appo.nextAction), - style: TextStyle( - fontSize: 12.0, color: Colors.grey[700])), - ), - ), - Expanded( - flex: 1, - child: GestureDetector( - onTap: () { - navigateToAppointmentDetails(context); - }, - child: Container( - child: Text(TranslationBase.of(context).upcomingDetails, - textAlign: TextAlign.end, - style: TextStyle( - fontSize: 12.0, - color: new Color(0xFF40ACC9), - decoration: TextDecoration.underline)), - ), + SizedBox(width: 11), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + MyRichText(TranslationBase.of(context).clinic + ": ", "Cardiology", projectViewModel.isArabic), + MyRichText(TranslationBase.of(context).appointmentDate + ": ", "11/04/2021 15:30", projectViewModel.isArabic), + MyRichText(TranslationBase.of(context).branch, "Olaya Hospital", projectViewModel.isArabic), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + mainAxisSize: MainAxisSize.max, + children: [ + RatingBar( + initialRating: 4.6, + direction: Axis.horizontal, + allowHalfRating: true, + itemCount: 5, + itemSize: 20, + ignoreGestures: true, + ratingWidget: RatingWidget( + full: Icon(Icons.star, color: CustomColors.accentColor,), + half: Icon(Icons.star_half, color: CustomColors.accentColor,), + empty: Icon(Icons.star, color: CustomColors.accentColor,), + ), + tapOnlyMode: true, + unratedColor: Colors.grey[500], + itemPadding: EdgeInsets.symmetric(horizontal: 4.0), + onRatingUpdate: (rating) { + print(rating); + }, + ) + // RatingBar.readOnly( + // initialRating: 4.5, + // size: 16.0, + // filledColor: Color(0XFFD02127), + // emptyColor: Color(0XFFD02127), + // isHalfAllowed: true, + // halfFilledIcon: Icons.star_half, + // filledIcon: Icons.star, + // emptyIcon: Icons.star_border, + // ), + ], ), - ) - ], + ], + ), ), ], ), - ), + Padding( + padding: const EdgeInsets.only(top: 12.0), + child: Text( + "Please confirm the appointment to avoid cancellation", + style: TextStyle(fontSize: 10, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.48, height: 25 / 16), + ), + ), + Padding( + padding: const EdgeInsets.only(top: 0.0), + child: Text( + "More Details", + style: TextStyle(fontSize: 10, fontWeight: FontWeight.w600, color: CustomColors.accentColor, letterSpacing: -0.48, height: 25 / 16, decoration: TextDecoration.underline), + ), + ), + ], ), ); } - - String getNextActionImage(nextAction) { - switch (nextAction) { - case 0: - return "No Action"; - break; - case 10: - return "assets/images/new-design/confirm_button.png"; - break; - - case 15: - return widget.languageID == 'ar' - ? "assets/images/new-design/pay_online_button_arabic_disabled.png" - : "assets/images/new-design/pay_online_button_disabled.png"; - break; - - case 20: - return widget.languageID == 'ar' - ? "assets/images/new-design/pay_online_button_arabic.png" - : "assets/images/new-design/pay_online_button.png"; - break; - - case 30: - return "assets/images/new-design/qr_code_button.png"; - break; - - case 40: - return "assets/images/new-design/video_call_instruction.png"; - break; - - case 50: - return "assets/images/new-design/liveCare_logo_icon.png"; - break; - - default: - return ""; - } - } - - String getNextActionText(nextAction) { - switch (nextAction) { - case 0: - return "No Action"; - break; - case 10: - return TranslationBase.of(context).confirm; - break; - - case 15: - return TranslationBase.of(context).pendingPayment; - break; - - case 20: - return TranslationBase.of(context).payNow; - break; - - case 30: - return TranslationBase.of(context).viewQR; - break; - - case 40: - return TranslationBase.of(context).instruction; - break; - - case 50: - return TranslationBase.of(context).livecare; - break; - - default: - return ""; - } - } - - String getNextActionDescription(nextAction) { - switch (nextAction) { - case 0: - return "No Action"; - break; - case 10: - return TranslationBase.of(context).upcomingConfirm; - break; - - case 15: - return TranslationBase.of(context).upcomingPaymentPending; - break; - - case 20: - return TranslationBase.of(context).upcomingPaymentNow; - break; - - case 30: - return TranslationBase.of(context).upcomingQR; - break; - - case 40: - return TranslationBase.of(context).upcomingVirtual; - break; - - case 50: - return TranslationBase.of(context).upcomingLivecare; - break; - - default: - return ""; - } - } - - getLanguageID() async { - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); - setState(() { - widget.languageID = languageID; - }); - } - - String getDate(String date) { - DateTime dateObj = DateUtil.convertStringToDate(date); - return DateUtil.getWeekDay(dateObj.weekday) + - ", " + - dateObj.day.toString() + - " " + - DateUtil.getMonth(dateObj.month) + - " " + - dateObj.year.toString() + - " " + - dateObj.hour.toString() + - ":" + - getMinute(dateObj); - } - - String getMinute(DateTime dateObj) { - if (dateObj.minute == 0) { - return dateObj.minute.toString() + "0"; - } else { - return dateObj.minute.toString(); - } - } - - String getDoctorSpeciality(List docSpecial) { - String docSpeciality = ""; - docSpecial.forEach((v) { - docSpeciality = docSpeciality + v + "\n"; - }); - return docSpeciality; - } - - Future navigateToAppointmentDetails(context) async { - Navigator.push( - context, FadePage(page: AppointmentDetails())); - } } diff --git a/lib/pages/appUpdatePage/app_update_page.dart b/lib/pages/appUpdatePage/app_update_page.dart index 7bcf2388..d9ecb3df 100644 --- a/lib/pages/appUpdatePage/app_update_page.dart +++ b/lib/pages/appUpdatePage/app_update_page.dart @@ -1,15 +1,17 @@ import 'dart:io'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/custom_text_button.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:in_app_update/in_app_update.dart'; import 'package:url_launcher/url_launcher.dart'; class AppUpdatePage extends StatefulWidget { - String appUpdateText; + final String appUpdateText; - AppUpdatePage({@required this.appUpdateText}); + AppUpdatePage({required this.appUpdateText}); @override _AppUpdatePageState createState() => _AppUpdatePageState(); @@ -29,39 +31,24 @@ class _AppUpdatePageState extends State { children: [ Stack( children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - SvgPicture.asset( - "assets/images/new-design/update_rocket_image.svg", - fit: BoxFit.fill), - ]), + Column(crossAxisAlignment: CrossAxisAlignment.stretch, children: [ + SvgPicture.asset("assets/images/new-design/update_rocket_image.svg", fit: BoxFit.fill), + ]), Container( margin: EdgeInsets.only(top: 40.0), width: MediaQuery.of(context).size.width, child: Text(TranslationBase.of(context).appUpdate, - textAlign: TextAlign.center, - style: TextStyle( - color: Color(0xff2d6c90).withOpacity(1.0), - fontSize: 22.0, - fontWeight: FontWeight.bold))), + textAlign: TextAlign.center, style: TextStyle(color: Color(0xff2d6c90).withOpacity(1.0), fontSize: 22.0, fontWeight: FontWeight.bold))), ], ), Container( margin: EdgeInsets.only(top: 5.0, bottom: 5.0), - child: SvgPicture.asset("assets/images/new-design/HMG_logo.svg", - fit: BoxFit.fill), + child: SvgPicture.asset("assets/images/new-design/HMG_logo.svg", fit: BoxFit.fill), ), Container( margin: EdgeInsets.only(top: 10.0, left: 10.0, right: 10.0), width: MediaQuery.of(context).size.width, - child: Text(widget.appUpdateText, - textAlign: TextAlign.center, - style: TextStyle( - color: Colors.grey[600], - fontSize: 16.0, - height: 1.5, - fontWeight: FontWeight.bold))), + child: Text(widget.appUpdateText, textAlign: TextAlign.center, style: TextStyle(color: Colors.grey[600], fontSize: 14.0, height: 1.5, fontWeight: FontWeight.w600))), Container( margin: EdgeInsets.only(left: 20.0, right: 20.0, top: 20.0), child: ButtonTheme( @@ -70,16 +57,15 @@ class _AppUpdatePageState extends State { ), minWidth: MediaQuery.of(context).size.width, height: 45.0, - child: RaisedButton( - color: Colors.red[800], - textColor: Colors.white, - disabledTextColor: Colors.white, - disabledColor: new Color(0xFFbcc2c4), + child: CustomTextButton( + backgroundColor: Colors.red[800]!, + disabledForegroundColor: Color(0xFFbcc2c4).withOpacity(0.38), + disabledBackgroundColor: Color(0xFFbcc2c4).withOpacity(0.12), + elevation: 0, onPressed: () { openAppUpdateLink(); }, - child: Text(TranslationBase.of(context).appUpdate, - style: TextStyle(fontSize: 18.0)), + child: Text(TranslationBase.of(context).appUpdate, style: TextStyle(fontSize: 18.0, color: Colors.white)), ), ), ), @@ -92,7 +78,18 @@ class _AppUpdatePageState extends State { openAppUpdateLink() { if (Platform.isAndroid) { - _launchURL("https://play.google.com/store/apps/details?id=com.ejada.hmg"); + // _launchURL("https://play.google.com/store/apps/details?id=com.ejada.hmg"); + InAppUpdate.checkForUpdate().then((info) { + print("checkForUpdate!!!"); + print(info.toString()); + if (info.immediateUpdateAllowed) { + print("Immediate Allowed!!!"); + InAppUpdate.performImmediateUpdate().then((value) {}).catchError((e) => print(e.toString())); + } + }).catchError((e) { + print(e.toString()); + _launchURL("https://play.google.com/store/apps/details?id=com.ejada.hmg"); + }); } if (Platform.isIOS) { _launchURL("https://itunes.apple.com/app/id733503978"); diff --git a/lib/pages/base/base_view.dart b/lib/pages/base/base_view.dart index 5977e97e..cede7732 100644 --- a/lib/pages/base/base_view.dart +++ b/lib/pages/base/base_view.dart @@ -11,13 +11,13 @@ import '../../locator.dart'; AppSharedPreferences sharedPref = AppSharedPreferences(); class BaseView extends StatefulWidget { - final Widget Function(BuildContext context, T model, Widget child) builder; - final Function(T) onModelReady; + final Widget Function(BuildContext context, T model, Widget? child) builder; + final Function(T)? onModelReady; final bool allowAny; BaseView({ - this.builder, - this.onModelReady, + required this.builder, + this.onModelReady, this.allowAny = false, }); @@ -27,17 +27,15 @@ class BaseView extends StatefulWidget { class _BaseViewState extends State> { T model = locator(); - AuthenticatedUserObject authenticatedUserObject = - locator(); + AuthenticatedUserObject authenticatedUserObject = locator(); bool isLogin = false; @override void initState() { - if(widget.allowAny && widget.onModelReady != null){ - widget.onModelReady(model); - } - else if (widget.onModelReady != null && Provider.of(context, listen: false).isLogin) { - widget.onModelReady(model); + if (widget.allowAny && widget.onModelReady != null) { + widget.onModelReady!(model); + } else if (widget.onModelReady != null && Provider.of(context, listen: false).isLogin) { + widget.onModelReady!(model); } super.initState(); } @@ -57,10 +55,12 @@ class _BaseViewState extends State> { @override void dispose() { + if (model != null) { - model = null; + //changed by Aamir + //May be cause a problem after update + model = locator(); } - super.dispose(); } } diff --git a/lib/pages/conference/clipped_video.dart b/lib/pages/conference/clipped_video.dart index 1c01c27c..14711656 100644 --- a/lib/pages/conference/clipped_video.dart +++ b/lib/pages/conference/clipped_video.dart @@ -6,10 +6,10 @@ class ClippedVideo extends StatefulWidget { final Widget child; const ClippedVideo({ - Key key, - @required this.width, - @required this.height, - @required this.child, + Key? key, + required this.width, + required this.height, + required this.child, }) : super(key: key); @override diff --git a/lib/pages/conference/conference_button_bar.dart b/lib/pages/conference/conference_button_bar.dart index d49c4e4a..1b80c3d5 100644 --- a/lib/pages/conference/conference_button_bar.dart +++ b/lib/pages/conference/conference_button_bar.dart @@ -5,28 +5,28 @@ import 'package:diplomaticquarterapp/pages/conference/widgets/circle_button.dart import 'package:flutter/material.dart'; class ConferenceButtonBar extends StatefulWidget { - final VoidCallback onVideoEnabled; - final VoidCallback onAudioEnabled; - final VoidCallback onHangup; - final VoidCallback onSwitchCamera; - final VoidCallback onPersonAdd; - final VoidCallback onPersonRemove; - final void Function(double) onHeight; - final VoidCallback onHide; - final VoidCallback onShow; + final VoidCallback? onVideoEnabled; + final VoidCallback? onAudioEnabled; + final VoidCallback? onHangup; + final VoidCallback? onSwitchCamera; + final VoidCallback? onPersonAdd; + final VoidCallback? onPersonRemove; + final void Function(double)? onHeight; + final VoidCallback? onHide; + final VoidCallback? onShow; final Stream videoEnabled; final Stream audioEnabled; const ConferenceButtonBar({ - Key key, + Key? key, this.onVideoEnabled, this.onAudioEnabled, this.onHangup, this.onSwitchCamera, this.onPersonAdd, this.onPersonRemove, - @required this.videoEnabled, - @required this.audioEnabled, + required this.videoEnabled, + required this.audioEnabled, this.onHeight, this.onHide, this.onShow, @@ -40,19 +40,19 @@ class ConferenceButtonBar extends StatefulWidget { class _ConferenceButtonBarState extends State with AfterLayoutMixin { var _bottom = -100.0; - Timer _timer; - int _remaining; + late Timer _timer; + late int _remaining; var _videoEnabled = true; var _audioEnabled = true; - double _hidden; - double _visible; + late double _hidden; + late double _visible; final _keyButtonBarHeight = GlobalKey(); final Duration timeout = const Duration(seconds: 5); final Duration ms = const Duration(milliseconds: 1); final Duration periodicDuration = const Duration(milliseconds: 100); - Timer startTimeout([int milliseconds]) { + Timer startTimeout([int? milliseconds]) { final duration = milliseconds == null ? timeout : ms * milliseconds; _remaining = duration.inMilliseconds; return Timer.periodic(periodicDuration, (Timer timer) { @@ -69,7 +69,7 @@ class _ConferenceButtonBarState extends State with AfterLay return; } _timer.cancel(); - _timer = null; + // _timer = null; } void _resumeTimer() { @@ -85,10 +85,10 @@ class _ConferenceButtonBarState extends State with AfterLay setState(() { _bottom = _bottom == _visible ? _hidden : _visible; if (_bottom == _visible && widget.onShow != null) { - widget.onShow(); + widget.onShow!(); } if (_bottom == _hidden && widget.onHide != null) { - widget.onHide(); + widget.onHide!(); } }); } @@ -98,7 +98,7 @@ class _ConferenceButtonBarState extends State with AfterLay if (_timer.isActive) { _timer.cancel(); } - _timer = null; + // _timer = null; } if (_bottom == 0) { _timer = startTimeout(); @@ -119,11 +119,11 @@ class _ConferenceButtonBarState extends State with AfterLay @override void afterFirstLayout(BuildContext context) { - final RenderBox renderBoxButtonBar = _keyButtonBarHeight.currentContext.findRenderObject(); - final heightButtonBar = renderBoxButtonBar.size.height; + final heightButtonBar = _keyButtonBarHeight.currentContext!.size!.height; + //Changed by Aamir // Because the `didChangeDependencies` fires before the `afterFirstLayout`, we can use the `_visible` property here. _hidden = -(heightButtonBar + _visible); - widget.onHeight(heightButtonBar); + widget.onHeight!(heightButtonBar); _toggleBar(); } @@ -132,7 +132,7 @@ class _ConferenceButtonBarState extends State with AfterLay super.dispose(); if (_timer != null && _timer.isActive) { _timer.cancel(); - _timer = null; + } } @@ -189,33 +189,33 @@ class _ConferenceButtonBarState extends State with AfterLay stream: widget.videoEnabled, initialData: _videoEnabled, builder: (context, snapshot) { - _videoEnabled = snapshot.data; + _videoEnabled = snapshot.data!; return Icon( _videoEnabled ? Icons.videocam : Icons.videocam_off, color: Colors.white, ); }), key: Key('camera-button'), - onPressed: () => _onPressed(widget.onVideoEnabled), + onPressed: () => _onPressed(widget.onVideoEnabled!), ), CircleButton( child: StreamBuilder( stream: widget.audioEnabled, initialData: _audioEnabled, builder: (context, snapshot) { - _audioEnabled = snapshot.data; + _audioEnabled = snapshot.data!; return Icon( _audioEnabled ? Icons.mic : Icons.mic_off, color: Colors.white, ); }), key: Key('microphone-button'), - onPressed: () => _onPressed(widget.onAudioEnabled), + onPressed: () => _onPressed(widget.onAudioEnabled!), ), CircleButton( child: const Icon(Icons.switch_camera, color: Colors.white), key: Key('switch-camera-button'), - onPressed: () => _onPressed(widget.onSwitchCamera), + onPressed: () => _onPressed(widget.onSwitchCamera!), ), CircleButton( radius: 35, @@ -229,7 +229,7 @@ class _ConferenceButtonBarState extends State with AfterLay ), color: Colors.red.withAlpha(200), key: Key('hangup-button'), - onPressed: () => _onPressed(widget.onHangup), + onPressed: () => _onPressed(widget.onHangup!), ), ], ), diff --git a/lib/pages/conference/conference_page.dart b/lib/pages/conference/conference_page.dart index 7848d4f7..3e5ebe41 100644 --- a/lib/pages/conference/conference_page.dart +++ b/lib/pages/conference/conference_page.dart @@ -1,388 +1,390 @@ -import 'dart:async'; - -import 'package:diplomaticquarterapp/models/LiveCare/room_model.dart'; -import 'package:diplomaticquarterapp/pages/conference/conference_button_bar.dart'; -import 'package:diplomaticquarterapp/pages/conference/conference_room.dart'; -import 'package:diplomaticquarterapp/pages/conference/draggable_publisher.dart'; -import 'package:diplomaticquarterapp/pages/conference/participant_widget.dart'; -import 'package:diplomaticquarterapp/pages/conference/widgets/noise_box.dart'; -import 'package:diplomaticquarterapp/pages/conference/widgets/platform_alert_dialog.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:wakelock/wakelock.dart'; - -class ConferencePage extends StatefulWidget { - final RoomModel roomModel; - - const ConferencePage({Key key, this.roomModel}) : super(key: key); - - @override - _ConferencePageState createState() => _ConferencePageState(); -} - -class _ConferencePageState extends State { - final StreamController _onButtonBarVisibleStreamController = StreamController.broadcast(); - final StreamController _onButtonBarHeightStreamController = StreamController.broadcast(); - ConferenceRoom _conferenceRoom; - StreamSubscription _onConferenceRoomException; - - @override - void initState() { - super.initState(); - _lockInPortrait(); - _connectToRoom(); - _wakeLock(true); - } - - void _connectToRoom() async { - try { - final conferenceRoom = ConferenceRoom( - name: widget.roomModel.name, - token: widget.roomModel.token, - identity: widget.roomModel.identity, - ); - await conferenceRoom.connect(); - setState(() { - _conferenceRoom = conferenceRoom; - _onConferenceRoomException = _conferenceRoom.onException.listen((err) async { - await PlatformAlertDialog( - title: err is PlatformException ? err.message : 'An error occured', - content: err is PlatformException ? err.details : err.toString(), - defaultActionText: 'OK', - ).show(context); - }); - _conferenceRoom.addListener(_conferenceRoomUpdated); - }); - } catch (err) { - print(err); - await PlatformAlertDialog( - title: err is PlatformException ? err.message : 'An error occured', - content: err is PlatformException ? err.details : err.toString(), - defaultActionText: 'OK', - ).show(context); - - Navigator.of(context).pop(); - } - } - - Future _lockInPortrait() async { - await SystemChrome.setPreferredOrientations([ - DeviceOrientation.portraitUp, - DeviceOrientation.portraitDown, - ]); - } - - @override - void dispose() { - _freePortraitLock(); - _wakeLock(false); - _disposeStreamsAndSubscriptions(); - if (_conferenceRoom != null) _conferenceRoom.removeListener(_conferenceRoomUpdated); - super.dispose(); - } - - Future _freePortraitLock() async { - await SystemChrome.setPreferredOrientations([ - DeviceOrientation.landscapeRight, - DeviceOrientation.landscapeLeft, - DeviceOrientation.portraitUp, - DeviceOrientation.portraitDown, - ]); - } - - Future _disposeStreamsAndSubscriptions() async { - if (_onButtonBarVisibleStreamController != null) await _onButtonBarVisibleStreamController.close(); - if (_onButtonBarHeightStreamController != null) await _onButtonBarHeightStreamController.close(); - if (_onConferenceRoomException != null) await _onConferenceRoomException.cancel(); - } - - @override - Widget build(BuildContext context) { - return WillPopScope( - onWillPop: () async => false, - child: Scaffold( - backgroundColor: Colors.black, - body: _conferenceRoom == null ? showProgress() : buildLayout(), - ), - ); - } - - LayoutBuilder buildLayout() { - return LayoutBuilder( - builder: (BuildContext context, BoxConstraints constraints) { - return Stack( - children: [ - _buildParticipants(context, constraints.biggest, _conferenceRoom), - ConferenceButtonBar( - audioEnabled: _conferenceRoom.onAudioEnabled, - videoEnabled: _conferenceRoom.onVideoEnabled, - onAudioEnabled: _conferenceRoom.toggleAudioEnabled, - onVideoEnabled: _conferenceRoom.toggleVideoEnabled, - onHangup: _onHangup, - onSwitchCamera: _conferenceRoom.switchCamera, - onPersonAdd: _onPersonAdd, - onPersonRemove: _onPersonRemove, - onHeight: _onHeightBar, - onShow: _onShowBar, - onHide: _onHideBar, - ), - ], - ); - }, - ); - } - - Widget showProgress() { - return Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Center(child: CircularProgressIndicator()), - SizedBox( - height: 10, - ), - Text( - 'Connecting to the call...', - style: TextStyle(color: Colors.white), - ), - ], - ); - } - - Future _onHangup() async { - print('onHangup'); - await _conferenceRoom.disconnect(); - Navigator.of(context).pop(); - } - - void _onPersonAdd() { - print('onPersonAdd'); - try { - _conferenceRoom.addDummy( - child: Stack( - children: [ - const Placeholder(), - Center( - child: Text( - (_conferenceRoom.participants.length + 1).toString(), - style: const TextStyle( - shadows: [ - Shadow( - blurRadius: 3.0, - color: Color.fromARGB(255, 0, 0, 0), - ), - Shadow( - blurRadius: 8.0, - color: Color.fromARGB(255, 255, 255, 255), - ), - ], - fontSize: 80, - ), - ), - ), - ], - ), - ); - } on PlatformException catch (err) { - PlatformAlertDialog( - title: err.message, - content: err.details, - defaultActionText: 'OK', - ).show(context); - } - } - - void _onPersonRemove() { - print('onPersonRemove'); - _conferenceRoom.removeDummy(); - } - - Widget _buildParticipants(BuildContext context, Size size, ConferenceRoom conferenceRoom) { - final children = []; - final length = conferenceRoom.participants.length; - - if (length <= 2) { - _buildOverlayLayout(context, size, children); - return Stack(children: children); - } - - void buildInCols(bool removeLocalBeforeChunking, bool moveLastOfEachRowToNextRow, int columns) { - _buildLayoutInGrid( - context, - size, - children, - removeLocalBeforeChunking: removeLocalBeforeChunking, - moveLastOfEachRowToNextRow: moveLastOfEachRowToNextRow, - columns: columns, - ); - } - -// if (length <= 3) { -// buildInCols(true, false, 1); -// } else if (length == 5) { -// buildInCols(false, true, 2); -// } else if (length <= 6 || length == 8) { -// buildInCols(false, false, 2); -// } else if (length == 7 || length == 9) { -// buildInCols(true, false, 2); -// } else if (length == 10) { -// buildInCols(false, true, 3); -// } else if (length == 13 || length == 16) { -// buildInCols(true, false, 3); -// } else if (length <= 18) { -// buildInCols(false, false, 3); -// } - - return Column( - children: children, - ); - } - - void _buildOverlayLayout(BuildContext context, Size size, List children) { - final participants = _conferenceRoom.participants; - if (participants.length == 1) { - children.add(_buildNoiseBox()); - } else { - final remoteParticipant = participants.firstWhere((ParticipantWidget participant) => participant.isRemote, orElse: () => null); - if (remoteParticipant != null) { - children.add(remoteParticipant); - } - } - - final localParticipant = participants.firstWhere((ParticipantWidget participant) => !participant.isRemote, orElse: () => null); - if (localParticipant != null) { - children.add(DraggablePublisher( - key: Key('publisher'), - child: localParticipant, - availableScreenSize: size, - onButtonBarVisible: _onButtonBarVisibleStreamController.stream, - onButtonBarHeight: _onButtonBarHeightStreamController.stream, - )); - } - } - - void _buildLayoutInGrid( - BuildContext context, - Size size, - List children, { - bool removeLocalBeforeChunking = false, - bool moveLastOfEachRowToNextRow = false, - int columns = 2, - }) { - final participants = _conferenceRoom.participants; - ParticipantWidget localParticipant; - if (removeLocalBeforeChunking) { - localParticipant = participants.firstWhere((ParticipantWidget participant) => !participant.isRemote, orElse: () => null); - if (localParticipant != null) { - participants.remove(localParticipant); - } - } - final chunkedParticipants = chunk(array: participants, size: columns); - if (localParticipant != null) { - chunkedParticipants.last.add(localParticipant); - participants.add(localParticipant); - } - - if (moveLastOfEachRowToNextRow) { - for (var i = 0; i < chunkedParticipants.length - 1; i++) { - var participant = chunkedParticipants[i].removeLast(); - chunkedParticipants[i + 1].insert(0, participant); - } - } - - for (final participantChunk in chunkedParticipants) { - final rowChildren = []; - for (final participant in participantChunk) { - rowChildren.add( - Container( - width: size.width / participantChunk.length, - height: size.height / chunkedParticipants.length, - child: participant, - ), - ); - } - children.add( - Container( - height: size.height / chunkedParticipants.length, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: rowChildren, - ), - ), - ); - } - } - - NoiseBox _buildNoiseBox() { - return NoiseBox( - density: NoiseBoxDensity.xLow, - backgroundColor: Colors.grey.shade900, - child: Center( - child: Container( - color: Colors.black54, - width: double.infinity, - height: 40, - child: Center( - child: Text( - 'Waiting for another participant to connect to the call...', - key: Key('text-wait'), - textAlign: TextAlign.center, - style: TextStyle(color: Colors.white), - ), - ), - ), - ), - ); - } - - List> chunk({@required List array, @required int size}) { - final result = >[]; - if (array.isEmpty || size <= 0) { - return result; - } - var first = 0; - var last = size; - final totalLoop = array.length % size == 0 ? array.length ~/ size : array.length ~/ size + 1; - for (var i = 0; i < totalLoop; i++) { - if (last > array.length) { - result.add(array.sublist(first, array.length)); - } else { - result.add(array.sublist(first, last)); - } - first = last; - last = last + size; - } - return result; - } - - void _onHeightBar(double height) { - _onButtonBarHeightStreamController.add(height); - } - - void _onShowBar() { - setState(() { - SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.bottom, SystemUiOverlay.top]); - }); - _onButtonBarVisibleStreamController.add(true); - } - - void _onHideBar() { - setState(() { - SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.bottom]); - }); - _onButtonBarVisibleStreamController.add(false); - } - - Future _wakeLock(bool enable) async { - try { - return await (enable ? Wakelock.enable() : Wakelock.disable()); - } catch (err) { - print('Unable to change the Wakelock and set it to $enable'); - print(err); - } - } - - void _conferenceRoomUpdated() { - setState(() {}); - } -} +// import 'dart:async'; +// +// import 'package:diplomaticquarterapp/models/LiveCare/room_model.dart'; +// import 'package:diplomaticquarterapp/pages/conference/conference_button_bar.dart'; +// import 'package:diplomaticquarterapp/pages/conference/conference_room.dart'; +// import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; +// import 'package:diplomaticquarterapp/pages/conference/draggable_publisher.dart'; +// import 'package:diplomaticquarterapp/pages/conference/participant_widget.dart'; +// import 'package:diplomaticquarterapp/pages/conference/widgets/noise_box.dart'; +// import 'package:diplomaticquarterapp/pages/conference/widgets/platform_alert_dialog.dart'; +// import 'package:flutter/material.dart'; +// import 'package:flutter/services.dart'; +// import 'package:wakelock/wakelock.dart'; +// +// class ConferencePage extends StatefulWidget { +// final RoomModel roomModel; +// +// const ConferencePage({Key key, this.roomModel}) : super(key: key); +// +// @override +// _ConferencePageState createState() => _ConferencePageState(); +// } +// +// class _ConferencePageState extends State { +// final StreamController _onButtonBarVisibleStreamController = StreamController.broadcast(); +// final StreamController _onButtonBarHeightStreamController = StreamController.broadcast(); +// // ConferenceRoom _conferenceRoom; +// StreamSubscription _onConferenceRoomException; +// +// @override +// void initState() { +// super.initState(); +// _lockInPortrait(); +// _connectToRoom(); +// _wakeLock(true); +// } +// +// void _connectToRoom() async { +// try { +// final conferenceRoom = ConferenceRoom( +// name: widget.roomModel.name, +// token: widget.roomModel.token, +// identity: widget.roomModel.identity, +// ); +// await conferenceRoom.connect(); +// setState(() { +// _conferenceRoom = conferenceRoom; +// _onConferenceRoomException = _conferenceRoom.onException.listen((err) async { +// await PlatformAlertDialog( +// title: err is PlatformException ? err.message : 'An error occured', +// content: err is PlatformException ? err.details : err.toString(), +// defaultActionText: 'OK', +// ).show(context); +// }); +// _conferenceRoom.addListener(_conferenceRoomUpdated); +// }); +// } catch (err) { +// print(err); +// await PlatformAlertDialog( +// title: err is PlatformException ? err.message : 'An error occured', +// content: err is PlatformException ? err.details : err.toString(), +// defaultActionText: 'OK', +// ).show(context); +// +// Navigator.of(context).pop(); +// } +// } +// +// Future _lockInPortrait() async { +// await SystemChrome.setPreferredOrientations([ +// DeviceOrientation.portraitUp, +// DeviceOrientation.portraitDown, +// ]); +// } +// +// @override +// void dispose() { +// _freePortraitLock(); +// _wakeLock(false); +// _disposeStreamsAndSubscriptions(); +// if (_conferenceRoom != null) _conferenceRoom.removeListener(_conferenceRoomUpdated); +// super.dispose(); +// } +// +// Future _freePortraitLock() async { +// await SystemChrome.setPreferredOrientations([ +// DeviceOrientation.landscapeRight, +// DeviceOrientation.landscapeLeft, +// DeviceOrientation.portraitUp, +// DeviceOrientation.portraitDown, +// ]); +// } +// +// Future _disposeStreamsAndSubscriptions() async { +// if (_onButtonBarVisibleStreamController != null) await _onButtonBarVisibleStreamController.close(); +// if (_onButtonBarHeightStreamController != null) await _onButtonBarHeightStreamController.close(); +// if (_onConferenceRoomException != null) await _onConferenceRoomException.cancel(); +// } +// +// @override +// Widget build(BuildContext context) { +// return WillPopScope( +// onWillPop: () async => false, +// child: Scaffold( +// backgroundColor: Colors.white, +// body: _conferenceRoom == null ? showProgress() : buildLayout(), +// ), +// ); +// } +// +// LayoutBuilder buildLayout() { +// return LayoutBuilder( +// builder: (BuildContext context, BoxConstraints constraints) { +// return Stack( +// children: [ +// _buildParticipants(context, constraints.biggest, _conferenceRoom), +// ConferenceButtonBar( +// audioEnabled: _conferenceRoom.onAudioEnabled, +// videoEnabled: _conferenceRoom.onVideoEnabled, +// onAudioEnabled: _conferenceRoom.toggleAudioEnabled, +// onVideoEnabled: _conferenceRoom.toggleVideoEnabled, +// onHangup: _onHangup, +// onSwitchCamera: _conferenceRoom.switchCamera, +// onPersonAdd: _onPersonAdd, +// onPersonRemove: _onPersonRemove, +// onHeight: _onHeightBar, +// onShow: _onShowBar, +// onHide: _onHideBar, +// ), +// ], +// ); +// }, +// ); +// } +// +// Widget showProgress() { +// return Column( +// mainAxisAlignment: MainAxisAlignment.center, +// crossAxisAlignment: CrossAxisAlignment.center, +// children: [ +// Center(child: CircularProgressIndicator()), +// SizedBox( +// height: 10, +// ), +// Text( +// 'Connecting to the call...', +// style: TextStyle(color: Colors.white), +// ), +// ], +// ); +// } +// +// Future _onHangup() async { +// print('onHangup'); +// await _conferenceRoom.disconnect(); +// LandingPage.isOpenCallPage = false; +// Navigator.of(context).pop(); +// } +// +// void _onPersonAdd() { +// print('onPersonAdd'); +// try { +// _conferenceRoom.addDummy( +// child: Stack( +// children: [ +// const Placeholder(), +// Center( +// child: Text( +// (_conferenceRoom.participants.length + 1).toString(), +// style: const TextStyle( +// shadows: [ +// Shadow( +// blurRadius: 3.0, +// color: Color.fromARGB(255, 0, 0, 0), +// ), +// Shadow( +// blurRadius: 8.0, +// color: Color.fromARGB(255, 255, 255, 255), +// ), +// ], +// fontSize: 80, +// ), +// ), +// ), +// ], +// ), +// ); +// } on PlatformException catch (err) { +// PlatformAlertDialog( +// title: err.message, +// content: err.details, +// defaultActionText: 'OK', +// ).show(context); +// } +// } +// +// void _onPersonRemove() { +// print('onPersonRemove'); +// _conferenceRoom.removeDummy(); +// } +// +// Widget _buildParticipants(BuildContext context, Size size, ConferenceRoom conferenceRoom) { +// final children = []; +// final length = conferenceRoom.participants.length; +// +// if (length <= 2) { +// _buildOverlayLayout(context, size, children); +// return Stack(children: children); +// } +// +// void buildInCols(bool removeLocalBeforeChunking, bool moveLastOfEachRowToNextRow, int columns) { +// _buildLayoutInGrid( +// context, +// size, +// children, +// removeLocalBeforeChunking: removeLocalBeforeChunking, +// moveLastOfEachRowToNextRow: moveLastOfEachRowToNextRow, +// columns: columns, +// ); +// } +// +// // if (length <= 3) { +// // buildInCols(true, false, 1); +// // } else if (length == 5) { +// // buildInCols(false, true, 2); +// // } else if (length <= 6 || length == 8) { +// // buildInCols(false, false, 2); +// // } else if (length == 7 || length == 9) { +// // buildInCols(true, false, 2); +// // } else if (length == 10) { +// // buildInCols(false, true, 3); +// // } else if (length == 13 || length == 16) { +// // buildInCols(true, false, 3); +// // } else if (length <= 18) { +// // buildInCols(false, false, 3); +// // } +// +// return Column( +// children: children, +// ); +// } +// +// void _buildOverlayLayout(BuildContext context, Size size, List children) { +// final participants = _conferenceRoom.participants; +// if (participants.length == 1) { +// children.add(_buildNoiseBox()); +// } else { +// final remoteParticipant = participants.firstWhere((ParticipantWidget participant) => participant.isRemote, orElse: () => null); +// if (remoteParticipant != null) { +// children.add(remoteParticipant); +// } +// } +// +// final localParticipant = participants.firstWhere((ParticipantWidget participant) => !participant.isRemote, orElse: () => null); +// if (localParticipant != null) { +// children.add(DraggablePublisher( +// key: Key('publisher'), +// child: localParticipant, +// availableScreenSize: size, +// onButtonBarVisible: _onButtonBarVisibleStreamController.stream, +// onButtonBarHeight: _onButtonBarHeightStreamController.stream, +// )); +// } +// } +// +// void _buildLayoutInGrid( +// BuildContext context, +// Size size, +// List children, { +// bool removeLocalBeforeChunking = false, +// bool moveLastOfEachRowToNextRow = false, +// int columns = 2, +// }) { +// final participants = _conferenceRoom.participants; +// ParticipantWidget localParticipant; +// if (removeLocalBeforeChunking) { +// localParticipant = participants.firstWhere((ParticipantWidget participant) => !participant.isRemote, orElse: () => null); +// if (localParticipant != null) { +// participants.remove(localParticipant); +// } +// } +// final chunkedParticipants = chunk(array: participants, size: columns); +// if (localParticipant != null) { +// chunkedParticipants.last.add(localParticipant); +// participants.add(localParticipant); +// } +// +// if (moveLastOfEachRowToNextRow) { +// for (var i = 0; i < chunkedParticipants.length - 1; i++) { +// var participant = chunkedParticipants[i].removeLast(); +// chunkedParticipants[i + 1].insert(0, participant); +// } +// } +// +// for (final participantChunk in chunkedParticipants) { +// final rowChildren = []; +// for (final participant in participantChunk) { +// rowChildren.add( +// Container( +// width: size.width / participantChunk.length, +// height: size.height / chunkedParticipants.length, +// child: participant, +// ), +// ); +// } +// children.add( +// Container( +// height: size.height / chunkedParticipants.length, +// child: Row( +// mainAxisAlignment: MainAxisAlignment.spaceEvenly, +// children: rowChildren, +// ), +// ), +// ); +// } +// } +// +// NoiseBox _buildNoiseBox() { +// return NoiseBox( +// density: NoiseBoxDensity.xLow, +// backgroundColor: Colors.grey.shade900, +// child: Center( +// child: Container( +// color: Colors.black54, +// width: double.infinity, +// height: 40, +// child: Center( +// child: Text( +// 'Waiting for another participant to connect to the call...', +// key: Key('text-wait'), +// textAlign: TextAlign.center, +// style: TextStyle(color: Colors.white), +// ), +// ), +// ), +// ), +// ); +// } +// +// List> chunk({@required List array, @required int size}) { +// final result = >[]; +// if (array.isEmpty || size <= 0) { +// return result; +// } +// var first = 0; +// var last = size; +// final totalLoop = array.length % size == 0 ? array.length ~/ size : array.length ~/ size + 1; +// for (var i = 0; i < totalLoop; i++) { +// if (last > array.length) { +// result.add(array.sublist(first, array.length)); +// } else { +// result.add(array.sublist(first, last)); +// } +// first = last; +// last = last + size; +// } +// return result; +// } +// +// void _onHeightBar(double height) { +// _onButtonBarHeightStreamController.add(height); +// } +// +// void _onShowBar() { +// setState(() { +// SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.bottom, SystemUiOverlay.top]); +// }); +// _onButtonBarVisibleStreamController.add(true); +// } +// +// void _onHideBar() { +// setState(() { +// SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.bottom]); +// }); +// _onButtonBarVisibleStreamController.add(false); +// } +// +// Future _wakeLock(bool enable) async { +// try { +// return await (enable ? Wakelock.enable() : Wakelock.disable()); +// } catch (err) { +// print('Unable to change the Wakelock and set it to $enable'); +// print(err); +// } +// } +// +// void _conferenceRoomUpdated() { +// setState(() {}); +// } +// } diff --git a/lib/pages/conference/conference_room.dart b/lib/pages/conference/conference_room.dart index 9c8c1c9a..b68f8ee8 100644 --- a/lib/pages/conference/conference_room.dart +++ b/lib/pages/conference/conference_room.dart @@ -1,530 +1,529 @@ -import 'dart:async'; -import 'dart:typed_data'; - -import 'package:diplomaticquarterapp/pages/conference/participant_widget.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:twilio_programmable_video/twilio_programmable_video.dart'; - -class ConferenceRoom with ChangeNotifier { - final String name; - final String token; - final String identity; - - final StreamController _onAudioEnabledStreamController = StreamController.broadcast(); - Stream onAudioEnabled; - final StreamController _onVideoEnabledStreamController = StreamController.broadcast(); - Stream onVideoEnabled; - final StreamController _onExceptionStreamController = StreamController.broadcast(); - Stream onException; - - final Completer _completer = Completer(); - - final List _participants = []; - final List _participantBuffer = []; - final List _streamSubscriptions = []; - final List _dataTracks = []; - final List _messages = []; - - CameraCapturer _cameraCapturer; - Room _room; - Timer _timer; - - ConferenceRoom({ - @required this.name, - @required this.token, - @required this.identity, - }) { - onAudioEnabled = _onAudioEnabledStreamController.stream; - onVideoEnabled = _onVideoEnabledStreamController.stream; - onException = _onExceptionStreamController.stream; - } - - List get participants { - return [..._participants]; - } - - Future connect() async { - print('ConferenceRoom.connect()'); - try { - await TwilioProgrammableVideo.debug(dart: true, native: true); - await TwilioProgrammableVideo.setSpeakerphoneOn(true); - - _cameraCapturer = CameraCapturer(CameraSource.FRONT_CAMERA); - var connectOptions = ConnectOptions( - token, - roomName: name, - preferredAudioCodecs: [OpusCodec()], - audioTracks: [LocalAudioTrack(true)], - dataTracks: [LocalDataTrack()], - videoTracks: [LocalVideoTrack(true, _cameraCapturer)], - enableDominantSpeaker: true, - ); - - _room = await TwilioProgrammableVideo.connect(connectOptions); - - _streamSubscriptions.add(_room.onConnected.listen(_onConnected)); - _streamSubscriptions.add(_room.onConnectFailure.listen(_onConnectFailure)); - - return _completer.future; - } catch (err) { - print(err); - rethrow; - } - } - - Future disconnect() async { - print('ConferenceRoom.disconnect()'); - if (_timer != null) { - _timer.cancel(); - } - await _room.disconnect(); - } - - @override - void dispose() { - print('ConferenceRoom.dispose()'); - _disposeStreamsAndSubscriptions(); - super.dispose(); - } - - Future _disposeStreamsAndSubscriptions() async { - await _onAudioEnabledStreamController.close(); - await _onVideoEnabledStreamController.close(); - await _onExceptionStreamController.close(); - for (var streamSubscription in _streamSubscriptions) { - await streamSubscription.cancel(); - } - } - - Future sendMessage(String message) async { - final tracks = _room.localParticipant.localDataTracks; - final localDataTrack = tracks.isEmpty ? null : tracks[0].localDataTrack; - if (localDataTrack == null || _messages.isNotEmpty) { - print('ConferenceRoom.sendMessage => Track is not available yet, buffering message.'); - _messages.add(message); - return; - } - await localDataTrack.send(message); - } - - Future sendBufferMessage(ByteBuffer message) async { - final tracks = _room.localParticipant.localDataTracks; - final localDataTrack = tracks.isEmpty ? null : tracks[0].localDataTrack; - if (localDataTrack == null) { - return; - } - await localDataTrack.sendBuffer(message); - } - - Future toggleVideoEnabled() async { - final tracks = _room.localParticipant.localVideoTracks; - final localVideoTrack = tracks.isEmpty ? null : tracks[0].localVideoTrack; - if (localVideoTrack == null) { - print('ConferenceRoom.toggleVideoEnabled() => Track is not available yet!'); - return; - } - await localVideoTrack.enable(!localVideoTrack.isEnabled); - - var index = _participants.indexWhere((ParticipantWidget participant) => !participant.isRemote); - if (index < 0) { - return; - } - var participant = _participants[index]; - _participants.replaceRange( - index, - index + 1, - [ - participant.copyWith(videoEnabled: localVideoTrack.isEnabled), - ], - ); - print('ConferenceRoom.toggleVideoEnabled() => ${localVideoTrack.isEnabled}'); - _onVideoEnabledStreamController.add(localVideoTrack.isEnabled); - notifyListeners(); - } - - Future toggleAudioEnabled() async { - final tracks = _room.localParticipant.localAudioTracks; - final localAudioTrack = tracks.isEmpty ? null : tracks[0].localAudioTrack; - if (localAudioTrack == null) { - print('ConferenceRoom.toggleAudioEnabled() => Track is not available yet!'); - return; - } - await localAudioTrack.enable(!localAudioTrack.isEnabled); - - var index = _participants.indexWhere((ParticipantWidget participant) => !participant.isRemote); - if (index < 0) { - return; - } - var participant = _participants[index]; - _participants.replaceRange( - index, - index + 1, - [ - participant.copyWith(audioEnabled: localAudioTrack.isEnabled), - ], - ); - print('ConferenceRoom.toggleAudioEnabled() => ${localAudioTrack.isEnabled}'); - _onAudioEnabledStreamController.add(localAudioTrack.isEnabled); - notifyListeners(); - } - - Future switchCamera() async { - print('ConferenceRoom.switchCamera()'); - try { - await _cameraCapturer.switchCamera(); - } on FormatException catch (e) { - print( - 'ConferenceRoom.switchCamera() failed because of FormatException with message: ${e.message}', - ); - } - } - - void addDummy({Widget child}) { - print('ConferenceRoom.addDummy()'); - if (_participants.length >= 18) { - throw PlatformException( - code: 'ConferenceRoom.maximumReached', - message: 'Maximum reached', - details: 'Currently the lay-out can only render a maximum of 18 participants', - ); - } - _participants.insert( - 0, - ParticipantWidget( - id: (_participants.length + 1).toString(), - child: child, - isRemote: true, - audioEnabled: true, - videoEnabled: true, - isDummy: true, - ), - ); - notifyListeners(); - } - - void removeDummy() { - print('ConferenceRoom.removeDummy()'); - var dummy = _participants.firstWhere((participant) => participant.isDummy, orElse: () => null); - if (dummy != null) { - _participants.remove(dummy); - notifyListeners(); - } - } - - void _onConnected(Room room) { - print('ConferenceRoom._onConnected => state: ${room.state}'); - - // When connected for the first time, add remote participant listeners - _streamSubscriptions.add(_room.onParticipantConnected.listen(_onParticipantConnected)); - _streamSubscriptions.add(_room.onParticipantDisconnected.listen(_onParticipantDisconnected)); - _streamSubscriptions.add(_room.onDominantSpeakerChange.listen(_onDominantSpeakerChanged)); - // Only add ourselves when connected for the first time too. - _participants.add( - _buildParticipant( - child: room.localParticipant.localVideoTracks[0].localVideoTrack.widget(), - id: identity, - audioEnabled: true, - videoEnabled: true, - ), - ); - for (final remoteParticipant in room.remoteParticipants) { - var participant = _participants.firstWhere((participant) => participant.id == remoteParticipant.sid, orElse: () => null); - if (participant == null) { - print('Adding participant that was already present in the room ${remoteParticipant.sid}, before I connected'); - _addRemoteParticipantListeners(remoteParticipant); - } - } - // We have to listen for the [onDataTrackPublished] event on the [LocalParticipant] in - // order to be able to use the [send] method. - _streamSubscriptions.add(room.localParticipant.onDataTrackPublished.listen(_onLocalDataTrackPublished)); - notifyListeners(); - _completer.complete(room); - - _timer = Timer.periodic(const Duration(minutes: 1), (_) { - // Let's see if we can send some data over the DataTrack API - sendMessage('And another minute has passed since I connected...'); - // Also try the ByteBuffer way of sending data - final list = 'This data has been sent over the ByteBuffer channel of the DataTrack API'.codeUnits; - var bytes = Uint8List.fromList(list); - sendBufferMessage(bytes.buffer); - }); - } - - void _onLocalDataTrackPublished(LocalDataTrackPublishedEvent event) { - // Send buffered messages, if any... - while (_messages.isNotEmpty) { - var message = _messages.removeAt(0); - print('Sending buffered message: $message'); - event.localDataTrackPublication.localDataTrack.send(message); - } - } - - void _onConnectFailure(RoomConnectFailureEvent event) { - print('ConferenceRoom._onConnectFailure: ${event.exception}'); - _completer.completeError(event.exception); - } - - void _onDominantSpeakerChanged(DominantSpeakerChangedEvent event) { - print('ConferenceRoom._onDominantSpeakerChanged: ${event.remoteParticipant.identity}'); - var oldDominantParticipant = _participants.firstWhere((p) => p.isDominant, orElse: () => null); - if (oldDominantParticipant != null) { - var oldDominantParticipantIndex = _participants.indexOf(oldDominantParticipant); - _participants.replaceRange(oldDominantParticipantIndex, oldDominantParticipantIndex + 1, [oldDominantParticipant.copyWith(isDominant: false)]); - } - - var newDominantParticipant = _participants.firstWhere((p) => p.id == event.remoteParticipant.sid); - var newDominantParticipantIndex = _participants.indexOf(newDominantParticipant); - _participants.replaceRange(newDominantParticipantIndex, newDominantParticipantIndex + 1, [newDominantParticipant.copyWith(isDominant: true)]); - notifyListeners(); - } - - void _onParticipantConnected(RoomParticipantConnectedEvent event) { - print('ConferenceRoom._onParticipantConnected, ${event.remoteParticipant.sid}'); - _addRemoteParticipantListeners(event.remoteParticipant); - } - - void _onParticipantDisconnected(RoomParticipantDisconnectedEvent event) { - print('ConferenceRoom._onParticipantDisconnected: ${event.remoteParticipant.sid}'); - _participants.removeWhere((ParticipantWidget p) => p.id == event.remoteParticipant.sid); - notifyListeners(); - } - - ParticipantWidget _buildParticipant({ - @required Widget child, - @required String id, - @required bool audioEnabled, - @required bool videoEnabled, - RemoteParticipant remoteParticipant, - }) { - return ParticipantWidget( - id: remoteParticipant?.sid, - isRemote: remoteParticipant != null, - child: child, - audioEnabled: audioEnabled, - videoEnabled: videoEnabled, - ); - } - - void _addRemoteParticipantListeners(RemoteParticipant remoteParticipant) { - print('ConferenceRoom._addRemoteParticipantListeners() => Adding listeners to remoteParticipant ${remoteParticipant.sid}'); - _streamSubscriptions.add(remoteParticipant.onAudioTrackDisabled.listen(_onAudioTrackDisabled)); - _streamSubscriptions.add(remoteParticipant.onAudioTrackEnabled.listen(_onAudioTrackEnabled)); - _streamSubscriptions.add(remoteParticipant.onAudioTrackPublished.listen(_onAudioTrackPublished)); - _streamSubscriptions.add(remoteParticipant.onAudioTrackSubscribed.listen(_onAudioTrackSubscribed)); - _streamSubscriptions.add(remoteParticipant.onAudioTrackSubscriptionFailed.listen(_onAudioTrackSubscriptionFailed)); - _streamSubscriptions.add(remoteParticipant.onAudioTrackUnpublished.listen(_onAudioTrackUnpublished)); - _streamSubscriptions.add(remoteParticipant.onAudioTrackUnsubscribed.listen(_onAudioTrackUnsubscribed)); - - _streamSubscriptions.add(remoteParticipant.onDataTrackPublished.listen(_onDataTrackPublished)); - _streamSubscriptions.add(remoteParticipant.onDataTrackSubscribed.listen(_onDataTrackSubscribed)); - _streamSubscriptions.add(remoteParticipant.onDataTrackSubscriptionFailed.listen(_onDataTrackSubscriptionFailed)); - _streamSubscriptions.add(remoteParticipant.onDataTrackUnpublished.listen(_onDataTrackUnpublished)); - _streamSubscriptions.add(remoteParticipant.onDataTrackUnsubscribed.listen(_onDataTrackUnsubscribed)); - - _streamSubscriptions.add(remoteParticipant.onVideoTrackDisabled.listen(_onVideoTrackDisabled)); - _streamSubscriptions.add(remoteParticipant.onVideoTrackEnabled.listen(_onVideoTrackEnabled)); - _streamSubscriptions.add(remoteParticipant.onVideoTrackPublished.listen(_onVideoTrackPublished)); - _streamSubscriptions.add(remoteParticipant.onVideoTrackSubscribed.listen(_onVideoTrackSubscribed)); - _streamSubscriptions.add(remoteParticipant.onVideoTrackSubscriptionFailed.listen(_onVideoTrackSubscriptionFailed)); - _streamSubscriptions.add(remoteParticipant.onVideoTrackUnpublished.listen(_onVideoTrackUnpublished)); - _streamSubscriptions.add(remoteParticipant.onVideoTrackUnsubscribed.listen(_onVideoTrackUnsubscribed)); - } - - void _onAudioTrackDisabled(RemoteAudioTrackEvent event) { - print('ConferenceRoom._onAudioTrackDisabled(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrackPublication.trackSid}, isEnabled: ${event.remoteAudioTrackPublication.isTrackEnabled}'); - _setRemoteAudioEnabled(event); - } - - void _onAudioTrackEnabled(RemoteAudioTrackEvent event) { - print('ConferenceRoom._onAudioTrackEnabled(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrackPublication.trackSid}, isEnabled: ${event.remoteAudioTrackPublication.isTrackEnabled}'); - _setRemoteAudioEnabled(event); - } - - void _onAudioTrackPublished(RemoteAudioTrackEvent event) { - print('ConferenceRoom._onAudioTrackPublished(), ${event.remoteParticipant.sid}}'); - } - - void _onAudioTrackSubscribed(RemoteAudioTrackSubscriptionEvent event) { - print('ConferenceRoom._onAudioTrackSubscribed(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrackPublication.trackSid}'); - _addOrUpdateParticipant(event); - } - - void _onAudioTrackSubscriptionFailed(RemoteAudioTrackSubscriptionFailedEvent event) { - print('ConferenceRoom._onAudioTrackSubscriptionFailed(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrackPublication.trackSid}'); - _onExceptionStreamController.add( - PlatformException( - code: 'ConferenceRoom.audioTrackSubscriptionFailed', - message: 'AudioTrack Subscription Failed', - details: event.exception.toString(), - ), - ); - } - - void _onAudioTrackUnpublished(RemoteAudioTrackEvent event) { - print('ConferenceRoom._onAudioTrackUnpublished(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrackPublication.trackSid}'); - } - - void _onAudioTrackUnsubscribed(RemoteAudioTrackSubscriptionEvent event) { - print('ConferenceRoom._onAudioTrackUnsubscribed(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrack.sid}'); - } - - void _onDataTrackPublished(RemoteDataTrackEvent event) { - print('ConferenceRoom._onDataTrackPublished(), ${event.remoteParticipant.sid}}'); - } - - void _onDataTrackSubscribed(RemoteDataTrackSubscriptionEvent event) { - print('ConferenceRoom._onDataTrackSubscribed(), ${event.remoteParticipant.sid}, ${event.remoteDataTrackPublication.trackSid}'); - final dataTrack = event.remoteDataTrackPublication.remoteDataTrack; - _dataTracks.add(dataTrack); - _streamSubscriptions.add(dataTrack.onMessage.listen(_onMessage)); - _streamSubscriptions.add(dataTrack.onBufferMessage.listen(_onBufferMessage)); - } - - void _onDataTrackSubscriptionFailed(RemoteDataTrackSubscriptionFailedEvent event) { - print('ConferenceRoom._onDataTrackSubscriptionFailed(), ${event.remoteParticipant.sid}, ${event.remoteDataTrackPublication.trackSid}'); - _onExceptionStreamController.add( - PlatformException( - code: 'ConferenceRoom.dataTrackSubscriptionFailed', - message: 'DataTrack Subscription Failed', - details: event.exception.toString(), - ), - ); - } - - void _onDataTrackUnpublished(RemoteDataTrackEvent event) { - print('ConferenceRoom._onDataTrackUnpublished(), ${event.remoteParticipant.sid}, ${event.remoteDataTrackPublication.trackSid}'); - } - - void _onDataTrackUnsubscribed(RemoteDataTrackSubscriptionEvent event) { - print('ConferenceRoom._onDataTrackUnsubscribed(), ${event.remoteParticipant.sid}, ${event.remoteDataTrack.sid}'); - } - - void _onVideoTrackDisabled(RemoteVideoTrackEvent event) { - print('ConferenceRoom._onVideoTrackDisabled(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrackPublication.trackSid}, isEnabled: ${event.remoteVideoTrackPublication.isTrackEnabled}'); - _setRemoteVideoEnabled(event); - } - - void _onVideoTrackEnabled(RemoteVideoTrackEvent event) { - print('ConferenceRoom._onVideoTrackEnabled(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrackPublication.trackSid}, isEnabled: ${event.remoteVideoTrackPublication.isTrackEnabled}'); - _setRemoteVideoEnabled(event); - } - - void _onVideoTrackPublished(RemoteVideoTrackEvent event) { - print('ConferenceRoom._onVideoTrackPublished(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrackPublication.trackSid}'); - } - - void _onVideoTrackSubscribed(RemoteVideoTrackSubscriptionEvent event) { - print('ConferenceRoom._onVideoTrackSubscribed(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrack.sid}'); - _addOrUpdateParticipant(event); - } - - void _onVideoTrackSubscriptionFailed(RemoteVideoTrackSubscriptionFailedEvent event) { - print('ConferenceRoom._onVideoTrackSubscriptionFailed(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrackPublication.trackSid}'); - _onExceptionStreamController.add( - PlatformException( - code: 'ConferenceRoom.videoTrackSubscriptionFailed', - message: 'VideoTrack Subscription Failed', - details: event.exception.toString(), - ), - ); - } - - void _onVideoTrackUnpublished(RemoteVideoTrackEvent event) { - print('ConferenceRoom._onVideoTrackUnpublished(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrackPublication.trackSid}'); - } - - void _onVideoTrackUnsubscribed(RemoteVideoTrackSubscriptionEvent event) { - print('ConferenceRoom._onVideoTrackUnsubscribed(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrack.sid}'); - } - - void _onMessage(RemoteDataTrackStringMessageEvent event) { - print('onMessage => ${event.remoteDataTrack.sid}, ${event.message}'); - } - - void _onBufferMessage(RemoteDataTrackBufferMessageEvent event) { - print('onBufferMessage => ${event.remoteDataTrack.sid}, ${String.fromCharCodes(event.message.asUint8List())}'); - } - - void _setRemoteAudioEnabled(RemoteAudioTrackEvent event) { - if (event.remoteAudioTrackPublication == null) { - return; - } - var index = _participants.indexWhere((ParticipantWidget participant) => participant.id == event.remoteParticipant.sid); - if (index < 0) { - return; - } - var participant = _participants[index]; - _participants.replaceRange( - index, - index + 1, - [ - participant.copyWith(audioEnabled: event.remoteAudioTrackPublication.isTrackEnabled), - ], - ); - notifyListeners(); - } - - void _setRemoteVideoEnabled(RemoteVideoTrackEvent event) { - if (event.remoteVideoTrackPublication == null) { - return; - } - var index = _participants.indexWhere((ParticipantWidget participant) => participant.id == event.remoteParticipant.sid); - if (index < 0) { - return; - } - var participant = _participants[index]; - _participants.replaceRange( - index, - index + 1, - [ - participant.copyWith(videoEnabled: event.remoteVideoTrackPublication.isTrackEnabled), - ], - ); - notifyListeners(); - } - - void _addOrUpdateParticipant(RemoteParticipantEvent event) { - print('ConferenceRoom._addOrUpdateParticipant(), ${event.remoteParticipant.sid}'); - final participant = _participants.firstWhere( - (ParticipantWidget participant) => participant.id == event.remoteParticipant.sid, - orElse: () => null, - ); - if (participant != null) { - print('Participant found: ${participant.id}, updating A/V enabled values'); - _setRemoteVideoEnabled(event); - _setRemoteAudioEnabled(event); - } else { - final bufferedParticipant = _participantBuffer.firstWhere( - (ParticipantBuffer participant) => participant.id == event.remoteParticipant.sid, - orElse: () => null, - ); - if (bufferedParticipant != null) { - _participantBuffer.remove(bufferedParticipant); - } else if (event is RemoteAudioTrackEvent) { - print('Audio subscription came first, waiting for the video subscription...'); - _participantBuffer.add( - ParticipantBuffer( - id: event.remoteParticipant.sid, - audioEnabled: event.remoteAudioTrackPublication?.remoteAudioTrack?.isEnabled ?? true, - ), - ); - return; - } - if (event is RemoteVideoTrackSubscriptionEvent) { - print('New participant, adding: ${event.remoteParticipant.sid}'); - _participants.insert( - 0, - _buildParticipant( - child: event.remoteVideoTrack.widget(), - id: event.remoteParticipant.sid, - remoteParticipant: event.remoteParticipant, - audioEnabled: bufferedParticipant?.audioEnabled ?? true, - videoEnabled: event.remoteVideoTrackPublication?.remoteVideoTrack?.isEnabled ?? true, - ), - ); - } - notifyListeners(); - } - } -} +// import 'dart:async'; +// import 'dart:typed_data'; +// +// import 'package:diplomaticquarterapp/pages/conference/participant_widget.dart'; +// import 'package:flutter/material.dart'; +// import 'package:flutter/services.dart'; +// +// class ConferenceRoom with ChangeNotifier { +// final String name; +// final String token; +// final String identity; +// +// final StreamController _onAudioEnabledStreamController = StreamController.broadcast(); +// Stream onAudioEnabled; +// final StreamController _onVideoEnabledStreamController = StreamController.broadcast(); +// Stream onVideoEnabled; +// final StreamController _onExceptionStreamController = StreamController.broadcast(); +// Stream onException; +// +// final Completer _completer = Completer(); +// +// final List _participants = []; +// final List _participantBuffer = []; +// final List _streamSubscriptions = []; +// final List _dataTracks = []; +// final List _messages = []; +// +// CameraCapturer _cameraCapturer; +// Room _room; +// Timer _timer; +// +// ConferenceRoom({ +// @required this.name, +// @required this.token, +// @required this.identity, +// }) { +// onAudioEnabled = _onAudioEnabledStreamController.stream; +// onVideoEnabled = _onVideoEnabledStreamController.stream; +// onException = _onExceptionStreamController.stream; +// } +// +// List get participants { +// return [..._participants]; +// } +// +// Future connect() async { +// print('ConferenceRoom.connect()'); +// try { +// await TwilioProgrammableVideo.debug(dart: true, native: true); +// await TwilioProgrammableVideo.setSpeakerphoneOn(true); +// +// _cameraCapturer = CameraCapturer(CameraSource.FRONT_CAMERA); +// var connectOptions = ConnectOptions( +// token, +// roomName: name, +// preferredAudioCodecs: [OpusCodec()], +// audioTracks: [LocalAudioTrack(true)], +// dataTracks: [LocalDataTrack()], +// videoTracks: [LocalVideoTrack(true, _cameraCapturer)], +// enableDominantSpeaker: true, +// ); +// +// _room = await TwilioProgrammableVideo.connect(connectOptions); +// +// _streamSubscriptions.add(_room.onConnected.listen(_onConnected)); +// _streamSubscriptions.add(_room.onConnectFailure.listen(_onConnectFailure)); +// +// return _completer.future; +// } catch (err) { +// print(err); +// rethrow; +// } +// } +// +// Future disconnect() async { +// print('ConferenceRoom.disconnect()'); +// if (_timer != null) { +// _timer.cancel(); +// } +// await _room.disconnect(); +// } +// +// @override +// void dispose() { +// print('ConferenceRoom.dispose()'); +// _disposeStreamsAndSubscriptions(); +// super.dispose(); +// } +// +// Future _disposeStreamsAndSubscriptions() async { +// await _onAudioEnabledStreamController.close(); +// await _onVideoEnabledStreamController.close(); +// await _onExceptionStreamController.close(); +// for (var streamSubscription in _streamSubscriptions) { +// await streamSubscription.cancel(); +// } +// } +// +// Future sendMessage(String message) async { +// final tracks = _room.localParticipant.localDataTracks; +// final localDataTrack = tracks.isEmpty ? null : tracks[0].localDataTrack; +// if (localDataTrack == null || _messages.isNotEmpty) { +// print('ConferenceRoom.sendMessage => Track is not available yet, buffering message.'); +// _messages.add(message); +// return; +// } +// await localDataTrack.send(message); +// } +// +// Future sendBufferMessage(ByteBuffer message) async { +// final tracks = _room.localParticipant.localDataTracks; +// final localDataTrack = tracks.isEmpty ? null : tracks[0].localDataTrack; +// if (localDataTrack == null) { +// return; +// } +// await localDataTrack.sendBuffer(message); +// } +// +// Future toggleVideoEnabled() async { +// final tracks = _room.localParticipant.localVideoTracks; +// final localVideoTrack = tracks.isEmpty ? null : tracks[0].localVideoTrack; +// if (localVideoTrack == null) { +// print('ConferenceRoom.toggleVideoEnabled() => Track is not available yet!'); +// return; +// } +// await localVideoTrack.enable(!localVideoTrack.isEnabled); +// +// var index = _participants.indexWhere((ParticipantWidget participant) => !participant.isRemote); +// if (index < 0) { +// return; +// } +// var participant = _participants[index]; +// _participants.replaceRange( +// index, +// index + 1, +// [ +// participant.copyWith(videoEnabled: localVideoTrack.isEnabled), +// ], +// ); +// print('ConferenceRoom.toggleVideoEnabled() => ${localVideoTrack.isEnabled}'); +// _onVideoEnabledStreamController.add(localVideoTrack.isEnabled); +// notifyListeners(); +// } +// +// Future toggleAudioEnabled() async { +// final tracks = _room.localParticipant.localAudioTracks; +// final localAudioTrack = tracks.isEmpty ? null : tracks[0].localAudioTrack; +// if (localAudioTrack == null) { +// print('ConferenceRoom.toggleAudioEnabled() => Track is not available yet!'); +// return; +// } +// await localAudioTrack.enable(!localAudioTrack.isEnabled); +// +// var index = _participants.indexWhere((ParticipantWidget participant) => !participant.isRemote); +// if (index < 0) { +// return; +// } +// var participant = _participants[index]; +// _participants.replaceRange( +// index, +// index + 1, +// [ +// participant.copyWith(audioEnabled: localAudioTrack.isEnabled), +// ], +// ); +// print('ConferenceRoom.toggleAudioEnabled() => ${localAudioTrack.isEnabled}'); +// _onAudioEnabledStreamController.add(localAudioTrack.isEnabled); +// notifyListeners(); +// } +// +// Future switchCamera() async { +// print('ConferenceRoom.switchCamera()'); +// try { +// await _cameraCapturer.switchCamera(); +// } on FormatException catch (e) { +// print( +// 'ConferenceRoom.switchCamera() failed because of FormatException with message: ${e.message}', +// ); +// } +// } +// +// void addDummy({Widget child}) { +// print('ConferenceRoom.addDummy()'); +// if (_participants.length >= 18) { +// throw PlatformException( +// code: 'ConferenceRoom.maximumReached', +// message: 'Maximum reached', +// details: 'Currently the lay-out can only render a maximum of 18 participants', +// ); +// } +// _participants.insert( +// 0, +// ParticipantWidget( +// id: (_participants.length + 1).toString(), +// child: child, +// isRemote: true, +// audioEnabled: true, +// videoEnabled: true, +// isDummy: true, +// ), +// ); +// notifyListeners(); +// } +// +// void removeDummy() { +// print('ConferenceRoom.removeDummy()'); +// var dummy = _participants.firstWhere((participant) => participant.isDummy, orElse: () => null); +// if (dummy != null) { +// _participants.remove(dummy); +// notifyListeners(); +// } +// } +// +// void _onConnected(Room room) { +// print('ConferenceRoom._onConnected => state: ${room.state}'); +// +// // When connected for the first time, add remote participant listeners +// _streamSubscriptions.add(_room.onParticipantConnected.listen(_onParticipantConnected)); +// _streamSubscriptions.add(_room.onParticipantDisconnected.listen(_onParticipantDisconnected)); +// _streamSubscriptions.add(_room.onDominantSpeakerChange.listen(_onDominantSpeakerChanged)); +// // Only add ourselves when connected for the first time too. +// _participants.add( +// _buildParticipant( +// child: room.localParticipant.localVideoTracks[0].localVideoTrack.widget(), +// id: identity, +// audioEnabled: true, +// videoEnabled: true, +// ), +// ); +// for (final remoteParticipant in room.remoteParticipants) { +// var participant = _participants.firstWhere((participant) => participant.id == remoteParticipant.sid, orElse: () => null); +// if (participant == null) { +// print('Adding participant that was already present in the room ${remoteParticipant.sid}, before I connected'); +// _addRemoteParticipantListeners(remoteParticipant); +// } +// } +// // We have to listen for the [onDataTrackPublished] event on the [LocalParticipant] in +// // order to be able to use the [send] method. +// _streamSubscriptions.add(room.localParticipant.onDataTrackPublished.listen(_onLocalDataTrackPublished)); +// notifyListeners(); +// _completer.complete(room); +// +// _timer = Timer.periodic(const Duration(minutes: 1), (_) { +// // Let's see if we can send some data over the DataTrack API +// sendMessage('And another minute has passed since I connected...'); +// // Also try the ByteBuffer way of sending data +// final list = 'This data has been sent over the ByteBuffer channel of the DataTrack API'.codeUnits; +// var bytes = Uint8List.fromList(list); +// sendBufferMessage(bytes.buffer); +// }); +// } +// +// void _onLocalDataTrackPublished(LocalDataTrackPublishedEvent event) { +// // Send buffered messages, if any... +// while (_messages.isNotEmpty) { +// var message = _messages.removeAt(0); +// print('Sending buffered message: $message'); +// event.localDataTrackPublication.localDataTrack.send(message); +// } +// } +// +// void _onConnectFailure(RoomConnectFailureEvent event) { +// print('ConferenceRoom._onConnectFailure: ${event.exception}'); +// _completer.completeError(event.exception); +// } +// +// void _onDominantSpeakerChanged(DominantSpeakerChangedEvent event) { +// print('ConferenceRoom._onDominantSpeakerChanged: ${event.remoteParticipant.identity}'); +// var oldDominantParticipant = _participants.firstWhere((p) => p.isDominant, orElse: () => null); +// if (oldDominantParticipant != null) { +// var oldDominantParticipantIndex = _participants.indexOf(oldDominantParticipant); +// _participants.replaceRange(oldDominantParticipantIndex, oldDominantParticipantIndex + 1, [oldDominantParticipant.copyWith(isDominant: false)]); +// } +// +// var newDominantParticipant = _participants.firstWhere((p) => p.id == event.remoteParticipant.sid); +// var newDominantParticipantIndex = _participants.indexOf(newDominantParticipant); +// _participants.replaceRange(newDominantParticipantIndex, newDominantParticipantIndex + 1, [newDominantParticipant.copyWith(isDominant: true)]); +// notifyListeners(); +// } +// +// void _onParticipantConnected(RoomParticipantConnectedEvent event) { +// print('ConferenceRoom._onParticipantConnected, ${event.remoteParticipant.sid}'); +// _addRemoteParticipantListeners(event.remoteParticipant); +// } +// +// void _onParticipantDisconnected(RoomParticipantDisconnectedEvent event) { +// print('ConferenceRoom._onParticipantDisconnected: ${event.remoteParticipant.sid}'); +// _participants.removeWhere((ParticipantWidget p) => p.id == event.remoteParticipant.sid); +// notifyListeners(); +// } +// +// ParticipantWidget _buildParticipant({ +// @required Widget child, +// @required String id, +// @required bool audioEnabled, +// @required bool videoEnabled, +// RemoteParticipant remoteParticipant, +// }) { +// return ParticipantWidget( +// id: remoteParticipant?.sid, +// isRemote: remoteParticipant != null, +// child: child, +// audioEnabled: audioEnabled, +// videoEnabled: videoEnabled, +// ); +// } +// +// void _addRemoteParticipantListeners(RemoteParticipant remoteParticipant) { +// print('ConferenceRoom._addRemoteParticipantListeners() => Adding listeners to remoteParticipant ${remoteParticipant.sid}'); +// _streamSubscriptions.add(remoteParticipant.onAudioTrackDisabled.listen(_onAudioTrackDisabled)); +// _streamSubscriptions.add(remoteParticipant.onAudioTrackEnabled.listen(_onAudioTrackEnabled)); +// _streamSubscriptions.add(remoteParticipant.onAudioTrackPublished.listen(_onAudioTrackPublished)); +// _streamSubscriptions.add(remoteParticipant.onAudioTrackSubscribed.listen(_onAudioTrackSubscribed)); +// _streamSubscriptions.add(remoteParticipant.onAudioTrackSubscriptionFailed.listen(_onAudioTrackSubscriptionFailed)); +// _streamSubscriptions.add(remoteParticipant.onAudioTrackUnpublished.listen(_onAudioTrackUnpublished)); +// _streamSubscriptions.add(remoteParticipant.onAudioTrackUnsubscribed.listen(_onAudioTrackUnsubscribed)); +// +// _streamSubscriptions.add(remoteParticipant.onDataTrackPublished.listen(_onDataTrackPublished)); +// _streamSubscriptions.add(remoteParticipant.onDataTrackSubscribed.listen(_onDataTrackSubscribed)); +// _streamSubscriptions.add(remoteParticipant.onDataTrackSubscriptionFailed.listen(_onDataTrackSubscriptionFailed)); +// _streamSubscriptions.add(remoteParticipant.onDataTrackUnpublished.listen(_onDataTrackUnpublished)); +// _streamSubscriptions.add(remoteParticipant.onDataTrackUnsubscribed.listen(_onDataTrackUnsubscribed)); +// +// _streamSubscriptions.add(remoteParticipant.onVideoTrackDisabled.listen(_onVideoTrackDisabled)); +// _streamSubscriptions.add(remoteParticipant.onVideoTrackEnabled.listen(_onVideoTrackEnabled)); +// _streamSubscriptions.add(remoteParticipant.onVideoTrackPublished.listen(_onVideoTrackPublished)); +// _streamSubscriptions.add(remoteParticipant.onVideoTrackSubscribed.listen(_onVideoTrackSubscribed)); +// _streamSubscriptions.add(remoteParticipant.onVideoTrackSubscriptionFailed.listen(_onVideoTrackSubscriptionFailed)); +// _streamSubscriptions.add(remoteParticipant.onVideoTrackUnpublished.listen(_onVideoTrackUnpublished)); +// _streamSubscriptions.add(remoteParticipant.onVideoTrackUnsubscribed.listen(_onVideoTrackUnsubscribed)); +// } +// +// void _onAudioTrackDisabled(RemoteAudioTrackEvent event) { +// print('ConferenceRoom._onAudioTrackDisabled(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrackPublication.trackSid}, isEnabled: ${event.remoteAudioTrackPublication.isTrackEnabled}'); +// _setRemoteAudioEnabled(event); +// } +// +// void _onAudioTrackEnabled(RemoteAudioTrackEvent event) { +// print('ConferenceRoom._onAudioTrackEnabled(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrackPublication.trackSid}, isEnabled: ${event.remoteAudioTrackPublication.isTrackEnabled}'); +// _setRemoteAudioEnabled(event); +// } +// +// void _onAudioTrackPublished(RemoteAudioTrackEvent event) { +// print('ConferenceRoom._onAudioTrackPublished(), ${event.remoteParticipant.sid}}'); +// } +// +// void _onAudioTrackSubscribed(RemoteAudioTrackSubscriptionEvent event) { +// print('ConferenceRoom._onAudioTrackSubscribed(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrackPublication.trackSid}'); +// _addOrUpdateParticipant(event); +// } +// +// void _onAudioTrackSubscriptionFailed(RemoteAudioTrackSubscriptionFailedEvent event) { +// print('ConferenceRoom._onAudioTrackSubscriptionFailed(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrackPublication.trackSid}'); +// _onExceptionStreamController.add( +// PlatformException( +// code: 'ConferenceRoom.audioTrackSubscriptionFailed', +// message: 'AudioTrack Subscription Failed', +// details: event.exception.toString(), +// ), +// ); +// } +// +// void _onAudioTrackUnpublished(RemoteAudioTrackEvent event) { +// print('ConferenceRoom._onAudioTrackUnpublished(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrackPublication.trackSid}'); +// } +// +// void _onAudioTrackUnsubscribed(RemoteAudioTrackSubscriptionEvent event) { +// print('ConferenceRoom._onAudioTrackUnsubscribed(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrack.sid}'); +// } +// +// void _onDataTrackPublished(RemoteDataTrackEvent event) { +// print('ConferenceRoom._onDataTrackPublished(), ${event.remoteParticipant.sid}}'); +// } +// +// void _onDataTrackSubscribed(RemoteDataTrackSubscriptionEvent event) { +// print('ConferenceRoom._onDataTrackSubscribed(), ${event.remoteParticipant.sid}, ${event.remoteDataTrackPublication.trackSid}'); +// final dataTrack = event.remoteDataTrackPublication.remoteDataTrack; +// _dataTracks.add(dataTrack); +// _streamSubscriptions.add(dataTrack.onMessage.listen(_onMessage)); +// _streamSubscriptions.add(dataTrack.onBufferMessage.listen(_onBufferMessage)); +// } +// +// void _onDataTrackSubscriptionFailed(RemoteDataTrackSubscriptionFailedEvent event) { +// print('ConferenceRoom._onDataTrackSubscriptionFailed(), ${event.remoteParticipant.sid}, ${event.remoteDataTrackPublication.trackSid}'); +// _onExceptionStreamController.add( +// PlatformException( +// code: 'ConferenceRoom.dataTrackSubscriptionFailed', +// message: 'DataTrack Subscription Failed', +// details: event.exception.toString(), +// ), +// ); +// } +// +// void _onDataTrackUnpublished(RemoteDataTrackEvent event) { +// print('ConferenceRoom._onDataTrackUnpublished(), ${event.remoteParticipant.sid}, ${event.remoteDataTrackPublication.trackSid}'); +// } +// +// void _onDataTrackUnsubscribed(RemoteDataTrackSubscriptionEvent event) { +// print('ConferenceRoom._onDataTrackUnsubscribed(), ${event.remoteParticipant.sid}, ${event.remoteDataTrack.sid}'); +// } +// +// void _onVideoTrackDisabled(RemoteVideoTrackEvent event) { +// print('ConferenceRoom._onVideoTrackDisabled(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrackPublication.trackSid}, isEnabled: ${event.remoteVideoTrackPublication.isTrackEnabled}'); +// _setRemoteVideoEnabled(event); +// } +// +// void _onVideoTrackEnabled(RemoteVideoTrackEvent event) { +// print('ConferenceRoom._onVideoTrackEnabled(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrackPublication.trackSid}, isEnabled: ${event.remoteVideoTrackPublication.isTrackEnabled}'); +// _setRemoteVideoEnabled(event); +// } +// +// void _onVideoTrackPublished(RemoteVideoTrackEvent event) { +// print('ConferenceRoom._onVideoTrackPublished(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrackPublication.trackSid}'); +// } +// +// void _onVideoTrackSubscribed(RemoteVideoTrackSubscriptionEvent event) { +// print('ConferenceRoom._onVideoTrackSubscribed(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrack.sid}'); +// _addOrUpdateParticipant(event); +// } +// +// void _onVideoTrackSubscriptionFailed(RemoteVideoTrackSubscriptionFailedEvent event) { +// print('ConferenceRoom._onVideoTrackSubscriptionFailed(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrackPublication.trackSid}'); +// _onExceptionStreamController.add( +// PlatformException( +// code: 'ConferenceRoom.videoTrackSubscriptionFailed', +// message: 'VideoTrack Subscription Failed', +// details: event.exception.toString(), +// ), +// ); +// } +// +// void _onVideoTrackUnpublished(RemoteVideoTrackEvent event) { +// print('ConferenceRoom._onVideoTrackUnpublished(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrackPublication.trackSid}'); +// } +// +// void _onVideoTrackUnsubscribed(RemoteVideoTrackSubscriptionEvent event) { +// print('ConferenceRoom._onVideoTrackUnsubscribed(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrack.sid}'); +// } +// +// void _onMessage(RemoteDataTrackStringMessageEvent event) { +// print('onMessage => ${event.remoteDataTrack.sid}, ${event.message}'); +// } +// +// void _onBufferMessage(RemoteDataTrackBufferMessageEvent event) { +// print('onBufferMessage => ${event.remoteDataTrack.sid}, ${String.fromCharCodes(event.message.asUint8List())}'); +// } +// +// void _setRemoteAudioEnabled(RemoteAudioTrackEvent event) { +// if (event.remoteAudioTrackPublication == null) { +// return; +// } +// var index = _participants.indexWhere((ParticipantWidget participant) => participant.id == event.remoteParticipant.sid); +// if (index < 0) { +// return; +// } +// var participant = _participants[index]; +// _participants.replaceRange( +// index, +// index + 1, +// [ +// participant.copyWith(audioEnabled: event.remoteAudioTrackPublication.isTrackEnabled), +// ], +// ); +// notifyListeners(); +// } +// +// void _setRemoteVideoEnabled(RemoteVideoTrackEvent event) { +// if (event.remoteVideoTrackPublication == null) { +// return; +// } +// var index = _participants.indexWhere((ParticipantWidget participant) => participant.id == event.remoteParticipant.sid); +// if (index < 0) { +// return; +// } +// var participant = _participants[index]; +// _participants.replaceRange( +// index, +// index + 1, +// [ +// participant.copyWith(videoEnabled: event.remoteVideoTrackPublication.isTrackEnabled), +// ], +// ); +// notifyListeners(); +// } +// +// void _addOrUpdateParticipant(RemoteParticipantEvent event) { +// print('ConferenceRoom._addOrUpdateParticipant(), ${event.remoteParticipant.sid}'); +// final participant = _participants.firstWhere( +// (ParticipantWidget participant) => participant.id == event.remoteParticipant.sid, +// orElse: () => null, +// ); +// if (participant != null) { +// print('Participant found: ${participant.id}, updating A/V enabled values'); +// _setRemoteVideoEnabled(event); +// _setRemoteAudioEnabled(event); +// } else { +// final bufferedParticipant = _participantBuffer.firstWhere( +// (ParticipantBuffer participant) => participant.id == event.remoteParticipant.sid, +// orElse: () => null, +// ); +// if (bufferedParticipant != null) { +// _participantBuffer.remove(bufferedParticipant); +// } else if (event is RemoteAudioTrackEvent) { +// print('Audio subscription came first, waiting for the video subscription...'); +// _participantBuffer.add( +// ParticipantBuffer( +// id: event.remoteParticipant.sid, +// audioEnabled: event.remoteAudioTrackPublication?.remoteAudioTrack?.isEnabled ?? true, +// ), +// ); +// return; +// } +// if (event is RemoteVideoTrackSubscriptionEvent) { +// print('New participant, adding: ${event.remoteParticipant.sid}'); +// _participants.insert( +// 0, +// _buildParticipant( +// child: event.remoteVideoTrack.widget(), +// id: event.remoteParticipant.sid, +// remoteParticipant: event.remoteParticipant, +// audioEnabled: bufferedParticipant?.audioEnabled ?? true, +// videoEnabled: event.remoteVideoTrackPublication?.remoteVideoTrack?.isEnabled ?? true, +// ), +// ); +// } +// notifyListeners(); +// } +// } +// } diff --git a/lib/pages/conference/draggable_publisher.dart b/lib/pages/conference/draggable_publisher.dart index a1a0b142..94c15af9 100644 --- a/lib/pages/conference/draggable_publisher.dart +++ b/lib/pages/conference/draggable_publisher.dart @@ -12,11 +12,11 @@ class DraggablePublisher extends StatefulWidget { final Stream onButtonBarHeight; const DraggablePublisher({ - Key key, - @required this.availableScreenSize, - this.child, - @required this.onButtonBarVisible, - @required this.onButtonBarHeight, + Key? key, + required this.availableScreenSize, + required this.child, + required this.onButtonBarVisible, + required this.onButtonBarHeight, /// The portion of the screen the DraggableWidget should use. this.scaleFactor = .25, @@ -33,18 +33,18 @@ class DraggablePublisher extends StatefulWidget { class _DraggablePublisherState extends State { bool _isButtonBarVisible = true; double _buttonBarHeight = 0; - double _width; - double _height; - double _top; - double _left; - double _viewPaddingTop; - double _viewPaddingBottom; + late double _width; + late double _height; + late double _top; + late double _left; + late double _viewPaddingTop; + late double _viewPaddingBottom; final double _padding = 8.0; final Duration _duration300ms = const Duration(milliseconds: 300); final Duration _duration0ms = const Duration(milliseconds: 0); - Duration _duration; - StreamSubscription _streamSubscription; - StreamSubscription _streamHeightSubscription; + late Duration _duration; + late StreamSubscription _streamSubscription; + late StreamSubscription _streamHeightSubscription; @override void initState() { diff --git a/lib/pages/conference/participant_widget.dart b/lib/pages/conference/participant_widget.dart index 5b8d1ff2..b9bfafcf 100644 --- a/lib/pages/conference/participant_widget.dart +++ b/lib/pages/conference/participant_widget.dart @@ -7,8 +7,8 @@ class ParticipantBuffer { final String id; ParticipantBuffer({ - @required this.audioEnabled, - @required this.id, + required this.audioEnabled, + required this.id, }) : assert(audioEnabled != null), assert(id != null); } @@ -23,12 +23,12 @@ class ParticipantWidget extends StatelessWidget { final bool isDominant; const ParticipantWidget({ - Key key, - @required this.child, - @required this.audioEnabled, - @required this.videoEnabled, - @required this.id, - @required this.isRemote, + Key? key, + required this.child, + required this.audioEnabled, + required this.videoEnabled, + required this.id, + required this.isRemote, this.isDominant = false, this.isDummy = false, }) : assert(child != null), @@ -40,10 +40,10 @@ class ParticipantWidget extends StatelessWidget { super(key: key); ParticipantWidget copyWith({ - Widget child, - bool audioEnabled, - bool videoEnabled, - bool isDominant, + Widget? child, + bool? audioEnabled, + bool? videoEnabled, + bool? isDominant, }) { return ParticipantWidget( id: id, diff --git a/lib/pages/conference/web_rtc/call_home_page.dart b/lib/pages/conference/web_rtc/call_home_page.dart new file mode 100644 index 00000000..dd841a6c --- /dev/null +++ b/lib/pages/conference/web_rtc/call_home_page.dart @@ -0,0 +1,61 @@ +// import 'dart:async'; +// +// import 'package:diplomaticquarterapp/pages/conference/web_rtc/widgets/cam_view_widget.dart'; +// import 'package:diplomaticquarterapp/pages/conference/widgets/noise_box.dart'; +// import 'package:diplomaticquarterapp/pages/webRTC/signaling.dart'; +// import 'package:flutter/material.dart'; +// import 'package:flutter/services.dart'; +// // import 'package:flutter_webrtc/flutter_webrtc.dart'; +// +// import '../conference_button_bar.dart'; +// +// class CallHomePage extends StatefulWidget { +// final String receiverId; +// final String callerId; +// +// const CallHomePage({Key key, this.receiverId, this.callerId}) : super(key: key); +// +// @override +// _CallHomePageState createState() => _CallHomePageState(); +// } +// +// class _CallHomePageState extends State { +// bool showNoise = false; +// // RTCVideoRenderer _localRenderer = RTCVideoRenderer(); +// // RTCVideoRenderer _remoteRenderer = RTCVideoRenderer(); +// +// final StreamController _audioButton = StreamController.broadcast(); +// final StreamController _videoButton = StreamController.broadcast(); +// final StreamController _onButtonBarVisibleStreamController = StreamController.broadcast(); +// final StreamController _onButtonBarHeightStreamController = StreamController.broadcast(); +// +// //Stream to enable video +// // MediaStream localMediaStream; +// // MediaStream remoteMediaStream; +// Signaling signaling = Signaling()..init(); +// +// @override +// void initState() { +// // TODO: implement initState +// super.initState(); +// startCall(); +// } +// +// startCall() async{ +// // await _localRenderer.initialize(); +// // await _remoteRenderer.initialize(); +// } +// +// Future _disposeStreamsAndSubscriptions() async { +// if (_onButtonBarVisibleStreamController != null) await _onButtonBarVisibleStreamController.close(); +// if (_onButtonBarHeightStreamController != null) await _onButtonBarHeightStreamController.close(); +// } +// +// @override +// Widget build(BuildContext context) { +// return Scaffold( +// backgroundColor: Colors.white, +// body: Container() //showNoise ? _buildNoiseBox() : buildLayout(), +// ); +// } +// } diff --git a/lib/pages/conference/web_rtc/call_home_page_.dart b/lib/pages/conference/web_rtc/call_home_page_.dart new file mode 100644 index 00000000..13dbfb35 --- /dev/null +++ b/lib/pages/conference/web_rtc/call_home_page_.dart @@ -0,0 +1,204 @@ +// import 'dart:async'; +// import 'dart:convert'; +// +// import 'package:diplomaticquarterapp/pages/conference/web_rtc/widgets/cam_view_widget.dart'; +// import 'package:diplomaticquarterapp/pages/conference/widgets/noise_box.dart'; +// import 'package:diplomaticquarterapp/pages/webRTC/signaling.dart'; +// import 'package:flutter/material.dart'; +// import 'package:flutter/services.dart'; +// import 'package:flutter_webrtc/flutter_webrtc.dart'; +// +// import '../conference_button_bar.dart'; +// +// class CallHomePage extends StatefulWidget { +// final String receiverId; +// final String callerId; +// +// const CallHomePage({Key key, this.receiverId, this.callerId}) : super(key: key); +// +// @override +// _CallHomePageState createState() => _CallHomePageState(); +// } +// +// class _CallHomePageState extends State { +// bool showNoise = true; +// RTCVideoRenderer _localRenderer = RTCVideoRenderer(); +// RTCVideoRenderer _remoteRenderer = RTCVideoRenderer(); +// +// final StreamController _audioButton = StreamController.broadcast(); +// final StreamController _videoButton = StreamController.broadcast(); +// final StreamController _onButtonBarVisibleStreamController = StreamController.broadcast(); +// final StreamController _onButtonBarHeightStreamController = StreamController.broadcast(); +// +// //Stream to enable video +// MediaStream localMediaStream; +// MediaStream remoteMediaStream; +// Signaling signaling = Signaling(); +// +// @override +// void initState() { +// // TODO: implement initState +// super.initState(); +// startCall(); +// } +// +// startCall() async{ +// await _localRenderer.initialize(); +// await _remoteRenderer.initialize(); +// await signaling.init(); +// final connected = await receivedCall(); +// } +// +// +// Future receivedCall() async { +// //Stream local media +// localMediaStream = await navigator.mediaDevices.getUserMedia({'video': true, 'audio': true}); +// _localRenderer.srcObject = localMediaStream; +// +// final connected = await signaling.acceptCall(widget.callerId, widget.receiverId, localMediaStream: localMediaStream, +// onRemoteMediaStream: (remoteMediaStream){ +// +// // print(remoteMediaStream.toString()); +// // print(json.encode(remoteMediaStream.getTracks().asMap())); +// this.remoteMediaStream = remoteMediaStream; +// _remoteRenderer.srcObject = remoteMediaStream; +// _remoteRenderer.addListener(() { +// print('_remoteRenderer'); +// print(_remoteRenderer); +// setState(() {}); +// }); +// }, +// onRemoteTrack: (track){ +// _remoteRenderer.srcObject.addTrack(track.track); +// // setState(() { +// // }); +// +// print(track.streams.first.getVideoTracks()); +// print(track.streams.first.getAudioTracks()); +// print(json.encode(track.streams.asMap())); +// } +// ); +// +// if(connected){ +// signaling.signalR.listen( +// onAcceptCall: (arg0){ +// print(arg0.toString()); +// }, +// onCandidate: (candidateJson){ +// signaling.addCandidate(candidateJson); +// }, +// onDeclineCall: (arg0,arg1){ +// // _onHangup(); +// }, +// onHangupCall: (arg0){ +// // _onHangup(); +// }, +// +// onOffer: (offerSdp, callerUser) async{ +// print('${offerSdp.toString()} | ${callerUser.toString()}'); +// await signaling.answerOffer(offerSdp); +// } +// ); +// } +// return connected; +// } +// +// @override +// void dispose() { +// // TODO: implement dispose +// super.dispose(); +// signaling.dispose(); +// _localRenderer?.dispose(); +// _remoteRenderer?.dispose(); +// _audioButton?.close(); +// _videoButton?.close(); +// localMediaStream?.dispose(); +// remoteMediaStream?.dispose(); +// _disposeStreamsAndSubscriptions(); +// } +// +// Future _disposeStreamsAndSubscriptions() async { +// if (_onButtonBarVisibleStreamController != null) await _onButtonBarVisibleStreamController.close(); +// if (_onButtonBarHeightStreamController != null) await _onButtonBarHeightStreamController.close(); +// } +// +// @override +// Widget build(BuildContext context) { +// return Scaffold( +// backgroundColor: Colors.white, +// body: buildLayout(), +// ); +// } +// +// LayoutBuilder buildLayout() { +// return LayoutBuilder( +// builder: (BuildContext context, BoxConstraints constraints) { +// return Stack( +// children: [ +// CamViewWidget( +// localRenderer: _localRenderer, +// remoteRenderer: _remoteRenderer, +// constraints: constraints, +// onButtonBarVisibleStreamController: _onButtonBarVisibleStreamController, +// onButtonBarHeightStreamController: _onButtonBarHeightStreamController, +// ), +// ConferenceButtonBar( +// audioEnabled: _audioButton.stream, +// videoEnabled: _videoButton.stream, +// onAudioEnabled: _onAudioEnable, +// onVideoEnabled: _onVideoEnabled, +// onSwitchCamera: _onSwitchCamera, +// onHangup: _onHangup, +// onPersonAdd: () {}, +// onPersonRemove: () {}, +// onHeight: _onHeightBar, +// onShow: _onShowBar, +// onHide: _onHideBar, +// ), +// ], +// ); +// }, +// ); +// } +// +// Function _onAudioEnable() { +// final audioTrack = localMediaStream.getAudioTracks()[0]; +// final mute = audioTrack.muted; +// Helper.setMicrophoneMute(!mute, audioTrack); +// _audioButton.add(mute); +// } +// +// Function _onVideoEnabled() { +// final videoTrack = localMediaStream.getVideoTracks()[0]; +// bool videoEnabled = videoTrack.enabled; +// localMediaStream.getVideoTracks()[0].enabled = !videoEnabled; +// _videoButton.add(!videoEnabled); +// } +// +// Function _onSwitchCamera() { +// Helper.switchCamera(localMediaStream.getVideoTracks()[0]); +// } +// +// void _onShowBar() { +// setState(() { +// }); +// _onButtonBarVisibleStreamController.add(true); +// } +// +// void _onHeightBar(double height) { +// _onButtonBarHeightStreamController.add(height); +// } +// +// void _onHideBar() { +// setState(() { +// SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.bottom]); +// }); +// _onButtonBarVisibleStreamController.add(false); +// } +// +// Future _onHangup() async { +// signaling.hangupCall(widget.callerId, widget.receiverId); +// print('onHangup'); +// Navigator.of(context).pop(); +// } +// } diff --git a/lib/pages/conference/web_rtc/widgets/cam_view_widget.dart b/lib/pages/conference/web_rtc/widgets/cam_view_widget.dart new file mode 100644 index 00000000..d9d030a7 --- /dev/null +++ b/lib/pages/conference/web_rtc/widgets/cam_view_widget.dart @@ -0,0 +1,82 @@ +// import 'dart:async'; +// import 'dart:core'; +// +// import 'package:diplomaticquarterapp/pages/conference/widgets/noise_box.dart'; +// import 'package:flutter/material.dart'; +// import 'package:flutter_webrtc/flutter_webrtc.dart'; +// +// import 'draggable_cam.dart'; +// +// class CamViewWidget extends StatefulWidget { +// RTCVideoRenderer? localRenderer; +// RTCVideoRenderer? remoteRenderer; +// MediaStream? localStream; +// BoxConstraints? constraints; +// StreamController? onButtonBarVisibleStreamController; +// StreamController? onButtonBarHeightStreamController; +// +// CamViewWidget({this.localRenderer, this.remoteRenderer, this.constraints, this.onButtonBarVisibleStreamController, this.onButtonBarHeightStreamController}); +// +// @override +// _CamViewWidgetState createState() => _CamViewWidgetState(); +// } +// +// class _CamViewWidgetState extends State { +// @override +// void initState() { +// super.initState(); +// } +// +// @override +// Widget build(BuildContext context) { +// return Container( +// width: double.infinity, +// height: double.infinity, +// child: Stack( +// children: [ +// FractionallySizedBox( +// heightFactor: 1, widthFactor: 1, +// child: Container( +// color: Colors.black87, +// // child: RTCVideoView(widget.remoteRenderer!, mirror: true,filterQuality: FilterQuality.medium,), +// ), +// ), +// +// if(widget.remoteRenderer!.srcObject == null) +// Positioned.fill(child: _buildNoiseBox()), +// +// // Positioned.fill( +// // child: RTCVideoView(widget.remoteRenderer!) +// // ), +// +// // DraggableCam( +// // key: Key('publisher'), +// // onButtonBarHeight: widget.onButtonBarHeightStreamController!.stream, +// // onButtonBarVisible: widget.onButtonBarVisibleStreamController!.stream, +// // availableScreenSize: widget.constraints!.biggest, +// // child: RTCVideoView(widget.localRenderer!) +// // ), +// +// if(widget.remoteRenderer!.srcObject == null) +// Container( +// margin: EdgeInsets.all(MediaQuery.of(context).size.width/8), +// child: Text( +// 'Waiting for another participant to connect to the call...', +// key: Key('text-wait'), +// textAlign: TextAlign.center, +// style: TextStyle(color: Colors.white), +// ) +// ), +// ], +// ), +// ); +// } +// +// +// Widget _buildNoiseBox() { +// return NoiseBox( +// density: NoiseBoxDensity.xHigh, +// backgroundColor: Colors.grey.shade900, +// ); +// } +// } diff --git a/lib/pages/conference/web_rtc/widgets/draggable_cam.dart b/lib/pages/conference/web_rtc/widgets/draggable_cam.dart new file mode 100644 index 00000000..2fef0dad --- /dev/null +++ b/lib/pages/conference/web_rtc/widgets/draggable_cam.dart @@ -0,0 +1,173 @@ +import 'dart:async'; +import 'dart:io'; + +import 'package:diplomaticquarterapp/pages/conference/clipped_video.dart'; +import 'package:flutter/material.dart'; + +class DraggableCam extends StatefulWidget { + final Size availableScreenSize; + final Widget child; + final double scaleFactor; + final Stream onButtonBarVisible; + final Stream onButtonBarHeight; + + const DraggableCam({ + Key? key, + required this.availableScreenSize, + required this.child, + required this.onButtonBarVisible, + required this.onButtonBarHeight, + + /// The portion of the screen the DraggableWidget should use. + this.scaleFactor = .25, + }) : assert(scaleFactor != null && scaleFactor > 0 && scaleFactor <= .4), + assert(availableScreenSize != null), + assert(onButtonBarVisible != null), + assert(onButtonBarHeight != null), + super(key: key); + + @override + _DraggablePublisherState createState() => _DraggablePublisherState(); +} + +class _DraggablePublisherState extends State { + bool _isButtonBarVisible = true; + double _buttonBarHeight = 0; + double? _width; + double? _height; + double? _top; + double? _left; + double? _viewPaddingTop; + double? _viewPaddingBottom; + final double _padding = 8.0; + final Duration _duration300ms = const Duration(milliseconds: 300); + final Duration _duration0ms = const Duration(milliseconds: 0); + Duration? _duration; + StreamSubscription? _streamSubscription; + StreamSubscription? _streamHeightSubscription; + + @override + void initState() { + super.initState(); + _duration = _duration300ms; + _width = widget.availableScreenSize.width * widget.scaleFactor; + _height = _width! * (widget.availableScreenSize.height / widget.availableScreenSize.width); + _top = widget.availableScreenSize.height - (_buttonBarHeight + _padding) - _height!; + _left = widget.availableScreenSize.width - _padding - _width!; + + _streamSubscription = widget.onButtonBarVisible.listen(_buttonBarVisible); + _streamHeightSubscription = widget.onButtonBarHeight.listen(_getButtonBarHeight); + } + + @override + void didChangeDependencies() { + final mediaQuery = MediaQuery.of(context); + _viewPaddingTop = mediaQuery.viewPadding.top; + _viewPaddingBottom = mediaQuery.viewPadding.bottom; + super.didChangeDependencies(); + } + + @override + void dispose() { + _streamSubscription!.cancel(); + _streamHeightSubscription!.cancel(); + super.dispose(); + } + + void _getButtonBarHeight(double height) { + setState(() { + _buttonBarHeight = height; + _positionWidget(); + }); + } + + void _buttonBarVisible(bool visible) { + if (!mounted) { + return; + } + setState(() { + _isButtonBarVisible = visible; + if (_duration == _duration300ms) { + // only position the widget when we are not currently dragging it around + _positionWidget(); + } + }); + } + + @override + Widget build(BuildContext context) { + return AnimatedPositioned( + top: _top, + left: _left, + width: _width, + height: _height, + duration: _duration!, + child: Listener( + onPointerDown: (_) => _duration = _duration0ms, + onPointerMove: (PointerMoveEvent event) { + setState(() { + _left = (_left! + event.delta.dx).roundToDouble(); + _top = (_top! + event.delta.dy).roundToDouble(); + }); + }, + onPointerUp: (_) => _positionWidget(), + onPointerCancel: (_) => _positionWidget(), + child: ClippedVideo( + height: _height!, + width: _width!, + child: widget.child, + ), + ), + ); + } + + double _getCurrentStatusBarHeight() { + if (_isButtonBarVisible) { + return _viewPaddingTop!; + } + final _defaultViewPaddingTop = Platform.isIOS ? 20.0 : Platform.isAndroid ? 24.0 : 0.0; + if (_viewPaddingTop! > _defaultViewPaddingTop) { + // There must be a hardware notch in the display. + return _viewPaddingTop!; + } + return 0.0; + } + + double _getCurrentButtonBarHeight() { + if (_isButtonBarVisible) { + return _buttonBarHeight + _viewPaddingBottom!; + } + return _viewPaddingBottom!; + } + + void _positionWidget() { + // Determine the center of the object being dragged so we can decide + // in which corner the object should be placed. + var dx = (_width! / 2) + _left!; + dx = dx < 0 ? 0 : dx >= widget.availableScreenSize.width ? widget.availableScreenSize.width - 1 : dx; + var dy = (_height! / 2) + _top!; + dy = dy < 0 ? 0 : dy >= widget.availableScreenSize.height ? widget.availableScreenSize.height - 1 : dy; + final draggableCenter = Offset(dx, dy); + + setState(() { + _duration = _duration300ms; + if (Rect.fromLTRB(0, 0, widget.availableScreenSize.width / 2, widget.availableScreenSize.height / 2).contains(draggableCenter)) { + // Top-left + _top = _getCurrentStatusBarHeight() + _padding; + _left = _padding; + } else if (Rect.fromLTRB(widget.availableScreenSize.width / 2, 0, widget.availableScreenSize.width, widget.availableScreenSize.height / 2).contains(draggableCenter)) { + // Top-right + _top = _getCurrentStatusBarHeight() + _padding; + _left = widget.availableScreenSize.width - _padding - _width!; + } else if (Rect.fromLTRB(0, widget.availableScreenSize.height / 2, widget.availableScreenSize.width / 2, widget.availableScreenSize.height).contains(draggableCenter)) { + // Bottom-left + _top = widget.availableScreenSize.height - (_getCurrentButtonBarHeight() + _padding) - _height!; + _left = _padding; + } else if (Rect.fromLTRB(widget.availableScreenSize.width / 2, widget.availableScreenSize.height / 2, widget.availableScreenSize.width, widget.availableScreenSize.height).contains(draggableCenter)) { + // Bottom-right + _top = widget.availableScreenSize.height - (_getCurrentButtonBarHeight() + _padding) - _height!; + _left = widget.availableScreenSize.width - _padding - _width!; + } + }); + } +} diff --git a/lib/pages/conference/widgets/button_to_progress.dart b/lib/pages/conference/widgets/button_to_progress.dart index 2879dc60..da7850c2 100644 --- a/lib/pages/conference/widgets/button_to_progress.dart +++ b/lib/pages/conference/widgets/button_to_progress.dart @@ -6,15 +6,15 @@ import 'package:flutter/material.dart'; class ButtonToProgress extends StatefulWidget { final double height; final double progressHeight; - final String loadingText; + final String? loadingText; final Duration duration; - final TextStyle loadingTextStyle; - final VoidCallback onPressed; - final Stream onLoading; + final TextStyle? loadingTextStyle; + final VoidCallback? onPressed; + final Stream? onLoading; final Widget child; const ButtonToProgress({ - Key key, + Key? key, this.height = 40.0, this.progressHeight = 5.0, this.loadingText, @@ -22,7 +22,7 @@ class ButtonToProgress extends StatefulWidget { this.loadingTextStyle, this.onPressed, this.onLoading, - @required this.child, + required this.child, }) : assert(child != null), assert(height != null && height > 0), assert(progressHeight != null && progressHeight > 0 && progressHeight <= height), @@ -33,18 +33,18 @@ class ButtonToProgress extends StatefulWidget { } class _ButtonToProgressState extends State { - double _height; + double? _height; double _opacity = 0; bool _isLoading = false; - StreamSubscription _subscription; + StreamSubscription? _subscription; @override void initState() { super.initState(); _height = widget.height; if (widget.onLoading != null) { - _subscription = widget.onLoading.listen((bool isLoading) { + _subscription = widget.onLoading!.listen((bool isLoading) { setState(() { _isLoading = isLoading; _height = isLoading ? widget.progressHeight : widget.height; @@ -57,7 +57,7 @@ class _ButtonToProgressState extends State { @override void dispose() { if (_subscription != null) { - _subscription.cancel(); + _subscription!.cancel(); } super.dispose(); } @@ -77,7 +77,7 @@ class _ButtonToProgressState extends State { child: Center( child: FittedBox( child: Text( - widget.loadingText, + widget.loadingText!, style: widget.loadingTextStyle, ), ), @@ -90,7 +90,7 @@ class _ButtonToProgressState extends State { AnimatedPadding( duration: widget.duration, padding: EdgeInsets.only( - top: math.max(widget.height - _height, 0), + top: math.max(widget.height - _height!, 0), ), child: AnimatedContainer( duration: widget.duration, diff --git a/lib/pages/conference/widgets/circle_button.dart b/lib/pages/conference/widgets/circle_button.dart index 37702c29..b49c1e70 100644 --- a/lib/pages/conference/widgets/circle_button.dart +++ b/lib/pages/conference/widgets/circle_button.dart @@ -4,16 +4,16 @@ import 'package:flutter/material.dart'; import 'package:native_device_orientation/native_device_orientation.dart'; class CircleButton extends StatefulWidget { - final VoidCallback onLongPress; - final VoidCallback onPressed; - final GestureTapDownCallback onTapDown; - final VoidCallback onTapCancel; - final Widget child; - final Color color; - final double radius; + final VoidCallback? onLongPress; + final VoidCallback? onPressed; + final GestureTapDownCallback? onTapDown; + final VoidCallback? onTapCancel; + final Widget? child; + final Color? color; + final double? radius; const CircleButton({ - Key key, + Key? key, this.onLongPress, this.onPressed, this.child, @@ -32,7 +32,7 @@ class _CircleButtonState extends State { double _rotationAngle = 0.0; final Stream _orientationStream = NativeDeviceOrientationCommunicator().onOrientationChanged(useSensor: true); - StreamSubscription _orientationSubscription; + late StreamSubscription _orientationSubscription; void _handleOrientationChange(NativeDeviceOrientation orientation) { var targetAngle = 0.0; @@ -73,7 +73,7 @@ class _CircleButtonState extends State { @override Widget build(BuildContext context) { - final size = 2 * widget.radius; + final size = 2 * widget.radius!; return Container( width: size, @@ -81,7 +81,7 @@ class _CircleButtonState extends State { decoration: BoxDecoration( color: (widget.color ?? Colors.blue).withAlpha(200), borderRadius: BorderRadius.all( - Radius.circular(widget.radius), + Radius.circular(widget.radius!), ), ), child: GestureDetector( diff --git a/lib/pages/conference/widgets/noise_box.dart b/lib/pages/conference/widgets/noise_box.dart index 5087415f..6e46616e 100644 --- a/lib/pages/conference/widgets/noise_box.dart +++ b/lib/pages/conference/widgets/noise_box.dart @@ -1,5 +1,6 @@ import 'dart:math' as math; import 'dart:ui'; + import 'package:flutter/material.dart'; enum NoiseBoxDensity { @@ -12,11 +13,11 @@ enum NoiseBoxDensity { class NoiseBox extends StatefulWidget { final NoiseBoxDensity density; - final Color backgroundColor; - final Widget child; + final Color? backgroundColor; + final Widget? child; const NoiseBox({ - Key key, + Key? key, this.backgroundColor, this.child, this.density = NoiseBoxDensity.medium, @@ -28,8 +29,8 @@ class NoiseBox extends StatefulWidget { } class _NoiseBoxState extends State with TickerProviderStateMixin { - AnimationController _animationController; - int _density; + late AnimationController _animationController; + late int _density; @override void initState() { @@ -73,7 +74,7 @@ class _NoiseBoxState extends State with TickerProviderStateMixin { height: constraints.biggest.height, child: AnimatedBuilder( animation: _animationController, - builder: (BuildContext context, Widget w) { + builder: (BuildContext context, Widget? w) { final children = [ CustomPaint( painter: NoisePainter( @@ -84,7 +85,7 @@ class _NoiseBoxState extends State with TickerProviderStateMixin { ), ]; if (widget.child != null) { - children.add(widget.child); + children.add(widget.child!); } return Stack( children: children, @@ -102,9 +103,9 @@ class NoisePainter extends CustomPainter { final int density; NoisePainter({ - @required this.width, - @required this.height, - @required this.density, + required this.width, + required this.height, + required this.density, }) : assert(width != null), assert(height != null), assert(density != null && diff --git a/lib/pages/conference/widgets/platform_alert_dialog.dart b/lib/pages/conference/widgets/platform_alert_dialog.dart index 1adaa223..c98450e5 100644 --- a/lib/pages/conference/widgets/platform_alert_dialog.dart +++ b/lib/pages/conference/widgets/platform_alert_dialog.dart @@ -1,12 +1,12 @@ import 'dart:io'; -import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; import './platform_widget.dart'; class PlatformAlertDialog extends PlatformWidget { - PlatformAlertDialog({@required this.title, @required this.content, @required this.defaultActionText, this.cancelActionText}) + PlatformAlertDialog({required this.title, required this.content, required this.defaultActionText, this.cancelActionText}) : assert(title != null), assert(content != null), assert(defaultActionText != null); @@ -14,9 +14,9 @@ class PlatformAlertDialog extends PlatformWidget { final String title; final String content; final String defaultActionText; - final String cancelActionText; + final String? cancelActionText; - Future show(BuildContext context) async { + Future show(BuildContext context) async { return Platform.isIOS ? await showCupertinoDialog( context: context, @@ -52,7 +52,7 @@ class PlatformAlertDialog extends PlatformWidget { if (cancelActionText != null) { actions.add( PlatformAlertDialogAction( - child: Text(cancelActionText), + child: Text(cancelActionText!), onPressed: () { Navigator.of(context).pop(false); }, @@ -73,8 +73,8 @@ class PlatformAlertDialog extends PlatformWidget { class PlatformAlertDialogAction extends PlatformWidget { PlatformAlertDialogAction({ - this.child, - this.onPressed, + required this.child, + required this.onPressed, }); final Widget child; @@ -90,7 +90,7 @@ class PlatformAlertDialogAction extends PlatformWidget { @override Widget buildMaterialWidget(BuildContext context) { - return FlatButton( + return TextButton( child: child, onPressed: onPressed, ); diff --git a/lib/pages/conference/widgets/platform_exception_alert_dialog.dart b/lib/pages/conference/widgets/platform_exception_alert_dialog.dart index 931a6e10..fea4bca9 100644 --- a/lib/pages/conference/widgets/platform_exception_alert_dialog.dart +++ b/lib/pages/conference/widgets/platform_exception_alert_dialog.dart @@ -1,11 +1,12 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; + import './platform_alert_dialog.dart'; class PlatformExceptionAlertDialog extends PlatformAlertDialog { PlatformExceptionAlertDialog({ String title = 'An error occurred', - @required Exception exception, + required Exception exception, }) : super( title: title, content: exception is PlatformException ? _message(exception) : exception.toString(), diff --git a/lib/pages/conference/widgets/platform_widget.dart b/lib/pages/conference/widgets/platform_widget.dart index 5773190f..d3366d5e 100644 --- a/lib/pages/conference/widgets/platform_widget.dart +++ b/lib/pages/conference/widgets/platform_widget.dart @@ -1,4 +1,5 @@ import 'dart:io'; + import 'package:flutter/material.dart'; abstract class PlatformWidget extends StatelessWidget { diff --git a/lib/pages/conference/widgets/responsive_save_area.dart b/lib/pages/conference/widgets/responsive_save_area.dart index f9a85467..9e38cbce 100644 --- a/lib/pages/conference/widgets/responsive_save_area.dart +++ b/lib/pages/conference/widgets/responsive_save_area.dart @@ -7,8 +7,8 @@ typedef ResponsiveBuilder = Widget Function( class ResponsiveSafeArea extends StatelessWidget { const ResponsiveSafeArea({ - @required ResponsiveBuilder builder, - Key key, + required ResponsiveBuilder builder, + Key? key, }) : responsiveBuilder = builder, assert(builder != null), super(key: key); diff --git a/lib/pages/conference/zoom/call_screen.dart b/lib/pages/conference/zoom/call_screen.dart new file mode 100644 index 00000000..1d71d72c --- /dev/null +++ b/lib/pages/conference/zoom/call_screen.dart @@ -0,0 +1,1609 @@ +import 'dart:async'; +import 'dart:convert'; +import 'dart:io'; +import 'package:diplomaticquarterapp/pages/conference/zoom/jwt.dart'; +import 'package:diplomaticquarterapp/pages/conference/zoom/video_view.dart'; +import 'package:events_emitter/events_emitter.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:flutter_zoom_videosdk/native/zoom_videosdk.dart'; +import 'package:flutter_zoom_videosdk/native/zoom_videosdk_cmd_channel.dart'; +import 'package:flutter_zoom_videosdk/native/zoom_videosdk_event_listener.dart'; +import 'package:flutter_zoom_videosdk/native/zoom_videosdk_live_transcription_message_info.dart'; +import 'package:flutter_zoom_videosdk/native/zoom_videosdk_user.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:wakelock_plus/wakelock_plus.dart'; + +// import '../components/video_view.dart'; +// import '../components/comment_list.dart'; +// import 'intro_screen.dart'; +// import 'join_screen.dart'; + +class CallScreen extends StatefulHookWidget { + const CallScreen({Key? key}) : super(key: key); + + @override + State createState() => _CallScreenState(); +} + +class _CallScreenState extends State { + static TextEditingController changeNameController = TextEditingController(); + double opacityLevel = 1.0; + + String currentCameraDeviceId = "1"; + + void _changeOpacity() { + setState(() => opacityLevel = opacityLevel == 0 ? 1.0 : 0.0); + } + + @override + Widget build(BuildContext context) { + var zoom = ZoomVideoSdk(); + var eventListener = ZoomVideoSdkEventListener(); + var isInSession = useState(false); + var sessionName = useState(''); + var sessionPassword = useState(''); + var users = useState([]); + var fullScreenUser = useState(null); + var sharingUser = useState(null); + var videoInfo = useState(''); + var isSharing = useState(false); + var isMuted = useState(false); + var isVideoOn = useState(false); + var isSpeakerOn = useState(false); + var isRenameModalVisible = useState(false); + var isRecordingStarted = useState(false); + var isMicOriginalOn = useState(false); + var isMounted = useIsMounted(); + var audioStatusFlag = useState(false); + var videoStatusFlag = useState(false); + var userNameFlag = useState(false); + var userShareStatusFlag = useState(false); + var isReceiveSpokenLanguageContentEnabled = useState(false); + var isVideoMirrored = useState(false); + var isOriginalAspectRatio = useState(false); + + //hide status bar + SystemChrome.setEnabledSystemUIMode(SystemUiMode.leanBack); + var circleButtonSize = 65.0; + Color backgroundColor = const Color(0xFF232323); + Color buttonBackgroundColor = const Color.fromRGBO(0, 0, 0, 0.6); + Color chatTextColor = const Color(0xFFAAAAAA); + Widget moreOptions; + final args = ModalRoute.of(context)!.settings.arguments as CallArguments; + + useEffect(() { + Future.microtask(() async { + WakelockPlus.enable(); + var token = generateJwt(args.sessionName, args.role); + try { + Map SDKaudioOptions = {"connect": true, "mute": false, "autoAdjustSpeakerVolume": false}; + Map SDKvideoOptions = { + "localVideoOn": args.callType == 1 ? true : false, + }; + JoinSessionConfig joinSession = JoinSessionConfig( + sessionName: args.sessionName, + sessionPassword: args.sessionPwd, + token: token, + userName: args.displayName, + audioOptions: SDKaudioOptions, + videoOptions: SDKvideoOptions, + sessionIdleTimeoutMins: int.parse(args.sessionIdleTimeoutMins), + ); + await zoom.joinSession(joinSession); + } catch (e) { + print(e); + const AlertDialog( + title: Text("Error"), + content: Text("Failed to join the session"), + ); + Future.delayed(const Duration(milliseconds: 1000)).asStream().listen((event) { + Navigator.pop(context); + // Navigator.popAndPushNamed( + // context, + // "Join", + // arguments: JoinArguments(args.isJoin, sessionName.value, sessionPassword.value, args.displayName, args.sessionIdleTimeoutMins, args.role), + // ); + }); + } + }); + return null; + }, []); + + useEffect(() { + updateVideoInfo() { + Timer timer = Timer.periodic(const Duration(milliseconds: 1000), (time) async { + if (!isMounted()) return; + + bool? videoOn = false; + videoOn = await fullScreenUser.value?.videoStatus?.isOn(); + + // Video statistic info doesn't update when there's no remote users + if (fullScreenUser.value == null || (videoOn != null && videoOn == false) || users.value.length < 2) { + time.cancel(); + videoInfo.value = ""; + return; + } + + var fps = isSharing.value ? await fullScreenUser.value?.shareStatisticInfo?.getFps() : await fullScreenUser.value?.videoStatisticInfo?.getFps(); + + var height = isSharing.value ? await fullScreenUser.value?.shareStatisticInfo?.getHeight() : await fullScreenUser.value?.videoStatisticInfo?.getHeight(); + + var width = isSharing.value ? await fullScreenUser.value?.shareStatisticInfo?.getWidth() : await fullScreenUser.value?.videoStatisticInfo?.getWidth(); + + videoInfo.value = ("${width}x$height ${fps}FPS"); + }); + } + + updateVideoInfo(); + return null; + }); + + useEffect(() { + eventListener.addEventListener(); + EventEmitter emitter = eventListener.eventEmitter; + + final sessionJoinListener = emitter.on(EventType.onSessionJoin, (sessionUser) async { + isInSession.value = true; + zoom.session.getSessionName().then((value) => sessionName.value = value!); + sessionPassword.value = await zoom.session.getSessionPassword(); + ZoomVideoSdkUser mySelf = ZoomVideoSdkUser.fromJson(jsonDecode(sessionUser.toString())); + List? remoteUsers = await zoom.session.getRemoteUsers(); + var muted = await mySelf.audioStatus?.isMuted(); + var videoOn = await mySelf.videoStatus?.isOn(); + var speakerOn = await zoom.audioHelper.getSpeakerStatus(); + // fullScreenUser.value = mySelf; + fullScreenUser.value = remoteUsers!.isNotEmpty ? remoteUsers![0] : mySelf; + remoteUsers?.insert(0, mySelf); + users.value = remoteUsers!; + isMuted.value = muted!; + isSpeakerOn.value = speakerOn; + isVideoOn.value = videoOn!; + users.value = remoteUsers; + isReceiveSpokenLanguageContentEnabled.value = await zoom.liveTranscriptionHelper.isReceiveSpokenLanguageContentEnabled(); + }); + + final sessionLeaveListener = emitter.on(EventType.onSessionLeave, (data) async { + isInSession.value = false; + users.value = []; + fullScreenUser.value = null; + await zoom.leaveSession(false); + Navigator.pop(context); + WakelockPlus.disable(); + }); + + final sessionNeedPasswordListener = emitter.on(EventType.onSessionNeedPassword, (data) async { + showDialog( + context: context, + builder: (BuildContext context) => AlertDialog( + title: const Text('Session Need Password'), + content: const Text('Password is required'), + actions: [ + TextButton( + onPressed: () async => { + // Navigator.popAndPushNamed(context, 'Join', arguments: JoinArguments(args.isJoin, args.sessionName, "", args.displayName, args.sessionIdleTimeoutMins, args.role)), + Navigator.pop(context), + await zoom.leaveSession(false), + }, + child: const Text('OK'), + ), + ], + ), + ); + }); + + final sessionPasswordWrongListener = emitter.on(EventType.onSessionPasswordWrong, (data) async { + showDialog( + context: context, + builder: (BuildContext context) => AlertDialog( + title: const Text('Session Password Incorrect'), + content: const Text('Password is wrong'), + actions: [ + TextButton( + onPressed: () async => { + // Navigator.popAndPushNamed(context, 'Join', arguments: JoinArguments(args.isJoin, args.sessionName, "", args.displayName, args.sessionIdleTimeoutMins, args.role)), + Navigator.pop(context), + await zoom.leaveSession(false), + }, + child: const Text('OK'), + ), + ], + ), + ); + }); + + final userVideoStatusChangedListener = emitter.on(EventType.onUserVideoStatusChanged, (data) async { + data = data as Map; + ZoomVideoSdkUser? mySelf = await zoom.session.getMySelf(); + var userListJson = jsonDecode(data['changedUsers']) as List; + List userList = userListJson.map((userJson) => ZoomVideoSdkUser.fromJson(userJson)).toList(); + for (var user in userList) { + { + if (user.userId == mySelf?.userId) { + mySelf?.videoStatus?.isOn().then((on) => isVideoOn.value = on); + } + } + } + videoStatusFlag.value = !videoStatusFlag.value; + }); + + final userAudioStatusChangedListener = emitter.on(EventType.onUserAudioStatusChanged, (data) async { + data = data as Map; + ZoomVideoSdkUser? mySelf = await zoom.session.getMySelf(); + var userListJson = jsonDecode(data['changedUsers']) as List; + List userList = userListJson.map((userJson) => ZoomVideoSdkUser.fromJson(userJson)).toList(); + for (var user in userList) { + { + if (user.userId == mySelf?.userId) { + mySelf?.audioStatus?.isMuted().then((muted) => isMuted.value = muted); + } + } + } + audioStatusFlag.value = !audioStatusFlag.value; + }); + + final userShareStatusChangeListener = emitter.on(EventType.onUserShareStatusChanged, (data) async { + data = data as Map; + ZoomVideoSdkUser? mySelf = await zoom.session.getMySelf(); + ZoomVideoSdkUser shareUser = ZoomVideoSdkUser.fromJson(jsonDecode(data['user'].toString())); + + if (data['status'] == ShareStatus.Start) { + sharingUser.value = shareUser; + fullScreenUser.value = shareUser; + isSharing.value = (shareUser.userId == mySelf?.userId); + } else { + sharingUser.value = null; + isSharing.value = false; + fullScreenUser.value = mySelf; + } + userShareStatusFlag.value = !userShareStatusFlag.value; + }); + + final userJoinListener = emitter.on(EventType.onUserJoin, (data) async { + if (!isMounted()) return; + data = data as Map; + ZoomVideoSdkUser? mySelf = await zoom.session.getMySelf(); + var userListJson = jsonDecode(data['remoteUsers']) as List; + List remoteUserList = userListJson.map((userJson) => ZoomVideoSdkUser.fromJson(userJson)).toList(); + remoteUserList.insert(0, mySelf!); + users.value = remoteUserList; + fullScreenUser.value = remoteUserList[1]; + }); + + final userLeaveListener = emitter.on(EventType.onUserLeave, (data) async { + if (!isMounted()) return; + ZoomVideoSdkUser? mySelf = await zoom.session.getMySelf(); + data = data as Map; + var remoteUserListJson = jsonDecode(data['remoteUsers']) as List; + List remoteUserList = remoteUserListJson.map((userJson) => ZoomVideoSdkUser.fromJson(userJson)).toList(); + var leftUserListJson = jsonDecode(data['leftUsers']) as List; + List leftUserLis = leftUserListJson.map((userJson) => ZoomVideoSdkUser.fromJson(userJson)).toList(); + if (fullScreenUser.value != null) { + for (var user in leftUserLis) { + { + if (fullScreenUser.value?.userId == user.userId) { + fullScreenUser.value = mySelf; + } + } + } + } else { + fullScreenUser.value = mySelf; + } + remoteUserList.add(mySelf!); + users.value = remoteUserList; + }); + + final userNameChangedListener = emitter.on(EventType.onUserNameChanged, (data) async { + if (!isMounted()) return; + data = data as Map; + ZoomVideoSdkUser? changedUser = ZoomVideoSdkUser.fromJson(jsonDecode(data['changedUser'])); + int index; + for (var user in users.value) { + if (user.userId == changedUser.userId) { + index = users.value.indexOf(user); + users.value[index] = changedUser; + } + } + userNameFlag.value = !userNameFlag.value; + }); + + final commandReceived = emitter.on(EventType.onCommandReceived, (data) async { + data = data as Map; + debugPrint("sender: ${ZoomVideoSdkUser.fromJson(jsonDecode(data['sender']))}, command: ${data['command']}"); + }); + + final chatDeleteMessageNotify = emitter.on(EventType.onChatDeleteMessageNotify, (data) async { + data = data as Map; + debugPrint("onChatDeleteMessageNotify: messageID: ${data['msgID']}, deleteBy: ${data['type']}"); + }); + + final liveStreamStatusChangeListener = emitter.on(EventType.onLiveStreamStatusChanged, (data) async { + data = data as Map; + debugPrint("onLiveStreamStatusChanged: status: ${data['status']}"); + }); + + final liveTranscriptionStatusChangeListener = emitter.on(EventType.onLiveTranscriptionStatus, (data) async { + data = data as Map; + debugPrint("onLiveTranscriptionStatus: status: ${data['status']}"); + }); + + final cloudRecordingStatusListener = emitter.on(EventType.onCloudRecordingStatus, (data) async { + data = data as Map; + debugPrint("onCloudRecordingStatus: status: ${data['status']}"); + ZoomVideoSdkUser? mySelf = await zoom.session.getMySelf(); + if (data['status'] == RecordingStatus.Start) { + if (mySelf != null && !mySelf.isHost!) { + await zoom.acceptRecordingConsent(); + // isRecordingStarted.value = true; + // showDialog( + // context: context, + // builder: (BuildContext context) => AlertDialog( + // content: const Text('The session is being recorded.'), + // actions: [ + // TextButton( + // onPressed: () async { + // await zoom.acceptRecordingConsent(); + // // if (context.mounted) { + // Navigator.pop(context); + // // }; + // }, + // child: const Text('accept'), + // ), + // TextButton( + // onPressed: () async { + // String currentConsentType = await zoom.getRecordingConsentType(); + // if (currentConsentType == ConsentType.ConsentType_Individual) { + // await zoom.declineRecordingConsent(); + // Navigator.pop(context); + // } else { + // await zoom.declineRecordingConsent(); + // zoom.leaveSession(false); + // // if (!context.mounted) return; + // // Navigator.popAndPushNamed( + // // context, + // // "Join", + // // arguments: JoinArguments(args.isJoin, sessionName.value, sessionPassword.value, args.displayName, args.sessionIdleTimeoutMins, args.role), + // // ); + // Navigator.pop(context); + // } + // }, + // child: const Text('decline'), + // ), + // ], + // ), + // ); + } + isRecordingStarted.value = true; + } else { + isRecordingStarted.value = false; + } + }); + + final liveTranscriptionMsgInfoReceivedListener = emitter.on(EventType.onLiveTranscriptionMsgInfoReceived, (data) async { + data = data as Map; + ZoomVideoSdkLiveTranscriptionMessageInfo? messageInfo = ZoomVideoSdkLiveTranscriptionMessageInfo.fromJson(jsonDecode(data['messageInfo'])); + debugPrint("onLiveTranscriptionMsgInfoReceived: content: ${messageInfo.messageContent}"); + }); + + final inviteByPhoneStatusListener = emitter.on(EventType.onInviteByPhoneStatus, (data) async { + data = data as Map; + debugPrint("onInviteByPhoneStatus: status: ${data['status']}, reason: ${data['reason']}"); + }); + + final multiCameraStreamStatusChangedListener = emitter.on(EventType.onMultiCameraStreamStatusChanged, (data) async { + data = data as Map; + ZoomVideoSdkUser? changedUser = ZoomVideoSdkUser.fromJson(jsonDecode(data['changedUser'])); + var status = data['status']; + for (var user in users.value) { + { + if (changedUser.userId == user.userId) { + if (status == MultiCameraStreamStatus.Joined) { + user.hasMultiCamera = true; + } else if (status == MultiCameraStreamStatus.Left) { + user.hasMultiCamera = false; + } + } + } + } + }); + + final requireSystemPermission = emitter.on(EventType.onRequireSystemPermission, (data) async { + data = data as Map; + ZoomVideoSdkUser? changedUser = ZoomVideoSdkUser.fromJson(jsonDecode(data['changedUser'])); + var permissionType = data['permissionType']; + switch (permissionType) { + case SystemPermissionType.Camera: + showDialog( + context: context, + builder: (BuildContext context) => AlertDialog( + title: const Text("Can't Access Camera"), + content: const Text("please turn on the toggle in system settings to grant permission"), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context, 'OK'), + child: const Text('OK'), + ), + ], + ), + ); + break; + case SystemPermissionType.Microphone: + showDialog( + context: context, + builder: (BuildContext context) => AlertDialog( + title: const Text("Can't Access Microphone"), + content: const Text("please turn on the toggle in system settings to grant permission"), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context, 'OK'), + child: const Text('OK'), + ), + ], + ), + ); + break; + } + }); + + final networkStatusChangeListener = emitter.on(EventType.onUserVideoNetworkStatusChanged, (data) async { + data = data as Map; + ZoomVideoSdkUser? networkUser = ZoomVideoSdkUser.fromJson(jsonDecode(data['user'])); + + if (data['status'] == NetworkStatus.Bad) { + debugPrint("onUserVideoNetworkStatusChanged: status: ${data['status']}, user: ${networkUser.userName}"); + } + }); + + final eventErrorListener = emitter.on( + EventType.onError, + (data) async { + data = data as Map; + String errorType = data['errorType']; + showDialog( + context: context, + builder: (BuildContext context) => AlertDialog( + title: const Text("Error"), + content: Text(errorType), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context, 'OK'), + child: const Text('OK'), + ), + ], + ), + ); + if (errorType == Errors.SessionJoinFailed || errorType == Errors.SessionDisconnecting) { + Timer( + const Duration(milliseconds: 1000), + () => Navigator.pop(context), + // Navigator.popAndPushNamed( + // context, + // "Join", + // arguments: JoinArguments(args.isJoin, sessionName.value, sessionPassword.value, args.displayName, args.sessionIdleTimeoutMins, args.role), + // ), + ); + } + }, + ); + + final userRecordingConsentListener = emitter.on(EventType.onUserRecordingConsent, (data) async { + data = data as Map; + ZoomVideoSdkUser? user = ZoomVideoSdkUser.fromJson(jsonDecode(data['user'])); + debugPrint('userRecordingConsentListener: user= ${user.userName}'); + }); + + final callCRCDeviceStatusListener = emitter.on(EventType.onCallCRCDeviceStatusChanged, (data) async { + data = data as Map; + debugPrint('onCallCRCDeviceStatusChanged: status = ${data['status']}'); + }); + + final originalLanguageMsgReceivedListener = emitter.on(EventType.onOriginalLanguageMsgReceived, (data) async { + data = data as Map; + ZoomVideoSdkLiveTranscriptionMessageInfo? messageInfo = ZoomVideoSdkLiveTranscriptionMessageInfo.fromJson(jsonDecode(data['messageInfo'])); + debugPrint("onOriginalLanguageMsgReceived: content: ${messageInfo.messageContent}"); + }); + + final chatPrivilegeChangedListener = emitter.on(EventType.onChatPrivilegeChanged, (data) async { + data = data as Map; + String type = data['privilege']; + debugPrint('chatPrivilegeChangedListener: type= $type'); + }); + + return () => { + sessionJoinListener.cancel(), + sessionLeaveListener.cancel(), + sessionPasswordWrongListener.cancel(), + sessionNeedPasswordListener.cancel(), + userVideoStatusChangedListener.cancel(), + userAudioStatusChangedListener.cancel(), + userJoinListener.cancel(), + userLeaveListener.cancel(), + userNameChangedListener.cancel(), + userShareStatusChangeListener.cancel(), + liveStreamStatusChangeListener.cancel(), + cloudRecordingStatusListener.cancel(), + inviteByPhoneStatusListener.cancel(), + eventErrorListener.cancel(), + commandReceived.cancel(), + chatDeleteMessageNotify.cancel(), + liveTranscriptionStatusChangeListener.cancel(), + liveTranscriptionMsgInfoReceivedListener.cancel(), + multiCameraStreamStatusChangedListener.cancel(), + requireSystemPermission.cancel(), + userRecordingConsentListener.cancel(), + networkStatusChangeListener.cancel(), + callCRCDeviceStatusListener.cancel(), + originalLanguageMsgReceivedListener.cancel(), + chatPrivilegeChangedListener.cancel(), + }; + }, [zoom, users.value, isMounted]); + + void onPressAudio() async { + ZoomVideoSdkUser? mySelf = await zoom.session.getMySelf(); + if (mySelf != null) { + final audioStatus = mySelf.audioStatus; + if (audioStatus != null) { + var muted = await audioStatus.isMuted(); + if (muted) { + await zoom.audioHelper.unMuteAudio(mySelf.userId); + } else { + await zoom.audioHelper.muteAudio(mySelf.userId); + } + } + } + } + + void onPressCameraChange() async { + ZoomVideoSdkUser? mySelf = await zoom.session.getMySelf(); + if (mySelf != null) { + final videoStatus = mySelf.videoStatus; + if (videoStatus != null) { + if (currentCameraDeviceId == "1") { + currentCameraDeviceId = "2"; + await zoom.videoHelper.switchCamera("2"); + } else { + currentCameraDeviceId = "1"; + await zoom.videoHelper.switchCamera("1"); + } + } + } + } + + void onPressVideo() async { + ZoomVideoSdkUser? mySelf = await zoom.session.getMySelf(); + if (mySelf != null) { + final videoStatus = mySelf.videoStatus; + if (videoStatus != null) { + var videoOn = await videoStatus.isOn(); + if (videoOn) { + await zoom.videoHelper.stopVideo(); + } else { + await zoom.videoHelper.startVideo(); + } + } + } + } + + void onPressShare() async { + var isOtherSharing = await zoom.shareHelper.isOtherSharing(); + var isShareLocked = await zoom.shareHelper.isShareLocked(); + + if (isOtherSharing) { + showDialog( + context: context, + builder: (BuildContext context) => AlertDialog( + title: const Text("Error"), + content: const Text('Other is sharing'), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context, 'OK'), + child: const Text('OK'), + ), + ], + ), + ); + } else if (isShareLocked) { + showDialog( + context: context, + builder: (BuildContext context) => AlertDialog( + title: const Text("Error"), + content: const Text('Share is locked by host'), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context, 'OK'), + child: const Text('OK'), + ), + ], + ), + ); + } else if (isSharing.value) { + zoom.shareHelper.stopShare(); + } else { + zoom.shareHelper.shareScreen(); + } + } + + moreOptions = Center( + child: Stack( + children: [ + Visibility( + visible: isRenameModalVisible.value, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + alignment: Alignment.bottomLeft, + decoration: const BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(10)), + color: Colors.white, + ), + width: MediaQuery.of(context).size.width - 130, + height: 130, + child: Center( + child: (Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(top: 20, left: 20), + child: Text( + 'Change Name', + style: GoogleFonts.lato( + textStyle: const TextStyle( + fontSize: 18, + fontWeight: FontWeight.w500, + ), + ), + ), + ), + Padding( + padding: const EdgeInsets.only(top: 10, left: 20), + child: SizedBox( + width: MediaQuery.of(context).size.width - 230, + child: TextField( + onEditingComplete: () {}, + autofocus: true, + cursorColor: Colors.black, + controller: changeNameController, + decoration: InputDecoration( + isDense: true, + hintText: 'New name', + hintStyle: TextStyle( + fontSize: 14.0, + color: chatTextColor, + ), + ), + ), + ), + ), + Padding( + padding: const EdgeInsets.only(top: 15), + child: Row( + children: [ + Padding( + padding: const EdgeInsets.only(left: 40), + child: InkWell( + child: Text( + 'Apply', + style: GoogleFonts.lato( + textStyle: const TextStyle( + fontSize: 16, + ), + ), + ), + onTap: () async { + if (fullScreenUser.value != null) { + ZoomVideoSdkUser? mySelf = await zoom.session.getMySelf(); + await zoom.userHelper.changeName((mySelf?.userId)!, changeNameController.text); + changeNameController.clear(); + } + isRenameModalVisible.value = false; + }, + ), + ), + Padding( + padding: const EdgeInsets.only(left: 40), + child: InkWell( + child: Text( + 'Cancel', + style: GoogleFonts.lato( + textStyle: const TextStyle( + fontSize: 16, + ), + ), + ), + onTap: () async { + isRenameModalVisible.value = false; + }, + ), + ) + ], + ), + ) + ], + )), + ), + ), + ], + )), + ], + ), + ); + + void onSelectedUserVolume(ZoomVideoSdkUser user) async { + var isShareAudio = user.isSharing; + bool canSetVolume = await user.canSetUserVolume(user.userId, isShareAudio); + num userVolume; + + List options = [ + ListTile( + title: Text( + 'Adjust Volume', + style: GoogleFonts.lato( + textStyle: const TextStyle( + fontSize: 18, + fontWeight: FontWeight.w600, + color: Colors.black, + ), + ), + ), + ), + ListTile( + title: Text( + 'Current volume', + style: GoogleFonts.lato( + textStyle: const TextStyle( + fontSize: 14, + fontWeight: FontWeight.normal, + color: Colors.black, + ), + ), + ), + onTap: () async => { + debugPrint('user volume'), + userVolume = await user.getUserVolume(user.userId, isShareAudio), + debugPrint('user ${user.userName}\'s volume is ${userVolume!}'), + }, + ), + ]; + if (canSetVolume) { + options.add( + ListTile( + title: Text( + 'Volume up', + style: GoogleFonts.lato( + textStyle: const TextStyle( + fontSize: 14, + fontWeight: FontWeight.normal, + color: Colors.black, + ), + ), + ), + onTap: () async => { + userVolume = await user.getUserVolume(user.userId, isShareAudio), + if (userVolume < 10) + { + await user.setUserVolume(user.userId, userVolume + 1, isShareAudio), + } + else + { + debugPrint("Cannot volume up."), + } + }, + ), + ); + options.add( + ListTile( + title: Text( + 'Volume down', + style: GoogleFonts.lato( + textStyle: const TextStyle( + fontSize: 14, + fontWeight: FontWeight.normal, + color: Colors.black, + ), + ), + ), + onTap: () async => { + userVolume = await user.getUserVolume(user.userId, isShareAudio), + if (userVolume > 0) + { + await user.setUserVolume(user.userId, userVolume - 1, isShareAudio), + } + else + { + debugPrint("Cannot volume down."), + } + }, + ), + ); + } + showDialog( + context: context, + builder: (context) { + return Dialog( + elevation: 0.0, + insetPadding: const EdgeInsets.symmetric(horizontal: 40), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), + child: SizedBox( + height: options.length * 58, + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + ListView( + shrinkWrap: true, + children: ListTile.divideTiles( + context: context, + tiles: options, + ).toList(), + ), + ], + ), + )); + }); + } + + Future onPressMore() async { + ZoomVideoSdkUser? mySelf = await zoom.session.getMySelf(); + bool isShareLocked = await zoom.shareHelper.isShareLocked(); + bool canSwitchSpeaker = await zoom.audioHelper.canSwitchSpeaker(); + bool canStartRecording = (await zoom.recordingHelper.canStartRecording()) == Errors.Success; + var startLiveTranscription = (await zoom.liveTranscriptionHelper.getLiveTranscriptionStatus()) == LiveTranscriptionStatus.Start; + bool canStartLiveTranscription = await zoom.liveTranscriptionHelper.canStartLiveTranscription(); + bool canStartLiveStream = await zoom.liveStreamHelper.canStartLiveStream() == Errors.Success; + debugPrint(await zoom.liveStreamHelper.canStartLiveStream()); + bool startLiveStream = false; + bool isHost = (mySelf != null) ? (await mySelf.getIsHost()) : false; + isOriginalAspectRatio.value = await zoom.videoHelper.isOriginalAspectRatioEnabled(); + bool canCallOutToCRC = await zoom.CRCHelper.isCRCEnabled(); + + List options = [ + ListTile( + title: Text( + 'More', + style: GoogleFonts.lato( + textStyle: const TextStyle( + fontSize: 18, + fontWeight: FontWeight.w600, + color: Colors.black, + ), + ), + ), + ), + ListTile( + title: Text( + 'is Support Virtual Background', + style: GoogleFonts.lato( + textStyle: const TextStyle( + fontSize: 14, + fontWeight: FontWeight.normal, + color: Colors.black, + ), + ), + ), + onTap: () async => { + debugPrint("${await zoom.virtualBackgroundHelper.isSupportVirtualBackground()}"), + Navigator.of(context).pop(), + }, + ), + ListTile( + title: Text( + 'Get Chat Privilege', + style: GoogleFonts.lato( + textStyle: const TextStyle( + fontSize: 14, + fontWeight: FontWeight.normal, + color: Colors.black, + ), + ), + ), + onTap: () async => { + debugPrint("Chat Privilege = ${await zoom.chatHelper.getChatPrivilege()}"), + Navigator.of(context).pop(), + }, + ), + ListTile( + title: Text( + 'Get Session Dial-in Number infos', + style: GoogleFonts.lato( + textStyle: const TextStyle( + fontSize: 14, + fontWeight: FontWeight.normal, + color: Colors.black, + ), + ), + ), + onTap: () async => { + debugPrint("session number = ${await zoom.session.getSessionNumber()}"), + Navigator.of(context).pop(), + }, + ), + ListTile( + title: Text( + '${isMicOriginalOn.value ? 'Disable' : 'Enable'} Original Sound', + style: GoogleFonts.lato( + textStyle: const TextStyle( + fontSize: 14, + fontWeight: FontWeight.normal, + color: Colors.black, + ), + ), + ), + onTap: () async => { + debugPrint("${isMicOriginalOn.value}"), + await zoom.audioSettingHelper.enableMicOriginalInput(!isMicOriginalOn.value), + isMicOriginalOn.value = await zoom.audioSettingHelper.isMicOriginalInputEnable(), + debugPrint("Original sound ${isMicOriginalOn.value ? 'Enabled' : 'Disabled'}"), + Navigator.of(context).pop(), + }, + ) + ]; + + if (canCallOutToCRC) { + options.add(ListTile( + title: Text( + 'Call-out to CRC devices', + style: GoogleFonts.lato( + textStyle: const TextStyle( + fontSize: 14, + fontWeight: FontWeight.normal, + color: Colors.black, + ), + ), + ), + onTap: () async => { + debugPrint('CRC result = ${await zoom.CRCHelper.callCRCDevice("bjn.vc", ZoomVideoSdkCRCProtocolType.SIP)}'), + Navigator.of(context).pop(), + }, + )); + options.add(ListTile( + title: Text( + 'Cancel call-out to CRC devices', + style: GoogleFonts.lato( + textStyle: const TextStyle( + fontSize: 14, + fontWeight: FontWeight.normal, + color: Colors.black, + ), + ), + ), + onTap: () async => { + debugPrint('cancel result= ${await zoom.CRCHelper.cancelCallCRCDevice()}'), + Navigator.of(context).pop(), + }, + )); + } + + if (canSwitchSpeaker) { + options.add(ListTile( + title: Text( + 'Turn ${isSpeakerOn.value ? 'off' : 'on'} Speaker', + style: GoogleFonts.lato( + textStyle: const TextStyle( + fontSize: 14, + fontWeight: FontWeight.normal, + color: Colors.black, + ), + ), + ), + onTap: () async => { + await zoom.audioHelper.setSpeaker(!isSpeakerOn.value), + isSpeakerOn.value = await zoom.audioHelper.getSpeakerStatus(), + debugPrint('Turned ${isSpeakerOn.value ? 'on' : 'off'} Speaker'), + Navigator.of(context).pop(), + }, + )); + } + + if (isHost) { + options.add(ListTile( + title: Text( + '${isShareLocked ? 'Unlock' : 'Lock'} Share', + style: GoogleFonts.lato( + textStyle: const TextStyle( + fontSize: 14, + fontWeight: FontWeight.normal, + color: Colors.black, + ), + ), + ), + onTap: () async => { + debugPrint("isShareLocked = ${await zoom.shareHelper.lockShare(!isShareLocked)}"), + Navigator.of(context).pop(), + })); + options.add(ListTile( + title: Text( + 'Change Name', + style: GoogleFonts.lato( + textStyle: const TextStyle( + fontSize: 14, + fontWeight: FontWeight.normal, + color: Colors.black, + ), + ), + ), + onTap: () => { + isRenameModalVisible.value = true, + Navigator.of(context).pop(), + }, + )); + } + + if (canStartLiveTranscription) { + options.add(ListTile( + title: Text( + "${startLiveTranscription ? 'Stop' : 'Start'} Live Transcription", + style: GoogleFonts.lato( + textStyle: const TextStyle( + fontSize: 14, + fontWeight: FontWeight.normal, + color: Colors.black, + ), + ), + ), + onTap: () async => { + if (startLiveTranscription) + { + debugPrint('stopLiveTranscription= ${await zoom.liveTranscriptionHelper.stopLiveTranscription()}'), + } + else + { + debugPrint('startLiveTranscription= ${await zoom.liveTranscriptionHelper.startLiveTranscription()}'), + }, + Navigator.of(context).pop(), + }, + )); + options.add(ListTile( + title: Text( + '${isReceiveSpokenLanguageContentEnabled.value ? 'Disable' : 'Enable'} receiving original caption', + style: GoogleFonts.lato( + textStyle: const TextStyle( + fontSize: 14, + fontWeight: FontWeight.normal, + color: Colors.black, + ), + ), + ), + onTap: () async => { + await zoom.liveTranscriptionHelper.enableReceiveSpokenLanguageContent(!isReceiveSpokenLanguageContentEnabled.value), + isReceiveSpokenLanguageContentEnabled.value = await zoom.liveTranscriptionHelper.isReceiveSpokenLanguageContentEnabled(), + debugPrint("isReceiveSpokenLanguageContentEnabled = ${isReceiveSpokenLanguageContentEnabled.value}"), + Navigator.of(context).pop(), + })); + } + + if (canStartRecording) { + options.add(ListTile( + title: Text( + '${isRecordingStarted.value ? 'Stop' : 'Start'} Recording', + style: GoogleFonts.lato( + textStyle: const TextStyle( + fontSize: 14, + fontWeight: FontWeight.normal, + color: Colors.black, + ), + ), + ), + onTap: () async => { + if (!isRecordingStarted.value) + { + debugPrint('isRecordingStarted = ${await zoom.recordingHelper.startCloudRecording()}'), + } + else + { + debugPrint('isRecordingStarted = ${await zoom.recordingHelper.stopCloudRecording()}'), + }, + Navigator.of(context).pop(), + })); + } + + if (isVideoOn.value) { + options.add(ListTile( + title: Text( + 'Mirror the video', + style: GoogleFonts.lato( + textStyle: const TextStyle( + fontSize: 14, + fontWeight: FontWeight.normal, + color: Colors.black, + ), + ), + ), + onTap: () async => { + await zoom.videoHelper.mirrorMyVideo(!isVideoMirrored.value), + isVideoMirrored.value = await zoom.videoHelper.isMyVideoMirrored(), + Navigator.of(context).pop(), + })); + options.add(ListTile( + title: Text( + '${isOriginalAspectRatio.value ? 'Enable' : 'Disable'} original aspect ratio', + style: GoogleFonts.lato( + textStyle: const TextStyle( + fontSize: 14, + fontWeight: FontWeight.normal, + color: Colors.black, + ), + ), + ), + onTap: () async => { + await zoom.videoHelper.enableOriginalAspectRatio(!isOriginalAspectRatio.value), + isOriginalAspectRatio.value = await zoom.videoHelper.isOriginalAspectRatioEnabled(), + debugPrint("isOriginalAspectRatio= ${isOriginalAspectRatio.value}"), + Navigator.of(context).pop(), + })); + } + showDialog( + context: context, + builder: (context) { + return Dialog( + elevation: 0.0, + insetPadding: const EdgeInsets.symmetric(horizontal: 40), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), + child: SizedBox( + height: 500, + child: Scrollbar( + child: ListView( + shrinkWrap: true, + scrollDirection: Axis.vertical, + children: ListTile.divideTiles( + context: context, + tiles: options, + ).toList(), + ), + ), + ), + ); + }); + } + + void onLeaveSession(bool isEndSession) async { + WakelockPlus.disable(); + await zoom.leaveSession(isEndSession); + Navigator.pop(context); + // Navigator.pop(context); + } + + void showLeaveOptions() async { + ZoomVideoSdkUser? mySelf = await zoom.session.getMySelf(); + bool isHost = await mySelf!.getIsHost(); + + onLeaveSession(true); + + // Widget endSession; + // Widget leaveSession; + // Widget cancel = TextButton( + // child: const Text('Cancel'), + // onPressed: () { + // Navigator.pop(context); //close Dialog + // }, + // ); + + // switch (defaultTargetPlatform) { + // case TargetPlatform.android: + // endSession = TextButton( + // child: const Text('End Session'), + // onPressed: () => onLeaveSession(true), + // ); + // leaveSession = TextButton( + // child: const Text('Leave Session'), + // onPressed: () => onLeaveSession(false), + // ); + // break; + // default: + // endSession = CupertinoActionSheetAction( + // isDestructiveAction: true, + // child: const Text('End Session'), + // onPressed: () => onLeaveSession(true), + // ); + // leaveSession = CupertinoActionSheetAction( + // child: const Text('Leave Session'), + // onPressed: () => onLeaveSession(false), + // ); + // break; + // } + // + // List options = [ + // leaveSession, + // cancel, + // ]; + // + // if (Platform.isAndroid) { + // if (isHost) { + // options.removeAt(1); + // options.insert(0, endSession); + // } + // showDialog( + // context: context, + // builder: (context) { + // return AlertDialog( + // content: const Text("Do you want to leave this session?"), + // shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(2.0))), + // actions: options, + // ); + // }); + // } else { + // options.removeAt(1); + // if (isHost) { + // options.insert(1, endSession); + // } + // showCupertinoModalPopup( + // context: context, + // builder: (context) => CupertinoActionSheet( + // message: const Text('Are you sure that you want to leave the call?'), + // actions: options, + // cancelButton: cancel, + // ), + // ); + // } + } + + final chatMessageController = TextEditingController(); + + void sendChatMessage(String message) async { + await zoom.chatHelper.sendChatToAll(message); + ZoomVideoSdkUser? self = await zoom.session.getMySelf(); + ZoomVideoSdkCmdChannel cmdChannel = zoom.cmdChannel; + for (var user in users.value) { + if (user.userId != self?.userId) { + await zoom.cmdChannel.sendCommand(user.userId, message); + } + } + chatMessageController.clear(); + // send the chat as a command + } + + void onSelectedUser(ZoomVideoSdkUser user) async { + setState(() { + fullScreenUser.value = user; + }); + } + + Widget fullScreenView; + Widget smallView; + + if (isInSession.value && fullScreenUser.value != null && users.value.isNotEmpty) { + fullScreenView = AnimatedOpacity( + opacity: opacityLevel, + duration: const Duration(seconds: 3), + child: VideoView( + user: fullScreenUser.value, + hasMultiCamera: false, + sharing: sharingUser.value == null ? false : (sharingUser.value?.userId == fullScreenUser.value?.userId), + preview: false, + focused: false, + multiCameraIndex: "0", + videoAspect: VideoAspect.Original, + fullScreen: true, + resolution: VideoResolution.Resolution360, + isPiPView: false, + ), + ); + + smallView = Container( + height: 110, + margin: const EdgeInsets.only(left: 20, right: 20), + alignment: Alignment.bottomLeft, + child: VideoView( + user: users.value[0], + hasMultiCamera: false, + sharing: sharingUser.value == null ? false : sharingUser.value?.userId == users.value[0].userId, + preview: false, + focused: false, + multiCameraIndex: "0", + videoAspect: VideoAspect.Original, + fullScreen: false, + resolution: VideoResolution.Resolution180, + isPiPView: false, + ), + + // ListView.separated( + // scrollDirection: Axis.horizontal, + // itemCount: users.value.length, + // itemBuilder: (BuildContext context, int index) { + // return InkWell( + // onTap: () async { + // onSelectedUser(users.value[index]); + // }, + // onDoubleTap: () async { + // onSelectedUserVolume(users.value[index]); + // }, + // child: Center( + // child: VideoView( + // user: users.value[index], + // hasMultiCamera: false, + // sharing: sharingUser.value == null ? false : sharingUser.value?.userId == users.value[index].userId, + // preview: false, + // focused: false, + // multiCameraIndex: "0", + // videoAspect: VideoAspect.Original, + // fullScreen: false, + // resolution: VideoResolution.Resolution180, + // isPiPView: false, + // ), + // ), + // ); + // }, + // separatorBuilder: (BuildContext context, int index) => const Divider(), + // ), + ); + } else { + fullScreenView = Container( + color: Colors.black, + child: const Center( + child: Text( + "Connecting...", + style: TextStyle( + fontSize: 20, + color: Colors.white, + ), + ), + )); + smallView = Container( + height: 110, + color: Colors.transparent, + ); + } + + _changeOpacity; + return Scaffold( + resizeToAvoidBottomInset: false, + backgroundColor: backgroundColor, + body: Stack( + children: [ + fullScreenView, + Container( + padding: const EdgeInsets.only(top: 35), + child: Stack( + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + // Container( + // height: 70, + // width: 150, + // margin: const EdgeInsets.only(top: 16, left: 8), + // padding: const EdgeInsets.all(8), + // alignment: Alignment.topLeft, + // decoration: BoxDecoration( + // borderRadius: const BorderRadius.all(Radius.circular(8.0)), + // color: buttonBackgroundColor, + // ), + // child: InkWell( + // onTap: () async { + // showDialog( + // context: context, + // builder: (context) { + // return Dialog( + // elevation: 0.0, + // insetPadding: const EdgeInsets.symmetric(horizontal: 40), + // shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), + // child: SizedBox( + // height: 280, + // width: 200, + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.stretch, + // children: [ + // ListView( + // shrinkWrap: true, + // children: ListTile.divideTiles( + // context: context, + // tiles: [ + // ListTile( + // title: Text( + // 'Session Information', + // style: GoogleFonts.lato( + // textStyle: const TextStyle( + // fontSize: 18, + // fontWeight: FontWeight.w600, + // ), + // ), + // ), + // ), + // ListTile( + // title: Text( + // 'Session Name', + // style: GoogleFonts.lato( + // textStyle: const TextStyle( + // fontSize: 14, + // ), + // ), + // ), + // subtitle: Text( + // sessionName.value, + // style: GoogleFonts.lato( + // textStyle: const TextStyle( + // fontSize: 12, + // ), + // ), + // ), + // ), + // ListTile( + // title: Text( + // 'Session Password', + // style: GoogleFonts.lato( + // textStyle: const TextStyle( + // fontSize: 14, + // ), + // ), + // ), + // subtitle: Text( + // sessionPassword.value, + // style: GoogleFonts.lato( + // textStyle: const TextStyle( + // fontSize: 12, + // ), + // ), + // ), + // ), + // ListTile( + // title: Text( + // 'Participants', + // style: GoogleFonts.lato( + // textStyle: const TextStyle( + // fontSize: 14, + // ), + // ), + // ), + // subtitle: Text( + // '${users.value.length}', + // style: GoogleFonts.lato( + // textStyle: const TextStyle( + // fontSize: 12, + // ), + // ), + // ), + // ), + // ], + // ).toList(), + // ), + // ], + // ), + // )); + // }); + // }, + // child: Stack( + // children: [ + // // Column( + // // children: [ + // // const Padding(padding: EdgeInsets.symmetric(vertical: 3)), + // // Align( + // // alignment: Alignment.centerLeft, + // // child: Text( + // // sessionName.value, + // // overflow: TextOverflow.ellipsis, + // // style: GoogleFonts.lato( + // // textStyle: const TextStyle( + // // fontSize: 14, + // // fontWeight: FontWeight.w600, + // // color: Colors.white, + // // ), + // // ), + // // ), + // // ), + // // const Padding(padding: EdgeInsets.symmetric(vertical: 5)), + // // Align( + // // alignment: Alignment.centerLeft, + // // child: Text( + // // "Participants: ${users.value.length}", + // // style: GoogleFonts.lato( + // // textStyle: const TextStyle( + // // fontSize: 14, + // // fontWeight: FontWeight.w600, + // // color: Colors.white, + // // ), + // // ), + // // ), + // // ) + // // ], + // // ), + // // Container( + // // alignment: Alignment.centerRight, + // // child: Image.asset( + // // "assets/icons/unlocked@2x.png", + // // height: 22, + // // )), + // ], + // ), + // ), + // ), + TextButton( + onPressed: (showLeaveOptions), + child: Container( + alignment: Alignment.topRight, + margin: const EdgeInsets.only(top: 16, right: 8), + padding: const EdgeInsets.only(top: 5, bottom: 5, left: 16, right: 16), + height: 28, + decoration: BoxDecoration( + borderRadius: const BorderRadius.all(Radius.circular(20.0)), + color: buttonBackgroundColor, + ), + child: const Text( + "LEAVE", + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.bold, + color: Color(0xFFE02828), + ), + ), + )), + ], + ), + Align( + alignment: Alignment.centerRight, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + IconButton( + onPressed: onPressAudio, + icon: isMuted.value ? Image.asset("assets/images/new/zoom/unmute@2x.png") : Image.asset("assets/images/new/zoom/mute@2x.png"), + iconSize: circleButtonSize, + tooltip: isMuted.value == true ? "Unmute" : "Mute", + ), + // IconButton( + // onPressed: onPressShare, + // icon: isSharing.value ? Image.asset("assets/images/new/zoom/share-off@2x.png") : Image.asset("assets/images/new/zoom/share-on@2x.png"), + // iconSize: circleButtonSize, + // ), + IconButton( + onPressed: onPressVideo, + iconSize: circleButtonSize, + icon: isVideoOn.value ? Image.asset("assets/images/new/zoom/video-off@2x.png") : Image.asset("assets/images/new/zoom/video-on@2x.png"), + ), + IconButton( + onPressed: onPressCameraChange, + iconSize: circleButtonSize, + icon: const Icon( + Icons.cameraswitch_sharp, + size: 45.0, + color: Colors.white, + ), + ), + // IconButton( + // onPressed: onPressMore, + // icon: Image.asset("assets/icons/more@2x.png"), + // iconSize: circleButtonSize, + // ), + ], + ), + ), + Container( + alignment: Alignment.bottomLeft, + margin: const EdgeInsets.only(bottom: 120), + child: smallView, + ), + // CommentList(zoom: zoom, eventListener: eventListener), + moreOptions, + ], + )), + ], + ) + // drawer: const MenuBar() + ); + } +} + +class CallArguments { + final bool isJoin; + final String sessionName; + final String sessionPwd; + final String displayName; + final String sessionIdleTimeoutMins; + final String role; + final int callType; + + CallArguments(this.sessionName, this.sessionPwd, this.displayName, this.sessionIdleTimeoutMins, this.role, this.isJoin, this.callType); +} + +class JoinArguments { + final bool isJoin; + final String sessionName; + final String sessionPwd; + final String displayName; + final String sessionTimeout; + final String roleType; + + JoinArguments(this.isJoin, this.sessionName, this.sessionPwd, this.displayName, this.sessionTimeout, this.roleType); +} diff --git a/lib/pages/conference/zoom/jwt.dart b/lib/pages/conference/zoom/jwt.dart new file mode 100644 index 00000000..c9d373bd --- /dev/null +++ b/lib/pages/conference/zoom/jwt.dart @@ -0,0 +1,40 @@ +import 'dart:math'; + +import 'package:dart_jsonwebtoken/dart_jsonwebtoken.dart'; +import 'package:diplomaticquarterapp/pages/conference/zoom/zoom_config.dart'; + +String makeId(int length) { + String result = ""; + String characters = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + int charactersLength = characters.length; + for (var i = 0; i < length; i++) { + result += characters[Random().nextInt(charactersLength)]; + } + return result; +} + +String generateJwt(String sessionName, String roleType) { + try { + var iat = DateTime.now(); + var exp = DateTime.now().add(Duration(days: 2)); + final jwt = JWT( + { + 'app_key': configs["ZOOM_SDK_KEY"], + 'version': 1, + 'user_identity': makeId(10), + 'iat': (iat.millisecondsSinceEpoch / 1000).round(), + 'exp': (exp.millisecondsSinceEpoch / 1000).round(), + 'tpc': sessionName, + 'role_type': int.parse(roleType), + 'cloud_recording_option': 1, + 'cloud_recording_election': 1, + }, + ); + var token = jwt.sign(SecretKey(configs["ZOOM_SDK_SECRET"])); + return token; + } catch (e) { + print(e); + return ''; + } +} diff --git a/lib/pages/conference/zoom/video_view.dart b/lib/pages/conference/zoom/video_view.dart new file mode 100644 index 00000000..5a53cad2 --- /dev/null +++ b/lib/pages/conference/zoom/video_view.dart @@ -0,0 +1,258 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:flutter_zoom_videosdk/flutter_zoom_view.dart' as FlutterZoomView; +import 'package:flutter_zoom_videosdk/native/zoom_videosdk.dart'; + +const SHOW_TALKING_ICON_DURATION = 2000; + +class VideoView extends FlutterZoomView.ZoomView { + const VideoView({ + super.key, + required super.user, + required super.sharing, + required super.preview, + required super.focused, + required super.hasMultiCamera, + required super.multiCameraIndex, + required super.videoAspect, + required super.fullScreen, + required super.resolution, + required super.isPiPView, + }); + + @override + Widget build(BuildContext context) { + var isVideoOn = useState(false); + var isTalking = useState(false); + var isMuted = useState(false); + var isMounted = useIsMounted(); + var zoom = ZoomVideoSdk(); + var isSharing = useState(false); + user?.audioStatus?.isMuted().then((muted) => isMuted.value = muted); + + useEffect(() { + updateVideoStatus() { + if (user == null) return; + Future.microtask(() async { + if (isMounted()) { + isVideoOn.value = (await user!.videoStatus!.isOn()); + isSharing.value = sharing; + } + }); + } + + resetAudioStatus() { + isTalking.value = false; + isMuted.value = false; + } + + updateAudioStatus() async { + if (!isMounted()) return; + var talking = await user?.audioStatus?.isTalking(); + var muted = await user?.audioStatus?.isMuted(); + isMuted.value = muted!; + isTalking.value = talking!; + if (talking) { + Timer( + const Duration(milliseconds: SHOW_TALKING_ICON_DURATION), + () => { + if (isMounted()) + { + isTalking.value = false, + } + }); + } + } + + updateVideoStatus(); + return null; + }, [zoom, user]); + + ImageIcon audioStatusIcon; + if (isTalking.value) { + audioStatusIcon = const ImageIcon( + AssetImage("assets/images/new/zoom/talking@2x.png"), + ); + } else if (isMuted.value) { + audioStatusIcon = const ImageIcon( + AssetImage("assets/images/new/zoom/muted@2x.png"), + ); + } + // Pass parameters to the platform side. + final Map creationParams = {}; + creationParams.putIfAbsent("userId", () => user?.userId); + creationParams.putIfAbsent("sharing", () => sharing); + creationParams.putIfAbsent("preview", () => preview); + creationParams.putIfAbsent("focused", () => focused); + creationParams.putIfAbsent("hasMultiCamera", () => hasMultiCamera); + if (videoAspect.isEmpty) { + creationParams.putIfAbsent("videoAspect", () => VideoAspect.PanAndScan); + } else { + creationParams.putIfAbsent("videoAspect", () => videoAspect); + } + creationParams.putIfAbsent("fullScreen", () => fullScreen); + if (resolution.isNotEmpty) { + creationParams.putIfAbsent("videoAspect", () => videoAspect); + } + + if (fullScreen) { + if (sharing) { + return Container( + height: MediaQuery.of(context).size.height, + width: MediaQuery.of(context).size.width, + alignment: Alignment.center, + child: FlutterZoomView.View(creationParams: creationParams), + ); + } else if (isVideoOn.value) { + return Container( + height: MediaQuery.of(context).size.height, + width: MediaQuery.of(context).size.width, + alignment: Alignment.center, + child: FlutterZoomView.View(creationParams: creationParams), + ); + } else { + return Container( + margin: const EdgeInsets.symmetric(vertical: 0), + child: Container( + alignment: Alignment.center, + child: const Image( + image: AssetImage("assets/images/new/zoom/default-avatar.png"), + )), + ); + } + } else { + if (isVideoOn.value || sharing) { + return Container( + padding: const EdgeInsets.symmetric(horizontal: 8), + height: 110, + width: 110, + child: Stack( + children: [ + Container( + height: 110, + width: 110, + decoration: BoxDecoration( + color: const Color(0xff232323), + border: Border.all( + color: const Color(0xff666666), + width: 1, + ), + borderRadius: const BorderRadius.all(Radius.circular(8)), + ), + alignment: Alignment.center, + child: FlutterZoomView.View(creationParams: creationParams), + ), + Container( + height: 110, + width: 110, + decoration: const BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(8)), + ), + ), + Container( + alignment: Alignment.bottomCenter, + child: Container( + height: 20, + width: 110, + decoration: const BoxDecoration( + color: Colors.black26, + borderRadius: BorderRadius.all(Radius.circular(8)), + ), + ), + ), + Container( + alignment: Alignment.bottomLeft, + margin: const EdgeInsets.only(left: 5), + child: Text( + user!.userName, + textAlign: TextAlign.left, + style: const TextStyle( + color: Colors.white, + fontSize: 12, + ), + ), + ), + Container( + alignment: Alignment.bottomRight, + margin: const EdgeInsets.only(right: 5, bottom: 5), + // height: 110, + // width: 110, + child: Image( + height: 12, + width: 12, + image: isMuted.value ? const AssetImage("assets/images/new/zoom/muted@2x.png") : const AssetImage("assets/images/new/zoom/talking@2x.png"), + fit: BoxFit.cover, + ), + ) + ], + ), + ); + } else { + return Container( + padding: const EdgeInsets.symmetric(horizontal: 8), + height: 110, + width: 110, + child: Stack( + children: [ + Container( + height: 110, + width: 110, + decoration: BoxDecoration( + color: const Color(0xff232323), + border: Border.all( + color: const Color(0xff666666), + width: 1, + ), + borderRadius: const BorderRadius.all(Radius.circular(8)), + ), + alignment: Alignment.center, + child: Container( + alignment: Alignment.center, + child: const Image( + height: 60, + width: 60, + image: AssetImage("assets/images/new/zoom/default-avatar.png"), + )), + ), + Align( + alignment: Alignment.bottomCenter, + child: Container( + height: 20, + width: 110, + decoration: const BoxDecoration( + color: Colors.black26, + borderRadius: BorderRadius.all(Radius.circular(8)), + ), + ), + ), + Container( + alignment: Alignment.bottomLeft, + margin: const EdgeInsets.only(left: 5), + child: Text( + user!.userName, + textAlign: TextAlign.left, + style: const TextStyle( + color: Colors.white, + fontSize: 12, + ), + ), + ), + Container( + alignment: Alignment.bottomRight, + margin: const EdgeInsets.only(right: 5, bottom: 5), + child: Image( + height: 12, + width: 12, + image: isMuted.value ? const AssetImage("assets/images/new/zoom/muted@2x.png") : const AssetImage("assets/images/new/zoom/talking@2x.png"), + fit: BoxFit.cover, + ), + ), + ], + ), + ); + } + } + } +} diff --git a/lib/pages/conference/zoom/zoom_config.dart b/lib/pages/conference/zoom/zoom_config.dart new file mode 100644 index 00000000..09370c00 --- /dev/null +++ b/lib/pages/conference/zoom/zoom_config.dart @@ -0,0 +1,4 @@ +const Map configs = { + 'ZOOM_SDK_KEY': 'b9T74nhfTg-ioP9urm970A', + 'ZOOM_SDK_SECRET': 'KOzmjBNXQ1f4IPHpnngfL29uZvJMufSy2Fk8', +}; diff --git a/lib/pages/feedback/appointment_history.dart b/lib/pages/feedback/appointment_history.dart index a1dcdd33..69bd54e8 100644 --- a/lib/pages/feedback/appointment_history.dart +++ b/lib/pages/feedback/appointment_history.dart @@ -1,71 +1,71 @@ import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; class AppointmentHistory { - String setupID; - int projectID; - int appointmentNo; - DateTime appointmentDate; - Null appointmentDateN; - int appointmentType; - String bookDate; - int patientType; - int patientID; - int clinicID; - int doctorID; - String endDate; - String startTime; - String endTime; - int status; - int visitType; - int visitFor; - int patientStatusType; - int companyID; - int bookedBy; - String bookedOn; - int confirmedBy; - String confirmedOn; - int arrivalChangedBy; - DateTime arrivedOn; - Null editedBy; - Null editedOn; - Null doctorName; - Null doctorNameN; - String statusDesc; - Null statusDescN; - bool vitalStatus; - Null vitalSignAppointmentNo; - int episodeID; - int actualDoctorRate; - String clinicName; - bool complainExists; - String doctorImageURL; - String doctorNameObj; - int doctorRate; - List doctorSpeciality; - String doctorTitle; - int gender; - String genderDescription; - bool iSAllowOnlineCheckedIN; - bool isActiveDoctor; - bool isActiveDoctorProfile; - bool isDoctorAllowVedioCall; - bool isExecludeDoctor; - int isFollowup; - bool isLiveCareAppointment; - bool isMedicalReportRequested; - bool isOnlineCheckedIN; - String latitude; - Null listHISGetContactLensPerscription; - Null listHISGetGlassPerscription; - String longitude; - int nextAction; - int noOfPatientsRate; - int originalClinicID; - int originalProjectID; - String projectName; - String qR; - int remaniningHoursTocanPay; - bool sMSButtonVisable; + String? setupID; + int? projectID; + int? appointmentNo; + DateTime? appointmentDate; + dynamic appointmentDateN; + int? appointmentType; + String? bookDate; + int? patientType; + int? patientID; + int? clinicID; + int? doctorID; + String? endDate; + String? startTime; + String? endTime; + int? status; + int? visitType; + int? visitFor; + int? patientStatusType; + int? companyID; + int? bookedBy; + String ?bookedOn; + int? confirmedBy; + String? confirmedOn; + int? arrivalChangedBy; + DateTime? arrivedOn; + dynamic editedBy; + dynamic editedOn; + dynamic doctorName; + dynamic doctorNameN; + String? statusDesc; + dynamic statusDescN; + bool? vitalStatus; + dynamic vitalSignAppointmentNo; + int? episodeID; + int? actualDoctorRate; + String? clinicName; + bool? complainExists; + String? doctorImageURL; + String? doctorNameObj; + int? doctorRate; + List? doctorSpeciality; + String? doctorTitle; + int? gender; + String? genderDescription; + bool? iSAllowOnlineCheckedIN; + bool? isActiveDoctor; + bool? isActiveDoctorProfile; + bool? isDoctorAllowVedioCall; + bool? isExecludeDoctor; + int? isFollowup; + bool? isLiveCareAppointment; + bool? isMedicalReportRequested; + bool? isOnlineCheckedIN; + String? latitude; + dynamic listHISGetContactLensPerscription; + dynamic listHISGetGlassPerscription; + String? longitude; + int? nextAction; + int? noOfPatientsRate; + int? originalClinicID; + int? originalProjectID; + String? projectName; + String? qR; + int? remaniningHoursTocanPay; + bool? sMSButtonVisable; AppointmentHistory( {this.setupID, diff --git a/lib/pages/feedback/feedback-detail.dart b/lib/pages/feedback/feedback-detail.dart new file mode 100644 index 00000000..e303ed39 --- /dev/null +++ b/lib/pages/feedback/feedback-detail.dart @@ -0,0 +1,64 @@ +import 'package:diplomaticquarterapp/core/model/feedback/COC_items.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:flutter/material.dart'; + +class FeedbackDetails extends StatelessWidget { + final COCItem items; + + FeedbackDetails({ + required this.items, + }); + + @override + Widget build(BuildContext context) { + return AppScaffold( + isShowAppBar: true, + showNewAppBar: true, + showNewAppBarTitle: true, + appBarTitle: TranslationBase.of(context).feedbackTitle, + body: Container( + margin: EdgeInsets.all(5), + padding: EdgeInsets.all(5), + color: Colors.white, + child: Table( + border: TableBorder.all(), + columnWidths: const { + 0: IntrinsicColumnWidth(), + 1: FlexColumnWidth(), + 2: FixedColumnWidth(64), + }, + defaultVerticalAlignment: TableCellVerticalAlignment.middle, + children: [ + TableRow( + children: [ + getColumnText(TranslationBase.of(context).feedbackTitle), + getColumnText(items.cOCTitle) + ], + ), + TableRow( + children: [ + getColumnText(TranslationBase.of(context).complaint), + getColumnText(items.cOCID) + ], + ), + TableRow( + children: [ + getColumnText(TranslationBase.of(context).date), + getColumnText(items.date) + ], + ), + TableRow( + children: [ + getColumnText(TranslationBase.of(context).type), + getColumnText(items.formType) + ], + ) + ]))); + } + + Widget getColumnText(value) { + return Container(child: Texts(value), padding: EdgeInsets.all(5)); + } +} diff --git a/lib/pages/feedback/feedback_home_page.dart b/lib/pages/feedback/feedback_home_page.dart index f7f998bf..d6bd5932 100644 --- a/lib/pages/feedback/feedback_home_page.dart +++ b/lib/pages/feedback/feedback_home_page.dart @@ -1,8 +1,10 @@ import 'dart:ui'; +import 'package:diplomaticquarterapp/core/viewModels/feedback/feedback_view_model.dart'; +import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; import 'package:diplomaticquarterapp/pages/feedback/send_feedback_page.dart'; +import 'package:diplomaticquarterapp/theme/colors.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:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -10,13 +12,16 @@ import 'package:flutter/material.dart'; import 'status_feedback_page.dart'; class FeedbackHomePage extends StatefulWidget { + final AppoitmentAllHistoryResultList? appointment; + final MessageType messageType; + const FeedbackHomePage({Key? key, this.appointment, this.messageType = MessageType.NON}) : super(key: key); + @override _FeedbackHomePageState createState() => _FeedbackHomePageState(); } -class _FeedbackHomePageState extends State - with SingleTickerProviderStateMixin { - TabController _tabController; +class _FeedbackHomePageState extends State with SingleTickerProviderStateMixin { + late TabController _tabController; @override void initState() { @@ -37,79 +42,45 @@ class _FeedbackHomePageState extends State isBottomBar: false, isShowDecPage: false, appBarTitle: TranslationBase.of(context).feedbackTitle, - body: Scaffold( - extendBodyBehindAppBar: true, - appBar: PreferredSize( - preferredSize: Size.fromHeight(65.0), - child: Stack( - children: [ - Positioned( - bottom: 1, - left: 0, - right: 0, - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10), - child: Container( - color: Theme.of(context) - .scaffoldBackgroundColor - .withOpacity(0.8), - height: 70.0, - ), - ), - ), - Center( - child: Container( - height: 60.0, - margin: EdgeInsets.only(top: 10.0), - width: MediaQuery.of(context).size.width * 0.9, - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Theme.of(context).dividerColor, width: 0.7), - ), - color: Colors.white), - child: Center( - child: TabBar( - isScrollable: true, - controller: _tabController, - indicatorWeight: 5.0, - indicatorSize: TabBarIndicatorSize.tab, - labelColor: Theme.of(context).primaryColor, - labelPadding: - EdgeInsets.only(top: 4.0, left: 18.0, right: 18.0), - unselectedLabelColor: Colors.grey[800], - tabs: [ - Container( - width: MediaQuery.of(context).size.width * 0.30, - child: Center( - child: Texts(TranslationBase.of(context).send), - ), - ), - Container( - width: MediaQuery.of(context).size.width * 0.30, - child: Center( - child: Texts(TranslationBase.of(context).status), - ), - ), - ], - ), - ), - ), - ), - ], + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: CustomColors.appBackgroudGrey2Color, + body: Column( + children: [ + TabBar( + controller: _tabController, + indicatorWeight: 3.0, + indicatorSize: TabBarIndicatorSize.tab, + labelColor: Color(0xff2B353E), + unselectedLabelColor: Color(0xff575757), + labelPadding: EdgeInsets.only(top: 15, bottom: 13, left: 20, right: 20), + labelStyle: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + ), + unselectedLabelStyle: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + ), + tabs: [Text(TranslationBase.of(context).send), Text(TranslationBase.of(context).status)], ), - ), - body: Column( - children: [ - Expanded( - child: TabBarView( - physics: BouncingScrollPhysics(), - controller: _tabController, - children: [SendFeedbackPage(), StatusFeedbackPage()], - ), - ) - ], - ), + Expanded( + child: TabBarView( + physics: BouncingScrollPhysics(), + controller: _tabController, + children: [ + SendFeedbackPage( + appointment: widget.appointment, + + messageType: widget.messageType, + ), + StatusFeedbackPage() + ], + ), + ) + ], ), ); } diff --git a/lib/pages/feedback/send_feedback_page.dart b/lib/pages/feedback/send_feedback_page.dart index 189b4761..595f6cd6 100644 --- a/lib/pages/feedback/send_feedback_page.dart +++ b/lib/pages/feedback/send_feedback_page.dart @@ -1,26 +1,40 @@ -import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'dart:io'; + +import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/core/viewModels/feedback/feedback_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; +import 'package:diplomaticquarterapp/services/permission/permission_service.dart'; +import 'package:diplomaticquarterapp/services/robo_search/event_provider.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/widgets/avatar/large_avatar.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/bottom_options/BottomSheet.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/medical/doctor_card.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; -import 'package:diplomaticquarterapp/widgets/input/text_field.dart'; -import 'package:diplomaticquarterapp/widgets/others/StarRating.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/radio_selection_dialog.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/others/floating_button_search.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; -import 'dart:convert'; -import 'dart:io'; -import 'appointment_history.dart'; +import 'package:permission_handler/permission_handler.dart'; +import 'package:provider/provider.dart'; + +// import 'package:speech_to_text/speech_recognition_error.dart'; +import 'package:speech_to_text/speech_to_text.dart' as stt; class SendFeedbackPage extends StatefulWidget { + final AppoitmentAllHistoryResultList? appointment; + final MessageType messageType; + + const SendFeedbackPage({Key? key, this.appointment, this.messageType = MessageType.NON}) : super(key: key); + @override _SendFeedbackPageState createState() => _SendFeedbackPageState(); } @@ -29,13 +43,22 @@ class _SendFeedbackPageState extends State { TextEditingController titleController = TextEditingController(); TextEditingController messageController = TextEditingController(); List images = []; - String title; - AppointmentHistory appointHistory; + late String title; + AppoitmentAllHistoryResultList? appointHistory = AppoitmentAllHistoryResultList(); bool isShowListAppointHistory = true; - String message; + String message = ""; final formKey = GlobalKey(); MessageType messageType = MessageType.NON; + var _currentLocaleId; + stt.SpeechToText speech = stt.SpeechToText(); + var reconizedWord; + int selectedStatusIndex = 5; + var event = RobotProvider(); + + List appoList = []; + + ProjectViewModel? projectViewModel; String getSelected(BuildContext context) { switch (messageType) { @@ -61,409 +84,345 @@ class _SendFeedbackPageState extends State { return TranslationBase.of(context).notClassified; } + setMessageType(MessageType messageType,AppoitmentAllHistoryResultList? appointHistory) { + print(widget); + setState(() { + this.messageType = messageType; + this.appointHistory = appointHistory; + }); + } - - setMessageType(MessageType messageType) { - setState(() { - this.messageType = messageType; - }); - + @override + void initState() { + setState(() { + this.messageType = widget.messageType; + this.appointHistory = widget.appointment; + }); + // requestPermissions(); + event.controller.stream.listen((p) { + if (p['isIOSFeedback'] == 'true') { + if (this.mounted) { + this.titleController.value = p['data']; + } + } + }); + super.initState(); } @override Widget build(BuildContext context) { + projectViewModel = Provider.of(context); return BaseView( allowAny: true, builder: (_, model, widget) => AppScaffold( baseViewModel: model, isShowDecPage: false, - body: Container( - height: MediaQuery.of(context).size.height * 0.8, - child: SingleChildScrollView( - child: Form( - key: formKey, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 65, - ), - Container( - margin: EdgeInsets.only(left: 20, right: 20, top: 8), - child: Texts( - TranslationBase.of(context).likeToHear, - textAlign: TextAlign.center, - ), - ), - InkWell( - onTap: () { - confirmBox(model); - }, - child: Container( - margin: EdgeInsets.only(left: 10, right: 10, top: 15), - height: 50, - decoration: BoxDecoration( - border: Border.all(color: Colors.grey), - borderRadius: BorderRadius.circular(7), - color: Colors.white, - shape: BoxShape.rectangle, + body: Column( + children: [ + Expanded( + child: SingleChildScrollView( + physics: BouncingScrollPhysics(), + padding: EdgeInsets.only(top: 16, bottom: 16, right: 21, left: 21), + child: Form( + key: formKey, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).likeToHear, + // textAlign: TextAlign.center, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64, height: 23 / 16), ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Container( - child: Texts( - getSelected(context), - variant: 'bodyText', + SizedBox(height: 21), + InkWell( + onTap: () { + confirmBox(model); + }, + child: 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, ), - margin: EdgeInsets.only(left: 10,right: 10), ), - Icon( - Icons.arrow_drop_down, - size: 22, - color: Colors.grey, - ) - ], - ), - ), - ), - if (appointHistory != null && messageType == - MessageType.ComplaintOnAnAppointment) - InkWell( - onTap: () { - setState(() { - isShowListAppointHistory = true; - }); - }, - child: Container( - margin: EdgeInsets.all(8.0), - color: Colors.white, - child: Row( - children: [ - Expanded( - flex: 4, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.all(10.0), - child: Row( - children: [ - Expanded( - flex: 1, - child: LargeAvatar( - name: appointHistory.doctorNameObj, - url: appointHistory.doctorImageURL, - ), - ), - Expanded( - flex: 4, - child: Container( - margin: EdgeInsets.all(10), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Texts( - appointHistory.doctorNameObj, - bold: true, - ), - Texts( - DateUtil - .getMonthDayYearDateFormatted( - appointHistory - .appointmentDate), - variant: 'caption3', - ), - StarRating( - totalAverage: appointHistory - .doctorRate - .toDouble(), - forceStars: true), - ], - ), - ), - ), - ], - ), - ), - ], - ), - ), - Expanded( - flex: 1, - child: Center( - child: Icon( - Icons.arrow_forward_ios, - size: 15, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + getSelected(context), + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + color: Color(0xff2B353E), ), ), - ) - ], + Icon( + Icons.keyboard_arrow_down, + size: 22, + color: Colors.grey, + ) + ], + ), ), ), - ), - if (messageType == MessageType.ComplaintOnAnAppointment && model.appointHistoryList.length != 0 && - isShowListAppointHistory) - Container( - height: model.appointHistoryList.length>2?MediaQuery.of(context).size.height * 0.25:MediaQuery.of(context).size.height * 0.15, - child: ListView.builder( - itemCount: model.appointHistoryList.length, - itemBuilder: (context, index) => InkWell( + SizedBox(height: 12), + if (appointHistory != null && appointHistory?.doctorTitle!=null && messageType == MessageType.ComplaintOnAnAppointment) + InkWell( onTap: () { setState(() { - appointHistory = model.appointHistoryList[index]; - isShowListAppointHistory = false; + isShowListAppointHistory = true; }); }, - child: Container( - margin: EdgeInsets.only(left: 8, right: 8), - color: Colors.white, - child: Column( - children: [ - Row( - children: [ - Expanded( - flex: 4, - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.all(10.0), - child: Row( - children: [ - Expanded( - flex: 1, - child: LargeAvatar( - name: model - .appointHistoryList[ - index] - .doctorNameObj, - url: model - .appointHistoryList[ - index] - .doctorImageURL, - ), - ), - Expanded( - flex: 4, - child: Container( - margin: EdgeInsets.all(10), - child: Column( - crossAxisAlignment: - CrossAxisAlignment - .start, - children: [ - Texts( - model - .appointHistoryList[ - index] - .doctorNameObj, - bold: true, - ), - Texts( - DateUtil.getMonthDayYearDateFormatted(model - .appointHistoryList[ - index] - .appointmentDate), - variant: 'caption3', - ), - StarRating( - totalAverage: model - .appointHistoryList[ - index] - .doctorRate - .toDouble(), - forceStars: true), - ], - ), - ), - ), - ], - ), - ), - ], - ), - ), - Expanded( - flex: 1, - child: Center( - child: Icon( - Icons.arrow_forward_ios, - size: 15, - ), - ), - ) - ], - ), - SizedBox( - height: 5, - ), - Divider( - height: 0.5, - color: Colors.grey[400], - ) - ], + child: DoctorCard( + onTap: null, + isInOutPatient: appointHistory?.isInOutPatient, + name: "${appointHistory?.doctorTitle} ${appointHistory!.doctorNameObj}", + // billNo: _appointmentResult.invoiceNo, + profileUrl: appointHistory!.doctorImageURL, + subName: appointHistory!.projectName, + isLiveCareAppointment: appointHistory!.isLiveCareAppointment, + date: DateUtil.convertStringToDate(appointHistory?.appointmentDate) , + rating: appointHistory?.actualDoctorRate!=null ? appointHistory?.actualDoctorRate +0.0 : 0.0, + appointmentTime: appointHistory?.startTime?.substring(0, 5), + ), + ), + SizedBox(height: 12), + if (messageType == MessageType.ComplaintOnAnAppointment && appoList.length != 0 && isShowListAppointHistory) + Container( + margin: EdgeInsets.only(bottom: 10.0), + height: appoList.length > 2 ? MediaQuery.of(context).size.height * 0.35 : MediaQuery.of(context).size.height * 0.17, + child: ListView.separated( + itemCount: appoList.length, + separatorBuilder: (ctx, index) => SizedBox(height: 12), + itemBuilder: (context, index) => InkWell( + onTap: () { + setState(() { + appointHistory = appoList[index]; + isShowListAppointHistory = false; + }); + }, + child: DoctorCard( + onTap: null, + isInOutPatient: appoList[index].isInOutPatient, + name: appoList[index].doctorTitle! + " " + appoList[index].doctorNameObj!, + profileUrl: appoList[index].doctorImageURL, + subName: appoList[index].projectName, + isLiveCareAppointment: appoList[index].isLiveCareAppointment, + date: DateUtil.convertStringToDate(appoList[index].appointmentDate!), + rating: appoList[index].actualDoctorRate! + 0.0, + appointmentTime: appoList[index].startTime!.substring(0, 5), + ), ), ), ), - ), - ), - Container( - margin: EdgeInsets.only(left: 10, right: 10, top: 15), - child: TextFields( - hintText: TranslationBase.of(context).subject, - controller: titleController, - fontSize: 13.5, - hintColor: Colors.black, - fontWeight: FontWeight.w600, - validator: (value) { - if (value.isEmpty) - return TranslationBase.of(context).emptySubject; - else - return null; - }, - ), - ), - Container( - margin: EdgeInsets.only(left: 10, right: 10, top: 15), - child: TextFields( - hintText: TranslationBase.of(context).message, - fontSize: 13.5, - hintColor: Colors.black, - fontWeight: FontWeight.w600, - maxLines: 25, - minLines: 13, - controller: messageController, - validator: (value) { - if (value.isEmpty) - return TranslationBase.of(context).emptyMessage; - else - return null; - }), - ), - InkWell( - onTap: () { - ImageOptions.showImageOptions(context, (String image,File file) { - setState(() { - images.add(image); - }); - } ); - }, - child: Container( - margin: EdgeInsets.only(left: 10, right: 10, top: 15), - height: 50, - decoration: BoxDecoration( - border: Border.all(color: Colors.grey), - borderRadius: BorderRadius.circular(7), - color: Colors.white, - shape: BoxShape.rectangle, - ), - child: Center( - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Icon(Icons.attach_file), - Texts( - TranslationBase.of(context).selectAttachment, - variant: 'bodyText', - textAlign: TextAlign.center, + inputWidget(TranslationBase.of(context).subject, "", titleController), + SizedBox(height: 12), + inputWidget(TranslationBase.of(context).message, "", messageController, lines: 11, suffixTap: () async { + if (Platform.isAndroid) { + if (await PermissionService.isMicrophonePermissionEnabled()) { + openSpeechReco(); + } else { + Utils.showPermissionConsentDialog(context, TranslationBase.of(context).recordAudioPermission, () { + openSpeechReco(); + }); + } + } else { + openSpeechReco(); + } + }), + SizedBox(height: 12), + InkWell( + onTap: () { + ImageOptions.showImageOptions(context, (String image, File file) { + setState(() { + images.add(image); + }); + }); + }, + child: 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: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + Icons.attach_file, + color: Color(0xff2B353E), + ), + Text( + TranslationBase.of(context).selectAttachment, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64, height: 23 / 16), + ), + ], + ), ), ), - ), - ), - ...List.generate( - images.length, - (index) => Container( - margin: EdgeInsets.all(10), - padding: EdgeInsets.all(8.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - crossAxisAlignment: CrossAxisAlignment.start, + ...List.generate( + images.length, + (index) => Container( + margin: EdgeInsets.all(10), + padding: EdgeInsets.all(8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Icon(FontAwesomeIcons.paperclip), - SizedBox( - width: 8, - ), - Texts( - 'image ${index + 1}.png', + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Icon(FontAwesomeIcons.paperclip), + SizedBox( + width: 8, + ), + Texts( + 'image ${index + 1}.png', + ), + ], ), + InkWell( + onTap: () { + setState(() { + images.remove(images[index]); + }); + }, + child: Icon( + FontAwesomeIcons.trashAlt, + color: Colors.red[300], + )) ], ), - InkWell( - onTap: () { - setState(() { - images.remove(images[index]); - }); - }, - child: Icon( - FontAwesomeIcons.trashAlt, - color: Colors.red[300], - )) - ], - ), - )), - SizedBox( - height: 100, + )), + ], ), - ], + ), ), ), - ), - ), - bottomSheet: Container( - height: MediaQuery.of(context).size.height * 0.12, - width: double.infinity, - padding: EdgeInsets.all(15.0), - child: Center( - child: Container( - height: MediaQuery.of(context).size.height * 0.1, - child: SecondaryButton( - label: TranslationBase.of(context).send, + Container( + color: Colors.white, + padding: EdgeInsets.only(top: 16, bottom: 16, right: 21, left: 21), + child: DefaultButton( + TranslationBase.of(context).send, + (titleController.text.toString().isEmpty || messageController.text.toString().isEmpty) + ? null + : () { + final form = formKey.currentState; + if (form!.validate()) { + GifLoaderDialogUtils.showMyDialog(context); + model + .sendCOCItem( + title: titleController.text, + attachment: images.length > 0 ? images[0] : "", + details: messageController.text, + cOCTypeName: getCOCName(), + appointHistory: messageType == MessageType.ComplaintOnAnAppointment ? appointHistory : null) + .then((value) { + if (value) { + setState(() { + titleController.text = ""; + messageController.text = ""; + images = []; + }); + selectedStatusIndex = 5; + setMessageType(MessageType.NON, appointHistory); + GifLoaderDialogUtils.hideDialog(context); + AppToast.showSuccessToast(message: TranslationBase.of(context).yourFeedback); + } else { + AppToast.showErrorToast(message: model.error); + GifLoaderDialogUtils.hideDialog(context); + } + }); + } + }, + color: Color(0xffD02127), textColor: Colors.white, - disabled: (titleController.text.toString().isEmpty || messageController.text.toString().isEmpty|| messageType == MessageType.NON), - onTap: () { - final form = formKey.currentState; - if (form.validate()) - if (messageType != MessageType.NON){ - GifLoaderDialogUtils.showMyDialog(context); - model.sendCOCItem( - title: titleController.text, - attachment: images.length > 0 ? images[0] : "", - details: messageController.text, - cOCTypeName: getCOCName(), - appointHistory:messageType == MessageType.ComplaintOnAnAppointment - ? appointHistory - : null) - .then((value) { - if (value) { - setState(() { - titleController.text = ""; - messageController.text = ""; - images = []; - }); - setMessageType(MessageType.NON); - GifLoaderDialogUtils.hideDialog(context); - AppToast.showSuccessToast( - message: TranslationBase.of(context).yourFeedback); - } else { - AppToast.showErrorToast(message: model.error); - GifLoaderDialogUtils.hideDialog(context); - } - });} - else { - AppToast.showErrorToast(message: TranslationBase.of(context).selectPart); - } - }, + disabledColor: Color(0xffEAEAEA), + ), + ), + ], + ), + ), + ); + } + + Widget inputWidget(String _labelText, String _hintText, TextEditingController _controller, {VoidCallback? suffixTap, bool isEnable = true, bool hasSelection = false, int? lines}) { + 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: 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), + ], ), ), ); @@ -484,10 +443,10 @@ class _SendFeedbackPageState extends State { return "4"; break; case MessageType.Suggestion: - return "5"; + return "6"; break; case MessageType.NON: - return ""; + return "5"; break; } return ""; @@ -495,268 +454,120 @@ class _SendFeedbackPageState extends State { // Show Dialog function void confirmBox(FeedbackViewModel model) { - showDialog( - context: context, - child: FeedbackTypeDialog( - messageTypeDialog: messageType, - onValueSelected: (MessageType value) { - if (value == MessageType.ComplaintOnAnAppointment) { - GifLoaderDialogUtils.showMyDialog(context); - model.getPatentAppointmentHistory().then((value) { - GifLoaderDialogUtils.hideDialog(context); - setState(() { - appointHistory = null; - }); - }); - } - setMessageType(value); - }, - )); - } -} + DoctorsListService service = new DoctorsListService(); -class FeedbackTypeDialog extends StatefulWidget { - final Function(MessageType) onValueSelected; - final MessageType messageTypeDialog; + List list = [ + RadioSelectionDialogModel(TranslationBase.of(context).notClassified, 5), + RadioSelectionDialogModel(TranslationBase.of(context).complainAppo, 1), + RadioSelectionDialogModel(TranslationBase.of(context).complainWithoutAppo, 2), + RadioSelectionDialogModel(TranslationBase.of(context).question, 3), + RadioSelectionDialogModel(TranslationBase.of(context).compliment, 4), + RadioSelectionDialogModel(TranslationBase.of(context).suggestion, 6), + ]; - const FeedbackTypeDialog({Key key, this.onValueSelected, this.messageTypeDialog=MessageType.NON}) : super(key: key); + showDialog( + context: context, + builder: (cxt) => RadioSelectionDialog( + listData: list, + selectedIndex: selectedStatusIndex, + onValueSelected: (index) { + int languageID = projectViewModel!.isArabic ? 1 : 2; + selectedStatusIndex = index; - @override - State createState() => new FeedbackTypeDialogState(); -} + if (index == 1) { + messageType = MessageType.ComplaintOnAnAppointment; + } else if (index == 2) { + messageType = MessageType.ComplaintWithoutAppointment; + } else if (index == 3) { + messageType = MessageType.Question; + } else if (index == 4) { + messageType = MessageType.Compliment; + } else if (index == 5) { + messageType = MessageType.NON; + } else { + messageType = MessageType.Suggestion; + } -class FeedbackTypeDialogState extends State { + if (messageType == MessageType.ComplaintOnAnAppointment) { + appoList.clear(); + GifLoaderDialogUtils.showMyDialog(context); + service.getPatientAppointmentHistory(false, languageID, 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 = AppoitmentAllHistoryResultList(); + isShowListAppointHistory = true; + }); + } else {} + } else {} + }); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + // print(err); + // AppToast.showErrorToast(message: err); + // Navigator.of(context).pop(); + }); + } else { + isShowListAppointHistory = false; + } + setMessageType(messageType, appointHistory); + }, + ), + ); + + return; + } - MessageType messageTypeDialog = MessageType.NON; + openSpeechReco() async { + new RoboSearch(context: context).showAlertDialog(context); + _currentLocaleId = TranslationBase.of(AppGlobal.context).locale.languageCode; + bool available = await speech.initialize(); - setMessageDialogType(MessageType messageType) { - setState(() { - messageTypeDialog = messageType; - }); + if(available) { + speech.listen( + onResult: resultListener, + listenFor: Duration(seconds: 10), + localeId: _currentLocaleId == 'en' ? 'en-US' : 'ar-SA', + // onSoundLevelChange: soundLevelListener, + // cancelOnError: true, + // partialResults: true, + // onDevice: true, + // listenMode: stt.ListenMode.deviceDefault + ); + } } - @override - void initState() { - messageTypeDialog = widget.messageTypeDialog; - super.initState(); + void statusListener(String status) { + reconizedWord = status == 'listening' ? 'Lisening...' : 'Sorry....'; } - 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: Theme.of(context).primaryColor, - 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: Theme.of(context).primaryColor, - 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: Theme.of(context).primaryColor, - 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: Theme.of(context).primaryColor, - 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: Theme.of(context).primaryColor, - 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: Theme.of(context).primaryColor, - 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: Theme.of(context).primaryColor, - ), - ), - ), - ), - ), - ), - 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, - )), - ), - )), - ], - ) - ], - ), - ), - ], - ), - ); + void requestPermissions() async { + Map statuses = await [ + Permission.microphone, + ].request(); } + + void resultListener(result) { + reconizedWord = result.recognizedWords; + event.setValue({"searchText": reconizedWord}); + + if (result.finalResult == true) { + setState(() { + messageController.text += reconizedWord + '\n'; + RoboSearch.closeAlertDialog(context); + // speech.stop(); + }); + } + } + + // Future initSpeechState() async { + // bool hasSpeech = await speech.initialize(onError: errorListener, onStatus: statusListener); + // print(hasSpeech); + // if (!mounted) return; + // } } diff --git a/lib/pages/feedback/status_feedback_page.dart b/lib/pages/feedback/status_feedback_page.dart index 59d68fa2..28c8fb52 100644 --- a/lib/pages/feedback/status_feedback_page.dart +++ b/lib/pages/feedback/status_feedback_page.dart @@ -1,12 +1,22 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/feedback/COC_items.dart'; import 'package:diplomaticquarterapp/core/viewModels/feedback/feedback_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/pages/feedback/feedback-detail.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/widgets/buttons/button.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/dialogs/radio_selection_dialog.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/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; class StatusFeedbackPage extends StatefulWidget { @override @@ -14,93 +24,348 @@ class StatusFeedbackPage extends StatefulWidget { } class _StatusFeedbackPageState extends State { + String countryCode = '966'; + String mobileNo = ""; + TextEditingController complainNumberController = TextEditingController(); + StatusType statusType = StatusType.ComplaintNumber; + int selectedStatusIndex = 3; + late ProjectViewModel projectViewModel; @override Widget build(BuildContext context) { + projectViewModel = Provider.of(context); return BaseView( - onModelReady: (model) => model.getCOC(), + allowAny: true, + onModelReady: (model) { + model.cOCItemList.clear(); + if (projectViewModel.isLogin) model.getCOC(); + }, builder: (_, model, widget) => AppScaffold( baseViewModel: model, isShowDecPage: false, - body: model.cOCItemList.isNotEmpty - ? Container( - margin: EdgeInsets.only(top: 8.0, left: 8.0, right: 8.0), - padding: EdgeInsets.all(15.0), - child: ListView.builder( - itemCount: model.cOCItemList.length, - itemBuilder: (context, index) => Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - border: Border.all(color: Colors.white, width: 0.5), - borderRadius: BorderRadius.all(Radius.circular(5)), - color: Colors.white, + body: Column( + children: [ + Expanded( + child: projectViewModel.isLogin + ? model.cOCItemList.isNotEmpty + ? listData(model.cOCItemList, projectViewModel.isArabic, true) + : Center( + child: Column( + children: [ + SizedBox( + height: MediaQuery.of(context).size.height * 0.4, + ), + Image.asset( + 'assets/images/comments.png', + width: 80, + height: 80, + ), + SizedBox( + height: 15, + ), + Text( + TranslationBase.of(context).noSearchResult, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + color: Color(0xff2B353E), + ), + ), + ], + ), + ) + : SingleChildScrollView( + padding: EdgeInsets.all(21), + physics: BouncingScrollPhysics(), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).selectSearchCriteria, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64, height: 23 / 16), ), - margin: EdgeInsets.all(4), - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 8, + SizedBox(height: 21), + InkWell( + onTap: () { + List list = [ + RadioSelectionDialogModel(TranslationBase.of(context).complaintNumber, 3), + RadioSelectionDialogModel(TranslationBase.of(context).fileNumber, 1), + RadioSelectionDialogModel(TranslationBase.of(context).identificationNumber, 2), + ]; + + showDialog( + context: context, + builder: (cxt) => RadioSelectionDialog( + listData: list, + selectedIndex: selectedStatusIndex, + onValueSelected: (index) { + selectedStatusIndex = index; + setState(() { + if (index == 3) { + statusType = StatusType.ComplaintNumber; + } else if (index == 1) { + statusType = StatusType.FileNumber; + } else { + statusType = StatusType.IdentificationNumber; + } + }); + }, ), - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Texts( - '${model.cOCItemList[index].cOCTitle}'), - Texts( - TranslationBase.of(context).number + - ' : ${model.cOCItemList[index].itemID}', - variant: 'overline', - ), - ], - ), - ), - Expanded( - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Texts( - '${model.cOCItemList[index].status}'), - Texts( - '${model.cOCItemList[index].date}', - variant: 'overline', - ), - ], - ), - ), - ], + ); + }, + child: 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, ), - Texts('${model.cOCItemList[index].formType}'), - Divider( - height: 4.5, - color: Colors.grey[500], - ) - ], + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + getSelected(context), + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + color: Color(0xff2B353E), + ), + ), + Icon( + Icons.keyboard_arrow_down, + size: 22, + color: Colors.grey, + ) + ], + ), ), ), - )), - ) - : Container( - child: Center( - child: Column( + SizedBox(height: 12), + Directionality( + textDirection: TextDirection.ltr, + child: inputWidget( + statusType == StatusType.ComplaintNumber + ? TranslationBase.of(context).enterComplainNumber + : (statusType == StatusType.FileNumber ? TranslationBase.of(context).enterfileNumber : TranslationBase.of(context).enterIdentificationNumber), + "", + complainNumberController, + isInputTypeNum: true)), + SizedBox(height: 12), + PhoneNumberSelectorWidget(onNumberChange: (value) { + setState(() { + mobileNo = value; + }); + }, onCountryChange: (value) { + setState(() { + countryCode = value; + }); + }), + if (model.cOCItemList.length > 0) listData(model.cOCItemList, projectViewModel.isArabic, false), + ], + ), + ), + ), + if (!projectViewModel.isLogin) + Container( + color: Colors.white, + padding: EdgeInsets.only(top: 16, bottom: 16, right: 21, left: 21), + child: DefaultButton( + TranslationBase.of(context).search, + projectViewModel.isLogin || (mobileNo.length < 9) || (complainNumberController.text.isEmpty) + ? null + : () { + model.searchFeedback(countryCode, mobileNo, selectedStatusIndex, complainNumberController.text).then((value) { + if (model.state == ViewState.ErrorLocal) { + Future.delayed(Duration(seconds: 1), () { + AppToast.showErrorToast(message: model.error); + }); + } else {} + }); + }, + disabledColor: Colors.grey, + ), + ), + ], + ), + ), + ); + } + + Widget listData(List cOCItemList, bool isArabic, bool isLogin) { + return ListView.builder( + padding: isLogin ? EdgeInsets.all(21) : null, + itemCount: cOCItemList.length, + shrinkWrap: isLogin ? false : true, + physics: isLogin ? null : NeverScrollableScrollPhysics(), + itemBuilder: (context, index) => InkWell( + onTap: () { + // sss + }, + child: Container( + margin: EdgeInsets.only(top: 12), + decoration: BoxDecoration( + color: (cOCItemList[index].statusId==7||cOCItemList[index].statusId==8)?CustomColors.accentColor:(cOCItemList[index].statusId==10||cOCItemList[index].statusId==6||cOCItemList[index].statusId==9)?CustomColors.green:CustomColors.orange, + borderRadius: BorderRadius.all( + Radius.circular(10.0), + ), + 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: 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), + ), + ), + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - SizedBox(height: MediaQuery.of(context).size.height*0.4,), - Image.asset('assets/images/comments.png',width: 80,height: 80,), - SizedBox(height: 15,), - Texts(TranslationBase.of(context).noSearchResult), + Text(isArabic ? cOCItemList[index].statusAr! : cOCItemList[index].status!, style: TextStyle(fontSize: 14.0, letterSpacing: -0.56, fontWeight: FontWeight.bold)), + Container( + margin: EdgeInsets.only(top: 5.0), + child: Text(cOCItemList[index].formType.toString(), + style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, fontFamily: isArabic ? 'Cairo' : 'Poppins', color: Color(0xff2B353E), letterSpacing: -0.48, height: 18 / 12))), + MyRichText(TranslationBase.of(context).number + ": ", cOCItemList[index].itemID.toString(), isArabic), + Text(cOCItemList[index].cOCTitle!, + style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, fontFamily: isArabic ? 'Cairo' : 'Poppins', color: Color(0xff2B353E), letterSpacing: -0.48, height: 18 / 12)), ], ), - ), + Column( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text(cOCItemList[index].date!.split(" ")[0], + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, fontFamily: isArabic ? 'Cairo' : 'Poppins', color: Color(0xff2B353E), letterSpacing: -0.48)), + Text(cOCItemList[index].date!.split(" ")[1].substring(0, 4), + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, fontFamily: isArabic ? 'Cairo' : 'Poppins', color: Color(0xff2B353E), letterSpacing: -0.48)), + ], + ), + ], + ), + ), + ), + ), + ), + ); + } + + 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), + ], + ), ), ); } + + gotodetails(item) { + Navigator.pushReplacement(context, FadePage(page: FeedbackDetails(items: item))); + } + + String getSelected(BuildContext context) { + switch (statusType) { + case StatusType.ComplaintNumber: + return TranslationBase.of(context).complaintNumber; + break; + case StatusType.FileNumber: + return TranslationBase.of(context).fileNumber; + break; + case StatusType.IdentificationNumber: + return TranslationBase.of(context).identificationNumber; + break; + } + return TranslationBase.of(context).notClassified; + } +} + +enum StatusType { + ComplaintNumber, + FileNumber, + IdentificationNumber, } diff --git a/lib/pages/final_products_page.dart b/lib/pages/final_products_page.dart index 66969331..4432cb1c 100644 --- a/lib/pages/final_products_page.dart +++ b/lib/pages/final_products_page.dart @@ -1,18 +1,33 @@ +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +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/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/locator.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/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/pages/pharmacies/product_detail.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart' as utils; 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'; +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:flutter_rating_bar/flutter_rating_bar.dart'; +import 'package:provider/provider.dart'; import 'base/base_view.dart'; +dynamic languageID; + class FinalProductsPage extends StatefulWidget { - final String id; + final String? id; final int productType; // 1 : default, 2 : manufacturer , 3 : recently viewed + AuthenticatedUserObject authenticatedUserObject = locator(); FinalProductsPage({this.id, this.productType = 1}); @@ -21,9 +36,12 @@ class FinalProductsPage extends StatefulWidget { } class _FinalProductsPageState extends State { - String id; + String? id; + _FinalProductsPageState({this.id}); + String categoriseName = "Personal Care"; + String appBarTitle = ""; bool styleOne = true; bool styleTwo = false; Icon styleIcon = Icon( @@ -31,48 +49,64 @@ class _FinalProductsPageState extends State { color: Colors.blue, size: 29.0, ); + + getLanguageID() async { + languageID = await sharedPref.getString(APP_LANGUAGE); + } + + void initState() { + getLanguageID(); + super.initState(); + } + @override Widget build(BuildContext context) { + ProjectViewModel projectProvider = Provider.of(context); + ProjectViewModel projectViewModel = Provider.of(context); return BaseView( onModelReady: (model) { if (widget.productType == 1) { model.getFinalProducts(i: id); + appBarTitle = TranslationBase.of(context).products; } else if (widget.productType == 2) { - model.getManufacturerProducts(id); + model.getManufacturerProducts(id!); } else if (widget.productType == 3) { model.getLastVisitedProducts(); - } else if (widget.productType == 4){ + appBarTitle = TranslationBase.of(context).recentlyViewed; + } else if (widget.productType == 4) { model.getMostViewedProducts(); - } else if (widget.productType == 5){ + appBarTitle = TranslationBase.of(context).mostViewed; + } else if (widget.productType == 5) { model.getNewProducts(); + appBarTitle = TranslationBase.of(context).newProducts; } else { model.getBestSellerProducts(); + appBarTitle = TranslationBase.of(context).bestSellers; } }, allowAny: true, - builder: (BuildContext context, PharmacyCategoriseViewModel model, - Widget child) => - PharmacyAppScaffold( - appBarTitle: "Products", - isBottomBar: false, + builder: (BuildContext context, PharmacyCategoriseViewModel model, Widget? child) => AppScaffold( + isPharmacy: true, + appBarTitle: appBarTitle, + isBottomBar: true, isShowAppBar: true, backgroundColor: Colors.white, isShowDecPage: false, + showPharmacyCart: false, + showHomeAppBarIcon: false, baseViewModel: model, body: Container( height: MediaQuery.of(context).size.height * 5.87, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ -//Expanded widget heree if nassery - Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Padding( padding: EdgeInsets.all(8.0), child: Texts( - 'Products', + "$appBarTitle " + TranslationBase.of(context).products, fontWeight: FontWeight.w600, ), ), @@ -98,7 +132,7 @@ class _FinalProductsPageState extends State { styleTwo = true; styleIcon = Icon( Icons.auto_awesome_mosaic, - color: Colors.blue, + color: CustomColors.green, size: 29.0, ); } else { @@ -106,7 +140,7 @@ class _FinalProductsPageState extends State { styleTwo = false; styleIcon = Icon( Icons.widgets_sharp, - color: Colors.blue, + color: CustomColors.green, size: 29.0, ); } @@ -124,433 +158,449 @@ class _FinalProductsPageState extends State { ), styleOne == true ? Expanded( - child: Container( - height: MediaQuery.of(context).size.height * 3.90, - child: GridView.builder( - gridDelegate: - SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 2, - crossAxisSpacing: 0.5, - mainAxisSpacing: 2.0, - childAspectRatio: 1.0, - ), - itemCount: model.finalProducts.length, - itemBuilder: (BuildContext context, int index) { - return NetworkBaseView( - baseViewModel: model, - child: InkWell( - child: Card( - color: model.finalProducts[index] - .discountName != - null - ? Color(0xffFFFF00) - : Colors.white, - elevation: 0, - shape: Border( - right: BorderSide( - color: Colors.grey.shade300, - width: 1, - ), - left: BorderSide( - color: Colors.grey.shade300, - width: 1, - ), - bottom: BorderSide( - color: Colors.grey.shade300, - width: 1, - ), - top: BorderSide( - color: Colors.grey.shade300, - width: 1, - ), - ), - margin: EdgeInsets.symmetric( - horizontal: 8, - vertical: 4, - ), - child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.only( - topLeft: Radius.circular(110.0), - ), - color: Colors.white, - ), - padding: EdgeInsets.symmetric( - horizontal: 0), - width: MediaQuery.of(context) - .size - .width / - 3, - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Stack( - children: [ - Container( - margin: - EdgeInsets.fromLTRB( - 0, 16, 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.cover, - height: 80, - ), - ), - 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: Texts( - model - .finalProducts[ - index] - .rxMessage != - null - ? model - .finalProducts[ - index] - .rxMessage - : "", - color: Colors.white, - regular: true, - fontSize: 10, - fontWeight: - FontWeight.w600, - ), - ), - ], + child: model.finalProducts.length > 0 + ? Container( + height: MediaQuery.of(context).size.height * 3.90, + child: GridView.builder( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + crossAxisSpacing: 0.5, + mainAxisSpacing: 2.0, + childAspectRatio: 1.0, + ), + itemCount: model.finalProducts.length, + itemBuilder: (BuildContext context, int index) { + return NetworkBaseView( + baseViewModel: model, + child: InkWell( + child: Card( + color: model.finalProducts[index].discountName != null ? Color(0xffFFFF00) : Colors.white, + elevation: 0, + shape: Border( + right: BorderSide( + color: Colors.grey.shade300, + width: 1, + ), + left: BorderSide( + color: Colors.grey.shade300, + width: 1, + ), + bottom: BorderSide( + color: Colors.grey.shade300, + width: 1, + ), + top: BorderSide( + color: Colors.grey.shade300, + width: 1, + ), + ), + margin: EdgeInsets.symmetric( + horizontal: 8, + vertical: 4, ), - Container( - margin: EdgeInsets.symmetric( - horizontal: 6, - vertical: 0, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(110.0), + ), + color: Colors.white, ), + padding: EdgeInsets.symmetric(horizontal: 0), + width: MediaQuery.of(context).size.width / 3, child: Column( - crossAxisAlignment: - CrossAxisAlignment - .start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ - if (model - .finalProducts[ - index] - .discountName != - null) - Container( - width: - double.infinity, - height: 13.0, - decoration: - BoxDecoration( - color: Color( - 0xff5AB145), + Stack( + children: [ + Container( + margin: EdgeInsets.fromLTRB(0, 16, 0, 0), + alignment: Alignment.center, + child: (model.finalProducts[index].images != null && model.finalProducts[index].images!.length > 0) + ? Image.network( + model.finalProducts[index].images![0].src!, + fit: BoxFit.cover, + height: 80, + width: 80, + ) + : Image.asset( + "assets/images/no_image.png", + fit: BoxFit.cover, + height: 80, + width: 80, + ), +// 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.cover, +// height: 80, +// ), ), - child: Center( - child: Texts( - model - .finalProducts[ - index] - .discountName, - regular: true, - color: - Colors.white, - fontSize: 10.4, + Container( + width: model.finalProducts[index].rxMessage != null ? double.infinity : 0, + //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( + projectProvider.isArabic ? model.finalProducts[index].rxMessagen : model.finalProducts[index].rxMessage, + color: Colors.white, + regular: true, + fontSize: 10, + fontWeight: FontWeight.w600, + ) + : Texts(""), ), - ), - Texts( - model - .finalProducts[ - index] - .name, - regular: true, - fontSize: 12, - fontWeight: - FontWeight.w400, + ], ), - Padding( - padding: - const EdgeInsets - .only( - top: 4, - bottom: 4), - child: Texts( - "SAR ${model.finalProducts[index].price}", - bold: true, - fontSize: 14, + Container( + margin: EdgeInsets.symmetric( + horizontal: 6, + vertical: 0, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (model.finalProducts[index].discountName != null) + Container( + width: double.infinity, + height: 13.0, + decoration: BoxDecoration( + color: Color(0xff5AB145), + ), + child: Center( + child: Texts( + model.finalProducts[index].discountName, + regular: true, + color: Colors.white, + fontSize: 10.4, + ), + ), + ), + Texts( + projectViewModel.isArabic ? model.finalProducts[index].namen : model.finalProducts[index].name, +// model.finalProducts[index].name, + regular: true, + fontSize: 12, + fontWeight: FontWeight.w400, + ), + 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), + + RatingBar( + itemSize: 20.0, + allowHalfRating: true, + initialRating: model.finalProducts[index].approvedRatingSum!.toDouble(), + ratingWidget: RatingWidget( + full: Icon( + Icons.star, + color: CustomColors.accentColor, + ), + half: Icon( + Icons.star_half, + color: CustomColors.accentColor, + ), + empty: Icon( + Icons.star_border, + color: CustomColors.accentColor, + ), + ), + onRatingUpdate: (double value) {}, + unratedColor: Colors.grey[500], + updateOnDrag: false, + tapOnlyMode: false, + ), + + 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, - ) - ], ), ], ), ), - ], - ), + ), + onTap: () => { + Navigator.push( + context, + FadePage( + page: ProductDetailPage(model.finalProducts[index]), + )), + }, + )); + }, + ), + ) + : Container( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Align( + alignment: Alignment.center, + child: Image.asset( + 'assets/images/pharmacy/empty_box.png', + width: 100, + height: 100, ), ), - onTap: () => { - Navigator.push( - context, - FadePage( - page: ProductDetailPage( - model.finalProducts[index]), - )), - }, - )); - }, - ), - ), + Text( + TranslationBase.of(context).noResult, + style: TextStyle( + fontSize: 20.0, +// fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), ) : Expanded( - child: Container( - height: MediaQuery.of(context).size.height * 5.0, - child: ListView.builder( - itemCount: model.finalProducts.length, - itemBuilder: - (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, - ), - ), - ), - 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, - ), - ), - ], - ), - Column( - children: [ - Container( - width: model - .finalProducts[ - index] - .rxMessage != - null - ? MediaQuery.of( - context) - .size - .width / - 3.5 - : 0, - padding: - EdgeInsets.all(4), - decoration: BoxDecoration( - color: - Color(0xffb23838), - borderRadius: - BorderRadius.only( - topLeft: Radius - .circular( - 6)), + child: model.finalProducts.length > 0 + ? Container( + height: MediaQuery.of(context).size.height * 5.0, + child: ListView.builder( + itemCount: model.finalProducts.length, + itemBuilder: (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, + ), + ), + ), + Container( + margin: EdgeInsets.fromLTRB(0, 0, 0, 8), + alignment: Alignment.center, + child: (model.finalProducts[index].images != null && model.finalProducts[index].images!.length > 0) + ? Image.network( + model.finalProducts[index].images![0].src!, + fit: BoxFit.cover, + height: 80, + width: 80, + ) + : Image.asset( + "assets/images/no_image.png", + fit: BoxFit.cover, + height: 80, + width: 80, + ), +// 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, +// ), + ), + ], ), - child: Texts( - model - .finalProducts[ - index] - .rxMessage != - null - ? model - .finalProducts[ - index] - .rxMessage - : "", - color: Colors.white, - regular: true, - fontSize: 10, - fontWeight: - FontWeight.w600, + Column( + children: [ + Container( + width: model.finalProducts[index].rxMessage != null ? MediaQuery.of(context).size.width / 3.70 : 0, + padding: EdgeInsets.all(4), + decoration: BoxDecoration( + color: Color(0xffb23838), + //borderRadius: BorderRadius.only(topLeft: Radius.circular(5)), + ), + child: model.finalProducts[index].rxMessage != null + ? Texts( + projectProvider.isArabic ? model.finalProducts[index].rxMessagen : model.finalProducts[index].rxMessage, + color: Colors.white, + regular: true, + fontSize: 8, + fontWeight: FontWeight.w600, + ) + : Texts(""), +// Texts( +// model.finalProducts[index].rxMessage != null ? model.finalProducts[index].rxMessage : "", +// color: Colors.white, +// regular: true, +// fontSize: 10, +// fontWeight: FontWeight.w600, +// ), + ), + ], ), - ), - ], - ), - ], - ), - 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, + height: 100.0, + margin: EdgeInsets.symmetric( + horizontal: 6, + vertical: 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, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceAround, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: 4.0, + ), + Container( + width: MediaQuery.of(context).size.width * 0.55, + child: Texts( + projectViewModel.isArabic ? model.finalProducts[index].namen : model.finalProducts[index].name, +// model.finalProducts[index].name, + regular: true, + fontSize: 13.2, + fontWeight: FontWeight.w500, + maxLines: 5, + ), + ), + SizedBox( + height: 8.0, + ), + 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), + RatingBar( + initialRating: model.finalProducts[index].approvedRatingSum!.toDouble(), + ratingWidget: RatingWidget( + full: Icon( + Icons.star, + color: CustomColors.accentColor, + ), + half: Icon( + Icons.star_half, + color: CustomColors.accentColor, + ), + empty: Icon( + Icons.star_border, + color: CustomColors.accentColor, + ), + ), + onRatingUpdate: (double value) {}, + unratedColor: Colors.grey[500], + updateOnDrag: false, + tapOnlyMode: false, + ), + + 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: CustomColors.green, + ), + onPressed: () async { + if (model.finalProducts[index].isRx == false) { + GifLoaderDialogUtils.showMyDialog(context); + await addToCartFunction(1, model.finalProducts[index].id); + GifLoaderDialogUtils.hideDialog(context); + // Navigator.push(context, FadePage(page: CartOrderPage())); + utils.Utils.navigateToCartPage(); + } else { + AppToast.showErrorToast(message: TranslationBase.of(context).needPrescription); + } +// + }), + ) + : Container(), ], ), ), - ], + onTap: () => { + Navigator.push( + context, + FadePage( + page: ProductDetailPage(model.finalProducts[index]), + )), + }, + ); + }), + ) + : Container( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Align( + alignment: Alignment.center, + child: Image.asset( + 'assets/images/pharmacy/empty_box.png', + width: 100, + height: 100, + ), ), - ), - onTap: () => { - Navigator.push( - context, - FadePage( - page: ProductDetailPage( - model.finalProducts[index]), - )), - }, - ); - }), - ), + Text( + TranslationBase.of(context).noResult, + style: TextStyle( + fontSize: 20.0, +// fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), ) ], ), ), )); } + + addToCartFunction(quantity, itemID) async { + ProductDetailViewModel x = new ProductDetailViewModel(); + await x.addToCartData(quantity, itemID, context); + } } diff --git a/lib/pages/insurance/AttachInsuranceCardImageDialog.dart b/lib/pages/insurance/AttachInsuranceCardImageDialog.dart index 20e17593..93e74183 100644 --- a/lib/pages/insurance/AttachInsuranceCardImageDialog.dart +++ b/lib/pages/insurance/AttachInsuranceCardImageDialog.dart @@ -1,33 +1,37 @@ import 'dart:io'; + +import 'package:diplomaticquarterapp/pages/insurance/UpdateInsuranceManually.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/widgets/bottom_options/BottomSheet.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; class AttachInsuranceCardImageDialog extends StatefulWidget { - final String name; - final String fileNo; - final Function(File file, String image) image; + String name; + String fileNo; + String? identificationNo; + String? mobileNo; + Function(File file, String image) image; + bool isBirthNotification; - const AttachInsuranceCardImageDialog( - {Key key, this.name, this.fileNo, this.image}) - : super(key: key); + AttachInsuranceCardImageDialog({Key? key, required this.name, required this.fileNo, this.identificationNo, this.mobileNo, required this.image, this.isBirthNotification = false}) : super(key: key); @override - _AttachInsuranceCardImageDialogState createState() => - _AttachInsuranceCardImageDialogState(); + _AttachInsuranceCardImageDialogState createState() => _AttachInsuranceCardImageDialogState(); } -class _AttachInsuranceCardImageDialogState - extends State { +class _AttachInsuranceCardImageDialogState extends State { @override void initState() { super.initState(); } - String image; - File file; + String? image = ""; + late File file; @override Widget build(BuildContext context) { @@ -36,39 +40,61 @@ class _AttachInsuranceCardImageDialogState Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ - Texts(TranslationBase.of(context).attachInsuraceImage), + Text( + widget.isBirthNotification ? TranslationBase.of(context).scanID : TranslationBase.of(context).updateInsurCards, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + ), + ), Divider(), - Texts(widget.name), + Padding( + padding: const EdgeInsets.only(left: 8, right: 8), + child: Text( + widget.name, + style: TextStyle( + fontSize: 14, + letterSpacing: -0.48, + ), + ), + ), SizedBox( height: 3, ), - Texts(TranslationBase.of(context).fileNo + " " + widget.fileNo), + Text( + TranslationBase.of(context).fileNo + " " + widget.fileNo, + style: TextStyle( + fontSize: 14, + letterSpacing: -0.48, + ), + ), SizedBox( height: 5.0, ), InkWell( onTap: () { - ImageOptions.showImageOptions(context, (String image,File file) { + ImageOptions.showImageOptions(context, (String image, File file) { setState(() { this.image = image; this.file = file; }); }); }, - child: image == null + child: image!.isEmpty ? Padding( - padding: const EdgeInsets.all(18.0), - child: Container( + padding: const EdgeInsets.all(18.0), + child: Container( width: double.maxFinite, - height: 250, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(2), - border: Border.all(color: Colors.grey, width: 1.5)), + height: 200, + decoration: BoxDecoration(borderRadius: BorderRadius.circular(2), border: Border.all(color: Colors.grey, width: 1.5)), child: Column( crossAxisAlignment: CrossAxisAlignment.center, - // mainAxisAlignment: MainAxisAlignment., + // mainAxisAlignment: MainAxisAlignment., children: [ - SizedBox(height: 25,), + SizedBox( + height: 25, + ), Icon( Icons.camera_enhance_rounded, size: 85, @@ -77,19 +103,94 @@ class _AttachInsuranceCardImageDialogState mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.attach_file), - Texts(TranslationBase.of(context).selectAttachment.toUpperCase()) + Text( + TranslationBase.of(context).selectAttachment.toUpperCase(), + style: TextStyle( + fontSize: 12, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + ), + ) ], ), ], ), ), - ) + ) : Image.file( file, fit: BoxFit.fill, - height: 250, + height: 250, ), ), + if (!widget.isBirthNotification) + Text( + "OR", + style: TextStyle( + fontSize: 16, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + ), + ), + if (!widget.isBirthNotification) + Padding( + padding: const EdgeInsets.all(18.0), + child: DefaultButton( + TranslationBase.of(context).updateInsuranceManually, + () { + Navigator.pop(context); + Navigator.push( + context, + FadePage( + page: UpdateInsuranceManually( + patientIdentificationNo: '', + patientMobileNumber: '', + patientID: 0, + ), + ), + ); + }, + textColor: Colors.white, + color: CustomColors.accentColor, + ), + ), + Text( + "OR", + style: TextStyle( + fontSize: 16, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + ), + ), + Padding( + padding: const EdgeInsets.all(18.0), + child: Text( + TranslationBase.of(context).habibCallCenter, + style: TextStyle( + fontSize: 16, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + ), + ), + // DefaultButton( + // TranslationBase.of(context).updateInsuranceManually, + // () { + // Navigator.pop(context); + // Navigator.push( + // context, + // FadePage( + // page: UpdateInsuranceManually( + // patientIdentificationNo: widget.identificationNo, + // patientMobileNumber: widget.mobileNo, + // patientID: num.parse(widget.fileNo), + // ), + // ), + // ); + // }, + // textColor: Colors.white, + // color: CustomColors.accentColor, + // ), + ), SizedBox( height: 25.0, ), @@ -106,9 +207,14 @@ class _AttachInsuranceCardImageDialogState padding: const EdgeInsets.all(8.0), child: Container( child: Center( - child: Texts( + child: Text( TranslationBase.of(context).cancel.toUpperCase(), - color: Colors.red, + style: TextStyle( + fontSize: 12, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + color: Colors.red, + ), ), ), ), @@ -124,15 +230,23 @@ class _AttachInsuranceCardImageDialogState flex: 1, child: InkWell( onTap: () { - Navigator.pop(context); - widget.image(file, image); + if (file != null && image != null) { + Navigator.pop(context); + widget.image(file, image!); + } else { + AppToast.showErrorToast(message: TranslationBase.of(context).noInsuranceCardAttached); + } }, child: Padding( padding: const EdgeInsets.all(8.0), child: Center( - child: Texts( - TranslationBase.of(context).ok, - fontWeight: FontWeight.w400, + child: Text( + TranslationBase.of(context).ok.toUpperCase(), + style: TextStyle( + fontSize: 12, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + ), )), ), ), diff --git a/lib/pages/insurance/UpdateInsuranceManually.dart b/lib/pages/insurance/UpdateInsuranceManually.dart new file mode 100644 index 00000000..637d7c5f --- /dev/null +++ b/lib/pages/insurance/UpdateInsuranceManually.dart @@ -0,0 +1,277 @@ +import 'package:diplomaticquarterapp/core/model/insurance/insuranceManualUpdateRequest.dart'; +import 'package:diplomaticquarterapp/core/service/insurance_service.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/locator.dart'; +import 'package:diplomaticquarterapp/models/insurance/getInsuranceCompaniesModel.dart'; +import 'package:diplomaticquarterapp/models/insurance/insuranceCompaniesSchemeModel.dart'; +import 'package:diplomaticquarterapp/pages/medical/balance/new_text_Field.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/radio_selection_dialog.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class UpdateInsuranceManually extends StatefulWidget { + String patientIdentificationNo; + String patientMobileNumber; + int patientID; + + UpdateInsuranceManually({required this.patientIdentificationNo, required this.patientMobileNumber, required this.patientID}); + + @override + State createState() => _UpdateInsuranceManuallyState(); +} + +class _UpdateInsuranceManuallyState extends State { + TextEditingController _nationalIDTextController = TextEditingController(); + TextEditingController _cardHolderNameTextController = TextEditingController(); + TextEditingController _membershipNoTextController = TextEditingController(); + TextEditingController _policyNoTextController = TextEditingController(); + late ProjectViewModel projectViewModel; + + InsuranceCardService _insuranceCardService = locator(); + + List insuranceCompaniesList = []; + List insuranceCompaniesSchemesList = []; + + int _selectedInsuranceCompanyIndex = -1; + int _selectedInsuranceCompanySchemeIndex = -1; + + late InsuranceCompaniesGetModel selectedInsuranceCompanyObj; + late InsuranceCompaniesSchemeModel selectedInsuranceCompaniesSchemesObj; + + @override + void initState() { + WidgetsBinding.instance.addPostFrameCallback((_) { + getInsuranceCompanies(); + }); + super.initState(); + } + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + _nationalIDTextController.text = widget.patientIdentificationNo; + return AppScaffold( + isShowAppBar: true, + isShowDecPage: false, + appBarTitle: TranslationBase.of(context).updateInsurCards, + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: CustomColors.appBackgroudGreyColor, + body: SingleChildScrollView( + child: Padding( + padding: EdgeInsets.all(21), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + TranslationBase.of(context).enterInsuranceDetails, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 16, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + ), + ), + SizedBox(height: 12), + InkWell( + onTap: () { + confirmSelectInsuranceCompanyDialog(); + }, + child: Container( + padding: EdgeInsets.all(8), + width: double.infinity, + height: 65, + decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), color: Colors.white), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + selectedInsuranceCompanyObj != null ? selectedInsuranceCompanyObj.companyName! : TranslationBase.of(context).insuranceCompany, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + letterSpacing: -0.46, + ), + ), + Icon(Icons.arrow_drop_down) + ], + ), + ), + ), + SizedBox(height: 12), + NewTextFields( + hintText: TranslationBase.of(context).nationalIdNumber, + controller: _nationalIDTextController, + readOnly: true, + ), + SizedBox(height: 12), + NewTextFields( + hintText: TranslationBase.of(context).cardHolderName, + controller: _cardHolderNameTextController, + readOnly: false, + ), + SizedBox(height: 12), + NewTextFields( + hintText: TranslationBase.of(context).membershipNo, + controller: _membershipNoTextController, + readOnly: false, + ), + SizedBox(height: 12), + NewTextFields( + hintText: TranslationBase.of(context).insurancePolicyNo, + controller: _policyNoTextController, + readOnly: false, + ), + SizedBox(height: 12), + InkWell( + onTap: () { + confirmSelectInsuranceCompanySchemeDialog(); + }, + child: Container( + padding: EdgeInsets.all(8), + width: double.infinity, + height: 65, + decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), color: Colors.white), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + selectedInsuranceCompaniesSchemesObj != null ? selectedInsuranceCompaniesSchemesObj.subCategoryDesc! : TranslationBase.of(context).insuranceClassName, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + letterSpacing: -0.46, + ), + ), + Icon(Icons.arrow_drop_down) + ], + ), + ), + ), + ], + ), + ), + ), + bottomSheet: Container( + color: Theme.of(context).scaffoldBackgroundColor, + padding: EdgeInsets.all(18), + child: DefaultButton( + TranslationBase.of(context).submit, + () { + if (isFormValid()) + submitManualInsuranceUpdateRequest(); + else + AppToast.showErrorToast(message: TranslationBase.of(context).enterInsuranceDetails); + }, + disabledColor: Colors.grey, + ), + ), + ); + } + + bool isFormValid() { + if (selectedInsuranceCompanyObj != null && + _cardHolderNameTextController.text.isNotEmpty && + _membershipNoTextController.text.isNotEmpty && + _policyNoTextController.text.isNotEmpty && + selectedInsuranceCompaniesSchemesObj != null) { + return true; + } else { + return false; + } + } + + void confirmSelectInsuranceCompanyDialog() { + List list = [ + for (int i = 0; i < insuranceCompaniesList.length; i++) RadioSelectionDialogModel(insuranceCompaniesList[i].companyName!, i), + ]; + showDialog( + context: context, + builder: (cxt) => RadioSelectionDialog( + listData: list, + selectedIndex: _selectedInsuranceCompanyIndex, + isScrollable: true, + isShowSearch: true, + onValueSelected: (index) { + _selectedInsuranceCompanyIndex = index; + selectedInsuranceCompanyObj = insuranceCompaniesList[index]; + setState(() {}); + getInsuranceScheme(); + }, + ), + ); + } + + void confirmSelectInsuranceCompanySchemeDialog() { + List list = [ + for (int i = 0; i < insuranceCompaniesSchemesList.length; i++) RadioSelectionDialogModel(insuranceCompaniesSchemesList[i].subCategoryDesc!, i), + ]; + showDialog( + context: context, + builder: (cxt) => RadioSelectionDialog( + listData: list, + selectedIndex: _selectedInsuranceCompanySchemeIndex, + isScrollable: true, + onValueSelected: (index) { + _selectedInsuranceCompanySchemeIndex = index; + selectedInsuranceCompaniesSchemesObj = insuranceCompaniesSchemesList[index]; + setState(() {}); + }, + ), + ); + } + + void getInsuranceCompanies() { + GifLoaderDialogUtils.showMyDialog(context); + _insuranceCardService.getInsuranceCompanies().then((value) { + value.forEach((result) { + insuranceCompaniesList.add(InsuranceCompaniesGetModel.fromJson(result)); + }); + GifLoaderDialogUtils.hideDialog(context); + }); + } + + void submitManualInsuranceUpdateRequest() { + GifLoaderDialogUtils.showMyDialog(context); + + InsuranceManualUpdateRequest insuranceManualUpdateRequest = new InsuranceManualUpdateRequest(); + + insuranceManualUpdateRequest.projectID = selectedInsuranceCompanyObj.projectID; + insuranceManualUpdateRequest.requestType = 2; + insuranceManualUpdateRequest.mobileNo = widget.patientMobileNumber; + insuranceManualUpdateRequest.cardHolderName = _cardHolderNameTextController.text; + insuranceManualUpdateRequest.insuranceCompanyName = selectedInsuranceCompanyObj.companyName; + insuranceManualUpdateRequest.memberShipNo = _membershipNoTextController.text; + insuranceManualUpdateRequest.policyNo = _policyNoTextController.text; + insuranceManualUpdateRequest.patientIdentificationID = widget.patientIdentificationNo; + insuranceManualUpdateRequest.schemeClass = selectedInsuranceCompaniesSchemesObj.subCategoryDesc; + insuranceManualUpdateRequest.setupID = selectedInsuranceCompanyObj.setupID; + insuranceManualUpdateRequest.patientID = widget.patientID; + + _insuranceCardService.submitManualInsuranceUpdateRequest(insuranceManualUpdateRequest).then((value) { + print(value); + AppToast.showSuccessToast(message: TranslationBase.of(context).insuranceRequestSubmit); + Navigator.pop(context); + GifLoaderDialogUtils.hideDialog(context); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err.toString()); + }); + } + + void getInsuranceScheme() { + GifLoaderDialogUtils.showMyDialog(context); + _insuranceCardService.getInsuranceSchemes(selectedInsuranceCompanyObj.projectID!, selectedInsuranceCompanyObj.companyID!).then((value) { + value.forEach((result) { + insuranceCompaniesSchemesList.add(InsuranceCompaniesSchemeModel.fromJson(result)); + }); + GifLoaderDialogUtils.hideDialog(context); + }); + } +} diff --git a/lib/pages/insurance/insurance_approval_detail_screen.dart b/lib/pages/insurance/insurance_approval_detail_screen.dart new file mode 100644 index 00000000..b17da0cf --- /dev/null +++ b/lib/pages/insurance/insurance_approval_detail_screen.dart @@ -0,0 +1,116 @@ +import 'package:diplomaticquarterapp/core/model/insurance/insurance_approval.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/widgets/avatar/large_avatar.dart'; +import 'package:diplomaticquarterapp/widgets/my_rich_text.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class InsuranceApprovalDetail extends StatelessWidget { + final InsuranceApprovalModel insuranceApprovalModel; + + InsuranceApprovalDetail({Key? key, required this.insuranceApprovalModel}) : super(key: key); + + @override + Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + + return AppScaffold( + isShowAppBar: true, + showNewAppBar: true, + showNewAppBarTitle: true, + appBarTitle: TranslationBase.of(context).insuranceApproval, + description: TranslationBase.of(context).infoApprovals, + infoList: TranslationBase.of(context).infoApprovalPoints, + body: SingleChildScrollView( + physics: BouncingScrollPhysics(), + padding: EdgeInsets.all(21), + child: Container( + padding: EdgeInsets.fromLTRB(16, 12, 16, 12), + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(10.0)), + boxShadow: [ + BoxShadow( + color: Color(0xff000000).withOpacity(.05), + blurRadius: 27, + offset: Offset(0, -3), + ), + ], + color: Colors.white), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + insuranceApprovalModel.approvalStatusDescption!, + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: insuranceApprovalModel.status == 9 ? Color(0xff359846) : Color(0xffD02127), letterSpacing: -0.4, height: 18 / 10), + ), + Text( + insuranceApprovalModel.doctorName!, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + color: Color(0xff2E303A), + letterSpacing: -0.64, + ), + ), + SizedBox(height: 6), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LargeAvatar( + name: insuranceApprovalModel.doctorName!, + url: insuranceApprovalModel.doctorImageURL!, + width: 48, + height: 48, + ), + SizedBox(width: 12), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + MyRichText(TranslationBase.of(context).clinic + ":", insuranceApprovalModel?.clinicName ?? "", projectViewModel.isArabic), + MyRichText(TranslationBase.of(context).approvalNo, insuranceApprovalModel?.approvalNo.toString() ?? "", projectViewModel.isArabic), + MyRichText(TranslationBase.of(context).unusedCount, insuranceApprovalModel?.unUsedCount.toString() ?? "", projectViewModel.isArabic), + MyRichText(TranslationBase.of(context).companyName, insuranceApprovalModel?.companyName ?? "", projectViewModel.isArabic), + SizedBox(height: 6), + MyRichText(TranslationBase.of(context).receiptOn, DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(insuranceApprovalModel.receiptOn!)) ?? "", + projectViewModel.isArabic), + MyRichText(TranslationBase.of(context).expiryOn, DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(insuranceApprovalModel.expiryDate!)) ?? "", + projectViewModel.isArabic), + ], + ), + ), + ], + ), + SizedBox(height: 21), + Table(columnWidths: { + 0: FlexColumnWidth(1.8), + 1: FlexColumnWidth(1), + 2: FlexColumnWidth(1), + }, children: [ + TableRow( + children: [ + Utils.tableColumnTitle(TranslationBase.of(context).procedure), + Utils.tableColumnTitle(TranslationBase.of(context).status), + Utils.tableColumnTitle(TranslationBase.of(context).usageStatus) + ], + ), + TableRow( + children: [ + Utils.tableColumnValue(insuranceApprovalModel?.apporvalDetails?.procedureName ?? '', isLast: true, mProjectViewModel: projectViewModel), + Utils.tableColumnValue(insuranceApprovalModel?.apporvalDetails?.status ?? '', isLast: true, mProjectViewModel: projectViewModel), + Utils.tableColumnValue(insuranceApprovalModel?.apporvalDetails?.isInvoicedDesc ?? '', isLast: true, mProjectViewModel: projectViewModel), + ], + ), + ]) + ], + ), + ), + ), + ); + } +} diff --git a/lib/pages/insurance/insurance_approval_screen.dart b/lib/pages/insurance/insurance_approval_screen.dart index d81e704e..d19a16db 100644 --- a/lib/pages/insurance/insurance_approval_screen.dart +++ b/lib/pages/insurance/insurance_approval_screen.dart @@ -1,417 +1,188 @@ -import 'package:diplomaticquarterapp/config/size_config.dart'; import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; import 'package:diplomaticquarterapp/core/viewModels/insurance_card_View_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/extensions/string_extensions.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/avatar/large_avatar.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/my_rich_text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:diplomaticquarterapp/widgets/others/rounded_container.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; import '../base/base_view.dart'; +import 'insurance_approval_detail_screen.dart'; class InsuranceApproval extends StatefulWidget { - int appointmentNo; + int? appointmentNo; - InsuranceApproval({this.appointmentNo}); + InsuranceApproval({ this.appointmentNo}); @override _InsuranceApprovalState createState() => _InsuranceApprovalState(); } class _InsuranceApprovalState extends State { - List imagesInfo = List(); + List imagesInfo =[]; @override Widget build(BuildContext context) { - imagesInfo.add(ImagesInfo( - imageEn: - 'https://hmgwebservices.com/Images/MobileApp/imges-info/apporvals/en/0.png', - imageAr: - 'https://hmgwebservices.com/Images/MobileApp/imges-info/apporvals/ar/0.png')); - imagesInfo.add(ImagesInfo( - imageEn: - 'https://hmgwebservices.com/Images/MobileApp/imges-info/apporvals/en/1.png', - imageAr: - 'https://hmgwebservices.com/Images/MobileApp/imges-info/apporvals/ar/1.png')); + ProjectViewModel projectViewModel = Provider.of(context); + imagesInfo + .add(ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/apporvals/en/0.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/apporvals/ar/0.png')); + imagesInfo + .add(ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/apporvals/en/1.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/apporvals/ar/1.png')); return BaseView( - onModelReady: widget.appointmentNo != null - ? (model) => - model.getInsuranceApproval(appointmentNo: widget.appointmentNo) - : (model) => model.getInsuranceApproval(), - builder: (BuildContext context, InsuranceViewModel model, Widget child) => - AppScaffold( - isShowAppBar: true, - baseViewModel: model, - appBarTitle: TranslationBase.of(context).approvals, - description: TranslationBase.of(context).infoApprovals, - infoList: TranslationBase.of(context).infoApprovalPoints, - imagesInfo: imagesInfo, - body: SingleChildScrollView( - child: Container( - margin: EdgeInsets.only( - left: SizeConfig.screenWidth * 0.004, - right: SizeConfig.screenWidth * 0.004, - top: SizeConfig.screenWidth * 0.04, - ), - child: Column( - children: [ - Container( - width: double.infinity, - height: SizeConfig.screenHeight * 0.09, - color: Color(0xffEEEEEE), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - Texts( - TranslationBase.of(context).totalApproval, - color: Color(0xff60688B), - fontSize: 19.0, - fontWeight: FontWeight.w600, - ), - if (model.insuranceApproval.length > 0) - Container( - width: 60, - height: 40, - decoration: BoxDecoration( - color: Theme.of(context).primaryColor, - borderRadius: BorderRadius.circular(19.0)), - child: Center( - child: Texts( - model.insuranceApproval[0].unUsedCount - .toString(), - color: Colors.white, fontSize: 17.0, + onModelReady: widget.appointmentNo != null ? (model) => model.getInsuranceApproval(appointmentNo: widget.appointmentNo) : (model) => model.getInsuranceApproval(), + builder: (BuildContext _context, InsuranceViewModel model, Widget? child) => AppScaffold( + isShowAppBar: true, + showNewAppBar: true, + baseViewModel: model, + showNewAppBarTitle: true, + appBarTitle: TranslationBase.of(context).insuranceApprovalSubtitle, + description: TranslationBase.of(context).infoApprovals, + infoList: TranslationBase.of(context).infoApprovalPoints, + imagesInfo: imagesInfo, + body: model.insuranceApproval.length > 0 + ? ListView.separated( + padding: EdgeInsets.all(21), + physics: BouncingScrollPhysics(), + itemBuilder: (_, index) { + Color _patientStatusColor; + String _patientStatusString; + + if (model.insuranceApproval[index].isLiveCareAppointment!) { + _patientStatusColor = Color(0xff2E303A); + _patientStatusString = TranslationBase.of(context).liveCare.capitalizeFirstofEach; + } else if (!model.insuranceApproval[index].isInOutPatient!) { + _patientStatusColor = Color(0xffD02127); + _patientStatusString = TranslationBase.of(context).inPatient.capitalizeFirstofEach; + } else { + _patientStatusString = TranslationBase.of(context).outpatient.capitalizeFirstofEach; + _patientStatusColor = Color(0xffa9a089); + } + return InkWell( + onTap: () { + Navigator.push(context, FadePage(page: InsuranceApprovalDetail(insuranceApprovalModel: model.insuranceApproval[index]))); + }, + child: Container( + 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: _patientStatusColor), + child: Row( + children: [ + SizedBox( + width: 16, + child: RotatedBox( + quarterTurns: 3, + child: Text( + _patientStatusString, + style: TextStyle(fontSize: 10, fontWeight: FontWeight.w700, color: Colors.white, letterSpacing: -0.2, height: 16 / 10), ), - )) - ], - )), - ...List.generate( - model.insuranceApproval.length, - (index) => RoundedContainer( - backgroundColor: Colors.white, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - ExpansionTile( - title: Container( - //height: 120.0, - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - model.insuranceApproval[index].patientDescription == "In Patient" - ? Container( - decoration: BoxDecoration( - color: Theme.of(context).primaryColor, - borderRadius: - BorderRadius.circular( - 16.0)), - width: 115.0, - padding: - EdgeInsets.only(left: 11.5), - child: Center( - child: Texts( - TranslationBase.of(context).inPatient, - color: Colors.white, - ), - ), - ) - : Container( - decoration: BoxDecoration( - color: Color(0xff505A5D), - borderRadius: - BorderRadius.circular( - 16.0)), - width: 115.0, - padding: - EdgeInsets.only(left: 11.5), - child: Center( - child: Texts( - TranslationBase.of(context).outpatient, - color: Colors.white, - ), - ), - ), - Padding( - padding: EdgeInsets.symmetric( - vertical: 10.0), - child: Texts( - model.insuranceApproval[index] - .clinicName, - fontSize: 20.0, - color: Color(0xff60686B), + ), + ), + Expanded( + child: Container( + padding: EdgeInsets.fromLTRB(12, 10, 12, 10), + decoration: BoxDecoration( + border: Border.all(color: Colors.white, width: 1), + borderRadius: BorderRadius.only( + bottomRight: Radius.circular(10.0), + topRight: Radius.circular(10.0), + ), + color: Colors.white), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + model.insuranceApproval[index].approvalStatusDescption!, + style: TextStyle( + fontSize: 12, fontWeight: FontWeight.w600, - ), - ), - Texts( - model.insuranceApproval[index] - .doctorName, - fontSize: 17.0, + color: model.insuranceApproval[index].status == 9 ? Color(0xff359846) : Color(0xffD02127), + letterSpacing: -0.4, + height: 18 / 10), + ), + Text( + model.insuranceApproval[index].doctorName!, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + color: Color(0xff2E303A), + letterSpacing: -0.64, ), - ], - ), - ), - children: [ - Padding( - padding: EdgeInsets.symmetric( - vertical: 12.0, horizontal: 12.0), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Row( - children: [ - Texts( - TranslationBase.of(context).approvalNo, - fontSize: 18.0, - ), - Texts(model.insuranceApproval[index].approvalNo.toString(), - fontSize: 18.0, - fontWeight: FontWeight.w600,), - ], - ), - Divider( - color: Colors.black, - height: 25.0, - thickness: 1.0, - ), - Row( - children: [ - Texts( - TranslationBase.of(context).procedureStatus , - fontSize: 17.5, - ), - SizedBox(width: 12,), - Texts( - model.insuranceApproval[index].approvalStatusDescption, - fontWeight: FontWeight.w600, - fontSize: 17.5, - ), - ], - ), - Divider( - color: Colors.black, - height: 25.0, - thickness: 1.0, - ), - Row( - children: [ - Texts( - TranslationBase.of(context).unusedCount, - fontSize: 17.5, - ), - Texts( - model.insuranceApproval[index].unUsedCount.toString(), - fontSize: 17.5, - fontWeight: FontWeight.w600, - ), - ], - ), - Divider( - color: Colors.black, - height: 25.0, - thickness: 1.0, - ), -// Text( -// 'Company Name: ' + -// model.insuranceApproval[index] -// .companyName == -// null -// ? '000' -// : model -// .insuranceApproval[index].companyName, -// style: TextStyle( -// fontSize: 17.5, -// fontWeight: FontWeight.w600), -// ), - Texts( - TranslationBase.of(context).companyName, - fontWeight: FontWeight.w600, - fontSize: 17.5, - ), - - Divider( - color: Colors.black, - height: 25.0, - thickness: 1.0, - ), - Row( - children: [ - Texts( - TranslationBase.of(context).receiptOn , - fontSize: 17.5, - fontWeight: FontWeight.w600, - - ), - Texts( - convertDateFormat(model.insuranceApproval[index].rceiptOn), - fontSize: 17.5, - fontWeight: FontWeight.w600, - - ), - ], - ), - Divider( - color: Colors.black, - height: 25.0, - thickness: 1.0, - ), - Row( - children: [ - Texts( - TranslationBase.of(context).expiryDate, - fontSize: 17.5, - fontWeight: FontWeight.w600, - - ), - Texts( - convertDateFormat(model.insuranceApproval[index].expiryDate), - fontSize: 17.5, - fontWeight: FontWeight.w600, - - ), - ], - ), - Divider( - color: Colors.black, - height: 55.0, - thickness: 1.2, + ), + SizedBox(height: 6), + Row( + children: [ + LargeAvatar( + name: model.insuranceApproval[index].doctorName!, + url: model.insuranceApproval[index].doctorImageURL!, + width: 48, + height: 48, ), - IntrinsicHeight( - child: Row( - crossAxisAlignment: - CrossAxisAlignment.center, - children: [ - Expanded( - flex: 1, - child: Column( - children: [ - Text(TranslationBase.of( - context) - .procedureName), - Padding( - padding: EdgeInsets.only( - top: SizeConfig - .heightMultiplier * - 3.0), - child: Text( - model - .insuranceApproval[ - index] - .approvalDetails == - null - ? '' - : model - .insuranceApproval[ - index] - .approvalDetails - .procedureName, - style: TextStyle( - fontWeight: - FontWeight.w600, - fontSize: 15.5), - ), - ), - ], - ), - ), - VerticalDivider( - width: 10.0, - thickness: 1.2, - color: Colors.black, - ), - Expanded( - flex: 1, - child: Column( - children: [ - Text(TranslationBase.of( - context) - .procedureStatus), - Padding( - padding: EdgeInsets.only( - top: SizeConfig - .heightMultiplier * - 3.0), - child: Text( - model - .insuranceApproval[ - index] - .approvalDetails == - null - ? '' - : model - .insuranceApproval[ - index] - .approvalDetails - .status, - style: TextStyle( - fontSize: 17.5, - fontWeight: - FontWeight - .w600), - ), - ), - ], - ), - ), - VerticalDivider( - width: 2.3, - thickness: 1.2, - color: Colors.black, - ), - Expanded( - flex: 1, - child: Column( - children: [ - Text(TranslationBase.of( - context) - .usageStatus), - Padding( - padding: EdgeInsets.only( - top: SizeConfig - .heightMultiplier * - 3.0), - child: Text( - model - .insuranceApproval[ - index] - .approvalDetails == - null - ? '' - : model - .insuranceApproval[ - index] - .approvalDetails - .isInvoicedDesc, - style: TextStyle( - fontWeight: - FontWeight.w600, - fontSize: 17.5), - ), - ), - ], - ), - ), + SizedBox(width: 12), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + MyRichText(TranslationBase.of(context).clinic + ":", model.insuranceApproval[index].clinicName != null ? model.insuranceApproval[index].clinicName!.toLowerCase().capitalizeFirstofEach : "", + projectViewModel.isArabic), + MyRichText(TranslationBase.of(context).approvalNo, model.insuranceApproval[index].approvalNo.toString() ?? "", projectViewModel.isArabic), ], ), ), - Divider( - color: Colors.black, - height: 25.0, - thickness: 1.0, - ), + Container( + height: 48, + alignment: Alignment.bottomRight, + child: Icon( + Icons.arrow_forward, + color: Color(0xff2E303A), + ), + ) ], - ), - ), - ], + ) + ], + ), ), - ], - ), - )), - ], - ), - ), - ), + ), + ], + ), + ), + ); + }, + separatorBuilder: (context, index) => SizedBox(height: 12), + itemCount: model.insuranceApproval.length) + : getNoDataWidget(context)), + ); + } + + Widget sideBadge(String title, int color) { + return Container( + decoration: BoxDecoration( + color: Color(color), + borderRadius: BorderRadius.circular(16.0), + ), + width: 115.0, + padding: EdgeInsets.only(top: 1, bottom: 1), + alignment: Alignment.center, + child: Texts( + title, + color: Colors.white, ), ); } @@ -423,13 +194,8 @@ class _InsuranceApprovalState extends State { final startIndex = Date.indexOf(start); final endIndex = Date.indexOf(end, startIndex + start.length); - var date = new DateTime.fromMillisecondsSinceEpoch( - int.parse(Date.substring(startIndex + start.length, endIndex))); - String newDate = date.year.toString() + - "-" + - date.month.toString().padLeft(2, '0') + - "-" + - date.day.toString().padLeft(2, '0'); + var date = new DateTime.fromMillisecondsSinceEpoch(int.parse(Date.substring(startIndex + start.length, endIndex))); + String newDate = date.year.toString() + "-" + date.month.toString().padLeft(2, '0') + "-" + date.day.toString().padLeft(2, '0'); return newDate.toString(); } diff --git a/lib/pages/insurance/insurance_card_screen.dart b/lib/pages/insurance/insurance_card_screen.dart index da66c572..fbe0c87e 100644 --- a/lib/pages/insurance/insurance_card_screen.dart +++ b/lib/pages/insurance/insurance_card_screen.dart @@ -1,16 +1,17 @@ -import 'package:diplomaticquarterapp/config/size_config.dart'; import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; import 'package:diplomaticquarterapp/core/service/insurance_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/insurance_card_View_model.dart'; 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/widgets/buttons/button.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/others/app_scaffold_widget.dart'; -import 'package:diplomaticquarterapp/widgets/others/rounded_container.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -18,9 +19,9 @@ import 'package:flutter/material.dart'; import '../base/base_view.dart'; class InsuranceCard extends StatefulWidget { - int appointmentNo; + int? appointmentNo; - InsuranceCard({this.appointmentNo}); + InsuranceCard({ this.appointmentNo}); @override _InsuranceCardState createState() => _InsuranceCardState(); @@ -28,201 +29,169 @@ class InsuranceCard extends StatefulWidget { class _InsuranceCardState extends State { InsuranceCardService _insuranceCardService = locator(); - List imagesInfo = List(); + List imagesInfo =[]; @override Widget build(BuildContext context) { imagesInfo.add(ImagesInfo( - imageEn: - 'https://hmgwebservices.com/Images/MobileApp/imges-info/insurance-card/en/0.png', - imageAr: - 'https://hmgwebservices.com/Images/MobileApp/imges-info/insurance-card/ar/0.png')); + imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/insurance-card/en/0.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/insurance-card/ar/0.png')); return BaseView( onModelReady: (model) => model.getInsurance(), - builder: (BuildContext context, InsuranceViewModel model, Widget child) => - AppScaffold( + builder: (BuildContext context, InsuranceViewModel model, Widget? child) => AppScaffold( isShowAppBar: true, baseViewModel: model, + showHomeAppBarIcon: false, appBarTitle: TranslationBase.of(context).insuranceCards, description: TranslationBase.of(context).infoInsuranceCards, infoList: TranslationBase.of(context).infoInsuranceCardsPoints, imagesInfo: imagesInfo, + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: CustomColors.appBackgroudGreyColor, + floatingActionButton: FloatingActionButton.extended( + onPressed: () { + Navigator.push(context, FadePage(page: InsuranceUpdate())); + }, + backgroundColor: CustomColors.accentColor, + label: Text(TranslationBase.of(context).update, style: TextStyle(fontSize: 12.0, fontWeight: FontWeight.bold)), + ), body: Container( - margin: EdgeInsets.only( - left: SizeConfig.screenWidth * 0.004, - right: SizeConfig.screenWidth * 0.004, - top: SizeConfig.screenWidth * 0.04), - child: ListView.builder( - itemCount: model.insurance == null ? 0 : model.insurance.length, - itemBuilder: (BuildContext context, int index) { - return RoundedContainer( - backgroundColor: Colors.white, + child: ListView.separated( + itemCount: model.insurance == null ? 0 : model.insurance.length, + itemBuilder: (BuildContext context, int index) { + return Container( + width: double.infinity, + padding: EdgeInsets.only( + left: 10, + right: 10, + top: index == 0 ? 10 : 0, + bottom: index == model.insurance.length - 1 ? 100 : 0, + ), + child: Container( + decoration: cardRadius(12), child: Padding( - padding: const EdgeInsets.all(8.0), + padding: const EdgeInsets.all(12.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, - children: [ - ExpansionTile( - title: Container( - height: 65.0, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: EdgeInsets.symmetric(vertical: 15.0), - child: Texts( - model.insurance[index].groupName, - ), + children: [ + Text( + model.insurance[index].groupName!, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, letterSpacing: -0.64), + ), + mHeight(8), + Text( + TranslationBase.of(context).companyName + model.insurance[index].companyName!, + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, letterSpacing: -0.48), + ), + Divider( + thickness: 2, + color: Colors.black, + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + TranslationBase.of(context).category, + style: TextStyle(fontSize: 10, fontWeight: FontWeight.w600, color: Color(0xFF575757)), + ), + Text( + model.insurance[index].subCategoryDesc!, + style: TextStyle(fontSize: 10, fontWeight: FontWeight.w600, color: Color(0xFF575757)), ), ], ), - ), - children: [ - Container( - padding: EdgeInsets.all(14), - width: double.infinity, - decoration: BoxDecoration( - shape: BoxShape.rectangle, - border: Border.all( - color: Colors.grey, width: 0.2), - borderRadius: - BorderRadius.all(Radius.circular(2)), - boxShadow: [ - BoxShadow( - color: Colors.white70, - ), - ]), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts( - TranslationBase.of(context).companyName + - model.insurance[index].companyName, - fontSize: 20.0, - fontWeight: FontWeight.w700, - ), - Divider( - color: Colors.black, - height: 25.0, - thickness: 0.5, - ), - Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Texts( - TranslationBase.of(context) - .category, - fontSize: 18.5), - Texts( - model.insurance[index] - .subCategoryDesc, - fontSize: 18.5) - ], - ), - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Texts( - TranslationBase.of(context) - .expirationDate, - fontSize: 18.5), - Texts( - convertDateFormat( - model.insurance[index] - .cardValidTo, - ), - fontSize: 18.5), - ], - ), - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Texts( - TranslationBase.of(context) - .status + - ": ", - fontSize: 18.5), - model.insurance[index].isActive == - true - ? Texts( - TranslationBase.of(context) - .activeInsurence, - color: Colors.green, - fontWeight: FontWeight.w900, - fontSize: 17.9) - : Texts( - TranslationBase.of(context) - .notActive, - color: Colors.red, - fontWeight: FontWeight.w900, - fontSize: 17.9) - ], - ), - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Texts( - TranslationBase.of(context) - .patientCard, - fontSize: 18.5), - Texts( - model.insurance[index] - .patientCardID, - fontSize: 18.5) - ], - ), - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Texts( - TranslationBase.of(context) - .policyNumber, - fontSize: 18.5, - ), - Texts( - model.insurance[index] - .insurancePolicyNumber, - fontSize: 18.5, - ) - ]), - ], - ), - SizedBox( - height: 14.5, - ), - if (model.insurance[index].isActive == true) - Container( - color: Colors.transparent, - child: SecondaryButton( - onTap: () => { - getDetails(model.insurance[index]) - }, - label: TranslationBase.of(context) - .seeDetails, - textColor: Colors.white, - ), - width: double.infinity, - ), - ], - ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + TranslationBase.of(context).expirationDate, + style: TextStyle(fontSize: 10, fontWeight: FontWeight.w600, color: Color(0xFF575757)), + ), + Text( + DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(model.insurance[index].cardValidTo!)), + style: TextStyle(fontSize: 10, fontWeight: FontWeight.w600, color: Color(0xFF575757)), + ), + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + TranslationBase.of(context).status + ": ", + style: TextStyle(fontSize: 10, fontWeight: FontWeight.w600, color: Color(0xFF575757)), + ), + model.insurance[index].isActive == true + ? Text( + TranslationBase.of(context).activeInsurence, + style: TextStyle(fontSize: 10, fontWeight: FontWeight.w600, color: Colors.green), + ) + : Text( + TranslationBase.of(context).notActive, + style: TextStyle( + fontSize: 10, + fontWeight: FontWeight.w600, + color: Colors.red, + ), + ) + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + TranslationBase.of(context).patientCard, + style: TextStyle(fontSize: 10, fontWeight: FontWeight.w600, color: Color(0xFF575757)), + ), + Text( + model.insurance[index].patientCardID!, + style: TextStyle(fontSize: 10, fontWeight: FontWeight.w600, color: Color(0xFF575757)), + ), + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + TranslationBase.of(context).policyNumber, + style: TextStyle(fontSize: 10, fontWeight: FontWeight.w600, color: Color(0xFF575757)), + ), + Text( + model.insurance[index].insurancePolicyNumber!, + style: TextStyle(fontSize: 10, fontWeight: FontWeight.w600, color: Color(0xFF575757)), + ) + ], ), ], ), + if (model.insurance[index].isActive == true) + SizedBox( + height: 8.5, + ), + // if (model.insurance[index].isActive == true) + // Container( + // color: Colors.transparent, + // child: DefaultButton( + // TranslationBase.of(context).seeDetails, + // () => { + // getDetails(model.insurance[index]), + // }, + // ), + // width: double.infinity, + // ), ], ), ), - ); - }), + ), + ); + }, + separatorBuilder: (BuildContext context, int index) { + return mHeight(8); + }, + ), ), ), ); @@ -235,23 +204,16 @@ class _InsuranceCardState extends State { final startIndex = exDate.indexOf(start); final endIndex = exDate.indexOf(end, startIndex + start.length); - var date = new DateTime.fromMillisecondsSinceEpoch( - int.parse(exDate.substring(startIndex + start.length, endIndex))); - String newDate = date.year.toString() + - "-" + - date.month.toString().padLeft(2, '0') + - "-" + - date.day.toString().padLeft(2, '0'); + var date = new DateTime.fromMillisecondsSinceEpoch(int.parse(exDate.substring(startIndex + start.length, endIndex))); + String newDate = date.year.toString() + "-" + date.month.toString().padLeft(2, '0') + "-" + date.day.toString().padLeft(2, '0'); return newDate.toString(); } getDetails(data) { GifLoaderDialogUtils.showMyDialog(context); - _insuranceCardService.getInsuranceDetails(data).then((value) => { - GifLoaderDialogUtils.hideDialog(context), - Navigator.push(context, - FadePage(page: InsuranceCardDetails(data: value[0]['CheckList']))) - }); + _insuranceCardService + .getInsuranceDetails(data) + .then((value) => {GifLoaderDialogUtils.hideDialog(context), Navigator.push(context, FadePage(page: InsuranceCardDetails(data: value[0]['CheckList'])))}); } } diff --git a/lib/pages/insurance/insurance_card_update_details.dart b/lib/pages/insurance/insurance_card_update_details.dart index 5e9db38a..fc0e1a78 100644 --- a/lib/pages/insurance/insurance_card_update_details.dart +++ b/lib/pages/insurance/insurance_card_update_details.dart @@ -3,15 +3,18 @@ import 'package:diplomaticquarterapp/core/model/insurance/Insurance_card_details import 'package:diplomaticquarterapp/core/viewModels/insurance_card_View_model.dart'; 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'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; + import 'AttachInsuranceCardImageDialog.dart'; class InsuranceCardUpdateDetails extends StatelessWidget { @@ -19,14 +22,9 @@ class InsuranceCardUpdateDetails extends StatelessWidget { final String patientIdentificationID; final int patientID; final String name; + final String mobileNo; - const InsuranceCardUpdateDetails( - {Key key, - this.insuranceCardDetailsModel, - this.patientIdentificationID, - this.patientID, - this.name}) - : super(key: key); + const InsuranceCardUpdateDetails({Key? key, required this.insuranceCardDetailsModel, required this.patientIdentificationID, required this.patientID, required this.name, required this.mobileNo}) : super(key: key); @override Widget build(BuildContext context) { @@ -36,307 +34,337 @@ class InsuranceCardUpdateDetails extends StatelessWidget { isShowAppBar: true, isShowDecPage: false, appBarTitle: TranslationBase.of(context).cardDetail, - body: SingleChildScrollView( - child: Column( - children: [ - ...List.generate( - insuranceCardDetailsModel.length, - (index) => Padding( - padding: const EdgeInsets.all(8.0), - child: Container( - width: double.maxFinite, - margin: EdgeInsets.only(left: 8, right: 8, top: 8), - height: projectViewModel.isArabic ? 320 : 240, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(25), - color: Color(0xff515B5D), - ), - child: Padding( - padding: const EdgeInsets.all(12.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - insuranceCardDetailsModel[index].memberID, - textScaleFactor: 2.1, - style: TextStyle( - color: Colors.white, - letterSpacing: 8.0, - fontWeight: FontWeight.w400, - fontSize: 15), - ), - SizedBox( - height: 5, - ), - Texts( - insuranceCardDetailsModel[index].companyName, - fontSize: 14, - color: Colors.white, - ), - SizedBox( - height: 25, - ), - Row( - children: [ - Expanded( + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: CustomColors.appBackgroudGreyColor, + body: Column( + children: [ + Expanded( + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Column( + children: [ + ListView.separated( + physics: NeverScrollableScrollPhysics(), + shrinkWrap: true, + itemBuilder: (context, index) { + return Container( + width: double.maxFinite, + // height: projectViewModel.isArabic ? 320 : 240, + // decoration: containerRadius(CustomColors.accentColor, 12), + child: Container( + decoration: cardRadius(12, color: CustomColors.accentColor), + child: Padding( + padding: const EdgeInsets.all(12.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Texts( - TranslationBase.of(context).policyHolder, - color: Colors.white, - fontSize: 14, + Text( + insuranceCardDetailsModel[index].memberID!, + style: TextStyle( + color: Colors.white, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + fontSize: 16, + ), ), - Texts( - insuranceCardDetailsModel[index] - .memberName, - color: Colors.white, - fontSize: 14, + SizedBox( + height: 2, ), - ], - ), - ), - Expanded( - child: Column( - children: [ - Texts(TranslationBase.of(context).policyNo, - color: Colors.white), - Texts( - insuranceCardDetailsModel[index] - .policyNumber, - color: Colors.white), - ], - ), - ), - ], - ), - SizedBox( - height: 25, - ), - Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts( - TranslationBase.of(context) - .expiryDateTitle, - color: Colors.white, - fontSize: 12, + Text( + insuranceCardDetailsModel[index].companyName!, + style: TextStyle( + color: Colors.white, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + fontSize: 14, + ), ), - Texts( - insuranceCardDetailsModel[index].dOB, - color: Colors.white, - fontSize: 12, + SizedBox( + height: 14, ), - ], - ), - ), - Expanded( - child: Column( - children: [ - Texts( - TranslationBase.of(context).classTitle, - color: Colors.white, - fontSize: 12, + Row( + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).policyHolder, + style: TextStyle( + color: Colors.white, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + fontSize: 12, + ), + ), + Text( + insuranceCardDetailsModel[index].memberName!, + style: TextStyle( + color: Colors.white, + letterSpacing: -0.48, + fontSize: 12, + ), + ), + ], + ), + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).policyNo, + style: TextStyle( + color: Colors.white, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + fontSize: 12, + ), + ), + Text( + insuranceCardDetailsModel[index].policyNumber!, + style: TextStyle( + color: Colors.white, + letterSpacing: -0.48, + fontSize: 12, + ), + ), + ], + ), + ], ), - Texts( - insuranceCardDetailsModel[index] - .subCategory, - color: Colors.white, - fontSize: 12, + SizedBox( + height: 14, ), + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).expiryDateTitle, + style: TextStyle( + color: Colors.white, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + fontSize: 12, + ), + ), + Text( + insuranceCardDetailsModel[index].effectiveTo!, + style: TextStyle( + color: Colors.white, + letterSpacing: -0.48, + fontSize: 12, + ), + ), + ], + ), + ), + Expanded( + child: Column( + children: [ + Text( + TranslationBase.of(context).classTitle, + style: TextStyle( + color: Colors.white, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + fontSize: 12, + ), + ), + Text( + insuranceCardDetailsModel[index].subCategory!, + style: TextStyle( + color: Colors.white, + letterSpacing: -0.48, + fontSize: 12, + ), + ), + ], + ), + ), + Expanded( + child: Column( + children: [ + Text( + TranslationBase.of(context).approval, + style: TextStyle( + color: Colors.white, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + fontSize: 12, + ), + ), + Text( + insuranceCardDetailsModel[index].approvalLimit.toString(), + style: TextStyle( + color: Colors.white, + letterSpacing: -0.48, + fontSize: 12, + ), + ), + ], + ), + ), + ], + ) ], ), ), - Expanded( - child: Column( - children: [ - Texts( - TranslationBase.of(context).approval, - color: Colors.white, - fontSize: 12, - ), - Texts( - insuranceCardDetailsModel[index] - .approvalLimit - .toString(), - color: Colors.white, - fontSize: 12, - ), - ], - ), - ), - ], - ) - ], + ), + ); + }, + separatorBuilder: (context, index) { + return mHeight(12); + }, + itemCount: insuranceCardDetailsModel.length, ), - ), - ), - ), - ), - if(insuranceCardDetailsModel.isEmpty) - Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Container( - margin: EdgeInsets.all(10.0), - child: Card( - margin: EdgeInsets.fromLTRB( - 8.0, 16.0, 8.0, 8.0), - color: Colors.white, - shape: RoundedRectangleBorder( - borderRadius: - BorderRadius.circular(10), - ), - child: Container( - width: MediaQuery.of(context).size.width, - padding: EdgeInsets.all(10.0), - child: Row( - crossAxisAlignment: - CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - children: [ - Expanded( - flex: 3, + if (insuranceCardDetailsModel.isEmpty) + Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + child: Container( + decoration: cardRadius(12), child: Container( - margin: EdgeInsets.only( - top: 2.0, - left: 10.0, - right: 20.0), - child: Column( - crossAxisAlignment: - CrossAxisAlignment - .start, + width: MediaQuery.of(context).size.width, + padding: EdgeInsets.all(10.0), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.max, children: [ - Texts( - name, - fontSize: 14, - color: Colors.black, - fontWeight: - FontWeight.w500, + Expanded( + child: Container( + margin: EdgeInsets.only(top: 2.0, left: 10.0, right: 20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + name, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + letterSpacing: -0.46, + ), + ), + Text( + TranslationBase.of(context).fileno + ": " + patientID.toString(), + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + letterSpacing: -0.46, + ), + ) + ], + ), + ), ), - SizedBox( - height: 8, - ), - Texts( - TranslationBase.of( - context) - .fileno + - ": " +patientID.toString(), - fontSize: 14, - color: Colors.black, - fontWeight: - FontWeight.w500, - ) ], ), ), ), - ], - ), - ), - ), - ), - SizedBox(height: 150,), - Image.asset('assets/images/no-data-found.png',width: 80,height: 80,), - SizedBox(height: 8,), - Texts(TranslationBase.of(context).noDataAvailable) - ], - ) - ], - ), - ), - 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, - onTap: () async { - confirmAttachInsuranceCardImageDialogDialog( - context: context, - name: name, - fileNo: patientID.toString(), - model: model); - }, + ), + SizedBox( + height: 150, + ), + Image.asset( + 'assets/images/no-data-found.png', + width: 80, + height: 80, + ), + SizedBox( + height: 8, + ), + Text( + TranslationBase.of(context).noDataAvailable, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + ), + ) + ], + ) + ], ), - 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); - }, - ) - ], + ), + ), + ), + Padding( + padding: const EdgeInsets.all(12.0), + child: Column( + children: [ + if (insuranceCardDetailsModel.isEmpty) + SecondaryButton( + textColor: Colors.white, + label: TranslationBase.of(context).scanNow.toUpperCase(), + color: CustomColors.accentColor, + small: true, + onTap: () async { + confirmAttachInsuranceCardImageDialogDialog( + context: context, name: name, fileNo: patientID.toString(), identificationNo: patientIdentificationID, mobileNo: mobileNo, model: model); + }, + ), + if (insuranceCardDetailsModel.isNotEmpty) + SecondaryButton( + textColor: Colors.white, + label: TranslationBase.of(context).agree.toUpperCase(), + color: CustomColors.accentColor, + onTap: () async { + GifLoaderDialogUtils.showMyDialog(context); + model.uploadInsuranceCard(context, patientIdentificationID: patientIdentificationID, patientID: patientID).then((res) { + print(res); + GifLoaderDialogUtils.hideDialog(context); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err.toString()); + print(err); + }); + }, + ), + 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(), identificationNo: patientIdentificationID, mobileNo: mobileNo, model: model); + }, + ) + ], + ), ), - ), + ], ), ), ); } - void confirmAttachInsuranceCardImageDialogDialog( - {BuildContext context, - String name, - String fileNo, - InsuranceViewModel model}) { + void confirmAttachInsuranceCardImageDialogDialog({required BuildContext context, required String name, required String fileNo, required String identificationNo, required String mobileNo, required InsuranceViewModel model}) { showDialog( context: context, - child: AttachInsuranceCardImageDialog( + builder: (cxt) => AttachInsuranceCardImageDialog( fileNo: fileNo, name: name, + identificationNo: identificationNo, + mobileNo: mobileNo, image: (file, image) async { GifLoaderDialogUtils.showMyDialog(context); - await model.uploadInsuranceCard( - patientIdentificationID: patientIdentificationID, - patientID: patientID, - image: image); + await model.uploadInsuranceCard(context, patientIdentificationID: patientIdentificationID, patientID: patientID, image: image); GifLoaderDialogUtils.hideDialog(context); - if (model.state == ViewState.ErrorLocal || - model.state == ViewState.Error) { + if (model.state == ViewState.ErrorLocal || model.state == ViewState.Error) { AppToast.showErrorToast(message: model.error); } else { - AppToast.showSuccessToast( - message: TranslationBase.of(context).requestSent); + AppToast.showSuccessToast(message: TranslationBase.of(context).requestSent); } Navigator.pop(context); }, diff --git a/lib/pages/insurance/insurance_details.dart b/lib/pages/insurance/insurance_details.dart index 16745e9e..9f456f63 100644 --- a/lib/pages/insurance/insurance_details.dart +++ b/lib/pages/insurance/insurance_details.dart @@ -1,22 +1,23 @@ -import 'package:diplomaticquarterapp/config/size_config.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/others/app_scaffold_widget.dart'; -import 'package:flutter_html/flutter_html.dart'; -import 'package:html/dom.dart' as dom; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_html/flutter_html.dart'; class InsuranceCardDetails extends StatelessWidget { final String data; - InsuranceCardDetails({this.data}); + InsuranceCardDetails({required this.data}); @override Widget build(BuildContext context) { return AppScaffold( isShowAppBar: true, appBarTitle: TranslationBase.of(context).cardDetail, + showNewAppBarTitle: true, + showNewAppBar: true, + backgroundColor: CustomColors.appBackgroudGreyColor, body: Center( child: SingleChildScrollView( child: Html( diff --git a/lib/pages/insurance/insurance_page.dart b/lib/pages/insurance/insurance_page.dart index a391f554..3ec71a0f 100644 --- a/lib/pages/insurance/insurance_page.dart +++ b/lib/pages/insurance/insurance_page.dart @@ -1,246 +1,209 @@ import 'package:diplomaticquarterapp/core/service/insurance_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/insurance_card_View_model.dart'; -import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/pages/insurance/UpdateInsuranceManually.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; import '../../locator.dart'; +import '../../widgets/dialogs/confirm_dialog.dart'; import 'insurance_card_update_details.dart'; class InsurancePage extends StatelessWidget { final InsuranceViewModel model; InsuranceCardService _insuranceCardService = locator(); - InsurancePage({Key key, this.model}) : super(key: key); + InsurancePage({Key? key, required this.model}) : super(key: key); + + late ProjectViewModel projectViewModel; + @override Widget build(BuildContext context) { + projectViewModel = Provider.of(context); return SingleChildScrollView( - child: Column( - children: [ - SizedBox( - height: 65, - ), - Container( - margin: EdgeInsets.all(10.0), - color: Colors.white, - width: MediaQuery.of(context).size.width, - padding: EdgeInsets.all(10.0), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - children: [ - if (model.user != null) - Expanded( - flex: 3, - child: Container( - margin: - EdgeInsets.only(top: 2.0, left: 10.0, right: 20.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts( - model.user.firstName + " " + model.user.lastName, - fontSize: 14, - color: Colors.black, - fontWeight: FontWeight.w500, - ), - SizedBox( - height: 8, + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Column( + children: [ + Container( + width: double.infinity, + child: Container( + decoration: cardRadius(12), + child: Padding( + padding: const EdgeInsets.all(12.0), + child: InkWell( + onTap: () { + getDetails( + setupID: '010266', + projectID: 15, + patientIdentificationID: projectViewModel.user!.patientIdentificationNo!, + //model.user.patientIdentificationNo, + patientID: projectViewModel.user!.patientID!, + //model.user.patientID, + parentID: 0, + isFamily: projectViewModel.isLoginChild, + //false, + name: projectViewModel.user!.firstName! + " " + projectViewModel.user!.lastName!, + mobileNumber: projectViewModel.user!.mobileNumber!, + //model.user.firstName + " " + model.user.lastName, + context: context, + ); + }, + child: Row( + crossAxisAlignment: CrossAxisAlignment.end, + mainAxisSize: MainAxisSize.max, + children: [ + if (model.user != null) + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + projectViewModel.user!.firstName! + " " + projectViewModel.user!.lastName!, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + letterSpacing: -0.46, + ), + ), + Text( + TranslationBase.of(context).fileno + ": " + projectViewModel.user!.patientID.toString(), //model.user.patientID.toString(), + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + letterSpacing: -0.46, + ), + ) + ], + ), ), - Texts( - TranslationBase.of(context).fileno + - ": " + - model.user.patientID.toString(), - fontSize: 14, - color: Colors.black, - fontWeight: FontWeight.w500, - ) - ], - ), + Icon(Icons.arrow_forward), + ], ), ), - Expanded( - flex: 2, - child: Container( - margin: EdgeInsets.only(top: 2.0), - child: Column( - children: [ - Container( - child: SecondaryButton( - label: TranslationBase.of(context).fetchData, - small: true, - textColor: Colors.white, + ), + ), + ), + if (!projectViewModel.isLoginChild) + if (model.getAllSharedRecordsByStatusResponse.getAllSharedRecordsByStatusList != null ?? false) + ListView.separated( + physics: NeverScrollableScrollPhysics(), + shrinkWrap: true, + itemBuilder: (context, index) { + return model.getAllSharedRecordsByStatusResponse.getAllSharedRecordsByStatusList![index].status == 3 + ? InkWell( onTap: () { getDetails( - setupID: '010266', projectID: 15, - patientIdentificationID: - model.user.patientIdentificationNo, - patientID: model.user.patientID, - name: model.user.firstName + - " " + - model.user.lastName, + patientIdentificationID: model.getAllSharedRecordsByStatusResponse.getAllSharedRecordsByStatusList![index].patientIdenficationNumber!, + setupID: '010266', + patientID: model.getAllSharedRecordsByStatusResponse.getAllSharedRecordsByStatusList![index].responseID!, + name: model.getAllSharedRecordsByStatusResponse.getAllSharedRecordsByStatusList![index].patientName!, + parentID: model.user!.patientID!, + isFamily: true, + mobileNumber: model.getAllSharedRecordsByStatusResponse.getAllSharedRecordsByStatusList![index].mobileNumber!, context: context); }, - ), - ), - ], - ), - ), - ) - ], - ), - ), - if (model.getAllSharedRecordsByStatusResponse - .getAllSharedRecordsByStatusList != - null ?? - false) - ...List.generate( - model.getAllSharedRecordsByStatusResponse - .getAllSharedRecordsByStatusList.length, - (index) => model.getAllSharedRecordsByStatusResponse - .getAllSharedRecordsByStatusList[index].status == - 3 - ? Container( - margin: EdgeInsets.all(10.0), - child: Card( - margin: EdgeInsets.fromLTRB(8.0, 16.0, 8.0, 8.0), - color: Colors.white, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - ), - child: Container( - width: MediaQuery.of(context).size.width, - padding: EdgeInsets.all(10.0), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - children: [ - Expanded( - flex: 3, - child: Container( - margin: EdgeInsets.only( - top: 2.0, left: 10.0, right: 20.0), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Texts( - model - .getAllSharedRecordsByStatusResponse - .getAllSharedRecordsByStatusList[ - index] - .patientName, - fontSize: 14, - color: Colors.black, - fontWeight: FontWeight.w500, - ), - SizedBox( - height: 8, + child: Container( + width: double.infinity, + margin: EdgeInsets.only(top: 12.0), + child: Container( + decoration: cardRadius(12), + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Row( + crossAxisAlignment: CrossAxisAlignment.end, + mainAxisSize: MainAxisSize.max, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + model.getAllSharedRecordsByStatusResponse.getAllSharedRecordsByStatusList![index].patientName!, + style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, letterSpacing: -0.46), + ), + Text( + TranslationBase.of(context).fileno + ": " + model.getAllSharedRecordsByStatusResponse.getAllSharedRecordsByStatusList![index].responseID.toString(), + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, letterSpacing: -0.46), + ), + ], ), - Texts( - TranslationBase.of(context).fileno + - ": " + - model - .getAllSharedRecordsByStatusResponse - .getAllSharedRecordsByStatusList[ - index] - .patientID - .toString(), - fontSize: 14, - color: Colors.black, - fontWeight: FontWeight.w500, - ) - ], - ), + ), + Icon(Icons.arrow_forward), + ], ), ), - Expanded( - flex: 2, - child: Container( - margin: EdgeInsets.only(top: 2.0), - child: Column( - children: [ - Container( - child: SecondaryButton( - label: TranslationBase.of(context) - .fetchData, - small: true, - textColor: Colors.white, - onTap: () { - getDetails( - projectID: 15, - patientIdentificationID: model - .getAllSharedRecordsByStatusResponse - .getAllSharedRecordsByStatusList[ - index] - .patientIdenficationNumber, - setupID: '010266', - patientID: model - .getAllSharedRecordsByStatusResponse - .getAllSharedRecordsByStatusList[ - index] - .responseID, - name: model - .getAllSharedRecordsByStatusResponse - .getAllSharedRecordsByStatusList[ - index] - .patientName, - context: context); - }, - ), - ), - ], - ), - ), - ) - ], + ), ), - ), - ), - ) - : Container()), - ], + ) + : Container(); + }, + separatorBuilder: (context, index) { + return mHeight(model.getAllSharedRecordsByStatusResponse.getAllSharedRecordsByStatusList![index].status == 3 ? 8 : 0); + }, + itemCount: model.getAllSharedRecordsByStatusResponse.getAllSharedRecordsByStatusList!.length, + ), + ], + ), ), ); } - getDetails( - {String setupID, - int projectID, - String patientIdentificationID, - int patientID, - String name, - BuildContext context}) { + getDetails({required String setupID, required int projectID, required String patientIdentificationID, required int patientID, required String name, required String mobileNumber, required bool isFamily, int parentID = 0, required BuildContext context}) { GifLoaderDialogUtils.showMyDialog(context); _insuranceCardService - .getPatientInsuranceDetails( - setupID: setupID, - projectID: projectID, - patientID: patientID, - patientIdentificationID: patientIdentificationID) + .getPatientInsuranceDetails(setupID: setupID, projectID: projectID, patientID: patientID, patientIdentificationID: patientIdentificationID, isFamily: isFamily, parentID: parentID) .then((value) { GifLoaderDialogUtils.hideDialog(context); - if (!_insuranceCardService.hasError && - _insuranceCardService.isHaveInsuranceCard) { + if (!_insuranceCardService.hasError && _insuranceCardService.isHaveInsuranceCard) { Navigator.push( context, FadePage( page: InsuranceCardUpdateDetails( - insuranceCardDetailsModel: - _insuranceCardService.insuranceCardDetailsList, + insuranceCardDetailsModel: _insuranceCardService.insuranceCardDetailsList, patientID: patientID, patientIdentificationID: patientIdentificationID, name: name, - ))); + mobileNo: mobileNumber, + ))).then((value) { + model.getInsuranceUpdated(); + }); } else { - AppToast.showErrorToast(message: _insuranceCardService.error); + // AppToast.showErrorToast(message: _insuranceCardService.error); + updateManually(context, _insuranceCardService.error!, patientIdentificationID, patientID, mobileNumber); } }); } + + void updateManually(BuildContext context, String errorMsg, String patientIdentificationID, int patientID, String mobileNumber) { + ConfirmDialog dialog = new ConfirmDialog( + context: context, + confirmMessage: errorMsg + ". " + TranslationBase.of(context).habibCallCenter, + okText: TranslationBase.of(context).ok, + cancelText: TranslationBase.of(context).cancel, + // confirmMessage: errorMsg + ". " + TranslationBase.of(context).updateInsuranceManuallyDialog, + // okText: TranslationBase.of(context).yes, + // cancelText: TranslationBase.of(context).no, + okFunction: () => { + Navigator.pop(context), + // Navigator.push( + // context, + // FadePage( + // page: UpdateInsuranceManually( + // patientIdentificationNo: patientIdentificationID, + // patientID: patientID, + // patientMobileNumber: mobileNumber, + // ), + // ), + // ), + }, + cancelFunction: () => {}); + dialog.showAlertDialog(context); + } } diff --git a/lib/pages/insurance/insurance_update_screen.dart b/lib/pages/insurance/insurance_update_screen.dart index 6c3ee61c..4c4d5686 100644 --- a/lib/pages/insurance/insurance_update_screen.dart +++ b/lib/pages/insurance/insurance_update_screen.dart @@ -1,21 +1,14 @@ import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; -import 'package:diplomaticquarterapp/core/service/insurance_service.dart'; -import 'package:diplomaticquarterapp/locator.dart'; -import 'package:diplomaticquarterapp/pages/insurance/insurance_details.dart'; -import 'package:diplomaticquarterapp/uitl/app_toast.dart'; -import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/core/viewModels/insurance_card_View_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/uitl/utils.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; -import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/cupertino.dart'; -import '../base/base_view.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; -import 'package:diplomaticquarterapp/core/viewModels/insurance_card_View_model.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; -import 'insurance_card_update_details.dart'; +import '../base/base_view.dart'; import 'insurance_page.dart'; class InsuranceUpdate extends StatefulWidget { @@ -23,20 +16,18 @@ class InsuranceUpdate extends StatefulWidget { _InsuranceUpdateState createState() => _InsuranceUpdateState(); } -class _InsuranceUpdateState extends State - with SingleTickerProviderStateMixin { - TabController _tabController; - List imagesInfo = List(); +class _InsuranceUpdateState extends State with SingleTickerProviderStateMixin { + late TabController _tabController; + List imagesInfo =[]; + late ProjectViewModel projectViewModel; + @override void initState() { super.initState(); _tabController = TabController(length: 2, vsync: this); imagesInfo.add(ImagesInfo( - imageEn: - 'https://hmgwebservices.com/Images/MobileApp/imges-info/insurance-card/en/0.png', - imageAr: - 'https://hmgwebservices.com/Images/MobileApp/imges-info/insurance-card/ar/0.png')); + imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/insurance-card/en/0.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/insurance-card/ar/0.png')); } void dispose() { @@ -45,90 +36,78 @@ class _InsuranceUpdateState extends State } Widget build(BuildContext context) { + projectViewModel = Provider.of(context); return BaseView( onModelReady: (model) => model.getInsuranceUpdated(), - builder: (BuildContext context, InsuranceViewModel model, Widget child) => - AppScaffold( - appBarTitle: TranslationBase.of(context).insurCards, + builder: (BuildContext context, InsuranceViewModel model, Widget? child) => AppScaffold( + appBarTitle: TranslationBase.of(context).updateInsurCards, description: TranslationBase.of(context).infoInsurCards, infoList: TranslationBase.of(context).infoPrescriptionsPoints, imagesInfo: imagesInfo, isShowAppBar: true, isShowDecPage: true, baseViewModel: model, - body: Scaffold( - extendBodyBehindAppBar: true, - appBar: PreferredSize( - preferredSize: Size.fromHeight(70.0), - child: Stack( - children: [ - Center( - child: Container( - height: 60.0, - margin: EdgeInsets.only(top: 10.0), - width: MediaQuery.of(context).size.width * 1.9, - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Theme.of(context).dividerColor, - width: 5.7, + showNewAppBarTitle: true, + showNewAppBar: true, + backgroundColor: CustomColors.appBackgroudGreyColor, + body: Column( + children: [ + Container( + height: 45, + child: TabBar( + controller: _tabController, + isScrollable: false, + indicatorWeight: 3.0, + indicatorColor: CustomColors.accentColor, + labelColor: CustomColors.textDarkColor, + labelPadding: EdgeInsets.symmetric(horizontal: 13.0, vertical: 2.0), + unselectedLabelColor: CustomColors.textDarkColor, + tabs: [ + Container( + child: Center( + child: Text( + TranslationBase.of(context).updateInsuranceSubtitle, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, ), ), - color: Colors.white, ), + ), + Container( child: Center( - child: TabBar( - controller: _tabController, - isScrollable: true, - indicatorWeight: 4.0, - indicatorColor: Theme.of(context).primaryColor, - labelColor: Theme.of(context).primaryColor, - labelPadding: EdgeInsets.symmetric( - horizontal: 13.0, vertical: 2.0), - unselectedLabelColor: Colors.grey, - tabs: [ - Container( - width: MediaQuery.of(context).size.width * 0.35, - child: Center( - child: Texts(TranslationBase.of(context) - .updateInsuranceSubtitle), - ), - ), - Container( - width: MediaQuery.of(context).size.width * 0.35, - child: Center( - child: Texts(TranslationBase.of(context).history), - ), - ), - ], + child: Text( + TranslationBase.of(context).history, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + ), ), ), ), - ) - ], + ], + ), ), - ), - body: Column( - children: [ - Expanded( - child: TabBarView( - physics: BouncingScrollPhysics(), - controller: _tabController, - children: [ - InsurancePage(model: model), - Container( + Expanded( + child: TabBarView( + physics: BouncingScrollPhysics(), + controller: _tabController, + children: [ + InsurancePage(model: model), + Container( + child: Padding( + padding: const EdgeInsets.all(12.0), child: ListView.builder( - itemCount: model.insuranceUpdate == null - ? 0 - : model.insuranceUpdate.length, + itemCount: model.insuranceUpdate == null ? 0 : model.insuranceUpdate.length, itemBuilder: (BuildContext context, int index) { return Container( - margin: EdgeInsets.all(10.0), child: Card( - margin: EdgeInsets.fromLTRB(8.0, 16.0, 8.0, 8.0), color: Colors.white, + elevation: 2, shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), + borderRadius: BorderRadius.circular(12), ), child: Container( width: MediaQuery.of(context).size.width, @@ -143,47 +122,36 @@ class _InsuranceUpdateState extends State Expanded( flex: 3, child: Container( - margin: EdgeInsets.only( - top: 2.0, - left: 10.0, - right: 20.0), + margin: EdgeInsets.only(top: 2.0, left: 10.0, right: 20.0), child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Texts( - model.user.firstName + - " " + - model.user.lastName, - fontSize: 14, - fontWeight: FontWeight.w500, - color: Colors.black, + Text( + projectViewModel.user!.firstName! + " " + projectViewModel.user!.lastName!, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + letterSpacing: -0.46, + ), ), SizedBox( - height: 8, - ), - Texts( - TranslationBase.of(context) - .fileno + - ": " + - model - .insuranceUpdate[ - index] - .patientID - .toString(), - fontSize: 14, - fontWeight: FontWeight.w500, - color: Colors.black, + height: 4, ), - SizedBox( - height: 8, + Text( + TranslationBase.of(context).fileno + ": " + model.insuranceUpdate[index].patientID.toString(), + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + letterSpacing: -0.46, + ), ), - Texts( - model.insuranceUpdate[index] - .createdOn, - fontSize: 14, - fontWeight: FontWeight.w500, - color: Colors.black, + Text( + model.insuranceUpdate[index].createdOn!, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + letterSpacing: -0.46, + ), ), ], ), @@ -195,19 +163,16 @@ class _InsuranceUpdateState extends State margin: EdgeInsets.only(top: 20.0), child: Column( children: [ - Image.asset( - "assets/images/new-design/confirm_button.png", - width: 30.0, - height: 30.0), + Image.asset("assets/images/new-design/confirm_button.png", width: 30.0, height: 30.0), Container( - margin: EdgeInsets.only( - top: 13.5, left: 2.0), - child: Texts( - model.insuranceUpdate[index] - .statusDescription, - textAlign: TextAlign.center, - fontSize: 12, - color: Colors.black, + margin: EdgeInsets.only(top: 6.5, left: 2.0), + child: Text( + model.insuranceUpdate[index].statusDescription ?? "", + style: TextStyle( + fontSize: 10, + fontWeight: FontWeight.w600, + letterSpacing: -0.46, + ), ), ), ], @@ -223,10 +188,10 @@ class _InsuranceUpdateState extends State ); }), ), - ], - )) - ], - ), + ), + ], + )) + ], ), ), ); diff --git a/lib/pages/landing/fragments/home_page_fragment2.dart b/lib/pages/landing/fragments/home_page_fragment2.dart new file mode 100644 index 00000000..d01554ea --- /dev/null +++ b/lib/pages/landing/fragments/home_page_fragment2.dart @@ -0,0 +1,652 @@ +import 'package:diplomaticquarterapp/config/size_config.dart'; +import 'package:diplomaticquarterapp/core/viewModels/dashboard_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; +import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart'; +import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; +import 'package:diplomaticquarterapp/models/apple_pay_response.dart'; +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_page2.dart'; +import 'package:diplomaticquarterapp/pages/ErService/ErOptions.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'; +import 'package:diplomaticquarterapp/pages/packages_offers/packages_offers_tab_pager.dart'; +import 'package:diplomaticquarterapp/theme/colors.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/transitions/fade_page.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:provider/provider.dart'; + +class HomePageFragment2 extends StatefulWidget { + DashboardViewModel model; + VoidCallback? onPharmacyClick, onLoginClick, onMedicalFileClick; + + HomePageFragment2(this.model, {this.onLoginClick, this.onPharmacyClick, this.onMedicalFileClick}); + + @override + _HomePageFragment2State createState() => _HomePageFragment2State(); +} + +class _HomePageFragment2State extends State { + late ProjectViewModel projectViewModel; + List hmgServices = []; + List appoList = []; + late ApplePayResponse applePayResponse; + + // bool isPatientAdmitted = true; + + @override + void initState() { + // TODO: implement initState + super.initState(); + + // getPatientAppointmentHistory1(); + // getFamilyFiles(); + } + + initialiseHmgServices(bool isLogin) { + hmgServices.clear(); + + hmgServices.add(HmgServices(0, TranslationBase.of(context).book, TranslationBase.of(context).appointmentLabel, "assets/images/new/book appointment.svg", isLogin)); + hmgServices.add(HmgServices(1, TranslationBase.of(context).liveCare, TranslationBase.of(context).onlineConsulting, "assets/images/new/Live_Care.svg", isLogin)); + + projectViewModel.isIndoorNavigationEnabled + ? hmgServices.add(HmgServices(2, TranslationBase.of(context).hospitalNavigationTitle, TranslationBase.of(context).hospitalNavigationSubtitle, "assets/images/new/indoor_nav_home.svg", isLogin, + isLocked: !projectViewModel.havePrivilege(107))) + : hmgServices.add(HmgServices(2, TranslationBase.of(context).emergencyTitle, TranslationBase.of(context).emergencySubtitle, "assets/images/new/emergency.svg", isLogin)); + + hmgServices.add( + HmgServices(9, TranslationBase.of(context).emergency, TranslationBase.of(context).checkinOptions, "assets/images/new/emergency.svg", isLogin, isLocked: !projectViewModel.havePrivilege(108))); + hmgServices.add(HmgServices(3, TranslationBase.of(context).hhcHome, TranslationBase.of(context).healthCare, "assets/images/new/HHC.svg", isLogin)); + hmgServices.add(HmgServices(4, TranslationBase.of(context).checkup, TranslationBase.of(context).comprehensive, "assets/images/new/comprehensive_checkup.svg", isLogin)); + hmgServices.add(HmgServices(5, TranslationBase.of(context).online, TranslationBase.of(context).payment, "assets/images/new/paymentMethods.png", isLogin)); + hmgServices.add(HmgServices(6, TranslationBase.of(context).ereferralTitle, TranslationBase.of(context).ereferralSubtitle, "assets/images/new/E_Referral.svg", isLogin)); + hmgServices.add(HmgServices(7, TranslationBase.of(context).covidTest, TranslationBase.of(context).driveThru, "assets/images/new/CoronaIcon.svg", isLogin)); + hmgServices.add(HmgServices(8, TranslationBase.of(context).connectTitle, TranslationBase.of(context).connectSubtitle, "assets/images/new/reach_us.svg", isLogin)); + } + + initialiseInPatientHmgServices(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(1, TranslationBase.of(context).covidTest, TranslationBase.of(context).driveThru, "assets/images/new/CoronaIcon.svg", isLogin)); + // hmgServices.add(new HmgServices(2, TranslationBase.of(context).online, TranslationBase.of(context).payment, "assets/images/new/paymentMethods.png", isLogin)); + + projectViewModel.isIndoorNavigationEnabled + ? hmgServices.add(HmgServices(2, TranslationBase.of(context).hospitalNavigationTitle, TranslationBase.of(context).hospitalNavigationSubtitle, "assets/images/new/indoor_nav_home.svg", isLogin, + isLocked: !projectViewModel.havePrivilege(107))) + : hmgServices.add(HmgServices(2, TranslationBase.of(context).emergencyTitle, TranslationBase.of(context).emergencySubtitle, "assets/images/new/emergency.svg", isLogin)); + + hmgServices.add(new HmgServices(9, TranslationBase.of(context).emergency, TranslationBase.of(context).checkinOptions, "assets/images/new/emergency.svg", isLogin, + isLocked: !projectViewModel.havePrivilege(108))); + hmgServices.add(new HmgServices(3, TranslationBase.of(context).hhcHome, TranslationBase.of(context).healthCare, "assets/images/new/HHC.svg", isLogin)); + hmgServices.add(new HmgServices(4, TranslationBase.of(context).checkup, TranslationBase.of(context).comprehensive, "assets/images/new/comprehensive_checkup.svg", isLogin)); + + // hmgServices.add(new HmgServices(2, TranslationBase.of(context).emergencyTitle, TranslationBase.of(context).emergencySubtitle, "assets/images/new/emergency.svg", isLogin)); + + hmgServices.add(new HmgServices(6, TranslationBase.of(context).ereferralTitle, TranslationBase.of(context).ereferralSubtitle, "assets/images/new/E_Referral.svg", isLogin)); + hmgServices.add(new HmgServices(7, "H\u2082O", TranslationBase.of(context).dailyWater, "assets/images/new/h2o.svg", isLogin)); + hmgServices.add(new HmgServices(8, TranslationBase.of(context).connectTitle, TranslationBase.of(context).connectSubtitle, "assets/images/new/reach_us.svg", isLogin)); + } + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + + if (projectViewModel.isPatientAdmitted || projectViewModel.patientHasAdmissionRequest) { + initialiseInPatientHmgServices(false); + } else { + initialiseHmgServices(false); + } + + var appoCountProvider = Provider.of(context); + // var userProvider = Provider.of(context); + List myMedicalList = Utils.myMedicalListHomePage(projectViewModel: projectViewModel, context: context, count: appoCountProvider.count, isLogin: projectViewModel.isLogin); + return Container( + width: double.infinity, + child: Column( + children: [ + projectViewModel.isLogin + ? AspectRatio( + aspectRatio: 2.6, + child: Padding( + padding: const EdgeInsets.only(left: 20, right: 20, top: 8, bottom: 6), + child: InkWell( + onTap: () { + widget.onMedicalFileClick!(); + }, + child: LoggedSliderView( + projectViewModel, + new SliderData( + TranslationBase.of(context).fileno + ": " + (projectViewModel.user.patientID.toString() ?? ""), + projectViewModel.user.firstName! + ' ' + (projectViewModel.user.lastName ?? ""), + "", + bannerColor[0].darkColor, + bannerColor[0].lightColor, + ), + widget.model, + ), + ), + ), + ) + : AspectRatio( + aspectRatio: 2.6, + child: Container( + margin: EdgeInsets.only(left: 20, right: 20, top: 8, bottom: 6), + child: SliderView( + onLoginClick: () { + widget.onLoginClick!(); + projectViewModel.analytics.loginRegistration.login_register_initiate(); + }, + ), + // height: MediaQuery.of(context).size.width / 2.6, + ), + ), + projectViewModel.isLogin + ? Column( + children: [ + Padding( + padding: projectViewModel.isArabic + ? EdgeInsets.only( + right: 20, + left: 8, + ) + : EdgeInsets.only( + left: 20, + right: 8, + ), + child: Row( + children: [ + Expanded( + child: Text( + TranslationBase.of(context).myMedicalFile, + style: TextStyle( + color: Colors.black, + fontSize: 16, + fontWeight: FontWeight.bold, + letterSpacing: -0.96, + height: 19 / 16, + ), + ), + ), + TextButton( + onPressed: () { + widget.onMedicalFileClick!(); + // navigateTo(context, MedicalProfilePageNew()); + }, + child: Text( + TranslationBase.of(context).viewMedicalFile, + style: TextStyle( + color: CustomColors.accentColor, + fontSize: 12, + letterSpacing: -0.72, + height: 23 / 12, + ), + ), + ), + ], + ), + ), + mHeight(4), + Container( + width: double.infinity, + height: MediaQuery.of(context).size.width * 0.26, + child: ListView.separated( + itemCount: myMedicalList.length, + padding: EdgeInsets.zero, + scrollDirection: Axis.horizontal, + physics: BouncingScrollPhysics(), + itemBuilder: (context, index) { + return projectViewModel.isArabic + ? Container( + child: myMedicalList[index], + width: MediaQuery.of(context).size.width * 0.26, + height: MediaQuery.of(context).size.width * 0.26, + margin: EdgeInsets.only(left: index == 4 ? 20 : 0, right: index == 0 ? 20 : 0), + ) + : Container( + child: myMedicalList[index], + width: MediaQuery.of(context).size.width * 0.26, + height: MediaQuery.of(context).size.width * 0.26, + margin: EdgeInsets.only(left: index == 0 ? 20 : 0, right: index == 4 ? 20 : 0), + ); + }, + separatorBuilder: (BuildContext context, int index) { + return mWidth(12); + }, + ), + ), + ], + ) + : Container(), + mHeight(16), + Column( + children: [ + Divider( + height: 1, + color: Color(0xFFC7C7C7), + ), + Container( + width: double.infinity, + height: MediaQuery.of(context).size.width * 0.3, + padding: EdgeInsets.only(left: 20, right: 20, top: 14, bottom: 14), + color: Colors.white, + child: Row( + children: [ + offersButton(), + mWidth(10), + hmgButton(), + ], + ), + ), + Divider( + height: 1, + color: Color(0xFFC7C7C7), + ), + ], + ), + mHeight(12), + Column( + children: [ + Padding( + padding: projectViewModel.isArabic + ? const EdgeInsets.only( + left: 8, + right: 20, + ) + : const EdgeInsets.only( + left: 20, + right: 8, + ), + child: Row( + children: [ + Expanded( + child: Text( + TranslationBase.of(context).hMGService, + style: TextStyle( + color: Colors.black, + fontSize: 16, + fontWeight: FontWeight.bold, + letterSpacing: -0.96, + height: 19 / 16, + ), + ), + ), + TextButton( + onPressed: () { + // AppSharedPreferences().getAll().then((value){ + // debugPrint("ALL SHARED PREFERENCES!!!!!"); + // debugPrint(jsonEncode(value)); + // }); + Navigator.push(context, FadePage(page: AllHabibMedicalSevicePage2())); + projectViewModel.analytics.hmgServices.viewAll(); + }, + child: Text( + TranslationBase.of(context).viewAllServices, + style: TextStyle( + color: CustomColors.accentColor, + fontSize: 12, + letterSpacing: -0.72, + height: 23 / 12, + ), + ), + ), + ], + ), + ), + projectViewModel.isPatientAdmitted || projectViewModel.patientHasAdmissionRequest + ? Column( + children: [ + Padding( + padding: const EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 12.0), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Expanded( + flex: 9, + child: Container( + margin: projectViewModel.isArabic ? EdgeInsets.only(left: 12.0) : EdgeInsets.only(right: 12.0), + child: AspectRatio( + aspectRatio: 2.15, + child: ServicesView( + new HmgServices(23, TranslationBase.of(context).InPatient, TranslationBase.of(context).inPatientServices, "assets/images/new/InPatient.svg", false), + 23, + true, + projectViewModel)), + ), + ), + Expanded( + flex: 4, + child: AspectRatio( + aspectRatio: 1.0, + child: ServicesView(new HmgServices(5, TranslationBase.of(context).online, TranslationBase.of(context).payment, "assets/images/new/paymentMethods.png", false), 2, + true, projectViewModel)), + ), + ], + ), + ), + Padding( + padding: const EdgeInsets.only( + left: 20, + right: 20, + top: 0, + ), + child: GridView.builder( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, childAspectRatio: 2 / 2, crossAxisSpacing: 12, mainAxisSpacing: 12), + physics: NeverScrollableScrollPhysics(), + shrinkWrap: true, + itemCount: hmgServices.length, + padding: EdgeInsets.zero, + itemBuilder: (BuildContext context, int index) { + return ServicesView(hmgServices[index], index, true, projectViewModel); + }, + ), + ), + ], + ) + : Padding( + padding: const EdgeInsets.only( + left: 20, + right: 20, + top: 0, + ), + child: GridView.builder( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, childAspectRatio: 2 / 2, crossAxisSpacing: 12, mainAxisSpacing: 12), + physics: NeverScrollableScrollPhysics(), + shrinkWrap: true, + itemCount: hmgServices.length, + padding: EdgeInsets.zero, + itemBuilder: (BuildContext context, int index) { + // return ServicesView(hmgServices[index], index, true, projectViewModel, + // isLocked: (hmgServices[index].action == 2 && projectViewModel.isIndoorNavigationEnabled) ? !projectViewModel.havePrivilege(107) : false); + return ServicesView(hmgServices[index], index, true, projectViewModel, isLocked: hmgServices[index].isLocked); + }, + ), + ), + ], + ), + mHeight(140), + ], + ), + ); + } + + Widget offersButton() { + final bypassPrivilageCheck = false; + return Expanded( + flex: 1, + child: InkWell( + onTap: () { + // Navigator.of(context).push(MaterialPageRoute(builder: (context) => ErOptions(isAppbar: true))); + Navigator.push(context, FadePage(page: ErOptions(isAppbar: true))); + }, + child: Stack( + children: [ + Container( + width: double.infinity, + height: double.infinity, + clipBehavior: Clip.antiAlias, + decoration: containerRadiusWithGradientServices(20, lightColor: CustomColors.lightGreyColor, darkColor: CustomColors.lightGreyColor), + child: Stack( + children: [ + Container( + width: double.infinity, + height: double.infinity, + // color: Color(0xFF2B353E), + decoration: containerRadius(CustomColors.accentColor, 20), + ), + Container( + width: double.infinity, + height: double.infinity, + clipBehavior: Clip.antiAlias, + decoration: projectViewModel.isArabic + ? containerBottomRightRadiusWithGradientForAr(60, lightColor: CustomColors.lightGreyColor, darkColor: CustomColors.lightGreyColor) + : containerBottomRightRadiusWithGradient(60, lightColor: CustomColors.lightGreyColor, darkColor: CustomColors.lightGreyColor), + child: Stack( + children: [ + SvgPicture.asset( + "assets/images/new/strips.svg", + width: double.infinity, + height: double.infinity, + fit: BoxFit.cover, + ), + ], + ), + ), + projectViewModel.isArabic + ? Positioned( + left: 20, + top: 12, + child: Opacity( + opacity: 0.5, + child: SvgPicture.asset( + "assets/images/new/emergency_services_back.svg", + height: MediaQuery.of(context).size.width * 0.14, + ), + ), + ) + : Positioned( + right: 20, + top: 12, + child: Opacity( + opacity: 0.5, + child: SvgPicture.asset( + "assets/images/new/emergency_services_back.svg", + height: MediaQuery.of(context).size.width * 0.14, + ), + ), + ), + Container( + width: double.infinity, + height: double.infinity, + padding: EdgeInsets.all(SizeConfig.widthMultiplier! * 3.4), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + child: SvgPicture.asset( + "assets/images/new/emergency_services.svg", + height: MediaQuery.of(context).size.width * 0.08, + ), + ), + mFlex(1), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + TranslationBase.of(context).emergencyServices, + style: TextStyle( + color: Colors.black, + fontSize: 14, + fontWeight: FontWeight.bold, + letterSpacing: -0.45, + height: 1, + ), + ), + projectViewModel.isArabic ? mHeight(5) : Container(), + Text( + TranslationBase.of(context).emergencyServicesSubtitle, + style: TextStyle( + color: Colors.black, + fontSize: 9, + fontWeight: FontWeight.w600, + letterSpacing: -0.27, + height: projectViewModel.isArabic ? 0.2 : 1, + ), + ), + ], + ), + ], + ), + ), + ], + ), + ), + // projectViewModel.havePrivilege(82) || bypassPrivilageCheck + // ? Container() + // : Container( + // width: double.infinity, + // height: double.infinity, + // clipBehavior: Clip.antiAlias, + // decoration: containerRadiusWithGradientServices(20, lightColor: CustomColors.lightGreyColor.withOpacity(0.7), darkColor: CustomColors.lightGreyColor.withOpacity(0.7)), + // child: Icon( + // Icons.lock_outline, + // size: 40, + // ), + // ) + ], + ), + ), + ); + } + + Widget hmgButton() { + return Expanded( + flex: 1, + child: InkWell( + onTap: () { + if (projectViewModel.havePrivilege(100)) widget.onPharmacyClick!(); + }, + child: Stack(children: [ + Container( + width: double.infinity, + height: double.infinity, + clipBehavior: Clip.antiAlias, + decoration: containerRadiusWithGradientServices(20, lightColor: CustomColors.lightGreyColor, darkColor: CustomColors.lightGreyColor), + child: Stack( + children: [ + Container( + width: double.infinity, + height: double.infinity, + // color: Color(0xFF2B353E), + decoration: containerRadius(Color(0xFF359846), 20), + ), + Container( + width: double.infinity, + height: double.infinity, + clipBehavior: Clip.antiAlias, + decoration: projectViewModel.isArabic + ? containerBottomRightRadiusWithGradientForAr(60, lightColor: CustomColors.lightGreyColor, darkColor: CustomColors.lightGreyColor) + : containerBottomRightRadiusWithGradient(60, lightColor: CustomColors.lightGreyColor, darkColor: CustomColors.lightGreyColor), + child: Stack( + children: [ + SvgPicture.asset( + "assets/images/new/strips.svg", + width: double.infinity, + height: double.infinity, + fit: BoxFit.cover, + ), + ], + ), + ), + projectViewModel.isArabic + ? Positioned( + left: 20, + top: 12, + child: Opacity( + opacity: 0.25, + child: SvgPicture.asset( + "assets/images/new/Pharmacy.svg", + height: MediaQuery.of(context).size.width * 0.15, + ), + ), + ) + : Positioned( + right: 20, + top: 12, + child: Opacity( + opacity: 0.25, + child: SvgPicture.asset( + "assets/images/new/Pharmacy.svg", + height: MediaQuery.of(context).size.width * 0.15, + ), + ), + ), + Container( + width: double.infinity, + height: double.infinity, + padding: EdgeInsets.all(SizeConfig.widthMultiplier! * 3.4), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + child: SvgPicture.asset( + "assets/images/new/Pharmacy.svg", + height: MediaQuery.of(context).size.width * 0.08, + ), + ), + mFlex(1), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + TranslationBase.of(context).onlinePharmacy, + style: TextStyle( + color: Colors.black, + fontSize: 14, + fontWeight: FontWeight.bold, + letterSpacing: -0.45, + height: 1, + ), + ), + projectViewModel.isArabic ? mHeight(5) : Container(), + Text( + TranslationBase.of(context).ecommerceSolution, + style: TextStyle( + color: Colors.black, + fontSize: 9, + fontWeight: FontWeight.w600, + letterSpacing: -0.27, + height: projectViewModel.isArabic ? 0.2 : 1, + ), + ), + ], + ), + ], + ), + ), + ], + ), + ), + projectViewModel.havePrivilege(100) + ? Container() + : Container( + width: double.infinity, + height: double.infinity, + clipBehavior: Clip.antiAlias, + decoration: containerRadiusWithGradientServices(20, lightColor: CustomColors.lightGreyColor.withOpacity(0.7), darkColor: CustomColors.lightGreyColor.withOpacity(0.7)), + child: Icon( + Icons.lock_outline, + size: 40, + ), + ) + ]), + ), + ); + } + + Widget getInpatientButton() { + return Container( + height: 50.0, + ); + } + + Widget showFloating(String icon) { + return Container( + width: MediaQuery.of(context).size.width * 0.06, + height: MediaQuery.of(context).size.width * 0.06, + decoration: containerRadius(CustomColors.accentColor, 100), + padding: EdgeInsets.all(4), + child: SvgPicture.asset(icon), + ); + } +} diff --git a/lib/pages/landing/home_page.dart b/lib/pages/landing/home_page.dart index ef38ae9c..cf31f6f4 100644 --- a/lib/pages/landing/home_page.dart +++ b/lib/pages/landing/home_page.dart @@ -4,6 +4,7 @@ import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/pharmacy_mod import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/locator.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_page.dart'; +import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/E-Referral/e_referral_page.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/HomeHealthCare/home_health_care_page.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/all_habib_medical_service_page.dart'; import 'package:diplomaticquarterapp/pages/ContactUs/contact_us_page.dart'; @@ -11,18 +12,18 @@ import 'package:diplomaticquarterapp/pages/Covid-DriveThru/covid-drivethru-locat import 'package:diplomaticquarterapp/pages/ErService/ErOptions.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/livecare/livecare_home.dart'; -import 'package:diplomaticquarterapp/pages/packages_offers/OfferAndPackagesPage.dart'; +import 'package:diplomaticquarterapp/pages/packages_offers/packages_offers_tab_pager.dart'; import 'package:diplomaticquarterapp/pages/paymentService/payment_service.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/custom_text_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; -import 'package:hexcolor/hexcolor.dart'; import 'package:provider/provider.dart'; import 'landing_page_pharmcy.dart'; @@ -30,21 +31,20 @@ import 'landing_page_pharmcy.dart'; class HomePage extends StatefulWidget { final Function goToMyProfile; - HomePage({Key key, this.goToMyProfile}); + HomePage({Key? key, required this.goToMyProfile}); @override _HomePageState createState() => _HomePageState(); } class _HomePageState extends State { - PharmacyModuleViewModel pharmacyModuleViewModel = - locator(); + PharmacyModuleViewModel pharmacyModuleViewModel = locator(); @override Widget build(BuildContext context) { ProjectViewModel projectViewModel = Provider.of(context); return BaseView( - onModelReady: (model) => model.getPatientRadOrders(), + onModelReady: (model) => () async {}, builder: (_, model, wi) => AppScaffold( isShowDecPage: false, isHelp: true, @@ -62,10 +62,7 @@ class _HomePageState extends State { width: double.infinity, height: 210, decoration: BoxDecoration( - image: DecorationImage( - image: ExactAssetImage( - 'assets/images/dashboard_top_bg.png'), - fit: BoxFit.cover), + image: DecorationImage(image: ExactAssetImage('assets/images/dashboard_top_bg.png'), fit: BoxFit.cover), ), child: Stack( children: [ @@ -74,127 +71,101 @@ class _HomePageState extends State { left: 5, right: 5, child: Container( - width: - MediaQuery.of(context).size.width * 0.8, + width: MediaQuery.of(context).size.width * 0.8, child: Row( children: [ Expanded( child: Container( - height: 125, - padding: EdgeInsets.all(5), - margin: EdgeInsets.all(5), - decoration: BoxDecoration( - image: DecorationImage( - image: AssetImage( - "assets/images/new-design/covid_bg_transparent.png"), - fit: BoxFit.fill, - ), - color: - Colors.white.withOpacity(0.3), - borderRadius: BorderRadius.all( - Radius.circular(5))), - child: Container( - child: Column( - children: [ - Texts( - TranslationBase.of(context) - .covidTest, - color: Colors.white, - fontWeight: FontWeight.w700, + height: 125, + padding: EdgeInsets.all(5), + margin: EdgeInsets.all(5), + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage("assets/images/new-design/covid_bg_transparent.png"), + fit: BoxFit.fill, ), - Row( - mainAxisAlignment: - MainAxisAlignment - .spaceAround, - children: [ - Container( - margin: EdgeInsets.only( - top: 15.0, - ), - child: SvgPicture.asset( - 'assets/images/new-design/covid-19-car.svg', - width: 45.0, - height: 45.0), + color: Colors.white.withOpacity(0.3), + borderRadius: BorderRadius.all(Radius.circular(5))), + child: (model.user != null && model.user!.outSA == 1) + ? Container( + width: double.infinity, + height: double.infinity, + color: Colors.grey.shade500.withOpacity(0.3), + child: Icon( + Icons.lock_outline, + size: 40, ), - Container( - margin: EdgeInsets.only( - top: 5.0), - child: Column( - children: [ - Texts( - TranslationBase.of( - context) - .driveThru, - fontWeight: - FontWeight.w700, - color: Colors.white, - ), - ButtonTheme( - shape: - RoundedRectangleBorder( - borderRadius: - BorderRadius - .circular( - 5.0), + ) + : Container( + child: Column( + children: [ + Texts( + TranslationBase.of(context).covidTest, + color: Colors.white, + fontWeight: FontWeight.w700, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Container( + margin: EdgeInsets.only( + top: 15.0, + ), + child: SvgPicture.asset('assets/images/new-design/covid-19-car.svg', width: 45.0, height: 45.0), ), - minWidth: MediaQuery.of( - context) - .size - .width * - 0.15, - height: 25.0, - child: RaisedButton( - color: Colors - .red[800], - textColor: - Colors.white, - disabledTextColor: - Colors.white, - disabledColor: - new Color( - 0xFFbcc2c4), - onPressed: () { - navigateToCovidDriveThru(); - }, - child: Texts( - TranslationBase.of( - context) - .bookNow, - fontWeight: - FontWeight - .w700, - color: Colors - .white, + Container( + margin: EdgeInsets.only(top: 5.0), + child: Column( + children: [ + Texts( + TranslationBase.of(context).driveThru, + fontWeight: FontWeight.w700, + color: Colors.white, + ), + ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5.0), + ), + minWidth: MediaQuery.of(context).size.width * 0.15, + height: 25.0, + child: CustomTextButton( + backgroundColor: Colors.red[800], + elevation: 0, + disabledForegroundColor: new Color(0xFFbcc2c4).withOpacity(0.38), + disabledBackgroundColor: new Color(0xFFbcc2c4).withOpacity(0.12), + onPressed: (model.user != null && model.user!.outSA == 1) + ? () {} + : () { + navigateToCovidDriveThru(); + }, + child: Center( + child: Texts( + TranslationBase.of(context).bookNow, + fontWeight: FontWeight.w700, + color: Colors.white, + ), + ), + ), + ), + ], ), ), - ), - ], - ), + ], + ), + ], ), - ], - ), - ], - ), - ), - ), + )), ), Expanded( child: InkWell( - onTap: () => Navigator.push(context, - FadePage(page: LiveCareHome())), + onTap: () => Navigator.push(context, FadePage(page: LiveCareHome())), child: Container( height: 125, padding: EdgeInsets.all(15), margin: EdgeInsets.all(5), - decoration: BoxDecoration( - color: Colors.white - .withOpacity(0.3), - borderRadius: BorderRadius.all( - Radius.circular(5))), + decoration: BoxDecoration(color: Colors.white.withOpacity(0.3), borderRadius: BorderRadius.all(Radius.circular(5))), child: SvgPicture.asset( - projectViewModel.isArabic - ? 'assets/images/new-design/livecare_arabic_logo.svg' - : 'assets/images/new-design/liveCare_white_logo.svg', + projectViewModel.isArabic ? 'assets/images/new-design/livecare_arabic_logo.svg' : 'assets/images/new-design/liveCare_white_logo.svg', ), ), ), @@ -206,38 +177,23 @@ class _HomePageState extends State { ], ), ), - Container( - width: double.infinity, - height: projectViewModel.isArabic ? 110 : 80) + Container(width: double.infinity, height: projectViewModel.isArabic ? 110 : 80) ], ), Positioned( top: 155, - left: MediaQuery.of(context).size.width * - (MediaQuery.of(context).orientation == - Orientation.landscape - ? 0.02 - : 0.03), - right: MediaQuery.of(context).size.width * - (MediaQuery.of(context).orientation == - Orientation.landscape - ? 0.02 - : 0.03), + left: MediaQuery.of(context).size.width * (MediaQuery.of(context).orientation == Orientation.landscape ? 0.02 : 0.03), + right: MediaQuery.of(context).size.width * (MediaQuery.of(context).orientation == Orientation.landscape ? 0.02 : 0.03), child: (!model.isLogin) ? Container( width: double.infinity, height: 125, decoration: BoxDecoration( - color: HexColor('#A59E9E'), + color: Color(0xFFA59E9E), shape: BoxShape.rectangle, - border: Border.all( - color: Colors.transparent, width: 0.5), - borderRadius: - BorderRadius.all(Radius.circular(9)), - image: DecorationImage( - image: ExactAssetImage( - 'assets/images/bg_graphic.png'), - fit: BoxFit.cover)), + border: Border.all(color: Colors.transparent, width: 0.5), + borderRadius: BorderRadius.all(Radius.circular(9)), + image: DecorationImage(image: ExactAssetImage('assets/images/bg_graphic.png'), fit: BoxFit.cover)), child: Container( margin: EdgeInsets.all(5), child: Column( @@ -253,37 +209,29 @@ class _HomePageState extends State { fontSize: 23, ), Texts( - TranslationBase.of(context) - .myMedicalFileSubTitle, + TranslationBase.of(context).myMedicalFileSubTitle, color: Colors.black, fontSize: 16, ), Align( - alignment: projectViewModel.isArabic - ? Alignment.bottomLeft - : Alignment.bottomRight, + alignment: projectViewModel.isArabic ? Alignment.bottomLeft : Alignment.bottomRight, child: InkWell( onTap: () { widget.goToMyProfile(); }, child: Container( - margin: EdgeInsets.only( - left: 15, right: 15), + margin: EdgeInsets.only(left: 15, right: 15), width: 90, height: 30, decoration: BoxDecoration( - color: HexColor('#D81A2E'), + color: Color(0xFFD81A2E), shape: BoxShape.rectangle, - border: Border.all( - color: Colors.transparent, - width: 0.5), - borderRadius: BorderRadius.all( - Radius.circular(0)), + border: Border.all(color: Colors.transparent, width: 0.5), + borderRadius: BorderRadius.all(Radius.circular(0)), ), child: Center( child: Texts( - TranslationBase.of(context) - .viewMore, + TranslationBase.of(context).viewMore, color: Colors.white, fontWeight: FontWeight.w700, fontSize: 12, @@ -300,16 +248,11 @@ class _HomePageState extends State { width: double.infinity, height: projectViewModel.isArabic ? 160 : 130, decoration: BoxDecoration( - color: HexColor('#A59E9E'), + color: Color(0xFFA59E9E), shape: BoxShape.rectangle, - border: Border.all( - color: Colors.transparent, width: 0.5), - borderRadius: - BorderRadius.all(Radius.circular(9)), - image: DecorationImage( - image: ExactAssetImage( - 'assets/images/bg_graphic.png'), - fit: BoxFit.cover), + border: Border.all(color: Colors.transparent, width: 0.5), + borderRadius: BorderRadius.all(Radius.circular(9)), + image: DecorationImage(image: ExactAssetImage('assets/images/bg_graphic.png'), fit: BoxFit.cover), ), child: Container( margin: EdgeInsets.all(5), @@ -317,40 +260,56 @@ class _HomePageState extends State { children: [ Row( children: [ - if (projectViewModel.user != null && - model.isLogin) + if (projectViewModel.user != null && model.isLogin) Expanded( child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( height: 8, ), - Row( - children: [ - Texts( - model.user.firstName + - " " + - model.user.lastName, - color: Colors.grey[100], - bold: true, - fontSize: 15, - ), - Container( - margin: - EdgeInsets.fromLTRB( - 8.0, - 0.0, - 8.0, - 0.0), - child: SvgPicture.asset( - "assets/images/new-design/verification_check.svg"), - ), - ], - ), + model.user!.cRSVerificationStatus == 2 + ? Row( + children: [ + Texts( + model.user!.firstName! + " " + model.user!.lastName!, + color: Colors.grey[100], + bold: true, + fontSize: 15, + ), + Container( + margin: EdgeInsets.fromLTRB(8.0, 0.0, 8.0, 0.0), + child: SvgPicture.asset("assets/images/new-design/verification_check.svg"), + ), + ], + ) + : model.user!.cRSVerificationStatus == 3 + ? Row( + children: [ + Texts( + model.user!.firstName! + " " + model.user!.lastName!, + color: Colors.grey[100], + bold: true, + fontSize: 15, + ), + Container( + margin: EdgeInsets.fromLTRB(8.0, 0.0, 8.0, 0.0), + child: SvgPicture.asset("assets/images/new-design/pending.svg"), + ), + ], + ) + : Row( + children: [ + Texts( + model.user!.firstName! + " " + model.user!.lastName!, + color: Colors.grey[100], + bold: true, + fontSize: 15, + ), + ], + ), Texts( - '${model.user.patientID}', + '${model.user!.patientID!}', color: Colors.white, fontSize: 14, ), @@ -358,7 +317,7 @@ class _HomePageState extends State { height: 5, ), Texts( - '${DateUtil.getMonthDayYearDateFormatted(model.user.dateofBirthDataTime)} ,${model.user.genderDescription} ${model.user.ageDesc}', + '${DateUtil.getMonthDayYearDateFormatted(model.user!.dateofBirthDataTime!)} ,${model.user!.gender == 1 ? TranslationBase.of(context).male : TranslationBase.of(context).female} ${model.user!.age.toString() + "y"}', color: Colors.grey[100], fontWeight: FontWeight.normal, fontSize: 14, @@ -375,21 +334,19 @@ class _HomePageState extends State { width: 90, height: 30, decoration: BoxDecoration( - color: HexColor('#D81A2E'), + color: Color(0xFFD81A2E), shape: BoxShape.rectangle, - border: Border.all( - color: Colors.transparent, - width: 0.5), + border: Border.all(color: Colors.transparent, width: 0.5), borderRadius: BorderRadius.all( Radius.circular(5), ), ), child: Center( child: Texts( - TranslationBase.of(context) - .viewMore, + TranslationBase.of(context).myMedicalFile, color: Colors.white, fontSize: 12, + textAlign: TextAlign.center, ), ), ), @@ -407,7 +364,7 @@ class _HomePageState extends State { height: 40, ), Texts( - "${model.heightCm}", + "${model.heightCm} ${TranslationBase.of(context).cm}", color: Colors.white, fontSize: 17, ) @@ -425,9 +382,7 @@ class _HomePageState extends State { width: 25, height: 40, ), - Texts('${model.weightKg}', - color: Colors.white, - fontSize: 17) + Texts('${model.weightKg} ${TranslationBase.of(context).kg}', color: Colors.white, fontSize: 17) ], ), ), @@ -436,18 +391,13 @@ class _HomePageState extends State { ), Expanded( child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, children: [ Image.asset( 'assets/images/blood_icon.png', width: 35, height: 40, ), - Texts( - '${model.booldType}', - color: Colors.white, - ) + Texts('${model.booldType}', color: Colors.white, fontSize: 17) ], ), ), @@ -463,21 +413,23 @@ class _HomePageState extends State { Padding( padding: const EdgeInsets.only(bottom: 15, right: 15, left: 15), child: InkWell( - onTap: (){ - Navigator.of(context).push(MaterialPageRoute(builder: (context) => PackagesHomePage())); + onTap: () { + Navigator.of(context).push(MaterialPageRoute(builder: (context) => PackagesOfferTabPage(projectViewModel.user!))); }, child: Container( decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - color: Color(0xffB8382C), + borderRadius: BorderRadius.circular(10), + color: Color(0xffB8382C), ), child: Padding( padding: const EdgeInsets.all(8), child: Row( children: [ Texts( - TranslationBase.of(context).offerAndPackages, - color: Colors.white, fontSize: 20, fontWeight: FontWeight.normal, + TranslationBase.of(context).offerAndPackages, + color: Colors.white, + fontSize: 20, + fontWeight: FontWeight.normal, ), Spacer(), Image.asset("assets/images/offer_icon.png"), @@ -487,9 +439,7 @@ class _HomePageState extends State { ), ), ), - if (projectViewModel.havePrivilege(64) || - projectViewModel.havePrivilege(65) || - projectViewModel.havePrivilege(67)) + if (projectViewModel.havePrivilege(64) || projectViewModel.havePrivilege(65) || projectViewModel.havePrivilege(67)) Container( margin: EdgeInsets.only(left: 15, right: 15), child: Row( @@ -497,39 +447,48 @@ class _HomePageState extends State { children: [ if (projectViewModel.havePrivilege(64)) DashboardItem( - onTap: () { - Navigator.push( - context, - FadePage( - page: HomeHealthCarePage(), - ), - ); - }, + onTap: (model.user != null && model.user!.outSA == 1) + ? () {} + : () { + Navigator.push( + context, + FadePage( + page: HomeHealthCarePage(), + ), + ); + }, child: Center( child: Padding( - padding: const EdgeInsets.all(15.0), - child: Column( - children: [ - Image.asset( - 'assets/images/home_health_care_icon.png', - width: 50, - height: 50, - ), - SizedBox( - height: 10, - ), - Texts( - TranslationBase.of(context) - .homeHealthCare, - textAlign: TextAlign.center, - color: Colors.white, - fontWeight: FontWeight.w700, - fontSize: - SizeConfig.textMultiplier * 1.55, - ) - ], - ), - ), + padding: (model.user != null && model.user!.outSA == 1) ? const EdgeInsets.all(0.0) : const EdgeInsets.all(15.0), + child: (model.user != null && model.user!.outSA == 1) + ? Container( + width: double.infinity, + height: double.infinity, + color: Colors.grey.shade500.withOpacity(0.3), + child: Icon( + Icons.lock_outline, + size: 40, + ), + ) + : Column( + children: [ + Image.asset( + 'assets/images/home_health_care_icon.png', + width: 50, + height: 50, + ), + SizedBox( + height: 10, + ), + Texts( + TranslationBase.of(context).homeHealthCare, + textAlign: TextAlign.center, + color: Colors.white, + fontWeight: FontWeight.w700, + fontSize: SizeConfig.textMultiplier! * 1.55, + ) + ], + )), ), height: MediaQuery.of(context).size.width * 0.4, imageName: 'home_healthcare_service_bg.png', @@ -537,31 +496,45 @@ class _HomePageState extends State { ), if (projectViewModel.havePrivilege(65)) DashboardItem( - onTap: () => getPharmacyToken(model), + onTap: () => (model.user != null && model.user!.outSA == 1) ? () {} : getPharmacyToken(model), child: Center( child: Padding( - padding: const EdgeInsets.all(15.0), - child: Column( - children: [ - Image.asset( - 'assets/images/pharmacy_logo.png', - width: 40, - height: 40, - ), - SizedBox( - height: 20, - ), - Texts( - TranslationBase.of(context) - .onlinePharmacy, - textAlign: TextAlign.center, - color: Colors.white, - fontWeight: FontWeight.w700, - fontSize: - SizeConfig.textMultiplier * 1.55, - ) - ], - ), + padding: (model.user != null && model.user!.outSA == 1) ? const EdgeInsets.all(0.0) : const EdgeInsets.all(15.0), + child: (model.user != null && model.user!.outSA == 1) + ? Container( + width: double.infinity, + height: double.infinity, + color: Colors.grey.shade500.withOpacity(0.3), + child: Icon( + Icons.lock_outline, + size: 40, + ), + ) + : Column( + children: [ + // if (projectViewModel.user != null && model.isLogin && model.user.outSA == 1) + // Image.asset( + // 'assets/images/lock_icon.png', + // width: 50, + // height: 50, + // ), + Image.asset( + 'assets/images/pharmacy_logo.png', + width: 40, + height: 40, + ), + SizedBox( + height: 20, + ), + Texts( + TranslationBase.of(context).onlinePharmacy, + textAlign: TextAlign.center, + color: Colors.white, + fontWeight: FontWeight.w700, + fontSize: SizeConfig.textMultiplier! * 1.55, + ) + ], + ), ), ), height: MediaQuery.of(context).size.width * 0.4, @@ -569,41 +542,51 @@ class _HomePageState extends State { ), if (projectViewModel.havePrivilege(67)) DashboardItem( - onTap: () { - Navigator.push( - context, - FadePage( - page: CMCPage(), - ), - ); - }, + onTap: (model.user != null && model.user!.outSA == 1) + ? () {} + : () { + Navigator.push( + context, + FadePage( + page: CMCPage(), + ), + ); + }, child: Center( child: Padding( - padding: const EdgeInsets.all(15.0), - child: Column( - children: [ - Image.asset( - 'assets/images/comprehensive_medical_checkup_logo.png', - width: 50, - height: 50, - ), - SizedBox( - height: 10, - ), - Texts( - TranslationBase.of(context).cmcHeading, - textAlign: TextAlign.center, - color: Colors.white, - fontWeight: FontWeight.w700, - fontSize: - SizeConfig.textMultiplier * 1.55, - ) - ], - ), - ), + padding: (model.user != null && model.user!.outSA == 1) ? const EdgeInsets.all(0.0) : const EdgeInsets.all(15.0), + child: (model.user != null && model.user!.outSA == 1) + ? Container( + width: double.infinity, + height: double.infinity, + color: Colors.grey.shade500.withOpacity(0.3), + child: Icon( + Icons.lock_outline, + size: 40, + ), + ) + : Column( + children: [ + Image.asset( + 'assets/images/comprehensive_medical_checkup_logo.png', + width: 50, + height: 50, + ), + SizedBox( + height: 10, + ), + Texts( + TranslationBase.of(context).cmcHeading, + textAlign: TextAlign.center, + color: Colors.white, + fontWeight: FontWeight.w700, + fontSize: SizeConfig.textMultiplier! * 1.55, + ) + ], + )), ), height: MediaQuery.of(context).size.width * 0.4, - color: HexColor("#747C80"), + color: Color(0xFF747C80), imageName: 'emergency_service_image.png', ), ], @@ -612,15 +595,14 @@ class _HomePageState extends State { SizedBox( height: 8, ), - InkWell( - onTap: () => - Navigator.push(context, FadePage(page: PaymentService())), - child: Container( - margin: EdgeInsets.only(left: 15, right: 15), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Container( + Container( + margin: EdgeInsets.only(left: 15, right: 15), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + InkWell( + onTap: () => Navigator.push(context, FadePage(page: PaymentService())), + child: Container( width: MediaQuery.of(context).size.width * 0.29, child: Center( child: Padding( @@ -635,12 +617,11 @@ class _HomePageState extends State { height: 5, ), Texts( - TranslationBase.of(context) - .onlinePaymentService, + TranslationBase.of(context).onlinePaymentService, textAlign: TextAlign.center, color: Colors.black87, bold: false, - fontSize: SizeConfig.textMultiplier * 1.7, + fontSize: SizeConfig.textMultiplier! * 1.7, ) ], ), @@ -652,7 +633,12 @@ class _HomePageState extends State { color: Colors.white, ), ), - Container( + ), + InkWell( + onTap: () { + Navigator.push(context, FadePage(page: EReferralPage())); + }, + child: Container( child: Center( child: Padding( padding: const EdgeInsets.all(15.0), @@ -667,12 +653,11 @@ class _HomePageState extends State { height: 10, ), Texts( - TranslationBase.of(context) - .offersAndPackages, + TranslationBase.of(context).ereferral, textAlign: TextAlign.center, color: Colors.black87, bold: false, - fontSize: SizeConfig.textMultiplier * 1.7, + fontSize: SizeConfig.textMultiplier! * 1.7, ) ], ), @@ -684,53 +669,52 @@ class _HomePageState extends State { borderRadius: BorderRadius.circular(6.0), color: Colors.white, )), - if (projectViewModel.havePrivilege(60)) - Container( - width: MediaQuery.of(context).size.width * 0.29, - child: InkWell( - onTap: () => Navigator.push( - context, - FadePage( - page: ErOptions( - isAppbar: true, - ))), - child: Center( - child: Padding( - padding: const EdgeInsets.all(15.0), - child: Column( - children: [ - Image.asset( - 'assets/images/Dr_Schedule_report.png', - width: 50, - height: 50, - ), - SizedBox( - height: 10, - ), - Texts( - TranslationBase.of(context) - .emergencyServices, - textAlign: TextAlign.center, - color: Colors.black87, - bold: false, - fontSize: - SizeConfig.textMultiplier * 1.7, - ) - ], - ), + ), + if (projectViewModel.havePrivilege(60)) + Container( + width: MediaQuery.of(context).size.width * 0.29, + child: InkWell( + onTap: () => Navigator.push( + context, + FadePage( + page: ErOptions( + isAppbar: true, + ))), + child: Center( + child: Padding( + padding: const EdgeInsets.all(15.0), + child: Column( + children: [ + Image.asset( + 'assets/images/Dr_Schedule_report.png', + width: 50, + height: 50, + ), + SizedBox( + height: 10, + ), + Texts( + TranslationBase.of(context).emergencyServices, + textAlign: TextAlign.center, + color: Colors.black87, + bold: false, + fontSize: SizeConfig.textMultiplier! * 1.7, + ) + ], ), ), ), - height: MediaQuery.of(context).size.width * 0.4, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(6.0), - color: Colors.white, - ), ), - ], - ), + height: MediaQuery.of(context).size.width * 0.4, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(6.0), + color: Colors.white, + ), + ), + ], ), ), + // ), SizedBox( height: 5, ), @@ -752,8 +736,7 @@ class _HomePageState extends State { fontWeight: FontWeight.normal, ), Texts( - TranslationBase.of(context) - .viewAllHabibMedicalService, + TranslationBase.of(context).viewAllHabibMedicalService, color: Colors.white, fontWeight: FontWeight.normal, fontSize: 10, @@ -772,17 +755,15 @@ class _HomePageState extends State { height: 100, imageName: 'contact_us_bg.png', opacity: 0.5, - color: Colors.grey[700], + color: Colors.grey[700]!, width: MediaQuery.of(context).size.width * 0.45, - onTap: () => Navigator.push( - context, FadePage(page: AllHabibMedicalService())), + onTap: () => Navigator.push(context, FadePage(page: AllHabibMedicalService())), ), DashboardItem( onTap: () { // Navigator.push( // context, FadePage(page: FeedbackHomePage())); - Navigator.push( - context, FadePage(page: ContactUsPage())); + Navigator.push(context, FadePage(page: ContactUsPage())); }, child: Container( width: double.infinity, @@ -791,7 +772,7 @@ class _HomePageState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Texts( - TranslationBase.of(context).contactUs, + TranslationBase.of(context).reachUs, color: Colors.white, fontWeight: FontWeight.normal, ), @@ -815,7 +796,7 @@ class _HomePageState extends State { height: 100, imageName: 'contact_us_bg.png', opacity: 0.5, - color: Colors.grey[700], + color: Colors.grey[700]!, width: MediaQuery.of(context).size.width * 0.45, ), ], @@ -833,20 +814,15 @@ class _HomePageState extends State { } getPharmacyToken(DashboardViewModel model) async { - if(!model.isLogin) { + if (!model.isLogin) { Navigator.push(context, FadePage(page: LandingPagePharmacy())); } else { GifLoaderDialogUtils.showMyDialog(context); await pharmacyModuleViewModel.generatePharmacyToken().then((value) async { - if (pharmacyModuleViewModel.error.isNotEmpty) { - await pharmacyModuleViewModel.createUser().then((value) { - GifLoaderDialogUtils.hideDialog(context); - Navigator.push(context, FadePage(page: LandingPagePharmacy())); - }); - } else { + await pharmacyModuleViewModel.verifyCustomer().then((value) { GifLoaderDialogUtils.hideDialog(context); Navigator.push(context, FadePage(page: LandingPagePharmacy())); - } + }); }); } } @@ -857,32 +833,22 @@ class _HomePageState extends State { } class DashboardItem extends StatelessWidget { - const DashboardItem( - {this.hasBorder = false, - this.imageName, - @required this.child, - this.onTap, - Key key, - this.width, - this.height, - this.color, - this.opacity = 0.4, - this.hasColorFilter = true}) + const DashboardItem({this.hasBorder = false, this.imageName, this.child, this.onTap, Key? key, this.width, this.height, this.color, this.opacity = 0.4, this.hasColorFilter = true}) : super(key: key); final bool hasBorder; - final String imageName; - final Widget child; - final Function onTap; - final double width; - final double height; - final Color color; - final double opacity; + final String? imageName; + final Widget? child; + final Function? onTap; + final double? width; + final double? height; + final Color? color; + final double? opacity; final bool hasColorFilter; @override Widget build(BuildContext context) { return InkWell( - onTap: onTap, + onTap: onTap!(), child: Container( width: width != null ? width : MediaQuery.of(context).size.width * 0.29, height: height != null @@ -894,20 +860,15 @@ class DashboardItem extends StatelessWidget { color: !hasBorder ? color != null ? color - : HexColor('#050705').withOpacity(opacity) + : Color(0xFF050705).withOpacity(opacity!) : Colors.white, borderRadius: BorderRadius.circular(6.0), - border: hasBorder - ? Border.all(width: 1.0, color: const Color(0xffcccccc)) - : Border.all(width: 0.0, color: Colors.transparent), + border: hasBorder ? Border.all(width: 1.0, color: const Color(0xffcccccc)) : Border.all(width: 0.0, color: Colors.transparent), image: imageName != null ? DecorationImage( image: ExactAssetImage('assets/images/$imageName'), fit: BoxFit.cover, - colorFilter: hasColorFilter - ? new ColorFilter.mode( - Colors.black.withOpacity(0.2), BlendMode.dstIn) - : null, + colorFilter: hasColorFilter ? new ColorFilter.mode(Colors.black.withOpacity(0.2), BlendMode.dstIn) : null, ) : null, ), diff --git a/lib/pages/landing/home_page_2.dart b/lib/pages/landing/home_page_2.dart new file mode 100644 index 00000000..a5fff824 --- /dev/null +++ b/lib/pages/landing/home_page_2.dart @@ -0,0 +1,104 @@ +import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/core/viewModels/dashboard_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/locator.dart'; +import 'package:diplomaticquarterapp/pages/Covid-DriveThru/covid-drivethru-location.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/pages/conference/zoom/call_screen.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +import 'package:firebase_crashlytics/firebase_crashlytics.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:url_launcher/url_launcher.dart'; +import 'package:url_launcher/url_launcher_string.dart'; + +import 'fragments/home_page_fragment2.dart'; +import 'landing_page_pharmcy.dart'; + +class HomePage2 extends StatefulWidget { + final Function? goToMyProfile; + VoidCallback? onLoginClick, onMedicalFileClick; + + HomePage2({Key? key, this.goToMyProfile, this.onLoginClick, this.onMedicalFileClick}); + + @override + _HomePageState2 createState() => _HomePageState2(); +} + +class _HomePageState2 extends State { + PharmacyModuleViewModel pharmacyModuleViewModel = locator(); + late ProjectViewModel projectViewModel; + + @override + void initState() { + super.initState(); + } + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + + return BaseView( + onModelReady: (model) => model.getPatientRadOrders(), + builder: (_, model, wi) => Container( + color: CustomColors.backgroudGreyColor, + // color: Colors.yellow, + child: SingleChildScrollView( + physics: BouncingScrollPhysics(), + child: Column( + children: [ + HomePageFragment2( + model, + onLoginClick: () { + widget.onLoginClick!(); + // FirebaseCrashlytics.instance.crash(); + // Navigator.pushNamed( + // context, + // "zoom_call_page", + // arguments: CallArguments("h9qkpf02", "123", "Patient", "40", "1", false), + // ); + }, + onPharmacyClick: () { + // getPharmacyToken(model); + Uri uri = Uri.parse(PHARMACY_REDIRECT_URL); + launchUrl(uri, mode: LaunchMode.externalApplication); + }, + onMedicalFileClick: () { + widget.onMedicalFileClick!(); + }, + ) + ], + ), + ), + ), + ); + } + + getPharmacyToken(DashboardViewModel model) async { + if (!model.isLogin) { + Navigator.push(context, FadePage(page: LandingPagePharmacy())); + } else { + GifLoaderDialogUtils.showMyDialog(context); + await pharmacyModuleViewModel.generatePharmacyToken().then((value) async { + if (!pharmacyModuleViewModel.error.isNotEmpty) { + await pharmacyModuleViewModel.createUser().then((value) { + GifLoaderDialogUtils.hideDialog(context); + Navigator.push(context, FadePage(page: LandingPagePharmacy())); + }); + } else { + GifLoaderDialogUtils.hideDialog(context); + Navigator.push(context, FadePage(page: LandingPagePharmacy())); + } + }); + } + } + + navigateToCovidDriveThru() { + Navigator.push(context, FadePage(page: CovidDrivethruLocation())); + } +} diff --git a/lib/pages/landing/landing_page.dart b/lib/pages/landing/landing_page.dart index c99930aa..ffc9fec5 100644 --- a/lib/pages/landing/landing_page.dart +++ b/lib/pages/landing/landing_page.dart @@ -1,79 +1,128 @@ +import 'dart:async'; import 'dart:io'; import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; -import 'package:diplomaticquarterapp/core/model/geofencing/requests/GeoZonesRequestModel.dart'; +import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; import 'package:diplomaticquarterapp/core/service/AuthenticatedUserObject.dart'; -import 'package:diplomaticquarterapp/core/service/geofencing/GeofencingServices.dart'; +import 'package:diplomaticquarterapp/core/viewModels/appointment_rate_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; -import 'package:diplomaticquarterapp/models/Authentication/select_device_imei_res.dart'; import 'package:diplomaticquarterapp/models/LiveCare/IncomingCallData.dart'; -import 'package:diplomaticquarterapp/pages/BookAppointment/BookingOptions.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/Search.dart'; import 'package:diplomaticquarterapp/pages/DrawerPages/family/my-family.dart'; import 'package:diplomaticquarterapp/pages/ToDoList/ToDo.dart'; -import 'package:diplomaticquarterapp/pages/livecare/incoming_call.dart'; -import 'package:diplomaticquarterapp/pages/medical/medical_profile_page.dart'; +import 'package:diplomaticquarterapp/pages/landing/home_page_2.dart'; +import 'package:diplomaticquarterapp/pages/medical/medical_profile_page_new.dart'; import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; +import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; import 'package:diplomaticquarterapp/services/family_files/family_files_provider.dart' as family; +import 'package:diplomaticquarterapp/services/livecare_services/livecare_provider.dart'; +import 'package:diplomaticquarterapp/services/payfort_services/payfort_view_model.dart'; import 'package:diplomaticquarterapp/services/robo_search/event_provider.dart'; -import 'package:diplomaticquarterapp/uitl/CalendarUtils.dart'; -import 'package:diplomaticquarterapp/uitl/HMGNetworkConnectivity.dart'; -import 'package:diplomaticquarterapp/uitl/HMG_Geofence.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/LocalNotification.dart'; -import 'package:diplomaticquarterapp/uitl/PlatformBridge.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/location_util.dart'; +import 'package:diplomaticquarterapp/uitl/push-notification-handler.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/bottom_navigation/bottom_nav_bar.dart'; import 'package:diplomaticquarterapp/widgets/buttons/floatingActionButton.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; -import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; import 'package:diplomaticquarterapp/widgets/drawer/app_drawer_widget.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/others/not_auh_page.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +// import 'package:flutter_app_icon_badge/flutter_app_icon_badge.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; -import 'package:permission_handler/permission_handler.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:flutter_zoom_videosdk/native/zoom_videosdk.dart'; import 'package:provider/provider.dart'; -import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; + import '../../locator.dart'; import '../../routes.dart'; -import 'home_page.dart'; class LandingPage extends StatefulWidget { + static late LandingPage shared; + late _LandingPageState state; + + LandingPage() { + LandingPage.shared = this; + } + static bool isOpenCallPage = false; static IncomingCallData incomingCallData = new IncomingCallData(); @override - _LandingPageState createState() => _LandingPageState(); + _LandingPageState createState() => state = _LandingPageState(); + + switchToDoFromHMGServices() { + state.changeCurrentTab(4); + } } class _LandingPageState extends State with WidgetsBindingObserver { var authProvider = new AuthProvider(); + AppointmentRateViewModel appointmentRateViewModel = locator(); int currentTab = 0; - PageController pageController; - ProjectViewModel projectViewModel; + late PageController pageController; + late ProjectViewModel projectViewModel; + late ToDoCountProviderModel model; var notificationCount = ''; var themeNotifier; + DateTime? currentBackPressTime; + + // SignalRUtil signalRUtil; + + late ToDoCountProviderModel toDoProvider; + + bool _showBottomNavigationBar = true; ///inject the user data - AuthenticatedUserObject authenticatedUserObject = - locator(); + AuthenticatedUserObject authenticatedUserObject = locator(); - final FirebaseMessaging _firebaseMessaging = FirebaseMessaging(); + final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance; final authService = new AuthProvider(); + var event = RobotProvider(); var familyFileProvider = family.FamilyFilesProvider(); + // VoIPKit + var dummyCallId = '123456'; + var dummyCallerName = 'Dummy Tester'; + late Timer timeOutTimer; + bool isTalking = false; + + var sharedPref = new AppSharedPreferences(); + + var data = { + "AppointmentNo": "2016059247", + "ProjectID": "15", + "NotificationType": "10", + "background": "0", + "doctorname": "Call from postman", + "clinicname": "LIVECARE FAMILY MEDICINE AND GP", + "speciality": "General Practioner", + "appointmentdate": "2022-01-19", + "appointmenttime": "12:10", + "PatientName": "Testing", + "session_id": "1_MX40NjIwOTk2Mn5-MTY0NzI1NjYxNDI2OX5ySXhlVjZjam13RFdMVmdleWVsSDhzQkx-fg", + "token": + "T1==cGFydG5lcl9pZD00NjIwOTk2MiZzaWc9OGMyY2IyYWFiZmZmMzI4ZmEwMjgxNDdmMGFhZGI0N2JiZjdmZWY4MjpzZXNzaW9uX2lkPTFfTVg0ME5qSXdPVGsyTW41LU1UWTBOekkxTmpZeE5ESTJPWDV5U1hobFZqWmphbTEzUkZkTVZtZGxlV1ZzU0RoelFreC1mZyZjcmVhdGVfdGltZT0xNjQ3MjU2NjE0Jm5vbmNlPTAuMjgzNDgyNjM1NDczNjQ2OCZyb2xlPW1vZGVyYXRvciZleHBpcmVfdGltZT0xNjQ3MjU4NDE0JmluaXRpYWxfbGF5b3V0X2NsYXNzX2xpc3Q9", + "DoctorImageURL": "https://image.shutterstock.com/image-vector/sample-stamp-square-grunge-sign-260nw-1474408826.jpg", + "callerID": "9920", + "PatientID": "1231755", + "is_call": "true" + }; + void _requestIOSPermissions() { - flutterLocalNotificationsPlugin - .resolvePlatformSpecificImplementation< - IOSFlutterLocalNotificationsPlugin>() - ?.requestPermissions( + flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation()?.requestPermissions( alert: true, badge: true, sound: true, @@ -81,59 +130,130 @@ class _LandingPageState extends State with WidgetsBindingObserver { } bool isPageNavigated = false; - LocationUtils locationUtils; - - _changeCurrentTab(int tab) { - setState(() { - currentTab = tab; - if (tab != 0) - pageController.jumpToPage(tab); - else { - IS_VOICE_COMMAND_CLOSED = false; - pageController.jumpToPage(tab); + late LocationUtils locationUtils; + + Future onWillPop() { + if (currentTab != 0) { + changeCurrentTab(0); + return Future.value(false); + } else { + DateTime now = DateTime.now(); + if (currentBackPressTime == null || now.difference(currentBackPressTime!) > Duration(seconds: 2)) { + currentBackPressTime = now; + AppToast.showToast(message: TranslationBase.of(context).pressAgain); + return Future.value(false); } - }); + return Future.value(true); + } } - @override - void didChangeAppLifecycleState(AppLifecycleState state) { - super.didChangeAppLifecycleState(state); + changeCurrentTab(int tab) { + if (!projectViewModel.isLogin) { + if (tab == 3) { + List imagesInfo = []; + imagesInfo.add( + ImagesInfo( + imageEn: 'https://hmgwebservices.com/Images/MobileApp/images-info-home/family-file/en/0.png', + imageAr: 'https://hmgwebservices.com/Images/MobileApp/images-info-home/family-file/ar/0.png'), + ); - var route = ModalRoute.of(context); + imagesInfo.add( + ImagesInfo( + imageEn: 'https://hmgwebservices.com/Images/MobileApp/images-info-home/family-file/en/1.png', + imageAr: 'https://hmgwebservices.com/Images/MobileApp/images-info-home/family-file/ar/1.png'), + ); - if (route != null) { - print(route.settings.name); + Navigator.push( + context, + MaterialPageRoute( + builder: (cxt) => NotAutPage( + title: TranslationBase.of(context).myFamilyFiles, + description: TranslationBase.of(context).familyInfo, + infoList: [], + imagesInfo: imagesInfo, + icon: "assets/images/new/bottom_nav/family_files.svg", + ), + ), + ); + return; + } + if (tab == 4) { + List imagesInfo = []; + imagesInfo.add( + ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/images-info-home/todo/en/0.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/images-info-home/todo/ar/0.png')); + + Navigator.push( + context, + MaterialPageRoute( + builder: (cxt) => NotAutPage( + title: TranslationBase.of(context).todoList, + description: TranslationBase.of(context).infoTodo, + infoList: [], + imagesInfo: imagesInfo, + icon: "assets/images/new/bottom_nav/todo.svg", + ), + ), + ); + return; + } } + // Future.delayed(Duration(seconds: 0), () { + // setState(() { + if (tab == 5) { + IS_VOICE_COMMAND_CLOSED = false; + triggerRobot(); - //setState(() { - print("didChangeAppLifecycleState"); - print('state = $state'); - AppGlobal.context = context; - if (state == AppLifecycleState.resumed) { - print(LandingPage.isOpenCallPage); - if (LandingPage.isOpenCallPage) { - if (!isPageNavigated) { - isPageNavigated = true; - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => IncomingCall( - incomingCallData: LandingPage.incomingCallData))) - .then((value) { - isPageNavigated = false; - }); + // pageController.jumpToPage(tab); + } else { + if (currentTab > 0 && tab == 2) { + pageController.jumpToPage(0); + + currentTab = tab; + } else if (tab != 0) { + // if (tab == 4 && projectViewModel.isLogin && model.count == 0) { + // AppToast.showErrorToast(message: TranslationBase.of(context).noBookedAppo); + // } else { + pageController.jumpToPage(tab); + currentTab = tab; + // } + } else { + pageController.jumpToPage(tab); + currentTab = tab; + } + setState(() {}); + // currentTab = tab; } - } - } + // }); + // }); - if (state == AppLifecycleState.paused) { - isPageNavigated = false; - } + projectViewModel.analytics.bottomTabNavigation.log(tabIndex: tab, isLoggedIn: projectViewModel.isLogin); + } + + getToDoCount() { + toDoProvider.setState(0, 0, true, toDoProvider.notificationsCount); + ClinicListService service = new ClinicListService(); + service.getActiveAppointmentNo(context).then((res) { + GifLoaderDialogUtils.hideDialog(context); + print(res['AppointmentActiveNumber']); + if (res['MessageStatus'] == 1) { + // toDoProvider.setState(res['AppointmentActiveNumber'], true, toDoProvider.notificationsCount); + toDoProvider.setState(res['AppointmentActiveNumber'], res['AncillaryOrderListCount'], true, toDoProvider.notificationsCount); + } else {} + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } - if (state == AppLifecycleState.inactive) { - isPageNavigated = false; + @override + void didChangeAppLifecycleState(AppLifecycleState state) { + super.didChangeAppLifecycleState(state); + + AppGlobal.context = context; + if (state == AppLifecycleState.resumed) { + PushNotificationHandler.getInstance().onResume(); + sharedPref.remove(APPOINTMENT_HISTORY_MEDICAL); } - //}); } @override @@ -145,214 +265,67 @@ class _LandingPageState extends State with WidgetsBindingObserver { @override void initState() { super.initState(); + PushNotificationHandler.getInstance().onResume(); + WidgetsBinding.instance.addObserver(this); - //setState(() { + AppGlobal.context = context; - // }); - _requestIOSPermissions(); pageController = PageController(keepPage: true); - _firebaseMessaging.setAutoInitEnabled(true); - locationUtils = - new LocationUtils(isShowConfirmDialog: true, context: context); - WidgetsBinding.instance - .addPostFrameCallback((_) => locationUtils.getCurrentLocation()); - // HMG (Guest/Internet) Wifi Access [Zohaib Kambrani] - HMGNetworkConnectivity(context, () { - GifLoaderDialogUtils.showMyDialog(context); - PlatformBridge() - .connectHMGGuestWifi() - .then((value) => {GifLoaderDialogUtils.hideDialog(context)}); - }).checkAndConnectIfNoInternet(); + _firebaseMessaging.setAutoInitEnabled(true); - if (Platform.isIOS) { - _firebaseMessaging.requestNotificationPermissions(); - } + WidgetsBinding.instance.addPostFrameCallback((_) { + if (projectViewModel.isLogin && !projectViewModel.isLoginChild) { + int languageID = Provider.of(context, listen: false).isArabic ? 1 : 2; + familyFileProvider.getSharedRecordByStatus(languageID); + } + // Future.delayed(Duration(seconds: 3)).then((result) async { + // LocalNotification.getInstance().showNow(title: "Payload Update", subtitle: "Payload Update", payload: "Payload Update"); + // }); + }); - requestPermissions().then((results) { - registerGeofences(); + PayfortViewModel payfortViewModel = context.read(); + payfortViewModel.initPayfort(); - if (results[Permission.notification].isGranted) - _firebaseMessaging.getToken().then((String token) { - sharedPref.setString(PUSH_TOKEN, token); - if (token != null && DEVICE_TOKEN == "") { - DEVICE_TOKEN = token; - checkUserStatus(token); - } + // HMG (Guest/Internet) Wifi Access [Zohaib Kambrani] + // for now commented to reduce this call will enable it when needed + // HMGNetworkConnectivity(context).start(); + + _firebaseMessaging.getToken().then((String? token) { + // print("Firebase Token: " + token!); + sharedPref.setString(PUSH_TOKEN, token!); + if (Platform.isIOS) { + FirebaseMessaging.instance.getAPNSToken().then((value) { + print("Push APNS getToken: " + value!); + AppSharedPreferences().setString(APNS_TOKEN, value); + AppSharedPreferences().setString(ONESIGNAL_APNS_TOKEN, value); }); - if (results[Permission.location].isGranted) ; - if (results[Permission.storage].isGranted) ; - if (results[Permission.camera].isGranted) ; - if (results[Permission.photos].isGranted) ; - if (results[Permission.accessMediaLocation].isGranted) ; - // if (results[Permission.calendar].isGranted) ; + // voIPKit.getVoIPToken().then((value) { + // print('🎈 example: getVoIPToken: $value'); + // AppSharedPreferences().setString(APNS_TOKEN, value!); + // // getOneSignalVOIPToken(value); + // }); + } + if (token != null) { + DEVICE_TOKEN = token; + if (!projectViewModel.isLoginChild) { + checkUserStatus(token); + } + } + }).catchError((err) { + print(err); }); - requestPermissions(); - // }); - // - // //_firebase Background message handler - // _firebaseMessaging.configure( - // // onMessage: (Map message) async { - // // showDialog("onMessage: $message"); - // // print("onMessage: $message"); - // // print(message); - // // print(message['name']); - // // print(message['appointmentdate']); - // // - // // if (Platform.isIOS) { - // // if (message['is_call'] == "true") { - // // var route = ModalRoute.of(context); - // // - // // if (route != null) { - // // print(route.settings.name); - // // } - // // - // // Map myMap = new Map.from(message); - // // print(myMap); - // // LandingPage.isOpenCallPage = true; - // // LandingPage.incomingCallData = IncomingCallData.fromJson(myMap); - // // if (!isPageNavigated) { - // // isPageNavigated = true; - // // Navigator.push( - // // context, - // // MaterialPageRoute( - // // builder: (context) => IncomingCall( - // // incomingCallData: LandingPage.incomingCallData))) - // // .then((value) { - // // isPageNavigated = false; - // // }); - // // } - // // } else { - // // print("Is Call Not Found iOS"); - // // } - // // } else { - // // print("Is Call Not Found iOS"); - // // } - // // - // // if (Platform.isAndroid) { - // // if (message['data'].containsKey("is_call")) { - // // var route = ModalRoute.of(context); - // // - // // if (route != null) { - // // print(route.settings.name); - // // } - // // - // // Map myMap = - // // new Map.from(message['data']); - // // print(myMap); - // // LandingPage.isOpenCallPage = true; - // // LandingPage.incomingCallData = IncomingCallData.fromJson(myMap); - // // if (!isPageNavigated) { - // // isPageNavigated = true; - // // Navigator.push( - // // context, - // // MaterialPageRoute( - // // builder: (context) => IncomingCall( - // // incomingCallData: LandingPage.incomingCallData))) - // // .then((value) { - // // isPageNavigated = false; - // // }); - // // } - // // } else { - // // print("Is Call Not Found Android"); - // // } - // // } else { - // // print("Is Call Not Found Android"); - // // } - // // }, - // // onBackgroundMessage: Platform.isIOS ? null : myBackgroundMessageHandler, - // // onLaunch: (Map message) async { - // // print("onLaunch: $message"); - // // showDialog("onLaunch: $message"); - // // }, - // // onResume: (Map message) async { - // // print("onResume: $message"); - // // print(message); - // // print(message['name']); - // // print(message['appointmentdate']); - // // - // // showDialog("onResume: $message"); - // // - // // if (Platform.isIOS) { - // // if (message['is_call'] == "true") { - // // var route = ModalRoute.of(context); - // // - // // if (route != null) { - // // print(route.settings.name); - // // } - // // - // // Map myMap = - // // new Map.from(message); - // // print(myMap); - // // LandingPage.isOpenCallPage = true; - // // LandingPage.incomingCallData = IncomingCallData.fromJson(myMap); - // // if (!isPageNavigated) { - // // isPageNavigated = true; - // // Navigator.push( - // // context, - // // MaterialPageRoute( - // // builder: (context) => IncomingCall( - // // incomingCallData: LandingPage.incomingCallData))) - // // .then((value) { - // // isPageNavigated = false; - // // }); - // // } - // // } else { - // // print("Is Call Not Found iOS"); - // // } - // // } else { - // // print("Is Call Not Found iOS"); - // // } - // // }, - // ); - } - - 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, - Permission.locationAlways, - Permission.storage, - Permission.camera, - Permission.photos, - Permission.notification, - Permission.accessMediaLocation, - // Permission.calendar, - Permission.activityRecognition - ].request(); - - // var permissionsGranted = await deviceCalendarPlugin.hasPermissions(); - // if (permissionsGranted.isSuccess && !permissionsGranted.data) { - // permissionsGranted = await deviceCalendarPlugin.requestPermissions(); - // if (!permissionsGranted.isSuccess || !permissionsGranted.data) {} - // } - return permissionResults; + startZoom(); + // HMG_Geofencing(context).loadZones().then((instance) => instance.init()); } - static Future myBackgroundMessageHandler( - Map message) async { - Map myMap = new Map.from(message['data']); - if (message.containsKey('data')) { - print("myBackgroundMessageHandler Inside"); - LandingPage.incomingCallData = IncomingCallData.fromJson(myMap); - print(LandingPage.incomingCallData.doctorname); - LandingPage.isOpenCallPage = true; - } - - if (message.containsKey('notification')) { - final dynamic notification = message['notification']; - print(notification); - } + void startZoom() { + var zoom = ZoomVideoSdk(); + InitConfig initConfig = InitConfig( + domain: "zoom.us", + enableLog: true, + ); + zoom.initSdk(initConfig); } void setUserValues(value) async { @@ -366,30 +339,30 @@ class _LandingPageState extends State with WidgetsBindingObserver { checkValue(projectProvider) { if (projectProvider.searchValue != null) { - _changeCurrentTab(2); + changeCurrentTab(2); } } - registerGeofences() async { - await locator().getAllGeoZones(GeoZonesRequestModel()); - - void doIt() { - getUserInformation().then((value) { - if (value != null) - projectViewModel.platformBridge().registerHmgGeofences(); - }); - } - - if (await Permission.location.isGranted) { - doIt(); - } else { - [Permission.location].request().then((value) async { - if (await Permission.location.isGranted) { - doIt(); - } - }); - } - } + // registerGeofences() async { + // await locator().getAllGeoZones(GeoZonesRequestModel()); + // + // // void doIt() { + // // // getUserInformation().then((value) { + // // // if (value != null) + // // projectViewModel.platformBridge().registerHmgGeofences(); + // // // }); + // // } + // // + // // if (await Permission.location.isGranted) { + // // doIt(); + // // } else { + // // [Permission.location].request().then((value) async { + // // if (await Permission.location.isGranted) { + // // doIt(); + // // } + // // }); + // // } + // } login() async { var data = await sharedPref.getObject(IMEI_USER_DATA); @@ -397,50 +370,98 @@ class _LandingPageState extends State with WidgetsBindingObserver { if (data != null) { Navigator.of(context).pushNamed(CONFIRM_LOGIN); } else { + // AppGlobal.context = context; GifLoaderDialogUtils.showMyDialog(context); - authService - .selectDeviceImei(DEVICE_TOKEN) - .then((SelectDeviceIMEIRES value) { + authService.selectDeviceImei(DEVICE_TOKEN).then((value) async { GifLoaderDialogUtils.hideDialog(context); + var data = await sharedPref.getObject(IMEI_USER_DATA); if (value != null) { setUserValues(value); Navigator.of(context).pushNamed(CONFIRM_LOGIN); } else { + GifLoaderDialogUtils.hideDialog(context); Navigator.of(context).pushNamed( WELCOME_LOGIN, ); } }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); - Navigator.of(context).pushNamed( - WELCOME_LOGIN, - ); + Navigator.of(context).pushNamed(WELCOME_LOGIN); }); } } + dummyCall() async { + // final server = await SelectionDialog( + // context, + // title: "Select Server", + // items: ["https://livecareturn.hmg.com:8086", "https://104.197.179.1:8086"] + // ).show(); + // + // final json = { + // "callerID": "s1", + // "PatientID": "s2", + // "msgID": "123", + // "notfID": "123", + // "notification_foreground": "true", + // "count": "1", + // "message": "Doctor is calling ", + // "AppointmentNo": "123", + // "title": "Rayyan Hospital", + // "ProjectID": "123", + // "NotificationType": "10", + // "background": "1", + // "doctorname": "Dr Sulaiman Al Habib", + // "clinicname": "ENT Clinic", + // "speciality": "Speciality", + // "appointmentdate": "Sun, 15th Dec, 2019", + // "appointmenttime": "09:00", + // "type": "video", + // "session_id": + // "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImN0eSI6InR3aWxpby1mcGE7dj0xIn0.eyJqdGkiOiJTS2I2NjYyOWMzN2ZhOTM3YjFjNDI2Zjg1MTgyNWFmN2M0LTE1OTg3NzQ1MDYiLCJpc3MiOiJTS2I2NjYyOWMzN2ZhOTM3YjFjNDI2Zjg1MTgyNWFmN2M0Iiwic3ViIjoiQUNhYWQ1YTNmOGM2NGZhNjczNTY3NTYxNTc0N2YyNmMyYiIsImV4cCI6MTU5ODc3ODEwNiwiZ3JhbnRzIjp7ImlkZW50aXR5IjoiSGFyb29uMSIsInZpZGVvIjp7InJvb20iOiJTbWFsbERhaWx5U3RhbmR1cCJ9fX0.7XUS5uMQQJfkrBZu9EjQ6STL6R7iXkso6BtO1HmrQKk", + // "identity": "Haroon1", + // "name": "SmallDailyStandup", + // "videoUrl": "video", + // "picture": "video", + // "is_call": "true", + // "server": server, + // }; + + // IncomingCallData incomingCallData = IncomingCallData.fromJson(json); + // final result = await Navigator.push(context, MaterialPageRoute(builder: (context) => IncomingCall(incomingCallData: incomingCallData))); + + String callerId = + "2_MX40NjIwOTk2Mn5-MTY1NjU3NTQ4MzQ0NX5aSGczeVlObGNVMGJXWEFWRnc0akZRcm1-fg*T1==cGFydG5lcl9pZD00NjIwOTk2MiZzaWc9MzY5MTBmZmUyMDRiNjE3NTRiYzlmNjVjMTEyZTE1MWFjN2YxYjAxZTpzZXNzaW9uX2lkPTJfTVg0ME5qSXdPVGsyTW41LU1UWTFOalUzTlRRNE16UTBOWDVhU0djemVWbE9iR05WTUdKWFdFRldSbmMwYWtaUmNtMS1mZyZjcmVhdGVfdGltZT0xNjU2NTc1NDgzJm5vbmNlPTAuNzM3OTQyOTY4Mzg5OTU1MiZyb2xlPW1vZGVyYXRvciZleHBpcmVfdGltZT0xNjU2NjYxODgzJmluaXRpYWxfbGF5b3V0X2NsYXNzX2xpc3Q9*true*s1*s2*https://livecareturn.hmg.com:8086"; + + String sessionID = callerId.split("*")[0]; + String token = callerId.split("*")[1]; + String isWebRTC = callerId.split("*")[2]; + + print("🎈 SessionID: $sessionID"); + print("🎈 Token: $token"); + print("🎈 isWebRTC: $isWebRTC"); + + String caller = callerId.split("*")[3]; + String receiver = callerId.split("*")[4]; + String host = callerId.split("*")[5]; + // await Navigator.push(context, MaterialPageRoute(builder: (context) => StartVideoCall(caller: caller, receiver: receiver, iAmCaller: false, host: host))); + } + getNotificationCount(token) async { if (await sharedPref.getObject(USER_PROFILE) != null) { - var data = - AuthenticatedUser.fromJson(await sharedPref.getObject(USER_PROFILE)); + var data = AuthenticatedUser.fromJson(await sharedPref.getObject(USER_PROFILE)); if (data != null) { - authService - .registeredAuthenticatedUser(data, token, 0, 0) - .then((res) => {print(res)}); authService.getDashboard().then((value) => { - setState(() { - notificationCount = value['List_PatientDashboard'][0] - ['UnreadPatientNotificationCount'] > - 99 - ? '99+' - : value['List_PatientDashboard'][0] - ['UnreadPatientNotificationCount'] - .toString(); - - sharedPref.setString(NOTIFICATION_COUNT, notificationCount); - }) + if (value != null) + { + setState(() { + notificationCount = + value['List_PatientDashboard'][0]['UnreadPatientNotificationCount'] > 99 ? '99+' : value['List_PatientDashboard'][0]['UnreadPatientNotificationCount'].toString(); + model.setState(model.count, 0, true, notificationCount); + sharedPref.setString(NOTIFICATION_COUNT, notificationCount); + }) + } }); - familyFileProvider.getSharedRecordByStatus(); } } } @@ -448,127 +469,163 @@ class _LandingPageState extends State with WidgetsBindingObserver { @override Widget build(BuildContext context) { projectViewModel = Provider.of(context); - + model = Provider.of(context); + // currentTab == 0 ? 45 : 0.0 return Scaffold( - appBar: AppBar( - elevation: 0, - textTheme: TextTheme( - headline6: TextStyle( - color: Theme.of(context).textTheme.headline1.color, - fontWeight: FontWeight.bold), - ), - title: Text( - getText(currentTab).toUpperCase(), - style: TextStyle( - fontWeight: FontWeight.bold, - color: Theme.of(context).textTheme.headline1.color, - fontFamily: projectViewModel.isArabic ? 'Cairo' : 'WorkSans'), - // bold: true, - // color: Colors.white, - ), - leading: Builder( - builder: (BuildContext context) { - return new Stack( - children: [ - currentTab == 0 - ? IconButton( - icon: Icon(Icons.menu), - color: Theme.of(context).textTheme.headline1.color, - onPressed: () => Scaffold.of(context).openDrawer(), - ) - : IconButton( - icon: Icon(Icons.arrow_back), - color: Theme.of(context).textTheme.headline1.color, - onPressed: () { - setState(() { - currentTab = 0; - }); - - pageController.jumpToPage(0); - }, - ), - notificationCount != '' - ? new Positioned( - right: projectViewModel.isArabic ? 35 : 0, - top: 5, - child: new Container( - padding: EdgeInsets.all(4), - decoration: new BoxDecoration( - color: Colors.red, - borderRadius: BorderRadius.circular(20), - ), - constraints: BoxConstraints( - minWidth: 20, - minHeight: 20, - ), - child: new Text( - notificationCount, - style: new TextStyle( - color: Colors.white, - fontSize: projectViewModel.isArabic ? 8 : 9, - ), - textAlign: TextAlign.center, - ), - ), - ) - : SizedBox() - ], - ); - }, - ), - actions: [ - IconButton( - //iconSize: 70, - icon: Icon( - projectViewModel.isLogin ? Icons.settings : Icons.login, - color: Theme.of(context).textTheme.headline1.color, - ), - onPressed: () { - if (projectViewModel.isLogin) - Navigator.of(context).pushNamed( - SETTINGS, - ); - else - login(); - }, //do something, - ) - ], - centerTitle: true, - ), + appBar: currentTab == 0 + ? PreferredSize( + preferredSize: Size.fromHeight(currentTab == 0 ? 45 : 0.0), + child: AppBar( + elevation: 0, + backgroundColor: CustomColors.backgroudGreyColor, + //Changed By Aamir + // textTheme: TextTheme( + // headline6: TextStyle(color: Theme.of(context).textTheme.headline1!.color, fontWeight: FontWeight.bold), + // ), + title: Text( + getText(currentTab).toUpperCase(), + style: TextStyle( + fontWeight: FontWeight.bold, + color: currentTab == 0 ? CustomColors.backgroudGreyColor : CustomColors.accentColor, + // : Theme.of(context).textTheme.headline1!.color, + fontFamily: projectViewModel.isArabic ? 'Cairo' : 'Poppins'), + // bold: true, + ), + leading: Builder( + builder: (BuildContext context) { + return new Stack( + children: [ + currentTab == 0 + ? IconButton( + icon: SvgPicture.asset("assets/images/new/menu.svg"), + // color: Theme.of(context).textTheme.headline1!.color, + color: CustomColors.white, + onPressed: () => Scaffold.of(context).openDrawer(), + ) + : IconButton( + icon: Icon(Icons.arrow_back), + onPressed: () { + setState(() { + currentTab = 0; + }); + pageController.jumpToPage(0); + }, + ), + projectViewModel.isLogin && model.notificationsCount != null && !projectViewModel.isLoginChild + ? Positioned( + right: projectViewModel.isArabic ? 35 : 0, + top: 5, + child: new Container( + padding: EdgeInsets.all(4), + decoration: new BoxDecoration( + color: CustomColors.accentColor, + borderRadius: BorderRadius.circular(20), + ), + constraints: BoxConstraints( + minWidth: 20, + minHeight: 20, + ), + child: Text( + model.notificationsCount.toString(), + style: TextStyle( + color: Colors.white, + fontSize: projectViewModel.isArabic ? 8 : 9, + ), + textAlign: TextAlign.center, + ), + ), + ) + : SizedBox() + ], + ); + }, + ), + actions: [ + // IconButton( + // //iconSize: 70, + // icon: Icon( + // projectViewModel.isLogin ? Icons.settings : Icons.login, + // color: Theme.of(context).textTheme.headline1.color, + // ), + // onPressed: () { + // if (projectViewModel.isLogin) + // Navigator.of(context).pushNamed( + // SETTINGS, + // ); + // else + // login(); + // }, //do something, + // ) + ], + centerTitle: true, + ), + ) + : null, drawer: SafeArea(child: AppDrawer()), - extendBody: true, - body: PageView( - physics: NeverScrollableScrollPhysics(), - controller: pageController, - children: [ - HomePage( - goToMyProfile: () { - _changeCurrentTab(0); - }, - ), - MedicalProfilePage(), - BookingOptions(), - MyFamily(isAppbarVisible: false), - ToDo(isShowAppBar: false), - ], // Please do not remove the BookingOptions from this array - ), + extendBody: false, + body: WillPopScope( + onWillPop: onWillPop, + child: Stack(children: [ + PageView( + physics: NeverScrollableScrollPhysics(), + controller: pageController, + onPageChanged: (idx) {}, + children: [ + HomePage2( + goToMyProfile: () { + changeCurrentTab(1); + }, + onLoginClick: () { + login(); + }, + onMedicalFileClick: () { + changeCurrentTab(1); + }, + ), + MedicalProfilePageNew( + onTap: () { + changeCurrentTab(0); + }, + ), + Search( + onBackClick: () { + changeCurrentTab(0); + }, + ), + MyFamily( + isAppbarVisible: false, + onBackClick: () { + changeCurrentTab(0); + }, + ), + ToDo( + isShowAppBar: true, + onBackClick: () { + changeCurrentTab(0); + }, + ), + ], // Please do not remove the BookingOptions from this array + ), + RobotIcon() + ])), bottomNavigationBar: BottomNavBar( - changeIndex: _changeCurrentTab, + changeIndex: changeCurrentTab, index: currentTab, ), floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, - floatingActionButton: - (projectViewModel.havePrivilege(34) && currentTab == 0) - ? FloatingButton( - elevation: true, - onTap: () { - _changeCurrentTab(2); - }) - : null); + floatingActionButton: (projectViewModel.havePrivilege(34) && currentTab == 0) + ? FloatingButton( + elevation: true, + onTap: () { + changeCurrentTab(2); + projectViewModel.analytics.appointment.book_appointment(); + }, + ) + : null); } triggerRobot() { - event.setValue({"isRobot": 'true'}); + event.setValue({"isRobotVisible": 'true'}); } getText(currentTab) { @@ -589,26 +646,62 @@ class _LandingPageState extends State with WidgetsBindingObserver { } void checkUserStatus(token) async { - authService - .selectDeviceImei(token) - .then((SelectDeviceIMEIRES value) => setUserValues(value)); - if (projectViewModel.isLoading == true) { - var data = - AuthenticatedUser.fromJson(await sharedPref.getObject(USER_PROFILE)); + await PushNotificationHandler.getInstance().requestPermissions(); + // authService.selectDeviceImei(token).then((SelectDeviceIMEIRES? value) => setUserValues(value)); + if (authenticatedUserObject.isLogin) { + var data = AuthenticatedUser.fromJson(await sharedPref.getObject(USER_PROFILE)); if (data != null) { - authService - .registeredAuthenticatedUser(data, token, 0, 0) - .then((res) => {print(res)}); - authService.getDashboard().then((value) => { - setState(() { - if (value != null) { - notificationCount = value['List_PatientDashboard'][0] - ['UnreadPatientNotificationCount'] - .toString(); - } - }) - }); + authService.registeredAuthenticatedUser(data, token, 0, 0).then((res) => {}); + authService.getDashboard().then((value) async { + setState(() { + if (value != null) { + notificationCount = value['List_PatientDashboard'][0]['UnreadPatientNotificationCount'] > 99 ? '99+' : value['List_PatientDashboard'][0]['UnreadPatientNotificationCount'].toString(); + model.setState(model.count, model.ancillaryCount, true, notificationCount); + sharedPref.setString(NOTIFICATION_COUNT, notificationCount); + // FlutterAppIconBadge.updateBadge(int.parse(notificationCount)); + } + }); + // if (await AppSharedPreferences().getBool(IS_LAST_APPOINTMENT_RATE_SHOWN) == null || !await AppSharedPreferences().getBool(IS_LAST_APPOINTMENT_RATE_SHOWN)) { + // int languageID = Provider.of(context, listen: false).isArabic ? 1 : 2; + // appointmentRateViewModel.getIsLastAppointmentRatedList(languageID).then((value) async { + // if (appointmentRateViewModel.isHaveAppointmentNotRate) { + // await AppSharedPreferences().setBool(IS_LAST_APPOINTMENT_RATE_SHOWN, true); + // Navigator.push( + // context, + // FadePage( + // page: RateAppointmentDoctor(), + // ), + // ); + // } + // }).catchError((err) { + // print(err); + // }); + // } + }); } + projectViewModel.analytics.setUser(data); + } else { + //changed by Aamir + projectViewModel.analytics.setUser(AuthenticatedUser()); } + if (Platform.isIOS) { + String voipToken = await sharedPref.getString(APNS_TOKEN); + // getOneSignalVOIPToken(voipToken); + } + // registerGeofences(); + } + + getOneSignalVOIPToken(String voipToken) { + LiveCareService service = new LiveCareService(); + service.getOneSignalVOIPToken(voipToken, context).then((res) { + print("OneSignalID: $res"); + AppSharedPreferences().setString(ONESIGNAL_APNS_TOKEN, res['id']); + }).catchError((err) { + print(err); + }); + } + + void showUserConsent() { + sharedPref.setString(IS_COVID_CONSENT_SHOWN, "true"); } } diff --git a/lib/pages/landing/landing_page_pharmcy.dart b/lib/pages/landing/landing_page_pharmcy.dart index 04c9bb54..f31cfe41 100644 --- a/lib/pages/landing/landing_page_pharmcy.dart +++ b/lib/pages/landing/landing_page_pharmcy.dart @@ -1,12 +1,13 @@ -import 'package:barcode_scan_fix/barcode_scan.dart'; +import 'package:barcode_scan2/barcode_scan2.dart'; import 'package:diplomaticquarterapp/config/config.dart'; 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/PharmacyPagesViewModel.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/product_detail.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/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'; @@ -14,159 +15,80 @@ 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/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/pharmacy/bottom_nav_pharmacy_bar.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +import '../../locator.dart'; class LandingPagePharmacy extends StatefulWidget { + final int currentTab; + + const LandingPagePharmacy({Key? key, this.currentTab = 0}) : super(key: key); @override _LandingPagePharmacyState createState() => _LandingPagePharmacyState(); } class _LandingPagePharmacyState extends State { + late ProjectViewModel projectProvider; int currentTab = 0; - PageController pageController; - ProjectViewModel projectProvider; + late PageController pageController; - _changeCurrentTab(int tab) { + void initState() { + super.initState(); + locator().manufacturerList = []; + locator().bestSellerProducts = []; + locator().lastVisitedProducts = []; + pageController = + PageController(keepPage: true, initialPage: widget.currentTab); setState(() { - currentTab = tab; - pageController.jumpToPage(tab); + currentTab = widget.currentTab; }); } - void initState() { - super.initState(); - pageController = PageController(keepPage: true); + void changeCurrentTab(int tab) { + if (pageController.hasClients) { + setState(() { + currentTab = tab; + pageController.jumpToPage(tab); + }); + } } @override Widget build(BuildContext context) { - return Scaffold( - appBar: currentTab != 4 - ? AppBar( - backgroundColor: Color(0xff5AB145), - elevation: 0, - title: Container( - height: MediaQuery.of(context).size.height * 0.056, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(5.0), - color: Colors.white, - ), - child: InkWell( - child: Padding( - padding: EdgeInsets.all(8.0), - child: Row( - //crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Icon(Icons.search, size: 25.0), - SizedBox( - width: 15.0, - ), - Texts( - TranslationBase.of(context).searchProductHere, - fontSize: 13, - ) - ], - ), - ), - onTap: () { - Navigator.push( - context, - FadePage(page: SearchProductsPage()), - ); - }, - ), - ), - leading: Builder( - builder: (BuildContext context) { - return InkWell( - onTap: () { - setState(() { - currentTab = 0; - pageController.jumpToPage(0); - }); - }, - child: Container( - height: 2.0, - width: 10.0, - child: Image.asset( - 'assets/images/pharmacy_logo.png', - ), - ), - ); - }, - ), - actions: [ - IconButton( - // iconSize: 70, - icon: Image.asset( - 'assets/images/new-design/qr-code.png', - ), - onPressed: _scanQrAndGetProduct //do something, - ) - ], - centerTitle: true, - ) - : null, - // : AppBar( - // backgroundColor: Color(0xff5AB145), - // elevation: 0, - // textTheme: TextTheme( - // headline6: TextStyle( - // color: Colors.white, fontWeight: FontWeight.bold), - // ), - // title: Text(getText(currentTab).toUpperCase()), - // leading: Builder( - // builder: (BuildContext context) { - // return IconButton( - // icon: Icon(Icons.arrow_back), - // color: Colors.white, - // onPressed: () => Scaffold.of(context).openDrawer(), - // ); - // }, - // ), - // actions: [ - // // IconButton( - // // iconSize: 70, - // // icon: SvgPicture.asset('assets/images/svg/robort_svg.svg', - // // height: 100, width: 100, fit: BoxFit.cover), - // // onPressed: () { - // // triggerRobot(); - // // } //do something, - // // ) - // ], - // centerTitle: true, - // ), - extendBody: false, - body: PageView( - physics: NeverScrollableScrollPhysics(), - controller: pageController, - children: [ - PharmacyPage(), - PharmacyCategorisePage(), -// OffersCategorisePage(), - WishlistPage(false), - PharmacyProfilePage(), -// Container( -// child: Text('text'), -// ), - CartOrderPage(), - ], // Please do not remove the BookingOptions from this array - ), - bottomNavigationBar: BottomNavPharmacyBar( - changeIndex: _changeCurrentTab, - index: currentTab, + return WillPopScope( + onWillPop: () async { + return false; + }, + child: AppScaffold( + isBottomBar: true, + extendBody: false, + isShowDecPage: false, + isMainPharmacyPages: true, + currentTab: currentTab, + changeCurrentTab: changeCurrentTab, + body: PageView( + physics: NeverScrollableScrollPhysics(), + controller: pageController, + children: [ + PharmacyPage(), + PharmacyCategorisePage(), + PharmacyProfilePage(moveToOrder: false, changeTab: (){changeCurrentTab(2);}), + CartOrderPage(changeTab: changeCurrentTab), + ], + ), ), ); } void _scanQrAndGetProduct() async { try { - String result = await BarcodeScanner.scan(); + ScanResult result = await BarcodeScanner.scan(); try { - String barcode = result; + String barcode = result.rawContent; GifLoaderDialogUtils.showMyDialog(context); await BaseAppClient() .getPharmacy("$GET_PHARMACY_PRODUCTs_BY_SKU$barcode", diff --git a/lib/pages/landing/widgets/logged_slider_view.dart b/lib/pages/landing/widgets/logged_slider_view.dart new file mode 100644 index 00000000..98e4b252 --- /dev/null +++ b/lib/pages/landing/widgets/logged_slider_view.dart @@ -0,0 +1,232 @@ +import 'package:diplomaticquarterapp/core/viewModels/dashboard_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/extensions/string_extensions.dart'; +import 'package:diplomaticquarterapp/models/slider_data.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/data_display/text.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +class LoggedSliderView extends StatelessWidget { + ProjectViewModel projectViewModel; + SliderData sliderData; + DashboardViewModel model; + + LoggedSliderView(this.projectViewModel, this.sliderData, this.model); + + @override + Widget build(BuildContext context) { + //'${DateUtil.getMonthDayYearDateFormatted(sliderData.dateofBirthDataTime)} ,${model.user.gender == 1 ? TranslationBase.of(context).male : TranslationBase.of(context).female} ${model.user.age.toString() + "y"}', + return Container( + decoration: cardRadius(20), + + margin: EdgeInsets.all(0), + child: Container( + decoration: cardRadius(20,color: sliderData.darkColor), + clipBehavior: Clip.antiAlias, + margin: EdgeInsets.zero, + + // padding: EdgeInsets.zero, + child: Stack( + children: [ + Card( + child: Container( + width: double.infinity, + height: double.infinity, + ), + color: Colors.transparent, + margin: EdgeInsets.zero, + elevation: 8, + ), + Container( + width: double.infinity, + height: double.infinity, + clipBehavior: Clip.antiAlias, + margin: EdgeInsets.zero, + decoration: projectViewModel.isArabic + ? containerBottomRightRadiusWithGradientForAr(MediaQuery.of(context).size.width / 4, darkColor: sliderData.darkColor, lightColor: sliderData.lightColor) + : containerBottomRightRadiusWithGradient(MediaQuery.of(context).size.width / 4, darkColor: sliderData.darkColor, lightColor: sliderData.lightColor), + child: Card( + color: Colors.transparent, + margin: EdgeInsets.zero, + elevation: 8, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + mFlex(2), + Row( + children: [ + Container( + decoration: projectViewModel.isArabic ? containerColorRadiusLeft(Color(0xFFFBF2E31), 100) : containerColorRadiusRight(Color(0xFFFBF2E31), 100), + padding: EdgeInsets.only(left: 20, right: 16, top: 6, bottom: 6), + child: Text( + TranslationBase.of(context).medicalFile, + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 10, + letterSpacing: -0.3, + height: 1.2, + ), + ), + ), + mWidth(MediaQuery.of(context).size.width / 50), + //circularAviator(MediaQuery.of(context).size.width / 14, brColor: Colors.white), + mFlex(1), + projectViewModel.isArabic ? circularAviator(MediaQuery.of(context).size.width / 28, brColor: Colors.white, icon: Icons.done, bcColor: Colors.white) : Container(), + Text( + TranslationBase.of(context).verified, + style: TextStyle( + color: Colors.white, + fontSize: 10, + letterSpacing: -0.3, + height: 1, + ), + ), + !projectViewModel.isArabic ? circularAviator(MediaQuery.of(context).size.width / 28, brColor: Colors.white, icon: Icons.done, bcColor: Colors.white) : Container(), + mWidth(MediaQuery.of(context).size.width / 70), + ], + ), + mFlex(1), + Padding( + padding: const EdgeInsets.only(left: 20, right: 20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + sliderData.pateintName.toLowerCase().capitalizeFirstofEach, + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 17, + letterSpacing: -0.25, + height: 25 / 17, + ), + ), + mHeight(2), + Text( + sliderData.pateintId, + style: TextStyle( + color: Colors.white, + fontSize: 12, + letterSpacing: -0.36, + height: 1, + ), + ), + ], + ), + ), + mHeight(3), + Padding( + padding: const EdgeInsets.only(left: 20, right: 20), + child: Text( + '${DateUtil.getMonthDayYearDateFormatted(projectViewModel.user.dateofBirthDataTime!)} ,${projectViewModel.user!.gender == 1 ? TranslationBase.of(context).male : TranslationBase.of(context).female} ${projectViewModel.user!.age.toString() + " " + TranslationBase.of(context).patientAge.toString()}', + style: TextStyle( + color: Colors.white, + fontSize: 12, + letterSpacing: -0.33, + height: 1, + ), + ), + ), + mFlex(3), + Padding( + padding: const EdgeInsets.only(left: 20, right: 20), + child: Row( + children: [ + Expanded( + flex: 3, + child: Row( + children: [ + SvgPicture.asset( + 'assets/images/new/height.svg', + width: 11, + height: 11, + ), + mWidth(6), + Texts( + "${TranslationBase.of(context).height}: ${model.heightCm} ${TranslationBase.of(context).cm}", + color: Colors.white, + fontSize: 8, + ) + ], + ), + ), + SizedBox( + width: 3, + ), + Expanded( + flex: 3, + child: Row( + children: [ + SvgPicture.asset( + 'assets/images/new/weight.svg', + width: 11, + height: 11, + ), + mWidth(6), + Texts( + '${TranslationBase.of(context).weight}: ${model.weightKg} ${TranslationBase.of(context).kg}', + color: Colors.white, + fontSize: 8, + ) + ], + ), + ), + SizedBox( + width: 3, + ), + Expanded( + flex: 3, + child: Row( + children: [ + SvgPicture.asset( + 'assets/images/new/blood.svg', + width: 11, + height: 11, + ), + mWidth(6), + Texts( + '${TranslationBase.of(context).bloodType1} ${model.booldType}', + color: Colors.white, + fontSize: 7, + ) + ], + ), + ), + mFlex(1), + ], + ), + ), + mFlex(2), + ], + ), + ), + ), + projectViewModel.isArabic + ? Positioned( + child: Icon( + Icons.arrow_forward, + color: Colors.white, + size: 20, + ), + bottom: 8, + left: 8, + ) + : Positioned( + child: Icon( + Icons.arrow_forward_rounded, + color: Colors.white, + size: 20, + ), + bottom: 8, + right: 8, + ), + ], + ), + ), + ); + } +} diff --git a/lib/pages/landing/widgets/offer_view.dart b/lib/pages/landing/widgets/offer_view.dart new file mode 100644 index 00000000..82afbc4a --- /dev/null +++ b/lib/pages/landing/widgets/offer_view.dart @@ -0,0 +1,87 @@ +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:flutter/material.dart'; + +class OfferView extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Container( + width: double.infinity, + height: MediaQuery.of(context).size.width / 5, + decoration: containerColorRadiusBorderWidth(Colors.grey[200]!, 20, Colors.grey[300]!, 2), + child: Row( + children: [ + Expanded( + flex: 2, + child: Container( + width: double.infinity, + padding: EdgeInsets.only(left: 20,right: 20,top: 8,bottom: 8), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Kid's Offer", + style: TextStyle( + color: Color(0xFFFBF2E31), + fontSize: 18, + fontWeight: FontWeight.bold, + ), + ), + Text( + "Take Care of your children's teeth", + style: TextStyle( + color: Colors.black, + fontSize: 12, + fontWeight: FontWeight.bold, + ), + ), + mFlex(1), + Row( + children: [ + Text( + "Only ", + style: TextStyle( + color: Color(0xFFFBF2E31), + fontSize: 14, + ), + ), + Text( + "500 ", + style: TextStyle( + color: Color(0xFFFBF2E31), + fontSize: 14, + fontWeight: FontWeight.bold, + ), + ), + Text( + "SAR ", + style: TextStyle( + color: Color(0xFFFBF2E31), + fontSize: 14, + ), + ), + mFlex(1), + ], + ), + ], + ), + ), + ), + Expanded( + child: Column( + children: [ + Expanded( + flex: 1, + child: Image.asset("assets/images/pharmacy_module/payment/hmg_shipping_logo.png"), + ), + Expanded( + flex: 1, + child: Image.asset("name"), + ), + ], + ), + ), + ], + ), + ); + } +} diff --git a/lib/pages/landing/widgets/pharmacy_view.dart b/lib/pages/landing/widgets/pharmacy_view.dart new file mode 100644 index 00000000..288eb20c --- /dev/null +++ b/lib/pages/landing/widgets/pharmacy_view.dart @@ -0,0 +1,65 @@ +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +class PharmacyView extends StatelessWidget { + Function onPharmacyClick; + PharmacyView({required this.onPharmacyClick}); + @override + Widget build(BuildContext context) { + return InkWell( + onTap: (){ + onPharmacyClick(); + }, + child: Container( + width: double.infinity, + decoration: + containerBottomRightRadiusWithGradientBorder(16, darkColor: CustomColors.darkGreyColor.withOpacity(0.5), lightColor: CustomColors.lightGreyColor, borderColor: Color(0xFFcccccc), w: 1), + padding: EdgeInsets.only(left: 12, right: 12, top: 12, bottom: 12), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SvgPicture.asset("assets/images/new/Pharmacy.svg"), + mWidth(12), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + TranslationBase.of(context).HMGPharmacy, + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 16, + ), + ), + Text( + TranslationBase.of(context).ecommerceSolution, + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 14, + ), + ), + ], + ), + ), + mWidth(12), + Opacity( + opacity: 0.2, + child: SvgPicture.asset("assets/images/new/Pharmacy.svg"), + ), + ], + ), + ), + ); + } + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties.add(DiagnosticsProperty('onPharmacyClick', onPharmacyClick)); + } +} diff --git a/lib/pages/landing/widgets/services_view.dart b/lib/pages/landing/widgets/services_view.dart new file mode 100644 index 00000000..fa0134bc --- /dev/null +++ b/lib/pages/landing/widgets/services_view.dart @@ -0,0 +1,510 @@ +import 'dart:io'; + +import 'package:auto_size_text/auto_size_text.dart'; +import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; +import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/config/size_config.dart'; +import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; +import 'package:diplomaticquarterapp/models/hmg_services.dart'; +import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/%E2%80%8B%20health_calculators.dart'; +import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_page.dart'; +import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/E-Referral/e_referral_page.dart'; +import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/HomeHealthCare/home_health_care_page.dart'; +import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/h2o/h2o_page.dart'; +import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/health_converter.dart'; +import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/my_web_view.dart'; +import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/parking_page.dart'; +import 'package:diplomaticquarterapp/pages/Blood/blood_donation.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/Search.dart'; +import 'package:diplomaticquarterapp/pages/ChildVaccines/new/child_initial_page.dart'; +import 'package:diplomaticquarterapp/pages/ContactUs/contact_us_page.dart'; +import 'package:diplomaticquarterapp/pages/Covid-DriveThru/covid-drivethru-location.dart'; +import 'package:diplomaticquarterapp/pages/DrawerPages/family/my-family.dart'; +import 'package:diplomaticquarterapp/pages/ErService/EROnlineCheckIn/EROnlineCheckInHome.dart'; +import 'package:diplomaticquarterapp/pages/ErService/ErOptions.dart'; +import 'package:diplomaticquarterapp/pages/InPatientServices/inpatient_home.dart'; +import 'package:diplomaticquarterapp/pages/insurance/insurance_update_screen.dart'; +import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; +import 'package:diplomaticquarterapp/pages/livecare/livecare_home.dart'; +import 'package:diplomaticquarterapp/pages/medical/medical_profile_page_new.dart'; +import 'package:diplomaticquarterapp/pages/medical/smart_watch_health_data/smart_watch_instructions.dart'; +import 'package:diplomaticquarterapp/pages/paymentService/payment_service.dart'; +import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/app-permissions.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/location_util.dart'; +import 'package:diplomaticquarterapp/uitl/penguin_method_channel.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/covid_consent_dialog.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/location_selection_dialog.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:permission_handler/permission_handler.dart'; +import 'package:url_launcher/url_launcher.dart'; + +import '../../../locator.dart'; +import '../landing_page_pharmcy.dart'; + +class ServicesView extends StatelessWidget { + HmgServices hmgServices; + int index; + AuthenticatedUser authUser = new AuthenticatedUser(); + AuthProvider authProvider = new AuthProvider(); + PharmacyModuleViewModel pharmacyModuleViewModel = locator(); + late LocationUtils locationUtils; + bool isHomePage; + late ProjectViewModel projectViewModel; + bool isLocked; + + ServicesView(this.hmgServices, this.index, this.isHomePage, this.projectViewModel, {this.isLocked = false}); + + @override + Widget build(BuildContext context) { + return InkWell( + onTap: () { + if (isHomePage) { + handleHomePageServices(hmgServices, context); + } else { + handleAllServices(hmgServices, context); + } + }, + child: Container( + width: double.infinity, + height: double.infinity, + decoration: containerRadiusWithGradientServices(20, lightColor: CustomColors.lightGreyColor, darkColor: CustomColors.darkGreyColor), + child: Stack( + children: [ + Container( + width: double.infinity, + height: double.infinity, + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + mFlex(1), + Flexible( + flex: 8, + child: Column( + children: [ + Flexible( + flex: 5, + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Opacity( + opacity: 0.04, + child: hmgServices.action == 5 + ? Image.asset( + hmgServices.icon, + width: double.infinity, + height: double.infinity, + ) + : SvgPicture.asset( + hmgServices.icon, + width: double.infinity, + height: double.infinity, + ), + ), + ), + ), + mFlex(1), + ], + ), + ), + ], + ), + ), + Container( + width: double.infinity, + height: double.infinity, + padding: EdgeInsets.only(left: SizeConfig.widthMultiplier! * 3, right: SizeConfig.widthMultiplier! * 3, top: SizeConfig.widthMultiplier! * 3, bottom: SizeConfig.widthMultiplier! * 2), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + mFlex(1), + hmgServices.action == (isHomePage ? 5 : 8) + ? Image.asset( + hmgServices.icon, + height: index == 0 ? MediaQuery.of(context).size.width / 18 : MediaQuery.of(context).size.width / 18, + ) + : Container( + // color: Colors.yellow, + width: index == 4 ? MediaQuery.of(context).size.width / 12 : MediaQuery.of(context).size.width / 12, + height: index == 4 ? MediaQuery.of(context).size.width / 10 : MediaQuery.of(context).size.width / 12, + child: SvgPicture.asset( + hmgServices.icon, +// width: MediaQuery.of(context).size.width / 12, + // height: MediaQuery.of(context).size.width / 12, + ), + ), + mFlex(4), + AutoSizeText( + hmgServices.title, + maxLines: 1, + minFontSize: 10, + style: TextStyle( + fontSize: SizeConfig.textMultiplier! * 1.6, + fontWeight: FontWeight.bold, + letterSpacing: -0.39, + height: 0.8, + ), + ), + AutoSizeText( + hmgServices.subTitle, + maxLines: 1, + minFontSize: 8, + style: TextStyle( + fontSize: SizeConfig.textMultiplier! * 1.4, + letterSpacing: -0.27, + fontWeight: FontWeight.w600, + ), + ), + mFlex(1), + ], + ), + ), + isLocked + ? Container( + width: double.infinity, + height: double.infinity, + decoration: containerRadiusWithGradientServices(20, lightColor: Colors.grey.withOpacity(0.6), darkColor: Colors.grey.withOpacity(0.6)), + child: Icon( + Icons.lock_outline, + size: 40, + ), + ) + : Container() + ], + ), + ), + ); + } + + openNavigationProjectSelection(BuildContext context) { + int _selectedHospitalIndex = 0; + List projectsListLocal = []; + Utils.navigationProjectsList.forEach((v) { + projectsListLocal.add(new HospitalsModel.fromJson(v)); + }); + showDialog( + context: context, + builder: (cxt) => LocationSelectionDialog( + isArabic: projectViewModel.isArabic, + data: projectsListLocal, + selectedIndex: _selectedHospitalIndex, + onValueSelected: (index) { + _selectedHospitalIndex = index; + initPenguinSDK(projectsListLocal[index].iD); + }, + ), + ); + } + + initPenguinSDK(int projectID) async { + final bool permited = await AppPermission.askPenguinPermissions(); + if (!permited) { + Map statuses = await [ + Permission.location, + Permission.bluetooth, + Permission.bluetoothConnect, + Permission.bluetoothScan, + Permission.activityRecognition, + ].request().whenComplete(() { + PenguinMethodChannel().launch("penguin", projectViewModel.isArabic ? "ar" : "en", projectViewModel.authenticatedUserObject.user.patientID.toString()); + }); + } + } + + handleHomePageServices(HmgServices hmgServices, BuildContext context) { + if (hmgServices.action == 0) { + Navigator.push(context, FadePage(page: Search())); + locator().hmgServices.logServiceName('book appointment'); + } else if (hmgServices.action == 1) { + openLiveCare(context); + } else if (hmgServices.action == 2) { + //todo for temporary basis + // Navigator.push(context, FadePage(page: VitalSigns())); + + // initPenguinSDK(); + if (projectViewModel.isIndoorNavigationEnabled) { + if (!isLocked) openNavigationProjectSelection(context); + } else { + Navigator.push(context, FadePage(page: ErOptions(isAppbar: true))); + locator().hmgServices.logServiceName('emergency service'); + } + } else if (hmgServices.action == 3) { + Navigator.push(context, FadePage(page: HomeHealthCarePage())); + locator().hmgServices.logServiceName('home health care'); + } else if (hmgServices.action == 4) { + Navigator.push(context, FadePage(page: CMCPage())); + locator().hmgServices.logServiceName('comprehensive medical checkup'); + } else if (hmgServices.action == 5) { + Navigator.push(context, FadePage(page: PaymentService())); + locator().hmgServices.logServiceName('online payments'); + } else if (hmgServices.action == 6) { + Navigator.push(context, FadePage(page: EReferralPage())); + locator().hmgServices.logServiceName('e-referral service'); + } else if (hmgServices.action == 7) { + showCovidDialog(context); + locator().hmgServices.logServiceName('covid-test drive-thru'); + } else if (hmgServices.action == 8) { + Navigator.push(context, FadePage(page: ContactUsPage())); + locator().hmgServices.logServiceName('find us reach us'); + } else if (hmgServices.action == 23) { + Navigator.push(context, FadePage(page: InPatientServicesHome())); + locator().hmgServices.logServiceName('find us reach us'); + } else if (hmgServices.action == 9) { + if (!isLocked) Navigator.push(context, FadePage(page: EROnlineCheckInHomePage())); + locator().hmgServices.logServiceName('ER Online CheckIn'); + } + } + + handleAllServices(HmgServices hmgServices, BuildContext context) { + if (hmgServices.action == 0) { + Navigator.push(context, FadePage(page: Search())); + locator().hmgServices.logServiceName('book appointment'); + } else if (hmgServices.action == 1) { + openLiveCare(context); + } else if (hmgServices.action == 2) { + Navigator.push(context, FadePage(page: ErOptions(isAppbar: true))); + locator().hmgServices.logServiceName('emergency service'); + } else if (hmgServices.action == 3) { + Navigator.push(context, FadePage(page: HomeHealthCarePage())); + locator().hmgServices.logServiceName('home health care'); + } else if (hmgServices.action == 4) { + Navigator.push(context, FadePage(page: CMCPage())); + locator().hmgServices.logServiceName('comprehensive medical checkup'); + } else if (hmgServices.action == 5) { + // getPharmacyToken(context); + Uri uri = Uri.parse(PHARMACY_REDIRECT_URL); + launchUrl(uri, mode: LaunchMode.externalApplication); + locator().hmgServices.logServiceName('al habib pharmacy'); + } else if (hmgServices.action == 6) { + Navigator.push(context, FadePage(page: MedicalProfilePageNew())); + } else if (hmgServices.action == 7) { + Navigator.push(context, FadePage(page: MyFamily())); + locator().hmgServices.logServiceName('my family files'); + } else if (hmgServices.action == 8) { + Navigator.push(context, FadePage(page: PaymentService())); + locator().hmgServices.logServiceName('online payments'); + } else if (hmgServices.action == 9) { + Navigator.push(context, FadePage(page: ChildInitialPage())); + locator().hmgServices.logServiceName('my child vaccines'); + } else if (hmgServices.action == 10) { + Navigator.push(context, FadePage(page: InsuranceUpdate())); + locator().hmgServices.logServiceName('update insurance'); + } else if (hmgServices.action == 11) { + Navigator.push(context, FadePage(page: EReferralPage())); + locator().hmgServices.logServiceName('e-referral service'); + } else if (hmgServices.action == 12) { + Navigator.push(context, FadePage(page: H2OPage())); + locator().hmgServices.logServiceName('water consumption'); + } else if (hmgServices.action == 13) { + Navigator.push(context, FadePage(page: (HealthCalculators()))); + locator().hmgServices.logServiceName('health calculator'); + } else if (hmgServices.action == 14) { + Navigator.push(context, FadePage(page: HealthConverter())); + locator().hmgServices.logServiceName('heath converters'); + } else if (hmgServices.action == 15) { + Navigator.pop(context); + LandingPage.shared.switchToDoFromHMGServices(); + locator().hmgServices.logServiceName('todo list'); + } else if (hmgServices.action == 16) { + Navigator.push(context, FadePage(page: BloodDonationPage())); + locator().hmgServices.logServiceName('blood donation'); + } else if (hmgServices.action == 17) { + showCovidDialog(context); + locator().hmgServices.logServiceName('covid-test drive-thru'); + } else if (hmgServices.action == 18) { + launch("https://hmgwebservices.com/vt_mobile/html/index.html"); + locator().hmgServices.logServiceName('virtual tour'); + } else if (hmgServices.action == 19) { + Navigator.push(context, FadePage(page: SmartWatchInstructions())); + locator().hmgServices.logServiceName('smart watches'); + } else if (hmgServices.action == 20) { + Navigator.push(context, FadePage(page: ParkingPage())); + locator().hmgServices.logServiceName('car parcking service'); + } else if (hmgServices.action == 21) { + Navigator.of(context).push( + MaterialPageRoute( + builder: (BuildContext context) => MyWebView(title: "HMG News", selectedUrl: "https://twitter.com/hmg" //"https://twitter.com/hashtag/مجموعة_د_سليمان_الحبيب_الطبية?src=hashtag_click&f=live", + ), + ), + ); + locator().hmgServices.logServiceName('latest news'); + } else if (hmgServices.action == 22) { + Navigator.push(context, FadePage(page: ContactUsPage())); + locator().hmgServices.logServiceName('find us reach us'); + } + + // if (hmgServices.action == 10) { + // openLiveCare(context); + // } else if (index == 1) { + // showCovidDialog(context); + // locator().hmgServices.logServiceName('covid-test drive-thru'); + // } else if (index == 2) { + // Navigator.push(context, FadePage(page: PaymentService())); + // locator().hmgServices.logServiceName('online payments'); + // } else if (index == 3) { + // Navigator.push(context, FadePage(page: HomeHealthCarePage())); + // locator().hmgServices.logServiceName('home health care'); + // } else if (index == 4) { + // Navigator.push(context, FadePage(page: CMCPage())); + // locator().hmgServices.logServiceName('comprehensive medical checkup'); + // } else if (index == 5) { + // Navigator.push(context, FadePage(page: ErOptions(isAppbar: true))); + // locator().hmgServices.logServiceName('emergency service'); + // } else if (index == 6) { + // Navigator.push(context, FadePage(page: EReferralPage())); + // locator().hmgServices.logServiceName('e-referral service'); + // } else if (index == 7) { + // Navigator.push(context, FadePage(page: H2OPage())); + // locator().hmgServices.logServiceName('water consumption'); + // } else if (index == 8) { + // Navigator.push(context, FadePage(page: ContactUsPage())); + // locator().hmgServices.logServiceName('find us reach us'); + // } else if (index == 9) { + // Navigator.push( + // context, + // FadePage( + // page: MedicalProfilePageNew(), + // ), + // ); + // locator().hmgServices.logServiceName('my medical details'); + // } else if (index == 10) { + // Navigator.push( + // context, + // FadePage( + // page: Search(), + // ), + // ); + // locator().hmgServices.logServiceName('book appointment'); + // } else if (index == 11) { + // getPharmacyToken(context); + // locator().hmgServices.logServiceName('al habib pharmacy'); + // } else if (index == 12) { + // Navigator.push( + // context, + // FadePage( + // page: InsuranceUpdate(), + // ), + // ); + // locator().hmgServices.logServiceName('update insurance'); + // } else if (index == 13) { + // Navigator.push( + // context, + // FadePage( + // page: MyFamily(), + // ), + // ); + // locator().hmgServices.logServiceName('my family files'); + // } else if (index == 14) { + // Navigator.push( + // context, + // FadePage(page: ChildInitialPage()), + // ); + // locator().hmgServices.logServiceName('my child vaccines'); + // } else if (index == 15) { + // LandingPage.shared.switchToDoFromHMGServices(); + // locator().hmgServices.logServiceName('todo list'); + // } else if (index == 16) { + // Navigator.push( + // context, + // FadePage(page: BloodDonationPage()), + // ); + // locator().hmgServices.logServiceName('blood donation'); + // } else if (index == 17) { + // Navigator.push( + // context, + // FadePage( + // page: (HealthCalculators()), + // ), + // ); + // locator().hmgServices.logServiceName('health calculator'); + // } else if (index == 18) { + // Navigator.push( + // context, + // FadePage( + // page: HealthConverter(), + // ), + // ); + // locator().hmgServices.logServiceName('heath converters'); + // } else if (index == 19) { + // Navigator.push( + // context, + // FadePage(page: SmartWatchInstructions()), + // ); + // locator().hmgServices.logServiceName('smart watches'); + // } else if (index == 20) { + // locator().hmgServices.logServiceName('car parcking service'); + // Navigator.push( + // context, + // FadePage( + // page: ParkingPage(), + // ), + // ); + // } else if (index == 21) { + // launch("https://hmgwebservices.com/vt_mobile/html/index.html"); + // locator().hmgServices.logServiceName('virtual tour'); + // } else if (index == 22) { + // Navigator.of(context).push( + // MaterialPageRoute( + // builder: (BuildContext context) => MyWebView( + // title: "HMG News", + // selectedUrl: "https://twitter.com/hashtag/مجموعة_د_سليمان_الحبيب_الطبية?src=hashtag_click&f=live", + // ), + // ), + // ); + // locator().hmgServices.logServiceName('latest news'); + // } + } + + showCovidDialog(BuildContext context) { + if (Platform.isAndroid) { + showDialog( + context: context, + builder: (cxt) => CovidConsentDialog( + okTitle: TranslationBase.of(context).acceptLbl, + title: TranslationBase.of(context).covidConsentHeader, + message: TranslationBase.of(context).covidConsent, + onTap: () async { + Navigator.push(context, FadePage(page: CovidDrivethruLocation())); + }, + )); + } else { + Navigator.push(context, FadePage(page: CovidDrivethruLocation())); + } + } + + openLiveCare(BuildContext context) { + locator().hmgServices.logServiceName('live care service'); + Navigator.push(context, FadePage(page: LiveCareHome())).then((value) { + LiveCareHome.isLiveCareTypeSelected = false; + }); + } + + getPharmacyToken(BuildContext context) async { + if (!authProvider.isLogin) { + Navigator.push(context, FadePage(page: LandingPagePharmacy())); + } else { + GifLoaderDialogUtils.showMyDialog(context); + await pharmacyModuleViewModel.generatePharmacyToken().then((value) async { + if (pharmacyModuleViewModel.error.isNotEmpty) { + await pharmacyModuleViewModel.createUser().then((value) { + GifLoaderDialogUtils.hideDialog(context); + Navigator.push(context, FadePage(page: LandingPagePharmacy())); + }); + } else { + GifLoaderDialogUtils.hideDialog(context); + Navigator.push(context, FadePage(page: LandingPagePharmacy())); + } + }); + } + } +} diff --git a/lib/pages/landing/widgets/slider_view.dart b/lib/pages/landing/widgets/slider_view.dart new file mode 100644 index 00000000..286706aa --- /dev/null +++ b/lib/pages/landing/widgets/slider_view.dart @@ -0,0 +1,165 @@ +import 'dart:math'; + +import 'package:auto_size_text/auto_size_text.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/buttons/custom_text_button.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class SliderView extends StatefulWidget { + VoidCallback onLoginClick; + + SliderView({required this.onLoginClick}); + + @override + State createState() => _SliderViewState(); +} + +class _SliderViewState extends State { + late ProjectViewModel projectViewModel; + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + return Container( + decoration: cardRadius(20), + margin: EdgeInsets.all(0), + child: Container( + decoration: cardRadius(20, color: Color(0xFFF2B353E)), + clipBehavior: Clip.antiAlias, + margin: EdgeInsets.zero, + + // padding: EdgeInsets.zero, + child: Container( + width: double.infinity, + height: double.infinity, + clipBehavior: Clip.antiAlias, + margin: EdgeInsets.zero, + decoration: projectViewModel.isArabic + ? containerBottomRightRadiusWithGradientForAr(MediaQuery.of(context).size.width / 4) + : containerBottomRightRadiusWithGradient(MediaQuery.of(context).size.width / 4), + child: Card( + color: Colors.transparent, + margin: EdgeInsets.zero, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + mFlex(3), + Container( + decoration: projectViewModel.isArabic ? containerColorRadiusLeft(Color(0xFFFBF2E31), 100) : containerColorRadiusRight(Color(0xFFFBF2E31), 100), + padding: EdgeInsets.only(left: projectViewModel.isArabic ? 16 : 20, right: projectViewModel.isArabic ? 20 : 16, top: 6, bottom: 6), + child: Text( + TranslationBase.of(context).medicalFile, + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 10, + letterSpacing: -0.3, + height: 1.2, + ), + ), + ), + mFlex(2), + Padding( + padding: const EdgeInsets.only(left: 20, right: 20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).cantSeeProfile, + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 17, + letterSpacing: -0.25, + height: 25 / 17, + ), + ), + // Text( + // TranslationBase.of(context).loginRegisterNow, + // style: TextStyle( + // color: Colors.white, + // fontSize: 12, + // letterSpacing: -0.36, + // height: 1, + // ), + // ), + ], + ), + ), + mFlex(2), + Padding( + padding: const EdgeInsets.only(left: 20, right: 20), + child: Container( + height: MediaQuery.of(context).size.width / 14, + width: MediaQuery.of(context).size.width / (projectViewModel.isArabic ? 4 : 6), + child: CustomTextButton( + shape: cardRadiusNew(8), + //shape: OutlinedBorder(), + backgroundColor: Color(0xFFFBF2E31), + elevation: 0, + onPressed: () { + + widget.onLoginClick(); + }, + child: Center( + child: AutoSizeText( + TranslationBase.of(context).login, + maxLines: 1, + style: TextStyle( + color: Colors.white, + fontSize: 13, + letterSpacing: -0.39, + height: 1, + ), + ), + ), + ), + ), + ), + mFlex(3), + ], + ), + ), + ), + ), + ); + } +} + +class CurvedBottomClipper extends CustomClipper { + @override + Path getClip(Size size) { + // I've taken approximate height of curved part of view + // Change it if you have exact spec for it + final roundingHeight = size.height * 3 / 5; + + // this is top part of path, rectangle without any rounding + final filledRectangle = Rect.fromLTRB(0, 0, size.width, size.height - roundingHeight); + + // this is rectangle that will be used to draw arc + // arc is drawn from center of this rectangle, so it's height has to be twice roundingHeight + // also I made it to go 5 units out of screen on left and right, so curve will have some incline there + final roundingRectangle = Rect.fromLTRB(-size.width, size.height - roundingHeight * 2, size.width, size.height); + + final path = Path(); + path.addRect(filledRectangle); + + // so as I wrote before: arc is drawn from center of roundingRectangle + // 2nd and 3rd arguments are angles from center to arc start and end points + // 4th argument is set to true to move path to rectangle center, so we don't have to move it manually + path.arcTo(roundingRectangle, pi, -pi, true); + path.close(); + + return path; + } + + @override + bool shouldReclip(CustomClipper oldClipper) { + // returning fixed 'true' value here for simplicity, it's not the part of actual question, please read docs if you want to dig into it + // basically that means that clipping will be redrawn on any changes + return true; + } +} diff --git a/lib/pages/livecare/clinic_timings_page.dart b/lib/pages/livecare/clinic_timings_page.dart new file mode 100644 index 00000000..781dfbe3 --- /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 { + late 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: 2, + child: Text( + item.dayOfWeekStr!, + style: TextStyle( + fontSize: 18, + letterSpacing: -0.72, + fontWeight: FontWeight.bold, + ), + ), + ), + Expanded( + flex: 4, + 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/incoming_call.dart b/lib/pages/livecare/incoming_call.dart index de80b4ae..c7b574f0 100644 --- a/lib/pages/livecare/incoming_call.dart +++ b/lib/pages/livecare/incoming_call.dart @@ -1,37 +1,48 @@ +import 'dart:ui'; + +import 'package:camera/camera.dart'; import 'package:diplomaticquarterapp/models/LiveCare/IncomingCallData.dart'; -import 'package:diplomaticquarterapp/models/LiveCare/room_model.dart'; -import 'package:diplomaticquarterapp/pages/conference/conference_page.dart'; import 'package:diplomaticquarterapp/pages/conference/widgets/platform_exception_alert_dialog.dart'; +import 'package:diplomaticquarterapp/pages/conference/zoom/call_screen.dart'; +import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; +import 'package:diplomaticquarterapp/pages/videocall-webrtc-rnd/webrtc/start_video_call.dart'; +import 'package:diplomaticquarterapp/pages/webRTC/OpenTok/OpenTok.dart'; +import 'package:diplomaticquarterapp/pages/webRTC/signaling.dart'; +import 'package:diplomaticquarterapp/services/livecare_services/livecare_provider.dart'; +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:just_audio/just_audio.dart'; +import '../../config/config.dart'; + class IncomingCall extends StatefulWidget { - IncomingCallData incomingCallData; + IncomingCallData? incomingCallData; - IncomingCall({@required this.incomingCallData}); + IncomingCall({this.incomingCallData}); @override _IncomingCallState createState() => _IncomingCallState(); } -class _IncomingCallState extends State - with SingleTickerProviderStateMixin { - AnimationController _animationController; +class _IncomingCallState extends State with SingleTickerProviderStateMixin { + late AnimationController _animationController; + bool openCallInWeb = true; final player = AudioPlayer(); + late CameraController _controller; + late Future _initializeControllerFuture; + bool isCameraReady = false; + + // Signaling signaling = Signaling()..init(); @override void initState() { - _animationController = - AnimationController(vsync: this, duration: Duration(milliseconds: 500)); + _animationController = AnimationController(vsync: this, duration: Duration(milliseconds: 500)); + isCameraReady = false; WidgetsBinding.instance.addPostFrameCallback((_) => _runAnimation()); - - print(widget.incomingCallData.doctorname); - print(widget.incomingCallData.clinicname); - print(widget.incomingCallData.speciality); - super.initState(); } @@ -39,6 +50,7 @@ class _IncomingCallState extends State void dispose() { _animationController.dispose(); player.stop(); + // _controller.dispose(); disposeAudioResources(); super.dispose(); } @@ -47,157 +59,147 @@ class _IncomingCallState extends State Widget build(BuildContext context) { return AppScaffold( isShowAppBar: false, - body: SafeArea( - child: Container( - decoration: BoxDecoration(color: Colors.grey[700]), - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - children: [ - Container( - margin: EdgeInsets.only(top: 30.0), - alignment: Alignment.center, - child: Text("Incoming Video Call", - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 26.0, - color: Colors.white, - letterSpacing: 1.0)), - ), - Container( - alignment: Alignment.center, - margin: EdgeInsets.fromLTRB(50.0, 30.0, 50.0, 20.0), - child: Image.asset( - 'assets/images/new-design/hmg_full_logo_hd_white.png'), - ), - Container( - margin: EdgeInsets.fromLTRB(30.0, 10.0, 30.0, 0.0), - child: Divider( - color: Colors.white, - thickness: 1.0, - ), - ), - Container( - margin: EdgeInsets.only(top: 20.0), - alignment: Alignment.center, - child: Text("Dr Eyad Ismail Abu Jayab", - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 22.0, - fontWeight: FontWeight.bold, - letterSpacing: 0.8, - color: Colors.white)), - ), - Container( - margin: EdgeInsets.only(top: 10.0), - alignment: Alignment.center, - child: Text("ENT Clinic", - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 22.0, - letterSpacing: 0.8, - color: Colors.white)), - ), - Container( - margin: EdgeInsets.only(top: 10.0), - alignment: Alignment.center, - child: Text("Speciality", - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 22.0, - letterSpacing: 0.8, - color: Colors.white)), - ), - Container( - decoration: BoxDecoration( - color: Colors.grey[900].withOpacity(0.8), - borderRadius: BorderRadius.all(Radius.circular(10.0)), + isShowDecPage: false, + body: Stack(alignment: FractionalOffset.center, children: [ + // new Positioned.fill( + // child: new AspectRatio(aspectRatio: _controller.value.aspectRatio, child: new CameraPreview(_controller)), + // ), + new Positioned.fill( + child: new ClipRect( + // child: new BackdropFilter( + // filter: new ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0), + child: new Container( + decoration: new BoxDecoration(color: Colors.grey[800]!.withOpacity(0.8)), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.max, + children: [ + Container( + margin: const EdgeInsets.all(21.0), + child: Row( + children: [ + Image.asset( + "assets/images/new/logo.png", + height: 70, + width: 70, + ), + Container( + margin: const EdgeInsets.only(left: 10.0, right: 10.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Text( + widget.incomingCallData!.doctorname!, + style: TextStyle(fontSize: 21, fontWeight: FontWeight.bold, color: Colors.white, letterSpacing: -1.26, height: 23 / 12), + ), + Text( + TranslationBase.of(context).videoAppo, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xffC6C6C6), letterSpacing: -0.48, height: 23 / 24), + ), + SizedBox(height: 2), + ], + ), + ), + ], + ), ), - padding: EdgeInsets.all(20.0), - margin: EdgeInsets.only(top: 20.0), - child: Column( - children: [ - Text("Appointment Information", - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 20.0, - fontWeight: FontWeight.bold, - letterSpacing: 1.0, - color: Colors.white)), - Container( - margin: EdgeInsets.only(top: 20.0), - child: Text("Sun, 15th Dec, 2019, 09:00", - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 20.0, - letterSpacing: 1.0, - color: Colors.white)), - ), - Container( - margin: EdgeInsets.only(top: 20.0), - child: Text("ENT Clinic", - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 20.0, - letterSpacing: 1.0, - color: Colors.white)), - ), - ], + Container( + margin: const EdgeInsets.all(21.0), + width: MediaQuery.of(context).size.width, + decoration: cardRadius(15.0, color: Colors.black), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Container( + padding: const EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 6.0), + child: Text( + TranslationBase.of(context).appoInfo, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Colors.white, letterSpacing: -0.64, height: 23 / 12), + ), + ), + Container( + padding: const EdgeInsets.only(left: 16.0, right: 16.0), + child: Text( + widget.incomingCallData!.appointmentdate! + ", " + widget.incomingCallData!.appointmenttime!, + style: TextStyle(fontSize: 12.0, letterSpacing: -0.48, color: Color(0xff8E8E8E), fontWeight: FontWeight.w600), + ), + ), + Container( + padding: const EdgeInsets.only(left: 16.0, right: 16.0, bottom: 21.0), + child: Text( + widget.incomingCallData!.clinicname!, + style: TextStyle(fontSize: 12.0, letterSpacing: -0.48, color: Color(0xff8E8E8E), fontWeight: FontWeight.w600), + ), + ), + ], + ), ), - ), - Container( - margin: EdgeInsets.only(top: 100.0), - alignment: Alignment.center, - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - RotationTransition( - turns: Tween(begin: 0.0, end: -.1) - .chain(CurveTween(curve: Curves.elasticIn)) - .animate(_animationController), - child: Container( - child: RawMaterialButton( - onPressed: () { - _submit(); - }, - elevation: 2.0, - fillColor: Colors.green, - child: Icon( - Icons.call, - color: Colors.white, - size: 35.0, + Spacer(), + Container( + margin: EdgeInsets.only(bottom: 70.0, left: 49, right: 49), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + RotationTransition( + turns: Tween(begin: 0.0, end: -.1).chain(CurveTween(curve: Curves.elasticIn)).animate(_animationController), + child: Container( + child: RawMaterialButton( + onPressed: () { + _submit(); + }, + elevation: 2.0, + fillColor: Colors.green, + child: Icon( + Icons.call, + color: Colors.white, + size: 35.0, + ), + padding: EdgeInsets.all(15.0), + shape: CircleBorder(), ), - padding: EdgeInsets.all(15.0), - shape: CircleBorder(), + )), + Container( + child: RawMaterialButton( + onPressed: () { + backToHome(); + }, + elevation: 2.0, + fillColor: Colors.red, + child: Icon( + Icons.call_end, + color: Colors.white, + size: 35.0, ), - )), - Container( - child: RawMaterialButton( - onPressed: () { - backToHome(); - }, - elevation: 2.0, - fillColor: Colors.red, - child: Icon( - Icons.call_end, - color: Colors.white, - size: 35.0, + padding: EdgeInsets.all(15.0), + shape: CircleBorder(), ), - padding: EdgeInsets.all(15.0), - shape: CircleBorder(), ), - ), - ], + ], + ), ), - ), - ], - )), - ), + ], + ), + ), + ), + ), + // ), + ] + // } else { + // return const Center(child: CircularProgressIndicator()); + // } + ), ); } void _runAnimation() async { + setState(() { + isCameraReady = true; + }); + setAudioFile(); for (int i = 0; i < 100; i++) { await _animationController.forward(); @@ -206,31 +208,60 @@ class _IncomingCallState extends State } Future _submit() async { - backToHome(); try { - final roomModel = RoomModel( - name: widget.incomingCallData.name, - token: widget.incomingCallData.sessionId, - identity: widget.incomingCallData.identity); - - await Navigator.of(context).push( - MaterialPageRoute( - fullscreenDialog: true, - builder: (BuildContext context) => - ConferencePage(roomModel: roomModel), - ), - ); + // backToHome(); + // final roomModel = RoomModel(name: widget.incomingCallData.name, token: widget.incomingCallData.sessionId, identity: widget.incomingCallData.identity); + // await _controller.dispose(); + + LandingPage.isOpenCallPage = false; + player.stop(); + changeCallStatusAPI(4); + + if (widget.incomingCallData!.background == "0") { + // Zoom Call Page + // Navigator.of(context).pop(); + Navigator.pushReplacementNamed( + context, + "zoom_call_page", + arguments: CallArguments(widget.incomingCallData!.sessionId!, "123", "Patient", "40", "0", false, int.parse(widget.incomingCallData!.appointmentNo!)), + ); + } else { + // OpenTok Call Page + await Navigator.of(context).pushReplacement( + MaterialPageRoute( + // fullscreenDialog: true, + builder: (BuildContext context) { + // final caller = widget.incomingCallData.callerID; + // final receiver = widget.incomingCallData.receiverID; + // final host = widget.incomingCallData.server; + // if(widget.incomingCallData.isWebRTC == "true"){ + // return StartVideoCall(caller: caller, receiver: receiver, iAmCaller: false, host: host); + // }else{ + return OpenTokConnectCallPage(apiKey: OPENTOK_API_KEY, sessionId: widget.incomingCallData!.sessionId!, token: widget.incomingCallData!.token!); + }, + ), + ); + } } catch (err) { print(err); await PlatformExceptionAlertDialog( - exception: err, + exception: Exception(err), ).show(context); } } - void backToHome() { + void changeCallStatusAPI(int sessionStatus) { + LiveCareService service = new LiveCareService(); + service.endCallAPI(widget.incomingCallData!.sessionId!, sessionStatus, context).then((res) {}).catchError((err) { + print(err); + }); + } + + void backToHome() async { + // final connected = await signaling.declineCall(widget.incomingCallData.callerID, widget.incomingCallData.receiverID); + LandingPage.isOpenCallPage = false; player.stop(); -// disposeAudioResources(); + changeCallStatusAPI(3); Navigator.of(context).pop(); } 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..1affe418 --- /dev/null +++ b/lib/pages/livecare/live_care_payment_page.dart @@ -0,0 +1,603 @@ +import 'dart:io'; + +import 'package:auto_size_text/auto_size_text.dart'; +import 'package:diplomaticquarterapp/config/size_config.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/LiveCare/ERAppointmentFeesResponse.dart'; +import 'package:diplomaticquarterapp/pages/insurance/insurance_update_screen.dart'; +import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; +import 'package:diplomaticquarterapp/pages/livecare/live_care_user_agreement_page.dart'; +import 'package:diplomaticquarterapp/services/livecare_services/livecare_provider.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/PlatformBridge.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/location_util.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/covid_consent_dialog.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:permission_handler/permission_handler.dart'; +import 'package:provider/provider.dart'; +import 'package:url_launcher/url_launcher.dart'; + +class LiveCarePatmentPage extends StatefulWidget { + GetERAppointmentFeesList getERAppointmentFeesList; + int waitingTime; + String clinicName; + bool isPharmaLiveCare; + String pharmaLiveCareClientID; + int selectedCallType; + + LiveCarePatmentPage( + {required this.getERAppointmentFeesList, required this.waitingTime, required this.clinicName, this.isPharmaLiveCare = false, this.pharmaLiveCareClientID = "", required this.selectedCallType}); + + @override + _LiveCarePatmentPageState createState() => _LiveCarePatmentPageState(); +} + +class _LiveCarePatmentPageState extends State { + int _selected = 0; + + late ProjectViewModel projectViewModel; + late LocationUtils locationUtils; + + @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, + onTap: () { + //Navigator.pop(context); + Navigator.pop(context); + }, + 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: (widget.getERAppointmentFeesList.currency! == "ريال" || widget.getERAppointmentFeesList.currency! == "SAR") + ? Row( + children: [ + projectViewModel.isArabic ? Container() : SvgPicture.asset("assets/images/new/Saudi_Riyal_Symbol.svg", width: 16, height: 16), + mWidth(6), + Text( + widget.getERAppointmentFeesList.amount!, + style: TextStyle( + fontSize: 12, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + ), + ), + mWidth(6), + projectViewModel.isArabic ? SvgPicture.asset("assets/images/new/Saudi_Riyal_Symbol.svg", width: 16, height: 16) : Container(), + ], + ) + : 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: (widget.getERAppointmentFeesList.currency! == "ريال" || widget.getERAppointmentFeesList.currency! == "SAR") + ? Row( + children: [ + projectViewModel.isArabic ? Container() : SvgPicture.asset("assets/images/new/Saudi_Riyal_Symbol.svg", width: 16, height: 16), + mWidth(6), + Text( + widget.getERAppointmentFeesList.tax!, + style: TextStyle( + fontSize: 12, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + ), + ), + mWidth(6), + projectViewModel.isArabic ? SvgPicture.asset("assets/images/new/Saudi_Riyal_Symbol.svg", width: 16, height: 16) : Container(), + ], + ) + : 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: (widget.getERAppointmentFeesList.currency! == "ريال" || widget.getERAppointmentFeesList.currency! == "SAR") + ? Row( + children: [ + projectViewModel.isArabic ? Container() : SvgPicture.asset("assets/images/new/Saudi_Riyal_Symbol.svg", width: 16, height: 16), + mWidth(6), + Text( + widget.getERAppointmentFeesList.total!, + style: TextStyle( + fontSize: 12, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + ), + ), + mWidth(6), + projectViewModel.isArabic ? SvgPicture.asset("assets/images/new/Saudi_Riyal_Symbol.svg", width: 16, height: 16) : Container(), + ], + ) + : 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, + ), + ), + ), + ], + ), + ), + // mHeight(0.0), + Container( + margin: EdgeInsets.only(top: 16.0), + child: Row( + children: [ + Radio( + value: 1, + groupValue: _selected, + onChanged: (val) { + onRadioChanged(val!); + }, + ), + Text( + TranslationBase.of(context).agreeTo, + style: new TextStyle( + fontSize: 12.0, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + color: CustomColors.textColor, + ), + ), + mWidth(4), + InkWell( + onTap: () { + Navigator.of(context).push(FadePage(page: LiveCareUserAgreementPage())); + // launchUrl(Uri.parse( + // "https://hmg.com/en/Pages/Privacy.aspx", + // )); + }, + child: Text( + TranslationBase.of(context).termsConditoins, + style: new TextStyle( + fontSize: 12.0, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + color: CustomColors.accentColor, + ), + ), + ), + ], + ), + ), + AutoSizeText( + TranslationBase.of(context).selectedCallType, + maxLines: 1, + minFontSize: 12, + style: TextStyle( + fontSize: SizeConfig.textMultiplier! * 2.0, + fontWeight: FontWeight.w600, + letterSpacing: -0.39, + height: 0.8, + ), + ), + mHeight(12.0), + Row( + children: [ + SvgPicture.asset( + getCallTypeImagePath(), + width: 18, + height: 18, + ), + mWidth(10), + Text( + getCallTypeText(), + style: TextStyle( + fontSize: 14.0, + letterSpacing: -0.4, + fontWeight: FontWeight.w600, + ), + ), + ], + ), + 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: Column( + children: [ + Flex( + direction: Axis.horizontal, + children: [ + Expanded( + child: DefaultButton( + TranslationBase.of(context).cancel, + () { + if (widget.isPharmaLiveCare) cancelAPI(); + Navigator.pop(context, false); + }, + ), + ), + mWidth(12), + Expanded( + child: DefaultButton( + TranslationBase.of(context).next, + () { + if (_selected == 0) { + AppToast.showErrorToast(message: TranslationBase.of(context).pleaseAcceptTerms); + } else { + if (widget.isPharmaLiveCare) { + Navigator.pop(context, true); + } else { + askVideoCallPermission().then((value) async { + if (value == true) { + locationUtils = new LocationUtils(isShowConfirmDialog: false, context: context); + locationUtils.getCurrentLocation(callBack: (value) { + print(value); + }); + if (Platform.isAndroid && !(await PlatformBridge.shared().isDrawOverAppsPermissionAllowed())) { + await drawOverAppsMessageDialog(context).then((value) { + return false; + }); + } else { + Navigator.pop(context, true); + projectViewModel.analytics.liveCare.livecare_immediate_consultation_TnC(clinic: widget.clinicName); + } + } else { + openPermissionsDialog(); + } + }); + } + } + }, + color: CustomColors.green, + ), + ), + ], + ), + widget.getERAppointmentFeesList.isCash! + ? Column( + children: [ + mHeight(10.0), + Text( + TranslationBase.of(context).cashAmountUpdateInsurance, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2E303A), + ), + ), + mHeight(5.0), + DefaultButton( + TranslationBase.of(context).updateInsuranceText, + () { + Navigator.pop(context, null); + Navigator.pushAndRemoveUntil( + context, + MaterialPageRoute(builder: (context) => LandingPage()), + (Route route) => false, + ).then((value) { + Navigator.push(context, FadePage(page: InsuranceUpdate())); + }); + }, + color: Color(0xffEAA118), + textColor: Colors.white, + ), + ], + ) + : Container(), + ], + ), + ), + ], + ), + ), + ); + } + + String getCallTypeImagePath() { + String callTypeImagePath = ""; + switch (widget.selectedCallType) { + case 1: + callTypeImagePath = "assets/images/new/services/video_call.svg"; + break; + case 2: + callTypeImagePath = "assets/images/new/services/audio_call.svg"; + break; + case 3: + callTypeImagePath = "assets/images/new/services/phone_call.svg"; + break; + } + return callTypeImagePath; + } + + String getCallTypeText() { + String callTypeText = ""; + switch (widget.selectedCallType) { + case 1: + callTypeText = TranslationBase.of(context).videoCall; + break; + case 2: + callTypeText = TranslationBase.of(context).audioCall; + break; + case 3: + callTypeText = TranslationBase.of(context).phoneCall; + break; + } + return callTypeText; + } + + @override + void dispose() { + // cancelAPI(); + super.dispose(); + } + + Future askVideoCallPermission() async { + bool result = false; + if (Platform.isIOS) { + if (!(await Permission.camera.request().isGranted) || !(await Permission.microphone.request().isGranted) || !(await Permission.location.request().isGranted)) { + result = false; + } + } else { + await showDialog( + context: context, + builder: (cxt) => CovidConsentDialog( + okTitle: TranslationBase.of(context).acceptLbl, + title: TranslationBase.of(context).covidConsentHeader, + message: TranslationBase.of(context).liveCarePermissions, + onTap: () async { + if (!(await Permission.notification.request().isGranted) || + !(await Permission.camera.request().isGranted) || + !(await Permission.microphone.request().isGranted) || + !(await Permission.location.request().isGranted)) { + { + result = false; + } + } + }, + )); + } + result = true; + return result; + // if (!(await Permission.camera.request().isGranted) || !(await Permission.microphone.request().isGranted) || !(await Permission.location.request().isGranted)) { + // return false; + // } + // return true; + } + + openPermissionsDialog() { + ConfirmDialog dialog = new ConfirmDialog( + context: context, + confirmMessage: TranslationBase.of(context).liveCarePermissions, + okText: TranslationBase.of(context).settings, + cancelText: TranslationBase.of(context).cancel_nocaps, + okFunction: () async { + openAppSettings(); + Navigator.pop(context); + }, + cancelFunction: () => {}); + dialog.showAlertDialog(context); + } + + openPermissionsConsentDialog() { + showDialog( + context: context, + builder: (cxt) => CovidConsentDialog( + okTitle: TranslationBase.of(context).acceptLbl, + title: TranslationBase.of(context).covidConsentHeader, + message: TranslationBase.of(context).covidConsent, + onTap: () async {}, + )); + } + + Future drawOverAppsMessageDialog(BuildContext context) async { + ConfirmDialog dialog = new ConfirmDialog( + context: context, + confirmMessage: TranslationBase.of(context).drawOverAppsPermission, + okText: TranslationBase.of(context).confirm, + cancelText: TranslationBase.of(context).cancel_nocaps, + okFunction: () async { + await PlatformBridge.shared().askDrawOverAppsPermission(); + Navigator.pop(context); + }, + cancelFunction: () => {}); + dialog.showAlertDialog(context); + } + + void cancelAPI() { + LiveCareService service = new LiveCareService(); + service.cancelPharmaLiveCareRequest(widget.pharmaLiveCareClientID, context).then((res) {}).catchError((err) { + print(err); + }); + } + + 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/live_care_user_agreement_page.dart b/lib/pages/livecare/live_care_user_agreement_page.dart new file mode 100644 index 00000000..675bf6d3 --- /dev/null +++ b/lib/pages/livecare/live_care_user_agreement_page.dart @@ -0,0 +1,462 @@ +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/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class LiveCareUserAgreementPage extends StatefulWidget { + const LiveCareUserAgreementPage({super.key}); + + @override + State createState() => _LiveCareUserAgreementPageState(); +} + +class _LiveCareUserAgreementPageState extends State { + late ProjectViewModel projectViewModel; + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + return AppScaffold( + isShowAppBar: true, + showNewAppBarTitle: true, + showNewAppBar: true, + isShowDecPage: false, + appBarTitle: TranslationBase.of(context).termsConditions, + body: SingleChildScrollView( + child: Padding( + padding: EdgeInsets.all(8.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).liveCareTermsHeading, + style: TextStyle( + fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsIntroHeading, + style: TextStyle( + fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions1, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions2, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsHeading2, + style: TextStyle( + fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions3, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions3a, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions3b, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions3c, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions3d, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions4, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions5, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions6, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsHeading3, + style: TextStyle( + fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions7, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions8, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions9, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions10, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions11, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions12, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions13, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsHeading4, + style: TextStyle( + fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions14, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions15, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions16, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsHeading5, + style: TextStyle( + fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions17, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + + Text( + TranslationBase.of(context).liveCareTermsConditions18, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions19, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions19a, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions19b, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions19c, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions19d, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions19e, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions20, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsHeading6, + style: TextStyle( + fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions21, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions22, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions23, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsHeading7, + style: TextStyle( + fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions24, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions25, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions26, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions27, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions28, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions29, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions30, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsHeading8, + style: TextStyle( + fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions31, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsHeading9, + style: TextStyle( + fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions32, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions33, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions34, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions35, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsHeading10, + style: TextStyle( + fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions36, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsHeading11, + style: TextStyle( + fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions37, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions38, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsHeading12, + style: TextStyle( + fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions39, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions40, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions41, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsHeading13, + style: TextStyle( + fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions42, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsHeading14, + style: TextStyle( + fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions43, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions43a, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions43b, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions43c, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions43d, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions43e, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions43f, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions43g, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsHeading15, + style: TextStyle( + fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions44, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions45, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions46, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsHeading16, + style: TextStyle( + fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions47, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).liveCareTermsConditions48, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + ], + ), + ), + ), + ); + } +} diff --git a/lib/pages/livecare/livecare_call_type_select.dart b/lib/pages/livecare/livecare_call_type_select.dart new file mode 100644 index 00000000..5592ee34 --- /dev/null +++ b/lib/pages/livecare/livecare_call_type_select.dart @@ -0,0 +1,146 @@ +import 'package:auto_size_text/auto_size_text.dart'; +import 'package:diplomaticquarterapp/config/size_config.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.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/data_display/medical/medical_profile_item.dart'; +import 'package:diplomaticquarterapp/widgets/mobile-no/mobile_no.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class LiveCareCallTypeSelectPage extends StatefulWidget { + Function onSelectedMethod; + + LiveCareCallTypeSelectPage({required this.onSelectedMethod}); + + @override + State createState() => _LiveCareCallTypeSelectPageState(); +} + +class _LiveCareCallTypeSelectPageState extends State { + int selectedCallType = 1; + String mobileNo = ""; + String countryCode = '966'; + late ProjectViewModel projectViewModel; + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + mobileNo = Utils.getPhoneNumberWithoutZero(projectViewModel.authenticatedUserObject.user.mobileNumber!); + return AppScaffold( + appBarTitle: TranslationBase.of(context).selectCallType, + isShowAppBar: true, + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: CustomColors.appBackgroudGrey2Color, + body: Padding( + padding: EdgeInsets.all(21), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + GridView( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, childAspectRatio: 2 / 2, crossAxisSpacing: 12, mainAxisSpacing: 12), + physics: NeverScrollableScrollPhysics(), + shrinkWrap: true, + children: [ + InkWell( + onTap: () { + setState(() { + selectedCallType = 1; + }); + }, + child: MedicalProfileItem( + title: TranslationBase.of(context).videoCall, + imagePath: 'video_call.svg', + subTitle: "", + isPngImage: false, + isShowBorder: selectedCallType == 1, + ), + ), + InkWell( + onTap: () { + setState(() { + selectedCallType = 2; + }); + }, + child: MedicalProfileItem( + title: TranslationBase.of(context).audioCall, + imagePath: 'audio_call.svg', + subTitle: "", + isPngImage: false, + isShowBorder: selectedCallType == 2, + ), + ), + InkWell( + onTap: () { + setState(() { + selectedCallType = 3; + }); + }, + child: MedicalProfileItem( + title: TranslationBase.of(context).phoneCall, + imagePath: 'phone_call.svg', + subTitle: "", + isPngImage: false, + isShowBorder: selectedCallType == 3, + ), + ), + ], + ), + if (selectedCallType == 3) + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + mHeight(32.0), + AutoSizeText( + TranslationBase.of(context).mobileNumber, + maxLines: 1, + minFontSize: 12, + style: TextStyle( + fontSize: SizeConfig.textMultiplier! * 2.0, + fontWeight: FontWeight.w600, + letterSpacing: -0.39, + height: 0.8, + ), + ), + mHeight(16.0), + PhoneNumberSelectorWidget( + onNumberChange: (value) => { + mobileNo = value, + }, + onCountryChange: (value) => { + countryCode = value, + }, + mobileNo: this.mobileNo, + isLiveCareTypeSelect: true, + isEnable: false, + ), + ], + ), + ], + ), + ), + bottomSheet: Container( + color: CustomColors.white, + padding: EdgeInsets.fromLTRB(12.0, 1.0, 12.0, 25.0), + child: DefaultButton( + TranslationBase.of(context).next, + () { + if (mobileNo.isNotEmpty) { + widget.onSelectedMethod(selectedCallType, mobileNo); + Navigator.pop(context, [selectedCallType, mobileNo]); + } else { + AppToast.showErrorToast(message: TranslationBase.of(context).enterMobileNumber); + } + }, + color: CustomColors.accentColor, + ), + ), + ); + } +} diff --git a/lib/pages/livecare/livecare_home.dart b/lib/pages/livecare/livecare_home.dart index bbad8d4c..6381ce8a 100644 --- a/lib/pages/livecare/livecare_home.dart +++ b/lib/pages/livecare/livecare_home.dart @@ -1,64 +1,122 @@ +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.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'; import 'package:diplomaticquarterapp/pages/livecare/widgets/livecare_logs.dart'; import 'package:diplomaticquarterapp/services/livecare_services/livecare_provider.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/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; class LiveCareHome extends StatefulWidget { static bool showFooterButton = true; + static bool isLiveCareTypeSelected = false; + final bool isPharmacyLiveCare; + final String pharmacyLiveCareQRCode; + + const LiveCareHome({Key? key, this.isPharmacyLiveCare = false, this.pharmacyLiveCareQRCode = ""}) : super(key: key); @override _LiveCareHomeState createState() => _LiveCareHomeState(); } -class _LiveCareHomeState extends State - with SingleTickerProviderStateMixin { - TabController _tabController; +class _LiveCareHomeState extends State with SingleTickerProviderStateMixin { + late TabController _tabController; bool isDataLoaded = false; bool hasLiveCareRequest = false; + List imagesInfo =[]; + + late List erRequestHistoryList; - List erRequestHistoryList; + late ErRequestHistoryList pendingERRequestHistoryList; - ErRequestHistoryList pendingERRequestHistoryList; + late ProjectViewModel projectViewModel; + AppSharedPreferences sharedPref = AppSharedPreferences(); @override void initState() { _tabController = new TabController(length: 2, vsync: this); - erRequestHistoryList = List(); - + erRequestHistoryList =[]; + LiveCareHome.isLiveCareTypeSelected = false; pendingERRequestHistoryList = new ErRequestHistoryList(); - + imagesInfo.add(ImagesInfo( + imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/er-consultation_en/en/0.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/er-consultation_ar/ar/0.png')); WidgetsBinding.instance.addPostFrameCallback((_) { - if (!isDataLoaded) getLiveCareHistory(); + if (!isDataLoaded && projectViewModel.isLogin) getLiveCareHistory(); }); super.initState(); } + @override + void dispose() { + LiveCareHome.isLiveCareTypeSelected = false; + sharedPref.remove(LIVECARE_CLINIC_DATA); + super.dispose(); + } + @override Widget build(BuildContext context) { + projectViewModel = Provider.of(context); return AppScaffold( - appBarTitle: "LiveCare", + appBarTitle: TranslationBase.of(context).livecare, isShowAppBar: true, + showNewAppBarTitle: true, + showNewAppBar: true, + imagesInfo: imagesInfo, + description: TranslationBase.of(context).erConsultation, body: Container( child: Column(children: [ - /// this is will not colored with theme data 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(text: TranslationBase.of(context).consultation), - Tab(text: TranslationBase.of(context).logs), + Tab( + child: Text( + TranslationBase.of(context).consultation, + style: TextStyle( + color: Colors.black, + fontSize: 14, + letterSpacing: -0.36, + fontWeight: FontWeight.w600, + ), + ), + ), + Tab( + child: Text( + TranslationBase.of(context).logs, + style: TextStyle( + color: Colors.black, + fontSize: 14, + letterSpacing: -0.36, + fontWeight: FontWeight.w600, + ), + ), + ), ], - controller: _tabController, - ), - Divider( - color: Colors.grey[600], - thickness: 0.5, ), Expanded( child: TabBarView( @@ -67,12 +125,11 @@ class _LiveCareHomeState extends State isDataLoaded && !hasLiveCareRequest ? ClinicList( getLiveCareHistory: getLiveCareHistory, + isPharmacyLiveCare: widget.isPharmacyLiveCare, + pharmacyLiveCareQRCode: widget.pharmacyLiveCareQRCode, ) : isDataLoaded - ? LiveCarePendingRequest( - getLiveCareHistory: getLiveCareHistory, - pendingERRequestHistoryList: - pendingERRequestHistoryList) + ? LiveCarePendingRequest(getLiveCareHistory: getLiveCareHistory, pendingERRequestHistoryList: pendingERRequestHistoryList) : Container(), isDataLoaded ? LiveCareLogs( @@ -95,23 +152,16 @@ class _LiveCareHomeState extends State hasLiveCareRequest = false; }); LiveCareService service = new LiveCareService(); - PatientERVirtualHistoryResponse patientERVirtualHistoryResponse = - new PatientERVirtualHistoryResponse(); + PatientERVirtualHistoryResponse patientERVirtualHistoryResponse = new PatientERVirtualHistoryResponse(); service.getLivecareHistory(context).then((res) { GifLoaderDialogUtils.hideDialog(context); setState(() { - print(res['ErRequestHistoryList'].length); if (res['ErRequestHistoryList'].length != 0) { - patientERVirtualHistoryResponse = - PatientERVirtualHistoryResponse.fromJson(res); - erRequestHistoryList = - patientERVirtualHistoryResponse.erRequestHistoryList; + patientERVirtualHistoryResponse = PatientERVirtualHistoryResponse.fromJson(res as Map); + erRequestHistoryList = patientERVirtualHistoryResponse.erRequestHistoryList!; - if (patientERVirtualHistoryResponse - .erRequestHistoryList[0].callStatus < - 4) { - pendingERRequestHistoryList = - patientERVirtualHistoryResponse.erRequestHistoryList[0]; + if (patientERVirtualHistoryResponse.erRequestHistoryList![0].callStatus! < 4) { + pendingERRequestHistoryList = patientERVirtualHistoryResponse.erRequestHistoryList![0]; hasLiveCareRequest = true; } else { hasLiveCareRequest = false; @@ -121,6 +171,7 @@ class _LiveCareHomeState extends State }); }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err, localContext: context); print(err); }); } diff --git a/lib/pages/livecare/livecare_scheduling/schedule_clinic_card.dart b/lib/pages/livecare/livecare_scheduling/schedule_clinic_card.dart index 72ca4ce9..1006dc86 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; + 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,68 @@ 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.clinicsHaveScheduleList.clinicDesc ?? "", + style: TextStyle( + fontSize: 16.0, + color: Colors.black, + fontWeight: FontWeight.w600, + ), + ), ), ], ), diff --git a/lib/pages/livecare/livecare_type_select.dart b/lib/pages/livecare/livecare_type_select.dart index 00c2b717..f3900c5e 100644 --- a/lib/pages/livecare/livecare_type_select.dart +++ b/lib/pages/livecare/livecare_type_select.dart @@ -1,8 +1,17 @@ +import 'package:barcode_scan2/barcode_scan2.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/pages/livecare/pharma_livecare_intro_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/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/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:provider/provider.dart'; class LiveCareTypeSelect extends StatefulWidget { @override @@ -13,6 +22,9 @@ class _LiveCareTypeSelectState extends State { var languageID; AppSharedPreferences sharedPref = AppSharedPreferences(); + late ProjectViewModel projectViewModel; + String pharmacyLiveCareQRCode = ""; + @override void initState() { getLanguageID(); @@ -21,188 +33,78 @@ class _LiveCareTypeSelectState extends State { @override Widget build(BuildContext context) { - return Scaffold( - 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)), - ), + projectViewModel = Provider.of(context); + return AppScaffold( + isShowDecPage: true, + isShowAppBar: true, + showNewAppBarTitle: true, + showNewAppBar: true, + appBarTitle: TranslationBase.of(context).livecare.toUpperCase(), 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: 10.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: 15.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: 20.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: 20.0), - child: Text( - TranslationBase.of(context).livecareSummary, - style: TextStyle(fontSize: 16.0))), - InkWell( - onTap: (){ - Navigator.pop(context, "immediate"); - }, - child: Container( - decoration: BoxDecoration( - color: Colors.red[900], - borderRadius: BorderRadius.all(Radius.circular(10.0))), - height: 120.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, 20.0, 0.0, 0.0), - child: Column( - 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: 10.0), - child: Text(TranslationBase.of(context).livecareOption2, - style: TextStyle( - fontSize: 18.0, color: Colors.white)), - ) - ], - ), - ), - ], - )), - ), - InkWell( - onTap: (){ - Navigator.pop(context, "schedule"); - }, - child: Container( - decoration: BoxDecoration( - color: Colors.grey[700], - borderRadius: BorderRadius.all(Radius.circular(10.0))), - height: 120.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: 70), - ), - Container( - width: MediaQuery.of(context).size.width * 0.58, - margin: EdgeInsets.fromLTRB(30.0, 20.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)), - ) - ], - ), - ), - ], - )), + 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), + _loginOptionButton(TranslationBase.of(context).pharmaLiveCare, 'assets/images/new/pharma.svg', 3, isEnable: projectViewModel.havePrivilege(99)), + ], ), SizedBox( height: 40.0, @@ -214,6 +116,108 @@ class _LiveCareTypeSelectState extends State { ); } + Widget _loginOptionButton(String _title, String _icon, int _loginIndex, {bool isEnable = true}) { + return InkWell( + onTap: () { + if (_loginIndex == 1) { + Navigator.pop(context, "immediate"); + projectViewModel.analytics.liveCare.livecare_immediate_consultation(); + } else if (_loginIndex == 2) { + Navigator.pop(context, "schedule"); + projectViewModel.analytics.liveCare.livecare_schedule_video_call(); + } else { + //Pharmacy LiveCare + if (isEnable) { + Navigator.push( + context, + FadePage( + page: PharmaLiveCareIntroPage(), + ), + ).then((value) { + if (value != null && value.contains("pharmacy/")) { + pharmacyLiveCareQRCode = value.split("/")[1]; + startPharmacyLiveCareProcess(); + } + }); + } + } + }, + child: Stack(children: [ + AspectRatio( + aspectRatio: 1.0, + child: Container( + padding: EdgeInsets.only(left: 20, right: 20, bottom: 3, 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 == 3 ? 80 : 60, + width: _loginIndex == 3 ? 80 : 60, + ), + Text( + _title, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.48, height: 20 / 16), + ), + ], + ), + ), + ), + isEnable + ? Container() + : Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15), + color: Colors.grey.withOpacity(0.6), + border: Border.all( + color: Color(0xffefefef), + width: 1, + ), + ), + width: double.infinity, + height: double.infinity, + child: Icon( + Icons.lock_outline, + size: 40, + ), + ) + ]), + ); + } + + readQRCode() async { + //Changed By Aamir + pharmacyLiveCareQRCode = await BarcodeScanner.scan().then((value) { + return value.rawContent; + }); + if (pharmacyLiveCareQRCode != "") { + GifLoaderDialogUtils.showMyDialog(context); + LiveCareService service = new LiveCareService(); + service.getPatientInfoByQR(pharmacyLiveCareQRCode, context).then((res) { + GifLoaderDialogUtils.hideDialog(context); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + startPharmacyLiveCareProcess(); + }); + } else {} + } + + startPharmacyLiveCareProcess() { + sharedPref.setString(LIVECARE_CLINIC_DATA, "Pharmacy LiveCare" + "-" + "501" + "-" + "1"); + Navigator.pop(context, "pharmacy/$pharmacyLiveCareQRCode"); + // Navigator.push(context, FadePage(page: LiveCareHome(isPharmacyLiveCare: true, pharmacyLiveCareQRCode: pharmacyLiveCareQRCode,))); + } + getLanguageID() async { var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); setState(() { diff --git a/lib/pages/livecare/pharma_livecare_intro_page.dart b/lib/pages/livecare/pharma_livecare_intro_page.dart new file mode 100644 index 00000000..c7120c08 --- /dev/null +++ b/lib/pages/livecare/pharma_livecare_intro_page.dart @@ -0,0 +1,209 @@ +import 'package:barcode_scan2/barcode_scan2.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/services/livecare_services/livecare_provider.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/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'; + +import '../../uitl/utils.dart'; + +class PharmaLiveCareIntroPage extends StatefulWidget { + const PharmaLiveCareIntroPage({Key? key}) : super(key: key); + + @override + State createState() => _PharmaLiveCareIntroPageState(); +} + +class _PharmaLiveCareIntroPageState extends State { + late ProjectViewModel projectViewModel; + String pharmacyLiveCareQRCode = ""; + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + return AppScaffold( + appBarTitle: TranslationBase.of(context).pharmaLiveCare, + isShowAppBar: true, + showNewAppBarTitle: true, + showNewAppBar: true, + body: SingleChildScrollView( + child: Container( + margin: EdgeInsets.only(left: 20.0, right: 20.0, top: 20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container(child: Text(TranslationBase.of(context).pharmaLiveCare1, style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0, letterSpacing: -0.64, color: CustomColors.darkGrey))), + Container( + margin: EdgeInsets.only(top: 7.0), + child: Text(TranslationBase.of(context).pharmaLiveCareDesc1, style: TextStyle(fontSize: 14.0, letterSpacing: -0.64, color: CustomColors.textColor, fontWeight: FontWeight.w600))), + Container( + margin: EdgeInsets.only(top: 20.0), + child: Text(TranslationBase.of(context).wherePharmaLiveCare, style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0, letterSpacing: -0.64, color: CustomColors.darkGrey))), + Container( + margin: EdgeInsets.only(top: 7.0), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Image.asset( + "assets/images/new/booth_image.png", + ), + Container( + width: MediaQuery.of(context).size.width * 0.6, + margin: EdgeInsets.only(left: 10.0, right: 10.0), + child: Text(TranslationBase.of(context).pharmaLiveCareDesc2, + style: TextStyle(fontSize: 14.0, letterSpacing: -0.64, color: CustomColors.textColor, fontWeight: FontWeight.w600))), + ], + )), + Container( + margin: EdgeInsets.only(top: 20.0), + child: Text(TranslationBase.of(context).howPharmaLiveCare, style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0, letterSpacing: -0.64, color: CustomColors.darkGrey))), + Container( + margin: EdgeInsets.only(top: 7.0), + child: Text(TranslationBase.of(context).pharmaLiveCareDesc3, style: TextStyle(fontSize: 14.0, letterSpacing: -0.64, color: CustomColors.textColor, fontWeight: FontWeight.w600))), + Container( + margin: EdgeInsets.only(top: 7.0), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + margin: EdgeInsets.only(top: 7.0), + padding: EdgeInsets.fromLTRB(14.0, 5.0, 14.0, 5.0), + decoration: BoxDecoration(color: CustomColors.green, borderRadius: BorderRadius.all(Radius.circular(100.0))), + child: Text("1", style: TextStyle(fontSize: 16.0, letterSpacing: -0.64, color: CustomColors.white, fontWeight: FontWeight.w600))), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: SvgPicture.asset("assets/images/new/qr_code.svg", width: 40), + ), + Container( + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text(TranslationBase.of(context).pharmaLiveCareScanQR, + style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0, letterSpacing: -0.64, color: CustomColors.darkGrey))), + Container( + width: MediaQuery.of(context).size.width * 0.7, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text(TranslationBase.of(context).pharmaLiveCareScanQR1, + style: TextStyle(fontSize: 14.0, letterSpacing: -0.64, color: CustomColors.textColor, fontWeight: FontWeight.w600))), + ], + ), + ], + ), + ), + Container( + margin: EdgeInsets.only(top: 7.0), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + margin: EdgeInsets.only(top: 7.0), + padding: EdgeInsets.fromLTRB(12.0, 5.0, 12.0, 5.0), + decoration: BoxDecoration(color: CustomColors.green, borderRadius: BorderRadius.all(Radius.circular(100.0))), + child: Text("2", style: TextStyle(fontSize: 16.0, letterSpacing: -0.64, color: CustomColors.white, fontWeight: FontWeight.w600))), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: SvgPicture.asset("assets/images/new/payment.svg", width: 40), + ), + Container( + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text(TranslationBase.of(context).pharmaLiveCareMakePayment, + style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0, letterSpacing: -0.64, color: CustomColors.darkGrey))), + Container( + width: MediaQuery.of(context).size.width * 0.7, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text(TranslationBase.of(context).pharmaLiveCareMakePayment1, + style: TextStyle(fontSize: 14.0, letterSpacing: -0.64, color: CustomColors.textColor, fontWeight: FontWeight.w600))), + ], + ), + ], + ), + ), + Container( + margin: EdgeInsets.only(top: 7.0), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + margin: EdgeInsets.only(top: 7.0), + padding: EdgeInsets.fromLTRB(12.0, 5.0, 12.0, 5.0), + decoration: BoxDecoration(color: CustomColors.green, borderRadius: BorderRadius.all(Radius.circular(100.0))), + child: Text("3", style: TextStyle(fontSize: 16.0, letterSpacing: -0.64, color: CustomColors.white, fontWeight: FontWeight.w600))), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: SvgPicture.asset("assets/images/new/pharmaicon.svg", width: 40), + ), + Container( + width: MediaQuery.of(context).size.width * 0.7, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text(TranslationBase.of(context).pharmaLiveCareJoinConsultation, + style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0, letterSpacing: -0.64, color: CustomColors.darkGrey))), + Container( + width: MediaQuery.of(context).size.width * 0.7, + margin: EdgeInsets.only(left: 5.0, right: 5.0), + child: Text(TranslationBase.of(context).pharmaLiveCareJoinConsultation1, + style: TextStyle(fontSize: 14.0, letterSpacing: -0.64, color: CustomColors.textColor, fontWeight: FontWeight.w600))), + ], + ), + ], + ), + ), + SizedBox( + height: 100.0, + ) + ], + ), + ), + ), + bottomSheet: Container( + height: MediaQuery.of(context).size.height * 0.08, + width: double.infinity, + color: Colors.white, + child: Column( + children: [ + Container( + width: MediaQuery.of(context).size.width * 0.9, + child: DefaultButton(TranslationBase.of(context).pharmaLiveCareScanQR, () { + readQRCode(); + }), + ), + ], + ), + ), + ); + } + + readQRCode() async { + pharmacyLiveCareQRCode = await BarcodeScanner.scan().then((value) { + return value.rawContent; + }); + if (pharmacyLiveCareQRCode != "") { + GifLoaderDialogUtils.showMyDialog(context); + LiveCareService service = new LiveCareService(); + service.getPatientInfoByQR(pharmacyLiveCareQRCode, context).then((res) { + GifLoaderDialogUtils.hideDialog(context); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + startPharmacyLiveCareProcess(); + }); + } else {} + } + + startPharmacyLiveCareProcess() { + sharedPref.setString(LIVECARE_CLINIC_DATA, "Pharmacy LiveCare" + "-" + "501" + "-" + "1"); + Navigator.pop(context, "pharmacy/$pharmacyLiveCareQRCode"); + } +} diff --git a/lib/pages/livecare/video-call-web-page.dart b/lib/pages/livecare/video-call-web-page.dart new file mode 100644 index 00000000..f755d1b0 --- /dev/null +++ b/lib/pages/livecare/video-call-web-page.dart @@ -0,0 +1,124 @@ +import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; + +class VideoCallWebPage extends StatelessWidget{ + final GlobalKey webViewKey = GlobalKey(); + + // InAppWebViewController webViewController; + InAppWebViewController? controller; + + URLRequest? request; + final String receiverId; + final String callerId; + VideoCallWebPage({required this.receiverId, required this.callerId}){ + request = URLRequest(url: WebUri.uri(Uri.parse("https://vcallapi.hmg.com/Mobileindex.html?username=$receiverId&doctorid=$callerId"))); + } + + InAppWebViewGroupOptions options = InAppWebViewGroupOptions( + crossPlatform: InAppWebViewOptions( + cacheEnabled: false, + clearCache: true, + disableHorizontalScroll: true, + disableVerticalScroll: true, + disableContextMenu: true, + supportZoom: false, + javaScriptEnabled: true, + preferredContentMode: UserPreferredContentMode.MOBILE, + useShouldOverrideUrlLoading: true, + mediaPlaybackRequiresUserGesture: false, + + ), + android: AndroidInAppWebViewOptions( + hardwareAcceleration: true, + useHybridComposition: true, + ), + ios: IOSInAppWebViewOptions( + allowsAirPlayForMediaPlayback: true, + allowsPictureInPictureMediaPlayback: true, + allowsInlineMediaPlayback: true, + ) + ); + + @override + Widget build(BuildContext context) { + return Scaffold( + primary: true, + appBar: AppBar( + backgroundColor: Colors.transparent, leading: Container(), + systemOverlayStyle: SystemUiOverlayStyle(statusBarColor: Colors.black), + ), + extendBodyBehindAppBar: true, + extendBody: false, + // backgroundColor: Colors.white, + body: Column( + children: [ + SizedBox(height: MediaQuery.of(context).viewPadding.top), + Expanded( + child: InAppWebView( + androidOnPermissionRequest: androidOnPermissionRequest, + initialOptions: options, + initialUrlRequest: request, + onWebViewCreated: onWebViewCreated, + onLoadStart: onLoadStart, + onLoadError: onError, + onConsoleMessage: onConsoleMessage, + // shouldOverrideUrlLoading: shouldRedirect , + ), + ), + ], + ), + ); + + ChromeSafariBrowser(); + } + + + Future androidOnPermissionRequest(InAppWebViewController controller, String origin, List resources) async { + return PermissionRequestResponse( + resources: resources, + action: PermissionRequestResponseAction.GRANT + ); + } + + onWebViewCreated(InAppWebViewController controller) { + this.controller = controller; + LandingPage.isOpenCallPage = true; + } + + onConsoleMessage(controller, ConsoleMessage consoleMessage){ + print(consoleMessage); + } + + onError(InAppWebViewController? controller, Uri? url, int code, String message) { + + } + + onLoadStart(InAppWebViewController? controller, Uri? url) { + print(url); + if(url.toString().toLowerCase().contains("endcallpage")){ + LandingPage.isOpenCallPage = false; + if(LandingPage.isOpenCallPage == true) { + print("END CALL!!!"); + // controller.goBack(); + Navigator.pop(webViewKey.currentContext!); + } + } + } + + Future shouldRedirect(InAppWebViewController controller, NavigationAction navigationAction) async { + var uri = navigationAction.request.url; + // if(uri.queryParameters['exit'] == "yes"){ + // Navigator.pop(webViewKey.currentContext); + // } + if(uri.toString().toLowerCase().contains("endcallpage")){ + Navigator.pop(webViewKey.currentContext!); + } + + return NavigationActionPolicy.ALLOW; + } + + +} \ No newline at end of file diff --git a/lib/pages/livecare/widgets/ClinicTimingsDialog.dart b/lib/pages/livecare/widgets/ClinicTimingsDialog.dart index d5fce79e..5f827fad 100644 --- a/lib/pages/livecare/widgets/ClinicTimingsDialog.dart +++ b/lib/pages/livecare/widgets/ClinicTimingsDialog.dart @@ -1,14 +1,12 @@ import 'package:diplomaticquarterapp/models/LiveCare/ClinicsServiceTimingsResponse.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:flutter/material.dart'; class ClinicTimingsDialog extends StatefulWidget { final clinicName; - final List - patientERGetClinicsServiceTimingsList; + final List patientERGetClinicsServiceTimingsList; - ClinicTimingsDialog( - {@required this.clinicName, - @required this.patientERGetClinicsServiceTimingsList}); + ClinicTimingsDialog({required this.clinicName, required this.patientERGetClinicsServiceTimingsList}); @override _ClinicTimingsDialogState createState() => _ClinicTimingsDialogState(); @@ -28,10 +26,9 @@ class _ClinicTimingsDialogState extends State { final double itemWidth = size.width / 2; return Container( child: Dialog( - shape: - RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.0)), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.0)), child: Container( - height: MediaQuery.of(context).size.height * 0.68, + height: 580.0, margin: EdgeInsets.all(20.0), width: 450.0, child: Column( @@ -41,10 +38,7 @@ class _ClinicTimingsDialogState extends State { Container( alignment: Alignment.center, margin: EdgeInsets.only(bottom: 10.0), - child: Text("Clinic Schedule", - textAlign: TextAlign.center, - style: - TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), + child: Text(TranslationBase.of(context).clinicSchedule, textAlign: TextAlign.center, style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), ), Divider( thickness: 1.0, @@ -52,9 +46,7 @@ class _ClinicTimingsDialogState extends State { ), Container( margin: EdgeInsets.only(bottom: 20.0, top: 10.0), - child: Text(widget.clinicName, - style: - TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), + child: Text(widget.clinicName, style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), ), CustomScrollView( primary: false, @@ -71,10 +63,8 @@ class _ClinicTimingsDialogState extends State { height: 10.0, child: Column( children: [ - Text(e.dayOfWeekStr), - Text(e.shiftTimings[0].startTime + - " - " + - e.shiftTimings[0].endTime), + Text(e.dayOfWeekStr!), + Text(e.shiftTimings![0].startTime! + " - " + e.shiftTimings![0].endTime!), ], ), )) @@ -98,7 +88,7 @@ class _ClinicTimingsDialogState extends State { Navigator.pop(context); }, child: Container( - child: Text("OK", + child: Text(TranslationBase.of(context).ok, textAlign: TextAlign.center, style: TextStyle( fontSize: 18.0, diff --git a/lib/pages/livecare/widgets/LiveCareHistoryCard.dart b/lib/pages/livecare/widgets/LiveCareHistoryCard.dart index 36e8274f..eecbfea6 100644 --- a/lib/pages/livecare/widgets/LiveCareHistoryCard.dart +++ b/lib/pages/livecare/widgets/LiveCareHistoryCard.dart @@ -1,20 +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; + ErRequestHistoryList? erRequestHistoryList; + int? isFirstOrLast; - LiveCareHistoryCard({this.erRequestHistoryList}); + LiveCareHistoryCard({this.erRequestHistoryList, this.isFirstOrLast}); @override _LiveCareHistoryCardState createState() => _LiveCareHistoryCardState(); @@ -24,6 +33,8 @@ class _LiveCareHistoryCardState extends State { AuthenticatedUser authUser = new AuthenticatedUser(); AppSharedPreferences sharedPref = AppSharedPreferences(); + late ProjectViewModel projectViewModel; + @override void initState() { getAuthenticatedUser(); @@ -32,143 +43,193 @@ class _LiveCareHistoryCardState extends State { @override 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("Requested date:", - style: - TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold)), - Container( - margin: EdgeInsets.only(top: 10.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text(widget.erRequestHistoryList.sArrivalTime, - style: TextStyle(fontSize: 14.0)), - Text( - "Call Duration\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 : 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(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( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Text( + widget.erRequestHistoryList!.stringCallStatus! , + style: TextStyle( + fontSize: 10.0, + fontWeight: FontWeight.w600, + letterSpacing: -0.4, + color: CustomColors.green, + //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: () { - print("Invoice"); - openInvoice(); - }, - child: Container( - child: Row( - children: [ - Icon(Icons.content_paste, color: Colors.blue), - Container( - margin: EdgeInsets.only(left: 10.0), - child: Text("Invoice", - textAlign: TextAlign.center), + ), + 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: () { - print("Complaints"); - openComplaint(); - }, - child: Container( - child: Row( - children: [ - Icon(Icons.add, size: 24.0, color: Colors.red), - Container( - margin: EdgeInsets.only(left: 10.0), - child: Text("Complaints", - textAlign: TextAlign.center), + ), + 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: () { - print("Rate Dr & Appointment"); - }, - 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: 10.0), - child: Text("Rate Dr & Appointment", - overflow: TextOverflow.clip, - textAlign: TextAlign.center), + ), + 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!) { + AppToast.showErrorToast(message: TranslationBase.of(context).alreadyRated); + } else {} + } + openInvoice() { - ConfirmDialog dialog = new ConfirmDialog( - context: context, - confirmMessage: "Send a copy of this invoice to the email: " + - authUser.emailAddress, - okText: TranslationBase.of(context).confirm, - cancelText: TranslationBase.of(context).cancel_nocaps, - okFunction: () => {sendInvoiceEmail(context)}, - cancelFunction: () => {}); - dialog.showAlertDialog(context); + showDialog( + context: context, + builder: (cxt) => ConfirmSendEmailDialog( + email: projectViewModel.user!.emailAddress, + onTapSendEmail: () { + sendInvoiceEmail(context); + }, + ), + ); } openComplaint() { @@ -176,27 +237,22 @@ class _LiveCareHistoryCardState extends State { } sendInvoiceEmail(context) { - ConfirmDialog.closeAlertDialog(context); + int languageID = projectViewModel.isArabic ? 1 : 2; LiveCareService service = new LiveCareService(); GifLoaderDialogUtils.showMyDialog(context); - service - .sendLiveCareInvoiceEmail( - widget.erRequestHistoryList.appointmentNo.toString(), - widget.erRequestHistoryList.projectID, - authUser.emailAddress, - context) - .then((res) { - AppToast.showSuccessToast(message: "LiveCare invoice sent successfully"); + service.sendLiveCareInvoiceEmail(widget.erRequestHistoryList!.appointmentNo.toString(), widget.erRequestHistoryList!.projectID!, authUser.emailAddress!, languageID, context).then((res) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showSuccessToast(message: TranslationBase.of(context).emailSentSuccessfully); }).catchError((err) { - AppToast.showErrorToast(message: err); + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err.toString()); print(err); }); } getAuthenticatedUser() async { 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)); setState(() { authUser = data; }); diff --git a/lib/pages/livecare/widgets/LiveCarePaymentDialog.dart b/lib/pages/livecare/widgets/LiveCarePaymentDialog.dart index e2dab5b0..de3cb248 100644 --- a/lib/pages/livecare/widgets/LiveCarePaymentDialog.dart +++ b/lib/pages/livecare/widgets/LiveCarePaymentDialog.dart @@ -1,15 +1,17 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/LiveCare/ERAppointmentFeesResponse.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:flutter/material.dart'; +import 'package:provider/provider.dart'; class LiveCarePaymentDialog extends StatefulWidget { GetERAppointmentFeesList getERAppointmentFeesList; int waitingTime; String clinicName; - LiveCarePaymentDialog( - {@required this.getERAppointmentFeesList, @required this.waitingTime, @required this.clinicName}); + LiveCarePaymentDialog({required this.getERAppointmentFeesList, required this.waitingTime, required this.clinicName}); @override _LiveCarePaymentDialogState createState() => _LiveCarePaymentDialogState(); @@ -18,31 +20,32 @@ class LiveCarePaymentDialog extends StatefulWidget { class _LiveCarePaymentDialogState extends State { int _selected = 0; + late 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 Container( child: Dialog( - shape: - RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.0)), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.0)), child: Container( - height: MediaQuery.of(context).size.height * 0.691, + height: 600.0, margin: EdgeInsets.all(20.0), - width: 450.0, - child: Column( + width: 500.0, + color: Colors.red, + child: SingleChildScrollView( + child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.max, children: [ Container( alignment: Alignment.center, margin: EdgeInsets.only(bottom: 10.0), - child: Text("Online Consultation", - textAlign: TextAlign.center, - style: - TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), + child: Text(TranslationBase.of(context).onlineConsultation, textAlign: TextAlign.center, style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), ), Divider( thickness: 1.0, @@ -52,33 +55,22 @@ class _LiveCarePaymentDialogState extends State { direction: Axis.horizontal, children: [ Expanded( - child: Text("Waiting time to start LiveCare consultation", - textAlign: TextAlign.end, - style: TextStyle(fontSize: 13.0)), + child: Text(TranslationBase.of(context).expectedWaiting, textAlign: TextAlign.end, style: TextStyle(fontSize: 13.0)), ), Expanded( child: Container( - child: Icon(Icons.access_time, - size: 36.0, color: Colors.red[800]), + child: Icon(Icons.access_time, size: 36.0, color: Colors.red[800]), ), ), Expanded( - child: Text(widget.waitingTime.toString() + " Minutes", - textAlign: TextAlign.start, - style: TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.bold, - color: Colors.red[900])), + child: Text(widget.waitingTime.toString() + " " + TranslationBase.of(context).minute, + textAlign: TextAlign.start, style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold, color: Colors.red[900])), ), ], ), Container( - alignment: Alignment.center, margin: EdgeInsets.only(bottom: 10.0, top: 10.0), - child: Text(widget.clinicName, - textAlign: TextAlign.center, - style: - TextStyle(fontSize: 22.0, fontWeight: FontWeight.bold)), + child: Text(widget.clinicName, style: TextStyle(fontSize: 22.0, fontWeight: FontWeight.bold)), ), Container( width: MediaQuery.of(context).size.width, @@ -92,12 +84,7 @@ class _LiveCarePaymentDialogState extends State { alignment: Alignment.center, margin: EdgeInsets.only(top: 5.0), padding: EdgeInsets.all(5.0), - child: Text("Consultation fee", - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 14.0, - fontWeight: FontWeight.bold, - color: Colors.white)), + child: Text(TranslationBase.of(context).erConsultFee, textAlign: TextAlign.center, style: TextStyle(fontSize: 14.0, fontWeight: FontWeight.bold, color: Colors.white)), ), Container( decoration: BoxDecoration( @@ -109,34 +96,16 @@ class _LiveCarePaymentDialogState extends State { child: Table( children: [ TableRow(children: [ - TableCell( - child: _getNormalText( - TranslationBase.of(context).patientShareToDo)), - TableCell( - child: _getNormalText( - widget.getERAppointmentFeesList.amount + - " " + - widget.getERAppointmentFeesList.currency)), + TableCell(child: _getNormalText(TranslationBase.of(context).patientShareToDo)), + TableCell(child: _getNormalText(widget.getERAppointmentFeesList.amount! + " " + widget.getERAppointmentFeesList.currency!)), ]), TableRow(children: [ - TableCell( - child: _getNormalText( - TranslationBase.of(context).patientTaxToDo)), - TableCell( - child: _getNormalText( - widget.getERAppointmentFeesList.tax + - " " + - widget.getERAppointmentFeesList.currency)), + TableCell(child: _getNormalText(TranslationBase.of(context).patientTaxToDo)), + TableCell(child: _getNormalText(widget.getERAppointmentFeesList.tax! + " " + widget.getERAppointmentFeesList.currency!)), ]), TableRow(children: [ - TableCell( - child: _getMarginText(TranslationBase.of(context) - .patientShareTotalToDo)), - TableCell( - child: _getMarginText( - widget.getERAppointmentFeesList.total + - " " + - widget.getERAppointmentFeesList.currency)), + TableCell(child: _getMarginText(TranslationBase.of(context).patientShareTotalToDo)), + TableCell(child: _getMarginText(widget.getERAppointmentFeesList.total! + " " + widget.getERAppointmentFeesList.currency!)), ]), ], ), @@ -147,17 +116,15 @@ class _LiveCarePaymentDialogState extends State { borderRadius: new BorderRadius.all( const Radius.circular(5.0), ), - color: Colors.green[200].withOpacity(0.5)), + color: Colors.green[200]!.withOpacity(0.5)), margin: EdgeInsets.only(top: 20.0), child: Row( children: [ Image.asset("assets/images/new-design/alert-triangle.png"), Container( - margin: EdgeInsets.only(left: 10.0), + margin: EdgeInsets.only(left: 10.0, right: 10.0), width: MediaQuery.of(context).size.width * 0.55, - child: Text( - "If you're Insurance patient, you have only have to pay the co-payment", - style: TextStyle(fontSize: 13.0)), + child: Text(TranslationBase.of(context).insuredPatient, style: TextStyle(fontSize: 13.0)), ), ], ), @@ -170,23 +137,17 @@ class _LiveCarePaymentDialogState extends State { child: new Radio( value: 1, groupValue: _selected, - onChanged: onRadioChanged, + onChanged:(val){ + onRadioChanged(val!); + }, ), ), Container( child: new Text( - 'I Accept the Terms And Conditions', + TranslationBase.of(context).iAcceptTerms, style: new TextStyle(fontSize: 14.0), ), ), -// Container( -//// alignment: Alignment.centerRight, -// child: new Text( -// 'Click Here', -// textAlign: TextAlign.end, -// style: new TextStyle(fontSize: 16.0), -// ), -// ), ], ), ), @@ -195,21 +156,13 @@ class _LiveCarePaymentDialogState extends State { color: Colors.grey[400], ), Container( - alignment: Alignment.center, margin: EdgeInsets.only(top: 10.0), child: new Text( - 'You can pay by the following Options:', - textAlign: TextAlign.center, + TranslationBase.of(context).upComingPayOption, style: new TextStyle(fontSize: 14.0), ), ), - Container( - alignment: Alignment.center, - margin: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 5.0), - child: Image.asset( - "assets/images/new-design/payment_options_invoice_confirmation.png", - width: 300), - ), + Container(margin: EdgeInsets.fromLTRB(10.0, 5.0, 10.0, 5.0), child: getPaymentMethods()), Divider( thickness: 1.0, color: Colors.grey[400], @@ -226,24 +179,21 @@ class _LiveCarePaymentDialogState extends State { Navigator.pop(context, false); }, child: Container( - child: Text("Cancel", - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 18.0, color: Colors.red[700])), + child: Text(TranslationBase.of(context).cancel, textAlign: TextAlign.center, style: TextStyle(fontSize: 18.0, color: Colors.red[700])), ), ), ), Expanded( child: InkWell( onTap: () { - if(_selected == 0) { - AppToast.showErrorToast(message: "Please accept terms & conditions to continue"); + if (_selected == 0) { + AppToast.showErrorToast(message: TranslationBase.of(context).pleaseAcceptTerms); } else { Navigator.pop(context, true); } }, child: Container( - child: Text("Ok", + child: Text(TranslationBase.of(context).ok, textAlign: TextAlign.center, style: TextStyle( fontSize: 18.0, @@ -255,13 +205,13 @@ class _LiveCarePaymentDialogState extends State { ), ), ], - ), + )), ), ), ); } - void onRadioChanged(int value) { + onRadioChanged(int value) { setState(() { _selected = value; }); @@ -270,27 +220,14 @@ class _LiveCarePaymentDialogState extends State { _getNormalText(text) { return Container( margin: EdgeInsets.only(top: 10.0, right: 10.0), - child: Text(text, - textAlign: TextAlign.end, - style: TextStyle( - fontSize: 14, - fontFamily: 'Open-Sans', - letterSpacing: 0.5, - color: Colors.black)), + 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.end, - style: TextStyle( - fontSize: 14, - fontFamily: 'Open-Sans', - letterSpacing: 0.5, - fontWeight: FontWeight.bold, - color: Colors.black)), + 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/LiveCarePendingRequest.dart b/lib/pages/livecare/widgets/LiveCarePendingRequest.dart index 839fb02c..9eb5b9f9 100644 --- a/lib/pages/livecare/widgets/LiveCarePendingRequest.dart +++ b/lib/pages/livecare/widgets/LiveCarePendingRequest.dart @@ -1,18 +1,24 @@ import 'package:circular_countdown_timer/circular_countdown_timer.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/FamilyFiles/PatientERVirtualHistoryResponse.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/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/my_rich_text.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:url_launcher/url_launcher.dart'; class LiveCarePendingRequest extends StatefulWidget { - ErRequestHistoryList pendingERRequestHistoryList; + ErRequestHistoryList? pendingERRequestHistoryList; final Function getLiveCareHistory; - LiveCarePendingRequest( - {@required this.getLiveCareHistory, this.pendingERRequestHistoryList}); + LiveCarePendingRequest({required this.getLiveCareHistory, this.pendingERRequestHistoryList}); @override _LiveCarePendingRequestState createState() => _LiveCarePendingRequestState(); @@ -27,119 +33,92 @@ class _LiveCarePendingRequestState extends State { @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); return Container( - decoration: BoxDecoration( - border: Border.all(color: Colors.grey[300]), - borderRadius: BorderRadius.circular(10), - color: Colors.white, - shape: BoxShape.rectangle, - ), - margin: EdgeInsets.all(15.0), + margin: EdgeInsets.fromLTRB(21, 21, 21, 12), padding: EdgeInsets.all(10.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, - children: [ - Container( - child: Text("In Progress:", - style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), - ), - Container( - alignment: Alignment.center, - margin: EdgeInsets.only(top: 10.0), - child: Text("Estimated Waiting Time: ", - style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold)), - ), - Container( - transform: Matrix4.translationValues(0.0, -50.0, 0.0), - alignment: Alignment.center, - child: CircularCountDownTimer( - duration: - widget.pendingERRequestHistoryList.watingtimeInteger * 60, - width: MediaQuery.of(context).size.width / 3, - height: MediaQuery.of(context).size.height / 3, - color: Colors.white, - fillColor: Colors.green[700], - strokeWidth: 15.0, - textStyle: TextStyle( - fontSize: 22.0, - color: Colors.black87, - fontWeight: FontWeight.bold), - isReverse: true, - isTimerTextShown: true, - onComplete: () { - print('Countdown Ended'); - }, - ), - ), - Container( - transform: Matrix4.translationValues(0.0, -60.0, 0.0), - child: Divider( - color: Colors.grey[500], - thickness: 0.7, - ), - ), + children: [ Container( - transform: Matrix4.translationValues(0.0, -50.0, 0.0), - child: Text("Requested date:", - style: TextStyle(fontSize: 14.0, fontWeight: FontWeight.bold)), - ), - Container( - transform: Matrix4.translationValues(0.0, -30.0, 0.0), - child: Text( - DateUtil.getDateFormatted( - widget.pendingERRequestHistoryList.arrivalTime), - style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold)), - ), - Container( - transform: Matrix4.translationValues(0.0, -20.0, 0.0), - padding: EdgeInsets.all(7.0), - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.all(Radius.circular(5)), - color: Colors.red[800], - ), - margin: EdgeInsets.only(top: 5.0, bottom: 5.0), - child: Text(widget.pendingERRequestHistoryList.stringCallStatus, - style: TextStyle(fontSize: 14.0, color: Colors.white)), - ), - Container( - transform: Matrix4.translationValues(0.0, 0.0, 0.0), - child: Divider( - color: Colors.grey[500], - thickness: 0.7, + width: MediaQuery.of(context).size.width, + decoration: cardRadius(15.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + padding: const EdgeInsets.fromLTRB(16, 21, 16, 23), + child: Text(TranslationBase.of(context).waitingTime, style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.w600, letterSpacing: -0.64)), + ), + Container( + height: MediaQuery.of(context).size.height * 0.25, + transform: Matrix4.translationValues(0.0, -10.0, 0.0), + alignment: Alignment.center, + child: CircularCountDownTimer( + duration: widget.pendingERRequestHistoryList!.watingtimeInteger! * 60, + width: MediaQuery.of(context).size.width / 2, + height: MediaQuery.of(context).size.height / 2, + ringColor: Colors.white, + fillColor: CustomColors.green, + strokeWidth: 7.0, + textStyle: TextStyle(fontSize: 32.0, color: Color(0xff2E303A), fontWeight: FontWeight.w400), + isReverse: true, + isTimerTextShown: true, + onComplete: () { + print('Countdown Ended'); + }, + ), + ), + ], ), ), Container( - alignment: Alignment.center, - transform: Matrix4.translationValues(0.0, 10.0, 0.0), - child: Text( - "Your turn is after " + - widget.pendingERRequestHistoryList.patCount.toString() + - " Patients", - style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), - ), - Container( - transform: Matrix4.translationValues(0.0, 130.0, 0.0), - alignment: Alignment.bottomCenter, + margin: const EdgeInsets.fromLTRB(0, 12, 0, 0), + padding: const EdgeInsets.fromLTRB(16, 21, 16, 12), width: MediaQuery.of(context).size.width, - child: ButtonTheme( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10.0), - ), - minWidth: MediaQuery.of(context).size.width, - height: 45.0, - child: RaisedButton( - color: Colors.red[800], - textColor: Colors.white, - disabledTextColor: Colors.white, - disabledColor: new Color(0xFFbcc2c4), - onPressed: () { - cancelLiveCareRequest(); - }, - child: Text(TranslationBase.of(context).cancel, - style: TextStyle(fontSize: 18.0)), - ), + decoration: cardRadius(15.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + decoration: cardRadius(15.0, color: Color(0xffCC9B14)), + padding: const EdgeInsets.all(5.0), + child: Text(widget.pendingERRequestHistoryList!.stringCallStatus!, style: TextStyle(fontSize: 10.0, fontWeight: FontWeight.w600, color: Colors.white, letterSpacing: -0.4)), + ), + Container( + padding: const EdgeInsets.all(5.0), + child: MyRichText(TranslationBase.of(context).requestedDateLiveCare, + DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(widget.pendingERRequestHistoryList!.arrivalTime!)), projectViewModel.isArabic), + ), + Container( + padding: const EdgeInsets.all(5.0), + child: Text(TranslationBase.of(context).yourTurn + " " + widget.pendingERRequestHistoryList!.patCount.toString() + " " + TranslationBase.of(context).patients, + style: TextStyle(fontSize: 12.0, fontWeight: FontWeight.w600, letterSpacing: -0.48)), + ), + // Row( + // children: [ + // Container( + // padding: const EdgeInsets.all(5.0), + // child: Text(TranslationBase.of(context).liveCareSupportContact, style: TextStyle(fontSize: 12.0, fontWeight: FontWeight.w600, letterSpacing: -0.48)), + // ), + // Directionality(textDirection: TextDirection.ltr, child: Text("011 525 9553", style: TextStyle(fontSize: 12.0, fontWeight: FontWeight.w600, letterSpacing: -0.48))) + // ], + // ), + mHeight(12.0), + Container( + child: DefaultButton(TranslationBase.of(context).callLiveCareSupport, () { + launchUrl(Uri.parse("tel://" + "011 525 9553")); + // cancelLiveCareRequest(); + }), + ), + // DefaultButton( + // TranslationBase.of(context).cancel, + // () { + // cancelLiveCareRequest(); + // }, + // ), + ], ), ), ], @@ -147,15 +126,14 @@ class _LiveCarePendingRequestState extends State { ); } + callLiveCareSupport() {} + cancelLiveCareRequest() { LiveCareService service = new LiveCareService(); GifLoaderDialogUtils.showMyDialog(context); - service - .cancelLiveCareRequest(widget.pendingERRequestHistoryList.vCID, context) - .then((res) { + service.cancelLiveCareRequest(widget.pendingERRequestHistoryList!.vCID!, context).then((res) { GifLoaderDialogUtils.hideDialog(context); - AppToast.showSuccessToast( - message: "LiveCare request cancelled successfully"); + AppToast.showSuccessToast(message: "LiveCare request cancelled successfully"); widget.getLiveCareHistory(); }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); diff --git a/lib/pages/livecare/widgets/clinic_card.dart b/lib/pages/livecare/widgets/clinic_card.dart index 9ea12f01..5c5c4aaa 100644 --- a/lib/pages/livecare/widgets/clinic_card.dart +++ b/lib/pages/livecare/widgets/clinic_card.dart @@ -1,29 +1,38 @@ +import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/locator.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/translations_delegate_base.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 '../clinic_timings_page.dart'; import 'ClinicTimingsDialog.dart'; // ignore: must_be_immutable class ClinicCard extends StatefulWidget { - bool isSelected; + bool? isSelected; final PatientERGetClinicsList patientERGetClinicsList; var languageID; + int? isOnline; - ClinicCard( - {this.isSelected, - this.languageID, - @required this.patientERGetClinicsList}); + ClinicCard({this.isSelected, this.languageID, this.isOnline, required this.patientERGetClinicsList}){ + + } @override _State createState() => _State(); } class _State extends State { - ClinicsServiceTimingsResponse clinicsServiceTimingsResponse; + late ClinicsServiceTimingsResponse clinicsServiceTimingsResponse; @override void initState() { @@ -33,99 +42,161 @@ 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 ? Colors.blue : Colors.white, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), + 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), + ), + 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), ), - child: Container( - width: MediaQuery.of(context).size.width * 0.75, - padding: EdgeInsets.all(12.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.0, - color: - widget.isSelected ? Colors.white : Colors.black)), - ), - ], - ), + ], + color: Colors.transparent, + ), + child: Container( + decoration: BoxDecoration( + color: widget.patientERGetClinicsList.isOnline == 1 ? CustomColors.green : CustomColors.accentColor, + borderRadius: BorderRadius.all( + Radius.circular(6.0), ), ), - InkWell( - onTap: () { - getClinicTimings(widget.patientERGetClinicsList); - }, - child: Card( - margin: EdgeInsets.fromLTRB(8.0, 10.0, 8.0, 8.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, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8), + 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: 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]), - ], + ), + 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 ? TranslationBase.of(context).onlineTag : TranslationBase.of(context).offlineTag, + style: TextStyle( + fontSize: 10, + fontWeight: FontWeight.w600, + color: widget.patientERGetClinicsList.isOnline == 1 ? CustomColors.green : CustomColors.accentColor, + letterSpacing: -0.48, + ), + ), + ], + ), + ], + ), ), - ), + 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, + ), + ) + ], + ), + ), + ), + ], ), ), - ], + ), ); } getClinicTimings(PatientERGetClinicsList patientERGetClinicsList) { + int languageID = widget.languageID == 'ar' ? 1 : 2; LiveCareService service = new LiveCareService(); GifLoaderDialogUtils.showMyDialog(context); - service - .getLivecareClinicTiming(patientERGetClinicsList.serviceID, context) - .then((res) { + service.getLivecareClinicTiming(patientERGetClinicsList!.serviceID!, languageID, context).then((res) { GifLoaderDialogUtils.hideDialog(context); if (res['MessageStatus'] == 1) { setState(() { - clinicsServiceTimingsResponse = - ClinicsServiceTimingsResponse.fromJson(res); - print(clinicsServiceTimingsResponse - .patientERGetClinicsServiceTimingsList.length); + clinicsServiceTimingsResponse = ClinicsServiceTimingsResponse.fromJson(res as Map); + 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']); @@ -134,5 +205,7 @@ class _State extends State { GifLoaderDialogUtils.hideDialog(context); print(err); }); + + locator().liveCare.livecare_clinic_schedule(clinic: patientERGetClinicsList.serviceName!); } } diff --git a/lib/pages/livecare/widgets/clinic_list.dart b/lib/pages/livecare/widgets/clinic_list.dart index 103066d5..c4b825dc 100644 --- a/lib/pages/livecare/widgets/clinic_list.dart +++ b/lib/pages/livecare/widgets/clinic_list.dart @@ -1,35 +1,60 @@ +import 'dart:developer'; +import 'dart:io'; + +import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/enum/PayfortEnums.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/main.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; +import 'package:diplomaticquarterapp/models/LiveCare/ApplePayInsertRequest.dart'; import 'package:diplomaticquarterapp/models/LiveCare/ERAppointmentFeesResponse.dart'; import 'package:diplomaticquarterapp/models/LiveCare/LiveCareClinicsListResponse.dart'; import 'package:diplomaticquarterapp/models/LiveCare/LiveCareScheduleClinicsListResponse.dart'; import 'package:diplomaticquarterapp/pages/BookAppointment/SearchResults.dart'; import 'package:diplomaticquarterapp/pages/ToDoList/payment_method_select.dart'; +import 'package:diplomaticquarterapp/pages/insurance/insurance_update_screen.dart'; +import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; +import 'package:diplomaticquarterapp/pages/livecare/livecare_call_type_select.dart'; +import 'package:diplomaticquarterapp/pages/livecare/livecare_home.dart'; import 'package:diplomaticquarterapp/pages/livecare/livecare_scheduling/schedule_clinic_card.dart'; import 'package:diplomaticquarterapp/pages/livecare/livecare_type_select.dart'; -import 'package:diplomaticquarterapp/pages/livecare/widgets/LiveCareInfoDialog.dart'; -import 'package:diplomaticquarterapp/pages/livecare/widgets/LiveCarePaymentDialog.dart'; 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/services/payfort_services/payfort_project_details_resp_model.dart'; +import 'package:diplomaticquarterapp/services/payfort_services/payfort_view_model.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/PlatformBridge.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'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/custom_text_button.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; +import 'package:diplomaticquarterapp/widgets/dragable_sheet.dart'; import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:fluttertoast/fluttertoast.dart'; +import 'package:permission_handler/permission_handler.dart'; +import 'package:provider/provider.dart'; + +import '../live_care_payment_page.dart'; class ClinicList extends StatefulWidget { final Function getLiveCareHistory; + bool isPharmacyLiveCare; + String pharmacyLiveCareQRCode; - ClinicList({@required this.getLiveCareHistory}); + ClinicList({required this.getLiveCareHistory, this.isPharmacyLiveCare = false, this.pharmacyLiveCareQRCode = ""}); @override _clinic_listState createState() => _clinic_listState(); @@ -37,72 +62,78 @@ class ClinicList extends StatefulWidget { class _clinic_listState extends State { int currentSelectedIndex = 0; - LiveCareClinicsListResponse liveCareClinicsListResponse; + late LiveCareClinicsListResponse liveCareClinicsListResponse; + + late List liveCareOnlineClinicsListResponse; + late List liveCareOfflineClinicsListResponse; - LiveCareScheduleClinicsListResponse liveCareScheduleClinicsListResponse; + late LiveCareScheduleClinicsListResponse liveCareScheduleClinicsListResponse; bool isDataLoaded = false; var languageID; var currentSelectedLiveCareType; - int selectedClinicID = 1; + late int selectedClinicID; String selectedClinicName = "-"; AppSharedPreferences sharedPref = AppSharedPreferences(); - AuthenticatedUser authUser; + late AuthenticatedUser authUser; AuthProvider authProvider = new AuthProvider(); - MyInAppBrowser browser; + late MyInAppBrowser browser; + + late dynamic liveCareClinicIDs; + + late ProjectViewModel projectViewModel; - bool isLiveCareTypeSelected = false; + String selectedPaymentMethod = ""; + String amount = ""; + + late String tamaraPaymentStatus; + late String tamaraOrderID; + late String selectedInstallmentPlan; + + String? transID; + BuildContext? localContext; + + int selectedCallType = 0; + String selectedMobileNumber = ""; @override void initState() { liveCareClinicsListResponse = new LiveCareClinicsListResponse(); - liveCareScheduleClinicsListResponse = - new LiveCareScheduleClinicsListResponse(); + + liveCareOnlineClinicsListResponse = []; + liveCareOfflineClinicsListResponse = []; + + liveCareScheduleClinicsListResponse = new LiveCareScheduleClinicsListResponse(); WidgetsBinding.instance.addPostFrameCallback((_) { - if (!isLiveCareTypeSelected) openLiveCareSelectionDialog(); + if (LiveCareHome.isLiveCareTypeSelected != true) { + openLiveCareSelectionDialog(); + } else { + setState(() { + currentSelectedLiveCareType = "immediate"; + getLiveCareClinicsList(); + }); + } }); - - getLanguageID(); super.initState(); } @override Widget build(BuildContext context) { - return SingleChildScrollView( - child: currentSelectedLiveCareType == "immediate" - ? getLiveCareImmediateClinicList() - : getLiveCareScheduleClinicList()); + projectViewModel = Provider.of(context); + localContext = context; + getLanguageID(); + return Container( + child: currentSelectedLiveCareType == "immediate" ? getLiveCareImmediateClinicList() : getLiveCareScheduleClinicList(), + ); } void startLiveCare() { - bool isError = false; - LiveCareService service = new LiveCareService(); - GifLoaderDialogUtils.showMyDialog(context); - ERAppointmentFeesResponse erAppointmentFeesResponse = - new ERAppointmentFeesResponse(); - service.getERAppointmentFees(selectedClinicID, context).then((res) { - GifLoaderDialogUtils.hideDialog(context); - if (res['HasAppointment'] == true) { - isError = true; - showLiveCareCancelDialog(res['ErrorEndUserMessage'], res); - } else { - erAppointmentFeesResponse = ERAppointmentFeesResponse.fromJson(res); - isError = false; - } - if (!isError) - getERAppointmentTime( - erAppointmentFeesResponse.getERAppointmentFeesList); - }).catchError((err) { - GifLoaderDialogUtils.hideDialog(context); - print(err); - isError = true; - AppToast.showErrorToast(message: err); - }); + makePayment(); } showLiveCareCancelDialog(String msg, res) { @@ -149,13 +180,40 @@ class _clinic_listState extends State { } getERAppointmentTime(GetERAppointmentFeesList getERAppointmentFeesList) { + int languageID = projectViewModel.isArabic ? 1 : 2; + String errorMsg = ""; LiveCareService service = new LiveCareService(); GifLoaderDialogUtils.showMyDialog(context); - service.getERAppointmentTime(selectedClinicID, context).then((res) { + service.getERAppointmentTime(selectedClinicID, widget.isPharmacyLiveCare, languageID, context).then((res) { GifLoaderDialogUtils.hideDialog(context); - print(res); - showLiveCarePaymentDialog( - getERAppointmentFeesList, res['WatingtimeInteger']); + + // getERAppointmentFeesList.isCash = false; + // getERAppointmentFeesList.isInsured = true; + // getERAppointmentFeesList.isEligible = false; + + if (getERAppointmentFeesList.isCash!) { + showLiveCarePaymentDialog(getERAppointmentFeesList, res['WatingtimeInteger']); + } else { + if (getERAppointmentFeesList.isInsured! && getERAppointmentFeesList.isEligible!) { + showLiveCarePaymentDialog(getERAppointmentFeesList, res['WatingtimeInteger']); + } else { + if (getERAppointmentFeesList.isInsured! && !getERAppointmentFeesList.isEligible!) { + errorMsg = TranslationBase.of(context).invalidEligibility; + } else { + errorMsg = TranslationBase.of(context).invalidInsurance; + } + ConfirmDialog dialog = new ConfirmDialog( + isDissmissable: false, + context: context, + confirmMessage: errorMsg, + okText: TranslationBase.of(context).updateInsuranceText, + cancelText: TranslationBase.of(context).continueCash, + okFunction: () => {openUpdateInsurance()}, + cancelFunction: () => {continueAsCash()}); + dialog.showAlertDialog(context); + } + } + // showLiveCarePaymentDialog(getERAppointmentFeesList, res['WatingtimeInteger']); }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); print(err); @@ -163,135 +221,326 @@ 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); - } + void continueAsCash() { + DoctorsListService service = new DoctorsListService(); + GifLoaderDialogUtils.showMyDialog(context); + service.convertPatientToCash(BASE_URL.contains("uat.") ? 15 : 12).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res["MessageStatus"] == 1) { + startLiveCare(); + } else { + AppToast.showErrorToast(message: res["ErrorEndUserMessage"]); } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); }); } - showLiveCareInfoDialog( - GetERAppointmentFeesList getERAppointmentFeesList) async { - if (await this.sharedPref.getObject(USER_PROFILE) != null) { - var data = AuthenticatedUser.fromJson( - await this.sharedPref.getObject(USER_PROFILE)); - setState(() { - authUser = data; - }); - } + void openUpdateInsurance() { + Navigator.pushAndRemoveUntil(context, MaterialPageRoute(builder: (context) => LandingPage()), (Route r) => false); + Navigator.push(context, FadePage(page: InsuranceUpdate())); + } - 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: LiveCareInfoDialog(), - ), - ); - }, - 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") { - addNewCallForPatientER(authUser.patientID.toString() + - "" + - DateTime.now().millisecondsSinceEpoch.toString()); + showLiveCarePaymentDialog(GetERAppointmentFeesList getERAppointmentFeesList, int waitingTime) { + navigateTo( + context, + LiveCarePatmentPage( + selectedCallType: this.selectedCallType, + getERAppointmentFeesList: getERAppointmentFeesList, + waitingTime: waitingTime, + clinicName: selectedClinicName, + isPharmaLiveCare: widget.isPharmacyLiveCare, + pharmaLiveCareClientID: widget.pharmacyLiveCareQRCode)) + .then( + (value) { + if (value != null && value) { + if (getERAppointmentFeesList.total == "0" || getERAppointmentFeesList.total == "0.0") { + addNewCallForPatientER(projectViewModel.user!.patientID.toString() + "" + DateTime.now().millisecondsSinceEpoch.toString()); + } else { + navigateToPaymentMethod(getERAppointmentFeesList, context); + } } else { - navigateToPaymentMethod(getERAppointmentFeesList, context); + Navigator.pop(context); } - } - }); + }, + ); + } + + makePayment() { + showDraggableDialog( + context, + LiveCareCallTypeSelectPage( + onSelectedMethod: (int selectedCallType, String mobileNumber) { + print(selectedCallType); + print(mobileNumber); + this.selectedCallType = selectedCallType; + selectedMobileNumber = mobileNumber; + int languageID = projectViewModel.isArabic ? 1 : 2; + bool isError = false; + LiveCareService service = new LiveCareService(); + GifLoaderDialogUtils.showMyDialog(context); + ERAppointmentFeesResponse erAppointmentFeesResponse = new ERAppointmentFeesResponse(); + service.getERAppointmentFees(selectedClinicID, widget.isPharmacyLiveCare, languageID, context).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res['HasAppointment'] == true) { + isError = true; + showLiveCareCancelDialog(res['ErrorEndUserMessage'], res); + } else { + erAppointmentFeesResponse = ERAppointmentFeesResponse.fromJson(res as Map); + isError = false; + } + if (!isError) getERAppointmentTime(erAppointmentFeesResponse.getERAppointmentFeesList!); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + isError = true; + AppToast.showErrorToast(message: err, localContext: context); + }); + projectViewModel.analytics.liveCare.livecare_immediate_consultation_clinic(clinic: selectedClinicName); + }, + ), + ); + } + + Future askVideoCallPermission() async { + if (!(await Permission.camera.request().isGranted) || !(await Permission.microphone.request().isGranted)) { + return false; + } + if (Platform.isAndroid && !(await PlatformBridge.shared().isDrawOverAppsPermissionAllowed())) { + await drawOverAppsMessageDialog(context); + return false; + } + return true; + } + + Future drawOverAppsMessageDialog(BuildContext context) async { + ConfirmDialog dialog = new ConfirmDialog( + context: context, + confirmMessage: TranslationBase.of(context).drawOverAppsPermission, + okText: TranslationBase.of(context).confirm, + cancelText: TranslationBase.of(context).cancel_nocaps, + okFunction: () async { + await PlatformBridge.shared().askDrawOverAppsPermission(); + Navigator.pop(context); + }, + cancelFunction: () => {}); + dialog.showAlertDialog(context); } - Future navigateToPaymentMethod( - GetERAppointmentFeesList getERAppointmentFeesList, context) async { + // showLiveCareInfoDialog(GetERAppointmentFeesList getERAppointmentFeesList) async { + // if (await this.sharedPref.getObject(USER_PROFILE) != null) { + // var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE)); + // setState(() { + // authUser = data; + // }); + // } + // + // 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: LiveCareInfoDialog(), + // ), + // ); + // }, + // 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") { + // addNewCallForPatientER(authUser.patientID.toString() + "" + DateTime.now().millisecondsSinceEpoch.toString()); + // } else { + // navigateToPaymentMethod(getERAppointmentFeesList, context); + // } + // } + // }); + // } + + Future navigateToPaymentMethod(GetERAppointmentFeesList getERAppointmentFeesList, context) async { AppoitmentAllHistoryResultList appo = new AppoitmentAllHistoryResultList(); appo.clinicID = selectedClinicID; appo.appointmentNo = DateTime.now().millisecondsSinceEpoch; + appo.projectID = BASE_URL.contains("uat.") ? 15 : 12; + appo.isLiveCareAppointment = false; 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)); setState(() { authUser = data; }); } - Navigator.push(context, FadePage(page: PaymentMethod())).then((value) { - print(value); + bool isPharmacyLiveCare = widget.isPharmacyLiveCare; + String pharmaLiveCareQRCodeValue = widget.pharmacyLiveCareQRCode; + + Navigator.push( + context, + FadePage( + page: PaymentMethod( + onSelectedMethod: (String metohd, [String? selectedInstallmentPlan]) { + setState(() {}); + }, + patientShare: num.parse(getERAppointmentFeesList.total!), + isFromAdvancePayment: widget.isPharmacyLiveCare, + ), + ), + ).then((value) { if (value != null) { - openPayment(value, authUser, - double.parse(getERAppointmentFeesList.total), appo); + selectedPaymentMethod = value[0]; + print(value); + widget.isPharmacyLiveCare = isPharmacyLiveCare; + widget.pharmacyLiveCareQRCode = pharmaLiveCareQRCodeValue; + if (value != null) { + if (selectedPaymentMethod == "ApplePay") { + if (projectViewModel.havePrivilege(103)) { + startApplePay(appo, getERAppointmentFeesList.total!); + } else { + openPayment(value, authUser, num.parse(getERAppointmentFeesList.total!), appo); + } + } else { + openPayment(value, authUser, num.parse(getERAppointmentFeesList.total!), appo); + } + projectViewModel.analytics.liveCare.payment_method(appointment_type: 'livecare', clinic: selectedClinicName, payment_method: value[0], payment_type: 'appointment'); + } } }); } - openPayment(String paymentMethod, AuthenticatedUser authenticatedUser, - double amount, AppoitmentAllHistoryResultList appo) { - browser = new MyInAppBrowser( - onExitCallback: onBrowserExit, - appo: appo, - onLoadStartCallback: onBrowserLoadStart); - - browser.openPaymentBrowser( - amount, - "LiveCare Payment", - Utils.getAppointmentTransID(12, appo.clinicID, appo.appointmentNo), - "12", - authenticatedUser.emailAddress, - paymentMethod, - authenticatedUser.patientType, - authenticatedUser.firstName, - authenticatedUser.patientID, - authenticatedUser, - browser, - false); + void startApplePay(AppoitmentAllHistoryResultList appo, String amount) async { + try { + transID = Utils.getAppointmentTransID(appo.projectID, appo.clinicID, appo.appointmentNo, isAddMilliseconds: false); + print("TransactionID: $transID"); + GifLoaderDialogUtils.showMyDialog(localContext!); + + LiveCareService service = new LiveCareService(); + ApplePayInsertRequest applePayInsertRequest = new ApplePayInsertRequest(); + + PayfortProjectDetailsRespModel? payfortProjectDetailsRespModel; + await localContext + ?.read() + .getProjectDetailsForPayfort(projectId: appo.projectID, serviceId: ServiceTypeEnum.liveCareAppointment.getIdFromServiceEnum(), languageID: projectViewModel.isArabic ? 1 : 2) + .then((value) { + payfortProjectDetailsRespModel = value; + }); + + applePayInsertRequest.clientRequestID = transID; + applePayInsertRequest.clinicID = appo.clinicID; + applePayInsertRequest.currency = projectViewModel.user.outSA == 1 ? "AED" : "SAR"; + // applePayInsertRequest.customerEmail = projectViewModel.authenticatedUserObject.user.emailAddress; + applePayInsertRequest.customerEmail = "CustID_${projectViewModel.user.patientID}@HMG.com"; + applePayInsertRequest.customerID = projectViewModel.user.patientID; + applePayInsertRequest.customerName = projectViewModel.user.firstName! + " " + projectViewModel.user.lastName!; + applePayInsertRequest.deviceToken = await AppSharedPreferences().getString(PUSH_TOKEN); + applePayInsertRequest.voipToken = await AppSharedPreferences().getString(ONESIGNAL_APNS_TOKEN); + applePayInsertRequest.doctorID = appo.doctorID; + applePayInsertRequest.projectID = appo.projectID.toString(); + applePayInsertRequest.serviceID = ServiceTypeEnum.liveCareAppointment.getIdFromServiceEnum().toString(); + applePayInsertRequest.channelID = 3; + applePayInsertRequest.patientID = projectViewModel.user.patientID; + applePayInsertRequest.patientTypeID = projectViewModel.user.patientType; + applePayInsertRequest.patientOutSA = projectViewModel.user.outSA; + applePayInsertRequest.appointmentDate = appo.appointmentDate; + applePayInsertRequest.appointmentNo = appo.appointmentNo; + applePayInsertRequest.orderDescription = "LiveCare Payment"; + applePayInsertRequest.liveServiceID = selectedClinicID.toString(); + applePayInsertRequest.latitude = "0.0"; + applePayInsertRequest.longitude = "0.0"; + applePayInsertRequest.amount = amount; + applePayInsertRequest.isSchedule = appo.isLiveCareAppointment! ? "1" : "0"; + applePayInsertRequest.language = projectViewModel.isArabic ? 'ar' : 'en'; + applePayInsertRequest.languageID = projectViewModel.isArabic ? 1 : 2; + applePayInsertRequest.userName = projectViewModel.user.patientID; + applePayInsertRequest.responseContinueURL = "http://hmg.com/Documents/success.html"; + applePayInsertRequest.backClickUrl = "http://hmg.com/Documents/success.html"; + applePayInsertRequest.paymentOption = "ApplePay"; + + applePayInsertRequest.isMobSDK = true; + applePayInsertRequest.merchantReference = transID; + applePayInsertRequest.merchantIdentifier = payfortProjectDetailsRespModel!.merchantIdentifier; + applePayInsertRequest.commandType = "PURCHASE"; + applePayInsertRequest.signature = payfortProjectDetailsRespModel!.signature; + applePayInsertRequest.accessCode = payfortProjectDetailsRespModel!.accessCode; + applePayInsertRequest.shaRequestPhrase = payfortProjectDetailsRespModel!.shaRequest; + applePayInsertRequest.shaResponsePhrase = payfortProjectDetailsRespModel!.shaResponse; + applePayInsertRequest.returnURL = ""; + + service.applePayInsertRequest(applePayInsertRequest, localContext!).then((res) async { + if (res["MessageStatus"] == 1) { + await localContext!.read().initiateApplePayWithPayfort( + customerName: projectViewModel.user.firstName! + " " + projectViewModel.user.lastName!, + // customerEmail: projectViewModel.authenticatedUserObject.user.emailAddress, + customerEmail: "CustID_${projectViewModel.user.patientID}@HMG.com", + orderDescription: "LiveCare Payment", + orderAmount: double.parse(amount), + merchantReference: transID, + payfortProjectDetailsRespModel: payfortProjectDetailsRespModel, + currency: projectViewModel.user.outSA == 1 ? "AED" : "SAR", + onFailed: (failureResult) async { + GifLoaderDialogUtils.hideDialog(context); + log("failureResult: ${failureResult.message.toString()}"); + AppToast.showErrorToast(message: failureResult.message.toString()); + }, + onSuccess: (successResult) async { + GifLoaderDialogUtils.hideDialog(localContext!); + log("Payfort: ${successResult.responseMessage}"); + await localContext!.read().addPayfortApplePayResponse(projectViewModel.user.patientID!, result: successResult); + checkPaymentStatus(appo); + }, + projectId: appo.projectID, + serviceTypeEnum: ServiceTypeEnum.appointmentPayment, + ); + } else { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: "An error occurred while processing your request", localContext: context); + } + }).catchError((err) { + print(err); + GifLoaderDialogUtils.hideDialog(localContext!); + AppToast.showErrorToast(message: err, localContext: context); + }); + } catch (ex) { + print(ex.toString()); + GifLoaderDialogUtils.hideDialog(localContext!); + } + } + + openPayment(List paymentMethod, AuthenticatedUser authenticatedUser, num amount, AppoitmentAllHistoryResultList appo) { + browser = new MyInAppBrowser(onExitCallback: onBrowserExit, appo: appo, onLoadStartCallback: onBrowserLoadStart, context: context); + transID = Utils.getAppointmentTransID(appo.projectID, appo.clinicID, appo.appointmentNo, isAddMilliseconds: false); + selectedPaymentMethod = paymentMethod[0]!; + selectedInstallmentPlan = paymentMethod[1] ?? "0"; + this.amount = amount.toString(); + + browser.openPaymentBrowser(amount, "LiveCare Payment", widget.isPharmacyLiveCare ? widget.pharmacyLiveCareQRCode! : transID!, "12", authenticatedUser.emailAddress!, paymentMethod[0]!, + authenticatedUser.patientType, authenticatedUser.firstName!, authenticatedUser.patientID, authenticatedUser, browser, false, "4", selectedClinicID, context, "", "", "", "", paymentMethod[1]); } onBrowserLoadStart(String url) { print("onBrowserLoadStart"); print(url); + if (selectedPaymentMethod == "TAMARA") { + if (Platform.isAndroid) { + Uri uri = new Uri.dataFromString(url); + tamaraPaymentStatus = uri.queryParameters['status']!; + tamaraOrderID = uri.queryParameters['AuthorizePaymentId']!; + } else { + Uri uri = new Uri.dataFromString(url); + tamaraPaymentStatus = uri.queryParameters['paymentStatus']!; + tamaraOrderID = uri.queryParameters['orderId']!; + } + } + MyInAppBrowser.successURLS.forEach((element) { if (url.contains(element)) { if (browser.isOpened()) browser.close(); @@ -311,27 +560,91 @@ class _clinic_listState extends State { onBrowserExit(AppoitmentAllHistoryResultList appo, bool isPaymentMade) { print("onBrowserExit Called!!!!"); - if (isPaymentMade) checkPaymentStatus(appo); + try { + if (selectedPaymentMethod == "TAMARA") { + checkTamaraPaymentStatus(transID!, appo); + // if (tamaraPaymentStatus != null && tamaraPaymentStatus.toLowerCase() == "approved") { + // updateTamaraRequestStatus("success", "14", Utils.getAppointmentTransID(appo.projectID, appo.clinicID, appo.appointmentNo), tamaraOrderID, num.parse(selectedInstallmentPlan), appo); + // } else { + // updateTamaraRequestStatus( + // "Failed", "00", Utils.getAppointmentTransID(appo.projectID, appo.clinicID, appo.appointmentNo), tamaraOrderID != null ? tamaraOrderID : "", num.parse(selectedInstallmentPlan), appo); + // } + } else { + checkPaymentStatus(appo); + } + } catch (err) { + print(err); + } + } + + checkTamaraPaymentStatus(String orderID, AppoitmentAllHistoryResultList appo) { + GifLoaderDialogUtils.showMyDialog(context); + DoctorsListService service = new DoctorsListService(); + service.getTamaraPaymentStatus(orderID).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res["status"].toString().toLowerCase() == "success") { + updateTamaraRequestStatus("success", "14", orderID, tamaraOrderID, int.parse(selectedInstallmentPlan), appo); + } else { + updateTamaraRequestStatus("Failed", "00", transID!, tamaraOrderID != null ? tamaraOrderID : "", num.parse(selectedInstallmentPlan), appo); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + + updateTamaraRequestStatus(String responseMessage, String status, String clientRequestID, String tamaraOrderID, num selectedInstallments, AppoitmentAllHistoryResultList appo) { + final currency = projectViewModel.user!.outSA == 0 ? "sar" : 'aed'; + GifLoaderDialogUtils.showMyDialog(context); + try { + DoctorsListService service = new DoctorsListService(); + service.updateTamaraRequestStatus(responseMessage, status, clientRequestID, tamaraOrderID, selectedInstallments).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (tamaraPaymentStatus != null && tamaraPaymentStatus.toLowerCase() == "approved") { + addNewCallForPatientER(transID!); + } else { + AppToast.showErrorToast(message: res['Response_Message']); + projectViewModel.analytics.liveCare.livecare_immediate_consultation_payment_failed( + appointment_type: 'livecare', + payment_type: 'appointment', + payment_method: selectedPaymentMethod, + txn_amount: this.amount, + txn_currency: currency, + error_message: res['Response_Message']); + } + }).catchError((err) { + print(err); + AppToast.showErrorToast(message: err); + GifLoaderDialogUtils.hideDialog(context); + }); + } catch (err) { + print(err); + } } checkPaymentStatus(AppoitmentAllHistoryResultList appo) { + String amount; + String payment_method; + final currency = projectViewModel.user!.outSA == 0 ? "sar" : 'aed'; DoctorsListService service = new DoctorsListService(); GifLoaderDialogUtils.showMyDialog(context); - service - .checkPaymentStatus( - Utils.getAppointmentTransID( - appo.projectID, appo.clinicID, appo.appointmentNo), - context) - .then((res) { + service.checkPaymentStatus(widget.isPharmacyLiveCare ? widget.pharmacyLiveCareQRCode! : transID!, widget.isPharmacyLiveCare, context).then((res) { GifLoaderDialogUtils.hideDialog(context); - print("Printing Payment Status Reponse!!!!"); - print(res); String paymentInfo = res['Response_Message']; + amount = res['Amount'].toString(); + payment_method = res['PaymentMethod']; if (paymentInfo == 'Success') { - addNewCallForPatientER(Utils.getAppointmentTransID( - appo.projectID, appo.clinicID, appo.appointmentNo)); + addNewCallForPatientER(widget.isPharmacyLiveCare! ? widget.pharmacyLiveCareQRCode! : transID!); } else { AppToast.showErrorToast(message: res['Response_Message']); + projectViewModel.analytics.liveCare.livecare_immediate_consultation_payment_failed( + appointment_type: 'livecare', payment_type: 'appointment', payment_method: selectedPaymentMethod, txn_amount: this.amount, txn_currency: currency, error_message: res['Response_Message']); + Navigator.pushAndRemoveUntil( + context, + MaterialPageRoute(builder: (context) => LandingPage()), + (Route route) => false, + ); } }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); @@ -342,13 +655,11 @@ class _clinic_listState extends State { addNewCallForPatientER(String clientRequestID) { LiveCareService service = new LiveCareService(); + int languageID = projectViewModel.isArabic ? 1 : 2; GifLoaderDialogUtils.showMyDialog(context); - service - .addNewCallForPatientER(selectedClinicID, clientRequestID, context) - .then((res) { + service.addNewCallForPatientER(selectedClinicID, clientRequestID, selectedCallType, languageID, widget.isPharmacyLiveCare, context).then((res) { GifLoaderDialogUtils.hideDialog(context); - AppToast.showSuccessToast( - message: "New Call has been added successfully"); + AppToast.showSuccessToast(message: "New Call has been added successfully"); widget.getLiveCareHistory(); }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); @@ -358,25 +669,36 @@ class _clinic_listState extends State { } getLanguageID() async { - languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + languageID = projectViewModel.isArabic ? "ar" : "en"; + // languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); } getLiveCareClinicsList() { isDataLoaded = false; LiveCareService service = new LiveCareService(); GifLoaderDialogUtils.showMyDialog(context); - service.getLivecareClinics(context).then((res) { + service.getLivecareClinics(languageID == 'ar' ? 1 : 2, context).then((res) { GifLoaderDialogUtils.hideDialog(context); print(res['PatientER_GetClinicsList'].length); if (res['MessageStatus'] == 1) { setState(() { - liveCareClinicsListResponse = - LiveCareClinicsListResponse.fromJson(res); - print(liveCareClinicsListResponse.patientERGetClinicsList.length); - selectedClinicID = - liveCareClinicsListResponse.patientERGetClinicsList[0].serviceID; - selectedClinicName = liveCareClinicsListResponse - .patientERGetClinicsList[0].serviceName; + liveCareOnlineClinicsListResponse.clear(); + liveCareClinicsListResponse = LiveCareClinicsListResponse.fromJson(res as Map); + + liveCareClinicsListResponse.patientERGetClinicsList!.forEach((clinic) { + if (clinic.isOnline == 1) { + liveCareOnlineClinicsListResponse.add(clinic); + } else { + liveCareOfflineClinicsListResponse.add(clinic); + } + }); + if (liveCareClinicIDs != null) { + selectedClinicID = int.parse(liveCareClinicIDs.split("-")[2]); + selectedClinicName = liveCareClinicIDs.split("-")[0]; + } else { + selectedClinicID = liveCareClinicsListResponse.patientERGetClinicsList![0].serviceID!; + selectedClinicName = liveCareClinicsListResponse.patientERGetClinicsList![0].serviceName!; + } isDataLoaded = true; }); } else { @@ -385,7 +707,6 @@ class _clinic_listState extends State { } }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); - AppToast.showErrorToast(message: err); print(err); }); } @@ -399,14 +720,9 @@ class _clinic_listState extends State { print(res['ClinicsHaveScheduleList'].length); if (res['MessageStatus'] == 1) { setState(() { - liveCareScheduleClinicsListResponse = - LiveCareScheduleClinicsListResponse.fromJson(res); - print(liveCareScheduleClinicsListResponse - .clinicsHaveScheduleList.length); - selectedClinicID = liveCareScheduleClinicsListResponse - .clinicsHaveScheduleList[0].serviceID; - selectedClinicName = liveCareScheduleClinicsListResponse - .clinicsHaveScheduleList[0].clinicDesc; + liveCareScheduleClinicsListResponse = LiveCareScheduleClinicsListResponse.fromJson(res as Map); + selectedClinicID = liveCareScheduleClinicsListResponse.clinicsHaveScheduleList![0].serviceID!; + selectedClinicName = liveCareScheduleClinicsListResponse.clinicsHaveScheduleList![0].clinicDesc!; isDataLoaded = true; }); } else { @@ -415,112 +731,121 @@ class _clinic_listState extends State { } }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); - AppToast.showErrorToast(message: err); + AppToast.showErrorToast(message: err, localContext: context); print(err); }); } - openLiveCareSelectionDialog() { - Navigator.of(context) - .push(new MaterialPageRoute( - builder: (BuildContext context) { - return LiveCareTypeSelect(); - }, - fullscreenDialog: true)) - .then((value) { - if (value == null) { - Navigator.pop(context); - } else { - print(value); - isLiveCareTypeSelected = true; - if (value == "immediate") { - setState(() { - currentSelectedLiveCareType = "immediate"; - }); - getLiveCareClinicsList(); - } - if (value == "schedule") { - setState(() { - currentSelectedLiveCareType = "schedule"; - }); - getLiveCareScheduleClinicsList(); + openLiveCareSelectionDialog() async { + liveCareClinicIDs = await sharedPref.getString(LIVECARE_CLINIC_DATA); + sharedPref.remove(LIVECARE_CLINIC_DATA); + if (liveCareClinicIDs != null) { + selectedClinicID = int.parse(liveCareClinicIDs.split("-")[2]); + setState(() { + currentSelectedLiveCareType = "immediate"; + }); + // if(widget.isPharmacyLiveCare) { + // + // } else { + getLiveCareClinicsList(); + startLiveCare(); + // } + } else { + Navigator.of(context) + .push(new MaterialPageRoute( + builder: (BuildContext context) { + return LiveCareTypeSelect(); + }, + fullscreenDialog: true)) + .then((value) async { + if (value == null) { + Navigator.pop(context); + } else if (value.contains("/")) { + widget.isPharmacyLiveCare = true; + widget.pharmacyLiveCareQRCode = value.split("/")[1]; + liveCareClinicIDs = await sharedPref.getString(LIVECARE_CLINIC_DATA); + selectedClinicID = 1; + selectedClinicName = TranslationBase.of(context).pharmaLiveCare; + sharedPref.remove(LIVECARE_CLINIC_DATA); + startLiveCare(); + } else { + print(value); + if (value == "immediate") { + setState(() { + LiveCareHome.isLiveCareTypeSelected = true; + currentSelectedLiveCareType = "immediate"; + }); + getLiveCareClinicsList(); + } + if (value == "schedule") { + setState(() { + LiveCareHome.isLiveCareTypeSelected = true; + currentSelectedLiveCareType = "schedule"; + }); + getLiveCareScheduleClinicsList(); + } } - } - }); + }); + } } Widget getLiveCareScheduleClinicList() { return Column( children: [ isDataLoaded - ? Container( - height: MediaQuery.of(context).size.height * 0.7, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ -// Container( -// margin: EdgeInsets.all(15.0), -// child: Text("Online Clinics: ", -// style: TextStyle( -// fontSize: 20.0, fontWeight: FontWeight.bold)), -// ), - 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, - ), - ], + ? 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, 10.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, - disabledTextColor: Colors.white, - disabledColor: new Color(0xFFbcc2c4), - onPressed: startScheduleLiveCare, - child: Text("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: CustomTextButton( + backgroundColor: CustomColors.accentColor, + disabledForegroundColor: Color(0xFFbcc2c4).withOpacity(0.38), + disabledBackgroundColor: Color(0xFFbcc2c4).withOpacity(0.12), + elevation: 0, + onPressed: startScheduleLiveCare, + child: Text(TranslationBase.of(context).start, style: TextStyle(fontSize: 18.0, color: Colors.white)), ), ), ) @@ -533,73 +858,63 @@ class _clinic_listState extends State { return Column( children: [ isDataLoaded - ? Container( - height: MediaQuery.of(context).size.height * 0.7, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - margin: EdgeInsets.all(15.0), - child: Text("Online Clinics: ", - 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, - itemBuilder: (context, index) { - return InkWell( - onTap: () { - updateSelectedIndex(liveCareClinicsListResponse - .patientERGetClinicsList[index]); - }, - child: ClinicCard( - isSelected: selectedClinicID == - liveCareClinicsListResponse - .patientERGetClinicsList[index] - .serviceID - ? true - : false, - patientERGetClinicsList: liveCareClinicsListResponse - .patientERGetClinicsList[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, + ), + ); + }, + ), + 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: 10.0, - ), - ], + ); + }, + ), + Container( + height: 10.0, + ), + ], + )), ), ) : 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, 10.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, - disabledTextColor: Colors.white, - disabledColor: new Color(0xFFbcc2c4), - onPressed: startLiveCare, - child: Text("Start", style: TextStyle(fontSize: 18.0)), - ), - ), + ? Container( + color: Colors.white, + width: double.infinity, + padding: EdgeInsets.all(16), + child: DefaultButton( + TranslationBase.of(context).start, + () { + startLiveCare(); + }, ), ) : Container(), @@ -608,14 +923,12 @@ class _clinic_listState extends State { } void startScheduleLiveCare() { + int languageID = projectViewModel.isArabic ? 1 : 2; List doctorsList = []; LiveCareService service = new LiveCareService(); GifLoaderDialogUtils.showMyDialog(context); - List _patientDoctorAppointmentListHospital = - List(); - service - .getLiveCareScheduledDoctorList(context, selectedClinicID) - .then((res) { + List _patientDoctorAppointmentListHospital = []; + service.getLiveCareScheduledDoctorList(context, selectedClinicID, languageID).then((res) { GifLoaderDialogUtils.hideDialog(context); if (res['MessageStatus'] == 1) { setState(() { @@ -625,68 +938,48 @@ class _clinic_listState extends State { }); doctorsList.forEach((element) { - List doctorByHospital = - _patientDoctorAppointmentListHospital - .where( - (elementClinic) => - elementClinic.filterName == element.projectName, - ) - .toList(); + List doctorByHospital = _patientDoctorAppointmentListHospital + .where( + (elementClinic) => elementClinic.filterName == element.projectName, + ) + .toList(); if (doctorByHospital.length != 0) { - _patientDoctorAppointmentListHospital[ - _patientDoctorAppointmentListHospital - .indexOf(doctorByHospital[0])] - .patientDoctorAppointmentList - .add(element); + _patientDoctorAppointmentListHospital[_patientDoctorAppointmentListHospital.indexOf(doctorByHospital[0])].patientDoctorAppointmentList!.add(element); } else { - _patientDoctorAppointmentListHospital.add( - PatientDoctorAppointmentList( - filterName: element.projectName, - distanceInKMs: - element.projectDistanceInKiloMeters.toString(), - patientDoctorAppointment: element)); + _patientDoctorAppointmentListHospital + .add(PatientDoctorAppointmentList(filterName: element.projectName, distanceInKMs: element.projectDistanceInKiloMeters.toString(), patientDoctorAppointment: element)); } }); } else {} }); this.sharedPref.setBool(IS_LIVECARE_APPOINTMENT, true); - navigateToSearchResults( - context, doctorsList, _patientDoctorAppointmentListHospital); + navigateToSearchResults(context, doctorsList, _patientDoctorAppointmentListHospital); } else {} }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); - AppToast.showErrorToast(message: err); + AppToast.showErrorToast(message: err, localContext: context); print(err); }); + projectViewModel.analytics.liveCare.livecare_schedule_video_call_clinic(clinic: selectedClinicName); } - Future navigateToSearchResults( - context, - List docList, - List - patientDoctorAppointmentListHospital) async { - Navigator.push( - context, - FadePage( - page: SearchResults( - doctorsList: docList, - isLiveCareAppointment: true, - patientDoctorAppointmentListHospital: - patientDoctorAppointmentListHospital))); + Future navigateToSearchResults(context, List docList, List patientDoctorAppointmentListHospital) async { + Navigator.push(context, + FadePage(page: SearchResults(doctorsList: docList, isLiveCareAppointment: false, patientDoctorAppointmentListHospital: patientDoctorAppointmentListHospital, isDoctorSearchResult: false))); } updateSelectedIndex(PatientERGetClinicsList patientERGetClinicsList) { setState(() { - selectedClinicID = patientERGetClinicsList.serviceID; - selectedClinicName = patientERGetClinicsList.serviceName; + selectedClinicID = patientERGetClinicsList.serviceID!; + selectedClinicName = patientERGetClinicsList.serviceName!; }); } updateSelectedScheduleIndex(ClinicsHaveScheduleList patientERGetClinicsList) { setState(() { - selectedClinicID = patientERGetClinicsList.serviceID; - selectedClinicName = patientERGetClinicsList.clinicDesc; + selectedClinicID = patientERGetClinicsList.serviceID!; + selectedClinicName = patientERGetClinicsList.clinicDesc!; }); } } diff --git a/lib/pages/livecare/widgets/livecare_logs.dart b/lib/pages/livecare/widgets/livecare_logs.dart index a7f7fdc0..92e1f0ab 100644 --- a/lib/pages/livecare/widgets/livecare_logs.dart +++ b/lib/pages/livecare/widgets/livecare_logs.dart @@ -1,11 +1,12 @@ import 'package:diplomaticquarterapp/models/FamilyFiles/PatientERVirtualHistoryResponse.dart'; import 'package:diplomaticquarterapp/pages/livecare/widgets/LiveCareHistoryCard.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:flutter/material.dart'; class LiveCareLogs extends StatefulWidget { List erRequestHistoryList; - LiveCareLogs({@required this.erRequestHistoryList}); + LiveCareLogs({required this.erRequestHistoryList}); @override _LiveCareLogsState createState() => _LiveCareLogsState(); @@ -20,21 +21,25 @@ class _LiveCareLogsState extends State { @override Widget build(BuildContext context) { return SingleChildScrollView( - child: Container( - child: ListView.builder( - scrollDirection: Axis.vertical, - shrinkWrap: true, - physics: ScrollPhysics(), - padding: EdgeInsets.all(0.0), - itemCount: widget.erRequestHistoryList.length, - itemBuilder: (context, index) { - return widget.erRequestHistoryList[index].callStatus < 4 - ? Container() - : LiveCareHistoryCard( - erRequestHistoryList: widget.erRequestHistoryList[index]); - }, - ), - ), + child: widget.erRequestHistoryList.length > 0 + ? Container( + child: ListView.builder( + scrollDirection: Axis.vertical, + shrinkWrap: true, + physics: ScrollPhysics(), + padding: EdgeInsets.all(0.0), + itemCount: widget.erRequestHistoryList.length, + itemBuilder: (context, index) { + return widget.erRequestHistoryList[index].callStatus! < 4 + ? Container() + : LiveCareHistoryCard( + erRequestHistoryList: widget.erRequestHistoryList[index], + isFirstOrLast: index==0?0:(index==widget.erRequestHistoryList.length-1)?1:2, + ); + }, + ), + ) + : Container(margin: EdgeInsets.only(top: 200.0), child: getNoDataWidget(context)), ); } } diff --git a/lib/pages/login/confirm-login.dart b/lib/pages/login/confirm-login.dart index 1952de64..cc3d1fa9 100644 --- a/lib/pages/login/confirm-login.dart +++ b/lib/pages/login/confirm-login.dart @@ -1,16 +1,25 @@ +import 'package:diplomaticquarterapp/analytics/flows/login_registration.dart'; +import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/config/size_config.dart'; import 'package:diplomaticquarterapp/core/service/AuthenticatedUserObject.dart'; import 'package:diplomaticquarterapp/core/viewModels/appointment_rate_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/extensions/string_extensions.dart'; import 'package:diplomaticquarterapp/locator.dart'; +import 'package:diplomaticquarterapp/main.dart'; import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart'; import 'package:diplomaticquarterapp/models/Authentication/check_activation_code_response.dart'; import 'package:diplomaticquarterapp/models/Authentication/check_paitent_authentication_req.dart'; import 'package:diplomaticquarterapp/models/Authentication/select_device_imei_res.dart'; import 'package:diplomaticquarterapp/models/Authentication/send_activation_request.dart'; +import 'package:diplomaticquarterapp/models/InPatientServices/get_admission_info_response_model.dart'; +import 'package:diplomaticquarterapp/models/InPatientServices/get_admission_request_info_response_model.dart'; import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; +import 'package:diplomaticquarterapp/pages/login/login.dart'; +import 'package:diplomaticquarterapp/pages/login/register_new.dart'; +import 'package:diplomaticquarterapp/pages/login/user-login-agreement-page.dart'; import 'package:diplomaticquarterapp/pages/rateAppointment/rate_appointment_doctor.dart'; import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; @@ -20,22 +29,29 @@ import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/uitl/whatsapp_method_channel.dart'; import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/card/rounded_container.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; -import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/otp/sms-popup.dart'; -import 'package:diplomaticquarterapp/widgets/text/app_texts_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:flutter_svg/flutter_svg.dart'; import 'package:intl/intl.dart'; import 'package:local_auth/local_auth.dart'; import 'package:provider/provider.dart'; -// import 'package:smart_progress_bar/smart_progress_bar.dart'; +// import 'package:local_auth_ios/types/auth_messages_ios.dart'; class ConfirmLogin extends StatefulWidget { + final Function? changePageViewIndex; + final fromRegistration; + final bool isDubai; + + const ConfirmLogin({Key? key, this.changePageViewIndex, this.fromRegistration = false, this.isDubai = false}) : super(key: key); + @override _ConfirmLogin createState() => _ConfirmLogin(); } @@ -43,14 +59,13 @@ class ConfirmLogin extends StatefulWidget { class _ConfirmLogin extends State { final LocalAuthentication auth = LocalAuthentication(); var _availableBiometrics; - var sharedPref = new AppSharedPreferences(); - bool authenticated; - final authService = new AuthProvider(); - PharmacyModuleViewModel pharmacyModuleViewModel = - locator(); - int mobileNumber; + var sharedPref = AppSharedPreferences(); + bool authenticated = false; + final authService = AuthProvider(); + PharmacyModuleViewModel pharmacyModuleViewModel = locator(); + late int mobileNumber; String errorMsg = ''; - SelectDeviceIMEIRES user; + SelectDeviceIMEIRES? user; bool isLoading = false; var registerd_data; bool isMoreOption = false; @@ -66,24 +81,26 @@ class _ConfirmLogin extends State { var lastLogin; - int selectedOption; + late int selectedOption; bool onlySMSBox = false; var userData; - static BuildContext _context; + late BuildContext _context; + + late bool _loading; - static bool _loading; + int fingrePrintBefore = 0; - int fingrePrintBefore; + AuthenticatedUserObject authenticatedUserObject = locator(); + AppointmentRateViewModel appointmentRateViewModel = locator(); + late ProjectViewModel projectViewModel; - AuthenticatedUserObject authenticatedUserObject = - locator(); - AppointmentRateViewModel appointmentRateViewModel = - locator(); - ProjectViewModel projectViewModel; + late ToDoCountProviderModel toDoProvider; - ToDoCountProviderModel toDoProvider; + var dob; + int isHijri = 0; + var healthId; @override void initState() { @@ -96,178 +113,196 @@ class _ConfirmLogin extends State { Widget build(BuildContext context) { projectViewModel = Provider.of(context); toDoProvider = Provider.of(context); - return AppScaffold( - appBarTitle: TranslationBase.of(context).confirm, - isShowAppBar: true, - isShowDecPage: false, - body: SingleChildScrollView( - child: Container( - padding: EdgeInsets.all(20), - height: SizeConfig.realScreenHeight * .9, - width: SizeConfig.realScreenWidth, - child: Column( - children: [ - user != null && isMoreOption == false - ? Column( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, + return Scaffold( + backgroundColor: Color(0xfff8f8f8), + resizeToAvoidBottomInset: false, + appBar: AppBar( + backgroundColor: Colors.transparent, + leading: IconButton( + icon: Icon(Icons.arrow_back_ios), + color: Color(0xff2B353E), + onPressed: () => Navigator.pop(context), + ), + ), + body: Padding( + padding: EdgeInsets.only(bottom: 20, left: 21, right: 21), + child: Column( + children: [ + Expanded( + child: ListView( + padding: EdgeInsets.zero, + physics: BouncingScrollPhysics(), + children: [ + SizedBox(height: 12), + if (user != null && isMoreOption == false) + Column( + mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Image.asset( - 'assets/images/habib-logo.png', - height: 90, - width: 90, + children: [ + Text( + TranslationBase.of(context).welcomeBack, + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64), ), - Texts( - TranslationBase.of(context).welcomeBack + - ' ' + - user.name, - fontSize: SizeConfig.textMultiplier * 3.5, + Text( + user!.name!.toLowerCase().capitalizeFirstofEach, + style: TextStyle(fontSize: 24, fontWeight: FontWeight.w700, color: Color(0xff2B353E), height: 1, letterSpacing: -1.44), ), - SizedBox( - height: 20, - ), - Texts( + SizedBox(height: 10), + Text( TranslationBase.of(context).accountInfo, - fontSize: SizeConfig.textMultiplier * 2.5, - ), - SizedBox( - height: 20, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64, height: 25 / 16), ), - Card( - color: Colors.grey[300], - child: Row( - children: [ - Flexible( - child: ListTile( - title: Text( - TranslationBase.of(context).lastLoginAt, - textAlign: TextAlign.center, - overflow: TextOverflow.ellipsis, - ), - subtitle: Text( - user.editedOn != null - ? formatDate( - DateUtil.convertStringToDate( - user.editedOn)) - : user.createdOn != null - ? formatDate( - DateUtil.convertStringToDate( - user.createdOn)) - : '--', - overflow: TextOverflow.ellipsis, - textAlign: TextAlign.center), - )), - Flexible( - child: ListTile( - title: Text( - TranslationBase.of(context).lastLoginWith, - overflow: TextOverflow.ellipsis, - textAlign: TextAlign.center), - subtitle: Text( - getType(user.logInType, context), - overflow: TextOverflow.ellipsis, - textAlign: TextAlign.center), - )) - ], - )), - ], - ) - : Column( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Image.asset( - 'assets/images/habib-logo.png', - height: 90, - width: 90, + Container( + height: 72, + margin: EdgeInsets.only(top: 23, bottom: 23), + alignment: Alignment.center, + padding: EdgeInsets.only(left: 17, right: 12), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: Colors.white, + border: Border.all( + color: Color(0xffefefef), + width: 1, + ), ), - this.onlySMSBox == false - ? Texts( - TranslationBase.of(context).verifyLoginWith, - fontSize: SizeConfig.textMultiplier * 3.5, - textAlign: TextAlign.left, - ) - : Texts( - TranslationBase.of(context) - .verifyFingerprint2, - fontSize: SizeConfig.textMultiplier * 2.5, - textAlign: TextAlign.start, - ), - ]), - user != null && isMoreOption == false - ? Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Expanded( - child: InkWell( - onTap: () => { - authenticateUser( - 3, BiometricType.face.index) - }, - child: getButton(user.logInType))), - Expanded(child: getButton(5)) - ]) - ]) - : Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - onlySMSBox == false - ? Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Expanded(child: getButton(3)), - Expanded(child: getButton(2)) - ], - ) - : SizedBox(), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Expanded(child: getButton(1)), - Expanded(child: getButton(4)) + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + TranslationBase.of(context).lastLoginAt.toCamelCase, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64), + ), + Text( + // user!.editedOn != null + // ? DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(user!.editedOn!)) + // : + user!.createdOn != null ? DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(user!.createdOn!)) : '--', + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.48), + ), + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + TranslationBase.of(context).lastLoginWith.toCamelCase, + style: TextStyle( + fontSize: 10, + fontWeight: FontWeight.w600, + color: Color(0xff575757), + ), + ), + Text( + " " + getType(user!.logInType, context), + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + ), + ), + Expanded(child: SizedBox()), + Text( + // user!.editedOn != null + // ? DateUtil.formatDateToTimeLang( + // DateUtil.convertStringToDate( + // user!.editedOn!), + // false) + // : + user!.createdOn != null ? DateUtil.formatDateToTimeLang(DateUtil.convertStringToDate(user!.createdOn!), false) : '--', + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff575757), letterSpacing: -0.48), + ), + ], + ) ], ), - ]), - Expanded( - flex: 1, - child: Column( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - user != null - ? Row( - children: [ - Expanded( - child: DefaultButton( - TranslationBase.of(context).useAnotherAccount, - () => { - Navigator.of(context).pushNamed( - LOGIN_TYPE, - ) - }, - )), - ], - ) - : SizedBox(), - ], - ), - ) - ], - ), + ), + Text( + TranslationBase.of(context).pleaseVerify, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.64), + ), + GridView( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, crossAxisSpacing: 13, mainAxisSpacing: 9), + physics: NeverScrollableScrollPhysics(), + padding: EdgeInsets.only(top: 9), + shrinkWrap: true, + children: [ + getButton(3), + getButton(2), + getButton(1), + getButton(4), + ], + ) + ], + ) + else + Column(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ + Image.asset( + 'assets/images/habib-logo.png', + height: 90, + width: 90, + ), + SizedBox(height: 23), + this.onlySMSBox == false + ? Text( + TranslationBase.of(context).verifyLoginWith, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64, height: 25 / 16), + ) + : Text( + TranslationBase.of(context).verifyFingerprint2, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64, height: 25 / 16), + ), + SizedBox(height: 23), + Text( + TranslationBase.of(context).pleaseVerify, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.64), + ), + GridView( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, crossAxisSpacing: 13, mainAxisSpacing: 9), + physics: NeverScrollableScrollPhysics(), + padding: EdgeInsets.only(top: 9), + shrinkWrap: true, + children: [ + if (onlySMSBox == false) getButton(3), + if (onlySMSBox == false) getButton(2), + getButton(1), + getButton(4), + ], + ), + ]), + ], + ), + ), + SizedBox( + height: 12, + ), + DefaultButton( + TranslationBase.of(context).useAnotherAccount, + () { + Navigator.of(context).pushNamed(LOGIN_TYPE); + projectViewModel.analytics.loginRegistration.login_with_other_account(); + }, + ), + ], ), ), ); } Future _getAvailableBiometrics() async { + final bool canAuthenticateWithBiometrics = await auth.canCheckBiometrics; + final bool canAuthenticate = canAuthenticateWithBiometrics || await auth.isDeviceSupported(); + var availableBiometrics; try { availableBiometrics = await auth.getAvailableBiometrics(); + // print(availableBiometrics); } on PlatformException catch (e) { + AppToast.showErrorToast(message: e.message!); print(e); } if (!mounted) return; @@ -277,34 +312,51 @@ class _ConfirmLogin extends State { }); } - authenticateUser(type, isActive) { + int login_method = 0; + + authenticateUser(int type, {int? isActive}) { GifLoaderDialogUtils.showMyDialog(context); if (type == 2 || type == 3) { fingrePrintBefore = type; } this.selectedOption = fingrePrintBefore != null ? fingrePrintBefore : type; + login_method = type; + LoginRegistration.verificationMethod = type; + // if(!widget.fromRegistration) + projectViewModel.analytics.loginRegistration.login_verfication(forRegistration: widget.fromRegistration); + switch (type) { case 1: - this.loginWithSMS(type, isActive); + this.loginWithSMS(type); break; case 2: - this.loginWithFingurePrintFace(type, isActive); + this.loginWithFingurePrintFace(type, isActive!); break; case 3: - this.loginWithFingurePrintFace(type, isActive); + this.loginWithFingurePrintFace(type, isActive!); break; case 4: - this.loginWithSMS(type, isActive); + this.loginWithSMS(type); break; default: break; } - sharedPref.setInt(LAST_LOGIN, - this.selectedOption); //this.cs.sharedService.setStorage(this.selectedOption, AuthenticationService.LAST_LOGIN); + sharedPref.setInt(LAST_LOGIN, this.selectedOption); //this.cs.sharedService.setStorage(this.selectedOption, AuthenticationService.LAST_LOGIN); } - loginWithSMS(type, isActive) { + loginWithSMS(type) async { + if (type == 4) { + var channel = WhatsappMethodChannel(); + // var whatsappStatus = await channel.isWhatsAppInstalled(); + // if(whatsappStatus) { + // print("whatapp is installed"); + channel.handleHandShake(); + // }else{ + // print("whatapp is not installed"); + // } + } + //if (!el.disabled) { if (this.user != null && this.registerd_data == null) { this.checkUserAuthentication(type); @@ -355,17 +407,41 @@ class _ConfirmLogin extends State { var request = this.getCommonRequest(type: type); request.sMSSignature = await SMSOTP.getSignature(); GifLoaderDialogUtils.showMyDialog(context); - await this.authService.sendActivationCode(request).then((result) { - GifLoaderDialogUtils.hideDialog(context); - if (result != null && result['isSMSSent'] == true) { - this.startSMSService(type); + if (healthId != null || widget.isDubai) { + if (!widget.isDubai) { + request.dob = dob; //isHijri == 1 ? dob : dateFormat2.format(dateFormat.parse(dob)); } - }).catchError((r) { - GifLoaderDialogUtils.hideDialog(context); - }); + request.healthId = healthId; + request.isHijri = isHijri; + await this.authService.sendActivationCodeRegister(request).then((result) { + GifLoaderDialogUtils.hideDialog(context); + if (result != null && result['isSMSSent'] == true) { + this.startSMSService(type); + } + }).catchError((r) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: r); + }); + } else { + request.dob = ""; + request.healthId = ""; + request.isHijri = 0; + await this.authService.sendActivationCode(request).then((result) { + GifLoaderDialogUtils.hideDialog(context); + if (result != null && result['isSMSSent'] == true) { + this.startSMSService(type); + } + }).catchError((r) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: r.toString()); + }); + } } + var tempType; + startSMSService(type) { + tempType = type; new SMSOTP( context, type, @@ -375,26 +451,40 @@ class _ConfirmLogin extends State { }, () => { Navigator.pop(context), - print('Faild..'), }, ).displayDialog(context); } - loginWithFingurePrintFace(type, isActive) async { - if (isActive == 1) { - // this.startBiometricLoginIfAvailable(); - authenticated = await auth.authenticateWithBiometrics( + loginWithFingurePrintFace(type, int isActive) async { + if (isActive == 1 || isActive == 0) { + try { + authenticated = await auth.authenticate( localizedReason: 'Scan your fingerprint to authenticate', - useErrorDialogs: true, - stickyAuth: true); + options: AuthenticationOptions( + useErrorDialogs: true, + stickyAuth: true, + ), + authMessages: [ + // IOSAuthMessages( + // cancelButton: 'cancel', + // goToSettingsButton: 'settings', + // goToSettingsDescription: 'Please set up your Touch ID.', + // lockOut: 'Please reenable your Touch ID'), + ], + ); + } on PlatformException catch (e) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: 'Please enable your Touch or Face ID'); + } if (authenticated == true) { - if (user != null && (user.logInType == 2 || user.logInType == 3)) { - this.checkActivationCode(); - } else { - var request = this.getCommonRequest(type: type); - this.getMobileInfo(request); - } + // if (user != null && (user.logInType == 2 || user.logInType == 3)) { + // this.checkActivationCode(); + // } else { + + var request = this.getCommonRequest(type: type); + this.getMobileInfo(request); + //} } } } @@ -404,13 +494,18 @@ class _ConfirmLogin extends State { this.authService.getLoginInfo(request).then((result) { GifLoaderDialogUtils.hideDialog(context); if (result['SMSLoginRequired'] == false) { - this.loginTokenID = result.logInTokenID; - this.patientOutSA = result.patientOutSA; + this.loginTokenID = result['LogInTokenID']; + this.patientOutSA = result['PatientOutSA']; // sms for register the biometric - if (result.isSMSSent) { - this.onlySMSBox = false; + if (result['isSMSSent']) { + setState(() { + isMoreOption = true; + this.onlySMSBox = true; + // this.fingrePrintBefore = true; + }); //this.button(); } else { + setDefault(); checkActivationCode(); } } else { @@ -429,40 +524,46 @@ class _ConfirmLogin extends State { } setDefault() async { - if (await sharedPref.getObject(IMEI_USER_DATA) != null) - user = SelectDeviceIMEIRES.fromJson( - await sharedPref.getObject(IMEI_USER_DATA)); + showLoader(true); + if (await sharedPref.getObject(IMEI_USER_DATA) != null) user = SelectDeviceIMEIRES.fromJson(await sharedPref.getObject(IMEI_USER_DATA)); if (await sharedPref.getObject(REGISTER_DATA_FOR_LOGIIN) != null) { isMoreOption = true; - this.registerd_data = CheckPatientAuthenticationReq.fromJson( - await sharedPref.getObject(REGISTER_DATA_FOR_LOGIIN)); + this.registerd_data = await CheckPatientAuthenticationReq.fromJson(await sharedPref.getObject(REGISTER_DATA_FOR_LOGIIN)); } - this.mobileNumber = this.registerd_data != null - ? this.registerd_data.patientMobileNumber - : int.parse(this.user.mobile); + this.mobileNumber = this.registerd_data != null ? this.registerd_data.patientMobileNumber : int.parse(this.user!.mobile!); this.zipCode = this.registerd_data != null ? this.registerd_data.zipCode - : this.user.outSA == true + : this.user!.outSA == true ? "971" : "966"; this.patientOutSA = this.registerd_data != null ? this.registerd_data.zipCode == "966" ? 0 : 1 - : this.user.outSA; + : this.user!.outSA; if (this.registerd_data != null) { this.loginTokenID = await sharedPref.getString(LOGIN_TOKEN_ID); this.loginType = this.registerd_data.searchType; } + var nhic = await sharedPref.getObject(NHIC_DATA); + if (nhic != null) { + final DateFormat dateFormat = DateFormat('MM/dd/yyyy'); + final DateFormat dateFormat2 = DateFormat('dd/MM/yyyy'); + dob = nhic['IsHijri'] ? nhic['DateOfBirth'] : dateFormat2.format(dateFormat.parse(nhic['DateOfBirth'])); + + isHijri = nhic['IsHijri'] ? 1 : 0; + healthId = nhic['HealthId']; + } this.deviceToken = await sharedPref.getString(PUSH_TOKEN); this.lastLogin = await sharedPref.getInt(LAST_LOGIN) != null ? await sharedPref.getInt(LAST_LOGIN) : user != null - ? user.logInType + ? user!.logInType : null; + showLoader(false); //this.cs.sharedService.getStorage(AuthenticationService.LAST_LOGIN); } @@ -473,33 +574,22 @@ class _ConfirmLogin extends State { request.deviceToken = this.deviceToken; request.projectOutSA = this.patientOutSA == true ? true : false; request.loginType = this.selectedOption; - request.oTPSendType = - type == 1 ? type : 2; //this.selectedOption == 1 ? 1 : 2; + request.oTPSendType = type == 1 ? type : 2; //this.selectedOption == 1 ? 1 : 2; request.zipCode = this.zipCode; request.logInTokenID = this.loginTokenID ?? ""; if (this.registerd_data != null) { - request.searchType = this.registerd_data.searchType != null - ? this.registerd_data.searchType - : 1; - request.patientID = this.registerd_data.patientID != null - ? this.registerd_data.patientID - : 0; - request.patientIdentificationID = request.nationalID = - this.registerd_data.patientIdentificationID != null - ? this.registerd_data.patientIdentificationID - : '0'; - + request.searchType = this.registerd_data.searchType != null ? this.registerd_data.searchType : 1; + request.patientID = this.registerd_data.patientID != null ? this.registerd_data.patientID : 0; + request.patientIdentificationID = request.nationalID = this.registerd_data.patientIdentificationID != null ? this.registerd_data.patientIdentificationID : '0'; + request.dob = this.registerd_data.dob; request.isRegister = this.registerd_data.isRegister; } else { request.searchType = request.searchType != null ? request.searchType : 2; - request.patientID = this.user.patientID != null ? this.user.patientID : 0; - request.nationalID = - request.nationalID != null ? request.nationalID : '0'; - request.patientIdentificationID = request.patientIdentificationID != null - ? request.patientIdentificationID - : '0'; + request.patientID = this.user!.patientID != null ? this.user!.patientID : 0; + request.nationalID = request.nationalID != null ? request.nationalID : '0'; + request.patientIdentificationID = request.patientIdentificationID != null ? request.patientIdentificationID : '0'; request.isRegister = false; } request.deviceTypeID = request.searchType; @@ -507,104 +597,223 @@ class _ConfirmLogin extends State { } checkActivationCode({value}) async { + // Navigator.pop(context); GifLoaderDialogUtils.showMyDialog(context); var request = this.getCommonRequest().toJson(); - - authService - .checkActivationCode(request, value) - .then((result) => { - if (result is Map) - { - result = CheckActivationCode.fromJson(result), - if (this.registerd_data != null && - this.registerd_data.isRegister == true) - { - Navigator.of(context).pushNamed( - REGISTER_INFO, - ) - } - else - { - sharedPref.remove(FAMILY_FILE), - result.list.isFamily = false, - userData = result.list, - // sharedPref.setString( - // BLOOD_TYPE, result['PatientBloodType']), - sharedPref.setObject(MAIN_USER, result.list), - sharedPref.setObject(USER_PROFILE, result.list), - loginTokenID = result.logInTokenID, - sharedPref.setObject(LOGIN_TOKEN_ID, result.logInTokenID), - sharedPref.setString(TOKEN, result.authenticationTokenID), - checkIfUserAgreedBefore(result), - } - } - else - { - // Navigator.of(context).pop(), - GifLoaderDialogUtils.hideDialog(context), - Future.delayed(Duration(seconds: 1), () { - AppToast.showErrorToast(message: result); - }), - } - }) - .catchError((err) { - print(err); - GifLoaderDialogUtils.hideDialog(context); - Future.delayed(Duration(seconds: 1), () { - AppToast.showErrorToast(message: err); + dynamic res; + if (healthId != null || widget.isDubai) { + if (!widget.isDubai) { + request['DOB'] = dob; + } + request['HealthId'] = healthId; + request['IsHijri'] = isHijri; + + authService + .checkActivationCodeRegister(request, value) + .then((result) => { + res = result, + if (result is Map) + { + result = CheckActivationCode.fromJson(result as Map), + if (this.registerd_data != null && this.registerd_data.isRegister == true) + { + // if(widget.isDubai ==false){ + widget.changePageViewIndex!(1), + // if(widget.isDubai ==false){ + + Navigator.popUntil(context, (route) => Utils.route(route, equalsTo: RegisterNew)), + } + } + else + { + // Navigator.of(context).pop(), + GifLoaderDialogUtils.hideDialog(context), + Future.delayed(Duration(seconds: 1), () { + AppToast.showErrorToast(message: result); + }), + projectViewModel.analytics.loginRegistration.login_fail(error: result), + projectViewModel.analytics.errorTracking.log('otp_verification_at_confirm_login', error: result), + } + }) + .catchError((err) { + print(err); + GifLoaderDialogUtils.hideDialog(context); + Future.delayed(Duration(seconds: 1), () { + AppToast.showErrorToast(message: err); + startSMSService(tempType); + }); }); - }); + } else { + authService + .checkActivationCode(request, value) + .then((result) async => { + res = result, + if (result is Map) + { + result = CheckActivationCode.fromJson(result as Map), + if (result.errorCode == '699') + { + //699 block run here + GifLoaderDialogUtils.hideDialog(context), + Future.delayed(Duration(seconds: 2), () { + AppToast.showErrorToast(message: result.errorEndUserMessage); + Navigator.popUntil(context, (route) => Utils.route(route, equalsTo: Login)); + }) + } + else if (this.registerd_data != null && this.registerd_data.isRegister == true) + { + widget.changePageViewIndex!(1), + Navigator.popUntil(context, (route) => Utils.route(route, equalsTo: RegisterNew)), + } + else + { + sharedPref.remove(FAMILY_FILE), + result.list.isFamily = false, + userData = result.list, + sharedPref.setString(BLOOD_TYPE, result.patientBloodType ?? ""), + //Remove o+ from here Added by Aamir + authenticatedUserObject.user = result.list, + projectViewModel.setPrivilege(privilegeList: res), + await sharedPref.setObject(MAIN_USER, result.list), + await sharedPref.setObject(USER_PROFILE, result.list), + loginTokenID = result.logInTokenID, + await sharedPref.setObject(LOGIN_TOKEN_ID, result.logInTokenID), + await sharedPref.setString(TOKEN, result.authenticationTokenID), + checkIfUserAgreedBefore(result), + projectViewModel.analytics.loginRegistration.login_successful(), + } + } + else + { + // Navigator.of(context).pop(), + GifLoaderDialogUtils.hideDialog(context), + Future.delayed(Duration(seconds: 1), () { + Navigator.of(context).pop(); + AppToast.showErrorToast(message: result, localContext: context); + startSMSService(tempType); + }), + + projectViewModel.analytics.loginRegistration.login_fail(error: result), + projectViewModel.analytics.errorTracking.log('otp_verification_at_confirm_login', error: result) + } + }) + .catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + Future.delayed(Duration(seconds: 1), () { + print(err); + AppToast.showErrorToast(message: err); + startSMSService(tempType); + }); + }); + } } checkIfUserAgreedBefore(CheckActivationCode result) { - if (result.isNeedUserAgreement == true) { - //move to agreement page. + if (projectViewModel.havePrivilege(109)) { + this.authService.checkIfUserAgreed().then((result) { + if (result['IsPatientAlreadyAgreed']) { + goToHome(); + } else { + this.authService.getUserAgreementContent().then((result) { + GifLoaderDialogUtils.hideDialog(AppGlobal.context); + Navigator.pushAndRemoveUntil( + context, + FadePage( + page: UserLoginAgreementPage( + userAgreementText: result['UserAgreementContent'], + authenticatedUserObject: authenticatedUserObject, + appointmentRateViewModel: appointmentRateViewModel, + selectedOption: selectedOption, + isArabic: projectViewModel.isArabic, + ), + ), + (r) => false); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); } else { - insertIMEI(); + goToHome(); } + + // if (result.isNeedUserAgreement == true) { + // // move to agreement page. + // } else { + // goToHome(); + // } + } + + checkIfIsInPatient() { + bool isAdmitted = false; + bool hasAdmissionRequest = false; + GetAdmissionInfoResponseModel getAdmissionInfoResponseModel; + GetAdmissionRequestInfoResponseModel getAdmissionRequestInfoResponseModel; + ClinicListService service = new ClinicListService(); + service.checkIfInPatientAPI(context).then((res) { + if (res['MessageStatus'] == 1) { + isAdmitted = res['isAdmitted']; + hasAdmissionRequest = res['hasAdmissionRequests']; + print("IS ADMITTED: $isAdmitted"); + print("Has Admission Request: $hasAdmissionRequest"); + if (isAdmitted) { + if (res['PatientAdmittedInformation'].length != 0) { + getAdmissionInfoResponseModel = GetAdmissionInfoResponseModel.fromJson(res['PatientAdmittedInformation'][0]); + projectViewModel.setInPatientProjectID(res['PatientAdmittedInformation'][0]['ProjectID']); + projectViewModel.setInPatientAdmissionInfo(getAdmissionInfoResponseModel); + projectViewModel.setIsPatientAdmitted(true); + } + } + if (hasAdmissionRequest) { + if (res['MedicalInstruction'].length != 0) { + getAdmissionRequestInfoResponseModel = GetAdmissionRequestInfoResponseModel.fromJson(res['MedicalInstruction'][0]); + // projectViewModel.setInPatientProjectID(res['MedicalInstruction'][0]['ProjectID']); + projectViewModel.setInPatientProjectID(res['MedicalInstruction'][0]['projectId']); + projectViewModel.setInPatientAdmissionRequest(getAdmissionRequestInfoResponseModel); + projectViewModel.setPatientHasAdmissionRequest(true); + } + } + } else {} + }); } insertIMEI() { - authService - .insertDeviceImei(selectedOption) - .then((value) => {goToHome()}) - .catchError((err) { + authService.insertDeviceImei(selectedOption).then((value) => {}).catchError((err) { print(err); }); } getToDoCount() { - toDoProvider.setState(0, true); + toDoProvider.setState(0, 0, true, "0"); ClinicListService service = new ClinicListService(); service.getActiveAppointmentNo(context).then((res) { - print(res['AppointmentActiveNumber']); if (res['MessageStatus'] == 1) { - toDoProvider.setState(res['AppointmentActiveNumber'], true); + toDoProvider.setState(res['AppointmentActiveNumber'], res['AncillaryOrderListCount'], true, "0"); + // toDoProvider.setState(res['AppointmentActiveNumber'], true, "0"); } else {} }).catchError((err) { print(err); }); } - goToHome() { + goToHome() async { authenticatedUserObject.isLogin = true; appointmentRateViewModel.isLogin = true; projectViewModel.isLogin = true; projectViewModel.user = authenticatedUserObject.user; - Provider.of(context, listen: false) - .setUser(authenticatedUserObject.user); - getToDoCount(); - - pharmacyModuleViewModel.generatePharmacyToken().then((value) async { - if (pharmacyModuleViewModel.error.isNotEmpty) - await pharmacyModuleViewModel.createUser(); - }); + await authenticatedUserObject.getUser(getUser: true); + // GifLoaderDialogUtils.hideDialog(context); + getToDoCount(); + checkIfIsInPatient(); appointmentRateViewModel - .getIsLastAppointmentRatedList() + .getIsLastAppointmentRatedList(projectViewModel.isArabic ? 1 : 2) .then((value) => { - getToDoCount(), - // GifLoaderDialogUtils.hideDialog(context), + GifLoaderDialogUtils.hideDialog(AppGlobal.context), if (appointmentRateViewModel.isHaveAppointmentNotRate) { Navigator.pushAndRemoveUntil( @@ -622,13 +831,12 @@ class _ConfirmLogin extends State { page: LandingPage(), ), (r) => false) - } + }, + insertIMEI() }) .catchError((err) { print(err); - //GifLoaderDialogUtils.hideDialog(context); }); - // SMSOTP.showLoadingDialog(context, false), } loading(flag) { @@ -637,163 +845,102 @@ class _ConfirmLogin extends State { }); } - Widget getButton(flag) { + Widget _loginOptionButton(String _title, String _icon, int _flag, int? _loginIndex) { + bool isDisable = (_flag == 3 && !checkIfBiometricAvailable(BiometricType.face) || + _flag == 2 && !checkIfBiometricAvailable(BiometricType.fingerprint) && _flag == 2 && !checkIfBiometricAvailable(BiometricType.strong)); + return InkWell( + onTap: isDisable + ? null + : () { + if (_flag == 0) { + setState(() { + isMoreOption = true; + }); + } else { + authenticateUser(_flag, isActive: _loginIndex); + projectViewModel.analytics.loginRegistration.verify_otp_method(forRegistration: widget.fromRegistration); + } + }, + child: Container( + padding: EdgeInsets.only(left: 20, right: 20, bottom: 15, top: 28), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15), + color: isDisable ? Colors.grey.withOpacity(0.3) : Colors.white, + border: Border.all( + color: Color(0xffefefef), + width: 1, + ), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + SvgPicture.asset( + _icon, + height: 38, + width: 38, + color: isDisable ? Color(0xff2B353E).withOpacity(0.7) : null, + ), + Text( + TranslationBase.of(context).verifyThrough + " " + _title, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: isDisable ? Color(0xff2B353E).withOpacity(0.7) : Color(0xff2B353E), letterSpacing: -0.48, height: 20 / 16), + ), + ], + ), + ), + ); + } + + // todo 'sikander' optimize this after knowing usage + Widget getButton(int flag) { switch (flag) { case 4: - return InkWell( - onTap: () => {authenticateUser(4, true)}, - child: RoundedContainer( - height: 150, - borderColor: Colors.grey, - showBorder: true, - child: Padding( - padding: EdgeInsets.fromLTRB(30, 15, 30, 15), - child: Column( - children: [ - Image.asset( - 'assets/images/login/104.png', - height: SizeConfig.imageSizeMultiplier * 13, - width: SizeConfig.imageSizeMultiplier * 16, - ), - SizedBox( - height: 20, - ), - Texts(TranslationBase.of(context).verifyWhatsApp, - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.black) - ], - ), - ))); + return _loginOptionButton(TranslationBase.of(context).verifyWhatsApp, 'assets/images/new/verify_whatsapp.svg', flag, null); break; case 1: - return InkWell( - onTap: () => {authenticateUser(1, true)}, - child: RoundedContainer( - height: 150, - borderColor: Colors.grey, - showBorder: true, - child: Padding( - padding: EdgeInsets.fromLTRB(30, 15, 30, 15), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Image.asset( - 'assets/images/login/103.png', - height: SizeConfig.imageSizeMultiplier * 13, - width: SizeConfig.imageSizeMultiplier * 16, - ), - projectViewModel.isArabic - ? SizedBox( - height: 0, - ) - : SizedBox( - height: 20, - ), - Texts(TranslationBase.of(context).verifySMS, - fontSize: SizeConfig.textMultiplier * 2, - textAlign: TextAlign.center, - color: Colors.black) - ], - ), - ))); + return _loginOptionButton(TranslationBase.of(context).verifySMS, 'assets/images/new/verify_sms.svg', flag, null); break; case 2: - return InkWell( - onTap: () => {authenticateUser(2, BiometricType.fingerprint.index)}, - child: RoundedContainer( - height: 150, - backgroundColor: BiometricType.fingerprint.index == 1 - ? Colors.white - : Colors.white.withOpacity(.7), - borderColor: Colors.grey, - showBorder: true, - child: Padding( - padding: EdgeInsets.fromLTRB(30, 15, 30, 15), - child: Column( - children: [ - Image.asset( - 'assets/images/login/102.png', - height: SizeConfig.imageSizeMultiplier * 13, - width: SizeConfig.imageSizeMultiplier * 16, - ), - SizedBox( - height: 20, - ), - Texts(TranslationBase.of(context).verifyFingerprint, - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.black) - ], - ), - ))); + return _loginOptionButton(TranslationBase.of(context).verifyFingerprint, 'assets/images/new/verify_thumb.svg', flag, BiometricType.fingerprint.index); break; case 3: - return InkWell( - onTap: () => {authenticateUser(3, BiometricType.face.index)}, - child: RoundedContainer( - height: 150, - backgroundColor: checkIfBiometricAvailable(BiometricType.face) - ? Colors.white - : Colors.white.withOpacity(.7), - borderColor: Colors.grey, - showBorder: true, - child: Padding( - padding: EdgeInsets.fromLTRB(30, 15, 30, 15), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Image.asset( - 'assets/images/login/101.png', - height: SizeConfig.imageSizeMultiplier * 13, - width: SizeConfig.imageSizeMultiplier * 16, - ), - SizedBox( - height: 20, - ), - Texts(TranslationBase.of(context).verifyFaceID, - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.black) - ], - ), - ))); + return _loginOptionButton(TranslationBase.of(context).verifyFaceID, 'assets/images/new/verify_face.svg', flag, BiometricType.face.index); break; default: return InkWell( - onTap: () => { - setState(() { - isMoreOption = true; - }) - }, - child: RoundedContainer( - height: 150, - backgroundColor: BiometricType.fingerprint.index == 1 - ? Colors.white - : Colors.white.withOpacity(.7), - borderColor: Colors.grey, - showBorder: true, - child: Padding( - padding: EdgeInsets.fromLTRB(0, 0, 0, 5), - child: Column( - children: [ - Image.asset( - 'assets/images/login/more_icon.png', - height: 45, - width: SizeConfig.imageSizeMultiplier * 16, - ), - projectViewModel.isArabic - ? SizedBox( - height: 15, - ) - : SizedBox( - height: 20, - ), - Texts(TranslationBase.of(context).moreVerification, - fontSize: SizeConfig.textMultiplier * 1.8, - textAlign: TextAlign.center, - color: Colors.black) - ], + onTap: () => { + setState(() { + isMoreOption = true; + }) + }, + child: RoundedContainer( + height: 150, + backgroundColor: BiometricType.fingerprint.index == 1 ? Colors.white : Colors.white.withOpacity(.7), + borderColor: Colors.grey, + showBorder: true, + child: Padding( + padding: EdgeInsets.fromLTRB(0, 0, 0, 5), + child: Column( + children: [ + Image.asset( + 'assets/images/login/more_icon.png', + height: 45, + width: SizeConfig.imageSizeMultiplier! * 16, ), - ))); + projectViewModel.isArabic + ? SizedBox( + height: 15, + ) + : SizedBox( + height: 20, + ), + Texts(TranslationBase.of(context).moreVerification, fontSize: SizeConfig.textMultiplier! * 1.8, textAlign: TextAlign.center, color: Colors.black) + ], + ), + ), + ), + ); } } diff --git a/lib/pages/login/forgot-password.dart b/lib/pages/login/forgot-password.dart index cb2604b1..529d0b8f 100644 --- a/lib/pages/login/forgot-password.dart +++ b/lib/pages/login/forgot-password.dart @@ -1,10 +1,15 @@ +import 'package:cloudflare_turnstile/cloudflare_turnstile.dart'; +import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; +import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/size_config.dart'; +import 'package:diplomaticquarterapp/locator.dart'; import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; 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/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/alert_dialog.dart'; +import 'package:diplomaticquarterapp/widgets/habib_logo_widget.dart'; import 'package:diplomaticquarterapp/widgets/mobile-no/mobile_no.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/otp/sms-popup.dart'; @@ -20,12 +25,112 @@ class ForgotPassword extends StatefulWidget { class _ForgotPassword extends State { String selectedType = 'Saudi Arabia'; String countryCode = '966'; - final TextEditingController nationalIDorFile = null; - String mobileNo; + final TextEditingController nationalIDorFile = TextEditingController(); + String mobileNo = ""; var con; + + final TurnstileController _controller = TurnstileController(); + final TurnstileOptions _options = TurnstileOptions( + size: TurnstileSize.normal, + theme: TurnstileTheme.light, + refreshExpired: TurnstileRefreshExpired.manual, + language: 'en', + retryAutomatically: false, + ); + + String? _token; + + @override + void dispose() { + super.dispose(); + _controller.dispose(); + } + @override Widget build(BuildContext context) { con = context; + + return Scaffold( + backgroundColor: Color(0xfff8f8f8), + appBar: AppBar( + backgroundColor: Colors.transparent, + leading: IconButton( + icon: Icon(Icons.arrow_back_ios), + color: Color(0xff2B353E), + onPressed: () => Navigator.pop(context), + ), + ), + body: Padding( + padding: EdgeInsets.only(bottom: 20, left: 21, right: 21), + child: Column(children: [ + Expanded( + child: ListView( + padding: EdgeInsets.zero, + physics: BouncingScrollPhysics(), + children: [ + SizedBox(height: 12), + HabibLogoWidget(), + SizedBox(height: 50), + Text( + TranslationBase.of(context).forgotDesc, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64, height: 23 / 16), + ), + SizedBox(height: 20), + PhoneNumberSelectorWidget(onNumberChange: (value) { + setState(() { + mobileNo = value; + }); + }, onCountryChange: (value) { + setState(() { + countryCode = value; + }); + }), + const SizedBox(height: 12.0), + CloudFlareTurnstile( + siteKey: '0x4AAAAAAAkmbvEy63pcxBBt', + baseUrl: BASE_URL, + options: _options, + controller: _controller, + onTokenRecived: (token) { + setState(() { + print("Cloudflare token: $token"); + _token = token; + }); + }, + onTokenExpired: () {}, + mode: TurnstileMode.managed, + errorBuilder: (context, error) { + return Text(error.message); + }, + ), + const SizedBox(height: 48.0), + ], + ), + ), + SizedBox( + height: 43, + width: double.infinity, + child: TextButton( + onPressed: () { + sendPatientIDBySMS(); + locator().loginRegistration.recover_file_number(); + }, + child: Text( + TranslationBase.of(context).submit, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Colors.white, letterSpacing: -0.48), + ), + style: TextButton.styleFrom( + backgroundColor: (mobileNo.length >= 9) == true ? Color(0xffD02127) : Color(0xff575757), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(6), + ), + ), + ), + ), + ]), + ), + ); + return AppScaffold( appBarTitle: TranslationBase.of(context).forgotFileNoTitle, isShowAppBar: true, @@ -33,14 +138,14 @@ class _ForgotPassword extends State { body: SingleChildScrollView( child: Container( padding: EdgeInsets.only(top: 10, left: 20, right: 20), - height: SizeConfig.realScreenHeight * .8, + height: SizeConfig.realScreenHeight! * .8, width: SizeConfig.realScreenWidth, child: Column(children: [ Expanded( flex: 1, child: AppText( TranslationBase.of(context).forgotDesc, - fontSize: SizeConfig.textMultiplier * 3, + fontSize: SizeConfig.textMultiplier! * 3, textAlign: TextAlign.start, marginTop: 10.0, )), @@ -53,9 +158,15 @@ class _ForgotPassword extends State { mainAxisAlignment: MainAxisAlignment.center, children: [], ), - MobileNo( - onNumberChange: (value) => {mobileNo = value}, - onCountryChange: (value) => countryCode = value), + MobileNo(onNumberChange: (value) { + setState(() { + mobileNo = value; + }); + }, onCountryChange: (value) { + setState(() { + countryCode = value; + }); + }), ], ), ), @@ -70,9 +181,13 @@ class _ForgotPassword extends State { child: DefaultButton( TranslationBase.of(context).submit, () { - sendPatientIDBySMS(); + // if (mobileNo.length >= 9 == true) + // sendPatientIDBySMS(); + if (mobileNo.length >= 9) sendPatientIDBySMS(); // print(mobileNo.text); }, + color: mobileNo.length >= 9 == true ? Colors.grey[900] : Colors.grey, + textColor: Colors.white, )), ], ), @@ -85,7 +200,7 @@ class _ForgotPassword extends State { sendPatientIDBySMS() { GifLoaderDialogUtils.showMyDialog(context); final authService = new AuthProvider(); - authService.sendPatientIDSMS(mobileNo, context).then((res) { + authService.sendPatientIDSMS(mobileNo, countryCode, context).then((res) { GifLoaderDialogUtils.hideDialog(context); if (res['MessageStatus'] == 1) { this.startSMSService(mobileNo, res['LogInTokenID']); @@ -116,7 +231,7 @@ class _ForgotPassword extends State { final authService = new AuthProvider(); var request = { "LogInTokenID": token, - "PatientOutSA": countryCode == '966' ? 0 : 1, + "PatientOutSA": (countryCode == '966' || countryCode == '+966') ? 0 : 1, "PatientMobileNumber": mobileNo, "ZipCode": countryCode, "activationCode": value, diff --git a/lib/pages/login/login-type.dart b/lib/pages/login/login-type.dart index f8af8eac..a9e309bc 100644 --- a/lib/pages/login/login-type.dart +++ b/lib/pages/login/login-type.dart @@ -1,184 +1,272 @@ -import 'package:diplomaticquarterapp/config/size_config.dart'; +import 'package:diplomaticquarterapp/analytics/flows/login_registration.dart'; +import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; +import 'package:diplomaticquarterapp/locator.dart'; import 'package:diplomaticquarterapp/pages/login/forgot-password.dart'; import 'package:diplomaticquarterapp/pages/login/login.dart'; -import 'package:diplomaticquarterapp/pages/login/register.dart'; -import 'package:diplomaticquarterapp/routes.dart'; +import 'package:diplomaticquarterapp/pages/login/register_new.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; -import 'package:diplomaticquarterapp/widgets/card/rounded_container.dart'; -import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:diplomaticquarterapp/widgets/text/app_texts_widget.dart'; +import 'package:diplomaticquarterapp/widgets/habib_logo_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; +import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; class LoginType extends StatelessWidget { static int loginType = 0; @override Widget build(BuildContext context) { - return AppScaffold( - appBarTitle: TranslationBase.of(context).login, - isShowAppBar: true, - isShowDecPage: false, - body: SingleChildScrollView( - child: Container( - padding: - EdgeInsets.only(top: 10, left: 20, right: 20, bottom: 30), - height: SizeConfig.realScreenHeight * .9, - width: SizeConfig.realScreenWidth, - child: Column( - children: [ - Expanded( - flex: 4, - child: Column( - // mainAxisAlignment: MainAxisAlignment.spaceEvenly, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Image.asset( - 'assets/images/DQ/logo.png', - height: 90, - width: 90, - ), - AppText( - TranslationBase.of(context).logintypeRadio, - fontSize: SizeConfig.textMultiplier * 3.5, - textAlign: TextAlign.start, - marginBottom: 20.0, - marginTop: 20.0, - ), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Expanded( - child: InkWell( - onTap: () => { - LoginType.loginType = 1, - Navigator.of(context) - .push(FadePage(page: Login())), - }, - child: RoundedContainer( - borderColor: Colors.grey, - showBorder: true, - child: Padding( - padding: EdgeInsets.fromLTRB( - 20, 10, 20, 10), - child: Column( - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - Image.asset( - 'assets/images/id_card_icon.png', - height: SizeConfig - .imageSizeMultiplier * - 12, - width: SizeConfig - .imageSizeMultiplier * - 15, - ), - SizedBox( - height: 20, - ), - AppText( - TranslationBase.of(context) - .idNo, - fontSize: SizeConfig - .textMultiplier * - 2, - fontWeight: FontWeight.bold, - ) - ], - ), - )))), - Expanded( - child: InkWell( - onTap: () => { - LoginType.loginType = 2, - Navigator.of(context) - .push(FadePage(page: Login())), - }, - child: RoundedContainer( - borderColor: Colors.grey, - showBorder: true, - child: Padding( - padding: EdgeInsets.fromLTRB( - 25, 10, 25, 10), - child: Column( - children: [ - Image.asset( - 'assets/images/my_file_white_icon.png', - height: SizeConfig - .imageSizeMultiplier * - 12, - width: SizeConfig - .imageSizeMultiplier * - 15, - ), - SizedBox( - height: 20, - ), - AppText( - TranslationBase.of(context) - .fileNo, - fontSize: SizeConfig - .textMultiplier * - 2, - fontWeight: FontWeight.bold, - ) - ], - ), - )))) - ], - ), - SizedBox( - height: 25, - ), - Divider( - color: Colors.grey, - height: 2, - ), - Center( - child: InkWell( - onTap: () => { - Navigator.of(context) - .push(FadePage(page: ForgotPassword())), - }, - child: AppText( - TranslationBase.of(context) - .forgotPassword, - fontSize: - SizeConfig.textMultiplier * 2.5, - marginTop: 20.0, - underline: true))) - ]), - ), - Expanded( - flex: 1, - child: Column( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - Divider( - color: Colors.grey, - height: 2, - ), - SizedBox( - height: 10, - ), - Row( - children: [ - Expanded( - child: DefaultButton( - TranslationBase.of(context).registerNow, - () => { - Navigator.of(context) - .push(FadePage(page: Register())), - }, - )), - ], - ), - ], - )) + return Scaffold( + backgroundColor: Color(0xfff8f8f8), + resizeToAvoidBottomInset: false, + appBar: AppBar( + backgroundColor: Colors.transparent, + leading: IconButton( + icon: Icon(Icons.arrow_back_ios), + color: Color(0xff2B353E), + onPressed: () => Navigator.pop(context), + ), + ), + body: Padding( + padding: EdgeInsets.only(bottom: 20, left: 21, right: 21), + child: Column(children: [ + Expanded( + child: ListView( + padding: EdgeInsets.zero, + physics: BouncingScrollPhysics(), + children: [ + SizedBox(height: 12), + HabibLogoWidget(), + SizedBox(height: 50), + Text( + TranslationBase.of(context).logintypeRadio, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64, height: 23 / 16), + ), + GridView( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, crossAxisSpacing: 13, mainAxisSpacing: 9), + physics: NeverScrollableScrollPhysics(), + padding: EdgeInsets.only(top: 25), + shrinkWrap: true, + children: [ + getButton(context, TranslationBase.of(context).nationalIdNumber, 'assets/images/new/national_id.svg', 1), + getButton(context, TranslationBase.of(context).medicalFileNumber, 'assets/images/new/medical_file.svg', 2), ], - )))); + ), + SizedBox(height: 20), + RichText( + text: TextSpan( + text: TranslationBase.of(context).forgotPassword, + style: TextStyle(decoration: TextDecoration.underline, fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xffC9272B), letterSpacing: -0.48, height: 18 / 12), + recognizer: TapGestureRecognizer() + ..onTap = () { + Navigator.of(context).push(FadePage(page: ForgotPassword())); + locator().loginRegistration.forget_file_number(); + }, + ), + ), + ], + ), + ), + SizedBox( + height: 43, + width: double.infinity, + child: TextButton( + onPressed: () { + Navigator.of(context).push(FadePage(page: RegisterNew())); + locator().loginRegistration.register_now(); + }, + child: Text( + TranslationBase.of(context).registerNow, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Colors.white, letterSpacing: -0.48), + ), + style: TextButton.styleFrom( + backgroundColor: Color(0xffD02127), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(6), + ), + ), + ), + ), + ]), + ), + ); + + // AppScaffold( + // appBarTitle: TranslationBase.of(context).login, + // isShowAppBar: true, + // isShowDecPage: false, + // body: SingleChildScrollView( + // child: Container( + // padding: EdgeInsets.only(top: 10, left: 20, right: 20, bottom: 30), + // height: SizeConfig.realScreenHeight * .9, + // width: SizeConfig.realScreenWidth, + // child: Column( + // children: [ + // Expanded( + // flex: 4, + // child: Column( + // // mainAxisAlignment: MainAxisAlignment.spaceEvenly, + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // Image.asset( + // 'assets/images/DQ/logo.png', + // height: 90, + // width: 90, + // ), + // AppText( + // TranslationBase.of(context).logintypeRadio, + // fontSize: SizeConfig.textMultiplier * 3.5, + // textAlign: TextAlign.start, + // marginBottom: 20.0, + // marginTop: 20.0, + // ), + // Row( + // mainAxisAlignment: MainAxisAlignment.center, + // children: [ + // Expanded( + // child: InkWell( + // onTap: () => { + // LoginType.loginType = 1, + // Navigator.of(context).push(FadePage(page: Login())), + // }, + // child: RoundedContainer( + // borderColor: Colors.grey, + // showBorder: true, + // child: Padding( + // padding: EdgeInsets.fromLTRB(20, 10, 20, 10), + // child: Column( + // mainAxisAlignment: MainAxisAlignment.center, + // children: [ + // Image.asset( + // 'assets/images/id_card_icon.png', + // height: SizeConfig.imageSizeMultiplier * 12, + // width: SizeConfig.imageSizeMultiplier * 15, + // ), + // SizedBox( + // height: 20, + // ), + // AppText( + // TranslationBase.of(context).idNo, + // fontSize: SizeConfig.textMultiplier * 2, + // fontWeight: FontWeight.bold, + // ) + // ], + // ), + // )))), + // Expanded( + // child: InkWell( + // onTap: () => { + // LoginType.loginType = 2, + // Navigator.of(context).push(FadePage(page: Login())), + // }, + // child: RoundedContainer( + // borderColor: Colors.grey, + // showBorder: true, + // child: Padding( + // padding: EdgeInsets.fromLTRB(25, 10, 25, 10), + // child: Column( + // children: [ + // Image.asset( + // 'assets/images/my_file_white_icon.png', + // height: SizeConfig.imageSizeMultiplier * 12, + // width: SizeConfig.imageSizeMultiplier * 15, + // ), + // SizedBox( + // height: 20, + // ), + // AppText( + // TranslationBase.of(context).fileNo, + // fontSize: SizeConfig.textMultiplier * 2, + // fontWeight: FontWeight.bold, + // ) + // ], + // ), + // )))) + // ], + // ), + // SizedBox( + // height: 25, + // ), + // Divider( + // color: Colors.grey, + // height: 2, + // ), + // Center( + // child: InkWell( + // onTap: () => { + // Navigator.of(context).push(FadePage(page: ForgotPassword())), + // }, + // child: AppText(TranslationBase.of(context).forgotPassword, fontSize: SizeConfig.textMultiplier * 2.5, marginTop: 20.0, underline: true))) + // ]), + // ), + // Expanded( + // flex: 1, + // child: Column( + // mainAxisAlignment: MainAxisAlignment.end, + // children: [ + // Divider( + // color: Colors.grey, + // height: 2, + // ), + // SizedBox( + // height: 10, + // ), + // Row( + // children: [ + // Expanded( + // child: DefaultButton( + // TranslationBase.of(context).registerNow, + // () => { + // Navigator.of(context).push(FadePage(page: Register())), + // }, + // )), + // ], + // ), + // ], + // )) + // ], + // )))); + } + + Widget getButton(BuildContext _context, String _title, String _icon, int _flag) { + var type = ''; + if (_flag == 1) type = 'national id'; + if (_flag == 2) type = 'file number'; + + return InkWell( + onTap: () { + LoginType.loginType = _flag; + LoginRegistration.loginMethod = _flag; + Navigator.of(_context).push(FadePage(page: Login())); + locator().loginRegistration.login_start(method: type); + }, + 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: 38, + width: 38, + ), + Text( + _title, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.48, height: 20 / 16), + ), + ], + ), + ), + ); } } diff --git a/lib/pages/login/login.dart b/lib/pages/login/login.dart index 8d655f76..832e0a1e 100644 --- a/lib/pages/login/login.dart +++ b/lib/pages/login/login.dart @@ -1,6 +1,7 @@ import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; -import 'package:diplomaticquarterapp/config/size_config.dart'; +import 'package:diplomaticquarterapp/core/model/geofencing/requests/GeoZonesRequestModel.dart'; import 'package:diplomaticquarterapp/core/service/AuthenticatedUserObject.dart'; +import 'package:diplomaticquarterapp/core/service/geofencing/GeofencingServices.dart'; import 'package:diplomaticquarterapp/core/viewModels/appointment_rate_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; @@ -8,30 +9,32 @@ import 'package:diplomaticquarterapp/locator.dart'; import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart'; import 'package:diplomaticquarterapp/models/Authentication/check_activation_code_response.dart'; import 'package:diplomaticquarterapp/models/Authentication/check_paitent_authentication_req.dart'; +import 'package:diplomaticquarterapp/models/InPatientServices/get_admission_info_response_model.dart'; +import 'package:diplomaticquarterapp/models/InPatientServices/get_admission_request_info_response_model.dart'; import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; import 'package:diplomaticquarterapp/pages/login/confirm-login.dart'; 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/pages/rateAppointment/rate_appointment_doctor.dart'; import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; +import 'package:diplomaticquarterapp/services/family_files/family_files_provider.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; -import 'package:diplomaticquarterapp/widgets/input/text_field.dart'; +import 'package:diplomaticquarterapp/widgets/habib_logo_widget.dart'; import 'package:diplomaticquarterapp/widgets/mobile-no/mobile_no.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/rendering.dart'; import 'package:provider/provider.dart'; -import '../../Constants.dart'; - class Login extends StatefulWidget { @override _Login createState() => _Login(); @@ -40,12 +43,13 @@ class Login extends StatefulWidget { class _Login extends State { final util = Utils(); final nationalIDorFile = TextEditingController(); - final int loginType = LoginType.loginType; - String mobileNo; + final mobileNumberController = TextEditingController(); + int loginType = LoginType.loginType; + String? mobileNo; String countryCode = '966'; bool isButtonDisabled = true; - final authService = new AuthProvider(); - var sharedPref = new AppSharedPreferences(); + final authService = AuthProvider(); + var sharedPref = AppSharedPreferences(); bool isLoading = false; AppointmentRateViewModel appointmentRateViewModel = locator(); @@ -55,13 +59,25 @@ class _Login extends State { AuthenticatedUserObject authenticatedUserObject = locator(); - ProjectViewModel projectViewModel; - ToDoCountProviderModel toDoProvider; + late ProjectViewModel projectViewModel; + late ToDoCountProviderModel toDoProvider; + + var familyFileProvider = FamilyFilesProvider(); @override void initState() { // getDeviceToken(); super.initState(); + + // if (BASE_URL.contains("uat.")) { + // nationalIDorFile.text = "2001273"; + // mobileNumberController.text = mobileNo = "0555416043"; + // } + getRegisterData(); + /* else { + nationalIDorFile.text = "3376044"; + mobileNumberController.text = mobileNo = "0555416575"; + }*/ } getDeviceToken() async { @@ -74,88 +90,158 @@ class _Login extends State { Widget build(BuildContext context) { projectViewModel = Provider.of(context); toDoProvider = Provider.of(context); - return AppScaffold( - appBarTitle: TranslationBase.of(context).login, - isShowAppBar: true, - isShowDecPage: false, - body: SingleChildScrollView( - child: Container( - padding: EdgeInsets.only(top: 10, left: 20, right: 20, bottom: 30), - height: SizeConfig.realScreenHeight * .9, - width: SizeConfig.realScreenWidth, - child: Column( - children: [ - Expanded( - flex: 2, - child: Texts( + + return Scaffold( + backgroundColor: Color(0xfff8f8f8), + appBar: AppBar( + backgroundColor: Colors.transparent, + leading: IconButton( + icon: Icon(Icons.arrow_back_ios), + color: Color(0xff2B353E), + onPressed: () => Navigator.pop(context), + ), + ), + body: Padding( + padding: EdgeInsets.only(bottom: 20, left: 21, right: 21), + child: Column(children: [ + Expanded( + child: ListView( + padding: EdgeInsets.zero, + physics: BouncingScrollPhysics(), + children: [ + SizedBox(height: 12), + HabibLogoWidget(), + SizedBox(height: 50), + Text( + loginType == 1 + ? TranslationBase.of(context).enterNationalId + : TranslationBase.of(context).enterFile, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + height: 23 / 16, + ), + ), + SizedBox(height: 20), + PhoneNumberSelectorWidget( + onNumberChange: (value) => {mobileNo = value, validateForm()}, + onCountryChange: (value) => countryCode = value, + mobileNo: this.mobileNo, + ), + SizedBox(height: 12), + Directionality( + textDirection: TextDirection.ltr, + child: inputWidget( loginType == 1 - ? TranslationBase.of(context).enterNationalId - : TranslationBase.of(context).enterFile, - fontSize: SizeConfig.textMultiplier * 3.5, - textAlign: TextAlign.start, - )), - Expanded( - flex: 3, - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Directionality( - textDirection: TextDirection.ltr, - child: MobileNo( - onNumberChange: (value) => - {mobileNo = value, validateForm()}, - onCountryChange: (value) => countryCode = value)), - Directionality( - textDirection: TextDirection.ltr, - child: Container( - child: TextFields( - keyboardType: TextInputType.number, - fontWeight: FontWeight.normal, - controller: nationalIDorFile, - onChanged: (value) => {validateForm()}, - prefixIcon: Icon( - loginType == 1 - ? Icons.chrome_reader_mode - : Icons.receipt, - color: secondaryColor), - padding: EdgeInsets.only( - top: 20, bottom: 20, left: 10, right: 10), - hintText: loginType == 1 - ? TranslationBase.of(context).nationalID - : TranslationBase.of(context).fileNo, - ))) - ], + ? TranslationBase.of(context).nationalIdNumber + : TranslationBase.of(context).medicalFileNumber, + "Xxxxxxxxx", + nationalIDorFile, + ), ), - ), - Expanded( - flex: 3, - child: Column( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - Divider( - color: Colors.grey, - height: 2, - ), - SizedBox( - height: 10, - ), - Row( - children: [ - Expanded( - child: DefaultButton( - TranslationBase.of(context).login, - () => {this.startLogin()}, - color: isButtonDisabled == true - ? Colors.grey - : Colors.grey[900], - textColor: Colors.white, - )) - ], - ), - ], - )) - ], + ], + ), + ), + SizedBox( + height: 12, ), + DefaultButton( + TranslationBase.of(context).login, + () { + if (isButtonDisabled) { + AppToast.showErrorToast(message: TranslationBase.of(context).incorrectNationalId, localContext: context); + } else { + this.startLogin(); + } + }, + disabledColor: Color(0xff575757), + ), + ]), + ), + ); + } + + 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(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: TextInputType.number, + controller: _controller, + onChanged: (value) => {validateForm()}, + 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, + ), + 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), + ], ), ), ); @@ -169,7 +255,7 @@ class _Login extends State { void validateForm() { if (util.validateIDBox(nationalIDorFile.text, loginType) == true && - util.isSAUDIIDValid(nationalIDorFile.text, loginType) == true) { + (countryCode == "971" ? true : util.isSAUDIIDValid(nationalIDorFile.text, loginType) == true)) { setState(() { isButtonDisabled = false; }); @@ -184,7 +270,7 @@ class _Login extends State { // showLoader(true); var request = CheckPatientAuthenticationReq(); request.isRegister = false; - request.patientMobileNumber = int.parse(mobileNo); + request.patientMobileNumber = int.parse(mobileNo!); request.zipCode = countryCode; request.searchType = this.loginType; request.deviceTypeID = this.loginType; @@ -197,23 +283,30 @@ class _Login extends State { } sharedPref.setObject(REGISTER_DATA_FOR_REGISTER, request); GifLoaderDialogUtils.showMyDialog(context); - authService - .checkPatientAuthentication(request) - .then((value) => { - //showLoader(false), - if (value['isSMSSent']) - { - sharedPref.setString(LOGIN_TOKEN_ID, value['LogInTokenID']), - sharedPref.setObject(REGISTER_DATA_FOR_LOGIIN, request), - GifLoaderDialogUtils.hideDialog(context), - Navigator.of(context).push(FadePage(page: ConfirmLogin())), - } - else - { - if (value['IsAuthenticated']) {this.checkActivationCode()} - } - }) - .catchError((err) { + authService.checkPatientAuthentication(request).then((value) { + // if (value['UserAccountIsActivated']) { + if (value['isSMSSent']) { + sharedPref.setString(LOGIN_TOKEN_ID, value['LogInTokenID']); + sharedPref.setObject(REGISTER_DATA_FOR_LOGIIN, request); + GifLoaderDialogUtils.hideDialog(context); + Navigator.of(context).push(FadePage(page: ConfirmLogin())); + } else { + if (value['IsAuthenticated']) { + this.checkActivationCode(); + } + } + // } else { + // ConfirmDialog activationDialog = new ConfirmDialog( + // context: context, + // confirmMessage: TranslationBase.of(context).accountDeactivatedMsg, + // okText: TranslationBase.of(context).yes, + // cancelText: TranslationBase.of(context).no, + // okFunction: () => {ConfirmDialog.closeAlertDialog(context), this.activatePatientFile()}, + // cancelFunction: () => {}); + // GifLoaderDialogUtils.hideDialog(context); + // activationDialog.showAlertDialog(context); + // } + }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); ConfirmDialog dialog = new ConfirmDialog( context: context, @@ -222,22 +315,37 @@ class _Login extends State { cancelText: TranslationBase.of(context).cancel_nocaps, okFunction: () => { ConfirmDialog.closeAlertDialog(context), - Navigator.of(context).push(FadePage(page: Register())), + Navigator.of(context).push(FadePage(page: RegisterNew())), }, - cancelFunction: () => {ConfirmDialog.closeAlertDialog(context)}); + cancelFunction: () => {}); dialog.showAlertDialog(context); + projectViewModel.analytics.loginRegistration + .login_fail(error: err.toString()); + }); + } + + activatePatientFile() { + GifLoaderDialogUtils.showMyDialog(context); + Map request = {}; + request["IsActive"] = true; + if (this.loginType == 1) { + request['PatientIdentificationID'] = int.parse(nationalIDorFile.text); + } else { + request['PatientID'] = int.parse(nationalIDorFile.text); + } + request["PatientMobileNumber"] = mobileNo; + authService.deactivateAccount(request, true).then((result) { + GifLoaderDialogUtils.hideDialog(context); + checkUserAuthentication(); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); }); - // SMSOTP.showLoadingDialog(context, false), } checkActivationCode({code}) async { Map request = {}; - // request.logInTokenID = await sharedPref.getString(LOGIN_TOKEN_ID); - // request.activationCode = code ?? "0000"; - // request.isSilentLogin = code != null ? false : true; - if (code == null) - //showLoader(true); - request['PatientMobileNumber'] = int.parse(mobileNo); + if (code == null) request['PatientMobileNumber'] = int.parse(mobileNo!); request['ZipCode'] = countryCode; request['SearchType'] = loginType; request['LoginType'] = loginType; @@ -248,34 +356,40 @@ class _Login extends State { request['PatientIdentificationID'] = ''; request['PatientID'] = int.parse(nationalIDorFile.text); } - // request.isRegister = false; this.authService.checkActivationCode(request, code).then((result) async { sharedPref.remove(FAMILY_FILE); - // Register GeoZones after login - registerGeoZones(); + // registerGeoZones(); projectViewModel.setPrivilege(privilegeList: result); result = CheckActivationCode.fromJson(result); result.list.isFamily = false; - // this.sharedPref.setString(BLOOD_TYPE, result['PatientBloodType']), - this.sharedPref.setObject(USER_PROFILE, result.list); - this.sharedPref.setObject(MAIN_USER, result.list); - this.sharedPref.setObject(LOGIN_TOKEN_ID, result.logInTokenID); - this.sharedPref.setString(TOKEN, result.authenticationTokenID); + await this.sharedPref.setString(BLOOD_TYPE, + result.patientBloodType != null ? result.patientBloodType : ""); + await this.sharedPref.setObject(USER_PROFILE, result.list); + await this.sharedPref.setObject(MAIN_USER, result.list); + await this.sharedPref.setObject(LOGIN_TOKEN_ID, result.logInTokenID); + await this.sharedPref.setString(TOKEN, result.authenticationTokenID); await authenticatedUserObject.getUser(getUser: true); authenticatedUserObject.isLogin = true; appointmentRateViewModel.isLogin = true; projectViewModel.isLogin = true; + authenticatedUserObject.user = result.list; projectViewModel.user = authenticatedUserObject.user; - await pharmacyModuleViewModel.generatePharmacyToken().then((value) async { - if (pharmacyModuleViewModel.error.isNotEmpty) - await pharmacyModuleViewModel.createUser(); - }); - + // GifLoaderDialogUtils.hideDialog(context); + // + // getToDoCount(); + // + // Navigator.pushAndRemoveUntil( + // context, + // FadePage( + // page: LandingPage(), + // ), + // (r) => false); + getToDoCount(); + checkIfIsInPatient(); appointmentRateViewModel - .getIsLastAppointmentRatedList() + .getIsLastAppointmentRatedList(projectViewModel.isArabic ? 1 : 2) .then((value) => { - getToDoCount(), GifLoaderDialogUtils.hideDialog(context), if (appointmentRateViewModel.isHaveAppointmentNotRate) { @@ -304,25 +418,83 @@ class _Login extends State { } getToDoCount() { - toDoProvider.setState(0, true); + toDoProvider.setState(0, 0, true, toDoProvider.notificationsCount); ClinicListService service = new ClinicListService(); service.getActiveAppointmentNo(context).then((res) { - print(res['AppointmentActiveNumber']); + //print(res['AppointmentActiveNumber']); if (res['MessageStatus'] == 1) { - toDoProvider.setState(res['AppointmentActiveNumber'], true); + // toDoProvider.setState(res['AppointmentActiveNumber'], true, toDoProvider.notificationsCount); + toDoProvider.setState(res['AppointmentActiveNumber'], res['AncillaryOrderListCount'], true, toDoProvider.notificationsCount); + } else {} }).catchError((err) { print(err); }); } - void registerGeoZones() { + checkIfIsInPatient() async { + bool isAdmitted = false; + bool hasAdmissionRequest = false; + GetAdmissionInfoResponseModel getAdmissionInfoResponseModel; + GetAdmissionRequestInfoResponseModel getAdmissionRequestInfoResponseModel; + ClinicListService? service = new ClinicListService(); + dynamic res = await service.checkIfInPatientAPI(context); + if (res != null) { + if (res['MessageStatus'] == 1) { + isAdmitted = res['isAdmitted']; + hasAdmissionRequest = res['hasAdmissionRequests']; + print("IS ADMITTED: $isAdmitted"); + print("Has Admission Request: $hasAdmissionRequest"); + if (isAdmitted) { + if (res['PatientAdmittedInformation'].length != 0) { + getAdmissionInfoResponseModel = + GetAdmissionInfoResponseModel.fromJson( + res['PatientAdmittedInformation'][0]); + projectViewModel.setInPatientProjectID( + res['PatientAdmittedInformation'][0]['ProjectID']); + projectViewModel + .setInPatientAdmissionInfo(getAdmissionInfoResponseModel); + projectViewModel.setIsPatientAdmitted(true); + } + } + if (hasAdmissionRequest) { + if (res['MedicalInstruction'].length != 0) { + getAdmissionRequestInfoResponseModel = + GetAdmissionRequestInfoResponseModel.fromJson( + res['MedicalInstruction'][0]); + projectViewModel.setInPatientProjectID( + res['MedicalInstruction'][0]['projectId']); + projectViewModel.setInPatientAdmissionRequest( + getAdmissionRequestInfoResponseModel); + projectViewModel.setPatientHasAdmissionRequest(true); + } + } + } + } + } + + void registerGeoZones() async { + await locator().getAllGeoZones(GeoZonesRequestModel()); projectViewModel.platformBridge().registerHmgGeofences(); } -// showLoader(bool isTrue) { -// setState(() { -// isLoading = isTrue; -// }); -// } + getRegisterData() async { + var registerData = await sharedPref.getObject(REGISTER_DATA_FOR_LOGIIN); + await sharedPref.remove(REGISTER_DATA_FOR_LOGIIN); + + if (registerData != null) { + setState(() { + this.nationalIDorFile.text = + registerData['PatientIdentificationID'].toString(); + this.isButtonDisabled = false; + this.loginType = 1; + this.mobileNo = registerData['PatientMobileNumber'].toString(); + }); + } + + // var voipToken = await sharedPref.getString("VOIPToken"); + // setState(() { + // nationalIDorFile.text = voipToken; + // }); + } } diff --git a/lib/pages/login/register-info.dart b/lib/pages/login/register-info.dart index 467068cc..c2c78182 100644 --- a/lib/pages/login/register-info.dart +++ b/lib/pages/login/register-info.dart @@ -1,27 +1,51 @@ +import 'dart:convert'; + +import 'package:auto_size_text/auto_size_text.dart'; +import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; +import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/config/size_config.dart'; +import 'package:diplomaticquarterapp/core/service/AuthenticatedUserObject.dart'; +import 'package:diplomaticquarterapp/core/viewModels/appointment_rate_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/locator.dart'; +import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart'; +import 'package:diplomaticquarterapp/models/Authentication/check_activation_code_response.dart' as checkActivation; import 'package:diplomaticquarterapp/models/Authentication/check_paitent_authentication_req.dart'; +import 'package:diplomaticquarterapp/models/Authentication/countries_list.dart'; +import 'package:diplomaticquarterapp/models/Authentication/get_patient_occupation_list_response.dart'; import 'package:diplomaticquarterapp/models/Authentication/register_info_response.dart'; -import 'package:diplomaticquarterapp/models/Authentication/register_user_requet.dart'; -import 'package:diplomaticquarterapp/pages/login/login-type.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/dialog/clinic_list_dialog.dart'; +import 'package:diplomaticquarterapp/pages/insurance/insurance_update_screen.dart'; +import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; +import 'package:diplomaticquarterapp/pages/rateAppointment/rate_appointment_doctor.dart'; import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; +import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; -import 'package:diplomaticquarterapp/widgets/input/text_field.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/text/app_texts_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:hijri/hijri_calendar.dart'; import 'package:intl/intl.dart'; +import 'package:provider/provider.dart'; class RegisterInfo extends StatefulWidget { + final Function? changePageViewIndex; + final int page; + + const RegisterInfo({Key? key, this.changePageViewIndex, this.page = 1}) : super(key: key); + @override _RegisterInfo createState() => _RegisterInfo(); } @@ -29,339 +53,616 @@ class RegisterInfo extends StatefulWidget { class _RegisterInfo extends State { final authService = new AuthProvider(); final sharedPref = new AppSharedPreferences(); - RegisterInfoResponse registerInfo; - bool isLoading; - int page = 1; + RegisterInfoResponse registerInfo = RegisterInfoResponse(); + late bool isLoading; + late int page; final List locationList = [ - new Location(name: 'KSA', value: '1'), - new Location(name: 'Dubai', value: '2'), + new Location(name: 'KSA', value: '1', nameAr: "السعودية"), + new Location(name: 'Dubai', value: '2', nameAr: "دبي"), ]; String language = '1'; - var registerd_data; + late CheckPatientAuthenticationReq registerd_data; final List languageList = [ - new Language(name: 'English', value: '2'), - new Language(name: 'Arabic', value: '1'), + new Language(name: 'English', value: '2', nameAr: "إنجليزي"), + new Language(name: 'Arabic', value: '1', nameAr: "عربي"), + ]; + final List genderList = [ + new Language(name: 'Male', value: 'M', nameAr: "ذكر"), + new Language(name: 'Female', value: 'F', nameAr: "أنثى"), + ]; + final List maritalList = [ + new Language(name: 'Married', value: 'M', nameAr: "متزوج"), + new Language(name: 'Single', value: 'S', nameAr: "اعزب"), + new Language(name: 'Divorce', value: 'D', nameAr: "الطلاق"), ]; String email = ''; - + List countriesList = []; + late ToDoCountProviderModel toDoProvider; String location = '1'; + AuthenticatedUserObject authenticatedUserObject = locator(); + + late ProjectViewModel projectViewModel; + + AppointmentRateViewModel appointmentRateViewModel = locator(); + bool isDubai = false; + RegisterInfoResponse data = RegisterInfoResponse(); + late CheckPatientAuthenticationReq data2; + String gender = 'M'; + String maritalStatus = 'M'; + String nationality = 'SAU'; + String selectedOccupationID = ""; + + // List patientOccupationList = []; + // GetPatientOccupationListResponse? selectedPatientOccupation; + + final GlobalKey projectDropdownKey = GlobalKey(); @override void initState() { + if (widget.page == 1) { + getCountries(); + // getPatientOccupationList(); + } WidgetsBinding.instance.addPostFrameCallback((timeStamp) { getRegisterInfo(); }); + page = widget.page; super.initState(); } @override Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + toDoProvider = Provider.of(context); return AppScaffold( appBarTitle: TranslationBase.of(context).register, - isShowAppBar: true, + isShowAppBar: false, isShowDecPage: false, body: SingleChildScrollView( - padding: EdgeInsets.all(20), - child: Column(children: [ - AppText( - TranslationBase.of(context).patientInfo, - fontSize: SizeConfig.textMultiplier * 3, - textAlign: TextAlign.left, + padding: EdgeInsets.all(30), + child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ + Row( + children: [ + Expanded( + child: AppText( + TranslationBase.of(context).personalInfo, + fontSize: 16, + textAlign: TextAlign.left, + fontWeight: FontWeight.bold, + ), + ), + Expanded(child: SizedBox()) + ], ), - registerInfo != null && page == 1 + SizedBox(height: 10), + (isDubai && page == 1) ? Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - AppText(TranslationBase.of(context).nationalID), - Container( - margin: EdgeInsets.only(bottom: 10), - child: TextFields( - hintText: registerInfo.idNumber, - prefixIcon: Icon(Icons.chrome_reader_mode, - color: Colors.red), - padding: EdgeInsets.only( - top: 20, bottom: 20, left: 10, right: 10), - readOnly: true, - )), - AppText(TranslationBase.of(context).firstName), - Container( - margin: EdgeInsets.only(bottom: 10), - child: TextFields( - hintText: registerInfo.firstNameEn == '-' - ? registerInfo.firstNameAr - : registerInfo.firstNameEn, - padding: EdgeInsets.only( - top: 20, bottom: 20, left: 10, right: 10), - readOnly: true, - )), - AppText(TranslationBase.of(context).middleName), - Container( - margin: EdgeInsets.only(bottom: 10), - child: TextFields( - hintText: registerInfo.secondNameEn == '-' - ? registerInfo.secondNameAr - : registerInfo.secondNameEn, - padding: EdgeInsets.only( - top: 20, bottom: 20, left: 10, right: 10), - readOnly: true, - )), - AppText(TranslationBase.of(context).lastName), - Container( - margin: EdgeInsets.only(bottom: 10), - child: TextFields( - hintText: registerInfo.lastNameEn == '-' - ? registerInfo.lastNameAr - : registerInfo.lastNameEn, - padding: EdgeInsets.only( - top: 20, bottom: 20, left: 10, right: 10), - readOnly: true, - )), - AppText(TranslationBase.of(context).gender), - Container( - margin: EdgeInsets.only(bottom: 10), - child: TextFields( - hintText: registerInfo.maritalStatusCode == 'U' - ? 'Unknown' - : registerInfo.maritalStatusCode == 'M' - ? 'Male' - : 'Female', - padding: EdgeInsets.only( - top: 20, bottom: 20, left: 10, right: 10), - readOnly: true, - )), - AppText(TranslationBase.of(context).maritalStatus), - Container( - margin: EdgeInsets.only(bottom: 10), - child: TextFields( - hintText: registerInfo.maritalStatus, - padding: EdgeInsets.only( - top: 20, bottom: 20, left: 10, right: 10), - readOnly: true, - )), - AppText(TranslationBase.of(context).nationality), - Container( - margin: EdgeInsets.only(bottom: 10), - child: TextFields( - hintText: registerInfo.nationalityCode, - padding: EdgeInsets.only( - top: 20, bottom: 20, left: 10, right: 10), - readOnly: true, - )), - AppText(TranslationBase.of(context).mobileNumber), - Container( - margin: EdgeInsets.only(bottom: 10), - child: TextFields( - hintText: - registerd_data.patientMobileNumber.toString(), - padding: EdgeInsets.only( - top: 20, bottom: 20, left: 10, right: 10), - readOnly: true, - )), - AppText(TranslationBase.of(context).dob), - Container( - margin: EdgeInsets.only(bottom: 10), - child: TextFields( - hintText: registerInfo.dateOfBirth, - padding: EdgeInsets.only( - top: 20, bottom: 20, left: 10, right: 10), - readOnly: true, - )), - ], - ) - : registerInfo != null && page == 2 - ? Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AppText(TranslationBase.of(context).language, - textAlign: TextAlign.start), + children: [ + SizedBox(height: 20), + getnameField(TranslationBase.of(context).identificationNumber, registerd_data.patientIdentificationID, TranslationBase.of(context).mobileNumber, + registerd_data.patientMobileNumber.toString()), + // SizedBox(height: 20), + projectViewModel.isArabic + ? getnameField( + '', + inputWidget("First Name", "First Name English", 'fNameEn'), + '', + inputWidget("Last Name", "Last Name English", 'lNameEn'), + ) + : SizedBox( + height: 0, + ), + getnameField( + '', + inputWidget(TranslationBase.of(context).firstName, TranslationBase.of(context).firstName, 'fName'), + '', + inputWidget(TranslationBase.of(context).middleName, TranslationBase.of(context).middleName, 'sName'), + ), + + getnameField( + '', + inputWidget(TranslationBase.of(context).lastName, TranslationBase.of(context).lastName, 'lName'), + TranslationBase.of(context).gender, + Container( + height: 20, + child: DropdownButtonHideUnderline( + child: DropdownButton( + isExpanded: true, + value: gender, + hint: Text(TranslationBase.of(context).gender), + iconSize: 40, + elevation: 16, + onChanged: (value) => { + setState(() { + gender = value!; + registerInfo.gender = value; + }) + }, + items: genderList.map>((Language value) { + return DropdownMenuItem( + value: value.value, + child: Text( + projectViewModel.isArabic == 1 ? value.nameAr! : value.name!, + ), + ); + }).toList()))), + ), + SizedBox(height: 20), + getnameField( + TranslationBase.of(context).maritalStatus, Container( - padding: EdgeInsets.all(10), - decoration: BoxDecoration( - color: Colors.white, - border: Border.all(color: Colors.grey), - borderRadius: BorderRadius.circular(10)), + height: 18, child: DropdownButtonHideUnderline( child: DropdownButton( isExpanded: true, - value: language, + value: maritalStatus, + hint: Text(TranslationBase.of(context).maritalStatus), iconSize: 40, elevation: 16, onChanged: (value) => { setState(() { - language = value; + maritalStatus = value!; + registerInfo.maritalStatusCode = value; }) }, - items: languageList - .map>( - (Language value) { + items: maritalList.map>((Language value) { return DropdownMenuItem( value: value.value, - child: Text(value.name), + child: Text( + projectViewModel.isArabic == 1 ? value.nameAr! : value.name!, + ), ); }).toList()))), - AppText(TranslationBase.of(context).location), + TranslationBase.of(context).nationality, Container( - padding: EdgeInsets.all(10), - decoration: BoxDecoration( - color: Colors.white, - border: Border.all(color: Colors.grey), - borderRadius: BorderRadius.circular(10)), + height: 22, child: DropdownButtonHideUnderline( child: DropdownButton( isExpanded: true, - value: location, + value: nationality, + hint: Text(TranslationBase.of(context).nationality), iconSize: 40, elevation: 16, onChanged: (value) => { setState(() { - location = value; + nationality = value!; + registerInfo.nationalityCode = value; }) }, - items: locationList - .map>( - (Location value) { + items: countriesList.map>((CountriesLists value) { return DropdownMenuItem( - value: value.value, - child: Text(value.name), + value: value.iD, + child: Text( + value.name!, + ), ); - }).toList()))), - AppText(TranslationBase.of(context).email), - Container( - margin: EdgeInsets.only(bottom: 10), - child: TextFields( - onChanged: (value) => { - setState(() { - email = value; - }) - }, - padding: EdgeInsets.only( - top: 20, bottom: 20, left: 10, right: 10), - )), + }).toList())))), + SizedBox(height: 20), + getnameField(TranslationBase.of(context).dateOfBirth, registerd_data.dob, "", ""), + SizedBox(height: 20), + ], + ) + : (registerInfo.healthId != null && page == 1) + ? Column( + children: [ + SizedBox(height: 10), + getnameField(TranslationBase.of(context).identificationNumber, registerInfo.idNumber, TranslationBase.of(context).firstName, + registerInfo.firstNameEn == '-' ? registerInfo.firstNameAr : registerInfo.firstNameEn), + SizedBox(height: 10), + getnameField(TranslationBase.of(context).middleName, registerInfo.secondNameEn == '-' ? registerInfo.secondNameEn : registerInfo.secondNameEn, + TranslationBase.of(context).lastName, registerInfo.lastNameEn == '-' ? registerInfo.lastNameEn : registerInfo.lastNameEn), + SizedBox(height: 10), + getnameField( + TranslationBase.of(context).gender, + registerInfo.maritalStatusCode == 'U' + ? 'Unknown' + : registerInfo.maritalStatusCode == 'M' + ? 'Male' + : 'Female', + TranslationBase.of(context).maritalStatus, + registerInfo.maritalStatus), + SizedBox(height: 10), + getnameField(TranslationBase.of(context).nationality, registerInfo.nationality, TranslationBase.of(context).mobileNumber, registerd_data.patientMobileNumber.toString()), + SizedBox(height: 10), + getnameField(TranslationBase.of(context).dateOfBirth, registerInfo.dateOfBirth, "", ""), ], ) - : SizedBox(), - Column( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - Row( - children: [ - Expanded( - child: DefaultButton( - page == 1 - ? TranslationBase.of(context).next - : TranslationBase.of(context).register, - () => {nextPage()}, - textColor: Colors.white, - color: this.isValid() == false && page == 2 - ? Colors.grey - : Colors.black, - )) - ], + : widget.page == 2 + ? Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // (!isDubai) + // ? Container( + // width: double.infinity, + // decoration: containerRadius(Colors.white, 12), + // padding: EdgeInsets.only(left: 10, right: 10, top: 12, bottom: 12), + // child: Row( + // children: [ + // Flexible( + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // Text( + // TranslationBase.of(context).selectOccupation, + // style: TextStyle( + // fontSize: 11, + // letterSpacing: -0.44, + // fontWeight: FontWeight.w600, + // ), + // ), + // Container( + // height: 18, + // width: double.infinity, + // child: DropdownButtonHideUnderline( + // child: DropdownButton( + // key: projectDropdownKey, + // hint: Text(TranslationBase.of(context).selectOccupation), + // value: selectedPatientOccupation, + // iconSize: 0, + // isExpanded: true, + // style: TextStyle(fontSize: 14, letterSpacing: -0.56, color: Colors.black), + // items: patientOccupationList.map((GetPatientOccupationListResponse item) { + // return DropdownMenuItem( + // value: item, + // child: AutoSizeText( + // projectViewModel.isArabic ? item.descriptionN! : item.description!, + // maxLines: 1, + // minFontSize: 10, + // style: TextStyle( + // fontSize: SizeConfig.textMultiplier! * 1.6, + // fontWeight: FontWeight.w600, + // letterSpacing: -0.39, + // height: 0.8, + // ), + // ), + // // Text('${item.name!}'), + // ); + // }).toList(), + // onChanged: (GetPatientOccupationListResponse? newValue) { + // setState(() { + // selectedPatientOccupation = newValue!; + // selectedOccupationID = selectedPatientOccupation!.occupationID!; + // registerInfo.occupationID = selectedOccupationID; + // }); + // debugPrint("Selected Occupation ID: ${registerInfo.occupationID}"); + // }, + // ), + // ), + // ), + // ], + // ), + // ), + // Icon(Icons.keyboard_arrow_down), + // ], + // )) + // : SizedBox(), + mHeight(20), + Container( + width: double.infinity, + decoration: containerRadius(Colors.white, 12), + padding: EdgeInsets.only(left: 10, right: 10, top: 5, bottom: 25), + child: Row(children: [ + Flexible( + child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ + Text( + TranslationBase.of(context).prefferedLanguage, + style: TextStyle( + fontSize: 11, + letterSpacing: -0.44, + fontWeight: FontWeight.w600, + ), + ), + Container( + height: 18, + child: DropdownButtonHideUnderline( + child: DropdownButton( + isExpanded: true, + value: language, + hint: Text(TranslationBase.of(context).prefferedLanguage), + iconSize: 40, + elevation: 16, + onChanged: (value) => { + setState(() { + language = value!; + }) + }, + items: languageList.map>((Language value) { + return DropdownMenuItem( + value: value.value, + child: Text( + projectViewModel.isArabic == 1 ? value.nameAr! : value.name!, + ), + ); + }).toList()))) + ])) + ])), + SizedBox( + height: 20, + ), + Container( + width: double.infinity, + decoration: containerRadius(Colors.white, 12), + padding: EdgeInsets.only(left: 10, right: 10, top: 5, bottom: 25), + child: Row(children: [ + Flexible( + child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ + Text( + TranslationBase.of(context).selectLocation, + style: TextStyle( + fontSize: 11, + letterSpacing: -0.44, + fontWeight: FontWeight.w600, + ), + ), + Container( + height: 18, + child: DropdownButtonHideUnderline( + child: DropdownButton( + isExpanded: true, + value: location, + hint: Text(TranslationBase.of(context).selectLocation), + iconSize: 40, + elevation: 16, + onChanged: (value) => { + setState(() { + location = value!; + }) + }, + items: locationList.map>((Location value) { + return DropdownMenuItem( + value: value.value, + child: Text( + projectViewModel.isArabic == 1 ? value.nameAr! : value.name!, + ), + ); + }).toList()))) + ])) + ])), + SizedBox( + height: 20, + ), + Container( + width: double.infinity, + decoration: containerRadius(Colors.white, 12), + padding: EdgeInsets.only(left: 10, right: 10, top: 5, bottom: 12), + margin: EdgeInsets.only(bottom: 0), + child: Row(children: [ + Flexible( + child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ + Text( + TranslationBase.of(context).email, + style: TextStyle( + fontSize: 11, + letterSpacing: -0.44, + fontWeight: FontWeight.w600, + ), + ), + Container( + child: TextField( + keyboardType: TextInputType.emailAddress, + onChanged: (value) { + setState(() { + email = value; + }); + }, + style: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: Color(0xff2B353E), + letterSpacing: -0.44, + ), + decoration: InputDecoration( + isDense: true, + hintStyle: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: Color(0xff575757), + letterSpacing: -0.56, + ), + prefixIconConstraints: BoxConstraints(minWidth: 50), + contentPadding: EdgeInsets.zero, + border: InputBorder.none, + focusedBorder: InputBorder.none, + enabledBorder: InputBorder.none, + ), + )) + ])) + ])), + ], + ) + : SizedBox(), + ]), + ), + bottomSheet: Container( + width: double.maxFinite, + height: 80.0, + child: Row( + children: [ + Expanded( + child: Padding( + padding: EdgeInsets.all(10), + child: DefaultButton(TranslationBase.of(context).cancel, () { + Navigator.of(context).pop(); + // widget.changePageViewIndex!(0); + // getPatientOccupationList(); + locator().loginRegistration.registration_cancel(step: page == 1 ? 'personal info' : 'other details'); + }, textColor: Colors.white, color: Color(0xffD02127))), + ), + Expanded( + child: Padding( + padding: EdgeInsets.all(10), + child: DefaultButton(page == 1 ? TranslationBase.of(context).next : TranslationBase.of(context).register, () { + nextPage(); + page == 1 ? locator().loginRegistration.registration_personal_info() : locator().loginRegistration.registration_patient_info(); + }, textColor: Colors.white, color: isValid() == true ? Color(0xff359846) : Colors.grey)), ), ], - ) - ]), - )); + ))); } - nextPage() { + nextPage() async { if (page == 1) { - setState(() { - page++; - }); + if (isDubai) { + await setRegisterData(); + widget.changePageViewIndex!(2); + } else { + widget.changePageViewIndex!(2); + } } else { registerNow(); + + // if (isDubai) { + // registerNow(); + // } else { + // if (selectedPatientOccupation != null) { + // registerNow(); + // } else { + // AppToast.showErrorToast(message: TranslationBase.of(context).selectOccupationError); + // } + // } } } + setRegisterData() async { + registerInfo.gender = gender; + registerInfo.maritalStatusCode = maritalStatus; + registerInfo.nationalityCode = nationality; + projectViewModel.setRegisterData(registerInfo); + // await sharedPref.setObject(REGISTER_INFO_DUBAI, registerInfo); + } + registerNow() { - dynamic request = getTempUserRequest(); - GifLoaderDialogUtils.showMyDialog(context); - this.authService.registerUser(request).then((result) => { - GifLoaderDialogUtils.hideDialog(context), - // userData = result.list; - //AuthenticatedUser.fromJson(result['List'][0]), - if(result is String){ - new ConfirmDialog( - context: context, - confirmMessage: result, - okText: TranslationBase.of(context).ok, - cancelText: TranslationBase.of(context).cancel_nocaps, - okFunction: () => { - ConfirmDialog.closeAlertDialog(context) - }, - cancelFunction: () => {ConfirmDialog.closeAlertDialog(context)}) - .showAlertDialog(context) - - }else - { - result.list.isFamily = false, - sharedPref.setObject(USER_PROFILE, result.list), - this.sharedPref.setObject(MAIN_USER, result.list), - sharedPref.setObject(LOGIN_TOKEN_ID, result.logInTokenID), - sharedPref.setString(TOKEN, result.authenticationTokenID), - Navigator.of(context).pushNamed(HOME) - } - }).catchError((err) { - GifLoaderDialogUtils.hideDialog(context); + dynamic request; + + if (isDubai) + request = getTempUserRequestDubai(); + else + request = getTempUserRequest(); + + print(request); + + GifLoaderDialogUtils.showMyDialog(context, barrierDismissible: true); + dynamic res; + this + .authService + .registerUser(request) + .then((result) async => { + if (result is String) + { + GifLoaderDialogUtils.hideDialog(context), + new ConfirmDialog( + context: context, + confirmMessage: result, + okText: TranslationBase.of(context).ok, + cancelText: TranslationBase.of(context).cancel_nocaps, + okFunction: () => {ConfirmDialog.closeAlertDialog(context)}, + cancelFunction: () => {ConfirmDialog.closeAlertDialog(context)}).showAlertDialog(context) + } + else + { + res = result, + result = checkActivation.CheckActivationCode.fromJson(result), + // result.list.isFamily = false, + // sharedPref.setObject(USER_PROFILE, result.list), + // this.sharedPref.setObject(MAIN_USER, result.list), + // sharedPref.setObject(LOGIN_TOKEN_ID, result.logInTokenID), + // sharedPref.setString(TOKEN, result.authenticationTokenID), + // this.setUser(result), + sharedPref.remove(FAMILY_FILE), + result.list.isFamily = false, + + await sharedPref.setString(BLOOD_TYPE, result.patientBloodType ?? ""), + authenticatedUserObject.user = result.list, + projectViewModel.setPrivilege(privilegeList: res), + await sharedPref.setObject(MAIN_USER, result.list), + await sharedPref.setObject(USER_PROFILE, result.list), + + await sharedPref.setObject(LOGIN_TOKEN_ID, result.logInTokenID), + await sharedPref.setString(TOKEN, result.authenticationTokenID), + AppToast.showSuccessToast(message: TranslationBase.of(context).successRegister), + checkIfUserAgreedBefore(result), + projectViewModel.analytics.loginRegistration.registration_confirmation() + } + }) + .catchError((err) { + // GifLoaderDialogUtils.hideDialog(context); ConfirmDialog dialog = new ConfirmDialog( context: context, confirmMessage: err, okText: TranslationBase.of(context).confirm, cancelText: TranslationBase.of(context).cancel_nocaps, - okFunction: () => { - ConfirmDialog.closeAlertDialog(context) - }, + okFunction: () => {ConfirmDialog.closeAlertDialog(context)}, cancelFunction: () => {ConfirmDialog.closeAlertDialog(context)}); dialog.showAlertDialog(context); - + projectViewModel.analytics.loginRegistration.registration_fail(errorType: ""); }); } + setUser(result) async { + await authenticatedUserObject.getUser(getUser: true); + authenticatedUserObject.isLogin = true; + appointmentRateViewModel.isLogin = true; + projectViewModel.isLogin = true; + authenticatedUserObject.user = result.list; + Navigator.of(context).pushNamed(HOME); + } + getRegisterInfo() async { - var data = - RegisterInfoResponse.fromJson(await sharedPref.getObject(NHIC_DATA)); + if (await sharedPref.getObject(NHIC_DATA) != null) { + data = RegisterInfoResponse.fromJson(await sharedPref.getObject(NHIC_DATA)); + this.registerInfo = data; + } if (await sharedPref.getObject(REGISTER_DATA_FOR_LOGIIN) != null) { - var data2 = CheckPatientAuthenticationReq.fromJson( - await sharedPref.getObject(REGISTER_DATA_FOR_LOGIIN)); + data2 = CheckPatientAuthenticationReq.fromJson(await sharedPref.getObject(REGISTER_DATA_FOR_LOGIIN)); setState(() { - this.registerInfo = data; - this.registerd_data = data2; + isDubai = data2.patientOutSA == 1 ? true : false; + if (isDubai) location = '2'; }); } + + // try { + // var patientOccupationListVal = json.decode(await sharedPref.getString(PATIENT_OCCUPATION_LIST)); + // patientOccupationListVal.forEach((v) { + // patientOccupationList.add(new GetPatientOccupationListResponse.fromJson(v)); + // }); + // setState(() {}); + // } catch (ex) { + // print(ex.toString()); + // } } getTempUserRequest() { DateFormat dateFormat = DateFormat("mm/dd/yyyy"); - print(dateFormat.parse(registerInfo.dateOfBirth)); - var hDate = - new HijriCalendar.fromDate(dateFormat.parse(registerInfo.dateOfBirth)); + print(dateFormat.parse(registerInfo.dateOfBirth!)); + var hDate = new HijriCalendar.fromDate(dateFormat.parse(registerInfo.dateOfBirth!)); var date = hDate.toString(); return { "Patientobject": { "TempValue": true, - "PatientIdentificationType": 1, + "PatientIdentificationType": registerInfo.idNumber!.substring(0, 1) == "1" ? 1 : 2, "PatientIdentificationNo": registerInfo.idNumber, "MobileNumber": registerd_data.patientMobileNumber, - "PatientOutSA": registerd_data.zipCode == '966' ? 0 : 1, - "FirstNameN":registerInfo.firstNameAr =='-' ?"": registerInfo.firstNameAr, - "FirstName": registerInfo.firstNameEn =='-' ?"":registerInfo.firstNameEn, - "MiddleNameN":registerInfo.secondNameAr =='-' ? "" : registerInfo.secondNameAr, - "MiddleName":registerInfo.secondNameEn == '-' ? "": registerInfo.secondNameEn, - "LastNameN": registerInfo.lastNameAr =='-'? "" : registerInfo.lastNameAr, - "LastName": registerInfo.lastNameEn =='-' ? "": registerInfo.lastNameEn, + "PatientOutSA": (registerd_data.zipCode == '966' || registerd_data.zipCode == '+966') ? 0 : 1, + "FirstNameN": registerInfo.firstNameAr, + "FirstName": registerInfo.firstNameEn, + "MiddleNameN": registerInfo.secondNameAr, + "MiddleName": registerInfo.secondNameEn, + "LastNameN": registerInfo.lastNameAr, + "LastName": registerInfo.lastNameEn, "StrDateofBirth": registerInfo.dateOfBirth, - "DateofBirth": DateUtil.convertISODateToJsonDate( - registerInfo.dateOfBirth.replaceAll('/', '-')), + "DateofBirth": DateUtil.convertISODateToJsonDate(registerInfo.dateOfBirth!.replaceAll('/', '-')), "Gender": registerInfo.gender == 'M' ? 1 : 2, - "NationalityID": registerInfo.nationality, + "NationalityID": registerInfo.nationalityCode, + "eHealthIDField": registerInfo.healthId, "DateofBirthN": date, "EmailAddress": email, "SourceType": location, "PreferredLanguage": registerd_data.languageID.toString(), + // "OccupationID": registerInfo.occupationID, "Marital": registerInfo.maritalStatusCode == 'U' ? '0' : registerInfo.maritalStatusCode == 'M' @@ -369,29 +670,384 @@ class _RegisterInfo extends State { : '2', }, "PatientIdentificationID": registerInfo.idNumber, - "PatientMobileNumber": registerd_data.patientMobileNumber, + "PatientMobileNumber": registerd_data.patientMobileNumber.toString()[0] == '0' ? registerd_data.patientMobileNumber : '0' + registerd_data.patientMobileNumber.toString(), + }; + } + + getTempUserRequestDubai() { + DateFormat dateFormat = DateFormat("mm/dd/yyyy"); + registerInfo = projectViewModel.registerInfo; + print(dateFormat.parse(registerd_data.dob!)); + var hDate = new HijriCalendar.fromDate(dateFormat.parse(registerd_data.dob!)); + var date = hDate.toString(); + final DateFormat dateFormat1 = DateFormat('MM/dd/yyyy'); + final DateFormat dateFormat2 = DateFormat('dd/MM/yyyy'); + + return { + "Patientobject": { + "TempValue": true, + "PatientIdentificationType": registerd_data.patientIdentificationID!.substring(0, 1) == "1" ? 1 : 2, + "PatientIdentificationNo": registerd_data.patientIdentificationID, + "MobileNumber": registerd_data.patientMobileNumber, + "PatientOutSA": (registerd_data.zipCode == '966' || registerd_data.zipCode == '+966') ? 0 : 1, + "FirstNameN": registerInfo.firstNameAr ?? "", + "FirstName": registerInfo.firstNameEn ?? "", + "MiddleNameN": registerInfo.secondNameAr ?? ".", + "MiddleName": registerInfo.secondNameEn ?? ".", + "LastNameN": registerInfo.lastNameAr ?? "", + "LastName": registerInfo.lastNameEn ?? "", + "StrDateofBirth": dateFormat1.format(dateFormat2.parse(registerd_data.dob!)), + "DateofBirth": DateUtil.convertISODateToJsonDate(registerd_data.dob!.replaceAll('/', '-')), + "Gender": registerInfo.gender == 'M' ? 1 : 2, + "NationalityID": registerInfo.nationalityCode, + "eHealthIDField": null, + "DateofBirthN": date, + "EmailAddress": email, + "SourceType": location, + "PreferredLanguage": registerd_data.languageID.toString(), + "Marital": registerInfo.maritalStatusCode == 'U' + ? '0' + : registerInfo.maritalStatusCode == 'M' + ? '1' + : '2', + }, + "PatientIdentificationID": registerd_data.patientIdentificationID, + "PatientMobileNumber": registerd_data.patientMobileNumber.toString()[0] == '0' ? registerd_data.patientMobileNumber : '0' + registerd_data.patientMobileNumber.toString(), + "DOB": registerd_data.dob, + "IsHijri": registerd_data.isHijri }; } bool isValid() { - if (location != null || - language != null || - Utils.validEmail(email) == true) { + if ((location != null && language != null && Utils.validEmail(email) == true) || + (registerInfo.firstNameEn != null && registerInfo.lastNameEn != null) || + (projectViewModel.isArabic && registerInfo.firstNameEn != null && registerInfo.firstNameAr != null && registerInfo.lastNameEn != null && registerInfo.lastNameAr != null)) { return true; } else { return false; } } + + Widget getnameField(name1, value1, name2, value2) { + return Row( + children: [ + Expanded( + child: Padding( + padding: EdgeInsets.only(left: 5, right: 5), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + name1, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.bold, + letterSpacing: -0.44, + ), + ), + value1 is String + ? Text( + value1, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + letterSpacing: -0.44, + ), + ) + : value1, + ], + ))), + Expanded( + child: Padding( + padding: EdgeInsets.only(left: 5, right: 5), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + name2, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.bold, + letterSpacing: -0.44, + ), + ), + value2 is String + ? Text( + value2, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + letterSpacing: -0.44, + ), + ) + : value2, + ], + ))) + ], + ); + } + + checkIfUserAgreedBefore(checkActivation.CheckActivationCode result) { + if (result.isNeedUserAgreement == true) { + //TODO need to implement agreement page here + insertIMEI(); + } else { + insertIMEI(); + } + } + + insertIMEI() async { + var selectedOption = await sharedPref.getInt(LAST_LOGIN); + authService.insertDeviceImei(selectedOption).then((value) => {goToHome()}).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } + + goToHome() async { + authenticatedUserObject.isLogin = true; + appointmentRateViewModel.isLogin = true; + projectViewModel.isLogin = true; + projectViewModel.user = authenticatedUserObject.user; + await authenticatedUserObject.getUser(getUser: true); + getToDoCount(); + GifLoaderDialogUtils.hideDialog(AppGlobal.context); + ConfirmDialog dialog = new ConfirmDialog( + context: context, + confirmMessage: TranslationBase.of(context).validInsurance, + okText: TranslationBase.of(context).yes, + cancelText: TranslationBase.of(context).no, + okFunction: () { + ConfirmDialog.closeAlertDialog(context); + Navigator.pushAndRemoveUntil( + context, + MaterialPageRoute(builder: (context) => LandingPage()), + (Route route) => false, + ); + Navigator.push(context, FadePage(page: InsuranceUpdate())); + }, + cancelFunction: () { + Navigator.pushAndRemoveUntil( + context, + MaterialPageRoute(builder: (context) => LandingPage()), + (Route route) => false, + ); + }); + dialog.showAlertDialog(context); + + // int languageID = Provider.of(context, listen: false).isArabic ? 1 : 2; + // appointmentRateViewModel.getIsLastAppointmentRatedList(languageID).then((value) { + // getToDoCount(); + // GifLoaderDialogUtils.hideDialog(AppGlobal.context); + // if (appointmentRateViewModel.isHaveAppointmentNotRate) { + // Navigator.pushAndRemoveUntil( + // context, + // FadePage( + // page: RateAppointmentDoctor(isFromRegistration: true), + // ), + // (r) => false); + // } else { + // ConfirmDialog dialog = new ConfirmDialog( + // context: context, + // confirmMessage: TranslationBase.of(context).validInsurance, + // okText: TranslationBase.of(context).yes, + // cancelText: TranslationBase.of(context).no, + // okFunction: () { + // ConfirmDialog.closeAlertDialog(context); + // Navigator.pushAndRemoveUntil( + // context, + // MaterialPageRoute(builder: (context) => LandingPage()), + // (Route route) => false, + // ); + // Navigator.push(context, FadePage(page: InsuranceUpdate())); + // }, + // cancelFunction: () { + // Navigator.pushAndRemoveUntil( + // context, + // MaterialPageRoute(builder: (context) => LandingPage()), + // (Route route) => false, + // ); + // }); + // dialog.showAlertDialog(context); + // } + // }).catchError((err) { + // print(err); + // //GifLoaderDialogUtils.hideDialog(context); + // }); + // SMSOTP.showLoadingDialog(context, false), + } + + getToDoCount() { + toDoProvider.setState(0, 0, true, "0"); + ClinicListService service = new ClinicListService(); + service.getActiveAppointmentNo(context).then((res) { + if (res['MessageStatus'] == 1) { + // toDoProvider.setState(res['AppointmentActiveNumber'], true, "0"); + toDoProvider.setState(res['AppointmentActiveNumber'], res['AncillaryOrderListCount'], true, "0"); + } else {} + }).catchError((err) { + print(err); + }); + } + + getCountries() { + ClinicListService service = new ClinicListService(); + service.getCountries().then((res) { + if (res['MessageStatus'] == 1) { + res['ListNationality'].forEach((items) => {countriesList.add(CountriesLists.fromJson(items))}); + + setState(() {}); + } + }).catchError((err) { + print(err); + }); + } + + Widget inputWidget(String _labelText, String _hintText, String name, {String? prefix, bool isEnable = true, bool hasSelection = false}) { + return Container( + padding: EdgeInsets.only(left: 10, right: 10, bottom: 5, top: 5), + 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: TextInputType.text, + // controller: _controller, + onChanged: (value) => { + setState(() { + switch (name) { + case 'fName': + { + if (projectViewModel.isArabic) { + registerInfo.firstNameAr = value; + } else { + registerInfo.firstNameEn = value; + registerInfo.firstNameAr = '...'; + } + } + break; + case 'sName': + { + if (projectViewModel.isArabic) { + registerInfo.secondNameAr = value.isEmpty ? "." : value; + registerInfo.secondNameEn = '...'; + } else { + registerInfo.secondNameEn = value.isEmpty ? "." : value; + registerInfo.secondNameAr = '...'; + } + } + break; + case 'lName': + { + if (projectViewModel.isArabic) { + registerInfo.lastNameAr = value; + } else { + registerInfo.lastNameEn = value; + registerInfo.lastNameAr = '...'; + } + } + break; + case 'fNameEn': + registerInfo.firstNameEn = value; + break; + case 'lNameEn': + registerInfo.lastNameEn = value; + break; + } + }) + //_controller.text =value + }, + 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, + ), + prefixIconConstraints: BoxConstraints(minWidth: 50), + contentPadding: EdgeInsets.zero, + border: InputBorder.none, + focusedBorder: InputBorder.none, + enabledBorder: InputBorder.none, + ), + ), + ], + ), + ), + if (hasSelection) Icon(Icons.keyboard_arrow_down_outlined), + ], + ), + ), + ); + } + + void openDropdown(GlobalKey key) { + GestureDetector? detector; + void searchForGestureDetector(BuildContext element) { + element.visitChildElements((element) { + if (element.widget != null && element.widget is GestureDetector) { + detector = element.widget as GestureDetector?; + // return false; + } else { + searchForGestureDetector(element); + } + // return true; + }); + } + + searchForGestureDetector(key.currentContext!); + assert(detector != null); + detector!.onTap!(); + } } class Language { - final String name; - final String value; - Language({this.name, this.value}); + final String? name; + final String? value; + final String? nameAr; + + Language({this.name, this.value, this.nameAr}); } class Location { - final String name; - final String value; - Location({this.name, this.value}); + final String? name; + final String? value; + final String? nameAr; + + Location({this.name, this.value, this.nameAr}); } diff --git a/lib/pages/login/register.dart b/lib/pages/login/register.dart index c6a3b872..fdb04362 100644 --- a/lib/pages/login/register.dart +++ b/lib/pages/login/register.dart @@ -1,10 +1,18 @@ +import 'dart:convert'; + +import 'package:diplomaticquarterapp/analytics/flows/login_registration.dart'; +import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/config/size_config.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/locator.dart'; import 'package:diplomaticquarterapp/models/Authentication/check_user_status_reponse.dart'; import 'package:diplomaticquarterapp/models/Authentication/check_user_status_req.dart'; import 'package:diplomaticquarterapp/models/Authentication/checkpatient_for_registration.dart'; +import 'package:diplomaticquarterapp/models/Authentication/get_patient_occupation_list_response.dart'; import 'package:diplomaticquarterapp/pages/login/confirm-login.dart'; import 'package:diplomaticquarterapp/pages/login/login-type.dart'; +import 'package:diplomaticquarterapp/pages/login/login.dart'; import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; @@ -14,15 +22,20 @@ import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/alert_dialog.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; -import 'package:diplomaticquarterapp/widgets/input/text_field.dart'; import 'package:diplomaticquarterapp/widgets/mobile-no/mobile_no.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:diplomaticquarterapp/widgets/text/app_texts_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_datetime_picker_plus/flutter_datetime_picker_plus.dart'; +import 'package:intl/intl.dart' as intl; +import 'package:provider/provider.dart'; class Register extends StatefulWidget { + final Function? changePageViewIndex; + + const Register({Key? key, this.changePageViewIndex}) : super(key: key); + @override _Register createState() => _Register(); } @@ -30,192 +43,278 @@ class Register extends StatefulWidget { class _Register extends State { final nationalIDorFile = TextEditingController(); final int loginType = LoginType.loginType; - String mobileNo; + late String mobileNo; String countryCode = '966'; var isHijri; final util = Utils(); - DateTime selectedDate; - String dob; + late DateTime selectedDate; + TextEditingController dob = TextEditingController(); + TextEditingController dobEn = TextEditingController(); + bool isButtonDisabled = true; final authService = new AuthProvider(); final sharedPref = new AppSharedPreferences(); - bool isLoading; + late bool isLoading; + + List patientOccupationList = []; + + GetPatientOccupationListResponse? selectedPatientOccupation; + + @override + void initState() { + getPatientOccupationList(); + super.initState(); + } @override Widget build(BuildContext context) { return AppScaffold( - appBarTitle: TranslationBase.of(context).register, - isShowAppBar: true, - isShowDecPage: false, - body: SingleChildScrollView( - child: Container( - padding: EdgeInsets.only(top: 10, left: 20, right: 20, bottom: 30), - height: SizeConfig.realScreenHeight * .9, - width: SizeConfig.realScreenWidth, - child: Column(children: [ - Expanded( - flex: 1, - child: AppText( - TranslationBase.of(context).enterNationalId, - fontSize: SizeConfig.textMultiplier * 3, - textAlign: TextAlign.left, - )), + appBarTitle: TranslationBase.of(context).register, + isShowAppBar: false, + isShowDecPage: false, + showNewAppBar: false, + showNewAppBarTitle: true, + body: Column( + children: [ + Expanded( + child: ListView( + padding: EdgeInsets.all(21), + physics: BouncingScrollPhysics(), + children: [ + SizedBox(height: 10), + Padding( + padding: EdgeInsets.all(10), + child: Text( + TranslationBase.of(context).enterNationalId, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64, height: 23 / 16), + )), + SizedBox(height: 10), + PhoneNumberSelectorWidget(onNumberChange: (value) => {mobileNo = value, validateForm()}, onCountryChange: (value) => countryCode = value), + SizedBox(height: 12), + Directionality(textDirection: TextDirection.ltr, child: inputWidget(TranslationBase.of(context).nationalIdNumber, "Xxxxxxxxx", nationalIDorFile)), + SizedBox(height: 20), + Row( + children: [ + Expanded( + child: Row( + children: [ + Radio( + value: 1, + groupValue: isHijri, + onChanged: (value) { + setState(() { + isHijri = value; + }); + validateForm(); + }, + ), + Text(TranslationBase.of(context).hijriDate), + ], + ), + ), + Expanded( + child: Row( + children: [ + Radio( + value: 0, + groupValue: isHijri, + onChanged: (value) { + setState(() { + isHijri = value; + }); + validateForm(); + }, + ), + Text(TranslationBase.of(context).gregorianDate), + ], + ), + ), + ], + ), + Row(children: [ + Container( + width: SizeConfig.realScreenWidth! * .89, + child: isHijri == 1 + ? Directionality( + textDirection: TextDirection.ltr, + child: inputWidget(TranslationBase.of(context).dob, "DD/MM/YYYYY", dob, + isNumber: false, + suffix: Icon( + Icons.calendar_today, + size: 16, + ))) + : Container( + child: InkWell( + onTap: () { + if (isHijri != null) _selectDate(context); + }, + child: Directionality( + textDirection: TextDirection.ltr, + child: inputWidget(TranslationBase.of(context).dob, "DD/MM/YYYYY", dobEn, + isNumber: false, + isEnable: false, + suffix: Icon( + Icons.calendar_today, + size: 16, + )))))), + ]) + ], + ), + ), + Container( + width: double.maxFinite, + // height: 80.0, + color: Colors.white, + // margin: EdgeInsets.only(bottom: 50.0), + child: Row( + children: [ + Expanded( + child: Padding( + padding: EdgeInsets.all(10), + child: DefaultButton(TranslationBase.of(context).cancel, () { + Navigator.of(context).pop(); + locator().loginRegistration.registration_cancel(step: 'enter details'); + }, textColor: Colors.white, color: Color(0xffD02127))), + ), + Expanded( + child: Padding( + padding: EdgeInsets.all(10), + child: DefaultButton(TranslationBase.of(context).next, () { + startRegistration(); + locator().loginRegistration.registration_enter_details(); + }, textColor: Colors.white, color: isButtonDisabled == true ? Colors.grey : Color(0xff359846))), + ), + ], + ), + ) + ], + ), + ); + } + + Future _selectDate(BuildContext context) async { + DatePicker.showDatePicker( + context, + showTitleActions: true, + minTime: DateTime(DateTime.now().year - 100, 1, 1), + maxTime: DateTime.now(), + onConfirm: (date) { + selectedDate = date; + setState(() { + final intl.DateFormat dateFormat = intl.DateFormat('dd/MM/yyyy'); + dobEn.text = dateFormat.format(date); + }); + }, + currentTime: DateTime.now(), + ); + } + + Widget inputWidget(String _labelText, String _hintText, TextEditingController _controller, {String? prefix, bool isEnable = true, bool hasSelection = false, bool isNumber = true, Icon? suffix}) { + 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( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ Expanded( - flex: 4, child: Column( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - MobileNo( - onNumberChange: (value) => - {mobileNo = value, validateForm()}, - onCountryChange: (value) => countryCode = value), - Container( - child: TextFields( - controller: nationalIDorFile, - onChanged: (value) => validateForm(), - keyboardType: TextInputType.number, - prefixIcon: Icon(Icons.chrome_reader_mode, - color: Color(0xFF40ACC9)), - padding: EdgeInsets.only( - top: 20, bottom: 20, left: 10, right: 10), - hintText: TranslationBase.of(context).nationalID, - )), - Row( - children: [ - Expanded( - child: Row( - children: [ - Radio( - value: 1, - groupValue: isHijri, - onChanged: (value) { - setState(() { - isHijri = value; - }); - validateForm(); - }, - ), - Text(TranslationBase.of(context).hijriDate), - ], - ), + 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: isNumber ? TextInputType.numberWithOptions(signed: true) : TextInputType.datetime, + controller: _controller, + onChanged: (value) => {validateForm()}, + 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, ), - Expanded( - child: Row( - children: [ - Radio( - value: 0, - groupValue: isHijri, - onChanged: (value) { - setState(() { - isHijri = value; - }); - validateForm(); - }, + 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, + ), ), - Text(TranslationBase.of(context).gregorianDate), - ], - ), - ), - ], + contentPadding: EdgeInsets.zero, + border: InputBorder.none, + focusedBorder: InputBorder.none, + enabledBorder: InputBorder.none, + ), ), - Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - Container( - width: SizeConfig.realScreenWidth * .9, - height: 60, - child: isHijri == 1 - ? TextFields( - onChanged: (value) => {dob = value}, - hintText: 'DD/MM/YYYY', - prefixIcon: Icon(Icons.date_range), - ) - : RaisedButton.icon( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(15.0), - ), - color: Colors.white, - onPressed: () => { - if (isHijri != null) - _selectDate(context) - }, - icon: Icon(Icons.date_range), - label: Text(selectedDate != null - ? "${selectedDate.toLocal()}" - .split(' ')[0] - : TranslationBase.of(context).dob))) - ]) ], ), ), - Expanded( - flex: 2, - child: Column( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - Divider( - color: Colors.grey, - height: 2, - ), - SizedBox( - height: 10, - ), - Row( - children: [ - Expanded( - child: DefaultButton( - TranslationBase.of(context).registerNow, - () => {startRegistration()}, - textColor: Colors.white, - color: isButtonDisabled == true - ? Colors.grey - : Colors.grey[900])) - ], - ), - ], - )) - ]), - ))); - } - - Future _selectDate(BuildContext context) async { - final DateTime picked = await showDatePicker( - context: context, - initialDate: DateTime.now(), - firstDate: DateTime(1950, 8), - lastDate: DateTime.now()); - if (picked != null && picked != selectedDate) - setState(() { - selectedDate = picked; - }); + if (hasSelection) Icon(Icons.keyboard_arrow_down_outlined), + if (suffix != null) suffix + ], + ), + ), + ); } startRegistration() { + final intl.DateFormat dateFormat = intl.DateFormat('dd/MM/yyyy'); if (isButtonDisabled == false) { var request = CheckPatientForRegistration(); request.patientMobileNumber = int.parse(mobileNo); request.zipCode = countryCode; request.patientOutSA = countryCode == '966' ? 0 : 1; - // if (this.loginType == 1) { + request.patientIdentificationID = int.parse(nationalIDorFile.text); request.patientID = 0; request.isRegister = true; - // } else { - // request.patientIdentificationID = 0; - // request.patientID = int.parse(nationalIDorFile.text); - // } + request.dob = isHijri == 1 ? dob.text : dateFormat.format(selectedDate); + request.isHijri = isHijri; this.checkPatientForRegisteration(request); } } checkPatientForRegisteration(request) { + int languageID = Provider.of(context, listen: false).isArabic ? 1 : 2; GifLoaderDialogUtils.showMyDialog(context); - this - .authService - .checkPatientForRegisteration(request) - .then((response) => {checkUserStatus(response, request)}) - .catchError((err) { + this.authService.checkPatientForRegisteration(request, languageID).then((response) => {checkUserStatus(response, request)}).catchError((err) { GifLoaderDialogUtils.hideDialog(context); ConfirmDialog dialog = new ConfirmDialog( context: context, @@ -235,7 +334,8 @@ class _Register extends State { if (util.validateIDBox(nationalIDorFile.text, loginType) == true && mobileNo.length >= 9 && util.isSAUDIIDValid(nationalIDorFile.text, loginType) == true && - isHijri != null) { + isHijri != null && + (dobEn.text != null || dob.text != null)) { setState(() { isButtonDisabled = false; }); @@ -252,23 +352,33 @@ class _Register extends State { var nRequest = request.toJson(); nRequest['LogInTokenID'] = response['LogInTokenID']; if (response['hasFile'] == true) { - // AppToast.showErrorToast(message: response['ErrorEndUserMessage']); - AlertDialogBox( - context: context, - confirmMessage: response['ErrorEndUserMessage'], - okText: TranslationBase.of(context).ok, - okFunction: () { - AlertDialogBox.closeAlertDialog(context); - Navigator.of(context).pop(); - }).showAlertDialog(context); + ConfirmDialog dialog = new ConfirmDialog( + context: context, + confirmMessage: response['ErrorEndUserMessage'], + okText: TranslationBase.of(context).ok, + cancelText: TranslationBase.of(context).cancel, + okFunction: () { + AlertDialogBox.closeAlertDialog(context); + sharedPref.setObject(REGISTER_DATA_FOR_LOGIIN, nRequest); + LoginRegistration.loginMethod = 1; // 1=NationalID, by default from Registration + Navigator.of(context).push(FadePage(page: Login())); + }, + cancelFunction: () {}) + .showAlertDialog(context); } else { + final intl.DateFormat dateFormat = intl.DateFormat('dd/MM/yyyy'); nRequest['forRegister'] = true; nRequest['isRegister'] = true; - nRequest["PatientIdentificationID"] = - nRequest["PatientIdentificationID"].toString(); + nRequest["PatientIdentificationID"] = nRequest["PatientIdentificationID"].toString(); + nRequest['dob'] = isHijri == 1 ? dob.text : dateFormat.format(selectedDate); + nRequest['isHijri'] = isHijri; sharedPref.setObject(REGISTER_DATA_FOR_LOGIIN, nRequest); sharedPref.setString(LOGIN_TOKEN_ID, response['LogInTokenID']); - this.chekUserData(response['LogInTokenID']); + if (request.patientOutSA == 0) { + this.chekUserData(response['LogInTokenID']); + } else { + Navigator.of(context).push(FadePage(page: ConfirmLogin(changePageViewIndex: widget.changePageViewIndex, fromRegistration: true, isDubai: true))); + } } } else { // if (response['ErrorCode'] == '-986') { @@ -294,30 +404,36 @@ class _Register extends State { // DOB: this.dateOption === '1' ? this.dateOfBirth : moment(this.dateOfBirth).format('DD/MM/YYYY'), // IsHijri: Number(this.dateOption) // } + + final intl.DateFormat dateFormat = intl.DateFormat('dd/MM/yyyy'); GifLoaderDialogUtils.showMyDialog(context); var request = CheckUserStatusRequest(); request.patientIdentificationID = nationalIDorFile.text; - request.dOB = isHijri == 1 - ? dob - : "${selectedDate.toLocal()}".split(' ')[0].replaceAll('-', '/'); + request.dOB = isHijri == 1 ? dob.text : dateFormat.format(selectedDate); request.isHijri = isHijri; request.patientOutSA = countryCode == '966' ? 0 : 1; this.authService.checkUserStatus(request).then((result) => { GifLoaderDialogUtils.hideDialog(context), if (result is Map) { - result = CheckUserStatusResponse.fromJson(result), + result = CheckUserStatusResponse.fromJson(result as Map), sharedPref.setObject(NHIC_DATA, result), - Navigator.of(context).push(FadePage(page: ConfirmLogin())), + // widget.changePageViewIndex!(1), + Navigator.of(context).push(FadePage(page: ConfirmLogin(changePageViewIndex: widget.changePageViewIndex, fromRegistration: true))), } else - {AppToast.showErrorToast(message: result)} + { + AppToast.showErrorToast(message: result != null ? result : TranslationBase.of(context).somethingWentWrong), + } }); } - showLoader(bool isTrue) { - setState(() { - isLoading = isTrue; + getPatientOccupationList() async { + patientOccupationList.clear(); + await authService.getPatientOccupationList().then((result) { + sharedPref.setString(PATIENT_OCCUPATION_LIST, json.encode(result['GetOccupationLst'])); + }).catchError((err) { + AppToast.showErrorToast(message: err); }); } } diff --git a/lib/pages/login/register_new.dart b/lib/pages/login/register_new.dart new file mode 100644 index 00000000..8a5b5ec8 --- /dev/null +++ b/lib/pages/login/register_new.dart @@ -0,0 +1,201 @@ +import 'package:diplomaticquarterapp/config/size_config.dart'; +import 'package:diplomaticquarterapp/pages/login/login-type.dart'; +import 'package:diplomaticquarterapp/pages/login/register-info.dart'; +import 'package:diplomaticquarterapp/pages/login/register.dart'; +import 'package:diplomaticquarterapp/services/authentication/auth_provider.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/uitl/utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; + +class RegisterNew extends StatefulWidget { + @override + _RegisterNew createState() => _RegisterNew(); +} + +class _RegisterNew extends State { + final nationalIDorFile = TextEditingController(); + final int loginType = LoginType.loginType; + late String mobileNo; + String countryCode = '966'; + var isHijri; + final util = Utils(); + late DateTime selectedDate; + late String dob; + bool isButtonDisabled = true; + final authService = new AuthProvider(); + final sharedPref = new AppSharedPreferences(); + late PageController _controller; + late bool isLoading; + int _currentIndex = 0; + + @override + void initState() { + super.initState(); + _controller = new PageController(); + } + + @override + void dispose() { + super.dispose(); + } + + changePageViewIndex(pageIndex) { + _controller.jumpToPage(pageIndex); + } + + @override + Widget build(BuildContext context) { + return AppScaffold( + appBarTitle: TranslationBase.of(context).register, + isShowAppBar: true, + isShowDecPage: false, + showNewAppBar: true, + showNewAppBarTitle: true, + body: SingleChildScrollView( + child: Container( + height: SizeConfig.realScreenHeight! * .9, + width: SizeConfig.realScreenWidth, + child: Column(children: [ + Container( + width: double.infinity, + padding: EdgeInsets.only(left: 20, right: 20, top: 12), + child: Row( + children: [ + Expanded( + child: showProgress( + title: TranslationBase.of(context).enterDetails, + status: _currentIndex == 0 + ? TranslationBase.of(context).inPrgress + : _currentIndex > 0 + ? TranslationBase.of(context).completed + : TranslationBase.of(context).locked, + color: _currentIndex == 0 ? CustomColors.orange : CustomColors.green, + ), + ), + Expanded( + child: showProgress( + title: TranslationBase.of(context).patientInfo, + status: _currentIndex == 1 + ? TranslationBase.of(context).inPrgress + : _currentIndex > 1 + ? TranslationBase.of(context).completed + : TranslationBase.of(context).locked, + color: _currentIndex == 1 + ? CustomColors.orange + : _currentIndex > 1 + ? CustomColors.green + : CustomColors.grey2, + ), + ), + showProgress( + title: TranslationBase.of(context).otherInfo, + status: _currentIndex == 2 ? TranslationBase.of(context).inPrgress : TranslationBase.of(context).locked, + color: _currentIndex == 2 + ? CustomColors.orange + : _currentIndex > 3 + ? CustomColors.green + : CustomColors.grey2, + isNeedBorder: false, + ), + ], + ), + ), + Expanded( + child: PageView( + physics: NeverScrollableScrollPhysics(), + controller: _controller, + onPageChanged: (index) { + setState(() { + _currentIndex = index; + }); + }, + scrollDirection: Axis.horizontal, + children: [ + Register( + changePageViewIndex: changePageViewIndex, + ), + + RegisterInfo( + changePageViewIndex: changePageViewIndex, + ), + RegisterInfo(changePageViewIndex: changePageViewIndex, page: 2), + // NewEReferralStepOnePage( + // changePageViewIndex: changePageViewIndex, + // createEReferralRequestModel: createEReferralRequestModel, + // ), + // NewEReferralStepTowPage( + // changePageViewIndex: changePageViewIndex, + // createEReferralRequestModel: createEReferralRequestModel, + // ), + // NewEReferralStepThreePage( + // changePageViewIndex: changePageViewIndex, + // createEReferralRequestModel: createEReferralRequestModel, + // ), + ], + ), + ), + ]), + )), + ); + } + + Widget showProgress({String? title, String? status, Color? color, bool isNeedBorder = true}) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Container( + width: 26, + height: 26, + decoration: containerRadius(color!, 200), + child: Icon( + Icons.done, + color: Colors.white, + size: 16, + ), + ), + if (isNeedBorder) + Expanded( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: mDivider(Colors.grey), + )), + ], + ), + mHeight(8), + Text( + title!, + style: TextStyle( + fontSize: 11, + fontWeight: FontWeight.w600, + letterSpacing: -0.44, + ), + ), + mHeight(2), + Container( + padding: EdgeInsets.all(5), + decoration: containerRadius(color!.withOpacity(0.2), 4), + child: Text( + status!, + style: TextStyle( + fontSize: 8, + fontWeight: FontWeight.w600, + letterSpacing: -0.32, + color: color, + ), + ), + ), + ], + ) + ], + ); + } +} diff --git a/speech_to_text/ios/Assets/.gitkeep b/lib/pages/login/register_new_dubai.dart similarity index 100% rename from speech_to_text/ios/Assets/.gitkeep rename to lib/pages/login/register_new_dubai.dart diff --git a/lib/pages/login/user-login-agreement-page.dart b/lib/pages/login/user-login-agreement-page.dart new file mode 100644 index 00000000..96e67f14 --- /dev/null +++ b/lib/pages/login/user-login-agreement-page.dart @@ -0,0 +1,828 @@ +import 'package:diplomaticquarterapp/core/service/AuthenticatedUserObject.dart'; +import 'package:diplomaticquarterapp/core/viewModels/TermsConditionsViewModel.dart'; +import 'package:diplomaticquarterapp/core/viewModels/appointment_rate_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart'; +import 'package:diplomaticquarterapp/models/InPatientServices/get_admission_info_response_model.dart'; +import 'package:diplomaticquarterapp/models/InPatientServices/get_admission_request_info_response_model.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; +import 'package:diplomaticquarterapp/pages/rateAppointment/rate_appointment_doctor.dart'; +import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; +import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/Loader/gif_loader_container.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/custom_text_button.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_html/flutter_html.dart'; +import 'package:provider/provider.dart'; +import 'package:webview_flutter/webview_flutter.dart'; + +class UserLoginAgreementPage extends StatefulWidget { + final String userAgreementText; + final AuthenticatedUserObject authenticatedUserObject; + final AppointmentRateViewModel appointmentRateViewModel; + final int selectedOption; + final isArabic; + + UserLoginAgreementPage({required this.userAgreementText, required this.authenticatedUserObject, required this.appointmentRateViewModel, required this.selectedOption, required this.isArabic}); + + @override + State createState() => _UserLoginAgreementPageState(); +} + +class _UserLoginAgreementPageState extends State { + late ProjectViewModel projectViewModel; + late ToDoCountProviderModel toDoProvider; + final authService = AuthProvider(); + + late final WebViewController _controller; + bool isPageLoaded = false; + + bool isTermsAndConditionsPage = true; + bool acceptTerms = false; + + @override + void initState() { + super.initState(); + _controller = WebViewController() + ..setJavaScriptMode(JavaScriptMode.unrestricted) + ..setNavigationDelegate( + NavigationDelegate( + onProgress: (int progress) { + // Update loading bar. + print("Progress: $progress"); + }, + onPageStarted: (String url) {}, + onPageFinished: (String url) { + setState(() { + isPageLoaded = true; + }); + }, + onHttpError: (HttpResponseError error) {}, + onWebResourceError: (WebResourceError error) {}, + onNavigationRequest: (NavigationRequest request) { + if (request.url.startsWith('https://www.youtube.com/')) { + return NavigationDecision.prevent; + } + return NavigationDecision.navigate; + }, + ), + ) + ..loadRequest(Uri.parse(widget.isArabic ? "https://hmg.com/ar/Pages/MBTerms.aspx" : "https://hmg.com/en/Pages/MBTerms.aspx")); + } + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + toDoProvider = Provider.of(context); + return BaseView( + builder: (_, model, w) => AppScaffold( + isShowAppBar: true, + showNewAppBarTitle: true, + showNewAppBar: true, + isShowDecPage: false, + appBarTitle: TranslationBase.of(context).userAgreement, + body: + // isTermsAndConditionsPage + // ? + // getTermsAndConditionsContent(), + // : + isPageLoaded + ? WebViewWidget(controller: _controller) + : Container( + child: Center( + child: GifLoaderContainer( + barrierDismissible: false, + ), + ), + ), + // Padding( + // padding: const EdgeInsets.all(8.0), + // child: SingleChildScrollView(child: WebViewWidget(controller: _controller) + // // Html( + // // data: widget.userAgreementText, + // // ), + // ), + // ), + bottomSheet: Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10), bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10)), + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.5), + spreadRadius: 5, + blurRadius: 7, + offset: Offset(0, 3), // changes position of shadow + ), + ], + ), + padding: EdgeInsets.only(left: 21, right: 21, top: 15, bottom: 15), + width: double.infinity, + // color: Colors.white, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox(height: 12), + Text( + TranslationBase.of(context).continueAgreeTerms, + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + mHeight(24.0), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Checkbox( + value: acceptTerms, + onChanged: (v) { + setState(() => acceptTerms = v!); + }), + Expanded( + child: Text( + TranslationBase.of(context).termsConditionsRead, + style: TextStyle( + fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + ), + ], + ), + SizedBox(height: 12), + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Expanded( + flex: 1, + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + height: 45.0, + child: CustomTextButton( + backgroundColor: CustomColors.green, + elevation: 0, + onPressed: isPageLoaded + ? () { + // if (isTermsAndConditionsPage) { + if (acceptTerms) { + addUsageAgreement(); + // setState(() { + // isTermsAndConditionsPage = false; + // }); + } else { + AppToast.showErrorToast(message: TranslationBase.of(context).pleaseAcceptTerms); + } + // } else { + // addUsageAgreement(); + // } + } + : null, + child: Text(TranslationBase.of(context).acceptLbl.toUpperCase(), + style: TextStyle( + fontSize: 18.0, + color: Colors.white, + )), + ), + ), + ), + mWidth(7), + Expanded( + flex: 1, + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + height: 45.0, + child: CustomTextButton( + backgroundColor: Color(0xffc5272d), + elevation: 0, + onPressed: isPageLoaded + ? () { + Navigator.pushAndRemoveUntil( + context, + FadePage( + page: LandingPage(), + ), + (r) => false); + } + : null, + child: Text(TranslationBase.of(context).declineLbl.toUpperCase(), style: TextStyle(fontSize: 18.0, color: Colors.white)), + ), + ), + ), + ], + ), + ], + ), + ), + ), + ); + } + + Widget getTermsAndConditionsContent() { + return SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).termsHeading, + style: + TextStyle(fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions1, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions2, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions3, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + // InkWell( + // onTap: () async { + // await launchUrl(uri); + // Uri.parse(widget.isArabic ? "https://hmg.com/ar/Pages/Privacy.aspx" : "https://hmg.com/en/Pages/Privacy.aspx"); + // }, + // child: Text( + // TranslationBase.of(context).clickPrivacyPolicy, + // style: TextStyle( + // fontSize: 16, + // fontWeight: FontWeight.bold, + // fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), + // color: Colors.blue, + // letterSpacing: -1.44, + // height: 35 / 24, + // decoration: TextDecoration.underline), + // ), + // ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions4, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions5, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsHeading2, + style: + TextStyle(fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions6, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsHeading3, + style: + TextStyle(fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions7, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions8, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions9, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions10, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions11, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions12, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions12a, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions12b, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions12c, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions13, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions14, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions14a, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions14b, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsHeading4, + style: + TextStyle(fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions15, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions16, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions16a, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions16b, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions17, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions18, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions19, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions19a, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions19b, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsHeading5, + style: + TextStyle(fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions20, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions21, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsHeading6, + style: + TextStyle(fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions21, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions22, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions23, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions24, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsHeading7, + style: + TextStyle(fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions25, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions25a, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions25b, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions25c, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions26, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions27, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions28, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions29, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions30, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions31, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions32, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsHeading8, + style: + TextStyle(fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions33, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions33a, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions33b, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions34, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions34a, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions34b, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions34c, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions34d, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions34e, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions35, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions35a, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions35b, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions35c, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions35d, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions35e, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions36, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions37, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions38, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions39, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions39a, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions39b, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions39c, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions39d, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsHeading9, + style: + TextStyle(fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions40, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions41, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsHeading10, + style: + TextStyle(fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions42, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions43, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsHeading11, + style: + TextStyle(fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions44, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsHeading12, + style: + TextStyle(fontSize: 20, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(12.0), + Text( + TranslationBase.of(context).termsConditions45, + style: TextStyle(fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + mHeight(24.0), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Checkbox( + value: acceptTerms, + onChanged: (v) { + setState(() => acceptTerms = v!); + }), + Expanded( + child: Text( + TranslationBase.of(context).termsConditionsRead, + style: TextStyle( + fontSize: 16, fontFamily: (projectViewModel.isArabic ? 'Cairo' : 'Poppins'), fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24), + ), + ), + ], + ), + mHeight(150.0), + ], + ), + ), + ); + } + + addUsageAgreement() { + GifLoaderDialogUtils.showMyDialog(context); + this.authService.addUserAgreementContent().then((result) { + goToHome(); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + + checkIfIsInPatient() { + bool isAdmitted = false; + bool hasAdmissionRequest = false; + GetAdmissionInfoResponseModel getAdmissionInfoResponseModel; + GetAdmissionRequestInfoResponseModel getAdmissionRequestInfoResponseModel; + ClinicListService service = new ClinicListService(); + service.checkIfInPatientAPI(context).then((res) { + if (res['MessageStatus'] == 1) { + isAdmitted = res['isAdmitted']; + hasAdmissionRequest = res['hasAdmissionRequests']; + print("IS ADMITTED: $isAdmitted"); + print("Has Admission Request: $hasAdmissionRequest"); + if (isAdmitted) { + if (res['PatientAdmittedInformation'].length != 0) { + getAdmissionInfoResponseModel = GetAdmissionInfoResponseModel.fromJson(res['PatientAdmittedInformation'][0]); + projectViewModel.setInPatientProjectID(res['PatientAdmittedInformation'][0]['ProjectID']); + projectViewModel.setInPatientAdmissionInfo(getAdmissionInfoResponseModel); + projectViewModel.setIsPatientAdmitted(true); + } + } + if (hasAdmissionRequest) { + if (res['MedicalInstruction'].length != 0) { + getAdmissionRequestInfoResponseModel = GetAdmissionRequestInfoResponseModel.fromJson(res['MedicalInstruction'][0]); + // projectViewModel.setInPatientProjectID(res['MedicalInstruction'][0]['ProjectID']); + projectViewModel.setInPatientProjectID(res['MedicalInstruction'][0]['projectId']); + projectViewModel.setInPatientAdmissionRequest(getAdmissionRequestInfoResponseModel); + projectViewModel.setPatientHasAdmissionRequest(true); + } + } + } else {} + }); + } + + goToHome() async { + widget.authenticatedUserObject.isLogin = true; + widget.appointmentRateViewModel.isLogin = true; + projectViewModel.isLogin = true; + projectViewModel.user = widget.authenticatedUserObject.user; + await widget.authenticatedUserObject.getUser(getUser: true); + + // GifLoaderDialogUtils.hideDialog(context); + getToDoCount(); + checkIfIsInPatient(); + widget.appointmentRateViewModel + .getIsLastAppointmentRatedList(projectViewModel.isArabic ? 1 : 2) + .then((value) => { + GifLoaderDialogUtils.hideDialog(context), + if (widget.appointmentRateViewModel.isHaveAppointmentNotRate) + { + Navigator.pushAndRemoveUntil( + context, + FadePage( + page: RateAppointmentDoctor(), + ), + (r) => false) + } + else + { + GifLoaderDialogUtils.hideDialog(context), + Navigator.pushAndRemoveUntil( + context, + FadePage( + page: LandingPage(), + ), + (r) => false) + }, + insertIMEI() + }) + .catchError((err) { + print(err); + }); + } + + insertIMEI() { + authService.insertDeviceImei(widget.selectedOption).then((value) => {}).catchError((err) { + print(err); + }); + } + + getToDoCount() { + toDoProvider.setState(0, 0, true, "0"); + ClinicListService service = new ClinicListService(); + service.getActiveAppointmentNo(context).then((res) { + if (res['MessageStatus'] == 1) { + toDoProvider.setState(res['AppointmentActiveNumber'], res['AncillaryOrderListCount'], true, "0"); + // toDoProvider.setState(res['AppointmentActiveNumber'], true, "0"); + } else {} + }).catchError((err) { + print(err); + }); + } +} diff --git a/lib/pages/login/welcome.dart b/lib/pages/login/welcome.dart index 6a007e0a..8b9e282f 100644 --- a/lib/pages/login/welcome.dart +++ b/lib/pages/login/welcome.dart @@ -1,14 +1,16 @@ -import 'package:diplomaticquarterapp/config/size_config.dart'; +import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; +import 'package:diplomaticquarterapp/locator.dart'; import 'package:diplomaticquarterapp/pages/login/login-type.dart'; import 'package:diplomaticquarterapp/pages/login/register.dart'; -import 'package:diplomaticquarterapp/routes.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'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:diplomaticquarterapp/widgets/text/app_texts_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; class WelcomeLogin extends StatefulWidget { @override @@ -21,82 +23,87 @@ class _WelcomeLogin extends State { @override void initState() { isLoading = true; - // checkUser(context); super.initState(); } Widget build(BuildContext context) { return AppScaffold( - appBarTitle: TranslationBase.of(context).welcome, - isShowDecPage: false, - isShowAppBar: true, - body: Padding( - padding: EdgeInsets.all(20), - child: Column( + appBarTitle: TranslationBase.of(context).welcome, + isShowDecPage: false, + isShowAppBar: true, + showNewAppBar: true, + backgroundColor: Color(0xffF8F8F8), + showNewAppBarTitle: false, + body: Column( + children: [ + Expanded( + child: ListView( + padding: EdgeInsets.only(left: 21, right: 21), + physics: BouncingScrollPhysics(), + children: [ + SizedBox(height: 12), + Row( + children: [ + SvgPicture.asset( + "assets/images/new/hmg_icon.svg", + height: 62, + width: 62, + ), + ], + ), + SizedBox(height: 24), + Text( + TranslationBase.of(context).welcome, + style: TextStyle(fontSize: 24, fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 23 / 24), + ), + SizedBox(height: 16), + // Text( + // TranslationBase.of(context).welcomeText, + // style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64, height: 23 / 16), + // ), + Text( + TranslationBase.of(context).welcomeText2, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64, height: 23 / 16), + ), + SizedBox( + height: 14, + ), + ], + ), + ), + Container( + color: Colors.white, + padding: EdgeInsets.only(top: 16, bottom: 16, right: 21, left: 21), + child: Row( + mainAxisSize: MainAxisSize.min, children: [ Expanded( - flex: 6, - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Image.asset('assets/images/DQ/logo.png', - height: 90, width: 90), - AppText( - TranslationBase.of(context).welcome, - fontSize: 30, - fontWeight: FontWeight.bold, - ), - AppText( - TranslationBase.of(context).welcomeText, - fontSize: 24, - textAlign: TextAlign.start, - ), - AppText( - TranslationBase.of(context).welcomeText2, - fontSize: 24, - textAlign: TextAlign.start, - ), - SizedBox( - height: SizeConfig.realScreenHeight * .15, - ) - ]), + child: DefaultButton( + TranslationBase.of(context).no, + () => { + Navigator.of(context).push(FadePage(page: RegisterNew())), + locator().loginRegistration.visited_alhabib_group(false), + }, + color: CustomColors.accentColor, + textColor: Colors.white, + ), ), + SizedBox(width: 8), Expanded( - flex: 2, - child: Column( - //mainAxisAlignment: MainAxisAlignment.end, - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Row( - children: [ - Expanded( - child: DefaultButton( - TranslationBase.of(context).yes, - () => { - Navigator.of(context) - .push(FadePage(page: LoginType())), - }, - color: Color(0xFFc5272c), - textColor: Colors.white, - )) - ], - ), - Row( - children: [ - Expanded( - child: DefaultButton( - TranslationBase.of(context).no, - () => { - Navigator.of(context) - .push(FadePage(page: Register())), - }, - )) - ], - ), - ], - )) + child: DefaultButton( + TranslationBase.of(context).yes, + () => { + Navigator.of(context).push(FadePage(page: LoginType())), + locator().loginRegistration.visited_alhabib_group(true), + }, + color: CustomColors.green, + ), + ), ], - ))); + ), + ), + ], + ), + ); } } diff --git a/lib/pages/medical/active_medications/ActiveMedicationsPage.dart b/lib/pages/medical/active_medications/ActiveMedicationsPage.dart index 5bc9618d..2744183e 100644 --- a/lib/pages/medical/active_medications/ActiveMedicationsPage.dart +++ b/lib/pages/medical/active_medications/ActiveMedicationsPage.dart @@ -5,6 +5,7 @@ import 'package:diplomaticquarterapp/pages/medical/active_medications/reminder_p 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/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; @@ -17,114 +18,186 @@ class ActiveMedicationsPage extends StatelessWidget { return BaseView( onModelReady: (model) => model.getActiveMedication(), builder: (_, model, w) => AppScaffold( + isShowAppBar: true, + showNewAppBar: true, + showNewAppBarTitle: true, + isShowDecPage: true, baseViewModel: model, appBarTitle: TranslationBase.of(context).activeMedications, - isShowAppBar: true, - body: Container( + body: model.activePrescriptionReport.length > 0 ? Container( child: ListView.builder( itemCount: model.activePrescriptionReport.length, itemBuilder: (context, index) => Container( - padding: EdgeInsets.all(10), - margin: EdgeInsets.all(10), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(8), color: Colors.white), - child: Row( - children: [ - Image.memory( - Utils.dataFromBase64String(model - .activePrescriptionReport[index].productImageBase64), - height: SizeConfig.imageSizeMultiplier * 19, - width: SizeConfig.imageSizeMultiplier * 18, - fit: BoxFit.cover, - ), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts( - model.activePrescriptionReport[index].itemDescription, - bold: true, - ), - SizedBox( - height: 5, - ), - Texts( - TranslationBase.of(context).expDate+' :' + - DateUtil.getDayMonthYearDateFormatted(model - .activePrescriptionReport[index].orderDate), - ), - SizedBox( - height: 5, - ), - Texts( - TranslationBase.of(context).route+ ' :' + - model.activePrescriptionReport[index].route, - ), - SizedBox( - height: 5, - ), - Texts( - TranslationBase.of(context).frequency+ ' :' + - model.activePrescriptionReport[index].frequency, + width: double.infinity, + child: Container( + margin: EdgeInsets.only(left: 16, right: 16, top: index == 0 ? 16 : 4, bottom: 4), + decoration: cardRadius(12), + child: Padding( + padding: const EdgeInsets.only(top: 12, bottom: 20, left: 20, right: 20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + model.activePrescriptionReport[index].itemDescription!, + style: TextStyle( + fontSize: 16, + letterSpacing: -0.64, + fontWeight: FontWeight.w600, ), - SizedBox( - height: 5, - ), - Texts( - TranslationBase.of(context).dailyQuantity + ' :${model.activePrescriptionReport[index].doseDailyQuantity}', - ), - ], - ), - ), - Container( - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Icon( - Icons.notifications, - color: Colors.red, - size: 28, - ), - SizedBox(height: 25,), - InkWell( - onTap: (){ - Navigator.push( - context, - FadePage( - page: ReminderPage( - frequency: model.activePrescriptionReport[index] - .frequencyNumber, - days: model.activePrescriptionReport[index].days, - itemDescription: model - .activePrescriptionReport[index] - .itemDescription, - ), - ), - ); - }, - child: Row( + ), + mHeight(10), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( children: [ - Icon( - Icons.notifications_active, - color: Colors.red, - size: 28, + // Container( + // child: Container( + // child: Image.memory( + // Utils.dataFromBase64String(model.activePrescriptionReport[index].imageString), + // fit: BoxFit.cover, + // height: SizeConfig.imageSizeMultiplier * 19, + // width: SizeConfig.imageSizeMultiplier * 18, + // ), + // margin: EdgeInsets.zero, + // clipBehavior: Clip.antiAlias, + // decoration: cardRadius(2000), + // ), + // clipBehavior: Clip.antiAlias, + // decoration: containerColorRadiusBorderWidth(Colors.white, 200, Colors.grey[200], 1), + // ), + // mWidth(12), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Text( + TranslationBase.of(context).expiryDateTitle + ": ", + style: TextStyle( + color: Colors.grey, + fontSize: 12, + letterSpacing: -0.4, + fontWeight: FontWeight.w600, + ), + ), + Text( + DateUtil.getDayMonthYearDateFormatted(model.activePrescriptionReport[index].orderDate!), + style: TextStyle( + fontSize: 13, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + ), + ), + ], + ), + Row( + children: [ + Text( + TranslationBase.of(context).frequency + ": ", + style: TextStyle( + color: Colors.grey, + fontSize: 12, + letterSpacing: -0.4, + fontWeight: FontWeight.w600, + ), + ), + Text( + model.activePrescriptionReport[index].frequency!, + style: TextStyle( + fontSize: 13, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + ), + ), + ], + ), + Row( + children: [ + Text( + TranslationBase.of(context).route + ": ", + style: TextStyle( + color: Colors.grey, + fontSize: 12, + letterSpacing: -0.4, + fontWeight: FontWeight.w600, + ), + ), + Text( + model.activePrescriptionReport[index].route!, + style: TextStyle( + fontSize: 13, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + ), + ), + ], + ), + Row( + children: [ + Text( + TranslationBase.of(context).dailyDoses + ": ", + style: TextStyle( + color: Colors.grey, + fontSize: 12, + letterSpacing: -0.4, + fontWeight: FontWeight.w600, + ), + ), + Text( + model.activePrescriptionReport[index].doseDailyQuantity.toString(), + style: TextStyle( + fontSize: 13, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + ), + ), + ], + ), + mHeight(12), + ], ), - Texts( - TranslationBase.of(context).addReminder, - color: Colors.red, - ) ], ), - ) - ], - ), - ) - ], + Container( + child: InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: ReminderPage( + frequency: model.activePrescriptionReport[index].frequencyNumber!, + days: model.activePrescriptionReport[index].days!, + itemDescription: model.activePrescriptionReport[index].itemDescription!, + ), + ), + ); + }, + child: Column( + children: [ + Icon( + Icons.notifications_outlined, + color: Colors.red, + size: 28, + ), + Texts( + TranslationBase.of(context).addReminder, + color: Colors.red, + fontSize: 11.0, + ) + ], + ), + ), + ), + ], + ), + ], + ), + ), ), ), ), - ), + ) : getNoDataWidget(context), ), ); } diff --git a/lib/pages/medical/active_medications/DayCheckBoxDialog.dart b/lib/pages/medical/active_medications/DayCheckBoxDialog.dart index 5cb4020c..49e6e1f6 100644 --- a/lib/pages/medical/active_medications/DayCheckBoxDialog.dart +++ b/lib/pages/medical/active_medications/DayCheckBoxDialog.dart @@ -20,7 +20,7 @@ class DayCheckBoxDialog extends StatefulWidget { ]; DayCheckBoxDialog( - {Key key, this.onValueSelected, this.selectedDaysOfWeek, this.title}); + {Key? key, required this.onValueSelected, required this.selectedDaysOfWeek, required this.title}); @override _DayCheckBoxDialogState createState() => _DayCheckBoxDialogState(); diff --git a/lib/pages/medical/active_medications/reminder_page.dart b/lib/pages/medical/active_medications/reminder_page.dart index 7980d941..3c775bdc 100644 --- a/lib/pages/medical/active_medications/reminder_page.dart +++ b/lib/pages/medical/active_medications/reminder_page.dart @@ -5,44 +5,36 @@ import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/uitl/CalendarUtils.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.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/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_datetime_picker/flutter_datetime_picker.dart'; +import 'package:flutter_datetime_picker_plus/flutter_datetime_picker_plus.dart'; import 'package:provider/provider.dart'; import 'DayCheckBoxDialog.dart'; // ignore: must_be_immutable class ReminderPage extends StatefulWidget { - final int frequency; - final int days; - final String itemDescription; + final int? frequency; + final int? days; + final String? itemDescription; - List _scheduleList = List(); - List daysOfWeek = [ - DayOfWeek.Monday, - DayOfWeek.Tuesday, - DayOfWeek.Wednesday, - DayOfWeek.Thursday, - DayOfWeek.Friday, - DayOfWeek.Saturday, - DayOfWeek.Sunday - ]; + List _scheduleList =[]; + List daysOfWeek = [DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday, DayOfWeek.Friday, DayOfWeek.Saturday, DayOfWeek.Sunday]; - DateTime startDay; - DateTime endDay; + late DateTime startDay; + late DateTime endDay; - ReminderPage({Key key, this.frequency, this.days, this.itemDescription}) { + ReminderPage({Key? key, this.frequency, this.days, this.itemDescription}) { startDay = DateTime.now(); - endDay = DateTime.now().add(Duration(days: days)); - int hour = (24 ~/ frequency).round(); + endDay = DateTime.now().add(Duration(days: days!)); + int hour = (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))); } } @@ -59,6 +51,9 @@ class _ReminderPageState extends State { builder: (_, model, w) => AppScaffold( baseViewModel: model, isShowAppBar: true, + showNewAppBar: true, + showNewAppBarTitle: true, + isShowDecPage: false, appBarTitle: TranslationBase.of(context).reminder, body: SingleChildScrollView( child: Container( @@ -68,7 +63,7 @@ class _ReminderPageState extends State { children: [ Container( width: double.maxFinite, - child: Texts(TranslationBase.of(context).reminderDes), + child: Texts(TranslationBase.of(context).reminderDes, textAlign: TextAlign.start), ), Divider(), SizedBox( @@ -80,25 +75,17 @@ class _ReminderPageState extends State { ), InkWell( onTap: () { - DatePicker.showDatePicker(context, - showTitleActions: true, - minTime: DateTime( - DateTime.now().year, DateTime.now().month - 1, 1), - maxTime: DateTime.now(), onConfirm: (date) { + DatePicker.showDatePicker(context, showTitleActions: true, minTime: DateTime(DateTime.now().year, DateTime.now().month - 1, 1), maxTime: DateTime.now(), onConfirm: (date) { setState(() { widget.startDay = date; }); - }, - currentTime: widget.startDay, - locale: projectViewModel.localeType); + }, 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), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), color: Colors.white), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -120,25 +107,17 @@ class _ReminderPageState extends State { ), InkWell( onTap: () { - DatePicker.showDatePicker(context, - showTitleActions: true, - minTime: DateTime( - DateTime.now().year, DateTime.now().month - 1, 1), - maxTime: DateTime.now(), onConfirm: (date) { + DatePicker.showDatePicker(context, showTitleActions: true, minTime: DateTime(DateTime.now().year, DateTime.now().month - 1, 1), maxTime: DateTime.now(), onConfirm: (date) { setState(() { widget.endDay = date; }); - }, - currentTime: widget.endDay, - locale: projectViewModel.localeType); + }, currentTime: widget.endDay, locale: projectViewModel.localeType); }, child: Container( padding: EdgeInsets.all(12), width: double.infinity, height: 65, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - color: Colors.white), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), color: Colors.white), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -163,10 +142,7 @@ class _ReminderPageState extends State { child: Container( padding: EdgeInsets.all(12), width: double.infinity, - height: 65, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - color: Colors.white), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), color: Colors.white), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -196,28 +172,21 @@ class _ReminderPageState extends State { ), InkWell( onTap: () { - DatePicker.showTimePicker(context, - showTitleActions: true, onConfirm: (date) { + DatePicker.showTimePicker(context, showTitleActions: true, onConfirm: (date) { setState(() { widget._scheduleList[index] = date; }); - }, - currentTime: widget._scheduleList[index], - locale: projectViewModel.localeType); + }, currentTime: widget._scheduleList[index], locale: projectViewModel.localeType); }, child: Container( padding: EdgeInsets.all(12), width: double.infinity, height: 65, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - color: Colors.white), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), color: Colors.white), child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Texts(getDateTime( - widget._scheduleList[index])), + Texts(getDateTime(widget._scheduleList[index])), Icon( Icons.access_time, color: Colors.black, @@ -238,29 +207,29 @@ class _ReminderPageState extends State { ), bottomSheet: Container( width: double.infinity, - height: MediaQuery.of(context).size.height * 0.2, + color: Theme.of(context).scaffoldBackgroundColor, padding: EdgeInsets.all(10), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + child: Row( + mainAxisSize: MainAxisSize.min, children: [ - SecondaryButton( - label: TranslationBase.of(context).ok, - color: Colors.grey[800], - textColor: Colors.white, - onTap: () { - schedule(); - }, - ), - SizedBox( - height: 15, - ), - SecondaryButton( - label: TranslationBase.of(context).cancel, - color: Colors.red[800], - textColor: Colors.white, - onTap: () { - Navigator.pop(context); - }, + // Expanded( + // child: DefaultButton( + // TranslationBase.of(context).cancel, + // () { + // Navigator.pop(context); + // }, + // color: Color(0xffC5272D), + // ), + // ), + // SizedBox(width: 10), + Expanded( + child: DefaultButton( + TranslationBase.of(context).ok.toUpperCase(), + () { + schedule(); + }, + color: Color(0xff359846), + ), ), ], ), @@ -270,16 +239,11 @@ class _ReminderPageState extends State { } schedule() async { - List scheduleDateTime = - calculateDaysInterval(widget.startDay, widget.endDay); + List scheduleDateTime = calculateDaysInterval(widget.startDay, widget.endDay); CalendarUtils calendarUtils = await CalendarUtils.getInstance(); - calendarUtils.createOrUpdateEvents( - scheduleList: widget._scheduleList, - description: widget.itemDescription, - title: widget.itemDescription, - scheduleDateTime: scheduleDateTime); + calendarUtils.createOrUpdateEvents(scheduleList: widget._scheduleList, description: widget.itemDescription, title: widget.itemDescription, scheduleDateTime: scheduleDateTime); Navigator.pop(context); } @@ -288,8 +252,7 @@ class _ReminderPageState extends State { List days = []; for (int i = 0; i <= endDate.difference(startDate).inDays; i++) { widget._scheduleList.forEach((element) { - days.add(startDate.add( - Duration(days: i, hours: element.hour, minutes: element.minute))); + days.add(startDate.add(Duration(days: i, hours: element.hour, minutes: element.minute))); }); } return days; @@ -318,7 +281,7 @@ class _ReminderPageState extends State { void confirmSelectDayDialog() { showDialog( context: context, - child: DayCheckBoxDialog( + builder: (cxt) => DayCheckBoxDialog( title: 'Select Day', selectedDaysOfWeek: widget.daysOfWeek, onValueSelected: (value) { diff --git a/lib/pages/medical/allergies_page.dart b/lib/pages/medical/allergies_page.dart index 459ef0f8..599d91b0 100644 --- a/lib/pages/medical/allergies_page.dart +++ b/lib/pages/medical/allergies_page.dart @@ -2,13 +2,14 @@ import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/AllergiesViewModel.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.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'; class AllergiesPage extends StatelessWidget { - List imagesInfo = List(); + List imagesInfo =[]; @override Widget build(BuildContext context) { imagesInfo.add(ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/alllergies/en/0.png',imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/alllergies/ar/0.png')); @@ -16,11 +17,13 @@ class AllergiesPage extends StatelessWidget { onModelReady: (model) => model.getAllergies(), builder: (_, model, w) => AppScaffold( isShowAppBar: true, + showNewAppBar: true, + showNewAppBarTitle: true, appBarTitle: TranslationBase.of(context).allergies, baseViewModel: model, description: TranslationBase.of(context).infoAllergies, imagesInfo: imagesInfo, - body: ListView.builder( + body: model.allergies.isNotEmpty ? ListView.builder( itemCount: model.allergies.length, itemBuilder: (context, index) => Container( margin: EdgeInsets.all(15), @@ -45,14 +48,14 @@ class AllergiesPage extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Texts(TranslationBase.of(context).remarks+" :"), - Texts(TranslationBase.of(context).description + model.allergies[index].description ?? ''), + Texts(TranslationBase.of(context).description + ": " + model.allergies[index].description! ?? ''), ], ), ) ], ), ), - ), + ) : getNoDataWidget(context), ), ); } diff --git a/lib/pages/medical/ask_doctor/ViewDoctorResponsesPage.dart b/lib/pages/medical/ask_doctor/ViewDoctorResponsesPage.dart index fc47ed3c..b96a6992 100644 --- a/lib/pages/medical/ask_doctor/ViewDoctorResponsesPage.dart +++ b/lib/pages/medical/ask_doctor/ViewDoctorResponsesPage.dart @@ -1,33 +1,342 @@ import 'package:diplomaticquarterapp/core/model/ask_doctor/DoctorResponse.dart'; +import 'package:diplomaticquarterapp/core/service/medical/ask_doctor_services.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/ask_doctor_view_model.dart'; +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/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_svg/flutter_svg.dart'; +import 'package:provider/provider.dart'; -class ViewDoctorResponsesPage extends StatelessWidget { - final DoctorResponse doctorResponse; +class ViewDoctorResponsesPage extends StatefulWidget { + final DoctorResponse? doctorResponse; - const ViewDoctorResponsesPage({Key key, this.doctorResponse}) - : super(key: key); + const ViewDoctorResponsesPage({Key? key, this.doctorResponse}) : super(key: key); + + @override + State createState() => _ViewDoctorResponsesPageState(); +} + +class _ViewDoctorResponsesPageState extends State { + int rate = 1; + TextEditingController textController = new TextEditingController(); + late ProjectViewModel projectViewModel; @override Widget build(BuildContext context) { + projectViewModel = Provider.of(context); return BaseView( - onModelReady: (model) => model.updateReadStatus(transactionNo: doctorResponse.transactionNo), + onModelReady: (model) => model.updateReadStatus(transactionNo: widget.doctorResponse!.transactionNo!), builder: (_, model, w) => AppScaffold( isShowAppBar: true, + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: Color(0xffF8F8F8), + isShowDecPage: false, appBarTitle: TranslationBase.of(context).viewDoctorResponses, baseViewModel: model, body: SingleChildScrollView( child: Container( child: Column( crossAxisAlignment: CrossAxisAlignment.start, - children: [], + children: [getResponsesList()], ), ), ), ), ); } + + Widget getResponsesList() { + return ListView.separated( + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + padding: EdgeInsets.only(bottom: 14, top: 14, left: 21, right: 21), + itemBuilder: (context, _index) { + return Container( + padding: const EdgeInsets.only(left: 20, right: 12, top: 12, bottom: 12), + height: 160, + decoration: BoxDecoration( + borderRadius: BorderRadius.all( + Radius.circular(10.0), + ), + border: Border.all(width: 1, color: Color(0xffEFEFEF)), + boxShadow: [ + BoxShadow( + color: Color(0xff000000).withOpacity(.05), + //spreadRadius: 5, + blurRadius: 27, + offset: Offset(0, -3), + ), + ], + color: Colors.white), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + child: Text( + (widget.doctorResponse!.doctorName ?? ""), + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + color: Color(0xff2E303A), + letterSpacing: -0.64, + ), + ), + ), + Container( + child: Text( + (DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(widget.doctorResponse!.createdOn!)) ?? ""), + style: TextStyle( + fontSize: 14, + color: Color(0xff2E303A), + letterSpacing: -0.64, + ), + ), + ), + Container( + margin: EdgeInsets.only(top: 10.0), + child: Text( + widget.doctorResponse!.transactions![_index]['DoctorResponse'], + style: TextStyle( + fontSize: 16, + color: Color(0xff2E303A), + letterSpacing: -0.64, + ), + ), + ), + Container( + margin: EdgeInsets.only(top: 10.0), + child: DefaultButton( + TranslationBase.of(context).rateDoctorResponse, + () { + openResponseRateDialog(context); + }, + color: CustomColors.accentColor, + ), + ), + ], + ), + ); + }, + separatorBuilder: (context, index) => SizedBox(height: 14), + itemCount: widget.doctorResponse!.transactions!.length); + } + + void openResponseRateDialog(BuildContext context) { + showModalBottomSheet( + context: context, + enableDrag: true, + isDismissible: true, + isScrollControlled: true, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.only(topLeft: Radius.circular(12), topRight: Radius.circular(12)), + ), + backgroundColor: Colors.white, + builder: (context) { + return StatefulBuilder(builder: (BuildContext context, StateSetter setState) { + return Container( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox( + height: 16.0, + ), + Text( + TranslationBase.of(context).rateDoctorResponseHeading, + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.w600, + color: Color(0xff2E303A), + letterSpacing: -0.64, + ), + ), + Padding( + padding: const EdgeInsets.all(24.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Container( + margin: rate == 1 ? EdgeInsets.only(left: 3.0, right: 3.0) : EdgeInsets.only(left: 0.0, right: 0.0), + decoration: rate == 1 + ? BoxDecoration(borderRadius: BorderRadius.circular(100), border: Border.all(width: 3, color: CustomColors.green)) + : BoxDecoration(borderRadius: BorderRadius.circular(100), border: Border.all(width: 3, color: CustomColors.white)), + child: IconButton( + onPressed: () { + rate = 1; + setState(() {}); + }, + iconSize: 35, + icon: SvgPicture.asset('assets/images/new/appointment-rating/5.svg'), + ), + ), + Container( + margin: rate == 0 ? EdgeInsets.only(left: 3.0, right: 3.0) : EdgeInsets.only(left: 0.0, right: 0.0), + decoration: rate == 0 + ? BoxDecoration(borderRadius: BorderRadius.circular(100), border: Border.all(width: 3, color: CustomColors.green)) + : BoxDecoration(borderRadius: BorderRadius.circular(100), border: Border.all(width: 3, color: CustomColors.white)), + child: IconButton( + onPressed: () { + rate = 0; + setState(() {}); + }, + iconSize: 35, + icon: SvgPicture.asset('assets/images/new/appointment-rating/1.svg'), + ), + ), + ], + ), + ), + if (rate == 0) + Container( + padding: const EdgeInsets.all(24.0), + child: Padding( + padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom), + child: inputWidget(TranslationBase.of(context).comments, "", textController, isEnable: true), + ), + ), + SizedBox( + height: 16.0, + ), + Container( + margin: EdgeInsets.fromLTRB(24.0, 0.0, 24.0, 24.0), + child: DefaultButton( + TranslationBase.of(context).submit, + () { + if (rate == 0 && textController.text.isEmpty) { + AppToast.showErrorToast(message: "Please enter comments"); + } else { + rateDoctorResponse(); + } + }, + color: CustomColors.accentColor, + ), + ), + ], + ), + ); + }); + }).then((value) { + rate = 1; + setState(() {}); + }); + } + + void rateDoctorResponse() { + GifLoaderDialogUtils.showMyDialog(context); + AskDoctorService service = new AskDoctorService(); + service + .rateDoctorResponse( + transactionNo: widget.doctorResponse!.transactionNo!, + questionType: widget.doctorResponse!.requestType!, + rate: rate, + notes: textController.text, + mobileNo: projectViewModel.user!.mobileNumber!, + idNo: projectViewModel.user!.patientIdentificationNo!, + patientName: projectViewModel.user!.firstName! + " " + projectViewModel.user!.lastName!, + projectID: widget.doctorResponse!.projectID, + language: projectViewModel.isArabic ? "ar" : "en") + .then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res['MessageStatus'] == 1) { + AppToast.showSuccessToast(message: res['SuccessMsg']); + Navigator.of(context).pop(); + } else { + AppToast.showErrorToast(message: res['ErrorEndUserMessage']); + } + }).catchError((err) { + print(err); + GifLoaderDialogUtils.hideDialog(context); + }); + } + + 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.all(40.0), + keyboardType: TextInputType.text, + 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/medical/ask_doctor/ask_doctor_home_page.dart b/lib/pages/medical/ask_doctor/ask_doctor_home_page.dart index 902225b1..ee6860a0 100644 --- a/lib/pages/medical/ask_doctor/ask_doctor_home_page.dart +++ b/lib/pages/medical/ask_doctor/ask_doctor_home_page.dart @@ -1,12 +1,9 @@ import 'dart:ui'; -import 'package:diplomaticquarterapp/core/viewModels/medical/ask_doctor_view_model.dart'; -import 'package:diplomaticquarterapp/core/viewModels/medical/prescriptions_view_model.dart'; -import 'package:diplomaticquarterapp/pages/base/base_view.dart'; -import 'package:diplomaticquarterapp/pages/medical/prescriptions/prescriptions_history_page.dart'; -import 'package:diplomaticquarterapp/pages/medical/prescriptions/prescriptions_page.dart'; +import 'package:diplomaticquarterapp/core/enum/filter_type.dart'; +import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/new_design/my_tab_view.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -19,9 +16,10 @@ class AskDoctorHomPage extends StatefulWidget { _AskDoctorHomPageState createState() => _AskDoctorHomPageState(); } -class _AskDoctorHomPageState extends State - with SingleTickerProviderStateMixin { - TabController _tabController; +class _AskDoctorHomPageState extends State with SingleTickerProviderStateMixin { + late TabController _tabController; + + int filterType = 0; @override void initState() { @@ -40,83 +38,40 @@ class _AskDoctorHomPageState extends State return AppScaffold( isShowAppBar: true, appBarTitle: TranslationBase.of(context).askDoctor, - body: Scaffold( - extendBodyBehindAppBar: true, - appBar: PreferredSize( - preferredSize: Size.fromHeight(65.0), - child: Stack( - children: [ - Positioned( - bottom: 1, - left: 0, - right: 0, - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10), - child: Container( - color: Theme.of(context) - .scaffoldBackgroundColor - .withOpacity(0.8), - height: 70.0, - ), - ), - ), - Center( - child: Container( - height: 60.0, - margin: EdgeInsets.only(top: 10.0), - width: MediaQuery.of(context).size.width * 0.9, - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Theme.of(context).dividerColor, - width: 0.9), - ), - color: Colors.white), - child: Center( - child: TabBar( - isScrollable: true, - controller: _tabController, - indicatorWeight: 5.0, - labelColor: Theme.of(context).primaryColor, - labelPadding: EdgeInsets.only(top: 4.0, left: 18.0, right: 18.0), - unselectedLabelColor: Colors.grey[800], - tabs: [ - Tab( - child: Container( - width: MediaQuery.of(context).size.width * 0.36, - child: Center( - child: Texts(TranslationBase.of(context).askDoctor), - ), - ), - ), - Tab(child: Container( - width: MediaQuery.of(context).size.width * 0.36, - child: Center( - child: Texts(TranslationBase.of(context).doctorResponses,textAlign: TextAlign.start,), - ), - ),) - ], - ), - ), - ), - ), + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: Color(0xffF8F8F8), + isShowDecPage: true, + description: TranslationBase.of(context).infoAskDoc, + imagesInfo: [ + ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/ask-doctor/en/0.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/ask-doctor/ar/0.png'), + ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/ask-doctor/en/1.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/ask-doctor/ar/1.png') + ], + body: Column( + children: [ + Row( + children: [ + MyTabView(TranslationBase.of(context).askDoctor, FilterType.Clinic, filterType == 0 ? FilterType.Clinic : FilterType.Hospital, () { + if (filterType != 0) + setState(() { + filterType = 0; + }); + }), + MyTabView(TranslationBase.of(context).doctorResponses, FilterType.Hospital, filterType != 0 ? FilterType.Hospital : FilterType.Clinic, () { + if (filterType == 0) + setState(() { + filterType = 1; + }); + }), ], ), - ), - body: Column( - children: [ - Expanded( - child: TabBarView( - physics: BouncingScrollPhysics(), - controller: _tabController, - children: [ - AskDoctorPage(), - DoctorResponse() - ], - ), - ) - ], - ), + Expanded( + child: IndexedStack( + index: filterType, + children: [AskDoctorPage(), DoctorResponse()], + ), + ) + ], ), ); } diff --git a/lib/pages/medical/ask_doctor/ask_doctor_page.dart b/lib/pages/medical/ask_doctor/ask_doctor_page.dart index 795d1869..96cd9944 100644 --- a/lib/pages/medical/ask_doctor/ask_doctor_page.dart +++ b/lib/pages/medical/ask_doctor/ask_doctor_page.dart @@ -1,216 +1,137 @@ -import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/service/medical/ask_doctor_services.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/ask_doctor_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; import 'package:diplomaticquarterapp/pages/BookAppointment/widgets/DoctorView.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/medical/ask_doctor/request_type.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/widgets/others/app_expandable_notifier.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:rating_bar/rating_bar.dart'; class AskDoctorPage extends StatelessWidget { + AskDoctorService service = new AskDoctorService(); + @override Widget build(BuildContext context) { return BaseView( onModelReady: (model) => model.getMyDoctor(), builder: (_, model, w) => AppScaffold( baseViewModel: model, - body: SingleChildScrollView( - child: Container( - margin: EdgeInsets.all(10), - child: Column( - children: [ - SizedBox( - height: 70, - ), - ...List.generate( - model.patientDoctorAppointmentListHospital.length, - (index) => AppExpandableNotifier( - title: - model.patientDoctorAppointmentListHospital[index].filterName, - bodyWidget: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: - model.patientDoctorAppointmentListHospital[index].patientDoctorAppointmentList.map((doctor) { - return InkWell( - onTap: () { - model - .getCallInfoHoursResult( - doctorId: doctor.doctorID, - projectId: doctor.projectID) - .then((value) { - if (model.state != ViewState.ErrorLocal && - model.state != ViewState.Error) { - // Navigator.pop(context); - Navigator.push( - context, - FadePage( - page: RequestTypePage(doctorList: doctor,), - ), - ); - } else { - AppToast.showErrorToast(message: model.error); - } - }); + body: model.patientDoctorAppointmentListHospital.length > 0 ? _appointmentExpandableList(model.patientDoctorAppointmentListHospital, model) : noDoctor(context), + ), + ); + } - ///.showProgressBar( - // text: "Loading", - // backgroundColor: - // Colors.blue.withOpacity(0.6)) - }, - child: Card( - margin: - EdgeInsets.fromLTRB(10.0, 16.0, 10.0, 8.0), - color: Colors.white, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - ), - child: Container( - decoration: BoxDecoration(), - padding: EdgeInsets.all(7.0), - width: MediaQuery.of(context).size.width, - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Expanded( - flex: 1, - child: ClipRRect( - borderRadius: - BorderRadius.circular(100.0), - child: Image.network( - doctor.doctorImageURL, - fit: BoxFit.fill, - height: 60.0, - width: 60.0), - ), - ), - Expanded( - flex: 4, - child: Container( - width: - MediaQuery.of(context).size.width * - 0.55, - margin: EdgeInsets.fromLTRB( - 20.0, 10.0, 10.0, 0.0), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - if (doctor.doctorTitle != null) - Text( - doctor.doctorTitle + - " " + - doctor.name, - style: TextStyle( - fontSize: 14.0, - color: Colors.grey[700], - letterSpacing: 1.0)), - Container( - margin: EdgeInsets.only(top: 3.0), - child: Text(doctor.clinicName, - style: TextStyle( - fontSize: 12.0, - color: Colors.grey[600], - letterSpacing: 1.0)), - ), - Container( - margin: EdgeInsets.only(top: 3.0), - child: Text(doctor.projectName, - style: TextStyle( - fontSize: 12.0, - color: Colors.grey[600], - letterSpacing: 1.0)), - ), - if (doctor.speciality != null) - Container( - margin: EdgeInsets.only( - top: 3.0, bottom: 3.0), - child: Text( - getDoctorSpeciality( - doctor.speciality) - .trim(), - style: TextStyle( - fontSize: 12.0, - color: Colors.grey[600], - letterSpacing: 1.0)), - ), - doctor.nearestFreeSlot != null - ? Container( - margin: EdgeInsets.only( - top: 3.0, bottom: 3.0), - child: Text( - getDate(doctor - .nearestFreeSlot), - style: TextStyle( - fontSize: 14.0, - fontWeight: - FontWeight.bold, - color: Colors - .green[600], - letterSpacing: - 1.0)), - ) - : Container(), - Row( - mainAxisAlignment: - MainAxisAlignment - .spaceBetween, - mainAxisSize: MainAxisSize.max, - children: [ - RatingBar.readOnly( - initialRating: doctor - .actualDoctorRate - .toDouble(), - size: 20.0, - filledColor: - Colors.yellow[700], - emptyColor: Colors.grey[500], - isHalfAllowed: true, - halfFilledIcon: - Icons.star_half, - filledIcon: Icons.star, - emptyIcon: Icons.star, - ), - Container( - child: Image.network( - doctor.nationalityFlagURL, - width: 25.0, - height: 25.0), - ), - ], - ), - ], - ), - ), - ), - ], - ), - ), - ), - ); - }).toList(), - )), - ) - ], - ), - ), - ), + Widget noDoctor(BuildContext context) { + return Container( + margin: EdgeInsets.only(left: 50.0, right: 50.0), + child: Center( + child: Text(TranslationBase.of(context).askDocEmpty, textAlign: TextAlign.center, style: TextStyle(fontSize: 14, fontWeight: FontWeight.w400, color: CustomColors.accentColor)), ), ); } - String getDoctorSpeciality(List docSpecial) { - String docSpeciality = ""; - docSpecial.forEach((v) { - docSpeciality = docSpeciality + v + "\n"; + Widget _appointmentExpandableList(List _patientDoctorAppointmentList, model) { + return ListView.separated( + addAutomaticKeepAlives: true, + physics: BouncingScrollPhysics(), + padding: EdgeInsets.only(top: 12), + separatorBuilder: (context, index) { + return Container( + height: 12, + margin: EdgeInsets.only(left: 21, right: 21), + // color: Color(0xffD9D9D9), + ); + }, + itemBuilder: (context, index) { + List _doctorList = _patientDoctorAppointmentList[index].patientDoctorAppointmentList!; + return AppExpandableNotifier( + title: _patientDoctorAppointmentList[index].filterName, + bodyWidget: ListView.separated( + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + padding: EdgeInsets.only(bottom: 14, top: 14, left: 21, right: 21), + itemBuilder: (context, _index) { + DoctorList _doctor = _doctorList[_index]; + DoctorList doctorList = DoctorList( + date: _doctor.date, + projectID: _doctor.projectID, + setupID: _doctor.setupID, + clinicID: _doctor.clinicID, + projectName: _doctor.projectName, + clinicName: _doctor.clinicName, + actualDoctorRate: _doctor.actualDoctorRate, + doctorID: _doctor.doctorID, + doctorRate: _doctor.doctorRate, + gender: _doctor.gender, + doctorTitle: _doctor.doctorTitle, + name: _doctor.name, + speciality: _doctor.speciality, + doctorImageURL: _doctor.doctorImageURL, + nationalityFlagURL: _doctor.nationalityFlagURL); + return DoctorView( + doctor: doctorList, + isLiveCareAppointment: false, + isShowFlag: false, + onTap: () async { + if (await checkIfDoctorAvailable(_doctor, context)) { + GifLoaderDialogUtils.showMyDialog(context); + service.getCallInfoHoursResult(doctorId: _doctor.doctorID, projectId: _doctor.projectID).then((res) { + GifLoaderDialogUtils.hideDialog(context); + Navigator.push( + context, + FadePage( + page: RequestTypePage(doctorList: _doctor), + ), + ); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + if (err != null) AppToast.showErrorToast(message: err.toString()); + print(err); + }); + } + }, + ); + }, + separatorBuilder: (context, index) => SizedBox(height: 14), + itemCount: _doctorList.length), + ); + }, + itemCount: _patientDoctorAppointmentList.length, + ); + } + + Future checkIfDoctorAvailable(DoctorList _doctor, BuildContext context) async { + AskDoctorService askDocservice = new AskDoctorService(); + bool isAvailable = false; + GifLoaderDialogUtils.showMyDialog(context); + await askDocservice.isDoctorAvailable(doctorId: _doctor.doctorID, projectId: _doctor.projectID, clinicId: _doctor.clinicID).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res != null) { + print(res['IsDoctorAvailable']); + if (res['IsDoctorAvailable']) { + isAvailable = true; + } else { + isAvailable = false; + AppToast.showErrorToast(message: res['endUserMessage'], localContext: context); + } + } else { + isAvailable = true; + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + if (err != null) AppToast.showErrorToast(message: err.toString(), localContext: context); + print(err); }); - return docSpeciality; + + return Future.value(isAvailable); } String getDate(String date) { @@ -236,4 +157,3 @@ class AskDoctorPage extends StatelessWidget { } } } - diff --git a/lib/pages/medical/ask_doctor/doctor_response.dart b/lib/pages/medical/ask_doctor/doctor_response.dart index 846c9a05..0f7c1a09 100644 --- a/lib/pages/medical/ask_doctor/doctor_response.dart +++ b/lib/pages/medical/ask_doctor/doctor_response.dart @@ -2,6 +2,7 @@ import 'package:diplomaticquarterapp/core/viewModels/medical/ask_doctor_view_mod import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.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/others/app_expandable_notifier.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; @@ -27,7 +28,7 @@ class DoctorResponse extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( - height: 65, + height: 16, ), AppExpandableNotifier( headerWidget: Padding( @@ -61,22 +62,26 @@ class DoctorResponse extends StatelessWidget { return InkWell( onTap: () { ///go to page ViewDoctorResponsesPage - Navigator.push( - context, - FadePage( - page: ViewDoctorResponsesPage( - doctorResponse: doctor, + if (doctor.transactions != null && doctor.transactions!.isNotEmpty) { + Navigator.push( + context, + FadePage( + page: ViewDoctorResponsesPage( + doctorResponse: doctor, + ), ), - ), - ); + ); + } else { + Utils.showErrorToast("There are no doctor responses for this request."); + } }, child: Container( - height: 70, + height: 100, margin: EdgeInsets.only(top: 8, bottom: 8), decoration: BoxDecoration( borderRadius: BorderRadius.circular(8), color: Colors.white, - border: Border.all(color: Colors.grey[300]), + border: Border.all(color: Colors.grey[300]!), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, @@ -85,22 +90,21 @@ class DoctorResponse extends StatelessWidget { child: Padding( padding: const EdgeInsets.all(8.0), child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ Texts('${doctor.doctorName}'), SizedBox( height: 5, ), - Texts( - '${doctor.requestTypeDescription}'), + Texts('${doctor.requestTypeDescription}'), ], ), ), ), - Icon(projectViewModel.isArabic - ? Icons.arrow_forward_ios - : Icons.arrow_back_ios) + Padding( + padding: const EdgeInsets.fromLTRB(10.0, 0.0, 10.0, 0.0), + child: Icon(projectViewModel.isArabic ? Icons.arrow_back_ios : Icons.arrow_forward_ios), + ) ], ), ), @@ -141,12 +145,12 @@ class DoctorResponse extends StatelessWidget { return InkWell( onTap: () {}, child: Container( - height: 70, + height: 85, margin: EdgeInsets.only(top: 8, bottom: 8), decoration: BoxDecoration( borderRadius: BorderRadius.circular(8), color: Colors.white, - border: Border.all(color: Colors.grey[300]), + border: Border.all(color: Colors.grey[300]!), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, @@ -155,22 +159,21 @@ class DoctorResponse extends StatelessWidget { child: Padding( padding: const EdgeInsets.all(8.0), child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ Texts('${doctor.doctorName}'), SizedBox( height: 5, ), - Texts( - '${doctor.requestTypeDescription}'), + Texts('${doctor.requestTypeDescription}'), ], ), ), ), - Icon(projectViewModel.isArabic - ? Icons.arrow_forward_ios - : Icons.arrow_back_ios) + Padding( + padding: const EdgeInsets.all(8.0), + child: Icon(projectViewModel.isArabic ? Icons.arrow_back_ios : Icons.arrow_forward_ios), + ) ], ), ), diff --git a/lib/pages/medical/ask_doctor/request_type.dart b/lib/pages/medical/ask_doctor/request_type.dart index 55e04a73..2dece140 100644 --- a/lib/pages/medical/ask_doctor/request_type.dart +++ b/lib/pages/medical/ask_doctor/request_type.dart @@ -5,15 +5,15 @@ import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/medical/balance/new_text_Field.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; class RequestTypePage extends StatefulWidget { - final DoctorList doctorList; + final DoctorList? doctorList; - RequestTypePage({Key key, this.doctorList}); + RequestTypePage({Key? key, this.doctorList}); @override _RequestTypePageState createState() => _RequestTypePageState(); @@ -27,11 +27,14 @@ class _RequestTypePageState extends State { @override Widget build(BuildContext context) { return BaseView( + // onModelReady: (model) => model.getQuestionTypes(), onModelReady: (model) => model.getCallRequestTypeLOVs(), builder: (_, model, w) => AppScaffold( isShowAppBar: true, appBarTitle: TranslationBase.of(context).requestType, baseViewModel: model, + showNewAppBar: true, + showNewAppBarTitle: true, body: SingleChildScrollView( child: Container( margin: EdgeInsets.all(10), @@ -43,16 +46,13 @@ class _RequestTypePageState extends State { (index) => Container( width: double.maxFinite, height: 55, - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(8.0)), + decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8.0)), margin: EdgeInsets.all(8.0), child: InkWell( onTap: () { setState(() { - selected = model.askDoctorReqTypes[index].description; - parameterCode = - model.askDoctorReqTypes[index].parameterCode; + selected = model.askDoctorReqTypes[index].description!; + parameterCode = model.askDoctorReqTypes[index].parameterCode!; }); }, child: Row( @@ -60,8 +60,7 @@ class _RequestTypePageState extends State { children: [ Padding( padding: const EdgeInsets.all(8.0), - child: Text( - model.askDoctorReqTypes[index].description), + child: Text(model.askDoctorReqTypes[index].description!), ), Radio( value: model.askDoctorReqTypes[index].description, @@ -69,9 +68,8 @@ class _RequestTypePageState extends State { activeColor: Colors.red[800], onChanged: (value) { setState(() { - selected = value; - parameterCode = model - .askDoctorReqTypes[index].parameterCode; + selected = value!; + parameterCode = model.askDoctorReqTypes[index].parameterCode!; }); }, ), @@ -104,27 +102,25 @@ class _RequestTypePageState extends State { ), bottomSheet: Container( width: double.maxFinite, - height: MediaQuery.of(context).size.height * 0.1, + height: 80.0, child: Padding( padding: const EdgeInsets.all(12.0), - child: SecondaryButton( - label: TranslationBase.of(context).submit, - loading: model.state == ViewState.BusyLocal, - textColor: Colors.white, - onTap: () { - model - .sendRequestLOV( - doctorList: widget.doctorList, - requestType: parameterCode.toString(), - remark: question) - .then((value) { - if (model.state != ViewState.ErrorLocal || - model.state != ViewState.Error) { - Navigator.pop(context); - } - }); - }, - color: Colors.grey[800], + child: Container( + width: MediaQuery.of(context).size.width * 0.8, + child: DefaultButton( + TranslationBase.of(context).submit, + () => { + model.sendRequestLOV(doctorList: widget.doctorList!, requestType: parameterCode.toString(), remark: question).then((value) { + if (model.state != ViewState.ErrorLocal && model.state != ViewState.Error) { + Navigator.pop(context); + AppToast.showSuccessToast(message: TranslationBase.of(context).RRTRequestSuccess); + } + }) + }, + color: Color(0xffD02127), + textColor: Colors.white, + disabledColor: Color(0xffEAEAEA), + ), ), ), ), diff --git a/lib/pages/medical/balance/advance_payment_page.dart b/lib/pages/medical/balance/advance_payment_page.dart index d3921d4a..19e4551c 100644 --- a/lib/pages/medical/balance/advance_payment_page.dart +++ b/lib/pages/medical/balance/advance_payment_page.dart @@ -4,28 +4,27 @@ import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; import 'package:diplomaticquarterapp/core/model/my_balance/patient_info.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/my_balance_view_model.dart'; +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/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'; 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/secondary_button.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.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'; import 'package:flutter/material.dart'; +import 'package:provider/provider.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 } @@ -39,342 +38,396 @@ class _AdvancePaymentPageState extends State { TextEditingController _fileTextController = TextEditingController(); TextEditingController _notesTextController = TextEditingController(); BeneficiaryType beneficiaryType = BeneficiaryType.NON; - HospitalsModel _selectedHospital; + HospitalsModel _selectedHospital = HospitalsModel(); String amount = ""; - String email; - PatientInfo _selectedPatientInfo; - AuthenticatedUser authenticatedUser; - GetAllSharedRecordsByStatusList selectedPatientFamily; + String email = ""; + PatientInfo _selectedPatientInfo = PatientInfo(); + AuthenticatedUser authenticatedUser = AuthenticatedUser(); + GetAllSharedRecordsByStatusList selectedPatientFamily = GetAllSharedRecordsByStatusList(); AdvanceModel advanceModel = AdvanceModel(); AppSharedPreferences sharedPref = AppSharedPreferences(); - AuthenticatedUser authUser; + AuthenticatedUser authUser = AuthenticatedUser(); - List imagesInfo = List(); + List imagesInfo =[]; + + late ProjectViewModel projectViewModel; @override void initState() { super.initState(); getAuthUser(); imagesInfo.add(ImagesInfo( - imageEn: - 'https://hmgwebservices.com/Images/MobileApp/images-info-home/advance-payment/en/0.png', - imageAr: - 'https://hmgwebservices.com/Images/MobileApp/images-info-home/advance-payment/ar/0.png')); + imageEn: 'https://hmgwebservices.com/Images/MobileApp/images-info-home/advance-payment/en/0.png', + imageAr: 'https://hmgwebservices.com/Images/MobileApp/images-info-home/advance-payment/ar/0.png')); } @override Widget build(BuildContext context) { + projectViewModel = Provider.of(context); return BaseView( - onModelReady: (model) => model.getHospitals(), + onModelReady: (model) { + model.getHospitals(projectViewModel.isArabic ? 1 : 2, isAdvancePayment: true); + model.getFamilyFiles(); + }, builder: (_, model, w) => AppScaffold( - isShowAppBar: true, - imagesInfo: imagesInfo, - appBarTitle: TranslationBase.of(context).advancePayment, - description: TranslationBase.of(context).infoAdvancePayment, - body: SingleChildScrollView( - physics: ScrollPhysics(), - child: Container( - margin: EdgeInsets.all(12), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts( - TranslationBase.of(context).advancePaymentLabel, - textAlign: TextAlign.center, - ), - SizedBox( - height: 12, - ), - InkWell( - onTap: () => confirmSelectBeneficiaryDialog(model), - 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(getBeneficiaryType()), - Icon(Icons.arrow_drop_down) - ], + isShowAppBar: true, + imagesInfo: imagesInfo, + appBarTitle: TranslationBase.of(context).advancePayment, + description: TranslationBase.of(context).infoAdvancePayment, + showNewAppBarTitle: true, + showNewAppBar: true, + backgroundColor: CustomColors.appBackgroudGreyColor, + body: Column( + children: [ + Expanded( + child: SingleChildScrollView( + padding: EdgeInsets.all(21), + physics: BouncingScrollPhysics(), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Text( + TranslationBase.of(context).advancePaymentLabel, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.64, ), ), - ), - if (beneficiaryType == BeneficiaryType.MyFamilyFiles) - SizedBox( - height: 12, - ), - if (beneficiaryType == BeneficiaryType.MyFamilyFiles) + SizedBox(height: 12), InkWell( onTap: () { - GifLoaderDialogUtils.showMyDialog(context); - model.getFamilyFiles().then((value) { - GifLoaderDialogUtils.hideDialog(context); - confirmSelectFamilyDialog(model - .getAllSharedRecordsByStatusResponse - .getAllSharedRecordsByStatusList); - }); + List list = [ + RadioSelectionDialogModel(TranslationBase.of(context).myAccount, 0), + RadioSelectionDialogModel(TranslationBase.of(context).myFamilyFiles, 1), + RadioSelectionDialogModel(TranslationBase.of(context).otherAccount, 2), + ]; + showDialog( + context: context, + builder: (cxt) => 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(12), + padding: EdgeInsets.all(8), width: double.infinity, height: 65, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - color: Colors.white), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), color: Colors.white), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Texts(getFamilyMembersName()), + Text( + getBeneficiaryType(), + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + letterSpacing: -0.46, + ), + ), Icon(Icons.arrow_drop_down) ], ), ), ), - SizedBox( - height: 12, - ), - NewTextFields( - hintText: TranslationBase.of(context).fileNumber, - controller: _fileTextController, - ), - if (beneficiaryType == BeneficiaryType.OtherAccount) - SizedBox( - height: 12, + if (beneficiaryType == BeneficiaryType.MyFamilyFiles) SizedBox(height: 12), + if (beneficiaryType == BeneficiaryType.MyFamilyFiles) + InkWell( + onTap: () { + // GifLoaderDialogUtils.showMyDialog(context); + model.getFamilyFiles().then((value) { + // GifLoaderDialogUtils.hideDialog(context); + confirmSelectFamilyDialog(model.getAllSharedRecordsByStatusResponse.getAllSharedRecordsByStatusList!); + }); + }, + 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: [ + Text( + getFamilyMembersName(), + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + letterSpacing: -0.46, + ), + ), + Icon(Icons.arrow_drop_down), + ], + ), + ), + ), + SizedBox(height: 12), + NewTextFields( + hintText: TranslationBase.of(context).fileNumber, + controller: _fileTextController, + readOnly: beneficiaryType == BeneficiaryType.OtherAccount ? false : true, ), - if (beneficiaryType == BeneficiaryType.OtherAccount) + if (beneficiaryType == BeneficiaryType.OtherAccount) SizedBox(height: 12), + if (beneficiaryType == BeneficiaryType.OtherAccount) + InkWell( + onTap: () { + if (_fileTextController.text.isNotEmpty) { + GifLoaderDialogUtils.showMyDialog(context); + model.getPatientInfoByPatientID(id: _fileTextController.text).then((value) { + GifLoaderDialogUtils.hideDialog(context); + confirmSelectPatientDialog(model.patientInfoList); + }); + } else + AppToast.showErrorToast(message: 'Please Enter The File Number'); + }, + 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: [ + Text( + getPatientName(), + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + letterSpacing: -0.46, + ), + ), + Icon(Icons.arrow_drop_down), + ], + ), + ), + ), + SizedBox(height: 12), InkWell( - onTap: () { - if (_fileTextController.text.isNotEmpty) { - GifLoaderDialogUtils.showMyDialog(context); - model - .getPatientInfoByPatientID( - id: _fileTextController.text) - .then((value) { - GifLoaderDialogUtils.hideDialog(context); - confirmSelectPatientDialog(model.patientInfoList); - }); - } else - AppToast.showErrorToast( - message: 'Please Enter The File Number'); - }, + onTap: () => confirmSelectHospitalDialog(model.hospitals), child: Container( padding: EdgeInsets.all(12), width: double.infinity, height: 65, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - color: Colors.white), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), color: Colors.white), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Texts(getPatientName()), - Icon(Icons.arrow_drop_down) + Text( + getHospitalName(), + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + letterSpacing: -0.46, + ), + ), + Icon(Icons.arrow_drop_down), ], ), ), ), - SizedBox( - height: 12, - ), - InkWell( - onTap: () => confirmSelectHospitalDialog(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()), - Icon(Icons.arrow_drop_down) - ], - ), - ), - ), - SizedBox( - height: 12, - ), - NewTextFields( - hintText: TranslationBase.of(context).amount, - keyboardType: TextInputType.number, - onChanged: (value) { - setState(() { - amount = value; - }); - }, - ), - SizedBox( - height: 12, - ), - if (model.user != null) + SizedBox(height: 12), NewTextFields( - hintText: TranslationBase.of(context).depositorEmail, - initialValue: model.user.emailAddress, + hintText: TranslationBase.of(context).amount, + keyboardType: TextInputType.numberWithOptions(signed: false, decimal: true), onChanged: (value) { - email = value; + setState(() { + amount = value; + }); }, ), - SizedBox( - height: 12, - ), - NewTextFields( - hintText: TranslationBase.of(context).notes, - controller: _notesTextController, - ), - SizedBox( - height: MediaQuery.of(context).size.height * 0.15, - ) - ], + SizedBox(height: 12), + if (model.user != null) + NewTextFields( + hintText: TranslationBase.of(context).depositorEmail, + initialValue: model.user.emailAddress, + onChanged: (value) { + email = value; + }, + ), + SizedBox(height: 12), + NewTextFields( + hintText: TranslationBase.of(context).notes, + controller: _notesTextController, + ), + SizedBox( + height: MediaQuery.of(context).size.height * 0.15, + ) + ], + ), ), ), - ), - bottomSheet: Container( - height: 90, - width: double.infinity, - padding: EdgeInsets.all(18), - child: SecondaryButton( - textColor: Colors.white, - label: TranslationBase.of(context).submit, - disabled: amount.isEmpty || - _fileTextController.text.isEmpty || - _selectedHospital == null, - onTap: () { - var mobileNum; - var patientName; + Container( + color: Colors.white, + padding: EdgeInsets.only(top: 16, bottom: 16, right: 21, left: 21), + child: DefaultButton( + TranslationBase.of(context).submit, + (amount.isEmpty || _fileTextController.text.isEmpty || _selectedHospital == null) + ? null + : () { + var mobileNum; + var patientName; - if (beneficiaryType == BeneficiaryType.MyFamilyFiles) { - mobileNum = selectedPatientFamily.mobileNumber; - patientName = selectedPatientFamily.patientName; - } + if (beneficiaryType == BeneficiaryType.MyFamilyFiles) { + mobileNum = selectedPatientFamily.mobileNumber; + patientName = selectedPatientFamily.patientName; + } - if (beneficiaryType == BeneficiaryType.MyAccount) { - mobileNum = model.user.mobileNumber; - patientName = model.user.firstName; - } + if (beneficiaryType == BeneficiaryType.MyAccount) { + mobileNum = model.user!.mobileNumber; + patientName = model.user!.firstName; + } - if (beneficiaryType == BeneficiaryType.OtherAccount) { - mobileNum = _selectedPatientInfo.mobileNumber; - patientName = _selectedPatientInfo.fullName; - } + if (beneficiaryType == BeneficiaryType.OtherAccount) { + mobileNum = _selectedPatientInfo.mobileNumber; + patientName = _selectedPatientInfo.fullName; + } - advanceModel.fileNumber = _fileTextController.text; - advanceModel.hospitalsModel = _selectedHospital; - advanceModel.note = _notesTextController.text; - advanceModel.email = email ?? model.user.emailAddress; - advanceModel.amount = amount; - advanceModel.mobileNumber = mobileNum; - advanceModel.patientName = patientName; - GifLoaderDialogUtils.showMyDialog(context); - model - .getPatientInfoByPatientIDAndMobileNumber(advanceModel) - .then((value) { - GifLoaderDialogUtils.hideDialog(context); - if (model.state != ViewState.Error && - model.state != ViewState.ErrorLocal) { - Utils.hideKeyboard(context); - Navigator.push(context, FadePage(page: PaymentMethod())) - .then( - (value) { - Navigator.push( - context, - FadePage( - page: ConfirmPaymentPage( - advanceModel: advanceModel, - selectedPaymentMethod: value, - patientInfoAndMobileNumber: - model.patientInfoAndMobileNumber, - authenticatedUser: authUser, - ), - ), - ); + advanceModel.fileNumber = _fileTextController.text; + advanceModel.hospitalsModel = _selectedHospital; + advanceModel.note = _notesTextController.text; + advanceModel.email = email ?? model.user!.emailAddress; + advanceModel.amount = amount; + advanceModel.mobileNumber = mobileNum; + advanceModel.patientName = patientName; + GifLoaderDialogUtils.showMyDialog(context); + + model.getPatientInfoByPatientIDAndMobileNumber(advanceModel).then((value) { + GifLoaderDialogUtils.hideDialog(context); + if (model.state != ViewState.Error && model.state != ViewState.ErrorLocal) { + Utils.hideKeyboard(context); + Navigator.push( + context, + FadePage( + page: PaymentMethod( + onSelectedMethod: (String metohd, [String? selectedInstallmentPlan]) { + setState(() {}); + }, + isShowInstallments: false, + isFromAdvancePayment: true), + ), + ).then( + (value) { + Navigator.push( + context, + FadePage( + page: ConfirmPaymentPage( + advanceModel: advanceModel, + selectedPaymentMethod: value[0], + patientInfoAndMobileNumber: model.patientInfoAndMobileNumber, + authenticatedUser: authUser, + installmentPlan: value[1], + ), + ), + ); + projectViewModel.analytics.advancePayments.payment_method(method: value[0].toString().toLowerCase(), type: 'wallet'); + }, + ); + } + }); + projectViewModel.analytics.advancePayments.wallet_payment_details(); }, - ); - } - }); - }, + color: Color(0xffD02127), + textColor: Colors.white, + disabledColor: Color(0xffEAEAEA), + ), ), - )), - ); - } - - 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; - }); + builder: (cxt) => 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; - }); + builder: (cxt) => RadioSelectionDialog( + listData: list, + isScrollable: true, + selectedIndex: _selectedPatientIndex, + onValueSelected: (index) { + _selectedPatientIndex = index; + _selectedPatientInfo = patientInfoList[index]; + advanceModel.depositorName = _selectedPatientInfo.fullName; + setState(() {}); }, ), ); } - void confirmSelectFamilyDialog( - List getAllSharedRecordsByStatusList) { - if (getAllSharedRecordsByStatusList.isNotEmpty) + int _selectedFamilyMemberIndex = -1; + + void confirmSelectFamilyDialog(List getAllSharedRecordsByStatusList) { + if (getAllSharedRecordsByStatusList.isNotEmpty) { + List list = [ + for (int i = 0; i < getAllSharedRecordsByStatusList.length; i++) + if (getAllSharedRecordsByStatusList[i].status == 3) RadioSelectionDialogModel(getAllSharedRecordsByStatusList[i].patientName!, i), + ]; + // GifLoaderDialogUtils.hideDialog(context); showDialog( context: context, - child: SelectPatientFamilyDialog( - getAllSharedRecordsByStatusList: getAllSharedRecordsByStatusList, - selectedPatientFamily: selectedPatientFamily, - onValueSelected: (value) { - setState(() { - selectedPatientFamily = value; - _fileTextController.text = - selectedPatientFamily.responseID.toString(); - advanceModel.depositorName = value.patientName; - }); + builder: (cxt) => RadioSelectionDialog( + listData: list, + isScrollable: true, + selectedIndex: _selectedFamilyMemberIndex, + onValueSelected: (index) { + _selectedFamilyMemberIndex = index; + selectedPatientFamily = getAllSharedRecordsByStatusList[index]; + _fileTextController.text = selectedPatientFamily.responseID.toString(); + setState(() {}); }, ), ); + } } String getBeneficiaryType() { @@ -394,23 +447,22 @@ class _AdvancePaymentPageState extends State { } String getHospitalName() { - if (_selectedHospital != null) - return _selectedHospital.name; + if (_selectedHospital != null && _selectedHospital.name != null) + return _selectedHospital.name!; else return TranslationBase.of(context).selectHospital; } String getPatientName() { if (_selectedPatientInfo != null) - return _selectedPatientInfo.fullName; + 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)); + var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE)); setState(() { authUser = data; }); @@ -418,8 +470,8 @@ class _AdvancePaymentPageState extends State { } String getFamilyMembersName() { - if (selectedPatientFamily != null) - return selectedPatientFamily.patientName; + if (selectedPatientFamily.patientName != null) + return selectedPatientFamily.patientName!; else return TranslationBase.of(context).selectFamilyPatientName; } diff --git a/lib/pages/medical/balance/confirm_payment_page.dart b/lib/pages/medical/balance/confirm_payment_page.dart index eecb6abd..70ff4821 100644 --- a/lib/pages/medical/balance/confirm_payment_page.dart +++ b/lib/pages/medical/balance/confirm_payment_page.dart @@ -1,69 +1,123 @@ +import 'dart:developer'; + import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/enum/PayfortEnums.dart'; import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/my_balance/AdvanceModel.dart'; import 'package:diplomaticquarterapp/core/model/my_balance/patient_info_and_mobile_number.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/my_balance_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; +import 'package:diplomaticquarterapp/models/LiveCare/ApplePayInsertRequest.dart'; +import 'package:diplomaticquarterapp/models/apple_pay_request.dart'; +import 'package:diplomaticquarterapp/models/apple_pay_response.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; +import 'package:diplomaticquarterapp/services/livecare_services/livecare_provider.dart'; +import 'package:diplomaticquarterapp/services/payfort_services/payfort_project_details_resp_model.dart'; +import 'package:diplomaticquarterapp/services/payfort_services/payfort_view_model.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:flutter/cupertino.dart'; +import 'package:diplomaticquarterapp/widgets/otp/sms-popup.dart'; import 'package:flutter/material.dart'; - -import 'dialogs/ConfirmSMSDialog.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:provider/provider.dart'; import 'new_text_Field.dart'; -class ConfirmPaymentPage extends StatelessWidget { - final AdvanceModel advanceModel; - final PatientInfoAndMobileNumber patientInfoAndMobileNumber; - final String selectedPaymentMethod; - MyInAppBrowser browser; - AuthenticatedUser authenticatedUser; +class ConfirmPaymentPage extends StatefulWidget { + final AdvanceModel? advanceModel; + final PatientInfoAndMobileNumber? patientInfoAndMobileNumber; + final String? selectedPaymentMethod; + AuthenticatedUser? authenticatedUser; + String? installmentPlan; + + ConfirmPaymentPage({this.advanceModel, this.patientInfoAndMobileNumber, this.selectedPaymentMethod, this.authenticatedUser, this.installmentPlan}); + + @override + _ConfirmPaymentPageState createState() => _ConfirmPaymentPageState(); +} + +class _ConfirmPaymentPageState extends State { + late MyInAppBrowser browser; + late ProjectViewModel projectViewModel; + AppSharedPreferences sharedPref = AppSharedPreferences(); + String transID = ""; - ConfirmPaymentPage( - {this.advanceModel, - this.patientInfoAndMobileNumber, - this.selectedPaymentMethod, - this.authenticatedUser}); + late String tamaraPaymentStatus; + late String tamaraOrderID; + + // Pay _payClient; @override - Widget build(BuildContext context) { - void showSMSDialog() { - showDialog( - context: context, - barrierDismissible: false, - child: ConfirmSMSDialog( - phoneNumber: patientInfoAndMobileNumber.mobileNumber, - ), - ).then((value) { - print("dialog dismissed"); - print(value); - if (value != null && value) { - AppoitmentAllHistoryResultList appo = - new AppoitmentAllHistoryResultList(); - appo.projectID = patientInfoAndMobileNumber.projectID; - openPayment(selectedPaymentMethod, authenticatedUser, - double.parse(advanceModel.amount), null); + void initState() { + // _payClient = Pay.withAssets([ + // 'applepay.json', + // ]); + super.initState(); + } + + void submit(MyBalanceViewModel model, code) { + final activationCode = code; + GifLoaderDialogUtils.showMyDialog(AppGlobal.context); + model.checkActivationCodeForAdvancePayment(activationCode: activationCode).then((value) { + GifLoaderDialogUtils.hideDialog(AppGlobal.context); + Navigator.pop(context, true); + AppoitmentAllHistoryResultList appo = new AppoitmentAllHistoryResultList(); + appo.projectID = widget.patientInfoAndMobileNumber!.projectID; + + if (widget.selectedPaymentMethod == "ApplePay") { + if (projectViewModel.havePrivilege(103)) { + startApplePay(); + } else { + openPayment(widget.selectedPaymentMethod!, widget.authenticatedUser!, double.parse(widget.advanceModel!.amount!), AppoitmentAllHistoryResultList()); } - }); + } else { + openPayment(widget.selectedPaymentMethod!, widget.authenticatedUser!, double.parse(widget.advanceModel!.amount!), AppoitmentAllHistoryResultList()); + } + + projectViewModel.analytics.advancePayments.payment_otp_confirmation(method: widget.selectedPaymentMethod!.toLowerCase(), type: 'wallet'); + // openPayment(widget.selectedPaymentMethod, widget.authenticatedUser, double.parse(widget.advanceModel.amount), null); + }); + } + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + void showSMSDialog(MyBalanceViewModel model) { + new SMSOTP( + context, + 1, + widget.patientInfoAndMobileNumber!.mobileNumber, + (value) { + submit(model, value); + }, + () => { + Navigator.pop(context), + }, + ).displayDialog(context); } + projectViewModel = Provider.of(context); return BaseView( builder: (_, model, w) => AppScaffold( isShowAppBar: true, appBarTitle: TranslationBase.of(context).advancePayment, + showNewAppBarTitle: true, + showNewAppBar: true, + backgroundColor: CustomColors.appBackgroudGreyColor, body: SingleChildScrollView( physics: ScrollPhysics(), child: Container( @@ -71,11 +125,14 @@ class ConfirmPaymentPage extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Texts( + Text( TranslationBase.of(context).confirmThePayment, textAlign: TextAlign.center, - fontWeight: FontWeight.w500, - fontSize: 24, + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + ), ), SizedBox( height: 12, @@ -86,13 +143,29 @@ class ConfirmPaymentPage extends StatelessWidget { Container( height: 100.0, padding: EdgeInsets.all(7.0), - width: MediaQuery.of(context).size.width * 0.45, - child: Image.asset(getImagePath(selectedPaymentMethod)), + width: MediaQuery.of(context).size.width * 0.30, + child: widget.selectedPaymentMethod == "ApplePay" + ? SvgPicture.asset( + getImagePath(widget.selectedPaymentMethod!), + ) + : Image.asset(getImagePath(widget.selectedPaymentMethod!)), ), - Texts( - '${advanceModel.amount} SAR', - fontSize: 26, - bold: true, + Row( + children: [ + widget.advanceModel!.hospitalsModel!.projectOutSA! ? Container() : projectViewModel.isArabic ? Container() : SvgPicture.asset("assets/images/new/Saudi_Riyal_Symbol.svg", width: 20, height: 20), + mWidth(6), + Text( + widget.advanceModel!.hospitalsModel!.projectOutSA! ? '${widget.advanceModel!.amount} ' + TranslationBase.of(context).aed : '${widget.advanceModel!.amount}', + // '${widget.advanceModel.amount} ' + TranslationBase.of(context).sar, + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.w900, + letterSpacing: -0.48, + ), + ), + mWidth(6), + widget.advanceModel!.hospitalsModel!.projectOutSA! ? Container() : projectViewModel.isArabic ? SvgPicture.asset("assets/images/new/Saudi_Riyal_Symbol.svg", width: 20, height: 20) : Container(), + ], ) ], ), @@ -106,7 +179,7 @@ class ConfirmPaymentPage extends StatelessWidget { margin: EdgeInsets.all(3), child: NewTextFields( hintText: TranslationBase.of(context).fileNumber, - initialValue: advanceModel.fileNumber, + initialValue: widget.advanceModel!.fileNumber!, isEnabled: false, ), ), @@ -116,7 +189,7 @@ class ConfirmPaymentPage extends StatelessWidget { margin: EdgeInsets.all(3), child: NewTextFields( hintText: TranslationBase.of(context).name, - initialValue: patientInfoAndMobileNumber.firstName, + initialValue: widget.patientInfoAndMobileNumber!.firstName!, isEnabled: false, ), ), @@ -128,7 +201,7 @@ class ConfirmPaymentPage extends StatelessWidget { ), NewTextFields( hintText: TranslationBase.of(context).mobileNumber, - initialValue: patientInfoAndMobileNumber.mobileNumber, + initialValue: widget.patientInfoAndMobileNumber!.mobileNumber!, isEnabled: false, ), SizedBox( @@ -136,11 +209,7 @@ class ConfirmPaymentPage extends StatelessWidget { ), NewTextFields( hintText: TranslationBase.of(context).depositorName, - initialValue: model.user.firstName + - " " + - model.user.middleName + - " " + - model.user.lastName, + initialValue: model.user!.firstName! + " " + model.user!.middleName! + " " + model.user!.lastName!, isEnabled: false, ), SizedBox( @@ -148,7 +217,7 @@ class ConfirmPaymentPage extends StatelessWidget { ), NewTextFields( hintText: TranslationBase.of(context).notes, - initialValue: advanceModel.note, + initialValue: widget.advanceModel!.note!, isEnabled: false, ), ], @@ -156,83 +225,224 @@ class ConfirmPaymentPage extends StatelessWidget { ), ), bottomSheet: Container( - height: MediaQuery.of(context).size.height * 0.13, - width: double.infinity, - padding: EdgeInsets.all(12), - child: SecondaryButton( - textColor: Colors.white, - color: Theme.of(context).primaryColor, - label: TranslationBase.of(context).confirm.toUpperCase(), - disabled: model.state == ViewState.Busy, - onTap: () { - GifLoaderDialogUtils.showMyDialog(context); - model - .sendActivationCodeForAdvancePayment( - patientID: int.parse(advanceModel.fileNumber), - projectID: advanceModel.hospitalsModel.iD) - .then((value) { - GifLoaderDialogUtils.hideDialog(context); - if (model.state != ViewState.ErrorLocal && - model.state != ViewState.Error) showSMSDialog(); - }); - }, + color: Colors.white, + child: Container( + // height: MediaQuery.of(context).size.width * 0.18, + width: double.infinity, + padding: EdgeInsets.all(20), + child: DefaultButton( + TranslationBase.of(context).confirm.toUpperCase(), + () async { + if (widget.advanceModel!.fileNumber == projectViewModel.user.patientID.toString()) { + if (widget.selectedPaymentMethod == "ApplePay") { + if (projectViewModel.havePrivilege(103)) { + startApplePay(); + } else { + openPayment(widget.selectedPaymentMethod!, widget.authenticatedUser!, double.parse(widget.advanceModel!.amount!), AppoitmentAllHistoryResultList()); + } + } else { + openPayment(widget.selectedPaymentMethod!, widget.authenticatedUser!, double.parse(widget.advanceModel!.amount!), AppoitmentAllHistoryResultList()); + } + } else { + GifLoaderDialogUtils.showMyDialog(context); + model.sendActivationCodeForAdvancePayment(patientID: int.parse(widget.advanceModel!.fileNumber!), projectID: widget.advanceModel!.hospitalsModel!.iD).then((value) { + GifLoaderDialogUtils.hideDialog(context); + if (model.state != ViewState.ErrorLocal && model.state != ViewState.Error) showSMSDialog(model); + }); + } + projectViewModel.analytics.advancePayments.payment_confirm(method: widget.selectedPaymentMethod!.toLowerCase(), type: 'wallet'); + + // startApplePay(); + // if() + // GifLoaderDialogUtils.showMyDialog(context); + // model.sendActivationCodeForAdvancePayment(patientID: int.parse(widget.advanceModel.fileNumber), projectID: widget.advanceModel.hospitalsModel.iD).then((value) { + // GifLoaderDialogUtils.hideDialog(context); + // if (model.state != ViewState.ErrorLocal && model.state != ViewState.Error) showSMSDialog(model); + // }); + }, + ), ), ), ), ); } + void startApplePay() async { + transID = Utils.getAdvancePaymentTransID(widget.advanceModel!.hospitalsModel!.iD!, int.parse(widget.advanceModel!.fileNumber!)); + print("TransactionID: $transID"); + GifLoaderDialogUtils.showMyDialog(context); + + LiveCareService service = new LiveCareService(); + ApplePayInsertRequest applePayInsertRequest = new ApplePayInsertRequest(); + + PayfortProjectDetailsRespModel? payfortProjectDetailsRespModel; + await context + .read() + .getProjectDetailsForPayfort(projectId: widget.advanceModel!.hospitalsModel!.iD, serviceId: ServiceTypeEnum.advancePayment.getIdFromServiceEnum()) + .then((value) { + payfortProjectDetailsRespModel = value!; + }); + + applePayInsertRequest.clientRequestID = transID; + applePayInsertRequest.clinicID = 0; + applePayInsertRequest.currency = projectViewModel.authenticatedUserObject.user.outSA == 1 ? "AED" : "SAR"; + // applePayInsertRequest.customerEmail = projectViewModel.authenticatedUserObject.user.emailAddress; + applePayInsertRequest.customerEmail = "CustID_${widget.advanceModel!.fileNumber}@HMG.com"; + applePayInsertRequest.customerID = widget.advanceModel!.fileNumber; + applePayInsertRequest.customerName = projectViewModel.authenticatedUserObject.user.firstName! + " " + projectViewModel.authenticatedUserObject.user.lastName!; + applePayInsertRequest.deviceToken = await AppSharedPreferences().getString(PUSH_TOKEN); + applePayInsertRequest.voipToken = await AppSharedPreferences().getString(ONESIGNAL_APNS_TOKEN); + applePayInsertRequest.doctorID = 0; + applePayInsertRequest.projectID = widget.advanceModel!.hospitalsModel!.iD.toString(); + applePayInsertRequest.serviceID = ServiceTypeEnum.advancePayment.getIdFromServiceEnum().toString(); + applePayInsertRequest.channelID = 3; + applePayInsertRequest.patientID = widget.advanceModel!.fileNumber; + applePayInsertRequest.patientTypeID = projectViewModel.authenticatedUserObject.user.patientType; + applePayInsertRequest.patientOutSA = projectViewModel.authenticatedUserObject.user.outSA; + applePayInsertRequest.appointmentDate = null; + applePayInsertRequest.appointmentNo = 0; + applePayInsertRequest.orderDescription = "Advance Payment"; + applePayInsertRequest.liveServiceID = "0"; + applePayInsertRequest.latitude = "0.0"; + applePayInsertRequest.longitude = "0.0"; + applePayInsertRequest.amount = widget.advanceModel!.amount.toString(); + applePayInsertRequest.isSchedule = "0"; + applePayInsertRequest.language = projectViewModel.isArabic ? 'ar' : 'en'; + applePayInsertRequest.languageID = projectViewModel.isArabic ? 1 : 2; + applePayInsertRequest.userName = int.parse(widget.advanceModel!.fileNumber!); + applePayInsertRequest.responseContinueURL = "http://hmg.com/Documents/success.html"; + applePayInsertRequest.backClickUrl = "http://hmg.com/Documents/success.html"; + applePayInsertRequest.paymentOption = "ApplePay"; + + applePayInsertRequest.isMobSDK = true; + applePayInsertRequest.merchantReference = transID; + applePayInsertRequest.merchantIdentifier = payfortProjectDetailsRespModel!.merchantIdentifier; + applePayInsertRequest.commandType = "PURCHASE"; + applePayInsertRequest.signature = payfortProjectDetailsRespModel!.signature; + applePayInsertRequest.accessCode = payfortProjectDetailsRespModel!.accessCode; + applePayInsertRequest.shaRequestPhrase = payfortProjectDetailsRespModel!.shaRequest; + applePayInsertRequest.shaResponsePhrase = payfortProjectDetailsRespModel!.shaResponse; + applePayInsertRequest.returnURL = ""; + + service.applePayInsertRequest(applePayInsertRequest, context).then((res) async { + if (res["MessageStatus"] == 1) { + await context.read().initiateApplePayWithPayfort( + customerName: projectViewModel.authenticatedUserObject.user.firstName! + " " + projectViewModel.authenticatedUserObject.user.lastName!, + // customerEmail: projectViewModel.authenticatedUserObject.user.emailAddress, + customerEmail: "CustID_${widget.advanceModel!.fileNumber!}@HMG.com", + orderDescription: "Advance Payment", + orderAmount: double.parse(widget.advanceModel!.amount!), + merchantReference: transID, + payfortProjectDetailsRespModel: payfortProjectDetailsRespModel, + currency: projectViewModel.authenticatedUserObject.user.outSA == 1 ? "AED" : "SAR", + onFailed: (failureResult) async { + GifLoaderDialogUtils.hideDialog(context); + log("failureResult: ${failureResult.message.toString()}"); + AppToast.showErrorToast(message: failureResult.message.toString()); + }, + onSuccess: (successResult) async { + log("Payfort: ${successResult.responseMessage}"); + await context.read().addPayfortApplePayResponse(num.parse(widget.advanceModel!.fileNumber!), result: successResult); + checkPaymentStatus(AppoitmentAllHistoryResultList()); + }, + projectId: widget.advanceModel!.hospitalsModel!.iD, + serviceTypeEnum: ServiceTypeEnum.advancePayment, + ); + } else { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: "An error occurred while processing your request"); + } + }).catchError((err) { + print(err); + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + }); + } + + String getApplePayPaymentType(dynamic paymentMethod) { + switch (paymentMethod) { + case 1: + return 'debit'; + break; + case 2: + return 'credit'; + break; + case 3: + return 'prepaid'; + break; + } + return 'debit'; + } + String getImagePath(String paymentMethod) { switch (paymentMethod) { case "MADA": - return 'assets/images/new-design/mada.png'; + return 'assets/images/new/payment/Mada.png'; break; case "SADAD": return 'assets/images/new-design/sadad.png'; break; case "VISA": - return 'assets/images/new-design/visa.png'; + return 'assets/images/new/payment/visa.png'; break; case "MASTERCARD": - return 'assets/images/new-design/mastercard.png'; + return 'assets/images/new/payment/Mastercard.png'; break; case "Installment": - return 'assets/images/new-design/installment.png'; + return 'assets/images/new/payment/installments.png'; + break; + case "ApplePay": + return 'assets/images/new/payment/Apple_Pay.svg'; + // return 'assets/images/new/payment/Apple_Pay.png'; + break; + case "TAMARA": + return 'assets/images/new/payment/tamara.png'; break; } return 'assets/images/new-design/mada.png'; } - openPayment(String paymentMethod, AuthenticatedUser authenticatedUser, - double amount, AppoitmentAllHistoryResultList appo) { - browser = new MyInAppBrowser( - onExitCallback: onBrowserExit, - appo: appo, - onLoadStartCallback: onBrowserLoadStart); + openPayment(String paymentMethod, AuthenticatedUser authenticatedUser, num amount, AppoitmentAllHistoryResultList appo) { + browser = new MyInAppBrowser(onExitCallback: onBrowserExit, appo: appo, onLoadStartCallback: onBrowserLoadStart); - transID = Utils.getAdvancePaymentTransID( - advanceModel.hospitalsModel.iD, int.parse(advanceModel.fileNumber)); + transID = Utils.getAdvancePaymentTransID(widget.advanceModel!.hospitalsModel!.iD, int.parse(widget.advanceModel!.fileNumber!)); browser.openPaymentBrowser( amount, "Advance Payment", transID, - advanceModel.hospitalsModel.iD.toString(), - advanceModel.email, + widget.advanceModel!.hospitalsModel!.iD.toString(), + widget.advanceModel!.email!, paymentMethod, - patientInfoAndMobileNumber.patientType, - advanceModel.patientName, - advanceModel.fileNumber, + widget.patientInfoAndMobileNumber!.patientType, + widget.advanceModel!.patientName!, + widget.advanceModel!.fileNumber!, authenticatedUser, browser, - false); + false, + "3", + "0", + context, + "", + "", + "", + "", + widget.installmentPlan); } onBrowserLoadStart(String url) { print("onBrowserLoadStart"); print(url); + if (widget.selectedPaymentMethod == "TAMARA") { + Uri uri = new Uri.dataFromString(url); + tamaraPaymentStatus = uri.queryParameters['paymentStatus']!; + tamaraOrderID = uri.queryParameters['orderId']!; + print(tamaraPaymentStatus); + print(tamaraOrderID); + } + MyInAppBrowser.successURLS.forEach((element) { if (url.contains(element)) { if (browser.isOpened()) browser.close(); @@ -251,22 +461,50 @@ class ConfirmPaymentPage extends StatelessWidget { } onBrowserExit(AppoitmentAllHistoryResultList appo, bool isPaymentMade) { - print("onBrowserExit Called!!!!"); - if (isPaymentMade) checkPaymentStatus(appo); + print("onBrowserExit Called"); + if (widget.selectedPaymentMethod == "TAMARA" && tamaraPaymentStatus != null && tamaraPaymentStatus == "approved") { + var res = { + "Amount": double.parse(widget.advanceModel!.amount!), + "ErrorMessage": null, + "Fort_id": tamaraOrderID, + "Merchant_Reference": "5058637919318707883366", + "PaymentMethod": "TAMARA", + "Response_Message": "Success" + }; + createAdvancePayment(res, appo); + } else { + checkPaymentStatus(appo); + } } checkPaymentStatus(AppoitmentAllHistoryResultList appo) { + String txn_ref; + String amount; + String payment_method; + final currency = projectViewModel.user!.outSA == 0 ? "sar" : 'aed'; GifLoaderDialogUtils.showMyDialog(AppGlobal.context); DoctorsListService service = new DoctorsListService(); - service.checkPaymentStatus(transID, AppGlobal.context).then((res) { - print("Printing Payment Status Reponse!!!!"); - print(res); + service.checkPaymentStatus(transID, false, AppGlobal.context).then((res) { String paymentInfo = res['Response_Message']; if (paymentInfo == 'Success') { + txn_ref = res['Merchant_Reference']; + amount = res['Amount'].toString(); + payment_method = res['PaymentMethod']; createAdvancePayment(res, appo); + projectViewModel.analytics.advancePayments.payment_success( + payment_type: 'wallet', payment_method: payment_method, txn_amount: "$amount", txn_currency: currency, txn_number: txn_ref, hospital: widget.advanceModel!.hospitalsModel!.name!); } else { GifLoaderDialogUtils.hideDialog(AppGlobal.context); AppToast.showErrorToast(message: res['Response_Message']); + amount = widget.advanceModel!.amount!; + payment_method = widget.selectedPaymentMethod!; + projectViewModel.analytics.advancePayments.payment_fail( + payment_type: 'wallet', + payment_method: payment_method, + txn_amount: "$amount", + txn_currency: currency, + hospital: widget.advanceModel!.hospitalsModel!.name!, + error_type: res['Response_Message']); } }).catchError((err) { GifLoaderDialogUtils.hideDialog(AppGlobal.context); @@ -278,20 +516,13 @@ class ConfirmPaymentPage extends StatelessWidget { createAdvancePayment(res, AppoitmentAllHistoryResultList appo) { DoctorsListService service = new DoctorsListService(); String paymentReference = res['Fort_id'].toString(); - service.HIS_createAdvancePayment( - appo, - advanceModel.hospitalsModel.iD.toString(), - res['Amount'], - res['Fort_id'], - res['PaymentMethod'], - patientInfoAndMobileNumber.patientType, - advanceModel.patientName, - advanceModel.fileNumber, - AppGlobal.context) + service.HIS_createAdvancePayment(appo, widget.advanceModel!.hospitalsModel!.iD.toString(), res['Amount'], res['Fort_id'], res['PaymentMethod'], widget.patientInfoAndMobileNumber!.patientType, + widget.advanceModel!.patientName!, widget.advanceModel!.fileNumber, AppGlobal.context) .then((res) { - print(res['OnlineCheckInAppointments'][0]['AdvanceNumber']); addAdvancedNumberRequest( - res['OnlineCheckInAppointments'][0]['AdvanceNumber'].toString(), + Utils.isVidaPlusProject(projectViewModel, widget.advanceModel!.hospitalsModel!.iD) + ? res['OnlineCheckInAppointments'][0]['AdvanceNumber_VP'].toString() + : res['OnlineCheckInAppointments'][0]['AdvanceNumber'].toString(), paymentReference, 0, appo); @@ -302,14 +533,9 @@ class ConfirmPaymentPage extends StatelessWidget { }); } - addAdvancedNumberRequest(String advanceNumber, String paymentReference, - dynamic appointmentID, AppoitmentAllHistoryResultList appo) { + addAdvancedNumberRequest(String advanceNumber, String paymentReference, dynamic appointmentID, AppoitmentAllHistoryResultList appo) { DoctorsListService service = new DoctorsListService(); - service - .addAdvancedNumberRequest( - advanceNumber, paymentReference, appointmentID, AppGlobal.context) - .then((res) { - print(res); + service.addAdvancedNumberRequest(advanceNumber, paymentReference, appointmentID, AppGlobal.context).then((res) { GifLoaderDialogUtils.hideDialog(AppGlobal.context); navigateToHome(AppGlobal.context); }).catchError((err) { diff --git a/lib/pages/medical/balance/dialogs/ConfirmSMSDialog.dart b/lib/pages/medical/balance/dialogs/ConfirmSMSDialog.dart index 380f250c..de22c7af 100644 --- a/lib/pages/medical/balance/dialogs/ConfirmSMSDialog.dart +++ b/lib/pages/medical/balance/dialogs/ConfirmSMSDialog.dart @@ -7,6 +7,7 @@ import 'package:diplomaticquarterapp/core/model/my_balance/AdvanceModel.dart'; import 'package:diplomaticquarterapp/core/model/my_balance/patient_info_and_mobile_number.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/my_balance_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; @@ -15,13 +16,13 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; class ConfirmSMSDialog extends StatefulWidget { - final String phoneNumber; - final AdvanceModel advanceModel; - final PatientInfoAndMobileNumber patientInfoAndMobileNumber; - final String selectedPaymentMethod; + final String? phoneNumber; + final AdvanceModel? advanceModel; + final PatientInfoAndMobileNumber? patientInfoAndMobileNumber; + final String? selectedPaymentMethod; const ConfirmSMSDialog( - {Key key, + {Key? key, this.phoneNumber, this.advanceModel, this.selectedPaymentMethod, @@ -49,7 +50,7 @@ class _ConfirmSMSDialogState extends State { String timerText = (TIMER_MIN - 1).toString() + ':59'; int min = TIMER_MIN - 1; int sec = 59; - Timer _timer; + late Timer _timer; resendCode() { min = TIMER_MIN - 1; @@ -74,10 +75,10 @@ class _ConfirmSMSDialogState extends State { }); } - FocusNode focusD1; - FocusNode focusD2; - FocusNode focusD3; - FocusNode focusD4; + late FocusNode focusD1; + late FocusNode focusD2; + late FocusNode focusD3; + late FocusNode focusD4; @override void initState() { @@ -157,7 +158,7 @@ class _ConfirmSMSDialogState extends State { Form( key: verifyAccountForm, child: Container( - width: SizeConfig.realScreenWidth * 0.90, + width: SizeConfig.realScreenWidth! * 0.90, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -172,7 +173,7 @@ class _ConfirmSMSDialogState extends State { child: TextFormField( textInputAction: TextInputAction.next, style: TextStyle( - fontSize: SizeConfig.textMultiplier * 3, + fontSize: SizeConfig.textMultiplier! * 3, ), focusNode: focusD1, //maxLength: 1, @@ -203,7 +204,7 @@ class _ConfirmSMSDialogState extends State { //maxLength: 1, textAlign: TextAlign.center, style: TextStyle( - fontSize: SizeConfig.textMultiplier * 3, + fontSize: SizeConfig.textMultiplier! * 3, ), keyboardType: TextInputType.number, decoration: buildInputDecoration(context), @@ -230,7 +231,7 @@ class _ConfirmSMSDialogState extends State { //maxLength: 1, textAlign: TextAlign.center, style: TextStyle( - fontSize: SizeConfig.textMultiplier * 3, + fontSize: SizeConfig.textMultiplier! * 3, ), keyboardType: TextInputType.number, decoration: buildInputDecoration(context), @@ -256,7 +257,7 @@ class _ConfirmSMSDialogState extends State { // maxLength: 1, textAlign: TextAlign.center, style: TextStyle( - fontSize: SizeConfig.textMultiplier * 3, + fontSize: SizeConfig.textMultiplier! * 3, ), keyboardType: TextInputType.number, decoration: buildInputDecoration(context), @@ -329,7 +330,7 @@ class _ConfirmSMSDialogState extends State { } void submit(MyBalanceViewModel model) { - if (verifyAccountForm.currentState.validate()) { + if (verifyAccountForm.currentState!.validate()) { final activationCode = digit1.text + digit2.text + digit3.text + digit4.text; GifLoaderDialogUtils.showMyDialog(AppGlobal.context); @@ -346,7 +347,7 @@ class _ConfirmSMSDialogState extends State { if (value.isEmpty) { return ''; } - return null; + return "null"; } InputDecoration buildInputDecoration(BuildContext context) { @@ -363,11 +364,11 @@ class _ConfirmSMSDialogState extends State { ), errorBorder: OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(5.0)), - borderSide: BorderSide(color: Theme.of(context).errorColor), + borderSide: BorderSide(color: CustomColors.accentColor), ), focusedErrorBorder: OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(5.0)), - borderSide: BorderSide(color: Theme.of(context).errorColor), + borderSide: BorderSide(color: CustomColors.accentColor), ), ); } diff --git a/lib/pages/medical/balance/dialogs/SelectBeneficiaryDialog.dart b/lib/pages/medical/balance/dialogs/SelectBeneficiaryDialog.dart deleted file mode 100644 index d7ce3fac..00000000 --- a/lib/pages/medical/balance/dialogs/SelectBeneficiaryDialog.dart +++ /dev/null @@ -1,177 +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'; - -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), - 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), - leading: Radio( - value: BeneficiaryType.MyFamilyFiles, - groupValue: beneficiaryType, - activeColor: Color(0xFF40ACC9), - 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), - leading: Radio( - value: BeneficiaryType.OtherAccount, - groupValue: beneficiaryType, - activeColor: Color(0xFF40ACC9), - 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: 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(beneficiaryType); - 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/medical/balance/dialogs/SelectCiteisDialog.dart b/lib/pages/medical/balance/dialogs/SelectCiteisDialog.dart index 19e4fea4..e7c766fd 100644 --- a/lib/pages/medical/balance/dialogs/SelectCiteisDialog.dart +++ b/lib/pages/medical/balance/dialogs/SelectCiteisDialog.dart @@ -7,13 +7,14 @@ 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; - CitiesModel selectedHospital; + final List? hospitals; + final Function(CitiesModel)? onValueSelected; + CitiesModel? selectedHospital; SelectCiteisDialog( - {Key key, this.hospitals, this.onValueSelected, this.selectedHospital}); + {Key? key, this.hospitals, this.onValueSelected, this.selectedHospital}); @override _SelectCiteisDialogState createState() => _SelectCiteisDialogState(); @@ -24,7 +25,7 @@ class _SelectCiteisDialogState extends State { void initState() { super.initState(); - widget.selectedHospital = widget.selectedHospital ?? widget.hospitals[0]; + widget.selectedHospital = widget.selectedHospital ?? widget.hospitals![0]; } @override @@ -37,7 +38,7 @@ class _SelectCiteisDialogState extends State { children: [ Divider(), ...List.generate( - widget.hospitals.length, + widget.hospitals!.length, (index) => Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -51,17 +52,17 @@ class _SelectCiteisDialogState extends State { child: InkWell( onTap: () { setState(() { - widget.selectedHospital = widget.hospitals[index]; + widget.selectedHospital = widget.hospitals![index]; }); }, child: ListTile( // title: Text(widget.hospitals[index].description + // ' ${widget.hospitals[index].distanceInKilometers} KM'), title: Text(projectProvider.isArabic - ? widget.hospitals[index].descriptionN - : widget.hospitals[index].description), + ? widget.hospitals![index].descriptionN! + : widget.hospitals![index].description!), leading: Radio( - value: widget.hospitals[index], + value: widget.hospitals![index], groupValue: widget.selectedHospital, activeColor: Colors.red[800], onChanged: (value) { @@ -115,7 +116,7 @@ class _SelectCiteisDialogState extends State { flex: 1, child: InkWell( onTap: () { - widget.onValueSelected(widget.selectedHospital); + widget.onValueSelected!(widget.selectedHospital!); Navigator.pop(context); }, child: Padding( diff --git a/lib/pages/medical/balance/dialogs/SelectHospitalDialog.dart b/lib/pages/medical/balance/dialogs/SelectHospitalDialog.dart deleted file mode 100644 index a9a4fea2..00000000 --- a/lib/pages/medical/balance/dialogs/SelectHospitalDialog.dart +++ /dev/null @@ -1,131 +0,0 @@ -import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_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'; - -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} KM'), - 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: 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.selectedHospital); - 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/medical/balance/dialogs/SelectPatientFamilyDialog.dart b/lib/pages/medical/balance/dialogs/SelectPatientFamilyDialog.dart deleted file mode 100644 index ab2b48d5..00000000 --- a/lib/pages/medical/balance/dialogs/SelectPatientFamilyDialog.dart +++ /dev/null @@ -1,130 +0,0 @@ -import 'package:diplomaticquarterapp/models/FamilyFiles/GetAllSharedRecordByStatusResponse.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'; - -import '../../../../Constants.dart'; - -class SelectPatientFamilyDialog extends StatefulWidget { - final List getAllSharedRecordsByStatusList; - final Function(GetAllSharedRecordsByStatusList) onValueSelected; - GetAllSharedRecordsByStatusList selectedPatientFamily; - - 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]; - } - - @override - Widget build(BuildContext context) { - return SimpleDialog( - children: [ - Column( - children: [ - Divider(), - ...List.generate( - widget.getAllSharedRecordsByStatusList.length, - (index) => Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 2, - ), - Row( - children: [ - Expanded( - flex: 1, - child: InkWell( - onTap: () { - setState(() { - widget.selectedPatientFamily = widget.getAllSharedRecordsByStatusList[index]; - }); - }, - child: ListTile( - title: Text(widget.getAllSharedRecordsByStatusList[index].patientName), - leading: Radio( - value: widget.getAllSharedRecordsByStatusList[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: 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.selectedPatientFamily); - 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/medical/balance/dialogs/SelectPatientInfoDialog.dart b/lib/pages/medical/balance/dialogs/SelectPatientInfoDialog.dart deleted file mode 100644 index 3cce8e61..00000000 --- a/lib/pages/medical/balance/dialogs/SelectPatientInfoDialog.dart +++ /dev/null @@ -1,132 +0,0 @@ -import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; -import 'package:diplomaticquarterapp/core/model/my_balance/patient_info.dart'; -import 'package:diplomaticquarterapp/models/FamilyFiles/GetAllSharedRecordByStatusResponse.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'; - -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), - 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: 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.selectedPatientInfo); - 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/medical/balance/my_balance_page.dart b/lib/pages/medical/balance/my_balance_page.dart index 7639bb2f..462c71c2 100644 --- a/lib/pages/medical/balance/my_balance_page.dart +++ b/lib/pages/medical/balance/my_balance_page.dart @@ -1,122 +1,231 @@ 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/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +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'; import 'package:flutter/material.dart'; -import 'package:hexcolor/hexcolor.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:provider/provider.dart'; import 'advance_payment_page.dart'; class MyBalancePage extends StatelessWidget { - List imagesInfo = List(); + List imagesInfo = []; + + late ProjectViewModel projectViewModel; @override Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + imagesInfo.add(ImagesInfo( - imageEn: - 'https://hmgwebservices.com/Images/MobileApp/images-info-home/my-balance/en/0.png', - imageAr: - 'https://hmgwebservices.com/Images/MobileApp/images-info-home/my-balance/ar/0.png')); + imageEn: 'https://hmgwebservices.com/Images/MobileApp/images-info-home/my-balance/en/0.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/images-info-home/my-balance/ar/0.png')); return BaseView( onModelReady: (model) => model.getPatientAdvanceBalanceAmount(), 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, - body: SingleChildScrollView( - child: Container( - margin: EdgeInsets.all(12), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts( - TranslationBase.of(context).balanceAmount, - color: Colors.black, - bold: true, - ), - 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: [ - Texts( - '${model.totalAdvanceBalanceAmount ?? 0} ' + - TranslationBase.of(context).sar, - color: Colors.white, - bold: true, + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: CustomColors.appBackgroudGreyColor, + 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), + ), ), - Texts( - TranslationBase.of(context).totalBalance, - color: Colors.white, + 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 + ), + ), + ], + ), + ), + 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: [ + Row( + children: [ + projectViewModel.user!.outSA == 1 + ? Container() + : projectViewModel.isArabic + ? Container() + : SvgPicture.asset( + "assets/images/new/Saudi_Riyal_Symbol.svg", + width: 22, + height: 22, + color: Colors.white, + ), + mWidth(6), + Text( + double.parse(model.totalAdvanceBalanceAmount?.toString() ?? "0").toStringAsFixed(2), + style: TextStyle( + fontSize: 24, + fontWeight: FontWeight.bold, + letterSpacing: -1.44, + height: 24 / 21, + color: Colors.white, + ), + ), + mWidth(6), + projectViewModel.user!.outSA == 1 + ? Container() + : projectViewModel.isArabic + ? SvgPicture.asset( + "assets/images/new/Saudi_Riyal_Symbol.svg", + width: 22, + height: 22, + color: Colors.white, + ) + : Container(), + ], + ), + Text( + projectViewModel.user!.outSA == 1 ? TranslationBase.of(context).aed : "", + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + letterSpacing: -0.96, + color: Colors.white, + ), + ), + ], + ), + ), + ], ), - ], - ), - ), - 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(7), ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Texts( - '${model.patientAdvanceBalanceAmountList[index].patientAdvanceBalanceAmount} ' + - TranslationBase.of(context).sar, - bold: true, - ), - Texts(model.patientAdvanceBalanceAmountList[index] - .projectDescription), - ], - ), - ), + 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), + ), + ), + ), + Row( + children: [ + projectViewModel.user!.outSA == 1 + ? Container() + : projectViewModel.isArabic + ? Container() + : SvgPicture.asset("assets/images/new/Saudi_Riyal_Symbol.svg", width: 16, height: 16), + mWidth(6), + Text( + amount.toStringAsFixed(2) + " " + (projectViewModel.user!.outSA == 1 ? TranslationBase.of(context).aed : ""), + style: TextStyle( + fontSize: 16, + letterSpacing: -0.64, + fontWeight: amount > 0 ? FontWeight.bold : FontWeight.w500, + color: Color(0xff2E303A), + ), + ), + mWidth(6), + projectViewModel.user!.outSA == 1 + ? Container() + : projectViewModel.isArabic + ? SvgPicture.asset("assets/images/new/Saudi_Riyal_Symbol.svg", width: 16, height: 16) + : Container(), + ], + ), + ], + ), + ); + }, + 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, - color: Colors.white, - width: double.infinity, - padding: EdgeInsets.all(12), - child: SecondaryButton( - // color: Colors.grey[900], - textColor: Colors.white, - label: TranslationBase.of(context).createAdvancedPayment, - onTap: () { - Navigator.push(context, FadePage(page: AdvancePaymentPage())); - }, - ), + DefaultButton( + TranslationBase.of(context).createAdvancedPayment, + () { + Navigator.push(context, FadePage(page: AdvancePaymentPage())); + projectViewModel.analytics.advancePayments.wallet_recharge(service_type: 'alhabib wallet'); + }, + ).insideContainer, + ], ), ), ); diff --git a/lib/pages/medical/balance/new_text_Field.dart b/lib/pages/medical/balance/new_text_Field.dart index f61c7267..fb9d8bed 100644 --- a/lib/pages/medical/balance/new_text_Field.dart +++ b/lib/pages/medical/balance/new_text_Field.dart @@ -1,12 +1,11 @@ -import 'package:eva_icons_flutter/eva_icons_flutter.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; class NumberTextInputFormatter extends TextInputFormatter { @override - TextEditingValue formatEditUpdate( - TextEditingValue oldValue, TextEditingValue newValue) { + TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) { final int newTextLength = newValue.text.length; int selectionIndex = newValue.selection.end; int usedSubstringIndex = 0; @@ -28,8 +27,7 @@ class NumberTextInputFormatter extends TextInputFormatter { if (newValue.selection.end >= 10) selectionIndex++; } // Dump the rest. - if (newTextLength >= usedSubstringIndex) - newText.write(newValue.text.substring(usedSubstringIndex)); + if (newTextLength >= usedSubstringIndex) newText.write(newValue.text.substring(usedSubstringIndex)); return TextEditingValue( text: newText.toString(), selection: TextSelection.collapsed(offset: selectionIndex), @@ -41,7 +39,7 @@ final _mobileFormatter = NumberTextInputFormatter(); class NewTextFields extends StatefulWidget { NewTextFields( - {Key key, + {Key? key, this.type, this.hintText, this.suffixIcon, @@ -65,53 +63,54 @@ class NewTextFields extends StatefulWidget { this.borderOnlyError = false, this.onSaved, this.onSuffixTap, - this.readOnly: false, + this.readOnly = false, this.maxLength, this.prefixIcon, this.bare = false, this.onTap, - this.fontSize = 16.0, - this.fontWeight = FontWeight.w700, - this.autoValidate = false, + this.fontSize = 14.0, + this.fontWeight = FontWeight.w600, this.hintColor, - this.isEnabled = true}) + this.isEnabled = true, + this.counterText = ""}) : super(key: key); - final String hintText; + final String? hintText; // final String initialValue; - final String type; - final bool autoFocus; - final IconData suffixIcon; - final Color suffixIconColor; - final Icon prefixIcon; - final VoidCallback onTap; - final TextEditingController controller; - final TextInputType keyboardType; - final FormFieldValidator validator; - final Function onSaved; - final Function onSuffixTap; - final Function onChanged; - final Function onSubmit; + final String? type; + final bool? autoFocus; + final IconData? suffixIcon; + final Color? suffixIconColor; + final Icon? prefixIcon; + final VoidCallback? onTap; + final TextEditingController? controller; + final TextInputType? keyboardType; + final FormFieldValidator? validator; + final Function(String?)? onSaved; + final Function? onSuffixTap; + final Function(String)? onChanged; + final Function(String)? onSubmit; final bool readOnly; - final int maxLength; - final int minLines; - final int maxLines; + final int? maxLength; + final int? minLines; + final int? maxLines; final bool maxLengthEnforced; final bool bare; final bool isEnabled; - final TextInputAction inputAction; + final TextInputAction? inputAction; final double fontSize; final FontWeight fontWeight; final bool keepPadding; final TextCapitalization textCapitalization; - final List inputFormatters; - final bool autoValidate; - final EdgeInsets padding; + final List? inputFormatters; + final EdgeInsets? padding; final bool focus; final bool borderOnlyError; - final Color hintColor; - final String initialValue; + final Color? hintColor; + final String? initialValue; + final String counterText; + @override _NewTextFieldsState createState() => _NewTextFieldsState(); } @@ -156,9 +155,7 @@ class _NewTextFieldsState extends State { Widget build(BuildContext context) { return AnimatedContainer( duration: Duration(milliseconds: 300), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - color: Colors.white), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), color: Colors.white), child: Container( margin: EdgeInsets.only(top: 8), child: TextFormField( @@ -166,7 +163,6 @@ class _NewTextFieldsState extends State { initialValue: widget.initialValue, keyboardAppearance: Theme.of(context).brightness, scrollPhysics: BouncingScrollPhysics(), - autovalidate: widget.autoValidate, textCapitalization: widget.textCapitalization, onFieldSubmitted: widget.inputAction == TextInputAction.next ? (widget.onSubmit != null @@ -178,7 +174,7 @@ class _NewTextFieldsState extends State { textInputAction: widget.inputAction, minLines: widget.minLines ?? 1, maxLines: widget.maxLines ?? 1, - maxLengthEnforced: widget.maxLengthEnforced, + // maxLengthEnforced: widget.maxLengthEnforced, onChanged: widget.onChanged, focusNode: _focusNode, maxLength: widget.maxLength ?? null, @@ -189,34 +185,22 @@ class _NewTextFieldsState extends State { autofocus: widget.autoFocus ?? false, validator: widget.validator, onSaved: widget.onSaved, - style: Theme.of(context).textTheme.body2.copyWith( - fontSize: widget.fontSize, fontWeight: widget.fontWeight), + // style: Theme.of(context).textTheme.bodyText2!.copyWith(fontSize: widget.fontSize, fontWeight: widget.fontWeight), + style: TextStyle(color: Colors.black, letterSpacing: 0.6, fontSize: widget.fontSize, fontWeight: widget.fontWeight), inputFormatters: widget.keyboardType == TextInputType.phone ? [ - WhitelistingTextInputFormatter.digitsOnly, + FilteringTextInputFormatter.digitsOnly, _mobileFormatter, ] : widget.inputFormatters, decoration: InputDecoration( labelText: widget.hintText, - labelStyle: - TextStyle(color: Theme.of(context).textTheme.bodyText1.color), - errorBorder: OutlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).errorColor.withOpacity(0.5), - width: 1.0), - borderRadius: BorderRadius.circular(12.0)), - focusedErrorBorder: OutlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).errorColor.withOpacity(0.5), - width: 1.0), - borderRadius: BorderRadius.circular(8.0)), - focusedBorder: OutlineInputBorder( - borderSide: BorderSide(color: Colors.white, width: 1.0), - borderRadius: BorderRadius.circular(12)), - disabledBorder: OutlineInputBorder( - borderSide: BorderSide(color: Colors.white, width: 1.0), - borderRadius: BorderRadius.circular(12)), + counterText: widget.counterText, + labelStyle: TextStyle(color: Colors.black), + errorBorder: OutlineInputBorder(borderSide: BorderSide(color: CustomColors.accentColor.withOpacity(0.5), width: 1.0), borderRadius: BorderRadius.circular(12.0)), + focusedErrorBorder: OutlineInputBorder(borderSide: BorderSide(color: CustomColors.accentColor.withOpacity(0.5), width: 1.0), borderRadius: BorderRadius.circular(8.0)), + focusedBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.white, width: 1.0), borderRadius: BorderRadius.circular(12)), + disabledBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.white, width: 1.0), borderRadius: BorderRadius.circular(12)), enabledBorder: OutlineInputBorder( borderSide: BorderSide(color: Colors.white, width: 1.0), borderRadius: BorderRadius.circular(12), diff --git a/lib/pages/medical/dental_instructions_page.dart b/lib/pages/medical/dental_instructions_page.dart new file mode 100644 index 00000000..133165d7 --- /dev/null +++ b/lib/pages/medical/dental_instructions_page.dart @@ -0,0 +1,85 @@ +import 'package:diplomaticquarterapp/models/get_dental_instructions_response_model.dart'; +import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; + +class DentalInstructionsPage extends StatefulWidget { + const DentalInstructionsPage(); + + @override + State createState() => _DentalInstructionsPageState(); +} + +class _DentalInstructionsPageState extends State { + GetDentalInstructionsResponseModel? getDentalInstructionsResponseModel; + + @override + void initState() { + WidgetsBinding.instance.addPostFrameCallback((_) { + getDentalInstructions(); + }); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return AppScaffold( + appBarTitle: TranslationBase.of(context).myinstructions, + isShowAppBar: true, + showNewAppBar: true, + showNewAppBarTitle: true, + isShowDecPage: false, + backgroundColor: CustomColors.appBackgroudGrey2Color, + body: Container( + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + children: [ + getDentalInstructionsResponseModel != null && getDentalInstructionsResponseModel!.data!.isNotEmpty + ? ListView.builder( + itemCount: getDentalInstructionsResponseModel!.data!.length, + shrinkWrap: true, + itemBuilder: (context, index) { + return Padding( + padding: EdgeInsets.only(top: 16.0, bottom: 16.0), + child: Text( + getDentalInstructionsResponseModel!.data![index].smsContent!, + style: TextStyle( + fontSize: 14.0, + letterSpacing: -0.56, + color: Color(0xff575757), + ), + ), + ); + }, + ) + : Center(child: getNoDataWidget(context)), + ], + ), + ), + ), + ), + ); + } + + getDentalInstructions() { + GifLoaderDialogUtils.showMyDialog(context); + ClinicListService service = new ClinicListService(); + service.getDentalInstructions().then((res) { + print(res["ProcedureNotificationResponse"]); + getDentalInstructionsResponseModel = GetDentalInstructionsResponseModel.fromJson(res["ProcedureNotificationResponse"]); + GifLoaderDialogUtils.hideDialog(context); + setState(() {}); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + AppToast.showErrorToast(message: err.toString()); + }); + } +} diff --git a/lib/pages/medical/doctor/doctor_home_page.dart b/lib/pages/medical/doctor/doctor_home_page.dart index c8fad3ce..c75d9582 100644 --- a/lib/pages/medical/doctor/doctor_home_page.dart +++ b/lib/pages/medical/doctor/doctor_home_page.dart @@ -4,23 +4,21 @@ import 'package:diplomaticquarterapp/core/viewModels/medical/my_doctor_view_mode import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; import 'package:diplomaticquarterapp/pages/BookAppointment/widgets/DoctorView.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/widgets/data_display/medical/doctor_card.dart'; +import 'package:diplomaticquarterapp/widgets/new_design/my_tab_view.dart'; import 'package:diplomaticquarterapp/widgets/others/app_expandable_notifier.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 'doctor_profile_page.dart'; - class DoctorHomePage extends StatelessWidget { - List imagesInfo = List(); + List imagesInfo =[]; @override Widget build(BuildContext context) { - imagesInfo.add(ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-doctor/en/0.png',imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-doctor/ar/0.png')); - imagesInfo.add(ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-doctor/en/1.png',imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-doctor/ar/1.png')); + imagesInfo + .add(ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-doctor/en/0.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-doctor/ar/0.png')); + imagesInfo + .add(ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-doctor/en/1.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-doctor/ar/1.png')); return BaseView( onModelReady: (model) => model.getMyDoctor(), builder: (context, MyDoctorViewModel model, widget) => AppScaffold( @@ -29,86 +27,71 @@ class DoctorHomePage extends StatelessWidget { appBarTitle: TranslationBase.of(context).myDoctor, description: TranslationBase.of(context).infoMyDoctor, infoList: TranslationBase.of(context).infoMyDoctorPoints, + showNewAppBar: true, + showNewAppBarTitle: true, imagesInfo: imagesInfo, - body: SingleChildScrollView( - physics: BouncingScrollPhysics(), - child: FractionallySizedBox( - widthFactor: 1.0, - child: Center( - child: Column( - children: [ - Row( - children: [ - Expanded( - flex: 1, - child: InkWell( - onTap: () => model.setFilterType(FilterType.Clinic), - child: ListTile( - title: Text(TranslationBase.of(context).clinic), - leading: Radio( - value: FilterType.Clinic, - groupValue: model.filterType, - onChanged: (FilterType value) { - model.setFilterType(value); - }, - ), - ), - ), - ), - Expanded( - flex: 1, - child: InkWell( - onTap: () => model.setFilterType(FilterType.Hospital), - child: ListTile( - title: Text(TranslationBase.of(context).hospital), - leading: Radio( - value: FilterType.Hospital, - groupValue: model.filterType, - onChanged: (FilterType value) => - model.setFilterType(value), - ), - ), - ), - ) - ], - ), - ...List.generate( - model.patientDoctorAppointmentList.length, - (index) => AppExpandableNotifier( - title: model - .patientDoctorAppointmentList[index].filterName, - bodyWidget: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: model.patientDoctorAppointmentList[index] - .patientDoctorAppointmentList - .map((doctor) { - DoctorList doctorList = DoctorList( - projectID: doctor.projectID, - setupID: doctor.setupID, - clinicID: doctor.clinicID, - projectName: doctor.projectName, - clinicName: doctor.clinicName, - actualDoctorRate: doctor.actualDoctorRate, - doctorID: doctor.doctorID, - doctorRate: doctor.doctorRate, - gender: doctor.gender, - doctorTitle: doctor.doctorTitle, - name: doctor.name, - doctorImageURL: doctor.doctorImageURL, - nationalityFlagURL: doctor.nationalityFlagURL); - return DoctorView( - doctor: doctorList, - isLiveCareAppointment: false, - ); - - }).toList(), - )), - ) - ], + backgroundColor: Color(0xffF8F8F8), + body: Column( + children: [ + Row( + children: [ + MyTabView(TranslationBase.of(context).byClinic, FilterType.Clinic, model.filterType, () { + model.setFilterType(FilterType.Clinic); + }), + MyTabView(TranslationBase.of(context).byHospital, FilterType.Hospital, model.filterType, () { + model.setFilterType(FilterType.Hospital); + }), + ], + ), + Expanded( + child: FractionallySizedBox( + widthFactor: 1.0, + child: ListView.separated( + physics: BouncingScrollPhysics(), + separatorBuilder: (context, index) { + return Container( + height: 12, + margin: EdgeInsets.only(left: 21, right: 21), + // color: Color(0xffD9D9D9), + ); + }, + itemBuilder: (context, index) { + return AppExpandableNotifier( + title: model.patientDoctorAppointmentList[index].filterName, + bodyWidget: ListView.separated( + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + padding: EdgeInsets.only(bottom: 14, top: 14, left: 21, right: 21), + itemBuilder: (context, _index) { + DoctorList _doctorList = model.patientDoctorAppointmentList[index].patientDoctorAppointmentList![_index]; + DoctorList doctorList = DoctorList( + projectID: _doctorList.projectID, + setupID: _doctorList.setupID, + clinicID: _doctorList.clinicID, + projectName: _doctorList.projectName, + clinicName: _doctorList.clinicName, + actualDoctorRate: _doctorList.actualDoctorRate, + doctorID: _doctorList.doctorID, + date: _doctorList.appointmentDate, + doctorRate: _doctorList.doctorRate, + gender: _doctorList.gender, + doctorTitle: _doctorList.doctorTitle, + name: _doctorList.name, + doctorImageURL: _doctorList.doctorImageURL, + nationalityFlagURL: _doctorList.nationalityFlagURL); + return DoctorView( + doctor: doctorList, + isLiveCareAppointment: _doctorList.isLiveCareClinic!, + ); + }, + separatorBuilder: (context, index) => SizedBox(height: 14), + itemCount: model.patientDoctorAppointmentList[index].patientDoctorAppointmentList!.length), + ); + }, + itemCount: model.patientDoctorAppointmentList.length), ), ), - ), + ], ), ), ); diff --git a/lib/pages/medical/doctor/doctor_information_page.dart b/lib/pages/medical/doctor/doctor_information_page.dart index 7634cde2..262bd87c 100644 --- a/lib/pages/medical/doctor/doctor_information_page.dart +++ b/lib/pages/medical/doctor/doctor_information_page.dart @@ -6,7 +6,7 @@ import 'package:flutter/material.dart'; class DoctorInformation extends StatefulWidget { final DoctorProfile doctorProfile; - const DoctorInformation({Key key, this.doctorProfile}) : super(key: key); + const DoctorInformation({Key? key, required this.doctorProfile}) : super(key: key); @override _DoctorInformationState createState() => _DoctorInformationState(); @@ -58,7 +58,7 @@ class _DoctorInformationState extends State { decoration: BoxDecoration(shape: BoxShape.circle, boxShadow: [ BoxShadow( - color: Colors.red[700], + color: Colors.red[700]!, blurRadius: 1.0, spreadRadius: 0.0, ) @@ -161,7 +161,7 @@ class _DoctorInformationState extends State { decoration: BoxDecoration(shape: BoxShape.circle, boxShadow: [ BoxShadow( - color: Colors.red[700], + color: Colors.red[700]!, blurRadius: 1.0, spreadRadius: 0.0, ) diff --git a/lib/pages/medical/doctor/doctor_profile_page.dart b/lib/pages/medical/doctor/doctor_profile_page.dart index 7588205c..5f9436c9 100644 --- a/lib/pages/medical/doctor/doctor_profile_page.dart +++ b/lib/pages/medical/doctor/doctor_profile_page.dart @@ -1,20 +1,14 @@ import 'package:diplomaticquarterapp/core/model/doctor/patient_doctor_appointment.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/my_doctor_view_model.dart'; -import 'package:diplomaticquarterapp/pages/BookAppointment/components/DocAvailableAppointments.dart'; import 'package:diplomaticquarterapp/pages/BookAppointment/widgets/DoctorView.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; -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:rating_bar/rating_bar.dart'; - -import 'doctor_information_page.dart'; class DoctorProfilePage extends StatefulWidget { final PatientDoctorAppointment patientDoctorAppointment; - DoctorProfilePage({this.patientDoctorAppointment}); + DoctorProfilePage({required this.patientDoctorAppointment}); @override _DoctorProfilePageState createState() => @@ -23,8 +17,8 @@ class DoctorProfilePage extends StatefulWidget { class _DoctorProfilePageState extends State with TickerProviderStateMixin { - TabController _tabController; - final PatientDoctorAppointment patientDoctorAppointment; + late TabController _tabController; + late PatientDoctorAppointment patientDoctorAppointment; _DoctorProfilePageState(this.patientDoctorAppointment); @@ -161,6 +155,7 @@ class _DoctorProfilePageState extends State height: MediaQuery.of(context).size.height * 0.8, child: TabBarView( physics: BouncingScrollPhysics(), + children: [ DoctorInformation( doctorProfile: model.doctorProfile, diff --git a/lib/pages/medical/eye/ClassesPage.dart b/lib/pages/medical/eye/ClassesPage.dart index 21a07d23..f4a87cb9 100644 --- a/lib/pages/medical/eye/ClassesPage.dart +++ b/lib/pages/medical/eye/ClassesPage.dart @@ -1,137 +1,112 @@ import 'package:diplomaticquarterapp/core/model/eye/AppoimentAllHistoryResult.dart'; -import 'package:diplomaticquarterapp/core/viewModels/medical/EyeViewModel.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'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/confirm_send_email_dialog.dart'; -import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; class ClassesPage extends StatelessWidget { - final ListHISGetGlassPerscription glassPerscription; - final int appointmentNo; - final String projectName; - final int projectID; + final ListHISGetGlassPerscription? glassPerscription; + final int? appointmentNo; + final String? projectName; + final int? projectID; - const ClassesPage( - {Key key, - this.glassPerscription, - this.appointmentNo, - this.projectName, - this.projectID}) - : super(key: key); + const ClassesPage({Key? key, this.glassPerscription, this.appointmentNo, this.projectName, this.projectID}) : super(key: key); @override Widget build(BuildContext context) { - return BaseView( - builder: (_, model, w) => AppScaffold( - body: SingleChildScrollView( - child: Container( - margin: EdgeInsets.only(top: 70, left: 15, right: 15, bottom: 15), - child: Column( - children: [ - Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.all(Radius.circular(8)), - color: Colors.white), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.all(8.0), - child: Texts( - TranslationBase.of(context).rightEye, - fontSize: 23, - bold: true, + return SingleChildScrollView( + child: Container( + margin: EdgeInsets.only(top: 20, left: 20, right: 20, bottom: 20), + child: Column( + children: [ + Container( + decoration: cardRadius(12), + child: Container( + + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + TranslationBase.of(context).rightEye, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.64, ), ), - getRow(TranslationBase.of(context).sphere, - '${glassPerscription.rightEyeSpherical}', '-'), - getRow(TranslationBase.of(context).cylinder, - '${glassPerscription.rightEyeCylinder}', '-'), - getRow(TranslationBase.of(context).axis, - '${glassPerscription.rightEyeAxis}', '-'), - getRow(TranslationBase.of(context).prism, - '${glassPerscription.rightEyePrism}', '-'), - getRow(TranslationBase.of(context).va, - '${glassPerscription.rightEyeVA}', '-'), - ], - ), - ), - SizedBox( - height: 17, + ), + getRow(TranslationBase.of(context).sphere, '${glassPerscription?.rightEyeSpherical}', '-'), + getRow(TranslationBase.of(context).cylinder, '${glassPerscription?.rightEyeCylinder}', '-'), + getRow(TranslationBase.of(context).axis, '${glassPerscription?.rightEyeAxis}', '-'), + getRow(TranslationBase.of(context).prism, '${glassPerscription?.rightEyePrism}', '-'), + getRow(TranslationBase.of(context).va, '${glassPerscription?.rightEyeVA}', '-',isLast:true), + ], ), - Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.all(Radius.circular(8)), - color: Colors.white), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.all(8.0), - child: Texts( - TranslationBase.of(context).leftEye, - fontSize: 23, - bold: true, - ), + ), + ), + SizedBox( + height: 12, + ), + Container( + decoration: cardRadius(12), + child: Container( child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + TranslationBase.of(context).leftEye, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.64, ), - getRow(TranslationBase.of(context).sphere, - '${glassPerscription.leftEyeSpherical}', '-'), - getRow(TranslationBase.of(context).cylinder, - '${glassPerscription.leftEyeCylinder}', '-'), - getRow(TranslationBase.of(context).axis, - '${glassPerscription.leftEyeAxis}', '-'), - getRow(TranslationBase.of(context).prism, - '${glassPerscription.leftEyePrism}', '-'), - getRow(TranslationBase.of(context).va, - '${glassPerscription.leftEyeVA}', '-'), - ], - ), - ), - SizedBox( - height: 17, - ), - Container( - width: double.infinity, - child: SecondaryButton( - label: TranslationBase.of(context).sendEmail, - onTap: () { - showConfirmMessage(context, () async { - GifLoaderDialogUtils.showMyDialog(context); - await model.sendGlassesPrescriptionEmail( - appointmentNo: appointmentNo, - projectName: projectName, - projectID: projectID); - GifLoaderDialogUtils.hideDialog(context); - }, model.user.emailAddress); - }, - textColor: Colors.white, - color: Colors.red[700], - icon: Icon( - Icons.email, - color: Colors.white, ), ), - ) - ], + getRow(TranslationBase.of(context).sphere, '${glassPerscription?.leftEyeSpherical}', '-'), + getRow(TranslationBase.of(context).cylinder, '${glassPerscription?.leftEyeCylinder}', '-'), + getRow(TranslationBase.of(context).axis, '${glassPerscription?.leftEyeAxis}', '-'), + getRow(TranslationBase.of(context).prism, '${glassPerscription?.leftEyePrism}', '-'), + getRow(TranslationBase.of(context).va, '${glassPerscription?.leftEyeVA}', '-',isLast:true), + ], + ), + ), ), - ), + SizedBox( + height: 17, + ), + // Container( + // width: double.infinity, + // child: SecondaryButton( + // label: TranslationBase.of(context).sendEmail, + // onTap: () { + // showConfirmMessage(context, () async { + // GifLoaderDialogUtils.showMyDialog(context); + // await model.sendGlassesPrescriptionEmail(appointmentNo: appointmentNo, projectName: projectName, projectID: projectID); + // GifLoaderDialogUtils.hideDialog(context); + // }, model.user.emailAddress); + // }, + // textColor: Colors.white, + // color: Colors.red[700], + // icon: Icon( + // Icons.email, + // color: Colors.white, + // ), + // ), + // ) + ], ), ), ); } - void showConfirmMessage( - BuildContext context, GestureTapCallback onTap, String email) { + void showConfirmMessage(BuildContext context, GestureTapCallback onTap, String email) { showDialog( context: context, - child: ConfirmSendEmailDialog( + builder: (cxt) => ConfirmSendEmailDialog( email: email, onTapSendEmail: () { onTap(); @@ -140,31 +115,40 @@ class ClassesPage extends StatelessWidget { ); } - Widget getRow(String title, String val1, String val2) => Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded(flex: 4, child: Texts(title)), - Expanded( - flex: 2, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - Texts(val1 == 'null' ? '-' : val1), - Texts(val2 != 'null' ? '-' : val2), - ], - ), - ) - ], - ), - Divider() - ], + Widget getRow(String title, String val1, String val2,{bool isLast=false}) => Padding( + padding: const EdgeInsets.only(left: 8,right: 8), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded(flex: 4, child: Text(title,style: TextStyle(fontSize: 11, fontWeight: FontWeight.w600, letterSpacing: -0.4))), + Expanded( + flex: 2, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Text( + val1 == 'null' ? '-' : val1, + style: TextStyle(fontSize: 11, fontWeight: FontWeight.w600, letterSpacing: -0.4), + ), + Text( + val2 != 'null' ? '-' : val2, + style: TextStyle(fontSize: 11, fontWeight: FontWeight.w600, letterSpacing: -0.4), + ), + ], + ), + ) + ], + ), ), - ); + isLast?Container(height: 4,): Divider() + ], + ), + ); } diff --git a/lib/pages/medical/eye/ContactLensPage.dart b/lib/pages/medical/eye/ContactLensPage.dart index b70b9c09..b459df15 100644 --- a/lib/pages/medical/eye/ContactLensPage.dart +++ b/lib/pages/medical/eye/ContactLensPage.dart @@ -2,10 +2,8 @@ import 'package:diplomaticquarterapp/core/model/eye/AppoimentAllHistoryResult.da import 'package:diplomaticquarterapp/core/viewModels/medical/EyeViewModel.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.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'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/confirm_send_email_dialog.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; @@ -13,125 +11,110 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; class ContactLensPage extends StatelessWidget { - final ListHISGetContactLensPerscription listHISGetContactLensPerscription; - final int appointmentNo; - final String projectName; - final int projectID; + final ListHISGetContactLensPerscription? listHISGetContactLensPerscription; + final int? appointmentNo; + final String? projectName; + final int? projectID; - const ContactLensPage( - {Key key, - this.listHISGetContactLensPerscription, - this.appointmentNo, - this.projectName, - this.projectID}) - : super(key: key); + const ContactLensPage({Key? key, this.listHISGetContactLensPerscription, this.appointmentNo, this.projectName, this.projectID}) : super(key: key); @override Widget build(BuildContext context) { ProjectViewModel projectViewModel = Provider.of(context); return BaseView( - builder: (_,model,w)=> - AppScaffold( + builder: (_, model, w) => AppScaffold( body: SingleChildScrollView( child: Container( - margin: EdgeInsets.only(top: 70, left: 15, right: 15, bottom: 15), + margin: EdgeInsets.only(top: 20, left: 20, right: 20, bottom: 20), child: Column( children: [ Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.all(Radius.circular(8)), - color: Colors.white), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.all(8.0), - child: Texts( - TranslationBase.of(context).rightEye, - fontSize: 23, - bold: true, + decoration: cardRadius(12), + child: Container( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + TranslationBase.of(context).rightEye, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.64, + ), + ), ), - ), - getRow(TranslationBase.of(context).brand, - '${listHISGetContactLensPerscription.brand}'), - getRow('B.C', - '${listHISGetContactLensPerscription.baseCurve}'), - getRow(TranslationBase.of(context).power, - '${listHISGetContactLensPerscription.power}'), - getRow(TranslationBase.of(context).diameter, - '${listHISGetContactLensPerscription.diameter}'), - getRow('OZ', '${listHISGetContactLensPerscription.oZ}'), - getRow('CT', '${listHISGetContactLensPerscription.cT}'), - getRow( - 'Blend', '${listHISGetContactLensPerscription.blend}'), - getRow(TranslationBase.of(context).reminder, - '${listHISGetContactLensPerscription.remarks}'), - ], + getRow(TranslationBase.of(context).brand, '${listHISGetContactLensPerscription!.brand}'), + getRow('B.C', '${listHISGetContactLensPerscription!.baseCurve}'), + getRow(TranslationBase.of(context).power, '${listHISGetContactLensPerscription!.power}'), + getRow(TranslationBase.of(context).diameter, '${listHISGetContactLensPerscription!.diameter}'), + getRow('OZ', '${listHISGetContactLensPerscription!.oZ}'), + getRow('CT', '${listHISGetContactLensPerscription!.cT}'), + getRow('Blend', '${listHISGetContactLensPerscription!.blend}'), + getRow(TranslationBase.of(context).remarks, '${listHISGetContactLensPerscription!.remarks}', isLast: true), + ], + ), ), ), SizedBox( - height: 17, + height: 12, ), Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.all(Radius.circular(8)), - color: Colors.white), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.all(8.0), - child: Texts( - TranslationBase.of(context).leftEye, - fontSize: 23, - bold: true, + decoration: cardRadius(12), + child: Container( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + TranslationBase.of(context).leftEye, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.64, + ), + ), ), - ), - getRow(TranslationBase.of(context).brand, - '${listHISGetContactLensPerscription.brand}'), - getRow('B.C', - '${listHISGetContactLensPerscription.baseCurve}'), - getRow(TranslationBase.of(context).power, - '${listHISGetContactLensPerscription.power}'), - getRow(TranslationBase.of(context).diameter, - '${listHISGetContactLensPerscription.diameter}'), - getRow('OZ', '${listHISGetContactLensPerscription.oZ}'), - getRow('CT', '${listHISGetContactLensPerscription.cT}'), - getRow( - 'Blend', '${listHISGetContactLensPerscription.blend}'), - getRow(TranslationBase.of(context).reminder, - '${listHISGetContactLensPerscription.remarks}'), - ], + getRow(TranslationBase.of(context).brand, '${listHISGetContactLensPerscription!.brand}'), + getRow('B.C', '${listHISGetContactLensPerscription!.baseCurve ?? "-"}'), + getRow(TranslationBase.of(context).power, '${listHISGetContactLensPerscription!.power}'), + getRow(TranslationBase.of(context).diameter, '${listHISGetContactLensPerscription!.diameter}'), + getRow('OZ', '${listHISGetContactLensPerscription!.oZ}'), + getRow('CT', '${listHISGetContactLensPerscription!.cT}'), + getRow('Blend', '${listHISGetContactLensPerscription!.blend}'), + getRow(TranslationBase.of(context).remarks, '${listHISGetContactLensPerscription!.remarks}', isLast: true), + ], + ), ), ), SizedBox( height: 17, ), - if (projectViewModel.havePrivilege(15)) - Container( - width: double.infinity, - child: SecondaryButton( - label: TranslationBase.of(context).sendEmail, - textColor: Colors.white, - color: Colors.red[700], - onTap: (){ - showConfirmMessage(context, () async { - GifLoaderDialogUtils.showMyDialog(context); - await model.sendContactLensPrescriptionEmail( - appointmentNo: appointmentNo, - projectName: projectName, - projectID: projectID); - GifLoaderDialogUtils.hideDialog(context); - }, model.user.emailAddress); - }, - icon: Icon( - Icons.email, - color: Colors.white, - ), - ), - ) + // if (projectViewModel.havePrivilege(15)) + // Container( + // width: double.infinity, + // child: SecondaryButton( + // label: TranslationBase.of(context).sendEmail, + // textColor: Colors.white, + // color: Colors.red[700], + // onTap: (){ + // showConfirmMessage(context, () async { + // GifLoaderDialogUtils.showMyDialog(context); + // await model.sendContactLensPrescriptionEmail( + // appointmentNo: appointmentNo, + // projectName: projectName, + // projectID: projectID); + // GifLoaderDialogUtils.hideDialog(context); + // }, model.user.emailAddress); + // }, + // icon: Icon( + // Icons.email, + // color: Colors.white, + // ), + // ), + // ) ], ), ), @@ -140,38 +123,51 @@ class ContactLensPage extends StatelessWidget { ); } - Widget getRow(String title, String val1) => Padding( - padding: const EdgeInsets.all(8.0), + Widget getRow(String title, String val1, {bool isLast = false}) => Padding( + padding: const EdgeInsets.only(left: 8, right: 8), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - Expanded(flex: 4, child: Texts(title)), - Expanded( - flex: 2, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts(val1 == 'null' ? '-' : val1), - ], - ), - ) - ], + Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Expanded( + flex: 4, + child: Text( + title, + style: TextStyle(fontSize: 11, fontWeight: FontWeight.w600, letterSpacing: -0.4), + )), + Expanded( + flex: 2, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + val1 == 'null' ? '-' : val1, + style: TextStyle(fontSize: 11, fontWeight: FontWeight.w600, letterSpacing: -0.4), + ), + ], + ), + ) + ], + ), ), - Divider() + isLast + ? Container( + height: 4, + ) + : Divider() ], ), ); - - void showConfirmMessage( - BuildContext context, GestureTapCallback onTap, String email) { + void showConfirmMessage(BuildContext context, GestureTapCallback onTap, String email) { showDialog( context: context, - child: ConfirmSendEmailDialog( + builder: (cxt) => ConfirmSendEmailDialog( email: email, onTapSendEmail: () { onTap(); diff --git a/lib/pages/medical/eye/EyeHomePage.dart b/lib/pages/medical/eye/EyeHomePage.dart index 3af2279e..e7a5c42b 100644 --- a/lib/pages/medical/eye/EyeHomePage.dart +++ b/lib/pages/medical/eye/EyeHomePage.dart @@ -2,124 +2,168 @@ import 'dart:ui'; import 'package:diplomaticquarterapp/core/model/eye/AppoimentAllHistoryResult.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/EyeViewModel.dart'; -import 'package:diplomaticquarterapp/core/viewModels/medical/weight_pressure_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DoctorRateDetails.dart'; +import 'package:diplomaticquarterapp/models/header_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/custom_text_button.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/confirm_send_email_dialog.dart'; +import 'package:diplomaticquarterapp/widgets/new_design/doctor_header.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_rating_bar/flutter_rating_bar.dart'; +import 'package:provider/provider.dart'; import 'ClassesPage.dart'; import 'ContactLensPage.dart'; class EyeHomePage extends StatefulWidget { - final AppoimentAllHistoryResultList appointmentAllHistoryResultList; + final AppoimentAllHistoryResultList? appointmentAllHistoryResultList; - const EyeHomePage({Key key, this.appointmentAllHistoryResultList}) - : super(key: key); + const EyeHomePage({Key? key, this.appointmentAllHistoryResultList}) : super(key: key); @override _EyeHomePageState createState() => _EyeHomePageState(); } -class _EyeHomePageState extends State - with SingleTickerProviderStateMixin { - TabController _tabController; +class _EyeHomePageState extends State with SingleTickerProviderStateMixin { + TabController? _tabController; + List? doctorDetailsList = []; + ProjectViewModel? projectViewModel; @override void initState() { super.initState(); _tabController = TabController(length: 2, vsync: this); + _tabController!.addListener(() { + setState(() {}); + }); } @override void dispose() { super.dispose(); - _tabController.dispose(); + _tabController!.dispose(); } @override Widget build(BuildContext context) { - return AppScaffold( - isShowAppBar: true, - isShowDecPage: false, - appBarTitle: TranslationBase.of(context).measurements, - body: Scaffold( - extendBodyBehindAppBar: true, - appBar: PreferredSize( - preferredSize: Size.fromHeight(60.0), - child: Stack( - children: [ - Positioned( - bottom: 1, - left: 0, - right: 0, - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10), - child: Container( - color: Theme.of(context) - .scaffoldBackgroundColor - .withOpacity(0.8), - height: 70.0, - ), - ), + projectViewModel = Provider.of(context); + return BaseView( + builder: (_, model, w) => AppScaffold( + isShowAppBar: true, + isShowDecPage: false, + appBarTitle: widget.appointmentAllHistoryResultList!.doctorTitle! + " " + widget.appointmentAllHistoryResultList!.doctorNameObj!, + showNewAppBarTitle: true, + showNewAppBar: true, + backgroundColor: CustomColors.appBackgroudGreyColor, + body: Column( + children: [ + DoctorHeader( + headerModel: HeaderModel( + widget.appointmentAllHistoryResultList!.doctorTitle! + " " + widget.appointmentAllHistoryResultList!.doctorNameObj!, + widget.appointmentAllHistoryResultList!.doctorID!, + widget.appointmentAllHistoryResultList!.doctorImageURL!, + widget.appointmentAllHistoryResultList!.doctorSpeciality !=null ? widget.appointmentAllHistoryResultList!.doctorSpeciality! : [], + "", + widget.appointmentAllHistoryResultList!.projectName!, + DateUtil.convertStringToDate(widget.appointmentAllHistoryResultList!.appointmentDate!), + widget.appointmentAllHistoryResultList!.startTime!.substring(0, 5), + "null", + widget.appointmentAllHistoryResultList!.doctorRate, + widget.appointmentAllHistoryResultList!.actualDoctorRate, + widget.appointmentAllHistoryResultList!.noOfPatientsRate, + "", + //model.user.emailAddress, ), - Center( - child: Container( - height: 55.0, - margin: EdgeInsets.only(left: 20,right: 20,top: 15), - color: Colors.white, - child: Center( - child: TabBar( - isScrollable: true, - controller: _tabController, - indicatorWeight: 5.0, - indicatorSize: TabBarIndicatorSize.tab, - labelColor: Theme.of(context).primaryColor, - labelPadding: - EdgeInsets.only(top: 4.0, left: 5.0, right: 5.0), - unselectedLabelColor: Colors.grey[800], - tabs: [ - Container( - width: MediaQuery.of(context).size.width * 0.40, - child: Center( - child: Texts(TranslationBase.of(context).classes), + isNeedToShowButton: _tabController!.index == 0 ? true : projectViewModel!.havePrivilege(15), + showConfirmMessageDialog: false, + onRatingAndReviewTap: getDoctorRatingsDetails, + onTap: () { + print("Email.."); + + showDialog( + context: context, + builder: (cxt) => ConfirmSendEmailDialog( + email: projectViewModel!.user!.emailAddress!, + onTapSendEmail: () async{ + GifLoaderDialogUtils.showMyDialog(context); + await model.sendGlassesPrescriptionEmail( + appointmentNo: widget.appointmentAllHistoryResultList!.appointmentNo!, + projectName: widget.appointmentAllHistoryResultList!.projectName!, + projectID: widget.appointmentAllHistoryResultList!.projectID!); + GifLoaderDialogUtils.hideDialog(context); + }, + ), + ); + }, + ), + Container( + height: 45.0, + width: double.infinity, + child: Center( + child: TabBar( + isScrollable: false, + controller: _tabController, + indicatorWeight: 2.0, + indicatorSize: TabBarIndicatorSize.tab, + labelColor: Theme.of(context).primaryColor, + labelPadding: EdgeInsets.only(top: 4.0, left: 5.0, right: 5.0), + unselectedLabelColor: Colors.grey[800], + tabs: [ + Container( + // width: double.infinity, + child: Center( + child: Text( + TranslationBase.of(context).classes, + style: TextStyle( + fontWeight: FontWeight.w600, + // fontSize: 12, + letterSpacing: -0.36, ), ), - Container( - width: MediaQuery.of(context).size.width * 0.40, - child: Center( - child: Texts(TranslationBase.of(context).contactLens), + ), + ), + Container( + // width: double.infinity, + child: Center( + child: Text( + TranslationBase.of(context).contactLens, + style: TextStyle( + fontWeight: FontWeight.w600, + // fontSize: 12, + letterSpacing: -0.36, ), ), - ], + ), ), - ), + ], ), ), - ], - ), - ), - body: Column( - children: [ + ), Expanded( child: TabBarView( - physics: BouncingScrollPhysics(), + physics: NeverScrollableScrollPhysics(), controller: _tabController, children: [ ClassesPage( - glassPerscription: widget.appointmentAllHistoryResultList - .listHISGetGlassPerscription[0], - appointmentNo: widget.appointmentAllHistoryResultList.appointmentNo, - projectName: widget.appointmentAllHistoryResultList.projectName, - projectID: widget.appointmentAllHistoryResultList.projectID, + glassPerscription: widget.appointmentAllHistoryResultList!.listHISGetGlassPerscription![0], + appointmentNo: widget.appointmentAllHistoryResultList!.appointmentNo, + projectName: widget.appointmentAllHistoryResultList!.projectName, + projectID: widget.appointmentAllHistoryResultList!.projectID, ), ContactLensPage( - listHISGetContactLensPerscription: widget.appointmentAllHistoryResultList.listHISGetContactLensPerscription[0], - appointmentNo: widget.appointmentAllHistoryResultList.appointmentNo, - projectName: widget.appointmentAllHistoryResultList.projectName, - projectID: widget.appointmentAllHistoryResultList.projectID, + listHISGetContactLensPerscription: widget.appointmentAllHistoryResultList!.listHISGetContactLensPerscription![0], + appointmentNo: widget.appointmentAllHistoryResultList!.appointmentNo, + projectName: widget.appointmentAllHistoryResultList!.projectName, + projectID: widget.appointmentAllHistoryResultList!.projectID, ) ], ), @@ -129,4 +173,237 @@ class _EyeHomePageState extends State ), ); } + // + // void showConfirmMessage(BuildContext context, GestureTapCallback onTap, String email) { + // + // } + + void getDoctorRatingsDetails() { + GifLoaderDialogUtils.showMyDialog(context); + DoctorsListService service = new DoctorsListService(); + service.getDoctorsRatingDetails(widget.appointmentAllHistoryResultList!.doctorID!, projectViewModel!.isArabic ? 1 : 2, context).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res['MessageStatus'] == 1) { + doctorDetailsList!.clear(); + res['DoctorRatingDetailsList'].forEach((v) { + doctorDetailsList!.add(new DoctorRateDetails.fromJson(v)); + }); + showRatingDialog(doctorDetailsList!); + } else { + AppToast.showErrorToast(message: res['ErrorEndUserMessage']); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + + void showRatingDialog(List doctorDetailsList) { + 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, + children: [ + Container( + // height: 400.0, + width: MediaQuery.of(context).size.width * 0.8, + color: Colors.white, + child: Column( + children: [ + Container( + alignment: Alignment.center, + width: MediaQuery.of(context).size.width, + color: Theme.of(context).primaryColor, + margin: EdgeInsets.only(bottom: 5.0), + padding: EdgeInsets.all(10.0), + child: Text(TranslationBase.of(context).doctorRating, style: TextStyle(fontSize: 22.0, color: Colors.white))), + Container( + margin: EdgeInsets.only(top: 0.0), + child: Text(this.widget.appointmentAllHistoryResultList!.actualDoctorRate!.ceilToDouble().toString(), style: TextStyle(fontSize: 32.0, color: Colors.black))), + Container( + margin: EdgeInsets.only(top: 5.0), + alignment: Alignment.center, + child: RatingBar( + initialRating: this.widget.appointmentAllHistoryResultList!.actualDoctorRate!.toDouble(), + direction: Axis.horizontal, + itemCount: 5, + itemSize: 20.0, + allowHalfRating: true, + ignoreGestures: true, + ratingWidget: RatingWidget( + full: Icon(Icons.star, color: CustomColors.accentColor,), + half: Icon(Icons.star_half, color: CustomColors.accentColor,), + empty: Icon(Icons.star, color: CustomColors.accentColor,), + ), + tapOnlyMode: true, + unratedColor: Colors.grey[500], + itemPadding: EdgeInsets.symmetric(horizontal: 4.0), + onRatingUpdate: (rating) { + print(rating); + }, + ), + ), + Container( + margin: EdgeInsets.only(top: 10.0), + child: Text(this.widget.appointmentAllHistoryResultList!.noOfPatientsRate.toString() + " " + TranslationBase.of(context).reviews, + style: TextStyle(fontSize: 14.0, color: Colors.black))), + Container( + margin: EdgeInsets.only(top: 10.0), + child: Row( + children: [ + Container( + width: 100.0, + margin: EdgeInsets.only(top: 10.0, left: 15.0, right: 15.0), + child: Text(TranslationBase.of(context).excellent, style: TextStyle(fontSize: 13.0, color: Colors.black))), + Container( + margin: EdgeInsets.only(top: 10.0), + child: SizedBox( + width: getRatingWidth(doctorDetailsList[0].patientNumber), + height: 6.0, + child: Container( + color: Colors.green[700], + ), + ), + ), + ], + ), + ), + Container( + child: Row( + children: [ + Container( + width: 100.0, + margin: EdgeInsets.only(top: 10.0, left: 15.0, right: 15.0), + child: Text(TranslationBase.of(context).v_good, style: TextStyle(fontSize: 13.0, color: Colors.black))), + Container( + margin: EdgeInsets.only(top: 10.0), + child: SizedBox( + width: getRatingWidth(doctorDetailsList[1].patientNumber), + height: 6.0, + child: Container( + color: Color(0xffB7B723), + ), + ), + ), + ], + ), + ), + Container( + child: Row( + children: [ + Container( + width: 100.0, + margin: EdgeInsets.only(top: 10.0, left: 15.0, right: 15.0), + child: Text(TranslationBase.of(context).good, style: TextStyle(fontSize: 13.0, color: Colors.black))), + Container( + margin: EdgeInsets.only(top: 10.0), + child: SizedBox( + width: getRatingWidth(doctorDetailsList[2].patientNumber), + height: 6.0, + child: Container( + color: Color(0xffEBA727), + ), + ), + ), + ], + ), + ), + Container( + child: Row( + children: [ + Container( + width: 100.0, + margin: EdgeInsets.only(top: 10.0, left: 15.0, right: 15.0), + child: Text(TranslationBase.of(context).average, style: TextStyle(fontSize: 13.0, color: Colors.black))), + Container( + margin: EdgeInsets.only(top: 10.0), + child: SizedBox( + width: getRatingWidth(doctorDetailsList[3].patientNumber), + height: 6.0, + child: Container( + color: Color(0xffEB7227), + ), + ), + ), + ], + ), + ), + Container( + child: Row( + children: [ + Container( + width: 100.0, + margin: EdgeInsets.only(top: 10.0, left: 15.0, right: 15.0), + child: Text(TranslationBase.of(context).below_average, style: TextStyle(fontSize: 13.0, color: Colors.black))), + Container( + margin: EdgeInsets.only(top: 10.0), + child: SizedBox( + width: getRatingWidth(doctorDetailsList[4].patientNumber), + height: 6.0, + child: Container( + color: Color(0xffE20C0C), + ), + ), + ), + ], + ), + ), + Container(margin: EdgeInsets.only(top: 40.0), child: Divider()), + Container( + margin: EdgeInsets.only(top: 0.0), + child: Align( + alignment: FractionalOffset.bottomCenter, + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + minWidth: MediaQuery.of(context).size.width, + height: 40.0, + child: CustomTextButton( + elevation: 0.0, + backgroundColor: Colors.white, + disabledForegroundColor: Color(0xFFbcc2c4).withOpacity(0.38), + disabledBackgroundColor: Color(0xFFbcc2c4).withOpacity(0.12), + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text(TranslationBase.of(context).cancel, + style: TextStyle( + fontSize: 18.0, + color: Colors.red, + )), + ), + ), + ), + ), + ], + ), + ), + ], + ), + ), + ), + ); + }, + transitionDuration: Duration(milliseconds: 500), + barrierDismissible: true, + barrierLabel: '', + context: context, + pageBuilder: (context, animation1, animation2) { + return SizedBox(); + }); + } + + double getRatingWidth(int patientNumber) { + var width = (patientNumber / this.widget.appointmentAllHistoryResultList!.noOfPatientsRate!) * 100; + return width; + } } diff --git a/lib/pages/medical/eye/EyeMeasurementsPage.dart b/lib/pages/medical/eye/EyeMeasurementsPage.dart index 8dbe0f16..652c0a24 100644 --- a/lib/pages/medical/eye/EyeMeasurementsPage.dart +++ b/lib/pages/medical/eye/EyeMeasurementsPage.dart @@ -1,11 +1,12 @@ +import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; +import 'package:diplomaticquarterapp/core/model/eye/AppoimentAllHistoryResult.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/EyeViewModel.dart'; 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/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/avatar/large_avatar.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; -import 'package:diplomaticquarterapp/widgets/others/StarRating.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/medical/doctor_card.dart'; import 'package:diplomaticquarterapp/widgets/others/app_expandable_notifier.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; @@ -13,6 +14,8 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import '../../../uitl/gif_loader_dialog_utils.dart'; +import '../../../widgets/dialogs/confirm_send_email_dialog.dart'; import 'EyeHomePage.dart'; class EyeMeasurementsPage extends StatelessWidget { @@ -24,100 +27,100 @@ class EyeMeasurementsPage extends StatelessWidget { builder: (_, model, w) => AppScaffold( isShowAppBar: true, baseViewModel: model, + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: CustomColors.appBackgroudGreyColor, + description: TranslationBase.of(context).infoEye, + imagesInfo: [ + ImagesInfo( + imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/eye-measurements/ar/0.png', + imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/eye-measurements/en/0.png') + ], appBarTitle: TranslationBase.of(context).eyeMeasurements, body: SingleChildScrollView( - child: Container( - margin: EdgeInsets.all(8), - child: Column( - children: [ - ...List.generate( - model.appointmentFilter.length, - (index) => AppExpandableNotifier( + child: Column( + children: [ + ListView.separated( + physics: NeverScrollableScrollPhysics(), + shrinkWrap: true, + padding: EdgeInsets.only(top: 12), + separatorBuilder: (context, index) { + return Container( + height: 12, + margin: EdgeInsets.only(left: 21, right: 21), + // color: Color(0xffD9D9D9), + ); + }, + itemBuilder: (context, index) { + List _appointmentAllHistoryResultList = model.appointmentFilter[index].appointmentAllHistoryResultList; + return AppExpandableNotifier( title: model.appointmentFilter[index].filterName, - bodyWidget: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: model.appointmentFilter[index] - .appointmentAllHistoryResultList - .map((appointment) { - return InkWell( - onTap: () { - Navigator.push( - context, - FadePage( - page: EyeHomePage( - appointmentAllHistoryResultList: appointment, - ), - ), - ); - }, - child: Container( - margin: EdgeInsets.all(8), - padding: EdgeInsets.all(8.0), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(8), - color: Colors.white, - border: Border.all(color: Colors.grey), - ), - child: Row( - children: [ - Expanded( - flex: 1, - child: LargeAvatar( - name: appointment.doctorNameObj, - url: appointment.doctorImageURL, - ), - ), - Expanded( - flex: 4, - child: Container( - margin: EdgeInsets.all(10), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Texts( - appointment.doctorNameObj, - bold: true, - ), - Texts( - appointment.clinicName, - variant: 'caption3', - ), - Texts( - DateUtil.getMonthDayYearDateFormatted( - appointment.bookDate), - variant: 'caption3', - ), - StarRating( - totalAverage: appointment - .actualDoctorRate - .toDouble(), - forceStars: true), - ], - ), + bodyWidget: ListView.separated( + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + padding: EdgeInsets.only(bottom: 14, top: 14, left: 21, right: 21), + itemBuilder: (context, _index) { + AppoimentAllHistoryResultList _appointmentResult = _appointmentAllHistoryResultList[_index]; + + return DoctorCard( + onTap: () => Navigator.push( + context, + FadePage( + page: EyeHomePage( + appointmentAllHistoryResultList: _appointmentResult, ), ), - Icon( - projectViewModel.isArabic - ? Icons.arrow_forward_ios - : Icons.arrow_back_ios, - color: Colors.grey, - size: 18, - ) - ], - ), - ), - ); - }).toList(), - ), - ), - ), - ], - ), + ), + onEmailTap: () { + showConfirmMessage(context, () async { + GifLoaderDialogUtils.showMyDialog(context); + await model.sendGlassesPrescriptionEmail( + appointmentNo: _appointmentResult!.appointmentNo!, + projectName: _appointmentResult!.projectName!, + projectID: _appointmentResult!.projectID!); + GifLoaderDialogUtils.hideDialog(context); + }, projectViewModel!.user!.emailAddress!); + }, + isInOutPatient: _appointmentResult.isInOutPatient, + name: _appointmentResult.doctorTitle! + " " + _appointmentResult.doctorNameObj!, + // billNo: "appointmentResult.do", + profileUrl: _appointmentResult.doctorImageURL, + subName: _appointmentResult.clinicName, + isLiveCareAppointment: _appointmentResult.isLiveCareAppointment, + date: DateUtil.convertStringToDate(_appointmentResult.appointmentDate!), + isSortByClinic: false, + rating: _appointmentResult.actualDoctorRate! + 0.0, + // appointmentTime: _appointmentResult.startTime.substring(0, 5), + // remainingTimeInMinutes: (_appointmentResult.patientStatusType == AppointmentType.BOOKED || _appointmentResult.patientStatusType == AppointmentType.CONFIRMED) + // ? _appointmentResult.remaniningHoursTocanPay + // : null + + //projectViewModel.isArabic ? DateUtil.getMonthDayYearDateFormattedAr(labOrder.orderDate) : DateUtil.getMonthDayYearDateFormatted(labOrder.orderDate), + ); + }, + separatorBuilder: (context, index) => SizedBox(height: 14), + itemCount: _appointmentAllHistoryResultList.length), + ); + }, + itemCount: model.appointmentFilter.length, + ), + + ], ), ), ), ); } + void showConfirmMessage(BuildContext context, GestureTapCallback onTap, String email) { + showDialog( + context: context, + builder: (cxt) => ConfirmSendEmailDialog( + email: email, + onTapSendEmail: () { + onTap(); + }, + ), + ); + } + } diff --git a/lib/pages/medical/labs/laboratory_result_page.dart b/lib/pages/medical/labs/laboratory_result_page.dart index a251a1ce..8441492e 100644 --- a/lib/pages/medical/labs/laboratory_result_page.dart +++ b/lib/pages/medical/labs/laboratory_result_page.dart @@ -1,55 +1,134 @@ +import 'dart:convert'; +import 'dart:io'; +import 'dart:typed_data'; + import 'package:diplomaticquarterapp/core/model/labs/patient_lab_orders.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/labs_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/data_display/medical/LabResult/laboratory_result_widget.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:open_filex/open_filex.dart'; +import 'package:path_provider/path_provider.dart'; +import 'package:provider/provider.dart'; class LaboratoryResultPage extends StatefulWidget { - final PatientLabOrders patientLabOrders; + final PatientLabOrders? patientLabOrders; - LaboratoryResultPage({Key key, this.patientLabOrders}); + LaboratoryResultPage({Key? key, this.patientLabOrders}); @override _LaboratoryResultPageState createState() => _LaboratoryResultPageState(); } class _LaboratoryResultPageState extends State { - - @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); return BaseView( onModelReady: (model) => model.getLaboratoryResult( - invoiceNo: widget.patientLabOrders.invoiceNo, - clinicID: widget.patientLabOrders.clinicID, - projectID: widget.patientLabOrders.projectID, - orderNo: widget.patientLabOrders.orderNo), + invoiceNo: widget.patientLabOrders!.invoiceNo, + invoiceType: widget.patientLabOrders!.invoiceType, + clinicID: widget.patientLabOrders!.clinicID, + projectID: widget.patientLabOrders!.projectID, + orderNo: widget.patientLabOrders!.orderNo, + setupID: widget.patientLabOrders!.setupID, + isVidaPlus: Utils.isVidaPlusProject(projectViewModel, int.parse(widget.patientLabOrders!.projectID!)), + ), builder: (_, model, w) => AppScaffold( isShowAppBar: true, - appBarTitle: TranslationBase.of(context).labResults, + appBarTitle: widget.patientLabOrders!.doctorName!, baseViewModel: model, - body: Scaffold( - body: ListView.builder( - itemBuilder: (context, index) => LaboratoryResultWidget( - onTap: ()async { - GifLoaderDialogUtils.showMyDialog(context); - await model.sendLabReportEmail(patientLabOrder: widget.patientLabOrders,mes: TranslationBase.of(context).sendSuc); - GifLoaderDialogUtils.hideDialog(context); - }, - billNo: widget.patientLabOrders.invoiceNo, - details: model.patientLabSpecialResult[index].resultDataHTML, - orderNo: widget.patientLabOrders.orderNo, - patientLabOrder: widget.patientLabOrders, - ), - itemCount: model.patientLabSpecialResult.length, + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: Color(0xffF8F8F8), + body: SingleChildScrollView( + child: Column( + children: [ + ListView.builder( + addAutomaticKeepAlives: true, + physics: BouncingScrollPhysics(), + shrinkWrap: true, + padding: EdgeInsets.only(bottom: 12), + itemBuilder: (context, index) => LaboratoryResultWidget( + onTap: () async { + GifLoaderDialogUtils.showMyDialog(context); + await model.sendLabReportEmail( + patientLabOrder: widget.patientLabOrders, + mes: TranslationBase.of(context).sendSuc, + userObj: projectViewModel.user, + languageID: projectViewModel.isArabic ? 1 : 2, + isDownload: true, + isVidaPlus: Utils.isVidaPlusProject( + projectViewModel, + int.parse(widget.patientLabOrders!.projectID!), + ), + ); + GifLoaderDialogUtils.hideDialog(context); + }, + billNo: widget.patientLabOrders!.invoiceNo, + // details: model.patientLabSpecialResult[index].resultDataHTML, + details: model.patientLabSpecialResult.isEmpty ? null : getSpecialResults(model), + orderNo: widget.patientLabOrders!.orderNo, + patientLabOrder: widget.patientLabOrders, + projectName: widget.patientLabOrders!.projectName, + ), + itemCount: 1, + ), + SizedBox( + height: 120.0, + ) + ], ), ), + // bottomSheet: Container( + // color: Colors.white, + // height: MediaQuery.of(context).size.height * 0.081, + // width: double.infinity, + // padding: EdgeInsets.all(12.0), + // child: Column( + // children: [ + // Container( + // width: MediaQuery.of(context).size.width * 0.9, + // child: DefaultButton( + // TranslationBase.of(context).downloadReport, + // () async { + // GifLoaderDialogUtils.showMyDialog(context); + // await model.sendLabReportEmail(patientLabOrder: widget.patientLabOrders, mes: TranslationBase.of(context).sendSuc, userObj: projectViewModel.user, isVidaPlus: Utils.isVidaPlusProject(projectViewModel, num.parse(widget.patientLabOrders.projectID)), isDownload: true); + // GifLoaderDialogUtils.hideDialog(context); + // try { + // String path = await _createFileFromString(model.labReportPDF, "pdf"); + // OpenFilex.open(path); + // } catch (ex) { + // AppToast.showErrorToast(message: "Cannot open file."); + // } + // }, + // textColor: Colors.white, + // ), + // ), + // ], + // ), + // ), ), ); } + + String getSpecialResults(LabsViewModel model) { + String labResults = ""; + model.patientLabSpecialResult.forEach((element) { + if (element.resultDataHTML != null) { + labResults += (element.resultDataHTML! + "

"); + } else { + labResults += ("
No Result Available
"); + } + }); + return labResults; + } } diff --git a/lib/pages/medical/labs/labs_home_page.dart b/lib/pages/medical/labs/labs_home_page.dart index ce78a7dc..5a163c10 100644 --- a/lib/pages/medical/labs/labs_home_page.dart +++ b/lib/pages/medical/labs/labs_home_page.dart @@ -1,11 +1,12 @@ import 'package:diplomaticquarterapp/core/enum/filter_type.dart'; import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; +import 'package:diplomaticquarterapp/core/model/labs/patient_lab_orders.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/labs_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.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/widgets/data_display/medical/doctor_card.dart'; +import 'package:diplomaticquarterapp/widgets/new_design/my_tab_view.dart'; import 'package:diplomaticquarterapp/widgets/others/app_expandable_notifier.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; @@ -16,96 +17,90 @@ import 'package:provider/provider.dart'; import 'laboratory_result_page.dart'; class LabsHomePage extends StatelessWidget { - List imagesInfo =List(); + List imagesInfo = []; @override Widget build(BuildContext context) { ProjectViewModel projectViewModel = Provider.of(context); - imagesInfo.add(ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-lab/en/0.png',imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-lab/ar/0.png')); + imagesInfo.add(ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-lab/en/0.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-lab/ar/0.png')); return BaseView( onModelReady: (model) => model.getLabs(), builder: (context, LabsViewModel model, widget) => AppScaffold( baseViewModel: model, isShowAppBar: true, description: TranslationBase.of(context).infoLab, - appBarTitle: TranslationBase.of(context).labOrders, + appBarTitle: TranslationBase.of(context).labResults, + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: Color(0xffF8F8F8), imagesInfo: imagesInfo, - body: SingleChildScrollView( - physics: BouncingScrollPhysics(), - child: FractionallySizedBox( - widthFactor: 1.0, - child: Center( - child: Column( - children: [ - Row( - children: [ - Expanded( - flex: 1, - child: InkWell( - onTap: () => model.setFilterType(FilterType.Clinic), - child: ListTile( - title: Text(TranslationBase.of(context).clinic), - leading: Radio( - value: FilterType.Clinic, - groupValue: model.filterType, - onChanged: (FilterType value) { - model.setFilterType(value); - }, - ), - ), - ), - ), - Expanded( - flex: 1, - child: InkWell( - onTap: () => model.setFilterType(FilterType.Hospital), - child: ListTile( - title: Text(TranslationBase.of(context).hospital), - leading: Radio( - value: FilterType.Hospital, - groupValue: model.filterType, - onChanged: (FilterType value) => - model.setFilterType(value), - ), - ), - ), - ) - ], - ), - ...List.generate( - model.patientLabOrdersList.length, - (index) => AppExpandableNotifier( - title: model.patientLabOrdersList[index].filterName, - bodyWidget: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: model - .patientLabOrdersList[index].patientLabOrdersList - .map((labOrder) { - return DoctorCard( - onTap: () => Navigator.push( - context, - FadePage( - page: LaboratoryResultPage( - patientLabOrders: labOrder, + body: Column( + children: [ + Row( + children: [ + MyTabView(TranslationBase.of(context).byClinic, FilterType.Clinic, model.filterType, () { + model.setFilterType(FilterType.Clinic); + }), + MyTabView(TranslationBase.of(context).byHospital, FilterType.Hospital, model.filterType, () { + model.setFilterType(FilterType.Hospital); + }), + ], + ), + Expanded( + child: FractionallySizedBox( + widthFactor: 1.0, + child: ListView.separated( + addAutomaticKeepAlives: true, + physics: BouncingScrollPhysics(), + padding: EdgeInsets.only(top: 12), + separatorBuilder: (context, index) { + return Container( + height: 12, + margin: EdgeInsets.only(left: 21, right: 21), + // color: Color(0xffD9D9D9), + ); + }, + itemBuilder: (context, index) { + return AppExpandableNotifier( + title: model.patientLabOrdersList[index].filterName, + bodyWidget: ListView.separated( + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + padding: EdgeInsets.only(bottom: 14, top: 14, left: 21, right: 21), + itemBuilder: (context, _index) { + PatientLabOrders labOrder = model.patientLabOrdersList[index].patientLabOrdersList[_index]; + bool _isSortByClinic = model.filterType == FilterType.Clinic; + return DoctorCard( + onTap: () => Navigator.push( + context, + FadePage( + page: LaboratoryResultPage( + patientLabOrders: labOrder, + ), + ), ), - ), - ),isInOutPatient: labOrder.isInOutPatient, - name: labOrder.doctorName, - billNo: ' ${labOrder.invoiceNo}', - profileUrl: labOrder.doctorImageURL, - subName: labOrder.projectName, - isLiveCareAppointment: labOrder.isLiveCareAppointment, - date: projectViewModel.isArabic?DateUtil.getMonthDayYearDateFormattedAr(labOrder.orderDate):DateUtil.getMonthDayYearDateFormatted(labOrder.orderDate), - ); - }).toList(), - ), - ), - ) - ], + isInOutPatient: labOrder.isInOutPatient, + name: TranslationBase.of(context).dr + " " + labOrder.doctorName!, + billNo: labOrder.invoiceNo, + profileUrl: labOrder.doctorImageURL, + subName: _isSortByClinic ? (labOrder.projectName ?? labOrder.clinicDescription) : (labOrder.clinicDescription ?? labOrder.projectName), + isLiveCareAppointment: labOrder.isLiveCareAppointment, + date: labOrder.orderDate, + isSortByClinic: _isSortByClinic, + isLabOrderResult: true, + resultStatus: labOrder.status!, + resultStatusDesc: labOrder.statusDesc!, + //projectViewModel.isArabic ? DateUtil.getMonthDayYearDateFormattedAr(labOrder.orderDate) : DateUtil.getMonthDayYearDateFormatted(labOrder.orderDate), + ); + }, + separatorBuilder: (context, index) => SizedBox(height: 14), + itemCount: model.patientLabOrdersList[index].patientLabOrdersList.length), + ); + }, + itemCount: model.patientLabOrdersList.length), ), ), - ), + ], ), ), ); diff --git a/lib/pages/medical/labs/passport_update_page.dart b/lib/pages/medical/labs/passport_update_page.dart new file mode 100644 index 00000000..61e74acb --- /dev/null +++ b/lib/pages/medical/labs/passport_update_page.dart @@ -0,0 +1,299 @@ +import 'package:diplomaticquarterapp/core/service/medical/labs_service.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/custom_text_button.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:provider/provider.dart'; + +class PassportUpdatePage extends StatefulWidget { + @override + _PassportUpdatePageState createState() => _PassportUpdatePageState(); +} + +class _PassportUpdatePageState extends State { + TextEditingController passportNumber = new TextEditingController(); + bool? _isButtonDisabled; + ProjectViewModel? projectViewModel; + + @override + void initState() { + WidgetsBinding.instance.addPostFrameCallback((_) => getPassportNumber()); + super.initState(); + } + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + return AppScaffold( + appBarTitle: TranslationBase.of(context).passportNumber, + isShowAppBar: true, + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: CustomColors.appBackgroudGrey2Color, + body: Container( + child: Column( + children: [ + Expanded( + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: double.infinity, + child: Container( + decoration: cardRadius(12), + margin: EdgeInsets.zero, + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).covidBookAppo, + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 16, + letterSpacing: -0.64, + ), + ), + mHeight(6), + Row( + children: [ + Text( + TranslationBase.of(context).patientName + ":", + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 10, + letterSpacing: -0.6, + color: CustomColors.grey, + ), + ), + mWidth(3), + Text( + projectViewModel!.user!.firstName! + " " + projectViewModel!.user!.lastName!, + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 12, + letterSpacing: -0.48, + ), + ), + ], + ), + Row( + children: [ + Text( + TranslationBase.of(context).identificationNumber + ":", + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 10, + letterSpacing: -0.6, + color: CustomColors.grey, + ), + ), + mWidth(3), + Text( + projectViewModel!.user!.patientIdentificationNo!, + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 12, + letterSpacing: -0.48, + ), + ), + ], + ), + ], + ), + ), + ), + ), + mHeight(40), + SvgPicture.asset("assets/images/new/passport.svg", width: 40.0, fit: BoxFit.fill), + mHeight(12), + Text( + TranslationBase.of(context).enterPassportNumber, + textAlign: TextAlign.start, + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.bold, + color: Colors.black, + letterSpacing: -0.64, + ), + ), + mHeight(8), + inputWidget(TranslationBase.of(context).passportNumber, "", passportNumber), + ], + ), + ), + ), + ), + Container( + width: MediaQuery.of(context).size.width, + margin: EdgeInsets.only(top: 12.0, left: 12.0, right: 12.0, bottom: 10.0), + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + height: 45.0, + child: CustomTextButton( + backgroundColor: Color(0xFFc5272d), + disabledForegroundColor: Colors.red[300]!.withOpacity(0.38), + disabledBackgroundColor: Colors.red[300]!.withOpacity(0.12), + elevation: 0, + onPressed: () { + if (_isButtonDisabled == false) + updatePassportNumber(); + else + AppToast.showErrorToast(message: TranslationBase.of(context).validPassportNumber); + }, + child: Text( + TranslationBase.of(context).submit, + style: TextStyle( + fontSize: 16.0, + letterSpacing: -0.64, + color: Colors.white, + ), + ), + ), + ), + ), + ], + ), + ), + ); + } + + 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(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: TextInputType.text, + controller: _controller, + onChanged: (value) => {_onPassportTextChanged(value)}, + 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, + ), + 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), + ], + ), + ), + ); + } + + _onPassportTextChanged(content) { + if (content.length >= 1) { + setState(() { + _isButtonDisabled = false; + }); + } else { + setState(() { + _isButtonDisabled = true; + }); + } + } + + void updatePassportNumber() { + LabsService service = new LabsService(); + GifLoaderDialogUtils.showMyDialog(context); + + service.updateCovidPassportNumber(passportNumber.text).then((res) { + GifLoaderDialogUtils.hideDialog(context); + Navigator.of(context).pop(true); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } + + void getPassportNumber() { + LabsService service = new LabsService(); + GifLoaderDialogUtils.showMyDialog(context); + + service.getCovidPassportNumber().then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res['Covid19_Certificate_GetPassportList'].length != 0) { + passportNumber.text = res['Covid19_Certificate_GetPassportList'][0]['PassportNo'] ?? ""; + if (res['Covid19_Certificate_GetPassportList'][0]['PassportNo'] != "") { + _isButtonDisabled = false; + } + } else { + passportNumber.text = ""; + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } +} diff --git a/lib/pages/medical/medical_profile_page.dart b/lib/pages/medical/medical_profile_page.dart deleted file mode 100644 index 8d49a89b..00000000 --- a/lib/pages/medical/medical_profile_page.dart +++ /dev/null @@ -1,208 +0,0 @@ -import 'dart:math'; - -import 'package:badges/badges.dart'; -import 'package:diplomaticquarterapp/core/service/medical/vital_sign_service.dart'; -import 'package:diplomaticquarterapp/core/viewModels/medical/medical_view_model.dart'; -import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; -import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart'; -import 'package:diplomaticquarterapp/pages/MyAppointments/MyAppointments.dart'; -import 'package:diplomaticquarterapp/pages/base/base_view.dart'; -import 'package:diplomaticquarterapp/pages/insurance/insurance_approval_screen.dart'; -import 'package:diplomaticquarterapp/pages/insurance/insurance_card_screen.dart'; -import 'package:diplomaticquarterapp/pages/insurance/insurance_update_screen.dart'; -import 'package:diplomaticquarterapp/pages/medical/patient_sick_leave_page.dart'; -import 'package:diplomaticquarterapp/pages/medical/reports/monthly_reports.dart'; -import 'package:diplomaticquarterapp/pages/medical/smart_watch_health_data/smart_watch_instructions.dart'; -import 'package:diplomaticquarterapp/pages/vaccine/my_vaccines_screen.dart'; -import 'package:diplomaticquarterapp/pages/medical/prescriptions/prescriptions_home_page.dart'; -import 'package:diplomaticquarterapp/pages/medical/radiology/radiology_home_page.dart'; -import 'package:diplomaticquarterapp/pages/medical/vital_sign/vital_sign_details_screen.dart'; -import 'package:diplomaticquarterapp/pages/medical/reports/report_home_page.dart'; -import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; -import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/uitl/utils.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/medical/medical_profile_item.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/medical/time_line_widget.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; -import 'package:diplomaticquarterapp/widgets/dialogs/alert_dialog.dart'; -import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; -import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:diplomaticquarterapp/widgets/others/sliver_app_bar_delegate.dart'; -import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:diplomaticquarterapp/pages/insurance/insurance_card_screen.dart'; -import 'package:provider/provider.dart'; -import '../../locator.dart'; -import '../../uitl/gif_loader_dialog_utils.dart'; -import 'active_medications/ActiveMedicationsPage.dart'; -import 'allergies_page.dart'; -import 'ask_doctor/ask_doctor_home_page.dart'; -import 'balance/my_balance_page.dart'; -import 'doctor/doctor_home_page.dart'; -import 'package:diplomaticquarterapp/pages/insurance/insurance_update_screen.dart'; -import 'package:diplomaticquarterapp/pages/insurance/insurance_approval_screen.dart'; -import 'eye/EyeHomePage.dart'; -import 'eye/EyeMeasurementsPage.dart'; -import 'labs/labs_home_page.dart'; -import 'my_trackers/my_trackers.dart'; - -class MedicalProfilePage extends StatefulWidget { - @override - _MedicalProfilePageState createState() => _MedicalProfilePageState(); -} - -class _MedicalProfilePageState extends State { - var authProvider = new AuthProvider(); - List medical = List(); - ProjectViewModel projectViewModel; - - @override - Widget build(BuildContext context) { - projectViewModel = Provider.of(context); - var appoCountProvider = Provider.of(context); - List myMedicalList = Utils.myMedicalList( - projectViewModel: projectViewModel, - context: context, - count: appoCountProvider.count, - isLogin: projectViewModel.isLogin); - return BaseView( - onModelReady: (model) => model.getAppointmentHistory(), - builder: (_, model, widget) => AppScaffold( - isShowDecPage: false, - baseViewModel: model, - isHelp: true, - body: Container( - child: SingleChildScrollView( - child: Column( - children: [ - Stack( - children: [ - Column( - children: [ - Container( - width: double.infinity, - height: 210, - child: Stack( - children: [ - Image.asset( - 'assets/images/timeline_bg.png', - fit: BoxFit.cover, - width: double.infinity, - // color: Colors.black.withOpacity(0.0) - ), - if (model.isLogin) - ListView.builder( - itemBuilder: (context, index) => - TimeLineWidget( - isUp: index % 2 == 1, - appoitmentAllHistoryResul: model - .appoitmentAllHistoryResultList[index], - ), - itemCount: model - .appoitmentAllHistoryResultList.length, - scrollDirection: Axis.horizontal, - reverse: projectViewModel.isArabic, - ), - ], - ), - ), - SizedBox( - height: 50, - ), - Padding( - padding: EdgeInsets.symmetric(vertical: 5.0), - child: GridView.builder( - shrinkWrap: true, - primary: false, - physics: NeverScrollableScrollPhysics(), - gridDelegate: - SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 3, - childAspectRatio: MediaQuery.of(context) - .size - .width / - (MediaQuery.of(context).size.height / 2.20), - ), - itemCount: myMedicalList.length, - itemBuilder: (BuildContext context, int index) { - return myMedicalList[index]; - }, - ), - ) - ], - ), - SizedBox( - height: MediaQuery.of(context).size.height * 0.12, - ), - if (model.user != null && model.isLogin) - Positioned( - top: 185, - left: 20, - right: 20, - child: Container( - width: double.infinity, - height: 80, - decoration: BoxDecoration( - color: Colors.grey[500], - shape: BoxShape.rectangle, - border: Border.all( - color: Colors.transparent, width: 0.5), - borderRadius: - BorderRadius.all(Radius.circular(9)), - image: DecorationImage( - image: ExactAssetImage( - 'assets/images/bg_graphic.png'), - fit: BoxFit.cover)), - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - SizedBox( - height: 8, - ), - Texts( - model.user.firstName + - " " + - model.user.lastName, - color: Colors.white, - bold: true, - ), - Texts( - '${model.user.patientID}', - color: Colors.white, - ), - ], - ), - ), - ), - Positioned( - top: 2, - left: projectViewModel.isArabic ? 0 : 10, - right: projectViewModel.isArabic ? 10 : 0, - child: Texts( - TranslationBase.of(context).timeLine, - color: Colors.white, - fontSize: 14, - fontWeight: FontWeight.normal, - ), - ) - ], - ), - ], - ), - ), - ), - ), - ); - } -} - -class Medical { - final String title; - final String imagePath; - final String subTitle; - final Widget page; - - Medical({this.title, this.imagePath, this.subTitle, this.page}); -} diff --git a/lib/pages/medical/medical_profile_page_new.dart b/lib/pages/medical/medical_profile_page_new.dart new file mode 100644 index 00000000..55b6a4c6 --- /dev/null +++ b/lib/pages/medical/medical_profile_page_new.dart @@ -0,0 +1,178 @@ +import 'package:diplomaticquarterapp/config/size_config.dart'; +import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/medical/medical_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; +import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.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'; +import 'package:diplomaticquarterapp/widgets/data_display/medical/time_line_new_widget.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/radio_selection_dialog.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:url_launcher/url_launcher.dart'; + +class MedicalProfilePageNew extends StatefulWidget { + Function()? onTap; + String? a; + + MedicalProfilePageNew({this.onTap}); + + @override + _MedicalProfilePageState createState() => _MedicalProfilePageState(); +} + +class _MedicalProfilePageState extends State { + var authProvider = new AuthProvider(); + List medical = []; + ProjectViewModel? projectViewModel; + + List projectsList = []; + HospitalsModel? _selectedHospital; + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + var appoCountProvider = Provider.of(context); + List myMedicalList = + Utils.myMedicalList(projectViewModel: projectViewModel!, context: context, count: appoCountProvider.count, isLogin: projectViewModel!.isLogin, onWeCareClick: openWeCareProjectSelection); + return BaseView( + onModelReady: (model) => model.getAppointmentHistory(isForTimeLine: true), + builder: (_, model, widget1) => AppScaffold( + isShowDecPage: false, + isShowAppBar: false, + baseViewModel: model, + showNewAppBar: true, + isHelp: true, + showNewAppBarTitle: true, + appBarTitle: TranslationBase.of(context).medicalFileTitle, + onTap: widget.onTap, + body: Container( + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + TimeLineView(model.isLogin, projectViewModel!.isArabic, model.appoitmentAllHistoryResultList, model), + SizedBox( + height: 20, + ), + Padding( + padding: EdgeInsets.only(left: 12, right: 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + projectViewModel!.isLogin + ? Text( + projectViewModel?.user.firstName ?? "", + style: TextStyle(color: Colors.black, fontSize: SizeConfig.textMultiplier! * 1.8), + ) + : Container(), + Text( + TranslationBase.of(context).medicalFileTitle, + style: TextStyle( + color: Colors.black, + fontSize: SizeConfig.textMultiplier! * 3, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + SizedBox( + height: 20, + ), + 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]; + }, + ), + ), + SizedBox( + height: 12, + ), + ], + ), + ), + ), + ), + ); + } + + openWeCareProjectSelection() { + int _selectedHospitalIndex = -1; + int languageID = projectViewModel!.isArabic ? 1 : 2; + GifLoaderDialogUtils.showMyDialog(context); + ClinicListService service = new ClinicListService(); + List projectsListLocal = []; + service.getProjectsList(languageID, context).then((res) { + if (res['MessageStatus'] == 1) { + setState(() { + res['ListProject'].forEach((v) { + projectsListLocal.add(new HospitalsModel.fromJson(v)); + }); + projectsList = projectsListLocal; + }); + GifLoaderDialogUtils.hideDialog(context); + List list = [ + for (int i = 0; i < projectsList.length; i++) RadioSelectionDialogModel(projectsList[i].name! + ' ${projectsList[i].distanceInKilometers} ' + TranslationBase.of(context).km, i), + ]; + showDialog( + context: context, + builder: (cxt) => RadioSelectionDialog( + buttonText: TranslationBase.of(context).confirm, + listData: list, + selectedIndex: _selectedHospitalIndex, + isScrollable: true, + onValueSelected: (index) { + _selectedHospitalIndex = index; + _selectedHospital = projectsList[index]; + openWeCareURL(_selectedHospital!.iD); + // setState(() {}); + }, + ), + ); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + }).catchError((err) { + print(err); + }); + } + + openWeCareURL(int projectID) { + GifLoaderDialogUtils.showMyDialog(context); + ClinicListService service = new ClinicListService(); + service.getWeCareURL(projectID).then((res) { + print(res["Consent_VirtualJurny_Url_GetByProjectIDList"][0]["Url"]); + Uri uri = Uri.parse(res["Consent_VirtualJurny_Url_GetByProjectIDList"][0]["Url"]); + GifLoaderDialogUtils.hideDialog(context); + launchUrl(uri, mode: LaunchMode.inAppWebView); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + AppToast.showErrorToast(message: err.toString()); + }); + } +} + +class Medical { + final String? title; + final String? imagePath; + final String? subTitle; + final Widget? page; + + Medical({this.title, this.imagePath, this.subTitle, this.page}); +} diff --git a/lib/pages/medical/my_admissions_page.dart b/lib/pages/medical/my_admissions_page.dart index ff25884e..956395c4 100644 --- a/lib/pages/medical/my_admissions_page.dart +++ b/lib/pages/medical/my_admissions_page.dart @@ -21,18 +21,18 @@ class _MyAdmissionsPageState extends State { children: [ DoctorCard( name: 'Dr Mohammad Aljammal', - date: 'Feb 14, 2020', + date:DateTime.now(),// 'Feb 14, 2020', profileUrl: 'https://scontent.famm4-1.fna.fbcdn.net/v/t31.0-8/30425660_1862582094040824_7851633779570222226_o.jpg?_nc_cat=101&_nc_sid=09cbfe&_nc_eui2=AeF3TI6D2_tFS5QoQsqyaCKd2zBfzh74hOzbMF_OHviE7PQdLHRwmBoIOiKyWmK9MskOshPjkU73a5EdQMA3dqnV&_nc_ohc=1feou2fDCuIAX_Ra9qB&_nc_ht=scontent.famm4-1.fna&oh=709d34d1c284de1d0aa08ed37b0ac09a&oe=5F3C5ACB', - rat: 3.8, + rating: 3.8, subName: 'Jammal', ), DoctorCard( name: 'Dr Mohammad Aljammal', - date: 'Feb 14, 2020', + date: DateTime.now(),//'Feb 14, 2020', profileUrl: 'https://scontent.famm4-1.fna.fbcdn.net/v/t31.0-8/30425660_1862582094040824_7851633779570222226_o.jpg?_nc_cat=101&_nc_sid=09cbfe&_nc_eui2=AeF3TI6D2_tFS5QoQsqyaCKd2zBfzh74hOzbMF_OHviE7PQdLHRwmBoIOiKyWmK9MskOshPjkU73a5EdQMA3dqnV&_nc_ohc=1feou2fDCuIAX_Ra9qB&_nc_ht=scontent.famm4-1.fna&oh=709d34d1c284de1d0aa08ed37b0ac09a&oe=5F3C5ACB', - rat: 3.8, + rating: 3.8, subName: 'Jammal', ), ], @@ -46,10 +46,10 @@ class _MyAdmissionsPageState extends State { //TODO when we need it }, name: 'Dr Mohammad Aljammal', - date: 'Feb 14, 2020', + date: DateTime.now(),//'Feb 14, 2020', profileUrl: 'https://scontent.famm4-1.fna.fbcdn.net/v/t31.0-8/30425660_1862582094040824_7851633779570222226_o.jpg?_nc_cat=101&_nc_sid=09cbfe&_nc_eui2=AeF3TI6D2_tFS5QoQsqyaCKd2zBfzh74hOzbMF_OHviE7PQdLHRwmBoIOiKyWmK9MskOshPjkU73a5EdQMA3dqnV&_nc_ohc=1feou2fDCuIAX_Ra9qB&_nc_ht=scontent.famm4-1.fna&oh=709d34d1c284de1d0aa08ed37b0ac09a&oe=5F3C5ACB', - rat: 4.8, + rating: 4.8, subName: 'Jammal', ), ), diff --git a/lib/pages/medical/my_invoices/invoice_detail_page.dart b/lib/pages/medical/my_invoices/invoice_detail_page.dart new file mode 100644 index 00000000..767354e2 --- /dev/null +++ b/lib/pages/medical/my_invoices/invoice_detail_page.dart @@ -0,0 +1,307 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; +import 'package:diplomaticquarterapp/models/MyInvoices/DentalInvoiceDetailResponse.dart'; +import 'package:diplomaticquarterapp/models/MyInvoices/GetDentalAppointmentsResponse.dart'; +import 'package:diplomaticquarterapp/models/header_model.dart'; +import 'package:diplomaticquarterapp/services/my_invoice_service/my_invoice_services.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/my_rich_text.dart'; +import 'package:diplomaticquarterapp/widgets/new_design/doctor_header.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class InvoiceDetail extends StatefulWidget { + final DoctorList doctor; + final ListDentalAppointments listDentalAppointments; + final DentalInvoiceDetailResponse dentalInvoiceDetailResponse; + final BuildContext context; + + InvoiceDetail(this.doctor, this.listDentalAppointments, this.dentalInvoiceDetailResponse, this.context); + + @override + _InvoiceDetailState createState() => _InvoiceDetailState(); +} + +class _InvoiceDetailState extends State { + dynamic totalServiceRate = 0; + + dynamic totalDiscount = 0; + + dynamic totalVAT = 0; + + dynamic subTotal = 0; + + dynamic grandTotal = 0; + + late ProjectViewModel projectViewModel; + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + generateInvoiceDetails(); + return AppScaffold( + appBarTitle: widget.doctor.doctorTitle != null ? widget.doctor.doctorTitle.toString() : TranslationBase.of(context).dr + " " + widget.doctor.name.toString(), + isShowAppBar: true, + isShowDecPage: false, + showNewAppBar: true, + showNewAppBarTitle: true, + body: SingleChildScrollView( + child: Container( + child: Column( + children: [ + // DoctorView(doctor: doctor, isLiveCareAppointment: false, isShowFlag: false), + DoctorHeader( + headerModel: HeaderModel( + widget.doctor.name!, + widget.doctor.doctorID!, + widget.doctor.doctorImageURL!, + widget.doctor.speciality??[""], + widget.doctor.clinicName!, + widget.doctor.projectName!, + DateUtil.convertStringToDate(widget.doctor.date), + null, + widget.doctor.nationalityFlagURL != null ? widget.doctor.nationalityFlagURL! : "" , + widget.doctor.doctorRate, + widget.doctor.actualDoctorRate, + widget.doctor.noOfPatientsRate ?? 0, + projectViewModel.user!.emailAddress!, + decimalDoctorRate: widget.doctor.decimalDoctorRate.toString()), + onTap: () { + sendInvoiceEmail(); + }, + ), + Container( + child: Container( + decoration: cardRadius(12), + margin: EdgeInsets.only(left: 16, top: 8, right: 16, bottom: 16), + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Table( + columnWidths: { + 0: FlexColumnWidth(2.0), + 1: FlexColumnWidth(1.5), + 2: FlexColumnWidth(1.5), + 3: FlexColumnWidth(1.5), + }, + children: fullData(context), + ), + ], + ), + ), + ), + ), + Container( + width: double.infinity, + child: Container( + decoration: cardRadius(12), + margin: EdgeInsets.only(left: 16, top: 8, right: 16, bottom: 16), + child: Padding( + padding: const EdgeInsets.all(15.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + margin: EdgeInsets.only(bottom: 10.0), + child: Text(TranslationBase.of(context).cardDetail, style: TextStyle(color: Colors.black, letterSpacing: -0.64, fontSize: 18.0, fontWeight: FontWeight.bold)), + ), + MyRichText( + TranslationBase.of(context).insuranceCompany + ": ", + projectViewModel.isArabic + ? widget.dentalInvoiceDetailResponse.listEInvoiceForDental![0].groupNameN + : widget.dentalInvoiceDetailResponse.listEInvoiceForDental![0].companyName, + projectViewModel.isArabic), + MyRichText( + TranslationBase.of(context).insuranceID + ": ", + widget.dentalInvoiceDetailResponse.listEInvoiceForDental![0].insuranceID != null ? widget.dentalInvoiceDetailResponse.listEInvoiceForDental![0].insuranceID! : "N/A", + projectViewModel.isArabic), + ], + ), + ), + ), + ), + Container( + width: double.infinity, + child: Container( + decoration: cardRadius(12), + margin: EdgeInsets.only(left: 16, top: 8, right: 16, bottom: 16), + child: Padding( + padding: const EdgeInsets.all(15.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + margin: EdgeInsets.only(bottom: 10.0), + child: Text(TranslationBase.of(context).totalBalance, style: TextStyle(letterSpacing: -0.64, color: Colors.black, fontSize: 18.0, fontWeight: FontWeight.bold)), + ), + Container( + width: double.infinity, + padding: EdgeInsets.only(top: 10, bottom: 5), + child: Row( + children: [ + Expanded( + child: _getNormalText(TranslationBase.of(context).discount), + ), + Expanded( + child: _getNormalText(this.totalDiscount.toString(), isBold: true), + ) + ], + ), + ), + mDivider( Color(0xffEFEFEF),), + Container( + width: double.infinity, + padding: EdgeInsets.only(top: 10, bottom: 5), + child: Row( + children: [ + Expanded( + child: _getNormalText(TranslationBase.of(context).totalVAT.toString() + + " (" + + widget.dentalInvoiceDetailResponse.listEInvoiceForDental![0].listConsultation![0].vATPercentage.toString() + + "%): "), + ), + Expanded( + child: _getNormalText(num.tryParse(this.totalVAT.toString())!.toStringAsFixed(2), isBold: true), + ) + ], + ), + ), + mDivider( Color(0xffEFEFEF),), + Container( + width: double.infinity, + padding: EdgeInsets.only(top: 10, bottom: 5), + child: Row( + children: [ + Expanded( + child: _getNormalText(TranslationBase.of(context).total), + ), + Expanded( + child: _getNormalText(this.subTotal.toString(), isBold: true), + ) + ], + ), + ), + mDivider( Color(0xffEFEFEF),), + Container( + width: double.infinity, + padding: EdgeInsets.only(top: 10, bottom: 5), + child: Row( + children: [ + Expanded( + child: _getNormalText(TranslationBase.of(context).paid), + ), + Expanded( + child: _getNormalText(this.grandTotal.toString(), isBold: true), + ) + ], + ), + ), + ], + ), + ), + )), + SizedBox( + height: 100.0, + ), + ], + ), + ), + )); + } + + void generateInvoiceDetails() { + totalServiceRate = 0; + totalDiscount = 0; + totalVAT = 0; + subTotal = 0; + grandTotal = 0; + + List listConsultations = []; + + widget.dentalInvoiceDetailResponse.listEInvoiceForDental![0].listConsultation!.forEach((item) { + var i = listConsultations.indexWhere((x) => x.procedureID == item.procedureID); + if (i <= -1) { + listConsultations.add(item); + } + }); + + listConsultations.forEach((element) { + print(element.procedureID); + this.totalServiceRate += element.total; + this.totalDiscount += element.discountAmount; + this.totalVAT += element.totalVATAmount; + }); + + this.subTotal = this.totalServiceRate - this.totalDiscount; + this.grandTotal = this.subTotal + this.totalVAT; + } + + sendInvoiceEmail() { + GifLoaderDialogUtils.showMyDialog(widget.context); + MyInvoicesService myInvoicesService = new MyInvoicesService(); + + myInvoicesService.sendDentalAppointmentInvoiceEmail(widget.listDentalAppointments.projectID!, widget.listDentalAppointments.appointmentNo!, widget.context).then((res) { + GifLoaderDialogUtils.hideDialog(widget.context); + if (res['MessageStatus'] == 1) { + AppToast.showSuccessToast(message: TranslationBase.of(widget.context).emailSentSuccessfully); + } else { + AppToast.showErrorToast(message: res['ErrorEndUserMessage']); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(widget.context); + print(err); + AppToast.showErrorToast(message: err); + Navigator.of(widget.context).pop(); + }); + } + + List fullData(context) { + List tableRow = []; + + tableRow.add( + TableRow( + children: [ + Utils.tableColumnTitle(TranslationBase.of(context).description), + Utils.tableColumnTitle(TranslationBase.of(context).quantity), + Utils.tableColumnTitle(TranslationBase.of(context).price), + Utils.tableColumnTitle(TranslationBase.of(context).total), + ], + ), + ); + for (int i = 0; i < widget.dentalInvoiceDetailResponse.listEInvoiceForDental![0].listConsultation!.length; i++) { + tableRow.add( + TableRow(children: [ + Utils.tableColumnValue('${widget.dentalInvoiceDetailResponse.listEInvoiceForDental![0].listConsultation![i].procedureName}', + isLast: i == (widget.dentalInvoiceDetailResponse.listEInvoiceForDental![0].listConsultation!.length - 1), mProjectViewModel: projectViewModel), + Utils.tableColumnValue('${widget.dentalInvoiceDetailResponse.listEInvoiceForDental![0].listConsultation![i].quantity}', + isLast: i == (widget.dentalInvoiceDetailResponse.listEInvoiceForDental![0].listConsultation!.length - 1), mProjectViewModel: projectViewModel), + Utils.tableColumnValue('${widget.dentalInvoiceDetailResponse.listEInvoiceForDental![0].listConsultation![i].price.toString()}', + isLast: i == (widget.dentalInvoiceDetailResponse.listEInvoiceForDental![0].listConsultation!.length - 1), mProjectViewModel: projectViewModel), + Utils.tableColumnValue('${widget.dentalInvoiceDetailResponse.listEInvoiceForDental![0].listConsultation![i].total.toString()}', + isLast: i == (widget.dentalInvoiceDetailResponse.listEInvoiceForDental![0].listConsultation!.length - 1), mProjectViewModel: projectViewModel), + ]), + ); + } + return tableRow; + } + + _getNormalText(text, {bool isBold = false}) { + return Text( + text, + style: TextStyle( + fontSize: isBold ? 14 : 12, + letterSpacing: -0.5, + color: isBold ? Colors.black : Colors.grey[700], + fontWeight: FontWeight.w600, + ), + ); + } +} diff --git a/lib/pages/medical/my_invoices/my_invoice_page.dart b/lib/pages/medical/my_invoices/my_invoice_page.dart new file mode 100644 index 00000000..2d287c39 --- /dev/null +++ b/lib/pages/medical/my_invoices/my_invoice_page.dart @@ -0,0 +1,144 @@ +import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart' as DoctorListResponse; +import 'package:diplomaticquarterapp/models/MyInvoices/DentalInvoiceDetailResponse.dart'; +import 'package:diplomaticquarterapp/models/MyInvoices/GetDentalAppointmentsResponse.dart'; +import 'package:diplomaticquarterapp/pages/medical/my_invoices/invoice_detail_page.dart'; +import 'package:diplomaticquarterapp/services/my_invoice_service/my_invoice_services.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/widgets/data_display/medical/doctor_card.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class MyInvoices extends StatefulWidget { + @override + _MyInvoicesState createState() => _MyInvoicesState(); +} + +class _MyInvoicesState extends State { + bool isDataLoaded = false; + GetDentalAppointmentsResponse? getDentalAppointmentsResponse; + DentalInvoiceDetailResponse? dentalInvoiceDetailResponse; + + ProjectViewModel? projectViewModel; + List imagesInfo =[]; + + @override + void initState() { + imagesInfo + .add(ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-invoice/en/0.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-invoice/ar/0.png')); + + WidgetsBinding.instance.addPostFrameCallback((_) { + if (projectViewModel!.isLogin) getDentalAppointments(); + }); + super.initState(); + } + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + return AppScaffold( + appBarTitle: TranslationBase.of(context).myInvoice, + isShowAppBar: true, + isShowDecPage: true, + showNewAppBar: true, + showNewAppBarTitle: true, + imagesInfo: imagesInfo, + body: Container( + child: SingleChildScrollView( + physics: BouncingScrollPhysics(), + child: isDataLoaded + ? Column( + children: [ + ListView.separated( + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + padding: EdgeInsets.only(bottom: 14, top: 14, left: 21, right: 21), + itemBuilder: (context, index) { + return DoctorCard( + onTap: () => openInvoiceDetailsPage(getDentalAppointmentsResponse!.listDentalAppointments![index]), + isInOutPatient: true, + name: TranslationBase.of(context).dr.toString() + " " + (projectViewModel!.isArabic ? getDentalAppointmentsResponse!.listDentalAppointments![index].doctorNameN.toString() : getDentalAppointmentsResponse!.listDentalAppointments![index].doctorName.toString()), + billNo: getDentalAppointmentsResponse!.listDentalAppointments![index].invoiceNo.toString(), + profileUrl: getDentalAppointmentsResponse!.listDentalAppointments![index].doctorImageURL, + subName: getDentalAppointmentsResponse!.listDentalAppointments![index].projectName, + isLiveCareAppointment: false, + date: DateUtil.convertStringToDate(getDentalAppointmentsResponse!.listDentalAppointments![index].appointmentDate!), + isSortByClinic: true, + ); + }, + itemCount: getDentalAppointmentsResponse!.listDentalAppointments!.length, + separatorBuilder: (context, index) => SizedBox(height: 14), + ), + ], + ) + : Container(), + ), + )); + } + + openInvoiceDetailsPage(ListDentalAppointments listDentalAppointments) { + GifLoaderDialogUtils.showMyDialog(context); + MyInvoicesService myInvoicesService = new MyInvoicesService(); + + DoctorListResponse.DoctorList doctor = new DoctorListResponse.DoctorList(); + + doctor.name = projectViewModel!.isArabic ? listDentalAppointments.doctorNameN : listDentalAppointments.doctorName; + doctor.projectName = listDentalAppointments.projectName; + doctor.date = listDentalAppointments.appointmentDate; + doctor.actualDoctorRate = 0; + doctor.doctorImageURL = listDentalAppointments.doctorImageURL; + doctor.projectID = listDentalAppointments.projectID; + doctor.dayName = listDentalAppointments.invoiceNo; + doctor.clinicName = listDentalAppointments.invoiceNo.toString(); + doctor.date = listDentalAppointments.appointmentDate; + doctor.noOfPatientsRate = listDentalAppointments.patientNumber; + doctor.actualDoctorRate = listDentalAppointments.doctorRate; + doctor.decimalDoctorRate = listDentalAppointments.decimalDoctorRate; + doctor.doctorID = listDentalAppointments.doctorID; + + myInvoicesService.getDentalAppointmentInvoice(listDentalAppointments.projectID!, listDentalAppointments.appointmentNo!, listDentalAppointments.invoiceNo!, context).then((res) { + GifLoaderDialogUtils.hideDialog(context); + setState(() { + if (res['MessageStatus'] == 1) { + dentalInvoiceDetailResponse = DentalInvoiceDetailResponse.fromJson(res as Map); + Navigator.push(context, FadePage(page: InvoiceDetail(doctor, listDentalAppointments, dentalInvoiceDetailResponse!, context))); + } else { + AppToast.showErrorToast(message: res['ErrorEndUserMessage']); + } + isDataLoaded = true; + }); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + AppToast.showErrorToast(message: err.toString()); + }); + } + + getDentalAppointments() { + GifLoaderDialogUtils.showMyDialog(context); + MyInvoicesService myInvoicesService = new MyInvoicesService(); + + myInvoicesService.getAllDentalAppointments(0, context).then((res) { + GifLoaderDialogUtils.hideDialog(context); + setState(() { + if (res['MessageStatus'] == 1) { + getDentalAppointmentsResponse = GetDentalAppointmentsResponse.fromJson(res as Map); + } else { + AppToast.showErrorToast(message: res['ErrorEndUserMessage']); + } + isDataLoaded = true; + }); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + AppToast.showErrorToast(message: err); + Navigator.of(context).pop(); + }); + } +} diff --git a/lib/pages/medical/my_trackers/Weight/AddWeightPage.dart b/lib/pages/medical/my_trackers/Weight/AddWeightPage.dart index 71799084..52f8a86b 100644 --- a/lib/pages/medical/my_trackers/Weight/AddWeightPage.dart +++ b/lib/pages/medical/my_trackers/Weight/AddWeightPage.dart @@ -6,35 +6,26 @@ 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/secondary_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/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'; -import 'package:flutter_datetime_picker/flutter_datetime_picker.dart'; +import 'package:flutter_datetime_picker_plus/flutter_datetime_picker_plus.dart'; import 'package:provider/provider.dart'; class AddWeightPage extends StatefulWidget { - final WeightPressureViewModel model; - final bool isUpdate; - final DateTime dayWeightDate; - final int lineItemNo; - final String weightValue; - final String measureTimeSelectedType; - final int weightUnit; + final WeightPressureViewModel? model; + final bool? isUpdate; + final DateTime? dayWeightDate; + final int? lineItemNo; + final String? weightValue; + final String? measureTimeSelectedType; + final int? weightUnit; - AddWeightPage( - {Key key, - this.model, - this.isUpdate = false, - this.dayWeightDate, - this.lineItemNo, - this.weightValue, - this.measureTimeSelectedType, - this.weightUnit}) - : super(key: key); + AddWeightPage({Key? key, this.model, this.isUpdate = false, this.dayWeightDate, this.lineItemNo, this.weightValue, this.measureTimeSelectedType, this.weightUnit}) : super(key: key); @override _AddWeightPageState createState() => _AddWeightPageState(); @@ -44,26 +35,28 @@ class _AddWeightPageState extends State { TextEditingController _weightValueController = TextEditingController(); DateTime dayWeightDate = DateTime.now(); DateTime timeWeightDate = DateTime.now(); - int weightUnit = 1; + int weightUnit = 0; final List measureUnitEnList = [ - 'Kg', 'Pound', + 'Kg', + ]; + final List measureUnitArList = [ + "باوند", + "كيلو جرام", ]; - final List measureUnitArList = ["كيلو جرام", "باوند"]; - String measureTimeSelectedType; + String? measureTimeSelectedType; + bool isButtonDisabled = true; @override void initState() { super.initState(); - if (widget.isUpdate) { - dayWeightDate = widget.dayWeightDate; - timeWeightDate = widget.dayWeightDate; - measureTimeSelectedType = widget.measureTimeSelectedType; - if (measureUnitEnList.contains(widget.measureTimeSelectedType)) - weightUnit = measureUnitEnList.indexOf(widget.measureTimeSelectedType); - else if (measureUnitArList.contains(widget.measureTimeSelectedType)) - weightUnit = measureUnitArList.indexOf(widget.measureTimeSelectedType); - _weightValueController.text = widget.weightValue; + if (widget.isUpdate!) { + dayWeightDate = widget.dayWeightDate!; + timeWeightDate = widget.dayWeightDate!; + measureTimeSelectedType = widget.measureTimeSelectedType!; + weightUnit = widget.weightUnit!; + _weightValueController.text = widget.weightValue!; + validateForm(); } } @@ -73,201 +66,206 @@ class _AddWeightPageState extends State { return AppScaffold( isShowAppBar: true, - appBarTitle: widget.isUpdate - ? TranslationBase.of(context).update - : TranslationBase.of(context).add, - appBarIcons:widget.isUpdate? [ - IconButton( - icon: Icon(Icons.delete), - color: Colors.white, - onPressed: () { - ConfirmDialog dialog = new ConfirmDialog( - context: context, - confirmMessage: 'Remove this measure', - okText: TranslationBase.of(context).ok, - cancelText: TranslationBase.of(context).cancel, - okFunction: () async { - ConfirmDialog.closeAlertDialog(context); + appBarTitle: widget.isUpdate! ? TranslationBase.of(context).update : TranslationBase.of(context).add, + showNewAppBar: true, + showNewAppBarTitle: true, + body: Column( + children: [ + Expanded( + child: ListView( + padding: EdgeInsets.all(21), + physics: BouncingScrollPhysics(), + children: [ + NewTextFields( + hintText: TranslationBase.of(context).weightAdd, + controller: _weightValueController, + keyboardType: TextInputType.number, + onChanged: (value) => validateForm(), + fontWeight: FontWeight.normal, + fontSize: 14, + ), + SizedBox(height: 12), + InkWell( + onTap: () { + List list = [ + RadioSelectionDialogModel(projectViewModel.isArabic ? measureUnitArList[0] : measureUnitEnList[0], 0), + RadioSelectionDialogModel(projectViewModel.isArabic ? measureUnitArList[1] : measureUnitEnList[1], 1), + ]; - 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); - }); + showDialog( + context: context, + builder: (cxt) => RadioSelectionDialog( + listData: list, + selectedIndex: weightUnit, + onValueSelected: (index) { + weightUnit = index; + measureTimeSelectedType = list[index].title; + setState(() {}); + validateForm(); + }, + ), + ); }, - cancelFunction: () => {}); - dialog.showAlertDialog(context); - }, - ) - ]:null, - body: SingleChildScrollView( - physics: BouncingScrollPhysics(), - child: Container( - margin: EdgeInsets.all(15), - child: Column( - children: [ - SizedBox( - height: 15, - ), - NewTextFields( - hintText: TranslationBase.of(context).weightAdd, - controller: _weightValueController, - keyboardType: TextInputType.number, - ), - SizedBox( - height: 8, - ), - InkWell( - onTap: () { - confirmSelectMeasureTimeDialog(projectViewModel.isArabic - ? measureUnitArList - : measureUnitEnList); - }, - 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, - ) - ], + 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: 8, - ), - InkWell( - onTap: () { - DatePicker.showDatePicker( - context, - showTitleActions: true, - minTime: DateTime(DateTime.now().year - 1, 1, 1), - maxTime: DateTime.now(), - onConfirm: (date) { - setState(() { - dayWeightDate = date; - }); - }, - currentTime: dayWeightDate, - 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(() { + dayWeightDate = date; + }); + }, + currentTime: dayWeightDate, + 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(() { - timeWeightDate = date; - }); - }, - currentTime: timeWeightDate, - 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(() { + timeWeightDate = date; + }); + }, + currentTime: timeWeightDate, + 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())], + ), ), ), - ), - ], + 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, + builder: (cxt) => ConfirmWithMessageDialog( + message: TranslationBase.of(context).removeMeasure, + onTap: () async { + 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); + }); + }, + ), + ); + return; + }) + ], + ), + ) + : Container() + ], + ), ), - ), - ), - bottomSheet: Container( - color: Colors.transparent, - width: double.infinity, - height: MediaQuery.of(context).size.width * 0.2, - child: Padding( - padding: const EdgeInsets.all(15.0), - child: SecondaryButton( - loading: widget.model.state == ViewState.BusyLocal, - label: TranslationBase.of(context).save.toUpperCase(), - textColor: Colors.white, - onTap: () { - if (_weightValueController.text.isNotEmpty) { - if (widget.isUpdate) { - GifLoaderDialogUtils.showMyDialog(context); - widget.model.updateWeightResult( - weightDate: '${dayWeightDate.year}-${dayWeightDate.month}-${dayWeightDate.day} ${timeWeightDate.hour}:${timeWeightDate.minute}:00', - weightMeasured: _weightValueController.text.toString(), - weightUnit: weightUnit, - lineItemNo: widget.lineItemNo - ) - .then((value) { - GifLoaderDialogUtils.hideDialog(context); - if (widget.model.state == ViewState.Error) - AppToast.showErrorToast(message: widget.model.error); - else - Navigator.pop(context); - }); - } else - widget.model.addWeightResult( - weightDate: '${dayWeightDate.year}-${dayWeightDate.month}-${dayWeightDate.day} ${timeWeightDate.hour}:${timeWeightDate.minute}:00', - weightMeasured: _weightValueController.text.toString(), - weightUnit: weightUnit, - ) - .then((value) { - GifLoaderDialogUtils.hideDialog(context); - if (widget.model.state == ViewState.Error) - AppToast.showErrorToast(message: widget.model.error); - else - Navigator.pop(context); - }); - } - }), - ), + Container( + color: Colors.white, + padding: EdgeInsets.only(top: 16, bottom: 16, right: 21, left: 21), + child: DefaultButton( + TranslationBase.of(context).save.toUpperCase(), + isButtonDisabled + ? null + : () async { + if (_weightValueController.text.isNotEmpty) { + GifLoaderDialogUtils.showMyDialog(context); + if (widget.isUpdate!) { + widget.model! + .updateWeightResult( + weightDate: '${dayWeightDate.year}-${dayWeightDate.month}-${dayWeightDate.day} ${timeWeightDate.hour}:${timeWeightDate.minute}:00', + weightMeasured: _weightValueController.text.toString(), + weightUnit: weightUnit, + lineItemNo: widget.lineItemNo!) + .then((value) { + GifLoaderDialogUtils.hideDialog(context); + if (widget.model!.state == ViewState.Error) + AppToast.showErrorToast(message: widget.model!.error); + else + Navigator.pop(context); + }); + } else + widget.model + !.addWeightResult( + weightDate: '${dayWeightDate.year}-${dayWeightDate.month}-${dayWeightDate.day} ${timeWeightDate.hour}:${timeWeightDate.minute}:00', + weightMeasured: _weightValueController.text.toString(), + weightUnit: weightUnit, + ) + .then((value) { + GifLoaderDialogUtils.hideDialog(context); + if (widget.model!.state == ViewState.Error) + AppToast.showErrorToast(message: widget.model!.error); + else + Navigator.pop(context); + }); + } + }, + disabledColor: Colors.grey, + ), + ) + ], ), ); } @@ -280,20 +278,15 @@ 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); - }); - }, - ), - ); + void validateForm() { + if (_weightValueController.text.length > 0 && measureTimeSelectedType != null) { + setState(() { + isButtonDisabled = false; + }); + } else { + setState(() { + isButtonDisabled = true; + }); + } } } diff --git a/lib/pages/medical/my_trackers/Weight/WeightHomePage.dart b/lib/pages/medical/my_trackers/Weight/WeightHomePage.dart index c90b29a7..8e15bc6a 100644 --- a/lib/pages/medical/my_trackers/Weight/WeightHomePage.dart +++ b/lib/pages/medical/my_trackers/Weight/WeightHomePage.dart @@ -1,7 +1,8 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/weight_pressure_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; -import 'package:diplomaticquarterapp/pages/medical/my_trackers/widget/TabBarWidget.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; @@ -10,19 +11,20 @@ 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'; + import 'AddWeightPage.dart'; import 'WeightMonthlyPage.dart'; -import 'WeightYeaPage.dart'; import 'WeightWeeklyPage.dart'; +import 'WeightYeaPage.dart'; class WeightHomePage extends StatefulWidget { @override _WeightHomePageState createState() => _WeightHomePageState(); } -class _WeightHomePageState extends State - with SingleTickerProviderStateMixin { - TabController _tabController; +class _WeightHomePageState extends State with SingleTickerProviderStateMixin { + late TabController _tabController; @override void initState() { @@ -38,83 +40,105 @@ class _WeightHomePageState extends State @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); return BaseView( onModelReady: (model) => model.getWeight(), builder: (_, model, w) => AppScaffold( isShowAppBar: true, + isShowDecPage: false, + showNewAppBar: true, + showNewAppBarTitle: true, appBarTitle: TranslationBase.of(context).weight, - appBarIcons: [IconButton( - icon: Icon(Icons.email), - color: Colors.white, - onPressed: () { - showDialog( - context: context, - child: ConfirmSendEmailDialog( - email: model.user.emailAddress, - onTapSendEmail: () async{ - GifLoaderDialogUtils.showMyDialog(context); - model.sendReportByEmail().then((value) { - GifLoaderDialogUtils.hideDialog(context); - if(model.state == ViewState.ErrorLocal){ + backgroundColor: CustomColors.appBackgroudGrey2Color, + appBarIcons: [ + IconButton( + icon: Icon(Icons.email), + color: Colors.white, + onPressed: () { + showDialog( + context: context, + builder: (cxt) => ConfirmSendEmailDialog( + email: model.user!.emailAddress, + onTapSendEmail: () async { + GifLoaderDialogUtils.showMyDialog(context); + model.sendReportByEmail().then((value) { + GifLoaderDialogUtils.hideDialog(context); + if (model.state == ViewState.ErrorLocal) { + AppToast.showErrorToast(message: model.error); + } else { + AppToast.showSuccessToast( + message: TranslationBase.of(context).emailSentSuccessfully, + ); + } + }).catchError((e) { + GifLoaderDialogUtils.hideDialog(context); AppToast.showErrorToast(message: model.error); - }else{ - AppToast.showSuccessToast(message:TranslationBase.of(context).emailSentSuccessfully, ); - } - }).catchError((e){ - GifLoaderDialogUtils.hideDialog(context); - AppToast.showErrorToast(message: model.error); - }); - }, - ), - ); - }, - ),], - baseViewModel: model, - body: Scaffold( - extendBodyBehindAppBar: true, - appBar: TabBarWidget( - tabController: _tabController, - ), - body: Column( - children: [ - Expanded( - child: TabBarView( - physics: BouncingScrollPhysics(), - controller: _tabController, - children: [ - WeightWeeklyPage( - model: model, - ), - WeightMonthlyPage( - model: model, - ), - WeightYearPage( - model: model, - ) - ], + }); + }, ), - ) - ], - ), - floatingActionButton: InkWell( - onTap: () { - Navigator.push(context, FadePage(page: AddWeightPage(model: model,))); + ); }, - child: Container( - width: 55, - height: 55, - decoration: BoxDecoration( - shape: BoxShape.circle, - color: Theme.of(context).primaryColor, + ), + ], + baseViewModel: model, + body: Column( + children: [ + TabBar( + controller: _tabController, + indicatorWeight: 3.0, + indicatorSize: TabBarIndicatorSize.tab, + labelColor: Color(0xff2B353E), + unselectedLabelColor: Color(0xff575757), + labelPadding: EdgeInsets.only(top: 15, bottom: 13, left: 20, right: 20), + labelStyle: TextStyle( + fontFamily: projectViewModel.isArabic ? 'Cairo' : 'Poppins', + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, ), - child: Center( - child: Icon( - Icons.add, - color: Colors.white, - ), + unselectedLabelStyle: TextStyle( + fontFamily: projectViewModel.isArabic ? 'Cairo' : 'Poppins', + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, ), + tabs: [Text(TranslationBase.of(context).weekly), Text(TranslationBase.of(context).monthlyT), Text(TranslationBase.of(context).yearly)], ), + Expanded( + child: TabBarView( + physics: BouncingScrollPhysics(), + controller: _tabController, + children: [ + WeightWeeklyPage( + model: model, + ), + WeightMonthlyPage( + model: model, + ), + WeightYearPage( + model: model, + ) + ], + ), + ) + ], + ), + floatingActionButton: FloatingActionButton( + child: Icon( + Icons.add, + color: Colors.white, ), + backgroundColor: CustomColors.accentColor, + onPressed: () { + Navigator.push( + context, + FadePage( + page: AddWeightPage( + model: model, + ), + ), + ); + }, ), ), ); diff --git a/lib/pages/medical/my_trackers/Weight/WeightMonthlyPage.dart b/lib/pages/medical/my_trackers/Weight/WeightMonthlyPage.dart index 6f64bacb..d890c157 100644 --- a/lib/pages/medical/my_trackers/Weight/WeightMonthlyPage.dart +++ b/lib/pages/medical/my_trackers/Weight/WeightMonthlyPage.dart @@ -1,178 +1,113 @@ -import 'package:diplomaticquarterapp/core/model/my_trakers/blood_pressur/BloodPressureResult.dart'; -import 'package:diplomaticquarterapp/core/model/my_trakers/blood_sugar/DiabtecPatientResult.dart'; -import 'package:diplomaticquarterapp/core/model/my_trakers/chartData/WeekChartDate.dart'; -import 'package:diplomaticquarterapp/core/model/my_trakers/chartData/YearMonthlyChartDate.dart'; -import 'package:diplomaticquarterapp/core/model/my_trakers/weight/WeightMeasurementResult.dart'; +import "package:collection/collection.dart"; import 'package:diplomaticquarterapp/core/viewModels/medical/weight_pressure_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/medical/my_trackers/widget/MonthLineChartCurved.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/charts/app_time_series_chart.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:charts_flutter/flutter.dart' as charts; -import 'package:hexcolor/hexcolor.dart'; import 'package:provider/provider.dart'; class WeightMonthlyPage extends StatelessWidget { - final WeightPressureViewModel model; + final WeightPressureViewModel? model; - const WeightMonthlyPage({ - Key key, + WeightMonthlyPage({ + Key? key, this.model, }) : super(key: key); + List monthlyGroup = []; + late ProjectViewModel projectViewModel; @override Widget build(BuildContext context) { - ProjectViewModel projectViewModel = Provider.of(context); - return AppScaffold( - body: model.weighMonthTimeSeriesData.isEmpty?Container(child: Center(child: Texts(TranslationBase.of(context).noDataAvailable),),):ListView( - children: [ - Container( - width: double.maxFinite, - color: Colors.white, - child: MonthLineChartCurved( - horizontalInterval: 1.0, - title: TranslationBase.of(context).weight, - timeSeries: model.weighMonthTimeSeriesData, - indexes: model.weighMonthTimeSeriesData.length ~/ 5.5, - )), - SizedBox( - height: 12, - ), - Padding( - padding: const EdgeInsets.all(8.0), - child: Texts(TranslationBase.of(context).details), + //if (projectViewModel == null) + projectViewModel = Provider.of(context); + groupData(); + return ListView( + children: [ + Container( + decoration: cardRadius(12), + margin: EdgeInsets.only(left: 16, top: 16, right: 16, bottom: 8), + child: MonthLineChartCurved( + horizontalInterval: 1.0, + title: TranslationBase.of(context).weight, + timeSeries: model!.weighMonthTimeSeriesData.isEmpty ? [TimeSeriesSales3(0, 0.0)] : model!.weighMonthTimeSeriesData, + indexes: model!.weighMonthTimeSeriesData.length ~/ 5.5, ), - Container( - padding: EdgeInsets.all(10), - color: Colors.transparent, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Table( - border: TableBorder.symmetric( - inside: BorderSide(width: 2.0, color: Colors.grey[300]), - ), - children: fullData(context, projectViewModel, model), + ), + 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: Texts(TranslationBase.of(context).details), + ), + Container( + padding: EdgeInsets.all(10), + color: Colors.transparent, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + model!.weighMonthTimeSeriesData.isEmpty + ? Container( + child: Center( + child: Texts(TranslationBase.of(context).noDataAvailable), + ), + ) + : Column(children: [ + for (var monthly in monthlyGroup) + Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ + Container( + width: double.maxFinite, + padding: EdgeInsets.only(top: 10, bottom: 10, left: 5, right: 5), + decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(5)), + child: Texts(monthly[0])), + Table( + columnWidths: { + 0: FlexColumnWidth(2.5), + // 2: FlexColumnWidth(1.8), + }, + children: fullData(context, monthly[1]), + ) + ]) + ]) + ], ), - ], - ), - ) - ], - ), + ) + ], + ), + ), + mHeight(80), + ], ); } - List fullData(BuildContext context, - ProjectViewModel projectViewModel, WeightPressureViewModel model) { + List fullData(BuildContext context, model) { List tableRow = []; tableRow.add( TableRow( children: [ - Container( - decoration: BoxDecoration( - color: Theme.of(context).primaryColor, - borderRadius: BorderRadius.only( - topLeft: projectViewModel.isArabic - ? Radius.circular(0.0) - : Radius.circular(10.0), - topRight: projectViewModel.isArabic - ? Radius.circular(10.0) - : Radius.circular(0.0), - ), - ), - child: Center( - child: Texts( - TranslationBase.of(context).date, - color: Colors.white, - fontSize: 15, - ), - ), - height: 40, - ), - Container( - decoration: BoxDecoration( - color: Theme.of(context).primaryColor, - ), - child: Center( - child: Texts( - TranslationBase.of(context).time, - color: Colors.white, - fontSize: 15, - ), - ), - height: 40), - Container( - decoration: BoxDecoration( - color: Theme.of(context).primaryColor, - borderRadius: BorderRadius.only( - topLeft: projectViewModel.isArabic - ? Radius.circular(10.0) - : Radius.circular(0.0), - topRight: projectViewModel.isArabic - ? Radius.circular(0.0) - : Radius.circular(10.0), - ), - ), - child: Center( - child: Texts( - TranslationBase.of(context).value, - color: Colors.white, - fontSize: 15, - ), - ), - height: 40), + Utils.tableColumnTitle(TranslationBase.of(context).date), + Utils.tableColumnTitle(TranslationBase.of(context).time), + Utils.tableColumnTitle(TranslationBase.of(context).value), ], ), ); - model.monthWeightMeasurementResult.forEach( + model.forEach( (diabtec) { tableRow.add( TableRow( children: [ - Container( - child: Container( - height: 70, - padding: EdgeInsets.all(10), - color: Colors.white, - child: Center( - child: Texts( - '${projectViewModel.isArabic ? DateUtil.getMonthDayYearDateFormattedAr(diabtec.weightDate) : DateUtil.getMonthDayYearDateFormatted(diabtec.weightDate)} ', - textAlign: TextAlign.center, - fontSize: 12, - ), - ), - ), - ), - Container( - height: 70, - padding: EdgeInsets.all(10), - color: Colors.white, - child: Center( - child: Texts( - '${diabtec.weightDate.hour}:${diabtec.weightDate.minute}', - textAlign: TextAlign.center, - fontSize: 12, - ), - ), - ), - Container( - child: Container( - height: 70, - padding: EdgeInsets.all(10), - color: Colors.white, - child: Center( - child: Texts( - '${diabtec.weightMeasured}', - textAlign: TextAlign.center, - fontSize: 12, - ), - ), - ), - ), + Utils.tableColumnValue('${DateUtil.getDayMonthYearDateFormatted(diabtec.weightDate)} ', isCapitable: false, mProjectViewModel: projectViewModel), + Utils.tableColumnValue('${diabtec.weightDate.hour}:${diabtec.weightDate.minute}', isCapitable: false, mProjectViewModel: projectViewModel), + Utils.tableColumnValue('${diabtec.weightMeasured}', isCapitable: false, mProjectViewModel: projectViewModel), ], ), ); @@ -180,4 +115,10 @@ class WeightMonthlyPage extends StatelessWidget { ); return tableRow; } + + groupData() { + monthlyGroup.clear(); + var groupedArray = groupBy(model!.monthWeightMeasurementResult, (obj) => DateUtil.getMonth(obj.weightDate!.month) + ' ' + obj.weightDate!.year.toString()); + groupedArray.entries.forEach((e) => monthlyGroup.add([e.key, e.value])); + } } diff --git a/lib/pages/medical/my_trackers/Weight/WeightWeeklyPage.dart b/lib/pages/medical/my_trackers/Weight/WeightWeeklyPage.dart index 866c2b5b..05cafe04 100644 --- a/lib/pages/medical/my_trackers/Weight/WeightWeeklyPage.dart +++ b/lib/pages/medical/my_trackers/Weight/WeightWeeklyPage.dart @@ -1,17 +1,16 @@ -import 'package:diplomaticquarterapp/core/model/my_trakers/chartData/WeekChartDate.dart'; -import 'package:diplomaticquarterapp/core/model/my_trakers/weight/WeightMeasurementResult.dart'; +import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/weight_pressure_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; -import 'package:diplomaticquarterapp/pages/medical/my_trackers/widget/LineChartCurved.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/charts/app_time_series_chart.dart'; +import 'package:diplomaticquarterapp/widgets/charts/show_chart.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; -import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:charts_flutter/flutter.dart' as charts; -import 'package:hexcolor/hexcolor.dart'; import 'package:provider/provider.dart'; import 'AddWeightPage.dart'; @@ -19,123 +18,74 @@ import 'AddWeightPage.dart'; class WeightWeeklyPage extends StatelessWidget { final WeightPressureViewModel model; - const WeightWeeklyPage({Key key, this.model}) : super(key: key); + WeightWeeklyPage({ Key? key, required this.model}) : super(key: key); + + late ProjectViewModel projectViewModel; @override Widget build(BuildContext context) { - ProjectViewModel projectViewModel = Provider.of(context); - - return AppScaffold( - body: model.weightWeekTimeSeriesData.isEmpty?Container(child: Center(child: Texts(TranslationBase.of(context).noDataAvailable),),):ListView( - children: [ - Container( - margin: EdgeInsets.only(top: 12, left: 8, right: 8), - color: Colors.white, - child: LineChartCurved( - horizontalInterval: 1.0, - title: TranslationBase.of(context).weight, - timeSeries: model.weightWeekTimeSeriesData, - indexes: model.weightWeekTimeSeriesData.length ~/ 5.5, - ), + ///if (projectViewModel == null) + projectViewModel = Provider.of(context); + return ListView( + children: [ + Container( + decoration: cardRadius(12), + margin: EdgeInsets.only(left: 16, top: 16, right: 16, bottom: 8), + child: ShowChart( + title: TranslationBase.of(context).weight, + timeSeries: model.weightWeekTimeSeriesData.isEmpty ? [TimeSeriesSales2(DateTime.now(), 0.0)] : model.weightWeekTimeSeriesData, + indexes: model.weightWeekTimeSeriesData.length ~/ 5.5 ?? 0, + horizontalInterval: 2, ), - SizedBox( - height: 12, - ), - Padding( - padding: const EdgeInsets.all(8.0), - child: Texts(TranslationBase.of(context).details), - ), - Container( - padding: EdgeInsets.all(10), - color: Colors.transparent, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Table( - border: TableBorder.symmetric( - inside: BorderSide(width: 2.0, color: Colors.grey[300]), - ), - children: fullData(context, projectViewModel, model), + ), + 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: Texts(TranslationBase.of(context).details), + ), + Container( + padding: EdgeInsets.all(10), + color: Colors.transparent, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + model.weightWeekTimeSeriesData.isEmpty + ? Container( + child: Center( + child: Texts(TranslationBase.of(context).noDataAvailable), + ), + ) + : Table( + columnWidths: { + 0: FlexColumnWidth(2.5), + }, + children: fullData(context, model), + ), + ], ), - ], - ), - ) - ], - ), + ) + ], + ), + ), + mHeight(80), + ], ); } - List fullData(BuildContext context, - ProjectViewModel projectViewModel, WeightPressureViewModel model) { + List fullData(BuildContext context, WeightPressureViewModel model) { List tableRow = []; tableRow.add( TableRow( children: [ - Container( - decoration: BoxDecoration( - color: Theme.of(context).primaryColor, - borderRadius: BorderRadius.only( - topLeft: projectViewModel.isArabic - ? Radius.circular(0.0) - : Radius.circular(10.0), - topRight: projectViewModel.isArabic - ? Radius.circular(10.0) - : Radius.circular(0.0), - ), - ), - child: Center( - child: Texts( - TranslationBase.of(context).date, - color: Colors.white, - fontSize: 15, - ), - ), - height: 40, - ), - Container( - decoration: BoxDecoration( - color: Theme.of(context).primaryColor, - ), - child: Center( - child: Texts( - TranslationBase.of(context).time, - color: Colors.white, - fontSize: 15, - ), - ), - height: 40), - Container( - decoration: BoxDecoration( - color: Theme.of(context).primaryColor, - ), - child: Center( - child: Texts( - TranslationBase.of(context).value, - color: Colors.white, - fontSize: 15, - ), - ), - height: 40), - Container( - decoration: BoxDecoration( - color: Theme.of(context).primaryColor, - borderRadius: BorderRadius.only( - topLeft: projectViewModel.isArabic - ? Radius.circular(10.0) - : Radius.circular(0.0), - topRight: projectViewModel.isArabic - ? Radius.circular(0.0) - : Radius.circular(10.0), - ), - ), - child: Center( - child: Texts( - TranslationBase.of(context).edit, - color: Colors.white, - fontSize: 15, - ), - ), - height: 40), + Utils.tableColumnTitle(TranslationBase.of(context).date), + Utils.tableColumnTitle(TranslationBase.of(context).time), + Utils.tableColumnTitle(TranslationBase.of(context).measured), + Utils.tableColumnTitle(TranslationBase.of(context).edit), ], ), ); @@ -144,72 +94,48 @@ class WeightWeeklyPage extends StatelessWidget { tableRow.add( TableRow( children: [ - Container( - child: Container( - height: 70, - padding: EdgeInsets.all(10), - color: Colors.white, - child: Center( - child: Texts( - '${projectViewModel.isArabic ? DateUtil.getMonthDayYearDateFormattedAr(diabtec.weightDate) : DateUtil.getMonthDayYearDateFormatted(diabtec.weightDate)} ', - textAlign: TextAlign.center, - fontSize: 12, - ), - ), - ), - ), - Container( - height: 70, - padding: EdgeInsets.all(10), - color: Colors.white, - child: Center( - child: Texts( - '${diabtec.weightDate.hour}:${diabtec.weightDate.minute}', - textAlign: TextAlign.center, - fontSize: 12, - ), - ), - ), - Container( - child: Container( - height: 70, - padding: EdgeInsets.all(10), - color: Colors.white, - child: Center( - child: Texts( - '${diabtec.weightMeasured}', - textAlign: TextAlign.center, - fontSize: 12, - ), - ), - ), - ), - InkWell( - onTap: () { - Navigator.push( - context, - FadePage( - page: AddWeightPage( - isUpdate: true, - dayWeightDate: diabtec.weightDate, - measureTimeSelectedType: 'Kg', - weightValue: diabtec.weightMeasured.toString(), - lineItemNo: diabtec.lineItemNo, - weightUnit: int.parse(diabtec.unit), - model: model, + Utils.tableColumnValue('${DateUtil.getDayMonthYearDateFormatted(diabtec.weightDate!)} ', isCapitable: false, mProjectViewModel: projectViewModel), + Utils.tableColumnValue('${diabtec.weightDate!.hour}:${diabtec.weightDate!.minute}', isCapitable: false, mProjectViewModel: projectViewModel), + Utils.tableColumnValue('${diabtec.weightMeasured}', isCapitable: false, mProjectViewModel: projectViewModel), + Column(crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ + SizedBox(height: 12), + Container( + child: InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: AddWeightPage( + isUpdate: true, + dayWeightDate: diabtec.weightDate, + measureTimeSelectedType: diabtec.unit == "1" ? 'Kg' : 'Pound', + weightValue: diabtec.weightMeasured.toString(), + lineItemNo: diabtec.lineItemNo, + weightUnit: int.parse(diabtec.unit), + model: model, + ), + ), + ).then((value) { + if (model.weekWeightMeasurementResult.isEmpty) { + model.weightWeekTimeSeriesData.clear(); + } + }); + }, + child: Container( + child: Icon( + Icons.edit, + color: Color(0xff575757), ), ), - ); - }, - child: Container( - height: 70, - padding: EdgeInsets.all(10), - color: Colors.white, - child: Center( - child: Icon(Icons.edit), ), ), - ), + SizedBox(height: 6), + Divider( + height: 1, + color: Color(0xffEFEFEF), + thickness: 1, + ) + ]), ], ), ); diff --git a/lib/pages/medical/my_trackers/Weight/WeightYeaPage.dart b/lib/pages/medical/my_trackers/Weight/WeightYeaPage.dart index 7fa03819..a79eb958 100644 --- a/lib/pages/medical/my_trackers/Weight/WeightYeaPage.dart +++ b/lib/pages/medical/my_trackers/Weight/WeightYeaPage.dart @@ -1,177 +1,111 @@ -import 'package:diplomaticquarterapp/core/model/my_trakers/blood_pressur/BloodPressureResult.dart'; -import 'package:diplomaticquarterapp/core/model/my_trakers/blood_sugar/DiabtecPatientResult.dart'; -import 'package:diplomaticquarterapp/core/model/my_trakers/chartData/WeekChartDate.dart'; -import 'package:diplomaticquarterapp/core/model/my_trakers/weight/WeightMeasurementResult.dart'; +import "package:collection/collection.dart"; import 'package:diplomaticquarterapp/core/viewModels/medical/weight_pressure_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/medical/my_trackers/widget/LineChartCurved.dart'; +import 'package:diplomaticquarterapp/theme/colors.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/charts/app_time_series_chart.dart'; +import 'package:diplomaticquarterapp/widgets/charts/show_chart.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:charts_flutter/flutter.dart' as charts; -import 'package:hexcolor/hexcolor.dart'; import 'package:provider/provider.dart'; class WeightYearPage extends StatelessWidget { final WeightPressureViewModel model; - - const WeightYearPage({Key key, this.model, }) - : super(key: key); - + WeightYearPage({ + Key? key, + required this.model, + }) : super(key: key); + List monthlyGroup = []; + ProjectViewModel? projectViewModel; @override Widget build(BuildContext context) { - ProjectViewModel projectViewModel = Provider.of(context); - return AppScaffold( - body: model.weightYearTimeSeriesData.isEmpty ? Container(child: Center(child: Texts(TranslationBase.of(context).noDataAvailable),),) : ListView( - children: [ - Container( - width: double.maxFinite, - color: Colors.white, - child: LineChartCurved( - horizontalInterval: 2.0, - title: TranslationBase.of(context).weight, - timeSeries: model.weightYearTimeSeriesData, - indexes: model.weightYearTimeSeriesData.length ~/ 5.5, - ) - ), - SizedBox( - height: 12, - ), - Padding( + if (projectViewModel == null) projectViewModel = Provider.of(context); + groupData(); + return ListView( + children: [ + Container( + decoration: cardRadius(12), + margin: EdgeInsets.only(left: 16, top: 16, right: 16, bottom: 8), + child: ShowChart( + horizontalInterval: 2.0, + title: TranslationBase.of(context).weight, + timeSeries: model.weightYearTimeSeriesData.isEmpty ? [TimeSeriesSales2(DateTime.now(), 0.0)] : model.weightYearTimeSeriesData, + indexes: model.weightYearTimeSeriesData.length ~/ 5.5, + )), + + 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: Texts(TranslationBase.of(context).details), ), - Container( - padding: EdgeInsets.all(10), - color: Colors.transparent, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Table( - border: TableBorder.symmetric( - inside: BorderSide(width: 2.0, color: Colors.grey[300]), - ), - children: fullData(context, projectViewModel, model), - ), - ], - ), - ) - ], - ), + Container( + padding: EdgeInsets.all(10), + color: Colors.transparent, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + model.weightYearTimeSeriesData.isEmpty + ? Container( + child: Center( + child: Texts(TranslationBase.of(context).noDataAvailable), + ), + ) + : Column(children: [ + for (var monthly in monthlyGroup) + Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ + Container( + width: double.maxFinite, + padding: EdgeInsets.only(top: 10, bottom: 10, left: 5, right: 5), + decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(5)), + child: Texts(monthly[0])), + Table( + columnWidths: { + 0: FlexColumnWidth(2.5), + }, + children: fullData(context, monthly[1]), + ) + ]) + ]), + ], + ), + )], + ), + ), + mHeight(80), + ], ); } - List fullData(BuildContext context, - ProjectViewModel projectViewModel, WeightPressureViewModel model) { + List fullData(BuildContext context, model) { List tableRow = []; tableRow.add( TableRow( children: [ - Container( - decoration: BoxDecoration( - color: Theme.of(context).primaryColor, - borderRadius: BorderRadius.only( - topLeft: projectViewModel.isArabic - ? Radius.circular(0.0) - : Radius.circular(10.0), - topRight: projectViewModel.isArabic - ? Radius.circular(10.0) - : Radius.circular(0.0), - ), - ), - child: Center( - child: Texts( - TranslationBase.of(context).date, - color: Colors.white, - fontSize: 15, - ), - ), - height: 40, - ), - Container( - decoration: BoxDecoration( - color: Theme.of(context).primaryColor, - ), - child: Center( - child: Texts( - TranslationBase.of(context).time, - color: Colors.white, - fontSize: 15, - ), - ), - height: 40), - Container( - decoration: BoxDecoration( - color: Theme.of(context).primaryColor, - borderRadius: BorderRadius.only( - topLeft: projectViewModel.isArabic - ? Radius.circular(10.0) - : Radius.circular(0.0), - topRight: projectViewModel.isArabic - ? Radius.circular(0.0) - : Radius.circular(10.0), - ), - ), - child: Center( - child: Texts( - TranslationBase.of(context).value, - color: Colors.white, - fontSize: 15, - ), - ), - height: 40), + Utils.tableColumnTitle(TranslationBase.of(context).date), + Utils.tableColumnTitle(TranslationBase.of(context).time), + Utils.tableColumnTitle(TranslationBase.of(context).value), ], ), ); - model.yearWeightMeasurementResult.forEach( - (diabtec) { + model.forEach( + (diabtec) { tableRow.add( TableRow( children: [ - Container( - child: Container( - height: 70, - padding: EdgeInsets.all(10), - color: Colors.white, - child: Center( - child: Texts( - '${projectViewModel.isArabic ? DateUtil.getMonthDayYearDateFormattedAr(diabtec.weightDate) : DateUtil.getMonthDayYearDateFormatted(diabtec.weightDate)} ', - textAlign: TextAlign.center, - fontSize: 12, - ), - ), - ), - ), - Container( - height: 70, - padding: EdgeInsets.all(10), - color: Colors.white, - child: Center( - child: Texts( - '${diabtec.weightDate.hour}:${diabtec.weightDate.minute}', - textAlign: TextAlign.center, - fontSize: 12, - ), - ), - ), - Container( - child: Container( - height: 70, - padding: EdgeInsets.all(10), - color: Colors.white, - child: Center( - child: Texts( - '${diabtec.weightMeasured}', - textAlign: TextAlign.center, - fontSize: 12, - ), - ), - ), - ), + Utils.tableColumnValue('${DateUtil.getDayMonthYearDateFormatted(diabtec.weightDate)} ', + isCapitable: false, mProjectViewModel: projectViewModel!), + Utils.tableColumnValue('${diabtec.weightDate.hour}:${diabtec.weightDate.minute}', isCapitable: false, mProjectViewModel: projectViewModel!), + Utils.tableColumnValue('${diabtec.weightMeasured}', isCapitable: false, mProjectViewModel: projectViewModel!), ], ), ); @@ -179,4 +113,10 @@ class WeightYearPage extends StatelessWidget { ); return tableRow; } + + groupData() { + monthlyGroup.clear(); + var groupedArray = groupBy(model.yearWeightMeasurementResult.reversed, (obj) => DateUtil.getMonth(obj.weightDate!.month) + ' ' + obj.weightDate!.year.toString()); + groupedArray.entries.forEach((e) => monthlyGroup.add([e.key, e.value])); + } } diff --git a/lib/pages/medical/my_trackers/blood_pressure/AddBloodPressurePage.dart b/lib/pages/medical/my_trackers/blood_pressure/AddBloodPressurePage.dart index 678ef7dc..780f94f5 100644 --- a/lib/pages/medical/my_trackers/blood_pressure/AddBloodPressurePage.dart +++ b/lib/pages/medical/my_trackers/blood_pressure/AddBloodPressurePage.dart @@ -6,34 +6,28 @@ 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/secondary_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'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_datetime_picker/flutter_datetime_picker.dart'; +import 'package:flutter_datetime_picker_plus/flutter_datetime_picker_plus.dart'; import 'package:provider/provider.dart'; class AddBloodPressurePage extends StatefulWidget { - final DateTime bloodSugarDate; - final String measureTimeSelectedType; - final bool isUpdate; - final int lineItemNo; - final String bloodSystolicValue; - final String bloodDiastolicValue; - final BloodPressureViewMode model; + final DateTime? bloodSugarDate; + final String? measureTimeSelectedType; + final bool? isUpdate; + final int? lineItemNo; + final int? measuredArm; + final String? bloodSystolicValue; + final String? bloodDiastolicValue; + final BloodPressureViewMode? model; const AddBloodPressurePage( - {Key key, - this.bloodSugarDate, - this.measureTimeSelectedType, - this.isUpdate=false, - this.lineItemNo, - this.model, - this.bloodSystolicValue, - this.bloodDiastolicValue}) + {Key? key, this.bloodSugarDate, this.measureTimeSelectedType, this.isUpdate = false, this.lineItemNo, this.measuredArm, this.model, this.bloodSystolicValue, this.bloodDiastolicValue}) : super(key: key); @override @@ -42,34 +36,28 @@ class AddBloodPressurePage extends StatefulWidget { class _AddBloodPressurePageState extends State { TextEditingController _bloodSystolicValueController = TextEditingController(); - TextEditingController _bloodDiastolicValueController = - TextEditingController(); + TextEditingController _bloodDiastolicValueController = TextEditingController(); DateTime bloodSugarDate = DateTime.now(); DateTime timeSugarDate = DateTime.now(); - int measuredArm = 1; - final List measureTimeEnList = [ - 'Left', - 'Right', - ]; - final List measureTimeArList = [ - 'الذراع الأيسر', - 'الذراع الأيمن', - ]; + int measuredArm = 0; + bool isButtonDisabled = true; + final List measureTimeEnList = ['Left Arm', 'Right Arm']; + final List measureTimeArList = ['الذراع الأيسر', 'الذراع الأيمن']; String measureTimeSelectedType = 'Left Arm'; @override void initState() { super.initState(); - if (widget.isUpdate) { - bloodSugarDate = widget.bloodSugarDate; - bloodSugarDate = widget.bloodSugarDate; - measureTimeSelectedType = widget.measureTimeSelectedType; - if (measureTimeEnList.contains(widget.measureTimeSelectedType)) - measuredArm = measureTimeEnList.indexOf(widget.measureTimeSelectedType); - else if (measureTimeArList.contains(widget.measureTimeSelectedType)) - measuredArm = measureTimeArList.indexOf(widget.measureTimeSelectedType); - _bloodSystolicValueController.text = widget.bloodSystolicValue; - _bloodDiastolicValueController.text = widget.bloodDiastolicValue; + if (widget.isUpdate!) { + bloodSugarDate = widget.bloodSugarDate!; + bloodSugarDate = widget.bloodSugarDate!; + measureTimeSelectedType = widget.measureTimeSelectedType!; + measuredArm = widget.measuredArm!; + if (measuredArm > 1) measuredArm = measuredArm - 1; + + _bloodSystolicValueController.text = widget.bloodSystolicValue!; + _bloodDiastolicValueController.text = widget.bloodDiastolicValue!; + validateForm(); } } @@ -79,199 +67,199 @@ class _AddBloodPressurePageState extends State { return AppScaffold( isShowAppBar: true, - appBarTitle: widget.isUpdate - ? TranslationBase.of(context).update - : TranslationBase.of(context).add, - appBarIcons: widget.isUpdate?[ - IconButton( - icon: Icon(Icons.delete), - color: Colors.white, - onPressed: () { - ConfirmDialog dialog = new ConfirmDialog( - context: context, - confirmMessage: 'Remove this measure', - okText: TranslationBase.of(context).ok, - cancelText: TranslationBase.of(context).cancel, - okFunction: () async { - ConfirmDialog.closeAlertDialog(context); + appBarTitle: widget.isUpdate! ? TranslationBase.of(context).update : TranslationBase.of(context).add, + showNewAppBar: true, + showNewAppBarTitle: true, + body: Column( + children: [ + Expanded( + child: ListView( + physics: BouncingScrollPhysics(), + padding: EdgeInsets.all(21), + children: [ + NewTextFields( + hintText: TranslationBase.of(context).systolicAdd, + controller: _bloodSystolicValueController, + keyboardType: TextInputType.number, + maxLength: 3, + onChanged: (value) => validateForm(), + fontWeight: FontWeight.normal, + fontSize: 14, + ), + SizedBox(height: 12), + NewTextFields( + hintText: TranslationBase.of(context).diastolicAdd, + controller: _bloodDiastolicValueController, + keyboardType: TextInputType.number, + maxLength: 3, + onChanged: (value) => validateForm(), + fontWeight: FontWeight.normal, + fontSize: 14, + ), + SizedBox(height: 12), + InkWell( + onTap: () { + List list = [ + RadioSelectionDialogModel(projectViewModel.isArabic ? measureTimeArList[0] : measureTimeEnList[0], 0), + RadioSelectionDialogModel(projectViewModel.isArabic ? measureTimeArList[1] : measureTimeEnList[1], 1), + ]; - GifLoaderDialogUtils.showMyDialog(context); - widget.model - .deactivateDiabeticStatus(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); - }, - ) - ]:null, - body: SingleChildScrollView( - physics: BouncingScrollPhysics(), - child: Container( - margin: EdgeInsets.all(15), - child: Column( - children: [ - SizedBox( - height: 15, - ), - NewTextFields( - hintText: TranslationBase.of(context).systolicAdd, - controller: _bloodSystolicValueController, - keyboardType: TextInputType.number, - ), - SizedBox( - height: 8, - ), - NewTextFields( - hintText: TranslationBase.of(context).diastolicAdd, - controller: _bloodDiastolicValueController, - keyboardType: TextInputType.number, - ), - SizedBox( - height: 8, - ), - InkWell( - onTap: () { - confirmSelectMeasureTimeDialog(projectViewModel.isArabic - ? measureTimeEnList - : measureTimeArList); - }, - 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), - Icon( - Icons.arrow_drop_down, - color: Colors.grey, - ) - ], + showDialog( + context: context, + builder: (cxt) => RadioSelectionDialog( + listData: list, + selectedIndex: measuredArm, + onValueSelected: (index) { + measuredArm = index; + measureTimeSelectedType = list[index].title; + setState(() {}); + validateForm(); + }, + ), + ); + }, + 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(projectViewModel.isArabic ? measureTimeArList[measuredArm] : measureTimeEnList[measuredArm]), + 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; - }, - ); + 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); }, - 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()), - ], + 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; - }, - ); + SizedBox(height: 12), + InkWell( + onTap: () { + DatePicker.showTimePicker(context, showTitleActions: true, onConfirm: (date) { + setState( + () { + timeSugarDate = date; + }, + ); + }, currentTime: timeSugarDate, locale: projectViewModel.localeType); }, - 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()) - ], + 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())], + ), ), ), - ), - ], - ), - ), - ), - bottomSheet: Container( - color: Colors.transparent, - width: double.infinity, - height: MediaQuery.of(context).size.width * 0.2, - child: Padding( - padding: const EdgeInsets.all(15.0), - child: SecondaryButton( - loading: widget.model.state == ViewState.BusyLocal, - label: TranslationBase.of(context).save.toUpperCase(), - textColor: Colors.white, - onTap: () async { - if (_bloodSystolicValueController.text.isNotEmpty && - _bloodDiastolicValueController.text.isNotEmpty) { - GifLoaderDialogUtils.showMyDialog(context); + 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( + context: context, + confirmMessage: TranslationBase.of(context).removeMeasure, + okText: TranslationBase.of(context).ok, + cancelText: TranslationBase.of(context).cancel, + okFunction: () async { + ConfirmDialog.closeAlertDialog(context); - widget.model.addORUpdateDiabtecResult( - isUpdate: widget.isUpdate, - bloodPressureDate: - '${bloodSugarDate.year}-${bloodSugarDate.month}-${bloodSugarDate.day} ${timeSugarDate.hour}:${timeSugarDate.minute}:00', - diastolicPressure: - _bloodDiastolicValueController.text.toString(), - systolicePressure: - _bloodSystolicValueController.text.toString(), - measuredArm: measuredArm, - ).then((value) { - GifLoaderDialogUtils.hideDialog(context); - if(widget.model.state == ViewState.BusyLocal) - AppToast.showErrorToast(message: widget.model.error); - else - Navigator.pop(context); -; - }).catchError((e){ - GifLoaderDialogUtils.hideDialog(context); - AppToast.showErrorToast(message: widget.model.error); - }); - } - }), - ), + GifLoaderDialogUtils.showMyDialog(context); + widget.model!.deactivateDiabeticStatus(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); + }) + ], + )) + : Container() + ], + ), + ), + Container( + color: Colors.white, + padding: EdgeInsets.only(top: 16, bottom: 16, right: 21, left: 21), + child: DefaultButton( + TranslationBase.of(context).save, + isButtonDisabled + ? null + : () async { + if (_bloodSystolicValueController.text.isNotEmpty && _bloodDiastolicValueController.text.isNotEmpty) { + GifLoaderDialogUtils.showMyDialog(context); + widget.model + !.addORUpdateDiabtecResult( + isUpdate: widget.isUpdate!, + bloodPressureDate: '${bloodSugarDate.year}-${bloodSugarDate.month}-${bloodSugarDate.day} ${timeSugarDate.hour}:${timeSugarDate.minute}:00', + diastolicPressure: _bloodDiastolicValueController.text.toString(), + systolicePressure: _bloodSystolicValueController.text.toString(), + measuredArm: (measuredArm), + lineItemNo: widget.lineItemNo) + .then((value) { + GifLoaderDialogUtils.hideDialog(context); + if (widget.model!.state == ViewState.BusyLocal) + AppToast.showErrorToast(message: widget.model!.error); + else + Navigator.pop(context); + ; + }).catchError((e) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: widget.model!.error); + }); + } + }, + disabledColor: Colors.grey, + ), + ) + ], ), ); } @@ -284,20 +272,33 @@ class _AddBloodPressurePageState extends State { return " ${timeSugarDate.hour}:${timeSugarDate.minute}"; } - void confirmSelectMeasureTimeDialog(List list) { - showDialog( - context: context, - child: RadioStringDialog( - radioList: list, - title: 'Select the Arm', - selectedValue: measureTimeSelectedType, - onValueSelected: (value) { - setState(() { - measureTimeSelectedType = value; - measuredArm = list.indexOf(value); - }); - }, - ), - ); + void validateForm() { + print("_bloodSystolicValueController " + _bloodSystolicValueController.text.length.toString()); + if (_bloodSystolicValueController.text.length > 0 && _bloodDiastolicValueController.text.length > 0) { + setState(() { + isButtonDisabled = false; + }); + } else { + setState(() { + isButtonDisabled = true; + }); + } + // if(measureTimeSelectedType == 'Left Arm'){ + // setState(() { + // isButtonDisabled = false; + // }); + // }else if(_bloodSystolicValueController.text.length < 0){ + // setState(() { + // isButtonDisabled = false; + // }); + // }else if(_bloodDiastolicValueController.text.length < 0){ + // setState(() { + // isButtonDisabled = false; + // }); + // }else{ + // setState(() { + // isButtonDisabled = true; + // }); + // } } } diff --git a/lib/pages/medical/my_trackers/blood_pressure/BloodPressureHomePage.dart b/lib/pages/medical/my_trackers/blood_pressure/BloodPressureHomePage.dart index 723871cb..d7230cdd 100644 --- a/lib/pages/medical/my_trackers/blood_pressure/BloodPressureHomePage.dart +++ b/lib/pages/medical/my_trackers/blood_pressure/BloodPressureHomePage.dart @@ -1,15 +1,18 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/blood_pressure_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; -import 'package:diplomaticquarterapp/pages/medical/my_trackers/widget/TabBarWidget.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/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/confirm_send_email_dialog.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'; + import 'AddBloodPressurePage.dart'; import 'BloodPressureMonthly.dart'; import 'BloodPressureYeaPage.dart'; @@ -20,9 +23,8 @@ class BloodPressureHomePage extends StatefulWidget { _BloodPressureHomePageState createState() => _BloodPressureHomePageState(); } -class _BloodPressureHomePageState extends State - with SingleTickerProviderStateMixin { - TabController _tabController; +class _BloodPressureHomePageState extends State with SingleTickerProviderStateMixin { + late TabController _tabController; @override void initState() { @@ -38,77 +40,116 @@ class _BloodPressureHomePageState extends State @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); return BaseView( onModelReady: (model) => model.getBloodPressure(), builder: (_, model, w) => AppScaffold( isShowAppBar: true, appBarTitle: TranslationBase.of(context).bloodPressure, + showNewAppBar: true, + showNewAppBarTitle: true, baseViewModel: model, - appBarIcons: [IconButton( - icon: Icon(Icons.email), - color: Colors.white, - onPressed: () { - showDialog( - context: context, - child: ConfirmSendEmailDialog( - email: model.user.emailAddress, - onTapSendEmail: () async{ - GifLoaderDialogUtils.showMyDialog(context); - model.sendReportByEmail().then((value) { - GifLoaderDialogUtils.hideDialog(context); - if(model.state == ViewState.ErrorLocal){ - AppToast.showErrorToast(message: model.error); - }else{ - AppToast.showSuccessToast(message:TranslationBase.of(context).emailSentSuccessfully, ); - } - }).catchError((e){ - GifLoaderDialogUtils.hideDialog(context); - AppToast.showErrorToast(message: model.error); - }); - }, + body: Column( + children: [ + TabBar( + controller: _tabController, + indicatorWeight: 3.0, + indicatorSize: TabBarIndicatorSize.tab, + labelColor: Color(0xff2B353E), + unselectedLabelColor: Color(0xff575757), + labelPadding: EdgeInsets.only(top: 15, bottom: 13, left: 20, right: 20), + labelStyle: TextStyle( + fontFamily: projectViewModel.isArabic ? 'Cairo' : 'Poppins', + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, ), - ); - }, - ),], - body: Scaffold( - extendBodyBehindAppBar: true, - appBar: TabBarWidget(tabController: _tabController,), - body: Column( - children: [ - Expanded( - child: TabBarView( - physics: BouncingScrollPhysics(), - controller: _tabController, - children: [ - BloodPressureWeeklyPage( - model: model, - ), - BloodPressureMonthlyPage( - model: model, - ), - BloodPressureYearPage( - model: model, - ) - ], - ), - ) - ], - ), - floatingActionButton: InkWell( - onTap: () { - Navigator.push(context, FadePage(page: AddBloodPressurePage(model: model,))); - }, - child: Container( - width: 55, - height: 55, - decoration: BoxDecoration( - shape: BoxShape.circle, color: Theme.of(context).primaryColor), - child: Center( - child: Icon( - Icons.add, - color: Colors.white, - ), + unselectedLabelStyle: TextStyle( + fontFamily: projectViewModel.isArabic ? 'Cairo' : 'Poppins', + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, ), + tabs: [Text(TranslationBase.of(context).weekly), Text(TranslationBase.of(context).monthlyT), Text(TranslationBase.of(context).yearly)], + ), + Expanded( + child: TabBarView( + physics: BouncingScrollPhysics(), + controller: _tabController, + children: [ + BloodPressureWeeklyPage( + model: model, + ), + BloodPressureMonthlyPage( + model: model, + ), + BloodPressureYearPage( + model: model, + ) + ], + ), + ) + ], + ), + floatingActionButton: Stack(children: [ + Positioned( + bottom: 60, + right: projectViewModel.isArabic ? MediaQuery.of(context).size.width * .85 : 0, + child: InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: AddBloodPressurePage( + model: model, + ))).then((value) { + model.getBloodPressure(); + }); + }, + child: Container( + width: 50, + height: 50, + decoration: BoxDecoration(shape: BoxShape.circle, color: Theme.of(context).primaryColor), + child: Center( + child: Icon( + Icons.add, + color: Colors.white, + ), + )), + )) + ]), + bottomSheet: Container( + color: Theme.of(context).scaffoldBackgroundColor, + child: Padding( + padding: const EdgeInsets.all(12.0), + child: DefaultButton( + TranslationBase.of(context).sendEmail, + () { + showDialog( + context: context, + builder: (cxt) => ConfirmSendEmailDialog( + email: model.user!.emailAddress, + onTapSendEmail: () async { + GifLoaderDialogUtils.showMyDialog(context); + model.sendReportByEmail().then((value) { + GifLoaderDialogUtils.hideDialog(context); + if (model.state == ViewState.ErrorLocal) { + AppToast.showErrorToast(message: model.error); + } else { + AppToast.showSuccessToast( + message: TranslationBase.of(context).emailSentSuccessfully, + ); + } + }).catchError((e) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: model.error); + }); + }, + ), + ); + }, + // label: TranslationBase.of(context).sendEmail, + // backgroundColor: Colors.red[900], ), ), ), diff --git a/lib/pages/medical/my_trackers/blood_pressure/BloodPressureMonthly.dart b/lib/pages/medical/my_trackers/blood_pressure/BloodPressureMonthly.dart index 04853689..1eabcce2 100644 --- a/lib/pages/medical/my_trackers/blood_pressure/BloodPressureMonthly.dart +++ b/lib/pages/medical/my_trackers/blood_pressure/BloodPressureMonthly.dart @@ -1,182 +1,107 @@ +import "package:collection/collection.dart"; import 'package:diplomaticquarterapp/core/viewModels/medical/blood_pressure_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/medical/my_trackers/widget/MonthCurvedChartBloodPressure.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/widgets/charts/app_time_series_chart.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:hexcolor/hexcolor.dart'; import 'package:provider/provider.dart'; class BloodPressureMonthlyPage extends StatelessWidget { - final BloodPressureViewMode model; - - const BloodPressureMonthlyPage({Key key, this.model}) : super(key: key); + final BloodPressureViewMode? model; + BloodPressureMonthlyPage({Key? key, this.model}) : super(key: key); + List monthlyGroup = []; + late ProjectViewModel projectViewModel; @override Widget build(BuildContext context) { - ProjectViewModel projectViewModel = Provider.of(context); - - return AppScaffold( - body: model.weighMonthTimeSeriesDataTop.isEmpty? Container(child: Center(child: Texts(TranslationBase.of(context).noDataAvailable),),):ListView( - children: [ - Container( - margin: EdgeInsets.only(top: 12, left: 8, right: 8), - color: Colors.white, - child: MonthCurvedChartBloodPressure( - horizontalInterval: 20.0, - title: TranslationBase.of(context).bloodPressure, - timeSeries1: model.weighMonthTimeSeriesDataTop, - timeSeries2: model.weighMonthTimeSeriesDataLow, - indexes: model.weightWeekTimeSeriesDataLow.length ~/ 5.5, - ), - ), - SizedBox( - height: 12, + // if (projectViewModel == null) + projectViewModel = Provider.of(context); + groupData(); + return ListView( + children: [ + Container( + margin: EdgeInsets.only(top: 12, left: 8, right: 8), + color: Colors.white, + child: + MonthCurvedChartBloodPressure( + horizontalInterval: 20.0, + title: TranslationBase.of(context).bloodPressure, + timeSeries1: model!.weighMonthTimeSeriesDataTop.isEmpty ? [TimeSeriesSales3(0, 0.0)] : model!.weighMonthTimeSeriesDataTop, + timeSeries2: model!.weighMonthTimeSeriesDataLow.isEmpty ? [TimeSeriesSales3(0, 0.0)] : model!.weighMonthTimeSeriesDataLow, + indexes: model!.weighMonthTimeSeriesDataLow.length ~/ 5.5, ), - Padding( - padding: const EdgeInsets.all(8.0), - child: Texts(TranslationBase.of(context).details), + ), + SizedBox( + height: 12, + ), + // Padding( + // padding: const EdgeInsets.all(8.0), + // child: Texts(TranslationBase.of(context).details), + // ), + Container( + padding: EdgeInsets.all(10), + color: Colors.transparent, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + model!.weighMonthTimeSeriesDataTop.isEmpty + ? Container( + child: Center( + child: Texts(TranslationBase.of(context).noDataAvailable), + ), + ) + : Column(children: [ + for (var monthly in monthlyGroup) + Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ + Container( + width: double.maxFinite, + padding: EdgeInsets.only(top: 10, bottom: 10, left: 5, right: 5), + decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(5)), + child: Texts(monthly[0])), + Table( + columnWidths: { + 0: FlexColumnWidth(1.8), + 2: FlexColumnWidth(1.8), + }, + children: fullData(context, monthly[1]), + ) + ]) + ]), + SizedBox(height: 80) + ], ), - Container( - padding: EdgeInsets.all(10), - color: Colors.transparent, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Table( - border: TableBorder.symmetric( - inside: BorderSide(width: 2.0, color: Colors.grey[300]), - ), - children: fullData(context,projectViewModel,model), - ), - ], - ), - ) - ], - ), + ) + ], ); } - List fullData(BuildContext context, - ProjectViewModel projectViewModel, BloodPressureViewMode model) { + List fullData(BuildContext context, model) { List tableRow = []; tableRow.add( TableRow( children: [ - Container( - child: Container( - decoration: BoxDecoration( - color: Theme.of(context).primaryColor, - borderRadius: BorderRadius.only( - topLeft: Radius.circular(10.0), - ), - ), - child: Center( - child: Texts( - 'Date', - color: Colors.white, - fontSize: 15, - ), - ), - height: 40, - ), - ), - Container( - child: Container( - decoration: BoxDecoration( - color: Theme.of(context).primaryColor, - ), - child: Center( - child: Texts( - 'Time', - color: Colors.white, - fontSize: 15, - ), - ), - height: 40), - ), - Container( - child: Container( - decoration: BoxDecoration( - color: Theme.of(context).primaryColor, - ), - child: Center( - child: Texts( - 'Arm', - color: Colors.white, - fontSize: 15, - ), - ), - height: 40), - ), - Container( - child: Container( - decoration: BoxDecoration( - color: Theme.of(context).primaryColor, - borderRadius: BorderRadius.only( - topRight: Radius.circular(10.0), - ), - ), - child: Center( - child: Texts( - 'SBP/DBP', - color: Colors.white, - fontSize: 15, - ), - ), - height: 40), - ), + Utils.tableColumnTitle(TranslationBase.of(context).date), + Utils.tableColumnTitle(TranslationBase.of(context).time), + Utils.tableColumnTitle(TranslationBase.of(context).arm), + Utils.tableColumnTitle(TranslationBase.of(context).value), ], ), ); - model.monthDiabtecPatientResult.reversed.forEach( + model.forEach( (diabtec) { tableRow.add( TableRow( children: [ - Container( - color: Colors.white, - child: Center( - child: Texts( - '${projectViewModel.isArabic? DateUtil.getMonthDayYearDateFormattedAr(diabtec.bloodPressureDate):DateUtil.getMonthDayYearDateFormatted(diabtec.bloodPressureDate)}', - fontSize: 15, - textAlign: TextAlign.center, - ), - ), - height: 40, - ), - Container( - color: Colors.white, - child: Center( - child: Texts( - '${diabtec.bloodPressureDate.hour}:${diabtec.bloodPressureDate.minute}', - fontSize: 15, - ), - ), - height: 40), - Container( - color: Colors.white, - child: Center( - child: Texts( - diabtec.measuredArmDesc, - fontSize: 15, - ), - ), - height: 40), - Container( - color: Colors.white, - child: Center( - child: Texts( - '${diabtec.systolicePressure}/${diabtec.diastolicPressure}', - color: Colors.red, - fontSize: 15, - ), - ), - height: 40), + Utils.tableColumnValue('${DateUtil.getDayMonthYearDateFormatted(diabtec.bloodPressureDate)}', isCapitable: false, mProjectViewModel: projectViewModel), + Utils.tableColumnValue('${diabtec.bloodPressureDate.hour}:${diabtec.bloodPressureDate.minute}', isCapitable: false, mProjectViewModel: projectViewModel), + Utils.tableColumnValue(diabtec.measuredArmDesc, isCapitable: false, mProjectViewModel: projectViewModel), + Utils.tableColumnValue('${diabtec.systolicePressure}/${diabtec.diastolicPressure}', isCapitable: false, mProjectViewModel: projectViewModel), ], ), ); @@ -184,4 +109,10 @@ class BloodPressureMonthlyPage extends StatelessWidget { ); return tableRow; } + + groupData() { + monthlyGroup.clear(); + var groupedArray = groupBy(model!.bloodPressureService.monthDiabtecPatientResult, (obj) => DateUtil.getMonth(obj.bloodPressureDate!.month) + ' ' + obj.bloodPressureDate!.year.toString()); + groupedArray.entries.forEach((e) => monthlyGroup.add([e.key, e.value])); + } } diff --git a/lib/pages/medical/my_trackers/blood_pressure/BloodPressureYeaPage.dart b/lib/pages/medical/my_trackers/blood_pressure/BloodPressureYeaPage.dart index b5b01f06..260cdbed 100644 --- a/lib/pages/medical/my_trackers/blood_pressure/BloodPressureYeaPage.dart +++ b/lib/pages/medical/my_trackers/blood_pressure/BloodPressureYeaPage.dart @@ -1,8 +1,12 @@ +import "package:collection/collection.dart"; import 'package:diplomaticquarterapp/core/viewModels/medical/blood_pressure_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/medical/my_trackers/widget/CurvedChartBloodPressure.dart'; +import 'package:diplomaticquarterapp/pages/medical/vital_sign/LineChartCurvedBloodPressure.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/widgets/charts/app_time_series_chart.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; @@ -12,196 +16,88 @@ import 'package:provider/provider.dart'; class BloodPressureYearPage extends StatelessWidget { final BloodPressureViewMode model; - const BloodPressureYearPage({Key key, this.model}) : super(key: key); + BloodPressureYearPage({Key? key, required this.model}) : super(key: key); + List monthlyGroup = []; + late ProjectViewModel projectViewModel; @override Widget build(BuildContext context) { - ProjectViewModel projectViewModel = Provider.of(context); - return AppScaffold( - body: model.weightYearTimeSeriesDataTop.isEmpty? Container(child: Center(child: Texts(TranslationBase.of(context).noDataAvailable),),):ListView( - children: [ - Container( - margin: EdgeInsets.only(top: 12, left: 8, right: 8), - color: Colors.white, - child: CurvedChartBloodPressure( - horizontalInterval: 3.0,// model.weightWeekTimeSeriesDataLow.length==1 ?1 :20.0, - title: TranslationBase.of(context).bloodPressure, - timeSeries1: model.weightYearTimeSeriesDataTop, - timeSeries2: model.weightYearTimeSeriesDataLow, - indexes: model.weightWeekTimeSeriesDataLow.length ~/ 5.5, - ), - ), - SizedBox( - height: 12, + // if (projectViewModel == null) + projectViewModel = Provider.of(context); + groupData(); + return ListView( + children: [ + Container( + margin: EdgeInsets.only(top: 12, left: 8, right: 8), + color: Colors.white, + child: LineChartCurvedBloodPressure( + title: TranslationBase.of(context).bloodPressure, + timeSeries1: model.weightYearTimeSeriesDataTop.isEmpty ? [TimeSeriesSales2(DateTime.now(), 0.0)] : model.weightYearTimeSeriesDataTop, + timeSeries2: model.weightYearTimeSeriesDataLow.isEmpty ? [TimeSeriesSales2(DateTime.now(), 0.0)] : model.weightYearTimeSeriesDataLow, + indexes: model.weightWeekTimeSeriesDataLow.length ~/ 5.5, ), - Padding( - padding: const EdgeInsets.all(8.0), - child: Texts(TranslationBase.of(context).details), - ), - Container( - padding: EdgeInsets.all(10), - color: Colors.transparent, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Table( - border: TableBorder.symmetric( - inside: BorderSide(width: 2.0, color: Colors.grey[300]), - ), - children: fullData(context, projectViewModel, model), + ), + SizedBox( + height: 12, + ), + Container( + padding: EdgeInsets.all(10), + color: Colors.transparent, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + model.weightYearTimeSeriesDataTop.isEmpty + ? Container( + child: Center( + child: Texts(TranslationBase.of(context).noDataAvailable), ), - ], - ), - ) - ], - ), + ) + : Column(children: [ + for (var monthly in monthlyGroup) + Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ + Container( + width: double.maxFinite, + padding: EdgeInsets.only(top: 10, bottom: 10, left: 5, right: 5), + decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(5)), + child: Texts(monthly[0])), + Table( + columnWidths: { + 0: FlexColumnWidth(1.8), + 2: FlexColumnWidth(1.8), + }, + children: fullData(context, monthly[1]), + ) + ]) + ]), + SizedBox(height: 80) + ], + ), + ) + ], ); } - List fullData( - BuildContext context, - ProjectViewModel projectViewModel, - BloodPressureViewMode bloodSugarViewMode) { + List fullData(BuildContext context, model) { List tableRow = []; tableRow.add( TableRow( children: [ - Container( - child: Container( - decoration: BoxDecoration( - color: Theme.of(context).primaryColor, - borderRadius: BorderRadius.only( - topLeft: projectViewModel.isArabic - ? Radius.circular(0.0) - : Radius.circular(10.0), - topRight: projectViewModel.isArabic - ? Radius.circular(10.0) - : Radius.circular(0.0), - ), - ), - child: Center( - child: Texts( - TranslationBase.of(context).date, - color: Colors.white, - fontSize: 15, - ), - ), - height: 40, - ), - ), - Container( - child: Container( - decoration: BoxDecoration( - color: Theme.of(context).primaryColor, - ), - child: Center( - child: Texts( - TranslationBase.of(context).time, - color: Colors.white, - fontSize: 15, - ), - ), - height: 40), - ), - Container( - child: Container( - decoration: BoxDecoration( - color: Theme.of(context).primaryColor, - ), - child: Center( - child: Texts( - TranslationBase.of(context).measured, - color: Colors.white, - fontSize: 15, - ), - ), - height: 40), - ), - Container( - child: Container( - decoration: BoxDecoration( - color: Theme.of(context).primaryColor, - borderRadius: BorderRadius.only( - topLeft: projectViewModel.isArabic - ? Radius.circular(10.0) - : Radius.circular(0.0), - topRight: projectViewModel.isArabic - ? Radius.circular(0.0) - : Radius.circular(10.0), - ), - ), - child: Center( - child: Texts( - TranslationBase.of(context).value, - color: Colors.white, - fontSize: 15, - ), - ), - height: 40), - ), + Utils.tableColumnTitle(TranslationBase.of(context).date), + Utils.tableColumnTitle(TranslationBase.of(context).time), + Utils.tableColumnTitle(TranslationBase.of(context).arm), + Utils.tableColumnTitle(TranslationBase.of(context).value), ], ), ); - model.yearDiabtecPatientResult.reversed.forEach( + model.forEach( (diabtec) { tableRow.add( TableRow( children: [ - Container( - child: Container( - height: 70, - padding: EdgeInsets.all(10), - color: Colors.white, - child: Center( - child: Texts( - '${DateUtil.getMonthDayYearDateFormatted(diabtec.bloodPressureDate)} ', - textAlign: TextAlign.center, - fontSize: 12, - ), - ), - ), - ), - Container( - height: 70, - padding: EdgeInsets.all(10), - color: Colors.white, - child: Center( - child: Texts( - '${diabtec.bloodPressureDate.hour}:${diabtec.bloodPressureDate.minute}', - textAlign: TextAlign.center, - fontSize: 12, - ), - ), - ), - Container( - child: Container( - height: 70, - padding: EdgeInsets.all(10), - color: Colors.white, - child: Center( - child: Texts( - '${diabtec.measuredArmDesc}', - textAlign: TextAlign.center, - fontSize: 12, - ), - ), - ), - ), - Container( - child: Container( - height: 70, - padding: EdgeInsets.all(10), - color: Colors.white, - child: Center( - child: Texts( - '${diabtec.systolicePressure}/${diabtec.diastolicPressure}', - textAlign: TextAlign.center, - fontSize: 12, - color: Colors.red, - ), - ), - ), - ), + Utils.tableColumnValue('${DateUtil.getDayMonthYearDateFormatted(diabtec.bloodPressureDate)}', isCapitable: false, mProjectViewModel: projectViewModel), + Utils.tableColumnValue('${diabtec.bloodPressureDate.hour}:${diabtec.bloodPressureDate.minute}', isCapitable: false, mProjectViewModel: projectViewModel), + Utils.tableColumnValue(diabtec.measuredArmDesc, isCapitable: false, mProjectViewModel: projectViewModel), + Utils.tableColumnValue('${diabtec.systolicePressure}/${diabtec.diastolicPressure}', isCapitable: false, mProjectViewModel: projectViewModel), ], ), ); @@ -209,4 +105,10 @@ class BloodPressureYearPage extends StatelessWidget { ); return tableRow; } + + groupData() { + monthlyGroup.clear(); + var groupedArray = groupBy(model.bloodPressureService.yearDiabtecPatientResult.reversed, (obj) => DateUtil.getMonth(obj.bloodPressureDate!.month) + ' ' + obj.bloodPressureDate!.year.toString()); + groupedArray.entries.forEach((e) => monthlyGroup.add([e.key, e.value])); + } } diff --git a/lib/pages/medical/my_trackers/blood_pressure/bloodPressureWeeklyPage.dart b/lib/pages/medical/my_trackers/blood_pressure/bloodPressureWeeklyPage.dart index e4ff7332..9d0d6685 100644 --- a/lib/pages/medical/my_trackers/blood_pressure/bloodPressureWeeklyPage.dart +++ b/lib/pages/medical/my_trackers/blood_pressure/bloodPressureWeeklyPage.dart @@ -1,10 +1,11 @@ import 'package:diplomaticquarterapp/core/viewModels/medical/blood_pressure_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; -import 'package:diplomaticquarterapp/pages/medical/my_trackers/widget/CurvedChartBloodPressure.dart'; +import 'package:diplomaticquarterapp/pages/medical/vital_sign/LineChartCurvedBloodPressure.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/widgets/charts/app_time_series_chart.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; -import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -13,238 +14,129 @@ import 'package:provider/provider.dart'; import 'AddBloodPressurePage.dart'; class BloodPressureWeeklyPage extends StatelessWidget { - final BloodPressureViewMode model; + final BloodPressureViewMode? model; - const BloodPressureWeeklyPage({Key key, this.model}) : super(key: key); + BloodPressureWeeklyPage({Key? key, this.model}) : super(key: key); + + late ProjectViewModel projectViewModel; @override Widget build(BuildContext context) { - ProjectViewModel projectViewModel = Provider.of(context); - return AppScaffold( - body: model.weightWeekTimeSeriesDataTop.isEmpty? Container(child: Center(child: Texts(TranslationBase.of(context).noDataAvailable),),): ListView( - children: [ - Container( - margin: EdgeInsets.only(top: 12, left: 8, right: 8), - color: Colors.white, - child: CurvedChartBloodPressure( - horizontalInterval:3.0, - title: TranslationBase.of(context).bloodPressure, - timeSeries1: model.weightWeekTimeSeriesDataTop, - timeSeries2: model.weightWeekTimeSeriesDataLow, - indexes: model.weightWeekTimeSeriesDataLow.length ~/ 5.5, - ), - ), - SizedBox( - height: 12, + // if (projectViewModel == null) + projectViewModel = Provider.of(context); + return ListView( + children: [ + Container( + margin: EdgeInsets.only(top: 12, left: 8, right: 8, bottom: 12.0), + padding: EdgeInsets.only(bottom: 12.0), + color: Colors.white, + child: LineChartCurvedBloodPressure( + title: TranslationBase.of(context).bloodPressure, + timeSeries1: model!.weightWeekTimeSeriesDataTop.isEmpty ? [TimeSeriesSales2(DateTime.now(), 0.0)] : model!.weightWeekTimeSeriesDataTop, + timeSeries2: model!.weightWeekTimeSeriesDataLow.isEmpty ? [TimeSeriesSales2(DateTime.now(), 0.0)] : model!.weightWeekTimeSeriesDataLow, + indexes: model!.weightWeekTimeSeriesDataLow.length ~/ 5.5, ), - Padding( - padding: const EdgeInsets.all(8.0), - child: Texts(TranslationBase.of(context).details), + ), + SizedBox( + height: 12, + ), + // Padding( + // padding: const EdgeInsets.all(8.0), + // child: Texts(TranslationBase.of(context).details), + // ), + Container( + padding: EdgeInsets.all(10), + color: Colors.transparent, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + model!.bloodPressureService.weekDiabtecPatientResult.isEmpty + ? Container( + child: Center( + child: Texts(TranslationBase.of(context).noDataAvailable), + ), + ) + : Table( + columnWidths: { + 0: FlexColumnWidth(1.8), + 2: FlexColumnWidth(1.8), + }, + children: fullData(context, model!), + ), + SizedBox(height: 80) + ], ), - Container( - padding: EdgeInsets.all(10), - color: Colors.transparent, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Table( - border: TableBorder.symmetric( - inside: BorderSide(width: 2.0, color: Colors.grey[300]), - ), - children: fullData(context, projectViewModel, model), - ), - ], - ), - ) - ], - ), + ) + ], ); } - List fullData( - BuildContext context, - ProjectViewModel projectViewModel, - BloodPressureViewMode bloodSugarViewMode) { + List fullData(BuildContext context, BloodPressureViewMode bloodSugarViewMode) { List tableRow = []; tableRow.add( TableRow( children: [ - Container( - child: Container( - decoration: BoxDecoration( - color: Theme.of(context).primaryColor, - borderRadius: BorderRadius.only( - topLeft: projectViewModel.isArabic - ? Radius.circular(0.0) - : Radius.circular(10.0), - topRight: projectViewModel.isArabic - ? Radius.circular(10.0) - : Radius.circular(0.0), - ), - ), - child: Center( - child: Texts( - TranslationBase.of(context).date, - color: Colors.white, - fontSize: 15, - ), - ), - height: 40, - ), - ), - Container( - child: Container( - decoration: BoxDecoration( - color: Theme.of(context).primaryColor, - ), - child: Center( - child: Texts( - TranslationBase.of(context).time, - color: Colors.white, - fontSize: 15, - ), - ), - height: 40), - ), - Container( - child: Container( - decoration: BoxDecoration( - color: Theme.of(context).primaryColor, - ), - child: Center( - child: Texts( - TranslationBase.of(context).measured, - color: Colors.white, - fontSize: 15, - ), - ), - height: 40), - ), - Container( - child: Container( - decoration: BoxDecoration( - color: Theme.of(context).primaryColor, - ), - child: Center( - child: Texts( - TranslationBase.of(context).value, - color: Colors.white, - fontSize: 15, - ), - ), - height: 40), - ), - Container( - child: Container( - decoration: BoxDecoration( - color: Theme.of(context).primaryColor, - borderRadius: BorderRadius.only( - topLeft: projectViewModel.isArabic - ? Radius.circular(10.0) - : Radius.circular(0.0), - topRight: projectViewModel.isArabic - ? Radius.circular(0.0) - : Radius.circular(10.0), - ), - ), - child: Center( - child: Texts( - TranslationBase.of(context).edit, - color: Colors.white, - fontSize: 15, - ), - ), - height: 40), - ), + Utils.tableColumnTitle(TranslationBase.of(context).date), + Utils.tableColumnTitle(TranslationBase.of(context).time), + Utils.tableColumnTitle(TranslationBase.of(context).measured), + Utils.tableColumnTitle(TranslationBase.of(context).value), + Utils.tableColumnTitle(TranslationBase.of(context).edit), ], ), ); - model.weekDiabtecPatientResult.reversed.forEach( + model!.weekDiabtecPatientResult!.reversed.forEach( (diabtec) { tableRow.add( TableRow( children: [ - Container( - child: Container( - height: 70, - padding: EdgeInsets.all(10), - color: Colors.white, - child: Center( - child: Texts( - '${DateUtil.getMonthDayYearDateFormatted(diabtec.bloodPressureDate)} ', - textAlign: TextAlign.center, - fontSize: 12, - ), - ), - ), - ), - Container( - height: 70, - padding: EdgeInsets.all(10), - color: Colors.white, - child: Center( - child: Texts( - '${diabtec.bloodPressureDate.hour}:${diabtec.bloodPressureDate.minute}', - textAlign: TextAlign.center, - fontSize: 12, - ), - ), - ), - Container( - child: Container( - height: 70, - padding: EdgeInsets.all(10), - color: Colors.white, - child: Center( - child: Texts( - '${diabtec.measuredArmDesc}', - textAlign: TextAlign.center, - fontSize: 12, - ), - ), - ), - ), - Container( - child: Container( - height: 70, - padding: EdgeInsets.all(10), - color: Colors.white, - child: Center( - child: Texts( - '${diabtec.systolicePressure}/${diabtec.diastolicPressure}', - textAlign: TextAlign.center, - fontSize: 12, - color: Colors.red, - ), - ), - ), - ), - InkWell( - onTap: () { - Navigator.push( - context, - FadePage( - page: AddBloodPressurePage( - model: model, - isUpdate: true, - lineItemNo: diabtec.lineItemNo, - bloodSugarDate: diabtec.bloodPressureDate, - bloodDiastolicValue: diabtec.diastolicPressure.toString(), - bloodSystolicValue: diabtec.systolicePressure.toString(), - measureTimeSelectedType: diabtec.measuredArmDesc, + Utils.tableColumnValue('${DateUtil.getDayMonthYearDateFormatted(diabtec.bloodPressureDate!)} ', isCapitable: false, mProjectViewModel: projectViewModel), + Utils.tableColumnValue(diabtec.bloodPressureDate!.hour.toString() + ':' + diabtec.bloodPressureDate!.minute.toString(), isCapitable: false, mProjectViewModel: projectViewModel), + Utils.tableColumnValue('${diabtec.measuredArmDesc}', isCapitable: false, mProjectViewModel: projectViewModel), + Utils.tableColumnValue('${diabtec.systolicePressure}/${diabtec.diastolicPressure}', isCapitable: false, mProjectViewModel: projectViewModel), + Column(crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ + SizedBox(height: 12), + Container( + child: InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: AddBloodPressurePage( + model: model, + isUpdate: true, + lineItemNo: diabtec.lineItemNo, + bloodSugarDate: diabtec.bloodPressureDate, + bloodDiastolicValue: diabtec.diastolicPressure.toString(), + bloodSystolicValue: diabtec.systolicePressure.toString(), + measureTimeSelectedType: diabtec.measuredArmDesc, + measuredArm: diabtec.measuredArm, + ), + ), + ).then((value) { + model!.getBloodPressure(); + if (model!.weekDiabtecPatientResult.isEmpty) { + model!.weightWeekTimeSeriesDataTop.clear(); + model!.weightWeekTimeSeriesDataLow.clear(); + } + }); + }, + child: Container( + // height: 70, + // padding: EdgeInsets.all(10), + child: Icon( + Icons.edit, + color: Color(0xff575757), ), ), - ); - }, - child: Container( - height: 70, - padding: EdgeInsets.all(10), - color: Colors.white, - child: Center( - child: Icon(Icons.edit), ), ), - ), + SizedBox(height: 6), + Divider( + height: 1, + color: Color(0xffEFEFEF), + thickness: 1, + ) + ]), ], ), ); diff --git a/lib/pages/medical/my_trackers/blood_suger/AddBloodSugarPage.dart b/lib/pages/medical/my_trackers/blood_suger/AddBloodSugarPage.dart index 94e48b92..279775f5 100644 --- a/lib/pages/medical/my_trackers/blood_suger/AddBloodSugarPage.dart +++ b/lib/pages/medical/my_trackers/blood_suger/AddBloodSugarPage.dart @@ -6,34 +6,28 @@ 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/secondary_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/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'; -import 'package:flutter_datetime_picker/flutter_datetime_picker.dart'; +import 'package:flutter_datetime_picker_plus/flutter_datetime_picker_plus.dart'; import 'package:provider/provider.dart'; class AddBloodSugarPage extends StatefulWidget { - final DateTime bloodSugarDate; - final String measureUnitSelectedType; - final bool isUpdate; - final String measuredTime; - final String bloodSugarValue; - final int lineItemNo; - final BloodSugarViewMode bloodSugarViewMode; + final DateTime? bloodSugarDate; + final String? measureUnitSelectedType; + final bool? isUpdate; + final String? measuredTime; + final String? bloodSugarValue; + final int? lineItemNo; + final String? measuredSelectedType; + final BloodSugarViewMode? bloodSugarViewMode; AddBloodSugarPage( - {Key key, - this.bloodSugarDate, - this.measureUnitSelectedType, - this.isUpdate = false, - this.measuredTime, - this.bloodSugarValue, - this.lineItemNo, - this.bloodSugarViewMode}) + {Key? key, this.bloodSugarDate, this.measureUnitSelectedType, this.isUpdate = false, this.measuredTime, this.bloodSugarValue, this.lineItemNo, this.bloodSugarViewMode, this.measuredSelectedType}) : super(key: key); @override @@ -45,7 +39,10 @@ class _AddBloodSugarPageState extends State { DateTime bloodSugarDate = DateTime.now(); DateTime timeSugarDate = DateTime.now(); String measureUnitSelectedType = 'mg/dlt'; - int measuredTime = 1; + int measuredTime = 9; + bool isButtonDisabled = true; + + int _selectedMeasureUnitIndex = 0; final List measureUnitList = ['mg/dlt', 'mol/L']; final List measureTimeEnList = [ 'Before Breakfast', @@ -62,7 +59,7 @@ class _AddBloodSugarPageState extends State { final List measureTimeArList = [ "قبل الإفطار", "بعد الإفطار", - "بعد الغداء", + "قبل الغداء", "بعد الغداء", "قبل العشاء", "بعد العشاء", @@ -71,20 +68,22 @@ class _AddBloodSugarPageState extends State { "صائم", "آخر", ]; - String measureTimeSelectedType; + int? _selectedMeasureTimeIndex =9; + String? measureTimeSelectedType; @override void initState() { super.initState(); - if (widget.isUpdate) { - bloodSugarDate = widget.bloodSugarDate; - timeSugarDate = widget.bloodSugarDate; - measureUnitSelectedType = widget.measureUnitSelectedType; + if (widget.isUpdate!) { + bloodSugarDate = widget.bloodSugarDate!; + timeSugarDate = widget.bloodSugarDate!; + measureUnitSelectedType = widget.measureUnitSelectedType!; if (measureTimeEnList.contains(widget.measuredTime)) - measuredTime = measureTimeEnList.indexOf(widget.measuredTime); - else if (measureTimeArList.contains(widget.measuredTime)) - measuredTime = measureTimeArList.indexOf(widget.measuredTime); - _bloodSugarValueController.text = widget.bloodSugarValue; + measuredTime = measureTimeEnList.indexOf(widget.measuredTime!); + else if (measureTimeArList.contains(widget.measuredTime)) measuredTime = measureTimeArList.indexOf(widget.measuredTime!); + _bloodSugarValueController.text = widget.bloodSugarValue!; + measureTimeSelectedType = widget.measuredSelectedType; + validateForm(); } } @@ -93,229 +92,195 @@ class _AddBloodSugarPageState extends State { ProjectViewModel projectViewModel = Provider.of(context); return AppScaffold( isShowAppBar: true, - appBarTitle: widget.isUpdate - ? TranslationBase.of(context).update - : TranslationBase.of(context).add, - appBarIcons: widget.isUpdate?[ - IconButton( - icon: Icon(Icons.delete), - color: Colors.white, - onPressed: () { - ConfirmDialog dialog = new ConfirmDialog( - context: context, - confirmMessage: 'Remove this measure', - 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) - 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); - }, - ) - ]:null, - 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, - ), - 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, - ) - ], + 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: 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: () { + 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.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.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: () { - 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: () { + 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: () { + 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: () { + showDialog( + context: context, + builder: (cxt) => 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); + }); + }, + ), + ); + }, + ) + ], + ), + ) + : Container() + ], ), - ], + ), ), - ), - ), - bottomSheet: Container( - color: Colors.transparent, - width: double.infinity, - height: MediaQuery.of(context).size.width * 0.2, - child: Padding( - padding: const EdgeInsets.all(15.0), - child: SecondaryButton( - label: TranslationBase.of(context).save.toUpperCase(), - textColor: Colors.white, - onTap: () { - if (_bloodSugarValueController.text.isNotEmpty) { - if (widget.isUpdate) { - GifLoaderDialogUtils.showMyDialog(context); - widget.bloodSugarViewMode - .updateDiabtecResult( + 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, lineItemNo: widget.lineItemNo, - bloodSugerResult: - _bloodSugarValueController.text.toString()) - .then((value) { - GifLoaderDialogUtils.hideDialog(context); - if (widget.bloodSugarViewMode.state == ViewState.ErrorLocal) - AppToast.showErrorToast( - message: widget.bloodSugarViewMode.error); - else - Navigator.pop(context); - }); - } else - widget.bloodSugarViewMode - .addDiabtecResult( - diabtecUnit: measureUnitSelectedType, - measuredTime: measuredTime, - bloodSugerResult: - _bloodSugarValueController.text.toString(), - bloodSugerDateChart: - '${bloodSugarDate.year}-${bloodSugarDate.month}-${bloodSugarDate.day} ${timeSugarDate.hour}:${timeSugarDate.minute}:00', - ) - .then((value) { - GifLoaderDialogUtils.hideDialog(context); - if (widget.bloodSugarViewMode.state == ViewState.Error) - AppToast.showErrorToast( - message: widget.bloodSugarViewMode.error); - else - Navigator.pop(context); - }); - } - }), - ), + 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( + 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, + ).insideContainer, + ], ), ); } @@ -329,35 +294,55 @@ 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; - }); + builder: (cxt) => 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); - }); + builder: (cxt) => RadioSelectionDialog( + listData: list, + selectedIndex: _selectedMeasureTimeIndex, + isScrollable: true, + onValueSelected: (index) { + _selectedMeasureTimeIndex = index; + measureTimeSelectedType = list[index].title; + measuredTime = index; + setState(() {}); }, ), ); } + + void validateForm() { + if (_bloodSugarValueController.text.length > 0) { + setState(() { + isButtonDisabled = false; + }); + } else { + setState(() { + isButtonDisabled = true; + }); + } + } } diff --git a/lib/pages/medical/my_trackers/blood_suger/BloodMonthly.dart b/lib/pages/medical/my_trackers/blood_suger/BloodMonthly.dart index 1294c5dd..59cc2e12 100644 --- a/lib/pages/medical/my_trackers/blood_suger/BloodMonthly.dart +++ b/lib/pages/medical/my_trackers/blood_suger/BloodMonthly.dart @@ -1,41 +1,44 @@ +import "package:collection/collection.dart"; import 'package:diplomaticquarterapp/core/model/my_trakers/blood_sugar/DiabtecPatientResult.dart'; -import 'package:diplomaticquarterapp/core/model/my_trakers/chartData/WeekChartDate.dart'; -import 'package:diplomaticquarterapp/core/model/my_trakers/chartData/YearMonthlyChartDate.dart'; +import 'package:diplomaticquarterapp/core/viewModels/medical/blood_sugar_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; -import 'package:diplomaticquarterapp/pages/medical/my_trackers/widget/LineChartCurved.dart'; import 'package:diplomaticquarterapp/pages/medical/my_trackers/widget/MonthLineChartCurved.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/charts/app_time_series_chart.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:charts_flutter/flutter.dart' as charts; -import 'package:hexcolor/hexcolor.dart'; import 'package:provider/provider.dart'; class BloodMonthlyPage extends StatelessWidget { - final List diabtecPatientResult; - final List timeSeriesData ; + final List? diabtecPatientResult; + final List? timeSeriesData; + final BloodSugarViewMode? bloodSugarViewMode; + + BloodMonthlyPage({Key? key, this.diabtecPatientResult, this.timeSeriesData, this.bloodSugarViewMode}) : super(key: key); + + List monthlyGroup = []; + late ProjectViewModel projectViewModel; - const BloodMonthlyPage({Key key, this.diabtecPatientResult, this.timeSeriesData}) - : super(key: key); @override Widget build(BuildContext context) { - ProjectViewModel projectViewModel = Provider.of(context); + projectViewModel = Provider.of(context); + groupData(); return AppScaffold( - body: timeSeriesData.isEmpty?Container(child: Center(child: Texts(TranslationBase.of(context).noDataAvailable),),): ListView( + body: ListView( children: [ Container( + margin: EdgeInsets.only(top: 12, left: 8, right: 8), width: double.maxFinite, color: Colors.white, child: MonthLineChartCurved( - title: 'Sugar', - timeSeries: timeSeriesData, - indexes: timeSeriesData.length ~/ 5.5, - ) - ), + title: '${TranslationBase.of(context).bloodSugar}', + timeSeries: timeSeriesData!.isEmpty ? [TimeSeriesSales3(0, 0.0)] : timeSeriesData!, + indexes: timeSeriesData!.length ~/ 5.5, + )), SizedBox( height: 12, ), @@ -44,160 +47,59 @@ class BloodMonthlyPage extends StatelessWidget { child: Texts(TranslationBase.of(context).details), ), Container( - padding: EdgeInsets.all(10), - color: Colors.transparent, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Table( - border: TableBorder.symmetric( - inside: BorderSide(width: 2.0, color: Colors.grey[300]), - ), - children: fullData(context,projectViewModel), - ), - ], - ), - ) + padding: EdgeInsets.all(10), + color: Colors.transparent, + child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ + timeSeriesData!.isEmpty + ? Container( + child: Center( + child: Texts(TranslationBase.of(context).noDataAvailable), + ), + ) + : Column(children: [ + for (var monthly in monthlyGroup) + Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ + Container( + width: double.maxFinite, + padding: EdgeInsets.only(top: 10, bottom: 10, left: 5, right: 5), + decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(5)), + child: Texts(monthly[0])), + Table( + columnWidths: { + 0: FlexColumnWidth(1.8), + 2: FlexColumnWidth(1.8), + }, + children: fullData(context, monthly[1]), + ) + ]) + ]), + ])) ], ), ); } - List fullData(BuildContext context,ProjectViewModel projectViewModel) { + List fullData(BuildContext context, e) { List tableRow = []; tableRow.add( TableRow( children: [ - Container( - child: Container( - decoration: BoxDecoration( - color: Theme.of(context).primaryColor, - borderRadius: BorderRadius.only( - topLeft: projectViewModel.isArabic? Radius.circular(0.0):Radius.circular(10.0), - topRight: projectViewModel.isArabic? Radius.circular(10.0):Radius.circular(0.0), - ), - ), - child: Center( - child: Texts( - TranslationBase.of(context).date, - color: Colors.white, - fontSize: 15, - ), - ), - height: 40, - ), - ), - Container( - child: Container( - decoration: BoxDecoration( - color: Theme.of(context).primaryColor, - ), - child: Center( - child: Texts( - TranslationBase.of(context).time, - color: Colors.white, - fontSize: 15, - ), - ), - height: 40), - ), - Container( - child: Container( - decoration: BoxDecoration( - color: Theme.of(context).primaryColor, - ), - child: Center( - child: Texts( - TranslationBase.of(context).measured, - color: Colors.white, - fontSize: 15, - ), - ), - height: 40), - ), - Container( - child: Container( - decoration: BoxDecoration( - color: Theme.of(context).primaryColor, - borderRadius: BorderRadius.only( - topLeft: projectViewModel.isArabic? Radius.circular(10.0):Radius.circular(0.0), - topRight: projectViewModel.isArabic? Radius.circular(0.0):Radius.circular(10.0), - ), - ), - child: Center( - child: Texts( - TranslationBase.of(context).value, - color: Colors.white, - fontSize: 15, - ), - ), - height: 40), - ), - + Utils.tableColumnTitle(TranslationBase.of(context).date), + Utils.tableColumnTitle(TranslationBase.of(context).time), + Utils.tableColumnTitle(TranslationBase.of(context).measured), + Utils.tableColumnTitle(TranslationBase.of(context).value), ], ), ); - diabtecPatientResult.forEach( + e.forEach( (diabtec) { tableRow.add( TableRow( children: [ - Container( - child: Container( - height: 70, - padding: EdgeInsets.all(10), - color: Colors.white, - child: Center( - child: Texts( - '${projectViewModel.isArabic ? DateUtil.getMonthDayYearDateFormattedAr(diabtec.dateChart):DateUtil.getMonthDayYearDateFormatted(diabtec.dateChart)} ', - textAlign: TextAlign.center, - fontSize: 12, - ), - ), - ), - ), - Container( - child: Container( - height: 70, - padding: EdgeInsets.all(10), - color: Colors.white, - child: Center( - child: Texts( - '${diabtec.dateChart.hour}:${diabtec.dateChart.minute}', - textAlign: TextAlign.center, - fontSize: 12, - ), - ), - ), - ), - Container( - child: Container( - height: 70, - padding: EdgeInsets.all(10), - color: Colors.white, - child: Center( - child: Texts( - '${diabtec.measuredDesc}', - textAlign: TextAlign.center, - fontSize: 12, - ), - ), - ), - ), - Container( - child: Container( - height: 70, - padding: EdgeInsets.all(10), - color: Colors.white, - child: Center( - child: Texts( - '${diabtec.resultValue}', - textAlign: TextAlign.center, - fontSize: 12, - ), - ), - ), - ), + Utils.tableColumnValue(DateUtil.getDayMonthYearDateFormatted(diabtec.dateChart), isCapitable: false, mProjectViewModel: projectViewModel), + Utils.tableColumnValue(diabtec.dateChart.hour.toString() + ':' + diabtec.dateChart.minute.toString(), isCapitable: false, mProjectViewModel: projectViewModel), + Utils.tableColumnValue(diabtec.measuredDesc, isCapitable: false, mProjectViewModel: projectViewModel), + Utils.tableColumnValue(diabtec.resultValue.toString(), isCapitable: false, mProjectViewModel: projectViewModel), ], ), ); @@ -205,4 +107,10 @@ class BloodMonthlyPage extends StatelessWidget { ); return tableRow; } + + groupData() { + monthlyGroup.clear(); + var groupedArray = groupBy(diabtecPatientResult!, (obj) => DateUtil.getMonth(obj.dateChart!.month) + ' ' + obj.dateChart!.year.toString()); + groupedArray.entries.forEach((e) => monthlyGroup.add([e.key, e.value])); + } } diff --git a/lib/pages/medical/my_trackers/blood_suger/BloodYeaPage.dart b/lib/pages/medical/my_trackers/blood_suger/BloodYeaPage.dart index 842d55f1..3e284565 100644 --- a/lib/pages/medical/my_trackers/blood_suger/BloodYeaPage.dart +++ b/lib/pages/medical/my_trackers/blood_suger/BloodYeaPage.dart @@ -1,216 +1,110 @@ +import "package:collection/collection.dart"; import 'package:diplomaticquarterapp/core/model/my_trakers/blood_sugar/DiabtecPatientResult.dart'; -import 'package:diplomaticquarterapp/core/model/my_trakers/chartData/WeekChartDate.dart'; +import 'package:diplomaticquarterapp/core/viewModels/medical/blood_sugar_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; -import 'package:diplomaticquarterapp/pages/medical/my_trackers/widget/LineChartCurved.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/charts/app_time_series_chart.dart'; +import 'package:diplomaticquarterapp/widgets/charts/show_chart.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:charts_flutter/flutter.dart' as charts; -import 'package:hexcolor/hexcolor.dart'; import 'package:provider/provider.dart'; class BloodYearPage extends StatelessWidget { - final List diabtecPatientResult; - final List timeSeriesData; + final List? diabtecPatientResult; + final List? timeSeriesData; + final BloodSugarViewMode? bloodSugarViewMode; - const BloodYearPage({Key key, this.diabtecPatientResult, this.timeSeriesData}) - : super(key: key); + BloodYearPage({Key? key, this.diabtecPatientResult, this.timeSeriesData, this.bloodSugarViewMode}) : super(key: key); + List yearlyGroup = []; + late ProjectViewModel projectViewModel; @override Widget build(BuildContext context) { - ProjectViewModel projectViewModel = Provider.of(context); - return AppScaffold( - body: timeSeriesData.isEmpty - ? Container( - child: Center( - child: Texts(TranslationBase.of(context).noDataAvailable), - ), - ) - : ListView( - children: [ - Container( - width: double.maxFinite, - color: Colors.white, - child: LineChartCurved( - title: 'Sugar', - timeSeries: timeSeriesData, - indexes: timeSeriesData.length ~/ 5.5, - )), - SizedBox( - height: 12, - ), - Padding( - padding: const EdgeInsets.all(8.0), - child: Texts(TranslationBase.of(context).details), - ), - Container( - padding: EdgeInsets.all(10), - color: Colors.transparent, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Table( - border: TableBorder.symmetric( - inside: - BorderSide(width: 2.0, color: Colors.grey[300]), - ), - children: fullData(context, projectViewModel), + // if (projectViewModel == null) + projectViewModel = Provider.of(context); + + groupData(); + return ListView( + children: [ + Container( + margin: EdgeInsets.only(top: 12, left: 8, right: 8), + width: double.maxFinite, + color: Colors.white, + child: ShowChart( + title: TranslationBase.of(context).weight, + timeSeries: timeSeriesData!.isEmpty ? [TimeSeriesSales2(DateTime.now(), 0.0)] : timeSeriesData, + indexes: timeSeriesData!.length ~/ 5.5, + horizontalInterval: 2, + ), + ), + SizedBox( + height: 12, + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: Texts(TranslationBase.of(context).details), + ), + Container( + padding: EdgeInsets.all(10), + color: Colors.transparent, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + timeSeriesData!.isEmpty + ? Container( + child: Center( + child: Texts(TranslationBase.of(context).noDataAvailable), ), - ], - ), - ) - ], - ), + ) + : Column(children: [ + for (var monthly in yearlyGroup) + Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ + Container( + width: double.maxFinite, + padding: EdgeInsets.only(top: 10, bottom: 10, left: 5, right: 5), + decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(5)), + child: Texts(monthly[0])), + Table( + columnWidths: { + 0: FlexColumnWidth(1.8), + 2: FlexColumnWidth(1.8), + }, + children: fullData(context, monthly[1]), + ) + ]) + ]), + SizedBox(height: 80) + ], + ), + ) + ], ); } - List fullData( - BuildContext context, ProjectViewModel projectViewModel) { + List fullData(BuildContext context, yearlyGroup) { List tableRow = []; tableRow.add( TableRow( children: [ - Container( - child: Container( - decoration: BoxDecoration( - color: Theme.of(context).primaryColor, - borderRadius: BorderRadius.only( - topLeft: projectViewModel.isArabic - ? Radius.circular(0.0) - : Radius.circular(10.0), - topRight: projectViewModel.isArabic - ? Radius.circular(10.0) - : Radius.circular(0.0), - ), - ), - child: Center( - child: Texts( - TranslationBase.of(context).date, - color: Colors.white, - fontSize: 15, - ), - ), - height: 40, - ), - ), - Container( - child: Container( - decoration: BoxDecoration( - color: Theme.of(context).primaryColor, - ), - child: Center( - child: Texts( - TranslationBase.of(context).time, - color: Colors.white, - fontSize: 15, - ), - ), - height: 40), - ), - Container( - child: Container( - decoration: BoxDecoration( - color: Theme.of(context).primaryColor, - ), - child: Center( - child: Texts( - TranslationBase.of(context).measured, - color: Colors.white, - fontSize: 15, - ), - ), - height: 40), - ), - Container( - child: Container( - decoration: BoxDecoration( - color: Theme.of(context).primaryColor, - borderRadius: BorderRadius.only( - topLeft: projectViewModel.isArabic - ? Radius.circular(10.0) - : Radius.circular(0.0), - topRight: projectViewModel.isArabic - ? Radius.circular(0.0) - : Radius.circular(10.0), - ), - ), - child: Center( - child: Texts( - TranslationBase.of(context).value, - color: Colors.white, - fontSize: 15, - ), - ), - height: 40), - ), + Utils.tableColumnTitle(TranslationBase.of(context).date), + Utils.tableColumnTitle(TranslationBase.of(context).time), + Utils.tableColumnTitle(TranslationBase.of(context).measured), + Utils.tableColumnTitle(TranslationBase.of(context).value), ], ), ); - diabtecPatientResult.forEach( + yearlyGroup.forEach( (diabtec) { tableRow.add( TableRow( children: [ - Container( - child: Container( - height: 70, - padding: EdgeInsets.all(10), - color: Colors.white, - child: Center( - child: Texts( - '${projectViewModel.isArabic ? DateUtil.getMonthDayYearDateFormattedAr(diabtec.dateChart) : DateUtil.getMonthDayYearDateFormatted(diabtec.dateChart)} ', - textAlign: TextAlign.center, - fontSize: 12, - ), - ), - ), - ), - Container( - child: Container( - height: 70, - padding: EdgeInsets.all(10), - color: Colors.white, - child: Center( - child: Texts( - '${diabtec.dateChart.hour}:${diabtec.dateChart.minute}', - textAlign: TextAlign.center, - fontSize: 12, - ), - ), - ), - ), - Container( - child: Container( - height: 70, - padding: EdgeInsets.all(10), - color: Colors.white, - child: Center( - child: Texts( - '${diabtec.measuredDesc}', - textAlign: TextAlign.center, - fontSize: 12, - ), - ), - ), - ), - Container( - child: Container( - height: 70, - padding: EdgeInsets.all(10), - color: Colors.white, - child: Center( - child: Texts( - '${diabtec.resultValue}', - textAlign: TextAlign.center, - fontSize: 12, - ), - ), - ), - ), + Utils.tableColumnValue(DateUtil.getDayMonthYearDateFormatted(diabtec.dateChart), isCapitable: false, mProjectViewModel: projectViewModel), + Utils.tableColumnValue(diabtec.dateChart.hour.toString() + ':' + diabtec.dateChart.minute.toString(), isCapitable: false, mProjectViewModel: projectViewModel), + Utils.tableColumnValue(diabtec.measuredDesc, isCapitable: false, mProjectViewModel: projectViewModel), + Utils.tableColumnValue(diabtec.resultValue.toString(), isCapitable: false, mProjectViewModel: projectViewModel), ], ), ); @@ -218,4 +112,10 @@ class BloodYearPage extends StatelessWidget { ); return tableRow; } + + groupData() { + yearlyGroup.clear(); + var groupedArray = groupBy(diabtecPatientResult!.reversed, (obj) => DateUtil.getMonth(obj.dateChart!.month) + ' ' + obj.dateChart!.year.toString()); + groupedArray.entries.forEach((e) => yearlyGroup.add([e.key, e.value])); + } } diff --git a/lib/pages/medical/my_trackers/blood_suger/blood_sugar_home_page.dart b/lib/pages/medical/my_trackers/blood_suger/blood_sugar_home_page.dart index 7abbcceb..b7f74988 100644 --- a/lib/pages/medical/my_trackers/blood_suger/blood_sugar_home_page.dart +++ b/lib/pages/medical/my_trackers/blood_suger/blood_sugar_home_page.dart @@ -1,20 +1,17 @@ -import 'dart:ui'; - import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/blood_sugar_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; -import 'package:diplomaticquarterapp/pages/medical/my_trackers/widget/TabBarWidget.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/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/confirm_send_email_dialog.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:charts_flutter/flutter.dart' as charts; -import 'package:hexcolor/hexcolor.dart'; +import 'package:provider/provider.dart'; import 'AddBloodSugarPage.dart'; import 'BloodMonthly.dart'; @@ -26,9 +23,8 @@ class BloodSugarHomePage extends StatefulWidget { _BloodSugarHomePageState createState() => _BloodSugarHomePageState(); } -class _BloodSugarHomePageState extends State - with SingleTickerProviderStateMixin { - TabController _tabController; +class _BloodSugarHomePageState extends State with SingleTickerProviderStateMixin { + late TabController _tabController; @override void initState() { @@ -44,81 +40,122 @@ class _BloodSugarHomePageState extends State @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); return BaseView( onModelReady: (model) => model.getBloodSugar(), builder: (_, model, w) => AppScaffold( - appBarIcons: [IconButton( - icon: Icon(Icons.email), - color: Colors.white, - onPressed: () { - showDialog( - context: context, - child: ConfirmSendEmailDialog( - email: model.user.emailAddress, - onTapSendEmail: () async{ - GifLoaderDialogUtils.showMyDialog(context); - model.sendReportByEmail().then((value) { - GifLoaderDialogUtils.hideDialog(context); - if(model.state == ViewState.ErrorLocal){ - AppToast.showErrorToast(message: model.error); - }else{ - AppToast.showSuccessToast(message:TranslationBase.of(context).emailSentSuccessfully, ); - } - }).catchError((e){ - GifLoaderDialogUtils.hideDialog(context); - AppToast.showErrorToast(message: model.error); - }); - }, - ), - ); - }, - ),], - isShowAppBar: true, - appBarTitle: TranslationBase.of(context).bloodSugar, + showNewAppBar: true, + isShowDecPage: true, + showNewAppBarTitle: true, baseViewModel: model, - body: Scaffold( - extendBodyBehindAppBar: true, - appBar: TabBarWidget(tabController: _tabController,), - body: Column( - children: [ - Expanded( - child: TabBarView( - physics: BouncingScrollPhysics(), - controller: _tabController, - children: [ - BloodSugarWeeklyPage( - timeSeriesData: model.bloodWeekTimeSeriesData, - diabtecPatientResult: model.weekDiabtecPatientResult, - bloodSugarViewMode: model, - ), - BloodMonthlyPage( - timeSeriesData: model.monthTimeSeriesData, - diabtecPatientResult: model.monthDiabtecPatientResult, - ), - BloodYearPage( - timeSeriesData: model.yearTimeSeriesData, - diabtecPatientResult: model.yearDiabtecPatientResult, - ) - ], - ), - ) - ], - ), - floatingActionButton: InkWell( - onTap: () { - Navigator.push(context, FadePage(page: AddBloodSugarPage(bloodSugarViewMode: model,))); - }, - child: Container( - width: 55, - height: 55, - decoration: BoxDecoration( - shape: BoxShape.circle, color:Theme.of(context).primaryColor), - child: Center( - child: Icon( - Icons.add, - color: Colors.white, - ), + appBarTitle: TranslationBase.of(context).bloodSugar, + // baseViewModel: model, + body: Column( + children: [ + TabBar( + controller: _tabController, + indicatorWeight: 3.0, + indicatorSize: TabBarIndicatorSize.tab, + labelColor: Color(0xff2B353E), + unselectedLabelColor: Color(0xff575757), + labelPadding: EdgeInsets.only(top: 15, bottom: 13, 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: [Text(TranslationBase.of(context).weekly), Text(TranslationBase.of(context).monthlyT), Text(TranslationBase.of(context).yearly)], + ), + Expanded( + child: TabBarView( + physics: BouncingScrollPhysics(), + controller: _tabController, + children: [ + BloodSugarWeeklyPage( + timeSeriesData: model.bloodWeekTimeSeriesData, + diabtecPatientResult: model.weekDiabtecPatientResult, + bloodSugarViewMode: model, + ), + BloodMonthlyPage( + timeSeriesData: model.monthTimeSeriesData, + diabtecPatientResult: model.monthDiabtecPatientResult, + bloodSugarViewMode: model, + ), + BloodYearPage( + timeSeriesData: model.yearTimeSeriesData, + diabtecPatientResult: model.yearDiabtecPatientResult, + bloodSugarViewMode: model, + ) + ], + ), + ) + ], + ), + floatingActionButton: Stack( + children: [ + Positioned( + bottom: 60, + right: projectViewModel.isArabic ? MediaQuery.of(context).size.width * .85 : 0, + child: InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: AddBloodSugarPage( + bloodSugarViewMode: model, + ))); + }, + child: Container( + width: 50, + height: 50, + decoration: BoxDecoration(shape: BoxShape.circle, color: Theme.of(context).primaryColor), + child: Center( + child: Icon( + Icons.add, + color: Colors.white, + ), + )), + ), + ), + ], + ), + bottomSheet: Container( + color: Theme.of(context).scaffoldBackgroundColor, + child: Padding( + padding: const EdgeInsets.all(12.0), + child: DefaultButton( + TranslationBase.of(context).sendEmail, + () { + showDialog( + context: context, + builder: (cxt) => ConfirmSendEmailDialog( + email: model.user!.emailAddress, + onTapSendEmail: () async { + GifLoaderDialogUtils.showMyDialog(context); + model.sendReportByEmail().then((value) { + GifLoaderDialogUtils.hideDialog(context); + if (model.state == ViewState.ErrorLocal) { + AppToast.showErrorToast(message: model.error); + } else { + AppToast.showSuccessToast( + message: TranslationBase.of(context).emailSentSuccessfully, + ); + } + }).catchError((e) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: model.error); + }); + }, + ), + ); + }, ), ), ), diff --git a/lib/pages/medical/my_trackers/blood_suger/blood_sugar_weekly_page.dart b/lib/pages/medical/my_trackers/blood_suger/blood_sugar_weekly_page.dart index 60f3293d..2b74395d 100644 --- a/lib/pages/medical/my_trackers/blood_suger/blood_sugar_weekly_page.dart +++ b/lib/pages/medical/my_trackers/blood_suger/blood_sugar_weekly_page.dart @@ -1,45 +1,43 @@ +import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/core/model/my_trakers/blood_sugar/DiabtecPatientResult.dart'; -import 'package:diplomaticquarterapp/core/model/my_trakers/chartData/WeekChartDate.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/blood_sugar_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; -import 'package:diplomaticquarterapp/pages/medical/my_trackers/widget/LineChartCurved.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/charts/app_time_series_chart.dart'; +import 'package:diplomaticquarterapp/widgets/charts/show_chart.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:charts_flutter/flutter.dart' as charts; import 'package:provider/provider.dart'; + import 'AddBloodSugarPage.dart'; class BloodSugarWeeklyPage extends StatelessWidget { - final List diabtecPatientResult; - final BloodSugarViewMode bloodSugarViewMode; - final List timeSeriesData; + final List? diabtecPatientResult; + final BloodSugarViewMode? bloodSugarViewMode; + final List? timeSeriesData; + ProjectViewModel? projectViewModel; - BloodSugarWeeklyPage( - {Key key, - this.diabtecPatientResult, - this.bloodSugarViewMode, - this.timeSeriesData}) - : super(key: key); + BloodSugarWeeklyPage({Key? key, this.diabtecPatientResult, this.bloodSugarViewMode, this.timeSeriesData}) : super(key: key); @override Widget build(BuildContext context) { - ProjectViewModel projectViewModel = Provider.of(context); + if (projectViewModel == null) projectViewModel = Provider.of(context); return AppScaffold( - body:timeSeriesData.isEmpty?Container(child: Center(child: Texts(TranslationBase.of(context).noDataAvailable),),): ListView( + body: ListView( children: [ Container( margin: EdgeInsets.only(top: 12, left: 8, right: 8), color: Colors.white, - child: LineChartCurved( - title: 'Sugar', - timeSeries: timeSeriesData, - indexes: timeSeriesData.length ~/ 5.5, + child: ShowChart( + title: TranslationBase.of(context).weight, + timeSeries: timeSeriesData!.isEmpty ? [TimeSeriesSales2(DateTime.now(), 0.0)] : timeSeriesData, + indexes: timeSeriesData!.length ~/ 5.5, + horizontalInterval: 2, ), ), SizedBox( @@ -55,13 +53,22 @@ class BloodSugarWeeklyPage extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Table( - border: TableBorder.symmetric( - inside: BorderSide(width: 2.0, color: Colors.grey[300]), - ), - children: - fullData(context, projectViewModel, bloodSugarViewMode), - ), + timeSeriesData!.isEmpty + ? Container( + child: Center( + child: Texts(TranslationBase.of(AppGlobal.context).noDataAvailable), + ), + ) + : Table( + columnWidths: { + 0: FlexColumnWidth(1.8), + 2: FlexColumnWidth(1.8), + }, + children: fullData(context, bloodSugarViewMode!), + ), + SizedBox( + height: 80, + ) ], ), ) @@ -70,193 +77,70 @@ class BloodSugarWeeklyPage extends StatelessWidget { ); } - List fullData( - BuildContext context, - ProjectViewModel projectViewModel, - BloodSugarViewMode bloodSugarViewMode) { + List fullData(BuildContext context, BloodSugarViewMode bloodSugarViewMode) { List tableRow = []; tableRow.add( TableRow( children: [ - Container( - child: Container( - decoration: BoxDecoration( - color: Theme.of(context).primaryColor, - borderRadius: BorderRadius.only( - topLeft: projectViewModel.isArabic - ? Radius.circular(0.0) - : Radius.circular(10.0), - topRight: projectViewModel.isArabic - ? Radius.circular(10.0) - : Radius.circular(0.0), - ), - ), - child: Center( - child: Texts( - TranslationBase.of(context).date, - color: Colors.white, - fontSize: 15, - ), - ), - height: 40, - ), - ), - Container( - child: Container( - decoration: BoxDecoration( - color: Theme.of(context).primaryColor, - ), - child: Center( - child: Texts( - TranslationBase.of(context).time, - color: Colors.white, - fontSize: 15, - ), - ), - height: 40), - ), - Container( - child: Container( - decoration: BoxDecoration( - color: Theme.of(context).primaryColor, - ), - child: Center( - child: Texts( - TranslationBase.of(context).measured, - color: Colors.white, - fontSize: 15, - ), - ), - height: 40), - ), - Container( - child: Container( - decoration: BoxDecoration( - color: Theme.of(context).primaryColor, - ), - child: Center( - child: Texts( - TranslationBase.of(context).value, - color: Colors.white, - fontSize: 15, - ), - ), - height: 40), - ), - Container( - child: Container( - decoration: BoxDecoration( - color: Theme.of(context).primaryColor, - borderRadius: BorderRadius.only( - topLeft: projectViewModel.isArabic - ? Radius.circular(10.0) - : Radius.circular(0.0), - topRight: projectViewModel.isArabic - ? Radius.circular(0.0) - : Radius.circular(10.0), - ), - ), - child: Center( - child: Texts( - TranslationBase.of(context).edit, - color: Colors.white, - fontSize: 15, - ), - ), - height: 40), - ), + Utils.tableColumnTitle(TranslationBase.of(context).date), + Utils.tableColumnTitle(TranslationBase.of(context).time), + Utils.tableColumnTitle(TranslationBase.of(context).measured), + Utils.tableColumnTitle(TranslationBase.of(context).value), + Utils.tableColumnTitle(TranslationBase.of(context).edit), ], ), ); - diabtecPatientResult.forEach( + diabtecPatientResult!.forEach( (diabtec) { tableRow.add( TableRow( children: [ - Container( - child: Container( - height: 70, - padding: EdgeInsets.all(10), - color: Colors.white, - child: Center( - child: Texts( - '${projectViewModel.isArabic ? DateUtil.getMonthDayYearDateFormattedAr(diabtec.dateChart):DateUtil.getMonthDayYearDateFormatted(diabtec.dateChart)} ', - textAlign: TextAlign.center, - fontSize: 12, - ), - ), - ), - ), - Container( - child: Container( - height: 70, - padding: EdgeInsets.all(10), - color: Colors.white, - child: Center( - child: Texts( - '${diabtec.dateChart.hour}:${diabtec.dateChart.minute}', - textAlign: TextAlign.center, - fontSize: 12, - ), - ), - ), - ), - Container( - child: Container( - height: 70, - padding: EdgeInsets.all(10), - color: Colors.white, - child: Center( - child: Texts( - '${diabtec.measuredDesc}', - textAlign: TextAlign.center, - fontSize: 12, - ), - ), - ), - ), - Container( - child: Container( - height: 70, - padding: EdgeInsets.all(10), - color: Colors.white, - child: Center( - child: Texts( - '${diabtec.resultValue}', - textAlign: TextAlign.center, - fontSize: 12, - ), - ), - ), - ), - Container( - child: InkWell( - onTap: () { - Navigator.push( - context, - FadePage( - page: AddBloodSugarPage( - isUpdate: true, - bloodSugarDate: diabtec.dateChart, - measuredTime: diabtec.measuredDesc, - bloodSugarValue: diabtec.resultValue.toString(), - lineItemNo: diabtec.lineItemNo, - measureUnitSelectedType: diabtec.unit, - bloodSugarViewMode: bloodSugarViewMode, + Utils.tableColumnValue(DateUtil.getDayMonthYearDateFormatted(diabtec.dateChart!), isCapitable: false, mProjectViewModel: projectViewModel!), + Utils.tableColumnValue(diabtec.dateChart!.hour.toString() + ':' + diabtec.dateChart!.minute.toString(), isCapitable: false, mProjectViewModel: projectViewModel!), + Utils.tableColumnValue(diabtec.measuredDesc!, isCapitable: false, mProjectViewModel: projectViewModel!), + Utils.tableColumnValue(diabtec.resultValue.toString(), isCapitable: false, mProjectViewModel: projectViewModel!), + Column(crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ + SizedBox(height: 12), + Container( + child: InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: AddBloodSugarPage( + isUpdate: true, + bloodSugarDate: diabtec.dateChart, + measuredTime: diabtec.measuredDesc, + bloodSugarValue: diabtec.resultValue.toString(), + lineItemNo: diabtec.lineItemNo, + measureUnitSelectedType: diabtec.unit, + bloodSugarViewMode: bloodSugarViewMode, + measuredSelectedType: diabtec.measuredDesc, + ), ), + ).then((value) { + if (bloodSugarViewMode.weekDiabtecPatientResult.isEmpty) { + timeSeriesData!.clear(); + } + }); + }, + child: Container( + // height: 70, + // padding: EdgeInsets.all(10), + child: Icon( + Icons.edit, + color: Color(0xff575757), ), - ); - }, - child: Container( - height: 70, - padding: EdgeInsets.all(10), - color: Colors.white, - child: Center( - child: Icon(Icons.edit), ), ), ), - ), + SizedBox(height: 6), + Divider( + height: 1, + color: Color(0xffEFEFEF), + thickness: 1, + ) + ]), ], ), ); diff --git a/lib/pages/medical/my_trackers/my_trackers.dart b/lib/pages/medical/my_trackers/my_trackers.dart index 5e5c4527..c6e7d5dc 100644 --- a/lib/pages/medical/my_trackers/my_trackers.dart +++ b/lib/pages/medical/my_trackers/my_trackers.dart @@ -1,115 +1,76 @@ +import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; +import 'package:diplomaticquarterapp/pages/medical/my_trackers/Weight/WeightHomePage.dart'; +import 'package:diplomaticquarterapp/pages/medical/my_trackers/blood_suger/blood_sugar_home_page.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.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'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'Weight/WeightHomePage.dart'; import 'blood_pressure/BloodPressureHomePage.dart'; -import 'blood_suger/blood_sugar_home_page.dart'; class MyTrackers extends StatelessWidget { @override Widget build(BuildContext context) { return AppScaffold( appBarTitle: TranslationBase.of(context).myTracker, - isShowAppBar: true, + showNewAppBar: true, + isShowDecPage: true, + showNewAppBarTitle: true, + backgroundColor: Color(0xffF8F8F8), + description: TranslationBase.of(context).infoTrackers, + imagesInfo: [ + ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-trackers/en/0.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-trackers/ar/0.png') + ], body: SingleChildScrollView( child: Container( - padding: EdgeInsets.all(12), - margin: EdgeInsets.all(12), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + child: GridView( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, childAspectRatio: 2 / 2, crossAxisSpacing: 12, mainAxisSpacing: 12), + physics: NeverScrollableScrollPhysics(), + padding: EdgeInsets.all(21), + shrinkWrap: true, children: [ - Expanded( - child: InkWell( - onTap: ()=> Navigator.push(context, FadePage(page: BloodSugarHomePage())), - child: Container( - margin: EdgeInsets.all(5), - width: MediaQuery.of(context).size.width*0.35, - height:MediaQuery.of(context).size.width*0.35 , - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - color: Colors.white - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Image.asset('assets/tracker/blood-suger.png',width: 60.0,), - SizedBox(height: 15,), - Texts(TranslationBase.of(context).bloodSugar), - ], - ), - ), - ), - ), - Expanded( - child: InkWell( - onTap: ()=> Navigator.push(context, FadePage(page: BloodPressureHomePage())), - child: Container( - margin: EdgeInsets.all(5), - width: MediaQuery.of(context).size.width*0.35, - height:MediaQuery.of(context).size.width*0.35 , - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - color: Colors.white - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Image.asset('assets/tracker/blood-pressure.png',width: 60.0,), - SizedBox(height: 15,), - Texts(TranslationBase.of(context).bloodPressure), - ], - ), - ), - ), - ), - ], + InkWell( + onTap: () { + Navigator.push(context, FadePage(page: BloodSugarHomePage())); + }, + child: MedicalProfileItem( + title: TranslationBase.of(context).bloodSugar, + imagePath: 'assets/tracker/blood-suger.png', + subTitle: "", + isPngImage: true, + width: 45.0, + height: 45.0, + ), ), - Row( - //mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - Expanded( - child: InkWell( - onTap: ()=> Navigator.push(context, FadePage(page: WeightHomePage())), - child: Container( - margin: EdgeInsets.all(5), - width: MediaQuery.of(context).size.width*0.35, - height:MediaQuery.of(context).size.width*0.35 , - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - color: Colors.white - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Image.asset('assets/tracker/weight.png',width: 60.0,), - SizedBox(height: 15,), - Texts(TranslationBase.of(context).weight), - ], - ), - ), - ), - ), - Expanded( - child: Container(), - ), - ], + InkWell( + onTap: () { + Navigator.push(context, FadePage(page: BloodPressureHomePage())); + }, + child: MedicalProfileItem( + title: TranslationBase.of(context).bloodPressure, + imagePath: 'assets/tracker/blood-pressure.png', + subTitle: "", + isPngImage: true, + width: 45.0, + height: 45.0, + ), + ), + InkWell( + onTap: () { + Navigator.push(context, FadePage(page: WeightHomePage())); + }, + child: MedicalProfileItem( + title: TranslationBase.of(context).weight, + imagePath: 'assets/tracker/weight.png', + subTitle: "", + isPngImage: true, + width: 45.0, + height: 45.0, + ), ), - ], - ), - ), + ])), ), ); } diff --git a/lib/pages/medical/my_trackers/widget/CurvedChartBloodPressure.dart b/lib/pages/medical/my_trackers/widget/CurvedChartBloodPressure.dart index ac2349bc..5f093eb7 100644 --- a/lib/pages/medical/my_trackers/widget/CurvedChartBloodPressure.dart +++ b/lib/pages/medical/my_trackers/widget/CurvedChartBloodPressure.dart @@ -7,21 +7,16 @@ import 'package:flutter/material.dart'; import '../../../../Constants.dart'; class CurvedChartBloodPressure extends StatelessWidget { - final String title; - final List timeSeries1; - final List timeSeries2; - final int indexes; - final double horizontalInterval; + final String? title; + final List? timeSeries1; + final List? timeSeries2; + final int? indexes; + final double? horizontalInterval; - CurvedChartBloodPressure( - {this.title, - this.timeSeries1, - this.indexes, - this.timeSeries2, - this.horizontalInterval = 20.0}); + CurvedChartBloodPressure({this.title, this.timeSeries1, this.indexes, this.timeSeries2, this.horizontalInterval = 20.0}); - List xAxixs = List(); - List yAxixs = List(); + List xAxixs = []; + List yAxixs = []; @override Widget build(BuildContext context) { @@ -42,9 +37,8 @@ class CurvedChartBloodPressure extends StatelessWidget { height: 15, ), Text( - title, - style: TextStyle( - color: Colors.black, fontSize: 15, letterSpacing: 2), + title!, + style: TextStyle(color: Colors.black, fontSize: 15, letterSpacing: 2), textAlign: TextAlign.center, ), SizedBox( @@ -52,11 +46,10 @@ class CurvedChartBloodPressure extends StatelessWidget { ), Expanded( child: Padding( - padding: - const EdgeInsets.only(right: 18.0, left: 16.0, top: 15), + padding: const EdgeInsets.only(right: 18.0, left: 16.0, top: 15), child: LineChart( sampleData1(context), - swapAnimationDuration: const Duration(milliseconds: 250), + duration: const Duration(milliseconds: 250), ), ), ), @@ -72,9 +65,7 @@ class CurvedChartBloodPressure extends StatelessWidget { Container( width: 20, height: 20, - decoration: BoxDecoration( - shape: BoxShape.rectangle, - color: Theme.of(context).primaryColor), + decoration: BoxDecoration(shape: BoxShape.rectangle, color: Theme.of(context).primaryColor), ), SizedBox( width: 5, @@ -90,8 +81,7 @@ class CurvedChartBloodPressure extends StatelessWidget { Container( width: 20, height: 20, - decoration: BoxDecoration( - shape: BoxShape.rectangle, color: secondaryColor), + decoration: BoxDecoration(shape: BoxShape.rectangle, color: secondaryColor), ), SizedBox( width: 5, @@ -110,9 +100,9 @@ class CurvedChartBloodPressure extends StatelessWidget { } getXaxix() { - for (int index = 0; index < timeSeries1.length; index++) { - int mIndex = indexes * index; - if (mIndex < timeSeries1.length) { + for (int index = 0; index < timeSeries1!.length; index++) { + int mIndex = indexes! * index; + if (mIndex < timeSeries1!.length) { xAxixs.add(mIndex); } } @@ -124,54 +114,71 @@ class CurvedChartBloodPressure extends StatelessWidget { touchTooltipData: LineTouchTooltipData( tooltipBgColor: Colors.white, ), - touchCallback: (LineTouchResponse touchResponse) {}, + touchCallback: (touchEvent, LineTouchResponse? touchResponse) {}, handleBuiltInTouches: true, ), - gridData: FlGridData( - show: true, drawVerticalLine: true, drawHorizontalLine: true), + gridData: FlGridData(show: true, drawVerticalLine: true, drawHorizontalLine: true), titlesData: FlTitlesData( - bottomTitles: SideTitles( - showTitles: true, - getTextStyles: (value) => const TextStyle( - color: Colors.black, - fontSize: 10, - ), - - margin: 22, - getTitles: (value) { - if (timeSeries1.length < 15) { - if (timeSeries1.length > value.toInt()) { - return '${timeSeries1[value.toInt()].time.month}/ ${timeSeries1[value.toInt()].time.year}'; - } else - return ''; - } else { - if (value.toInt() == 0) - return '${timeSeries1[value.toInt()].time.month}/ ${timeSeries1[value.toInt()].time.year}'; - if (value.toInt() == timeSeries1.length - 1) - return '${timeSeries1[value.toInt()].time.month}/ ${timeSeries1[value.toInt()].time.year}'; - if (xAxixs.contains(value.toInt())) { - return '${timeSeries1[value.toInt()].time.month}/ ${timeSeries1[value.toInt()].time.year}'; + bottomTitles: AxisTitles( + sideTitles: SideTitles( + showTitles: true, + getTitlesWidget: (value, TitleMeta) { + TextStyle style = TextStyle( + color: Colors.black, + fontSize: 10, + ); + if (timeSeries1!.length < 15) { + if (timeSeries1!.length > value.toInt()) { + return Text( + '${timeSeries1![value.toInt()].time.month}/ ${timeSeries1![value.toInt()].time.year}', + style: style, + ); + } else + //return Text(""); + return SizedBox(); + } else { + if (value.toInt() == 0) + return Text( + '${timeSeries1![value.toInt()].time.month}/ ${timeSeries1![value.toInt()].time.year}', + style: style, + ); + if (value.toInt() == timeSeries1!.length - 1) + return Text( + '${timeSeries1![value.toInt()].time.month}/ ${timeSeries1![value.toInt()].time.year}', + style: style, + ); + if (xAxixs.contains(value.toInt())) { + return Text( + '${timeSeries1![value.toInt()].time.month}/ ${timeSeries1![value.toInt()].time.year}', + style: style, + ); + } } - } - return ''; - }, - ), - leftTitles: SideTitles( - showTitles: true, - getTextStyles: (value) => const TextStyle( - color: Colors.black, - fontWeight: FontWeight.bold, - fontSize: 10, + return SizedBox(); + }, + + // margin: 22, ), - getTitles: (value) { - if (value.toInt() == 0) - return '${value.toInt()}'; - else if (value.toInt() % horizontalInterval == 0) - return '${value.toInt()}'; - else - return ''; - }, - margin: 12, + ), + leftTitles: AxisTitles( + sideTitles: SideTitles( + showTitles: true, + interval: getMaxY() - getMinY() <= 500 + ? 50 + : getMaxY() - getMinY() <= 1000 + ? 100 + : 200, + getTitlesWidget: (value, TitleMeta) { + TextStyle style = TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold, + fontSize: 10, + ); + return SizedBox(); + } + + // margin: 12, + ), ), ), borderData: FlBorderData( @@ -193,7 +200,7 @@ class CurvedChartBloodPressure extends StatelessWidget { ), ), minX: 0, - maxX: (timeSeries1.length - 1).toDouble(), + maxX: (timeSeries1!.length - 1).toDouble(), maxY: getMaxY() + 0.3, minY: getMinY(), lineBarsData: getData(context), @@ -202,11 +209,11 @@ class CurvedChartBloodPressure extends StatelessWidget { double getMaxY() { double max = 0; - timeSeries1.forEach((element) { + timeSeries1!.forEach((element) { double resultValueDouble = element.sales; if (resultValueDouble > max) max = resultValueDouble; }); - timeSeries2.forEach((element) { + timeSeries2!.forEach((element) { double resultValueDouble = element.sales; if (resultValueDouble > max) max = resultValueDouble; }); @@ -215,12 +222,12 @@ class CurvedChartBloodPressure extends StatelessWidget { } double getMinY() { - double min = timeSeries1[0].sales; - timeSeries1.forEach((element) { + double min = timeSeries1![0].sales; + timeSeries1!.forEach((element) { double resultValueDouble = element.sales; if (resultValueDouble < min) min = resultValueDouble; }); - timeSeries2.forEach((element) { + timeSeries2!.forEach((element) { double resultValueDouble = element.sales; if (resultValueDouble < min) min = resultValueDouble; }); @@ -231,20 +238,20 @@ class CurvedChartBloodPressure extends StatelessWidget { } List getData(context) { - List spots = List(); - for (int index = 0; index < timeSeries1.length; index++) { - spots.add(FlSpot(index.toDouble(), timeSeries1[index].sales)); + List spots = []; + for (int index = 0; index < timeSeries1!.length; index++) { + spots.add(FlSpot(index.toDouble(), timeSeries1![index].sales)); } - List spots2 = List(); - for (int index = 0; index < timeSeries2.length; index++) { - spots2.add(FlSpot(index.toDouble(), timeSeries2[index].sales)); + List spots2 = []; + for (int index = 0; index < timeSeries2!.length; index++) { + spots2.add(FlSpot(index.toDouble(), timeSeries2![index].sales)); } final LineChartBarData lineChartBarData1 = LineChartBarData( spots: spots, isCurved: true, - colors: [Colors.red], + color: Colors.red, barWidth: 5, isStrokeCapRound: true, dotData: FlDotData( @@ -257,7 +264,7 @@ class CurvedChartBloodPressure extends StatelessWidget { final LineChartBarData lineChartBarData2 = LineChartBarData( spots: spots2, isCurved: true, - colors: [Theme.of(context).primaryColor], + color: Theme.of(context).primaryColor, barWidth: 5, isStrokeCapRound: true, dotData: FlDotData( diff --git a/lib/pages/medical/my_trackers/widget/LineChartCurved.dart b/lib/pages/medical/my_trackers/widget/LineChartCurved.dart index eeff06dd..882cf034 100644 --- a/lib/pages/medical/my_trackers/widget/LineChartCurved.dart +++ b/lib/pages/medical/my_trackers/widget/LineChartCurved.dart @@ -5,26 +5,22 @@ import 'package:flutter/material.dart'; import '../../../../Constants.dart'; class LineChartCurved extends StatelessWidget { - final String title; - final List timeSeries; - final int indexes; - final double horizontalInterval; + final String? title; + final List? timeSeries; + final int? indexes; + final double? horizontalInterval; - LineChartCurved( - {this.title, - this.timeSeries, - this.indexes, - this.horizontalInterval = 20.0}); + LineChartCurved({this.title, this.timeSeries, this.indexes, this.horizontalInterval = 20.0}); - List xAxixs = List(); - List yAxixs = List(); + List xAxixs = []; + List yAxixs = []; @override Widget build(BuildContext context) { getXaxix(); getYaxix(); return AspectRatio( - aspectRatio: 1.1, + aspectRatio: 1.0, child: Container( decoration: const BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(18)), @@ -39,9 +35,8 @@ class LineChartCurved extends StatelessWidget { height: 4, ), Text( - title, - style: TextStyle( - color: Colors.black, fontSize: 15, letterSpacing: 2), + title!, + style: TextStyle(color: Colors.black, fontSize: 16, letterSpacing: -0.64, fontWeight: FontWeight.w600), textAlign: TextAlign.center, ), SizedBox( @@ -49,11 +44,10 @@ class LineChartCurved extends StatelessWidget { ), Expanded( child: Padding( - padding: const EdgeInsets.only( - right: 18.0, left: 16.0, top: 15, bottom: 15), + padding: const EdgeInsets.only(right: 18.0, left: 16.0), child: LineChart( sampleData1(context), - swapAnimationDuration: const Duration(milliseconds: 250), + duration: const Duration(milliseconds: 250), ), ), ), @@ -69,84 +63,172 @@ class LineChartCurved extends StatelessWidget { } getXaxix() { - for (int index = 0; index < timeSeries.length; index++) { - int mIndex = indexes * index; - if (mIndex < timeSeries.length) { + for (int index = 0; index < timeSeries!.length; index++) { + int mIndex = indexes! * index; + if (mIndex < timeSeries!.length) { xAxixs.add(mIndex); } } } getYaxix() { - int indexess = (timeSeries.length * 0.30).toInt(); - for (int index = 0; index < timeSeries.length; index++) { + int indexess = (timeSeries!.length * 0.30).toInt(); + for (int index = 0; index < timeSeries!.length; index++) { int mIndex = indexess * index; - if (mIndex < timeSeries.length) { - yAxixs.add(timeSeries[mIndex].sales); + if (mIndex < timeSeries!.length) { + yAxixs.add(timeSeries![mIndex].sales); } } } + // LineChartData sampleData1(context) { + // return LineChartData( + // lineTouchData: LineTouchData( + // touchTooltipData: LineTouchTooltipData( + // tooltipBgColor: Colors.white, + // ), + // touchCallback: (LineTouchResponse touchResponse) {}, + // handleBuiltInTouches: true, + // ), + // gridData: FlGridData(show: true, drawVerticalLine: true, drawHorizontalLine: true, horizontalInterval: 14, verticalInterval: 14), + // titlesData: FlTitlesData( + // bottomTitles: SideTitles( + // showTitles: true, + // getTextStyles: (value) => const TextStyle( + // color: Colors.black, + // fontSize: 10, + // ), + // // rotateAngle: 90, + // //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 ''; + // } 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 ''; + // }, + // ), + // leftTitles: SideTitles( + // showTitles: true, + // // interval:getMaxY() - getMinY() <=500?50:getMaxY() - getMinY() <=1000?100:200, + // interval: 3, + // getTextStyles: (value) => const TextStyle( + // color: Colors.black, + // fontWeight: FontWeight.bold, + // fontSize: 10, + // ), + // + // margin: 12, + // ), + // ), + // borderData: FlBorderData( + // show: true, + // border: const Border( + // bottom: BorderSide( + // color: Colors.black, + // width: 0.5, + // ), + // left: BorderSide( + // color: Colors.black, + // ), + // right: BorderSide( + // color: Colors.black, + // ), + // top: BorderSide( + // color: Colors.transparent, + // ), + // ), + // ), + // minX: 0, + // maxX: (timeSeries.length - 1).toDouble(), + // maxY: getMaxY() + 0.3, + // minY: 0, + // //getMinY(), + // lineBarsData: getData(context), + // ); + // } + LineChartData sampleData1(context) { return LineChartData( lineTouchData: LineTouchData( touchTooltipData: LineTouchTooltipData( tooltipBgColor: Colors.white, ), - touchCallback: (LineTouchResponse touchResponse) {}, + touchCallback: (touchEvent, LineTouchResponse? touchResponse) {}, handleBuiltInTouches: true, ), - gridData: FlGridData( - horizontalInterval: horizontalInterval, - show: true, - drawVerticalLine: true, - drawHorizontalLine: true), + gridData: FlGridData(show: true, drawVerticalLine: true, drawHorizontalLine: true, horizontalInterval: 14, verticalInterval: 14), titlesData: FlTitlesData( - bottomTitles: SideTitles( - showTitles: true, - getTextStyles: (value) => const TextStyle( - color: Colors.black, - fontSize: 10, - ), - // rotateAngle: 90, - //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 ''; - } 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 ''; - }, - ), - leftTitles: SideTitles( - showTitles: true, - getTextStyles: (value) => const TextStyle( - color: Colors.black, - fontWeight: FontWeight.bold, - fontSize: 10, + bottomTitles: AxisTitles( + axisNameSize: 22, + sideTitles: SideTitles( + showTitles: true, +//Changed By Aamir + // rotateAngle: -65, + // margin: 22, + getTitlesWidget: (value, title) { + TextStyle style = TextStyle( + color: Colors.black, + fontSize: 10, + ); + if (timeSeries!.length < 15) { + if (timeSeries!.length > value.toInt()) { + return Text( + '${timeSeries![value.toInt()].time.month}/ ${timeSeries![value.toInt()].time.year}', + style: style, + ); + } else + return SizedBox(); + } else { + if (value.toInt() == 0) return Text('${timeSeries![value.toInt()].time.month}/ ${timeSeries![value.toInt()].time.year}', style: style); + if (value.toInt() == timeSeries!.length - 1) return Text('${timeSeries![value.toInt()].time.month}/ ${timeSeries![value.toInt()].time.year}', style: style); + if (xAxixs.contains(value.toInt())) { + return Text( + '${timeSeries![value.toInt()].time.month}/ ${timeSeries![value.toInt()].time.year}', + style: style, + ); + } + } + return SizedBox(); + }, + ), ), - getTitles: (value) { - if (value.toInt() == 0) - return '${value.toInt()}'; - else if (value.toInt() % horizontalInterval == 0) - return '${value.toInt()}'; - else - return ''; - }, - margin: 12, - ), - ), + leftTitles: AxisTitles( + sideTitles: SideTitles( + showTitles: true, + interval: 3.0, + getTitlesWidget: (val, title) { + TextStyle styl = const TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold, + fontSize: 10, + ); + return Text( + "", + style: styl, + ); + } + // interval: getMaxY() - getMinY() <= 500 + // ? getMaxY() - getMinY() <= 50 + // ? 10 + // : 10 + // : getMaxY() - getMinY() <= 1000 + // ? 100 + // : getMaxY() - getMinY() >= 10000 + // ? 5000 + // : 200, + //margin: 12, + ), + )), borderData: FlBorderData( show: true, border: const Border( @@ -166,16 +248,17 @@ class LineChartCurved extends StatelessWidget { ), ), minX: 0, - maxX: (timeSeries.length - 1).toDouble(), + maxX: (timeSeries!.length - 1).toDouble(), maxY: getMaxY() + 0.3, - minY: getMinY(), + minY: 0, + //getMinY(), lineBarsData: getData(context), ); } double getMaxY() { double max = 0; - timeSeries.forEach((element) { + timeSeries!.forEach((element) { double resultValueDouble = element.sales; if (resultValueDouble > max) max = resultValueDouble; }); @@ -184,8 +267,8 @@ class LineChartCurved extends StatelessWidget { } double getMinY() { - double min = timeSeries[0].sales; - timeSeries.forEach((element) { + double min = timeSeries!.isEmpty ? 0 : timeSeries!.first.sales; + timeSeries!.forEach((element) { double resultValueDouble = element.sales; if (resultValueDouble < min) min = resultValueDouble; }); @@ -195,18 +278,17 @@ class LineChartCurved extends StatelessWidget { } List getData(context) { - List spots = List(); - for (int index = 0; index < timeSeries.length; index++) { - spots.add(FlSpot(index.toDouble(), timeSeries[index].sales)); + List spots = []; + for (int index = 0; index < timeSeries!.length; index++) { + spots.add(FlSpot(index.toDouble(), timeSeries![index].sales)); } final LineChartBarData lineChartBarData1 = LineChartBarData( spots: spots, isCurved: true, - colors: [secondaryColor], - barWidth: 5, + color: secondaryColor, + barWidth: 1.5, isStrokeCapRound: true, - curveSmoothness: 0.12, dotData: FlDotData( show: false, ), diff --git a/lib/pages/medical/my_trackers/widget/MonthCurvedChartBloodPressure.dart b/lib/pages/medical/my_trackers/widget/MonthCurvedChartBloodPressure.dart index 135d0a95..54228d1e 100644 --- a/lib/pages/medical/my_trackers/widget/MonthCurvedChartBloodPressure.dart +++ b/lib/pages/medical/my_trackers/widget/MonthCurvedChartBloodPressure.dart @@ -1,3 +1,4 @@ +import 'package:diplomaticquarterapp/Constants.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/charts/app_time_series_chart.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; @@ -5,23 +6,22 @@ import 'package:fl_chart/fl_chart.dart'; import 'package:flutter/material.dart'; class MonthCurvedChartBloodPressure extends StatelessWidget { - final String title; - final List timeSeries1; - final List timeSeries2; - final int indexes; - final double horizontalInterval; + final String? title; + final List? timeSeries1; + final List? timeSeries2; + final int? indexes; + final double? horizontalInterval; - MonthCurvedChartBloodPressure( - {this.title, this.timeSeries1, this.indexes, this.timeSeries2, this.horizontalInterval = 20.0}); + MonthCurvedChartBloodPressure({this.title, this.timeSeries1, this.indexes, this.timeSeries2, this.horizontalInterval = 20.0}); - List xAxixs = List(); - List yAxixs = List(); + List xAxixs = []; + List yAxixs = []; @override Widget build(BuildContext context) { getXaxix(); return AspectRatio( - aspectRatio: 1.1, + aspectRatio: 1.0, child: Container( decoration: const BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(18)), @@ -36,9 +36,8 @@ class MonthCurvedChartBloodPressure extends StatelessWidget { height: 15, ), Text( - title, - style: TextStyle( - color: Colors.black, fontSize: 15, letterSpacing: 2), + title!, + style: TextStyle(color: Colors.black, fontSize: 15, letterSpacing: 2), textAlign: TextAlign.center, ), SizedBox( @@ -46,11 +45,10 @@ class MonthCurvedChartBloodPressure extends StatelessWidget { ), Expanded( child: Padding( - padding: - const EdgeInsets.only(right: 18.0, left: 16.0, top: 15), + padding: const EdgeInsets.only(right: 18.0, left: 16.0, top: 15), child: LineChart( sampleData1(context), - swapAnimationDuration: const Duration(milliseconds: 250), + duration: const Duration(milliseconds: 250), ), ), ), @@ -66,9 +64,7 @@ class MonthCurvedChartBloodPressure extends StatelessWidget { Container( width: 20, height: 20, - decoration: BoxDecoration( - shape: BoxShape.rectangle, - color: Theme.of(context).primaryColor), + decoration: BoxDecoration(shape: BoxShape.rectangle, color: Theme.of(context).primaryColor), ), SizedBox( width: 5, @@ -84,8 +80,7 @@ class MonthCurvedChartBloodPressure extends StatelessWidget { Container( width: 20, height: 20, - decoration: BoxDecoration( - shape: BoxShape.rectangle, color: Colors.grey), + decoration: BoxDecoration(shape: BoxShape.rectangle, color: secondaryColor), ), SizedBox( width: 5, @@ -104,9 +99,9 @@ class MonthCurvedChartBloodPressure extends StatelessWidget { } getXaxix() { - for (int index = 0; index < timeSeries1.length; index++) { - int mIndex = indexes * index; - if (mIndex < timeSeries1.length) { + for (int index = 0; index < timeSeries1!.length; index++) { + int mIndex = indexes! * index; + if (mIndex < timeSeries1!.length) { xAxixs.add(mIndex); } } @@ -118,39 +113,55 @@ class MonthCurvedChartBloodPressure extends StatelessWidget { touchTooltipData: LineTouchTooltipData( tooltipBgColor: Colors.white, ), - touchCallback: (LineTouchResponse touchResponse) {}, + touchCallback: (touchEvent, LineTouchResponse? touchResponse) {}, handleBuiltInTouches: true, ), - gridData: FlGridData( - show: true, drawVerticalLine: true, drawHorizontalLine: true), + gridData: FlGridData(show: true, drawVerticalLine: true, drawHorizontalLine: true, horizontalInterval: 14, verticalInterval: 14), titlesData: FlTitlesData( - bottomTitles: SideTitles( - showTitles: true, - getTextStyles: (value) => const TextStyle( - color: Colors.black, - fontSize: 10, - ), - margin: 22, - getTitles: (value) { - return ''; - }, + bottomTitles: AxisTitles( + sideTitles: SideTitles( + showTitles: true, + getTitlesWidget: (value, title) { + TextStyle styl = const TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold, + fontSize: 10, + ); + return Text( + timeSeries1![value.toInt()].time.toString(), + style: styl, + ); + }), ), - leftTitles: SideTitles( - showTitles: true, - getTextStyles: (value) => const TextStyle( - color: Colors.black, - fontWeight: FontWeight.bold, - fontSize: 10, - ), - getTitles: (value) { - if (value.toInt() == 0) - return '${value.toInt()}'; - else if (value.toInt() % horizontalInterval == 0) - return '${value.toInt()}'; - else - return ''; - }, - margin: 12, + leftTitles: AxisTitles( + sideTitles: SideTitles( + showTitles: true, + interval: getMaxY() - getMinY() <= 500 + ? 10 + : getMaxY() - getMinY() <= 1000 + ? 30 + : 40, + getTitlesWidget: (value, title) { + TextStyle styl = const TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold, + fontSize: 10, + ); + return Text( + timeSeries1![value.toInt()].time.toString(), + style: styl, + ); + } + // getTitles: (value) { + // // if (value.toInt() == 0) + // // return '${value.toInt()}'; + // // else if (value.toInt() % horizontalInterval == 0) + // // return '${value.toInt()}'; + // // else + // return '${value.toInt()}'; + // }, + // margin: 12, + ), ), ), borderData: FlBorderData( @@ -172,7 +183,7 @@ class MonthCurvedChartBloodPressure extends StatelessWidget { ), ), minX: 0, - maxX: (timeSeries1.length - 1).toDouble(), + maxX: (timeSeries1!.length - 1).toDouble(), maxY: getMaxY() + 0.3, minY: getMinY(), lineBarsData: getData(context), @@ -181,11 +192,11 @@ class MonthCurvedChartBloodPressure extends StatelessWidget { double getMaxY() { double max = 0; - timeSeries1.forEach((element) { + timeSeries1!.forEach((element) { double resultValueDouble = element.sales; if (resultValueDouble > max) max = resultValueDouble; }); - timeSeries2.forEach((element) { + timeSeries2!.forEach((element) { double resultValueDouble = element.sales; if (resultValueDouble > max) max = resultValueDouble; }); @@ -194,12 +205,12 @@ class MonthCurvedChartBloodPressure extends StatelessWidget { } double getMinY() { - double min = timeSeries1[0].sales; - timeSeries1.forEach((element) { + double min = timeSeries1![0].sales; + timeSeries1!.forEach((element) { double resultValueDouble = element.sales; if (resultValueDouble < min) min = resultValueDouble; }); - timeSeries2.forEach((element) { + timeSeries2!.forEach((element) { double resultValueDouble = element.sales; if (resultValueDouble < min) min = resultValueDouble; }); @@ -210,21 +221,21 @@ class MonthCurvedChartBloodPressure extends StatelessWidget { } List getData(context) { - List spots = List(); - for (int index = 0; index < timeSeries1.length; index++) { - spots.add(FlSpot(index.toDouble(), timeSeries1[index].sales)); + List spots = []; + for (int index = 0; index < timeSeries1!.length; index++) { + spots.add(FlSpot(index.toDouble(), timeSeries1![index].sales)); } - List spots2 = List(); - for (int index = 0; index < timeSeries2.length; index++) { - spots2.add(FlSpot(index.toDouble(), timeSeries2[index].sales)); + List spots2 = []; + for (int index = 0; index < timeSeries2!.length; index++) { + spots2.add(FlSpot(index.toDouble(), timeSeries2![index].sales)); } final LineChartBarData lineChartBarData1 = LineChartBarData( spots: spots, isCurved: true, - colors: [Colors.red], - barWidth: 5, + color: Colors.red, + barWidth: 1.5, isStrokeCapRound: true, dotData: FlDotData( show: false, @@ -236,8 +247,8 @@ class MonthCurvedChartBloodPressure extends StatelessWidget { final LineChartBarData lineChartBarData2 = LineChartBarData( spots: spots2, isCurved: true, - colors: [Theme.of(context).primaryColor], - barWidth: 5, + color: Theme.of(context).primaryColor, + barWidth: 1.5, isStrokeCapRound: true, dotData: FlDotData( show: false, diff --git a/lib/pages/medical/my_trackers/widget/MonthLineChartCurved.dart b/lib/pages/medical/my_trackers/widget/MonthLineChartCurved.dart index 607f3ab0..9a6616f9 100644 --- a/lib/pages/medical/my_trackers/widget/MonthLineChartCurved.dart +++ b/lib/pages/medical/my_trackers/widget/MonthLineChartCurved.dart @@ -5,19 +5,15 @@ import 'package:flutter/material.dart'; import '../../../../Constants.dart'; class MonthLineChartCurved extends StatelessWidget { - final String title; - final List timeSeries; - final int indexes; - final double horizontalInterval; + final String? title; + final List? timeSeries; + final int? indexes; + final double? horizontalInterval; - MonthLineChartCurved( - {this.title, - this.timeSeries, - this.indexes, - this.horizontalInterval = 15.0}); + MonthLineChartCurved({this.title, this.timeSeries, this.indexes, this.horizontalInterval = 15.0}); - List xAxixs = List(); - List yAxixs = List(); + List xAxixs = []; + List yAxixs = []; @override Widget build(BuildContext context) { @@ -39,9 +35,8 @@ class MonthLineChartCurved extends StatelessWidget { height: 4, ), Text( - title, - style: TextStyle( - color: Colors.black, fontSize: 15, letterSpacing: 2), + title!, + style: TextStyle(color: Colors.black, fontSize: 16, letterSpacing: -0.64, fontWeight: FontWeight.w600), textAlign: TextAlign.center, ), SizedBox( @@ -49,11 +44,10 @@ class MonthLineChartCurved extends StatelessWidget { ), Expanded( child: Padding( - padding: const EdgeInsets.only( - right: 18.0, left: 16.0, top: 15, bottom: 15), + padding: const EdgeInsets.only(right: 18.0, left: 16.0, top: 15, bottom: 15), child: LineChart( sampleData1(context), - swapAnimationDuration: const Duration(milliseconds: 250), + duration: const Duration(milliseconds: 250), ), ), ), @@ -69,20 +63,20 @@ class MonthLineChartCurved extends StatelessWidget { } getXaxix() { - for (int index = 0; index < timeSeries.length; index++) { - int mIndex = indexes * index; - if (mIndex < timeSeries.length) { + for (int index = 0; index < timeSeries!.length; index++) { + int mIndex = indexes! * index; + if (mIndex < timeSeries!.length) { xAxixs.add(mIndex); } } } getYaxix() { - int indexess = (timeSeries.length * 0.30).toInt(); - for (int index = 0; index < timeSeries.length; index++) { + int indexess = (timeSeries!.length * 0.30).toInt(); + for (int index = 0; index < timeSeries!.length; index++) { int mIndex = indexess * index; - if (mIndex < timeSeries.length) { - yAxixs.add(timeSeries[mIndex].sales); + if (mIndex < timeSeries!.length) { + yAxixs.add(timeSeries![mIndex].sales); } } } @@ -93,42 +87,63 @@ class MonthLineChartCurved extends StatelessWidget { touchTooltipData: LineTouchTooltipData( tooltipBgColor: Colors.white, ), - touchCallback: (LineTouchResponse touchResponse) {}, + touchCallback: (touchEvent, LineTouchResponse? touchResponse) {}, handleBuiltInTouches: true, ), gridData: FlGridData( - horizontalInterval: horizontalInterval, - show: true, - drawVerticalLine: true, - drawHorizontalLine: true), + horizontalInterval: 12, + show: true, + drawVerticalLine: true, + drawHorizontalLine: true, + verticalInterval: 12, + ), titlesData: FlTitlesData( - bottomTitles: SideTitles( - showTitles: true, - getTextStyles: (value) => const TextStyle( - color: Colors.black, - fontSize: 10, - ), - margin: 22, - getTitles: (value) { - return '${value.toInt()}'; - }, + bottomTitles: AxisTitles( + sideTitles: SideTitles( + showTitles: true, + getTitlesWidget: (value, title) { + TextStyle styl = const TextStyle( + color: Colors.black, + fontSize: 10, + ); + return Text( + '${value.toInt()}', + style: styl, + ); + } + // margin: 22, + ), ), - leftTitles: SideTitles( - showTitles: true, - getTextStyles: (value) => const TextStyle( - color: Colors.black, - fontWeight: FontWeight.bold, - fontSize: 10, + leftTitles: AxisTitles( + sideTitles: SideTitles( + showTitles: true, + getTitlesWidget: (value, title) { + TextStyle styl = const TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold, + fontSize: 10, + ); + return Text( + '', + style: styl, + ); + }, + interval: getMaxY() - getMinY() <= 500 + ? 50 + : getMaxY() - getMinY() <= 1000 + ? 100 + : 200, + + // getTitles: (value) { + // if (value.toInt() == 0) + // return '${value.toInt()}'; + // else if (value.toInt() % horizontalInterval == 0) + // return '${value.toInt()}'; + // else + // return ''; + // }, + // margin: 12, ), - getTitles: (value) { - if (value.toInt() == 0) - return '${value.toInt()}'; - else if (value.toInt() % horizontalInterval == 0) - return '${value.toInt()}'; - else - return ''; - }, - margin: 12, ), ), borderData: FlBorderData( @@ -150,7 +165,7 @@ class MonthLineChartCurved extends StatelessWidget { ), ), minX: 0, - maxX: (timeSeries.length - 1).toDouble(), + maxX: (timeSeries!.length - 1).toDouble(), maxY: getMaxY() + 0.3, minY: getMinY(), lineBarsData: getData(context), @@ -159,7 +174,7 @@ class MonthLineChartCurved extends StatelessWidget { double getMaxY() { double max = 0; - timeSeries.forEach((element) { + timeSeries!.forEach((element) { double resultValueDouble = element.sales; if (resultValueDouble > max) max = resultValueDouble; }); @@ -168,8 +183,8 @@ class MonthLineChartCurved extends StatelessWidget { } double getMinY() { - double min = timeSeries[0].sales; - timeSeries.forEach((element) { + double min = timeSeries![0].sales; + timeSeries!.forEach((element) { double resultValueDouble = element.sales; if (resultValueDouble < min) min = resultValueDouble; }); @@ -179,16 +194,19 @@ class MonthLineChartCurved extends StatelessWidget { } List getData(context) { - List spots = List(); - for (int index = 0; index < timeSeries.length; index++) { - spots.add(FlSpot(index.toDouble(), timeSeries[index].sales)); + List spots = []; + if (timeSeries!.length == 0) { + spots.add(FlSpot(0, 0)); + } + for (int index = 0; index < timeSeries!.length; index++) { + spots.add(FlSpot(index.toDouble(), timeSeries![index].sales)); } final LineChartBarData lineChartBarData1 = LineChartBarData( spots: spots, isCurved: true, - colors: [secondaryColor], - barWidth: 5, + color: secondaryColor, + barWidth: 1.5, isStrokeCapRound: true, curveSmoothness: 0.0, dotData: FlDotData( diff --git a/lib/pages/medical/my_trackers/widget/TabBarWidget.dart b/lib/pages/medical/my_trackers/widget/TabBarWidget.dart index 199dbc54..779a6b98 100644 --- a/lib/pages/medical/my_trackers/widget/TabBarWidget.dart +++ b/lib/pages/medical/my_trackers/widget/TabBarWidget.dart @@ -5,10 +5,10 @@ import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -class TabBarWidget extends StatelessWidget with PreferredSizeWidget{ +class TabBarWidget extends StatelessWidget { final TabController tabController; - const TabBarWidget({Key key, this.tabController}) : super(key: key); + const TabBarWidget({Key? key, required this.tabController}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/lib/pages/medical/patient_sick_leave_page.dart b/lib/pages/medical/patient_sick_leave_page.dart index 196b5d79..e6802145 100644 --- a/lib/pages/medical/patient_sick_leave_page.dart +++ b/lib/pages/medical/patient_sick_leave_page.dart @@ -1,13 +1,21 @@ import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; +import 'package:diplomaticquarterapp/core/model/sick_leave/admission_status_for_sick_leave.dart'; import 'package:diplomaticquarterapp/core/model/sick_leave/sick_leave.dart'; +import 'package:diplomaticquarterapp/core/service/medical/labs_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/patient_sick_leave_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; -import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/pages/medical/sickleave_workplace_update_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'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/widgets/data_display/medical/doctor_card.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/confirm_send_email_dialog.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'; @@ -18,19 +26,17 @@ class PatientSickLeavePage extends StatefulWidget { } class _PatientSickLeavePageState extends State { - List imagesInfo = List(); + List imagesInfo = []; @override void initState() { - imagesInfo.add(ImagesInfo( - imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/sick-leaves/en/0.png', - imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/sick-leaves/ar/0.png')); + imagesInfo.add( + ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/sick-leaves/en/0.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/sick-leaves/ar/0.png')); super.initState(); } @override Widget build(BuildContext context) { - ProjectViewModel projectViewModel = Provider.of(context); return BaseView( onModelReady: (model) => model.getSickLeave(), builder: (_, model, w) => AppScaffold( @@ -38,45 +44,152 @@ class _PatientSickLeavePageState extends State { appBarTitle: TranslationBase.of(context).sickLeaves, description: TranslationBase.of(context).infoSickLeaves, infoList: TranslationBase.of(context).infoSickLeavePoints, + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: Color(0xffF7F7F7), imagesInfo: imagesInfo, baseViewModel: model, - body: Container( - margin: EdgeInsets.all(12), - child: ListView.builder( - itemCount: model.sickLeaveList.length, - itemBuilder: (context, index) => DoctorCard( - isLiveCareAppointment: model.sickLeaveList[index].isLiveCareAppointment, - name: model.sickLeaveList[index].doctorName, - date:projectViewModel.isArabic? DateUtil.getMonthDayYearDateFormattedAr(model.sickLeaveList[index].requestDate):DateUtil.getMonthDayYearDateFormatted(model.sickLeaveList[index].requestDate), - profileUrl: model.sickLeaveList[index].doctorImageURL, - rat: model.sickLeaveList[index].actualDoctorRate.toDouble(), - subName: model.sickLeaveList[index].projectName, - isInOutPatient: model.sickLeaveList[index].isInOutPatient, - onEmailTap: () { - showConfirmMessage(model, index); - }, - ), - ), - ), + body: model.sickLeaveList.isNotEmpty + ? ListView.separated( + physics: BouncingScrollPhysics(), + itemCount: model.sickLeaveList.length, + padding: EdgeInsets.all(21), + separatorBuilder: (context, index) => SizedBox(height: 14), + itemBuilder: (context, index) => DoctorCard( + isLiveCareAppointment: model.sickLeaveList[index].isLiveCareAppointment, + name: model.sickLeaveList[index].doctorName, + date: model.sickLeaveList[index].appointmentDate, + profileUrl: model.sickLeaveList[index].doctorImageURL, + rating: model.sickLeaveList[index].actualDoctorRate!.toDouble(), + subName: model.sickLeaveList[index].clinicName, + isSortByClinic: false, + isInOutPatient: model.sickLeaveList[index].isInOutPatient, + isSickLeave: true, + sickLeaveStatus: model.sickLeaveList[index].status ?? 0, + onEmailTap: () { + showConfirmMessage(model, index); + }, + ), + ) + : getNoDataWidget(context), ), ); } void showConfirmMessage(PatientSickLeaveViewMode model, int index) { + if (model.sickLeaveList[index].status == 1) { + openWorkPlaceUpdatePage(model.sickLeaveList[index].requestNo!, model.sickLeaveList[index]!.setupID!, model, index, model.sickLeaveList[index]!.projectID!); + } else if (model.sickLeaveList[index].status == 2) { + // showEmailDialog(model, index); + model.sendSickLeaveEmail( + message: TranslationBase.of(context).emailSentSuccessfully, + requestNo: model.sickLeaveList[index].requestNo!, + doctorName: model.sickLeaveList[index].doctorName!, + projectName: model.sickLeaveList[index].projectName!, + setupID: model.sickLeaveList[index].setupID!, + projectID: model.sickLeaveList[index].projectID!, + isDownload: true); + } else { + showApprovalDialog(); + } + } + + void showApprovalDialog() { + ConfirmDialog dialog = new ConfirmDialog( + context: context, + confirmMessage: TranslationBase.of(context).needApproval, + okText: TranslationBase.of(context).ok, + cancelText: TranslationBase.of(context).cancel_nocaps, + okFunction: () { + Navigator.of(context).pop(); + }, + cancelFunction: () => {}); + dialog.showAlertDialog(context); + } + + void showEmailDialog(PatientSickLeaveViewMode model, int index) { showDialog( context: context, - child: ConfirmSendEmailDialog( - email: model.user.emailAddress, + builder: (cxt) => ConfirmSendEmailDialog( + email: model.user!.emailAddress!, onTapSendEmail: () { model.sendSickLeaveEmail( message: TranslationBase.of(context).emailSentSuccessfully, - requestNo: model.sickLeaveList[index].requestNo, - doctorName: model.sickLeaveList[index].doctorName, - projectName: model.sickLeaveList[index].projectName, - setupID: model.sickLeaveList[index].setupID, - projectID: model.sickLeaveList[index].projectID); + requestNo: model.sickLeaveList[index].requestNo!, + doctorName: model.sickLeaveList[index].doctorName!, + projectName: model.sickLeaveList[index].projectName!, + setupID: model.sickLeaveList[index].setupID!, + projectID: model.sickLeaveList[index].projectID!, + isDownload: true); + model.getSickLeave(); }, ), ); } + + Future openWorkPlaceUpdatePage(int requestNumber, String setupID, PatientSickLeaveViewMode model, int index, int projectID) async { + if (model.sickLeaveList[index].admissionNo != 0 && model.sickLeaveList[index].admissionNo != null) { + getSickLeaveStatusByAdmissionNo(requestNumber, setupID, model, index, projectID); + } else { + openWorkPlaceUpdatePageFunc(requestNumber, setupID, model, index, projectID); + } + } + + void getSickLeaveStatusByAdmissionNo(int requestNumber, String setupID, PatientSickLeaveViewMode model, int index, int projectID) { + AdmissionStatusForSickLeave admissionStatusForSickLeave; + + LabsService service = new LabsService(); + GifLoaderDialogUtils.showMyDialog(context); + + service.getSickLeaveStatusByAdmissionNo(model.sickLeaveList[index]!.projectID!, model.sickLeaveList[index].admissionNo!).then((res) { + print(res); + GifLoaderDialogUtils.hideDialog(context); + if (res != null && res["List_GetSickLeaveStatusByAdmissionNo"] != null) { + if (res["List_GetSickLeaveStatusByAdmissionNo"].length != 0) { + admissionStatusForSickLeave = AdmissionStatusForSickLeave.fromJson(res["List_GetSickLeaveStatusByAdmissionNo"][0]); + if (admissionStatusForSickLeave.status != 6) { + AppToast.showErrorToast(message: TranslationBase.of(context).sickLeaveAdmittedPatient); + } else { + openWorkPlaceUpdatePageFunc(requestNumber, setupID, model, index, projectID); + } + } else { + openWorkPlaceUpdatePageFunc(requestNumber, setupID, model, index, projectID); + } + } else { + openWorkPlaceUpdatePageFunc(requestNumber, setupID, model, index, projectID); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } + + void openWorkPlaceUpdatePageFunc(int requestNumber, String setupID, PatientSickLeaveViewMode model, int index, int projectID) { + Navigator.push( + context, + FadePage( + page: WorkplaceUpdatePage( + requestNumber: requestNumber, + setupID: setupID, + projectID: projectID, + ), + ), + ).then( + (value) { + print(value); + if (value != null && value == true) { + model.getSickLeave(); + // showEmailDialog(model, index); + model.sendSickLeaveEmail( + message: TranslationBase.of(context).emailSentSuccessfully, + requestNo: model.sickLeaveList[index].requestNo!, + doctorName: model.sickLeaveList[index].doctorName!, + projectName: model.sickLeaveList[index].projectName!, + setupID: model.sickLeaveList[index].setupID!, + projectID: model.sickLeaveList[index].projectID!, + isDownload: true); + } + }, + ); + } } diff --git a/lib/pages/medical/prescriptions/PrescriptionIDeliveryAddressPage.dart b/lib/pages/medical/prescriptions/PrescriptionIDeliveryAddressPage.dart index 8f04d3a0..ebc2bd4a 100644 --- a/lib/pages/medical/prescriptions/PrescriptionIDeliveryAddressPage.dart +++ b/lib/pages/medical/prescriptions/PrescriptionIDeliveryAddressPage.dart @@ -1,5 +1,7 @@ import 'dart:async'; +import 'dart:io'; +import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/core/model/prescriptions/Prescriptions.dart'; import 'package:diplomaticquarterapp/core/model/prescriptions/prescription_report.dart'; import 'package:diplomaticquarterapp/core/model/prescriptions/prescription_report_enh.dart'; @@ -8,10 +10,16 @@ import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/add_n import 'package:diplomaticquarterapp/core/viewModels/medical/PrescriptionDeliveryViewModel.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/location_page.dart'; +import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/h2o/h20_setting.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/services/permission/permission_service.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/location_util.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/uitl/utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/radio_selection_dialog.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/select_location_dialog.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; @@ -25,25 +33,21 @@ import 'PrescriptionOrderOverveiw.dart'; class PrescriptionDeliveryAddressPage extends StatefulWidget { final Prescriptions prescriptions; - final List prescriptionReportList; - final List prescriptionReportEnhList; + final List? prescriptionReportList; + final List? prescriptionReportEnhList; - const PrescriptionDeliveryAddressPage( - {Key key, - this.prescriptions, - this.prescriptionReportList, - this.prescriptionReportEnhList}) - : super(key: key); + const PrescriptionDeliveryAddressPage({Key? key, required this.prescriptions, this.prescriptionReportList, this.prescriptionReportEnhList}) : super(key: key); @override - _PrescriptionDeliveryAddressPageState createState() => - _PrescriptionDeliveryAddressPageState(); + _PrescriptionDeliveryAddressPageState createState() => _PrescriptionDeliveryAddressPageState(); } -class _PrescriptionDeliveryAddressPageState - extends State { - AddressInfo _selectedAddress; +class _PrescriptionDeliveryAddressPageState extends State { + late AddressInfo _selectedAddress = AddressInfo(); + int _selectedAddressIndex = -1; Completer _controller = Completer(); + late ProjectViewModel projectViewModel; + late LocationUtils locationUtils; CameraPosition _kGooglePlex = CameraPosition( target: LatLng(24.665011045779107, 46.73502189439707), @@ -56,241 +60,273 @@ class _PrescriptionDeliveryAddressPageState @override void initState() { super.initState(); - _getCurrentLocation(); + locationUtils = new LocationUtils(isShowConfirmDialog: true, context: context); + WidgetsBinding.instance.addPostFrameCallback((_) => locationUtils.getCurrentLocation()); } - _getCurrentLocation() async { - await Geolocator.getLastKnownPosition().then((value) { - latitude = value.latitude; - latitude = value.longitude; - _kGooglePlex = CameraPosition( - target: LatLng(latitude, longitude), - zoom: 14.4746, - ); - }).catchError((e) { - latitude = 24.665011045779107; - latitude = 46.73502189439707; - }); - } + // _getCurrentLocation() async { + // if (await PermissionService.isLocationEnabled()) { + // await Geolocator.getLastKnownPosition().then((value) { + // latitude = value.latitude; + // longitude = value.longitude; + // _kGooglePlex = CameraPosition( + // target: LatLng(latitude, longitude), + // zoom: 14.4746, + // ); + // }).catchError((e) { + // latitude = 24.665011045779107; + // longitude = 46.73502189439707; + // }); + // } else { + // if (Platform.isAndroid) { + // Utils.showPermissionConsentDialog(AppGlobal.context, TranslationBase.of(AppGlobal.context).locationPermissionDialog, () { + // Geolocator.getLastKnownPosition().then((value) { + // latitude = value.latitude; + // latitude = value.longitude; + // _kGooglePlex = CameraPosition( + // target: LatLng(latitude, longitude), + // zoom: 14.4746, + // ); + // }).catchError((e) { + // latitude = 24.665011045779107; + // latitude = 46.73502189439707; + // }); + // }); + // } else { + // await Geolocator.getLastKnownPosition().then((value) { + // latitude = value.latitude; + // latitude = value.longitude; + // _kGooglePlex = CameraPosition( + // target: LatLng(latitude, longitude), + // zoom: 14.4746, + // ); + // }).catchError((e) { + // latitude = 24.665011045779107; + // latitude = 46.73502189439707; + // }); + // } + // } + // } @override Widget build(BuildContext context) { - ProjectViewModel projectViewModel = Provider.of(context); + projectViewModel = Provider.of(context); return BaseView( onModelReady: (model) => model.getCustomerInfo(), builder: (_, model, w) => AppScaffold( - isShowAppBar: true, - appBarTitle: TranslationBase.of(context).shippingAddresss, - baseViewModel: model, - body: Container( - height: MediaQuery.of(context).size.height * 0.65, - child: SingleChildScrollView( - physics: BouncingScrollPhysics(), - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SizedBox( - height: 8, - ), - InkWell( - onTap: () { - confirmSelectLocationDialog(model.addressesList); - }, - child: Container( - margin: EdgeInsets.only(left: 10, right: 10, top: 15), - height: 50, - decoration: BoxDecoration( - border: Border.all(color: Colors.grey), - borderRadius: BorderRadius.circular(7), - color: Colors.white, - shape: BoxShape.rectangle, - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Container( - child: Text( - getAddressName(), + isShowAppBar: true, + appBarTitle: TranslationBase.of(context).shippingAddresss, + baseViewModel: model, + showNewAppBarTitle: true, + showNewAppBar: true, + backgroundColor: CustomColors.appBackgroudGrey2Color, + body: Container( + child: Column( + children: [ + Expanded( + child: SingleChildScrollView( + padding: EdgeInsets.all(21), + physics: BouncingScrollPhysics(), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + CommonDropDownView(TranslationBase.of(context).selectAddress, getAddressName(), () { + List list = [ + for (int i = 0; i < model.addressesList.length; i++) RadioSelectionDialogModel(model.addressesList[i].address1!, i), + ]; + + showDialog( + context: context, + builder: (cxt) => RadioSelectionDialog( + listData: list, + isScrollable: true, + selectedIndex: _selectedAddressIndex, + onValueSelected: (index) { + _selectedAddressIndex = index; + _selectedAddress = model.addressesList[index]; + List latLongArr = _selectedAddress!.latLong!.split(','); + + latitude = double.parse(latLongArr[0]); + longitude = double.parse(latLongArr[1]); + markers = Set(); + markers.add( + Marker( + markerId: MarkerId( + _selectedAddress!.latLong.hashCode.toString(), + ), + position: LatLng(latitude, longitude), ), - margin: EdgeInsets.only(left: 10, right: 10), + ); + _kGooglePlex = CameraPosition( + target: LatLng(latitude, longitude), + zoom: 14.4746, + ); + setState(() {}); + }, + ), + ); + }).withBorderedContainer, + SizedBox(height: 12), + InkWell( + onTap: () async { + Navigator.push( + context, + FadePage( + page: LocationPage( + // latitude: latitude, + // longitude: longitude, ), ), - ), - Icon( - Icons.arrow_drop_down, - size: 22, - color: Colors.grey, - ) - ], + ).then((value) { + if (value != null && value is AddNewAddressRequestModel) { + setState(() { + _selectedAddress = AddressInfo( + id: value.customer!.id.toString(), + email: value.customer!.email, + firstName: value.customer!.addresses![0].firstName, + lastName: value.customer!.addresses![0].lastName, + address1: value.customer!.addresses![0].address1, + address2: value.customer!.addresses![0].address2, + city: value.customer!.addresses![0].city, + country: value.customer!.addresses![0].country, + phoneNumber: value.customer!.addresses![0].phoneNumber, + latLong: value.customer!.addresses![0].latLong, + company: value.customer!.addresses![0].company, + countryId: value.customer!.addresses![0].countryId, + createdOnUtc: value.customer!.addresses![0].createdOnUtc, + customerAttributes: value.customer!.addresses![0].customerAttributes, + faxNumber: value.customer!.addresses![0].faxNumber, + province: value.customer!.addresses![0].province, + stateProvinceId: value.customer!.addresses![0].stateProvinceId, + zipPostalCode: value.customer!.addresses![0].zipPostalCode, + ); + List latLongArr = _selectedAddress!.latLong!.split(','); + + latitude = double.parse(latLongArr[0]); + longitude = double.parse(latLongArr[1]); + markers = Set(); + markers.add( + Marker( + markerId: MarkerId( + _selectedAddress!.latLong.hashCode.toString(), + ), + position: LatLng(latitude, longitude), + ), + ); + _kGooglePlex = CameraPosition( + target: LatLng(latitude, longitude), + zoom: 14.4746, + ); + }); + } + }); + }, + child: Row( + children: [ + Icon(Icons.add_circle_outline_sharp), + mWidth(12), + Text( + TranslationBase.of(context).addNewAddress, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + letterSpacing: -0.46, + ), + ), + ], + ), ), - ), - ), - SizedBox( - height: 10, - ), - _selectedAddress == null - ? Container( - child: Image.asset( - projectViewModel.isArabic - ? 'assets/images/pharmacy/shipping_image_ar.png' - : 'assets/images/pharmacy/shipping_image.png', - height: 300, - ), - ) - : Padding( - padding: const EdgeInsets.all(8.0), + SizedBox(height: 12), + if (_selectedAddress != null) + Container( + decoration: cardRadius(15), + padding: const EdgeInsets.all(12.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Padding( - padding: const EdgeInsets.all(8.0), + Text( + TranslationBase.of(context).selectAddress + ":", + style: TextStyle(fontSize: 14, color: Color(0xff575757), fontWeight: FontWeight.w600, letterSpacing: -0.56), + ), + mHeight(12), + Container( + height: 175, + decoration: containerColorRadiusBorder(Colors.white, 12, Color(0xffDDDDDD)), + clipBehavior: Clip.antiAlias, child: Container( - decoration: BoxDecoration( - border: Border.all(color: Colors.grey)), - height: 200, - child: GoogleMap( - mapType: MapType.normal, - markers: markers, - initialCameraPosition: _kGooglePlex, - onMapCreated: - (GoogleMapController controller) { - _controller.complete(controller); - }, + decoration: cardRadius(10), + clipBehavior: Clip.antiAlias, + margin: const EdgeInsets.all(0), + child: Image.network( + "https://maps.googleapis.com/maps/api/staticmap?center=" + + _kGooglePlex.target.latitude.toString() + + "," + + _kGooglePlex.target.longitude.toString() + + "&zoom=16&size=600x300&maptype=roadmap&markers=color:red%7C" + + _kGooglePlex.target.latitude.toString() + + "," + + _kGooglePlex.target.longitude.toString() + + "&key=AIzaSyCyDbWUM9d_sBUGIE8PcuShzPaqO08NSC8", + width: double.infinity, + height: double.infinity, + fit: BoxFit.cover, ), ), ), - SizedBox( - height: 10, + SizedBox(height: 18), + Text( + TranslationBase.of(context).shippingAddresss + ":", + style: TextStyle(fontSize: 14, color: Color(0xff575757), fontWeight: FontWeight.w600, letterSpacing: -0.56), ), - Texts( - TranslationBase.of(context).shippingAddresss), - SizedBox( - height: 10, + SizedBox(height: 2), + Text( + '${model.user!.firstName} ${model.user!.lastName}', + style: TextStyle(fontSize: 12, color: Color(0xff2B353E), fontWeight: FontWeight.w600, letterSpacing: -0.48), ), - Texts( - '${model.user.firstName} ${model.user.lastName}'), - SizedBox( - height: 10, + Text( + _selectedAddress!.address1 ??"", + style: TextStyle(fontSize: 12, color: Color(0xff2B353E), fontWeight: FontWeight.w600, letterSpacing: -0.48), ), - Texts(_selectedAddress.address1), - SizedBox( - height: 10, + Text( + _selectedAddress!.address2 ??"", + style: TextStyle(fontSize: 12, color: Color(0xff2B353E), fontWeight: FontWeight.w600, letterSpacing: -0.48), ), - Texts(_selectedAddress.address2), - SizedBox( - height: 10, + Text( + (_selectedAddress!.city) ??"" + " " + (_selectedAddress!.country ?? ""), + style: TextStyle(fontSize: 12, color: Color(0xff2B353E), fontWeight: FontWeight.w600, letterSpacing: -0.48), ), - Texts(_selectedAddress.city + - " " + - _selectedAddress.country), ], ), ) - ], - ), - ), - ), - bottomSheet: Container( - width: double.infinity, - height: MediaQuery.of(context).size.height * 0.25, - color: Colors.grey[100], - child: Column( - children: [ - Divider(), - Container( - width: MediaQuery.of(context).size.width * 0.8, - child: Button( - label: - TranslationBase.of(context).addNewAddress.toUpperCase(), - onTap: () { - Navigator.push( - context, - FadePage( - page: LocationPage( - latitude: latitude, - longitude: longitude, - )), - ).then((value) { - if (value != null && - value is AddNewAddressRequestModel) { - setState(() { - _selectedAddress = AddressInfo( - id: value.customer.id.toString(), - email: value.customer.email, - firstName: value.customer.addresses[0].firstName, - lastName: value.customer.addresses[0].lastName, - address1: value.customer.addresses[0].address1, - address2: value.customer.addresses[0].address2, - city: value.customer.addresses[0].city, - country: value.customer.addresses[0].country, - phoneNumber: value.customer.addresses[0].phoneNumber, - latLong: value.customer.addresses[0].latLong, - company: value.customer.addresses[0].company, - countryId: value.customer.addresses[0].countryId, - createdOnUtc: value.customer.addresses[0].createdOnUtc, - customerAttributes: value.customer.addresses[0].customerAttributes, - faxNumber: value.customer.addresses[0].faxNumber, - province: value.customer.addresses[0].province, - stateProvinceId: value.customer.addresses[0].stateProvinceId, - zipPostalCode: value.customer.addresses[0].zipPostalCode, - - ); - List latLongArr = _selectedAddress.latLong.split(','); - - latitude = double.parse(latLongArr[0]); - longitude = double.parse(latLongArr[1]); - markers = Set(); - markers.add( - Marker( - markerId: MarkerId( - _selectedAddress.latLong.hashCode.toString(), - ), - position: LatLng(latitude, longitude), - ), - ); - _kGooglePlex = CameraPosition( - target: LatLng(latitude, longitude), - zoom: 14.4746, - ); - }); - } - }); - }, + ], ), ), - Container( - width: MediaQuery.of(context).size.width * 0.8, - child: Button( - label: - TranslationBase.of(context).continues.toUpperCase(), - disabled: _selectedAddress == null, - backgroundColor: _selectedAddress == null - ? Colors.green[300] - : Colors.green[700], - onTap: () { + ), + DefaultButton( + TranslationBase.of(context).continues.toUpperCase(), + _selectedAddress == null + ? null + : () { Navigator.push( context, FadePage( page: PrescriptionOrderOverview( latitude: latitude, longitude: longitude, - prescriptionReportEnhList: - widget.prescriptionReportEnhList, - prescriptionReportList: - widget.prescriptionReportList, + prescriptionReportEnhList: widget.prescriptionReportEnhList!, + prescriptionReportList: widget.prescriptionReportList!, prescriptions: widget.prescriptions, selectedAddress: _selectedAddress, ), ), ); }, - )) - ], - ), - )), + disabledColor: CustomColors.grey2, + ).insideContainer, + ], + ), + ), + ), ); } @@ -299,13 +335,13 @@ class _PrescriptionDeliveryAddressPageState ) { showDialog( context: context, - child: SelectLocationDialog( + builder: (cxt) => SelectLocationDialog( addresses: addresses, selectedAddress: _selectedAddress, onValueSelected: (value) { setState(() { _selectedAddress = value; - List latLongArr = value.latLong.split(','); + List latLongArr = value.latLong!.split(','); latitude = double.parse(latLongArr[0]); longitude = double.parse(latLongArr[1]); @@ -313,7 +349,7 @@ class _PrescriptionDeliveryAddressPageState markers.add( Marker( markerId: MarkerId( - _selectedAddress.latLong.hashCode.toString(), + _selectedAddress!.latLong.hashCode.toString(), ), position: LatLng(latitude, longitude), ), @@ -329,9 +365,6 @@ class _PrescriptionDeliveryAddressPageState } String getAddressName() { - if (_selectedAddress != null) - return _selectedAddress.address1; - else - return TranslationBase.of(context).selectAddress; + return _selectedAddress!=null && _selectedAddress!.address1 !=null? _selectedAddress!.address1! : ""; } } diff --git a/lib/pages/medical/prescriptions/PrescriptionOrderOverveiw.dart b/lib/pages/medical/prescriptions/PrescriptionOrderOverveiw.dart index bad43a02..f8b0b876 100644 --- a/lib/pages/medical/prescriptions/PrescriptionOrderOverveiw.dart +++ b/lib/pages/medical/prescriptions/PrescriptionOrderOverveiw.dart @@ -5,27 +5,26 @@ import 'package:diplomaticquarterapp/core/model/prescriptions/prescription_repor import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/customer_addresses_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/PrescriptionDeliveryViewModel.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; -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/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'; class PrescriptionOrderOverview extends StatelessWidget { final Prescriptions prescriptions; - final List prescriptionReportList; - final List prescriptionReportEnhList; - final AddressInfo selectedAddress; - final double latitude; - final double longitude; - PrescriptionOrderOverview( - {Key key, - this.prescriptions, - this.prescriptionReportList, - this.prescriptionReportEnhList, this.selectedAddress, this.latitude, this.longitude}); + final List? prescriptionReportList; + final List? prescriptionReportEnhList; + final AddressInfo? selectedAddress; + final double? latitude; + final double? longitude; + + PrescriptionOrderOverview({Key? key, required this.prescriptions, this.prescriptionReportList, this.prescriptionReportEnhList, this.selectedAddress, this.latitude, this.longitude}); @override Widget build(BuildContext context) { @@ -34,148 +33,189 @@ class PrescriptionOrderOverview extends StatelessWidget { isShowAppBar: true, appBarTitle: TranslationBase.of(context).orderOverview, baseViewModel: model, + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: CustomColors.appBackgroudGrey2Color, body: Container( - height: MediaQuery.of(context).size.height * 0.8, + height: double.infinity, child: Column( children: [ - if (!prescriptions.isInOutPatient) - ...List.generate( - prescriptionReportList.length, - (index) => Container( - width: double.infinity, - margin: EdgeInsets.only(top: 10, left: 10, right: 10), - padding: EdgeInsets.all(8.0), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.all( - Radius.circular(10.0), - ), - border: - Border.all(color: Colors.grey[200], width: 0.5), + Expanded( + child: Column( + children: [ + if (!prescriptions.isInOutPatient!) + Container( + margin: EdgeInsets.all(12), + decoration: cardRadius(12), + clipBehavior: Clip.antiAlias, + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Column( + children: [ + ...List.generate( + prescriptionReportList!.length, + (index) => Container( + margin: EdgeInsets.all(0.0), + decoration: cardRadius(0), + child: Row( + children: [ + ClipRRect( + borderRadius: BorderRadius.all(Radius.circular(5)), + child: Image.network( + prescriptionReportList![index].imageSRCUrl!, + fit: BoxFit.cover, + width: 60, + height: 70, + ), + ), + SizedBox( + width: 10, + ), + Expanded( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Center( + child: Text( + prescriptionReportList![index].itemDescription!.isNotEmpty + ? prescriptionReportList![index].itemDescription! + : prescriptionReportList![index].itemDescriptionN!, + style: TextStyle(fontFamily: prescriptionReportList![index].itemDescription!.isNotEmpty ? 'Poppins' : 'Cairo'))), + )), + ], + ), + )) + ], ), - child: Row( - children: [ - ClipRRect( - borderRadius: - BorderRadius.all(Radius.circular(5)), - child: Image.network( - prescriptionReportList[index].imageSRCUrl, - fit: BoxFit.cover, - width: 60, - height: 70, + ), + ) + else + Container( + margin: EdgeInsets.all(12), + decoration: cardRadius(12), + clipBehavior: Clip.antiAlias, + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ...List.generate( + prescriptionReportEnhList!.length, + (index) => Container( + margin: EdgeInsets.all(0.0), + // decoration: cardRadius(0), + child: Row( + children: [ + // 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), + Expanded( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + (prescriptionReportList![index].itemDescription!.isNotEmpty + ? prescriptionReportList![index].itemDescription! + : prescriptionReportList![index].itemDescriptionN! ?? ''), + style: TextStyle( + fontFamily: prescriptionReportList![index].itemDescription!.isNotEmpty ? 'Poppins' : 'Cairo', + letterSpacing: -0.64, + color: Color(0xff2E303A), + fontSize: 16.0, + fontWeight: FontWeight.w600)), + ], + ), + ), + ), + ], + ), ), - ), - SizedBox( - width: 10, - ), - Expanded( - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Center( - child: Texts(prescriptionReportList[index] - .itemDescription - .isNotEmpty - ? prescriptionReportList[index] - .itemDescription - : prescriptionReportList[index] - .itemDescriptionN)), - )), - Icon( - Icons.arrow_forward_ios, - size: 18, - color: Colors.grey[500], ) ], ), - )) - else - ...List.generate( - prescriptionReportEnhList.length, - (index) => Container( - margin: EdgeInsets.all(8.0), - color: Colors.white, - child: Row( - children: [ - ClipRRect( - borderRadius: BorderRadius.all(Radius.circular(5)), - child: Image.network( - prescriptionReportEnhList[index].imageSRCUrl, - fit: BoxFit.cover, - width: 60, - height: 70, - ), - ), - SizedBox( - width: 10, - ), - Expanded( - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts(prescriptionReportEnhList[index] - .itemDescription), - ], - ), - ), ), - Icon( - Icons.arrow_forward_ios, - size: 18, - color: Colors.grey[500], - ) - ], - ), - ), - ) - ], - ), - ), - bottomSheet: Container( - width: double.infinity, - height: MediaQuery.of(context).size.height * 0.15, - color: Colors.grey[100], - child: Column( - children: [ - SizedBox(height: 12,), + ), + ], + ), + ), Container( - width: MediaQuery.of(context).size.width * 0.8, - child: SecondaryButton( - label: TranslationBase.of(context).submit.toUpperCase(), - color: Colors.green[800], - onTap: () async { - showDialog( - context: context, - child: ConfirmWithMessageDialog( - message: TranslationBase.of(context).confirmPrescription, - okTitle: TranslationBase.of(context).ok, - onTap: () async { - GifLoaderDialogUtils.showMyDialog(context); - await model.insertDeliveryOrder(lineItemNo: 0, - longitude: longitude, - latitude: latitude,appointmentNo: prescriptions.appointmentNo, - dischargeID: prescriptions.dischargeNo,createdBy: model.user.patientID) - .then((value) { - GifLoaderDialogUtils.hideDialog(context); - if (model.state == ViewState.ErrorLocal) - showErrorDialog(context,model.error); - else - { - Navigator.pop(context); + // decoration: cardRadius(0), + margin: EdgeInsets.zero, + child: Container( + width: double.infinity, + margin: EdgeInsets.all(12), + child: DefaultButton( + TranslationBase.of(context).submit.toUpperCase(), + () async { + showDialog( + context: context, + builder: (cxt) => ConfirmWithMessageDialog( + message: TranslationBase.of(context).confirmPrescription, + okTitle: TranslationBase.of(context).ok, + onTap: () async { + GifLoaderDialogUtils.showMyDialog(context); + await model + .insertDeliveryOrder( + lineItemNo: 1, + longitude: longitude, + latitude: latitude, + appointmentNo: prescriptions.appointmentNo, + dischargeID: prescriptions.dischargeNo, + projectID: prescriptions.projectID, + createdBy: model.user!.patientID) + .then((value) { + GifLoaderDialogUtils.hideDialog(context); + if (model.state == ViewState.ErrorLocal) + showErrorDialog(context, model.error); + else { Navigator.pop(context); Navigator.pop(context); + Navigator.pop(context, true); } - - }).catchError((e) { - GifLoaderDialogUtils.hideDialog(context); - }); - }, - ), - ); - - }, - )) + }).catchError((e) { + GifLoaderDialogUtils.hideDialog(context); + }); + }, + ), + ); + }, + )), + ) ], ), ), @@ -183,21 +223,18 @@ class PrescriptionOrderOverview extends StatelessWidget { ); } - void showErrorDialog(BuildContext context,String error) { + void showErrorDialog(BuildContext context, String error) { showDialog( context: context, - child: ConfirmWithMessageDialog( + builder: (cxt) => ConfirmWithMessageDialog( message: TranslationBase.of(context).youAlreadyHaveOrder, okTitle: TranslationBase.of(context).orderOverview, onTap: () { Navigator.pop(context); Navigator.pop(context); - Navigator.pop(context); - + Navigator.pop(context, true); }, ), ); - } - } diff --git a/lib/pages/medical/prescriptions/pharmacy_for_prescriptions_page.dart b/lib/pages/medical/prescriptions/pharmacy_for_prescriptions_page.dart index 96227fba..88b99b45 100644 --- a/lib/pages/medical/prescriptions/pharmacy_for_prescriptions_page.dart +++ b/lib/pages/medical/prescriptions/pharmacy_for_prescriptions_page.dart @@ -1,101 +1,102 @@ +import 'package:diplomaticquarterapp/core/model/contactus/get_hmg_locations.dart'; import 'package:diplomaticquarterapp/core/model/prescriptions/prescription_report.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/prescriptions_view_model.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:diplomaticquarterapp/widgets/hospital_location.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:maps_launcher/maps_launcher.dart'; -import 'package:url_launcher/url_launcher.dart'; class PharmacyForPrescriptionsPage extends StatelessWidget { - final PrescriptionReport prescriptionReport; + final itemID; + final PrescriptionReport? prescriptionReport; - PharmacyForPrescriptionsPage({Key key, this.prescriptionReport}); + PharmacyForPrescriptionsPage({Key? key, this.itemID, this.prescriptionReport}); @override Widget build(BuildContext context) { - return BaseView( - onModelReady: (model) => model.getListPharmacyForPrescriptions(itemId: prescriptionReport.itemID), - builder: (_, model, widget) => AppScaffold( - isShowAppBar: true, - appBarTitle: TranslationBase.of(context).availability, - baseViewModel: model, - body: ListView.builder( - itemBuilder: (context, index) => Container( - width: double.infinity, - margin: EdgeInsets.only(top: 10, left: 10, right: 10), - padding: EdgeInsets.all(8.0), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.all( - Radius.circular(10.0), - ), - border: Border.all(color: Colors.grey[200], width: 0.5), - ), - child: Row( - children: [ - ClipRRect( - borderRadius: BorderRadius.all(Radius.circular(5)), - child: Image.network( - model.pharmacyPrescriptionsList[index].projectImageURL, - fit: BoxFit.cover, - width: 60, - height: 70, + return BaseView( + onModelReady: (model) => model.getListPharmacyForPrescriptions(itemId: itemID), + builder: (_, model, widget) => AppScaffold( + isShowAppBar: true, + showNewAppBar: true, + showNewAppBarTitle: true, + appBarTitle: TranslationBase.of(context).availability, + baseViewModel: model, + body: Column( + children: [ + Padding( + padding: const EdgeInsets.fromLTRB(21, 21, 21, 10), + child: Container( + width: double.infinity, + padding: const EdgeInsets.only(left: 12, right: 12, top: 12, bottom: 12), + decoration: BoxDecoration( + borderRadius: BorderRadius.all( + Radius.circular(10.0), ), - ), - Expanded( - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts(model.pharmacyPrescriptionsList[index] - .locationDescription), - SizedBox( - height: 5, - ), - Texts(model.pharmacyPrescriptionsList[index].cityName), - ], + boxShadow: [ + BoxShadow( + color: Color(0xff000000).withOpacity(.05), + //spreadRadius: 5, + blurRadius: 27, + offset: Offset(0, -3), ), - ), - ), - InkWell( - onTap: () { - MapsLauncher.launchCoordinates( - double.parse( - model.pharmacyPrescriptionsList[index].latitude), - double.parse( - model.pharmacyPrescriptionsList[index].longitude)); - }, - child: Icon( - Icons.pin_drop, - size: 18, - color: Colors.red[900], - ), - ), - SizedBox( - width: 15, - ), - InkWell( - onTap: Feedback.wrapForTap((){ - launch("tel://${model.pharmacyPrescriptionsList[index].phoneNumber}"); - },context), - child: Container( - child: Icon( - Icons.call, - size: 18, - color: Colors.red[900], + ], + color: Colors.white), + child: Row( + children: [ + ClipRRect( + borderRadius: BorderRadius.all(Radius.circular(5)), + child: Image.network( + prescriptionReport?.imageSRCUrl ?? "", + fit: BoxFit.cover, + width: 60, + height: 70, ), ), - ) - ], + Expanded( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Center( + child: Texts((prescriptionReport?.itemDescription ?? "").isNotEmpty ? prescriptionReport?.itemDescription ?? "" : prescriptionReport?.itemDescriptionN ?? ''), + ), + ), + ) + ], + ), ), ), - itemCount: model.pharmacyPrescriptionsList.length, - ), + model.pharmacyPrescriptionsList.isNotEmpty == true + ? Expanded( + child: ListView.builder( + scrollDirection: Axis.vertical, + padding: EdgeInsets.fromLTRB(21, 11, 21, 21), + physics: BouncingScrollPhysics(), + itemBuilder: (context, index) { + GetHMGLocationsModel location = GetHMGLocationsModel(); + location.locationName = model.pharmacyPrescriptionsList[index].locationDescription; + location.cityName = model.pharmacyPrescriptionsList[index].cityName; + location.phoneNumber = model.pharmacyPrescriptionsList[index].phoneNumber; + location.latitude = model.pharmacyPrescriptionsList[index].latitude; + location.longitude = model.pharmacyPrescriptionsList[index].longitude; + location.distanceInKilometers = model.pharmacyPrescriptionsList[index].distanceInKilometers; + return HospitalLocation(location, showCity: true); + }, + itemCount: model.pharmacyPrescriptionsList.length, + ), + ) + : Padding( + padding: const EdgeInsets.only(top: 65.0), + child: Texts( + TranslationBase.of(context).thisItemIsNotAvailable, + textAlign: TextAlign.center, + ), + ), + ], ), - ); + ), + ); } } diff --git a/lib/pages/medical/prescriptions/prescription_details_inp.dart b/lib/pages/medical/prescriptions/prescription_details_inp.dart new file mode 100644 index 00000000..b446fed2 --- /dev/null +++ b/lib/pages/medical/prescriptions/prescription_details_inp.dart @@ -0,0 +1,275 @@ +import 'package:diplomaticquarterapp/core/model/prescriptions/Prescriptions.dart'; +import 'package:diplomaticquarterapp/core/model/prescriptions/prescription_report.dart'; +import 'package:diplomaticquarterapp/core/model/prescriptions/prescription_report_inp.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/extensions/string_extensions.dart'; +import 'package:diplomaticquarterapp/models/header_model.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/widgets/reminder_dialog.dart'; +import 'package:diplomaticquarterapp/pages/medical/prescriptions/pharmacy_for_prescriptions_page.dart'; +import 'package:diplomaticquarterapp/uitl/CalendarUtils.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:diplomaticquarterapp/widgets/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'; +import 'package:jiffy/jiffy.dart'; +import 'package:provider/provider.dart'; + +class PrescriptionDetailsPageINP extends StatelessWidget { + final PrescriptionReportINP? prescriptionReport; + final Prescriptions prescriptions; + + PrescriptionDetailsPageINP({Key? key, this.prescriptionReport, required this.prescriptions}); + + @override + Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + return AppScaffold( + isShowAppBar: true, + showNewAppBar: true, + showNewAppBarTitle: true, + appBarTitle: TranslationBase.of(context).prescriptions, + body: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + DoctorHeader( + headerModel: HeaderModel( + prescriptions.doctorName!, + prescriptions.doctorID!, + prescriptions.doctorImageURL!, + prescriptions.speciality ?? [""], + "", + prescriptions.name!, + DateUtil.convertStringToDate(prescriptions.appointmentDate!), + DateUtil.formatDateToTime(DateUtil.convertStringToDate(prescriptions.appointmentDate!)), + prescriptions.nationalityFlagURL ?? "", + prescriptions.doctorRate, + prescriptions.actualDoctorRate, + prescriptions.noOfPatientsRate, + "", + ), + isNeedToShowButton: false, + ), + Expanded( + child: ListView( + physics: BouncingScrollPhysics(), + padding: EdgeInsets.all(21), + children: [ + Container( + padding: EdgeInsets.all(14), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all(Radius.circular(10.0)), + boxShadow: [ + BoxShadow( + color: Color(0xff000000).withOpacity(.05), + //spreadRadius: 5, + blurRadius: 27, + offset: Offset(0, -3), + ), + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Row( + children: [ + 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( + child: Text( + (prescriptionReport!.itemDescription!.isNotEmpty ? prescriptionReport!.itemDescription : prescriptionReport!.itemDescriptionN ?? '')!.toLowerCase().capitalizeFirstofEach, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.64), + ), + ) + ], + ), + SizedBox(height: 12), + Table(border: TableBorder(horizontalInside: BorderSide(width: 1, color: Colors.black, style: BorderStyle.solid)), children: [ + TableRow( + children: [ + Utils.tableColumnTitle(TranslationBase.of(context).route, showDivider: false), + Utils.tableColumnTitle(TranslationBase.of(context).frequency, showDivider: false), + Utils.tableColumnTitle(TranslationBase.of(context).dailyDoses, showDivider: false), + Utils.tableColumnTitle(TranslationBase.of(context).duration, showDivider: false) + ], + ), + TableRow( + children: [ + Utils.tableColumnValue(prescriptionReport?.routeN ?? '', isLast: true, mProjectViewModel: projectViewModel), + Utils.tableColumnValue(prescriptionReport?.frequencyN ?? '', isLast: true, mProjectViewModel: projectViewModel), + Utils.tableColumnValue(prescriptionReport?.doseDailyQuantity.toString() ?? '', isLast: true, mProjectViewModel: projectViewModel), + Utils.tableColumnValue(prescriptionReport?.days.toString() ?? '', isLast: true, mProjectViewModel: projectViewModel), + ], + ), + ]), + Text( + TranslationBase.of(context).remarks, + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.48), + ), + Text( + prescriptionReport!.remarks!, + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff575757), letterSpacing: -0.4, height: 16 / 10), + ), + ], + ), + ), + ], + ), + ), + Container( + color: Colors.white, + padding: EdgeInsets.only(top: 16, bottom: 16, right: 21, left: 21), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Expanded( + child: DefaultButton( + TranslationBase.of(context).availability, + () { + Navigator.push( + context, + FadePage( + page: PharmacyForPrescriptionsPage( + itemID: prescriptionReport!.itemID, + prescriptionReport: PrescriptionReport.fromJson(prescriptionReport!.toJson()), + ), + ), + ); + }, + iconData: Icons.location_on, + color: Color(0xff359846), + ), + ), + SizedBox(width: 10), + Expanded( + child: DefaultButton( + TranslationBase.of(context).addReminder, + () { + DateTime startDate = DateTime.now(); + DateTime endDate = DateTime(startDate.year, startDate.month, startDate.day + prescriptionReport!.days!); + + showReminderDialog( + context, + endDate, + "", + prescriptionReport!.itemID.toString(), + "", + "", + title: "${prescriptionReport!.itemDescriptionN} Prescription Reminder", + description: "${prescriptionReport!.itemDescriptionN} ${prescriptionReport!.frequencyN} ${prescriptionReport!.routeN} ", + onSuccess: () { + AppToast.showSuccessToast(message: TranslationBase.of(context).reminderSuccess); + }, + onMultiDateSuccess: (int selectedIndex) { + setCalender(context, prescriptionReport!.itemID.toString(), selectedIndex); + }, + ); + return; + }, + iconData: Icons.notifications_active, + color: Color(0xffD02127), + fontSize: 13.0, + //textColor: Color(0xff2B353E), + ), + ), + ], + ), + ), + ], + ), + ); + } + + setCalender(BuildContext context, String eventId, int reminderIndex) async { + CalendarUtils calendarUtils = await CalendarUtils.getInstance(); + int frequencyNumber = int.parse(prescriptionReport!.frequency!); + + DateTime actualDate = DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day, 8, 0); //Time will start at 8:00 AM from starting date + if (frequencyNumber == null) frequencyNumber = 1; //Some time frequency number is null so by default will be 2 + + int remainingDays = + prescriptionReport!.days! - (Jiffy.parseFromDateTime(DateTime.now()).diff(Jiffy.parseFromDateTime(DateUtil.convertStringToDate(prescriptionReport!.orderDate!)), unit: Unit.day).toInt()); + + GifLoaderDialogUtils.showMyDialog(context); + + for (int i = 0; i < remainingDays; i++) { + //event for number of days. + for (int j = 0; j < frequencyNumber; j++) { + // event for number of times per day. + if (j != 0) { + actualDate.add(new Duration(hours: 8)); // 8 hours addition for daily dose. + } + //Time subtraction from actual reminder time. like before 30, or 1 hour. + if (reminderIndex == 0) { + // Before 30 mints + actualDate = Jiffy.parseFromDateTime(actualDate).subtract(minutes: 30).dateTime; + // dateTime.add(new Duration(minutes: -30)); + } else if (reminderIndex == 1) { + // Before 1 hour + // dateTime.add(new Duration(minutes: -60)); + actualDate = Jiffy.parseFromDateTime(actualDate).subtract(hours: 1).dateTime; + } else if (reminderIndex == 2) { + // Before 1 hour and 30 mints + // dateTime.add(new Duration(minutes: -90)); + actualDate = Jiffy.parseFromDateTime(actualDate).subtract(hours: 1, minutes: 30).dateTime; + } else if (reminderIndex == 3) { + // Before 2 hours + // dateTime.add(new Duration(minutes: -120)); + actualDate = Jiffy.parseFromDateTime(actualDate).subtract(hours: 2).dateTime; + } + calendarUtils + .createOrUpdateEvent( + title: "${prescriptionReport!.itemDescriptionN} Prescription Reminder", + description: "${prescriptionReport!.itemDescriptionN} ${prescriptionReport!.frequencyN} ${prescriptionReport!.routeN} ", + scheduleDateTime: actualDate, + eventId: eventId + (i.toString() + j.toString()), //event id with varitions + ) + .then((value) {}); + actualDate = DateTime(actualDate.year, actualDate.month, actualDate.day, 8, 0); + } + actualDate = Jiffy.parseFromDateTime(actualDate).add(days: 1).dateTime; + print(actualDate); + } + AppToast.showSuccessToast(message: TranslationBase.of(context).reminderSuccess); + GifLoaderDialogUtils.hideDialog(context); + } +} diff --git a/lib/pages/medical/prescriptions/prescription_details_page.dart b/lib/pages/medical/prescriptions/prescription_details_page.dart index f40999c2..4ee85086 100644 --- a/lib/pages/medical/prescriptions/prescription_details_page.dart +++ b/lib/pages/medical/prescriptions/prescription_details_page.dart @@ -1,293 +1,242 @@ +import 'dart:collection'; +import 'dart:io'; + +import 'package:device_calendar/device_calendar.dart'; +import 'package:diplomaticquarterapp/core/model/prescriptions/Prescriptions.dart'; import 'package:diplomaticquarterapp/core/model/prescriptions/prescription_report.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; -import 'package:diplomaticquarterapp/pages/MyAppointments/widgets/reminder_dialog.dart'; +import 'package:diplomaticquarterapp/extensions/string_extensions.dart'; +import 'package:diplomaticquarterapp/models/header_model.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/widgets/reminder_dialog.dart'; import 'package:diplomaticquarterapp/pages/medical/prescriptions/pharmacy_for_prescriptions_page.dart'; +import 'package:diplomaticquarterapp/uitl/CalendarUtils.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/location_util.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.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'; +import 'package:jiffy/jiffy.dart'; +import 'package:manage_calendar_events/manage_calendar_events.dart' as ios; import 'package:provider/provider.dart'; -class PrescriptionDetailsPage extends StatelessWidget { - final PrescriptionReport prescriptionReport; +class PrescriptionDetailsPage extends StatefulWidget { + final PrescriptionReport? prescriptionReport; + final Prescriptions? prescriptions; + + PrescriptionDetailsPage({Key? key, this.prescriptionReport, this.prescriptions}); + + @override + _PrescriptionDetailsPageState createState() => _PrescriptionDetailsPageState(); +} + +class _PrescriptionDetailsPageState extends State { + bool hasReminder = false; + late LocationUtils locationUtils; - PrescriptionDetailsPage({Key key, this.prescriptionReport}); + @override + void initState() { + checkAndRemove(delete: false); + locationUtils = new LocationUtils(isShowConfirmDialog: true, context: context); + WidgetsBinding.instance.addPostFrameCallback((_) => locationUtils.getCurrentLocation()); + super.initState(); + } @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); return AppScaffold( isShowAppBar: true, + showNewAppBar: true, + showNewAppBarTitle: true, appBarTitle: TranslationBase.of(context).prescriptions, - body: SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - width: double.infinity, - margin: EdgeInsets.only(top: 10, left: 10, right: 10), - padding: EdgeInsets.all(8.0), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.all( - Radius.circular(10.0), - ), - border: Border.all(color: Colors.grey[200], width: 0.5), - ), - child: Row( - children: [ - ClipRRect( - borderRadius: BorderRadius.all(Radius.circular(5)), - child: Image.network( - prescriptionReport.imageSRCUrl, - fit: BoxFit.cover, - width: 60, - height: 70, - ), - ), - Expanded( - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Center( - child: Texts( - prescriptionReport.itemDescription.isNotEmpty - ? prescriptionReport.itemDescription - : prescriptionReport.itemDescriptionN), - ), - ), - ) - ], - ), + body: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + DoctorHeader( + headerModel: HeaderModel( + widget.prescriptions!.doctorName!, + widget.prescriptions!.doctorID!, + widget.prescriptions!.doctorImageURL!, + widget.prescriptions!.speciality ?? [""], + "", + widget.prescriptions!.name!, + DateUtil.convertStringToDate(widget.prescriptions!.appointmentDate!), + DateUtil.formatDateToTime(DateUtil.convertStringToDate(widget.prescriptions!.appointmentDate!)), + widget.prescriptions!.nationalityFlagURL!, + widget.prescriptions!.doctorRate, + widget.prescriptions!.actualDoctorRate, + widget.prescriptions!.noOfPatientsRate, + "", ), - Container( - margin: EdgeInsets.all(8), - child: Row( - children: [ - Expanded( - child: InkWell( - onTap: () => Navigator.push( - context, - FadePage( - page: PharmacyForPrescriptionsPage( - prescriptionReport: prescriptionReport), - ), - ), - child: Center( - child: Column( - children: [ - Container( - width: 50, - decoration: BoxDecoration( - color: Colors.white, - shape: BoxShape.rectangle), - child: Column( - children: [ - Icon( - Icons.pin_drop, - color: Colors.red[800], - size: 55, - ), - ], - ), - ), - SizedBox( - height: 5, - ), - Texts(TranslationBase.of(context).availability) - ], - ), - )), - ), - _addReminderButton(context) - ], - ), - ), - Container( - color: Colors.white, - margin: EdgeInsets.only(top: 10, left: 10, right: 10), - child: Table( - border: TableBorder.symmetric( - inside: BorderSide(width: 0.5), - outside: BorderSide(width: 0.5)), - children: [ - TableRow( - children: [ - Container( - color: Colors.white, - height: 30, - width: double.infinity, - child: Center( - child: Texts(TranslationBase.of(context).route, fontSize: 14,))), - Container( - color: Colors.white, - height: 30, - width: double.infinity, - child: Center( - child: - Texts(TranslationBase.of(context).frequency, fontSize: 14,))), - Container( - color: Colors.white, - width: double.infinity, - padding: EdgeInsets.symmetric(horizontal: 4), - child: Center( - child: Texts( - "${TranslationBase.of(context).dailyDoses}", fontSize: 14,))), - Container( - color: Colors.white, - height: 30, - width: double.infinity, - child: Center( - child: - Texts(TranslationBase.of(context).duration, fontSize: 14,))), + isNeedToShowButton: false, + ), + Expanded( + child: ListView( + physics: BouncingScrollPhysics(), + padding: EdgeInsets.all(21), + children: [ + Container( + padding: EdgeInsets.all(14), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all(Radius.circular(10.0)), + boxShadow: [ + BoxShadow( + color: Color(0xff000000).withOpacity(.05), + //spreadRadius: 5, + blurRadius: 27, + offset: Offset(0, -3), + ), ], ), - TableRow( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, children: [ - Container( - color: Colors.white, - height: 50, - width: double.infinity, - child: - Center(child: Text(prescriptionReport.routeN))), - Container( - color: Colors.white, - height: 50, - width: double.infinity, - child: Center( - child: - Text(prescriptionReport.frequencyN ?? ''))), - Container( - color: Colors.white, - height: 50, - width: double.infinity, - child: Center( - child: Text( - '${prescriptionReport.doseDailyQuantity}'))), - Container( - color: Colors.white, - height: 50, - width: double.infinity, - child: - Center(child: Text('${prescriptionReport.days}'))) + Row( + children: [ + // InkWell( + // child: Stack( + // alignment: Alignment.center, + // children: [ + // Container( + // child: Image.network( + // widget.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, widget.prescriptionReport.imageSRCUrl); + // }, + // ), + // SizedBox(width: 12), + Expanded( + child: Text( + (widget.prescriptionReport!.itemDescription!.isNotEmpty ? widget.prescriptionReport!.itemDescription : widget.prescriptionReport!.itemDescriptionN ?? '')! + .toLowerCase() + .capitalizeFirstofEach, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.64), + ), + ) + ], + ), + SizedBox(height: 12), + Table(border: TableBorder(horizontalInside: BorderSide(width: 1, color: Colors.black, style: BorderStyle.solid)), children: [ + TableRow( + children: [ + Utils.tableColumnTitle(TranslationBase.of(context).route, showDivider: false), + Utils.tableColumnTitle(TranslationBase.of(context).frequency, showDivider: false), + Utils.tableColumnTitle(TranslationBase.of(context).dailyDoses, showDivider: false), + Utils.tableColumnTitle(TranslationBase.of(context).duration, showDivider: false) + ], + ), + TableRow( + children: [ + Utils.tableColumnValue(widget.prescriptionReport?.routeN ?? '', isLast: true, mProjectViewModel: projectViewModel), + Utils.tableColumnValue(widget.prescriptionReport?.frequencyN ?? '', isLast: true, mProjectViewModel: projectViewModel), + Utils.tableColumnValue(widget.prescriptionReport?.doseDailyQuantity.toString() ?? '', isLast: true, mProjectViewModel: projectViewModel), + Utils.tableColumnValue(widget.prescriptionReport?.days.toString() ?? '', isLast: true, mProjectViewModel: projectViewModel), + ], + ), + ]), + Text( + TranslationBase.of(context).remarks, + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.48), + ), + Text( + widget.prescriptionReport!.remarks!, + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff575757), letterSpacing: -0.4, height: 16 / 10), + ), ], ), - ], - ), - ), - Container( - margin: EdgeInsets.only(top: 10, left: 10, right: 10), - width: double.infinity, - color: Colors.white, - padding: EdgeInsets.all(5), - child: Center( - child: Column( - children: [ - Texts(TranslationBase.of(context).notes), - SizedBox( - height: 5, - ), - Divider( - height: 0.5, - color: Colors.grey[300], - ), - SizedBox( - height: 5, - ), - Texts(prescriptionReport.remarks ?? ''), - ], - ), - ), - ) - ], - ), - ), - ); - } - - Widget _addReminderButton(BuildContext context) { - ProjectViewModel projectViewModel = Provider.of(context); - - return GestureDetector( - onTap: () { - DateTime startDate = DateTime.now(); - DateTime endDate = DateTime(startDate.year, startDate.month, - startDate.day + prescriptionReport.days); - - print(prescriptionReport); - 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: ReminderDialog( - eventId: prescriptionReport.itemID.toString(), - title: "Prescription Reminder", - description: - "${prescriptionReport.itemDescriptionN} ${prescriptionReport.frequencyN} ${prescriptionReport.routeN} ", - startDate: - "/Date(${startDate.millisecondsSinceEpoch}+0300)/", - endDate: "/Date(${endDate.millisecondsSinceEpoch}+0300)/", - location: prescriptionReport.remarks, - ), ), - ); - }, - transitionDuration: Duration(milliseconds: 500), - barrierDismissible: true, - barrierLabel: '', - context: context, - pageBuilder: (context, animation1, animation2) {}); - }, - child: Column( - mainAxisSize: MainAxisSize.max, - children: [ + ], + ), + ), Container( - // height: 100.0, - margin: EdgeInsets.all(7.0), - padding: EdgeInsets.only(bottom: 4.0), - decoration: BoxDecoration(boxShadow: [ - BoxShadow( - color: Colors.grey[400], blurRadius: 2.0, spreadRadius: 0.0) - ], borderRadius: BorderRadius.circular(10), color: Colors.white), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - children: [ - Container( - margin: EdgeInsets.fromLTRB(5.0, 5.0, 5.0, 0.0), - child: Text("add", - overflow: TextOverflow.clip, - style: TextStyle( - color: new Color(0xffB8382C), - letterSpacing: 1.0, - fontSize: 18.0)), - ), - Container( - margin: EdgeInsets.fromLTRB(5.0, 0.0, 5.0, 0.0), - child: Text("reminder", - overflow: TextOverflow.clip, - style: TextStyle( - color: Colors.black, - letterSpacing: 1.0, - fontSize: 15.0)), + color: Colors.white, + padding: EdgeInsets.only(top: 16, bottom: 16, right: 21, left: 21), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Expanded( + child: DefaultButton( + TranslationBase.of(context).availability, + () { + Navigator.push( + context, + FadePage( + page: PharmacyForPrescriptionsPage( + itemID: widget.prescriptionReport!.itemID, + prescriptionReport: widget.prescriptionReport, + ), + ), + ); + }, + iconData: Icons.location_on, + color: Color(0xff359846), + ), ), - Container( - alignment: projectViewModel.isArabic - ? Alignment.bottomLeft - : Alignment.bottomRight, - margin: projectViewModel.isArabic - ? EdgeInsets.fromLTRB(10.0, 7.0, 0.0, 8.0) - : EdgeInsets.fromLTRB(0.0, 7.0, 10.0, 8.0), - child: Image.asset( - "assets/images/new-design/reminder_icon.png", - width: 45.0, - height: 45.0), + SizedBox(width: 10), + Expanded( + child: DefaultButton( + hasReminder ? TranslationBase.of(context).cancelReminder : TranslationBase.of(context).addReminder, + () { + if (hasReminder) { + checkAndRemove(delete: true); + } else { + DateTime startDate = DateTime.now(); + DateTime endDate = DateTime(startDate.year, startDate.month, startDate.day + widget.prescriptionReport!.days!); + showReminderDialog( + context, + endDate, + "", + widget.prescriptionReport!.itemID.toString(), + "", + "", + title: "${widget.prescriptionReport!.itemDescriptionN} Prescription Reminder", + description: "${widget.prescriptionReport!.itemDescriptionN} ${widget.prescriptionReport!.frequencyN} ${widget.prescriptionReport!.routeN} ", + onSuccess: () { + AppToast.showSuccessToast(message: TranslationBase.of(context).reminderSuccess); + }, + isMultiAllowed: true, + onMultiDateSuccess: (int selectedIndex) { + setCalender(context, widget.prescriptionReport!.itemID.toString(), selectedIndex); + }, + ); + return; + } + }, + iconData: Icons.notifications_active, + color: Color(0xffD02127), + fontSize: 13.0, + //textColor: Color(0xff2B353E), + ), ), ], ), @@ -296,4 +245,214 @@ class PrescriptionDetailsPage extends StatelessWidget { ), ); } + + // checkAndRemove({bool delete = false}) async { + // final ios.CalendarPlugin _myPlugin = ios.CalendarPlugin(); + // CalendarUtils calendarUtils = await CalendarUtils.getInstance(); + // DateTime startEventsDate = Jiffy.parseFromDateTime(DateTime.now()).subtract(days: 30).dateTime; + // DateTime endEventsDate = Jiffy.parseFromDateTime(DateTime.now()).add(days: 120).dateTime; + // RetrieveEventsParams params = new RetrieveEventsParams(startDate: startEventsDate, endDate: endEventsDate); + // + // if (calendarUtils.calendars != null) { + // print(calendarUtils.calendars); + // if (Platform.isAndroid) { + // Future.forEach( + // calendarUtils.calendars, + // (Calendar calender) => { + // calendarUtils.retrieveEvents(calender.id!, params).then((value) { + // Result> events = value; + // events.data!.forEach((element) { + // if (delete) { + // if (element.title!.contains(widget.prescriptionReport!.itemDescriptionN!)) calendarUtils.deleteEvent(calender, element); + // AppToast.showSuccessToast(message: TranslationBase.of(context).reminderCancelSuccess); + // setState(() { + // hasReminder = false; + // }); + // } else { + // if (element.title!.contains(widget.prescriptionReport!.itemDescriptionN!)) + // setState(() { + // hasReminder = true; + // }); + // } + // }); + // }), + // }); + // } else { + // List? iosCall = await _myPlugin.getCalendars(); + // Future.forEach( + // iosCall!, + // (ios.Calendar cal) async => { + // print(cal), + // calendarUtils.retrieveEvents(cal.id!, params).then((value) { + // Result> events = value; + // events.data!.forEach((element) { + // if (delete) { + // if (element.title!.contains(widget.prescriptionReport!.itemDescriptionN!)) calendarUtils.deleteEvent(Calendar(id: cal.id, name: cal.name, accountName: cal.accountName), element); + // AppToast.showSuccessToast(message: TranslationBase.of(context).reminderCancelSuccess); + // setState(() { + // hasReminder = false; + // }); + // } else { + // if (element.title!.contains(widget.prescriptionReport!.itemDescriptionN!)) + // setState(() { + // hasReminder = true; + // }); + // } + // }); + // }), + // }, + // ); + // } + // } + // } + + Future checkAndRemove({bool delete = false}) async { + final ios.CalendarPlugin _myPlugin = ios.CalendarPlugin(); + CalendarUtils calendarUtils = await CalendarUtils.getInstance(); + DateTime startEventsDate = Jiffy.parseFromDateTime(DateTime.now()).subtract(days: 30).dateTime; + DateTime endEventsDate = Jiffy.parseFromDateTime(DateTime.now()).add(days: 120).dateTime; + RetrieveEventsParams params = RetrieveEventsParams(startDate: startEventsDate, endDate: endEventsDate); + + if (calendarUtils.calendars != null) { + if (Platform.isAndroid) { + await processEvents(calendarUtils.calendars, calendarUtils, params, delete); + } else { + List? iosCalendars = await _myPlugin.getCalendars(); + if (iosCalendars != null) { + await processEvents(iosCalendars.map((cal) => Calendar(id: cal.id, name: cal.name, accountName: cal.accountName)).toList(), calendarUtils, params, delete); + } + } + } + } + + Future processEvents(List calendars, calendarUtils, params, delete) async { + for (var calendar in calendars) { + Result> events = await calendarUtils.retrieveEvents(calendar.id!, params); + for (var event in events.data!) { + if (event.title!.contains(widget.prescriptionReport!.itemDescriptionN!)) { + if (delete) { + await calendarUtils.deleteEvent(calendar, event); + AppToast.showSuccessToast(message: TranslationBase.of(context).reminderCancelSuccess); + setState(() { + hasReminder = false; + }); + } else { + setState(() { + hasReminder = true; + }); + } + } + } + } + } + + // cancelReminders() async { + // CalendarUtils calendarUtils = await CalendarUtils.getInstance(); + // final ios.CalendarPlugin _myPlugin = ios.CalendarPlugin(); + // DateTime startEventsDate = Jiffy.parseFromDateTime(DateTime.now()).subtract(days: 30).dateTime; + // DateTime endEventsDate = Jiffy.parseFromDateTime(DateTime.now()).add(days: 120).dateTime; + // RetrieveEventsParams params = RetrieveEventsParams(startDate: startEventsDate, endDate: endEventsDate); + // + // if (Platform.isAndroid) { + // Future.forEach( + // calendarUtils.calendars, + // (Calendar calender) => { + // calendarUtils.retrieveEvents(calender.id!, params).then((value) { + // Result> events = value; + // events.data!.forEach((element) { + // if (element.title!.contains(widget.prescriptionReport!.itemDescriptionN!)) calendarUtils.deleteEvent(calender, element); + // }); + // }), + // }); + // } else { + // List? iosCal = await _myPlugin.getCalendars(); + // Future.forEach( + // iosCal!, + // (ios.Calendar cale) async => { + // calendarUtils.retrieveEvents(cale.id!, params).then((value) { + // Result> events = value; + // events.data!.forEach((element) { + // print(element.title); + // if (element.title!.contains(widget.prescriptionReport!.itemDescriptionN!)) + // calendarUtils.deleteEvent( + // Calendar( + // id: cale.id, + // name: cale.name, + // accountName: cale.accountName, + // ), + // element); + // }); + // }), + // }); + // AppToast.showSuccessToast(message: TranslationBase.of(context).reminderCancelSuccess); + // setState(() { + // hasReminder = false; + // }); + // } + // } + + setCalender(BuildContext context, String eventId, int reminderIndex) async { + DateTime actualDate = DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day, 8, 0); + if (widget.prescriptionReport?.frequencyNumber == null) widget.prescriptionReport!.frequencyNumber = 2; //Some time frequency number is null so by default will be 2 + + int remainingDays = widget.prescriptionReport!.days! - + (Jiffy.parseFromDateTime(DateTime.now()).diff(Jiffy.parseFromDateTime(DateUtil.convertStringToDate(widget.prescriptionReport!.orderDate!)), unit: Unit.day) as int); + if (remainingDays.isNegative) { + Utils.showErrorToast("Prescription date has been already passed you can not add a reminder for this prescription."); + return; + } + CalendarUtils calendarUtils = await CalendarUtils.getInstance(); + GifLoaderDialogUtils.showMyDialog(context); + + try { + for (int i = 0; i < remainingDays; i++) { + //event for number of days. + for (int j = 0; j < widget.prescriptionReport!.frequencyNumber!; j++) { + // event for number of times per day. + if (j != 0) { + actualDate.add(new Duration(hours: 8)); // 8 hours addition for daily dose. + } + //Time subtraction from actual reminder time. like before 30, or 1 hour. + if (reminderIndex == 0) { + // Before 30 mints + actualDate = Jiffy.parseFromDateTime(actualDate).subtract(minutes: 30).dateTime; + // dateTime.add(new Duration(minutes: -30)); + } else if (reminderIndex == 1) { + // Before 1 hour + // dateTime.add(new Duration(minutes: -60)); + actualDate = Jiffy.parseFromDateTime(actualDate).subtract(hours: 1).dateTime; + } else if (reminderIndex == 2) { + // Before 1 hour and 30 mints + // dateTime.add(new Duration(minutes: -90)); + actualDate = Jiffy.parseFromDateTime(actualDate).subtract(hours: 1, minutes: 30).dateTime; + } else if (reminderIndex == 3) { + // Before 2 hours + // dateTime.add(new Duration(minutes: -120)); + actualDate = Jiffy.parseFromDateTime(actualDate).subtract(hours: 2).dateTime; + } + + calendarUtils.createOrUpdateEvent( + title: "${widget.prescriptionReport!.itemDescriptionN} Prescription Reminder", + description: "${widget.prescriptionReport!.itemDescriptionN} ${widget.prescriptionReport!.frequencyN} ${widget.prescriptionReport!.routeN} ", + scheduleDateTime: actualDate, + eventId: eventId + (i.toString() + j.toString()), //event id with varitions + ); + + actualDate = DateTime(actualDate.year, actualDate.month, actualDate.day, 8, 0); + } + actualDate = Jiffy.parseFromDateTime(actualDate).add(days: 1).dateTime; + print(actualDate); + } + } catch (ex) { + print("catch:$ex"); + } + + AppToast.showSuccessToast(message: TranslationBase.of(context).reminderSuccess); + Future.delayed(Duration(seconds: 2), () { + GifLoaderDialogUtils.hideDialog(context); + }); + setState(() { + hasReminder = true; + }); + } } diff --git a/lib/pages/medical/prescriptions/prescription_items_page.dart b/lib/pages/medical/prescriptions/prescription_items_page.dart index c6581493..70ce271a 100644 --- a/lib/pages/medical/prescriptions/prescription_items_page.dart +++ b/lib/pages/medical/prescriptions/prescription_items_page.dart @@ -3,224 +3,437 @@ import 'package:diplomaticquarterapp/core/model/prescriptions/Prescriptions.dart import 'package:diplomaticquarterapp/core/model/prescriptions/prescription_report.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/prescriptions_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/extensions/string_extensions.dart'; +import 'package:diplomaticquarterapp/main.dart'; +import 'package:diplomaticquarterapp/models/header_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/pages/medical/prescriptions/prescription_details_inp.dart'; import 'package:diplomaticquarterapp/pages/medical/prescriptions/prescription_details_page.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/widgets/buttons/button.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.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/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'; import 'package:provider/provider.dart'; + import '../../../widgets/dialogs/confirm_send_email_dialog.dart'; import 'PrescriptionIDeliveryAddressPage.dart'; class PrescriptionItemsPage extends StatelessWidget { final Prescriptions prescriptions; + late ProjectViewModel projectViewModel; + + PrescriptionItemsPage({Key? key, required this.prescriptions}); - PrescriptionItemsPage({Key key, this.prescriptions}); - //TODO @override Widget build(BuildContext context) { - ProjectViewModel projectViewModel = Provider.of(context); + projectViewModel = Provider.of(context); return BaseView( - onModelReady: (model) => - model.getPrescriptionReport(prescriptions: prescriptions), + onModelReady: (model) => model.getPrescriptionReport(prescriptions: prescriptions), builder: (_, model, widget) => AppScaffold( isShowAppBar: true, - appBarTitle: TranslationBase.of(context).prescriptions, + appBarTitle: prescriptions.doctorName!, baseViewModel: model, - body: Container( - height: MediaQuery.of(context).size.height * 0.8, - child: Column( - children: [ - if (!prescriptions.isInOutPatient) - ...List.generate( - model.prescriptionReportList.length, - (index) => InkWell( - onTap: () => Navigator.push( - context, - FadePage( - page: PrescriptionDetailsPage( - prescriptionReport: - model.prescriptionReportList[index], + showNewAppBar: true, + showNewAppBarTitle: true, + body: model.state != ViewState.Busy + ? Column( + children: [ + Expanded( + child: SingleChildScrollView( + physics: BouncingScrollPhysics(), + child: Column( + children: [ + DoctorHeader( + headerModel: HeaderModel( + prescriptions.doctorName!, + prescriptions.doctorID!, + prescriptions.doctorImageURL!, + prescriptions.speciality ?? [""], + "", + prescriptions.name!, + DateUtil.convertStringToDate(prescriptions.appointmentDate!), + DateUtil.formatDateToTime( + model.prescriptionReportEnhList.length > 0 || model.prescriptionReportListINP.length > 0 + ? DateUtil.convertStringToDate( + model.prescriptionReportEnhList.length > 0 ? model.prescriptionReportEnhList[0].orderDate! : model.prescriptionReportListINP[0].orderDate!, + ) + : DateTime.now(), ), + prescriptions.nationalityFlagURL ?? "", + prescriptions.doctorRate, + prescriptions.actualDoctorRate, + prescriptions.noOfPatientsRate, + projectViewModel.user.emailAddress!, ), + isNeedToShowButton: (model.prescriptionReportListINP.length > 0 || model.prescriptionReportEnhList.length > 0) ? projectViewModel.havePrivilege(13) : false, + buttonTitle: TranslationBase.of(context).download, + buttonIcon: "assets/images/new/download_1.svg", + showConfirmMessageDialog: false, + isDownload: true, + onTap: () async { + // showConfirmMessage(context, model); + GifLoaderDialogUtils.showMyDialog(context); + await model.sendPrescriptionEmail( + appointmentDate: prescriptions.appointmentDate!, + patientID: prescriptions.patientID!, + clinicName: prescriptions.companyName!, + doctorName: prescriptions.doctorName!, + doctorID: prescriptions.doctorID!, + mes: TranslationBase.of(context).sendSuc, + projectID: prescriptions.projectID!, + isInOutPatient: prescriptions.isInOutPatient!, + isDownload: true); + GifLoaderDialogUtils.hideDialog(context); + }, ), - child: Container( - width: double.infinity, - margin: - EdgeInsets.only(top: 10, left: 10, right: 10), - padding: EdgeInsets.all(8.0), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.all( - Radius.circular(10.0), - ), - border: Border.all( - color: Colors.grey[200], width: 0.5), - ), - child: Row( - children: [ - ClipRRect( - borderRadius: - BorderRadius.all(Radius.circular(5)), - child: Image.network( - model.prescriptionReportList[index] - .imageSRCUrl, - fit: BoxFit.cover, - width: 60, - height: 70, + if (!prescriptions.isInOutPatient!) + model.prescriptionReportListINP.length > 0 + ? ListView.separated( + itemBuilder: (context, index) { + return InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: PrescriptionDetailsPageINP( + prescriptionReport: model.prescriptionReportListINP[index], + prescriptions: prescriptions, + ), + ), + ); + }, + child: Container( + width: double.infinity, + child: Container( + margin: EdgeInsets.only(left: 16, right: 16, top: index == 0 ? 16 : 4, bottom: 4), + decoration: cardRadius(12), + child: Padding( + padding: EdgeInsets.only(top: 12, bottom: 20, left: projectViewModel.isArabic ? 12 : 20, right: projectViewModel.isArabic ? 20 : 12), + child: Row( + children: [ + Flexible( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + model.prescriptionReportListINP[index].itemDescription!.isNotEmpty + ? model.prescriptionReportListINP[index].itemDescription! + : model.prescriptionReportListINP[index].itemDescriptionN ?? '', + style: TextStyle( + fontSize: 16, + letterSpacing: -0.64, + fontWeight: FontWeight.w600, + ), + ), + mHeight(10), + Row( + children: [ + // 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), + // ) + // ], + // ), + // onTap: () { + // showZoomImageDialog( + // context, + // model.prescriptionReportListINP[index].imageSRCUrl, + // ); + // }, + // ), + // mWidth(12), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Text( + TranslationBase.of(context).route + ": ", + style: TextStyle( + color: Colors.grey, + fontSize: 10, + letterSpacing: -0.4, + fontWeight: FontWeight.w600, + ), + ), + Text( + model.prescriptionReportListINP[index].route!, + style: TextStyle( + fontSize: 12, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + ), + ), + ], + ), + Row( + children: [ + Text( + TranslationBase.of(context).dailyDoses + ": ", + style: TextStyle( + color: Colors.grey, + fontSize: 10, + letterSpacing: -0.4, + fontWeight: FontWeight.w600, + ), + ), + Text( + model.prescriptionReportListINP[index].doseDailyQuantity.toString(), + style: TextStyle( + fontSize: 12, + letterSpacing: -0.48, + fontWeight: FontWeight.w600, + ), + ), + ], + ), + mHeight(12), + Text( + model.prescriptionReportListINP[index].remarks!, + style: TextStyle( + color: Colors.grey, + fontSize: 10, + letterSpacing: -0.4, + fontWeight: FontWeight.w600, + ), + ), + ], + ) + ], + ), + ], + ), + ), + Icon( + Icons.arrow_forward, + size: 16, + ), + ], + ), + ), + ), + ), + ); + }, + separatorBuilder: (context, index) { + return mHeight(8); + }, + physics: NeverScrollableScrollPhysics(), + shrinkWrap: true, + itemCount: model.prescriptionReportListINP.length) + : Padding( + padding: const EdgeInsets.only(top: 150.0), + child: getNoDataWidget(context), + ) + else + model.prescriptionReportEnhList.length > 0 + ? ListView.separated( + padding: EdgeInsets.all(21), + itemBuilder: (context, index) { + return InkWell( + onTap: () { + PrescriptionReport prescriptionReport = PrescriptionReport( + imageSRCUrl: model.prescriptionReportEnhList[index].imageSRCUrl, + itemDescription: model.prescriptionReportEnhList[index].itemDescription, + itemDescriptionN: model.prescriptionReportEnhList[index].itemDescription, + routeN: model.prescriptionReportEnhList[index].route, + frequency: model.prescriptionReportEnhList[index].frequency, + frequencyN: model.prescriptionReportEnhList[index].frequency, + doseDailyQuantity: model.prescriptionReportEnhList[index].doseDailyQuantity, + days: model.prescriptionReportEnhList[index].days, + itemID: model.prescriptionReportEnhList[index].itemID, + orderDate: model.prescriptionReportEnhList[index].orderDate, + startDate: model.prescriptionReportEnhList[index].startDate, + remarks: model.prescriptionReportEnhList[index].remarks); + Navigator.push( + context, + FadePage( + page: PrescriptionDetailsPage( + prescriptionReport: prescriptionReport, + prescriptions: prescriptions, + ), + ), + ); + }, + child: Container( + 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: Padding( + padding: EdgeInsets.only(top: 12, bottom: 20, left: projectViewModel.isArabic ? 12 : 20, right: projectViewModel.isArabic ? 20 : 12), + child: Row( + children: [ + Flexible( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + (model.prescriptionReportEnhList[index].itemDescription!.isNotEmpty + ? model.prescriptionReportEnhList[index].itemDescription + : model.prescriptionReportEnhList[index].itemDescriptionN ?? '')! + .toLowerCase() + .capitalizeFirstofEach, + style: TextStyle( + fontSize: 16, + color: Color(0xff2E303A), + letterSpacing: -0.64, + fontWeight: FontWeight.w600, + ), + ), + mHeight(10), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // 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), + // ) + // ], + // ), + // onTap: () { + // showZoomImageDialog( + // context, + // model.prescriptionReportEnhList[index].imageSRCUrl, + // ); + // }, + // ), + // mWidth(12), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + MyRichText(TranslationBase.of(context).route + ": ", model.prescriptionReportEnhList[index].route!, projectViewModel.isArabic), + MyRichText(TranslationBase.of(context).dailyDoses + ": ", model.prescriptionReportEnhList[index].doseDailyQuantity.toString(), + projectViewModel.isArabic), + mHeight(9), + Text( + model.prescriptionReportEnhList[index].remarks!, + style: TextStyle( + color: Color(0xff575757), + fontSize: 12, + letterSpacing: -0.4, + fontWeight: FontWeight.w600, + ), + ), + ], + ), + ) + ], + ), + ], + ), + ), + Icon( + Icons.arrow_forward, + size: 16, + ), + ], + ), + ), + ), + ); + }, + separatorBuilder: (context, index) { + return mHeight(12); + }, + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + itemCount: model.prescriptionReportEnhList.length) + : Padding( + padding: const EdgeInsets.only(top: 150.0), + child: getNoDataWidget(context), ), - ), - SizedBox( - width: 10, - ), - Expanded( - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Center( - child: Texts(model - .prescriptionReportList[index] - .itemDescription - .isNotEmpty - ? model.prescriptionReportList[index] - .itemDescription - : model.prescriptionReportList[index] - .itemDescriptionN)), - )), - Icon( - Icons.arrow_forward_ios, - size: 18, - color: Colors.grey[500], - ) - ], - ), - ), - )) - else - ...List.generate( - model.prescriptionReportEnhList.length, - (index) => InkWell( - onTap: () { - PrescriptionReport prescriptionReport = - PrescriptionReport( - imageSRCUrl: model - .prescriptionReportEnhList[index].imageSRCUrl, - itemDescription: model - .prescriptionReportEnhList[index] - .itemDescription, - itemDescriptionN: model - .prescriptionReportEnhList[index] - .itemDescription, - routeN: - model.prescriptionReportEnhList[index].route, - frequency: model - .prescriptionReportEnhList[index].frequency, - frequencyN: model - .prescriptionReportEnhList[index].frequency, - doseDailyQuantity: model - .prescriptionReportEnhList[index] - .doseDailyQuantity, - days: model.prescriptionReportEnhList[index].days, - itemID: - model.prescriptionReportEnhList[index].itemID, - remarks: model - .prescriptionReportEnhList[index].remarks); - Navigator.push( - context, - FadePage( - page: PrescriptionDetailsPage( - prescriptionReport: prescriptionReport, - ), - ), - ); - }, - child: Container( - margin: EdgeInsets.all(8.0), - color: Colors.white, - child: Row( - children: [ - ClipRRect( - borderRadius: BorderRadius.all(Radius.circular(5)), - child: Image.network( - model - .prescriptionReportEnhList[index].imageSRCUrl, - fit: BoxFit.cover, - width: 60, - height: 70, - ), - ), - SizedBox( - width: 10, - ), - Expanded( - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts(model.prescriptionReportEnhList[index] - .itemDescription), - ], - ), - ), - ), - Icon( - Icons.arrow_forward_ios, - size: 18, - color: Colors.grey[500], - ) ], ), ), ), - ) - ], - ), - ), - bottomSheet: Container( - width: double.infinity, - height: MediaQuery.of(context).size.height * 0.25, - color: Colors.grey[100], - child: Column( - children: [ - Divider(), - if(projectViewModel.havePrivilege(13)) - Container( - width: MediaQuery.of(context).size.width * 0.8, - child: Button( - label: TranslationBase.of(context).sendCopy, - onTap: () { - showConfirmMessage(context,model); - }, - loading: model.state == ViewState.BusyLocal, - ), - ), - Container( - width: MediaQuery.of(context).size.width * 0.8, - child: Button( - label: TranslationBase.of(context).resendOrder, - backgroundColor: Colors.green[800], - onTap: (){ - - Navigator.push( - context, - FadePage( - page: PrescriptionDeliveryAddressPage( - prescriptions: prescriptions, - prescriptionReportList: model.prescriptionReportList, - prescriptionReportEnhList: model.prescriptionReportEnhList, + Container( + color: Colors.white, + padding: EdgeInsets.only(top: 16, bottom: 16, right: 21, left: 21), + child: DefaultButton( + TranslationBase.of(context).resendOrder, + () { + if (model.isMedDeliveryAllowed == false) { + AppToast.showErrorToast(message: TranslationBase.of(context).prescriptionDeliveryError); + } else { + Navigator.push( + context, + FadePage( + page: PrescriptionDeliveryAddressPage( + prescriptions: prescriptions, + prescriptionReportList: model.prescriptionReportList, + prescriptionReportEnhList: model.prescriptionReportEnhList, + ), ), - ), - ); + ); + } }, - )) - ], - ), - ), + color: model.isMedDeliveryAllowed == false ? Color(0xff575757) : Color(0xff359846), + disabledColor: Color(0xff575757), + ), + ), + ], + ) + : Container(), ), ); } @@ -228,16 +441,19 @@ class PrescriptionItemsPage extends StatelessWidget { void showConfirmMessage(BuildContext context, PrescriptionsViewModel model) { showDialog( context: context, - child: ConfirmSendEmailDialog( - email: model.user.emailAddress, + builder: (cxt) => ConfirmSendEmailDialog( + email: projectViewModel.user!.emailAddress!, onTapSendEmail: () { model.sendPrescriptionEmail( - appointmentDate: prescriptions.appointmentDate, - patientID: prescriptions.patientID, - clinicName: prescriptions.companyName, - doctorName: prescriptions.doctorName, + appointmentDate: prescriptions.appointmentDate!, + patientID: prescriptions.patientID!, + clinicName: prescriptions.companyName!, + doctorName: prescriptions.doctorName!, + doctorID: prescriptions.doctorID!, mes: TranslationBase.of(context).sendSuc, - projectID: prescriptions.projectID); + projectID: prescriptions.projectID!, + isInOutPatient: prescriptions.isInOutPatient!, + isDownload: true); }, ), ); diff --git a/lib/pages/medical/prescriptions/prescriptions_history_details_page.dart b/lib/pages/medical/prescriptions/prescriptions_history_details_page.dart index 30bfa13e..ad47c841 100644 --- a/lib/pages/medical/prescriptions/prescriptions_history_details_page.dart +++ b/lib/pages/medical/prescriptions/prescriptions_history_details_page.dart @@ -1,160 +1,196 @@ -import 'package:diplomaticquarterapp/core/model/prescriptions/prescriptions_order.dart'; +import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/GetCMCAllOrdersResponseModel.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/prescriptions_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/extensions/string_extensions.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/widgets/buttons/BottomButton.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.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 PrescriptionsHistoryDetailsPage extends StatelessWidget { - final PrescriptionsOrder prescriptionsOrder; + final GetCMCAllOrdersResponseModel prescriptionsOrder; - PrescriptionsHistoryDetailsPage({Key key, this.prescriptionsOrder}); + PrescriptionsHistoryDetailsPage({Key? key, required this.prescriptionsOrder}); @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); return BaseView( - onModelReady: (model) => model.getPrescriptionReportEnh( - prescriptionsOrder: prescriptionsOrder), - builder: (_, model, widget) => AppScaffold( - isShowAppBar: true, - appBarTitle: TranslationBase.of(context).orderDetails, - baseViewModel: model, - body: SingleChildScrollView( - child: Container( - margin: EdgeInsets.all(15.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 5, - ), - Container( - width: double.infinity, - decoration: BoxDecoration( - color: prescriptionsOrder.status == 3 ?Colors.green : prescriptionsOrder.status ==2 ? Colors.grey: Colors.red, - borderRadius: BorderRadius.circular(5)), - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Texts(TranslationBase.of(context).orderStatus +' : ${prescriptionsOrder.descriptionN}',color: Colors.white,), - )), - SizedBox( - height: 15, - ), - Table( - border: TableBorder.symmetric( - inside: BorderSide(width: 0.5), - outside: BorderSide(width: 0.5)), - children: [ - TableRow(children: [ - Container( - height: 50, - color: Colors.white, - child: Center( - child: Texts(TranslationBase.of(context).orderNo), - ), - ), - Container( - height: 50, - color: Colors.white, - child: Center( - child: Texts(TranslationBase.of(context).date), - ), - ), - ]), - TableRow(children: [ - Container( - height: 70, - color: Colors.white, - child: Center( - child: Texts('${prescriptionsOrder.iD}'), - ), - ), - Container( - height: 70, - color: Colors.white, - child: Center( - child: Texts('${prescriptionsOrder.createdOn.year}-${prescriptionsOrder.createdOn.day}-${prescriptionsOrder.createdOn.day} ${prescriptionsOrder.createdOn.hour}:${prescriptionsOrder.createdOn.minute}'), + onModelReady: (model) => model.getPrescriptionReportDetailsRC(prescriptionsOrder.iD!, projectViewModel.user!.patientID), + builder: (_, model, widget) { + int status = prescriptionsOrder.statusId!; + String _statusDisp = prescriptionsOrder.statusText!; + late 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 AppScaffold( + isShowAppBar: true, + appBarTitle: TranslationBase.of(context).orderDetails, + baseViewModel: model, + showNewAppBar: true, + backgroundColor: Color(0xffF8F8F8), + showNewAppBarTitle: true, + body: Column( + children: [ + Expanded( + child: ListView( + physics: BouncingScrollPhysics(), + padding: EdgeInsets.all(21), + children: [ + Container( + decoration: BoxDecoration( + color: _color, + borderRadius: BorderRadius.all( + Radius.circular(10.0), ), + boxShadow: [ + BoxShadow( + color: Color(0xff000000).withOpacity(.05), + blurRadius: 27, + offset: Offset(0, -3), + ), + ], ), - ]) - ], - ), - SizedBox( - height: 15, - ), - ...List.generate( - model.prescriptionReportEnhList.length, - (index) => Container( - margin: EdgeInsets.all(8.0), - color: Colors.white, - child: Row( - children: [ - ClipRRect( - borderRadius: BorderRadius.all(Radius.circular(5)), - child: Image.network( - model.prescriptionReportEnhList[index].imageSRCUrl, - fit: BoxFit.cover, - width: 60, - height: 70, + child: Container( + 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), ), ), - Expanded( - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Column( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row( crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts(model.prescriptionReportEnhList[index] - .itemDescription), + 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}. ${prescriptionsOrder.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(prescriptionsOrder.created!)!), + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.4, height: 16 / 10), + ), + ], + ) ], ), - ), + SizedBox(height: 16), + ListView.separated( + physics: NeverScrollableScrollPhysics(), + shrinkWrap: true, + itemBuilder: (context, index) => 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( + model.prescriptionsOrderListRC[index].image!, + fit: BoxFit.cover, + width: 48, + height: 48, + ), + ), + ), + SizedBox(width: 14), + Expanded( + child: Text( + (model.prescriptionsOrderListRC[index].itemDescription!.isNotEmpty + ? model.prescriptionsOrderListRC[index].itemDescription + : model.prescriptionsOrderListRC[index].itemDescription ?? '')! + .toLowerCase() + .capitalizeFirstofEach, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.64), + ), + ) + ], + ), + separatorBuilder: (context, index) => SizedBox(height: 12), + itemCount: model.prescriptionsOrderListRC.length) + ], ), - ], + ), ), - ), + ], ), - SizedBox(height: 120,) - ], - ), - ), - ), - bottomSheet: Container( - //padding: EdgeInsets.all(8.0), - // margin: EdgeInsets.all(8.0), - child: BottomButton( - label: TranslationBase.of(context).cancelOrder, - disabled: prescriptionsOrder.status != 1, - textColor: Colors.white, - onTap: (){ - - showCDialog(model,context); - //showAlertDialog(context); - }, + ), + Container( + color: Colors.white, + padding: EdgeInsets.only(top: 16, bottom: 16, right: 21, left: 21), + child: DefaultButton( + TranslationBase.of(context).cancelOrder, + // prescriptionsOrder.statusId != 1 + // ? null + // : + () { + showCDialog(model, context); + }, + disabledColor: Color(0xff575757), + ), + ), + ], ), - ), - ), + ); + }, ); } - showCDialog(PrescriptionsViewModel model,context){ + showCDialog(PrescriptionsViewModel model, context) { ConfirmDialog( context: context, confirmMessage: "Are you sure ?", okText: TranslationBase.of(context).confirm, cancelText: TranslationBase.of(context).cancel, - okFunction: () { + okFunction: () async { Navigator.of(context).pop(); - model.updatePressOrder(presOrderID: prescriptionsOrder.iD).then((value) { - Navigator.of(context).pop(); - }); + await model.updatePressOrder(presOrderID: prescriptionsOrder.iD!); + Navigator.of(context).pop(true); }, cancelFunction: () => {}).showAlertDialog(context); // dialog.showAlertDialog(context); } - } diff --git a/lib/pages/medical/prescriptions/prescriptions_history_page.dart b/lib/pages/medical/prescriptions/prescriptions_history_page.dart index 84691773..eb0a56b5 100644 --- a/lib/pages/medical/prescriptions/prescriptions_history_page.dart +++ b/lib/pages/medical/prescriptions/prescriptions_history_page.dart @@ -1,9 +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/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/medical/prescriptions/prescriptions_history_details_page.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +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/cupertino.dart'; @@ -11,76 +13,143 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; class PrescriptionsHistoryPage extends StatelessWidget { - final PrescriptionsViewModel prescriptionsViewModel; + final VoidCallback? showOrderLog; + final PrescriptionsViewModel? prescriptionsViewModel; - PrescriptionsHistoryPage({Key key, this.prescriptionsViewModel}); + PrescriptionsHistoryPage({Key? key, this.prescriptionsViewModel, this.showOrderLog}); @override Widget build(BuildContext context) { ProjectViewModel projectViewModel = Provider.of(context); - return AppScaffold( - baseViewModel: prescriptionsViewModel, - body: ListView.builder( - physics: BouncingScrollPhysics(), - itemBuilder: (context, index) => InkWell( - onTap: () => Navigator.push( - context, - FadePage( - page: PrescriptionsHistoryDetailsPage( - prescriptionsOrder: - prescriptionsViewModel.prescriptionsHistory[index], - ), - ), - ), - child: Container( - padding: EdgeInsets.all(15.0), - margin: EdgeInsets.all(8.0), - decoration: - BoxDecoration(shape: BoxShape.rectangle, color: Colors.white), - child: Row( - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts( - DateUtil.getDayMonthYearHourMinuteDateFormatted(prescriptionsViewModel.prescriptionsHistory[index].createdOn), - fontWeight: FontWeight.w300, - ), - SizedBox( - height: 5, - ), - Texts( - '${TranslationBase.of(context).orderNo} ${prescriptionsViewModel.prescriptionsHistory[index].iD}'), - SizedBox( - height: 5, - ), - Texts( - '${prescriptionsViewModel.prescriptionsHistory[index].descriptionN}'), - SizedBox( - height: 5, - ), - Texts( - '${TranslationBase.of(context).orderNo}', - fontWeight: FontWeight.w300, - ), - SizedBox( - height: 5, - ), - ], - ), - ), - Icon( - Icons.arrow_forward_ios, - size: 25, - ) - ], - ), - ), - ), - itemCount: prescriptionsViewModel.prescriptionsHistory.length, - ), - ); + return BaseView( + onModelReady: (model) => model.getPrescriptionsOrders(showLoading: true), + builder: (_, model, widget) => AppScaffold( + baseViewModel: prescriptionsViewModel, + 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!; + late 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), + ), + ], + ), + ), + 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, + ) + : getNoDataWidget(context) + : Container(), + )); } } diff --git a/lib/pages/medical/prescriptions/prescriptions_home_page.dart b/lib/pages/medical/prescriptions/prescriptions_home_page.dart index 380d6284..0ac4d04d 100644 --- a/lib/pages/medical/prescriptions/prescriptions_home_page.dart +++ b/lib/pages/medical/prescriptions/prescriptions_home_page.dart @@ -1,34 +1,37 @@ import 'dart:ui'; +import 'package:diplomaticquarterapp/core/enum/filter_type.dart'; import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/prescriptions_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/medical/prescriptions/prescriptions_history_page.dart'; import 'package:diplomaticquarterapp/pages/medical/prescriptions/prescriptions_page.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:flutter/cupertino.dart'; import 'package:flutter/material.dart'; - -import '../../../Constants.dart'; +import 'package:provider/provider.dart'; class HomePrescriptionsPage extends StatefulWidget { @override _HomePrescriptionsPageState createState() => _HomePrescriptionsPageState(); } -class _HomePrescriptionsPageState extends State - with SingleTickerProviderStateMixin { - TabController _tabController; - List imagesInfo = List(); +class _HomePrescriptionsPageState extends State with SingleTickerProviderStateMixin { + late TabController _tabController; + List imagesInfo =[]; + + late ProjectViewModel projectViewModel; @override void initState() { super.initState(); - _tabController = TabController(length: 2, vsync: this); - imagesInfo.add(ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-prescriptions/en/0.png',imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-prescriptions/ar/0.png')); - imagesInfo.add(ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-prescriptions/en/1.png',imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-prescriptions/ar/1.png')); + _tabController = TabController(length: 3, vsync: this); + imagesInfo.add(ImagesInfo( + imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-prescriptions/en/0.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-prescriptions/ar/0.png')); + imagesInfo.add(ImagesInfo( + imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-prescriptions/en/1.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-prescriptions/ar/1.png')); } @override @@ -39,6 +42,7 @@ class _HomePrescriptionsPageState extends State @override Widget build(BuildContext context) { + projectViewModel = Provider.of(context); return BaseView( onModelReady: (model) => model.getPrescriptions(), builder: (_, model, widget) => AppScaffold( @@ -47,87 +51,69 @@ class _HomePrescriptionsPageState extends State description: TranslationBase.of(context).infoPrescriptions, infoList: TranslationBase.of(context).infoPrescriptionsPoints, imagesInfo: imagesInfo, - body: Scaffold( - extendBodyBehindAppBar: true, - appBar: PreferredSize( - preferredSize: Size.fromHeight(65.0), - child: Stack( - children: [ - Positioned( - bottom: 1, - left: 0, - right: 0, - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10), - child: Container( - color: Theme.of(context) - .scaffoldBackgroundColor - .withOpacity(0.8), - height: 70.0, - ), - ), - ), - Center( - child: Container( - height: 60.0, - margin: EdgeInsets.only(top: 10.0), - width: MediaQuery.of(context).size.width * 0.92, - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Theme.of(context).dividerColor, - width: 0.9), //width: 0.7 - ), - color: Colors.white), - child: Center( - child: TabBar( - isScrollable: true, - controller: _tabController, - indicatorWeight: 5.0, - indicatorSize: TabBarIndicatorSize.tab, - labelColor: Theme.of(context).primaryColor, - labelPadding: - EdgeInsets.only(top: 4.0, left: 35.0, right: 35.0), - unselectedLabelColor: Colors.grey[800], - tabs: [ - Container( - width: MediaQuery.of(context).size.width * 0.30, - child: Center( - child: Texts(TranslationBase.of(context).prescriptions), - ), - ), - Container( - width: MediaQuery.of(context).size.width * 0.30, - child: Center( - child: Texts(TranslationBase.of(context).history), - ), - ), - ], - ), - ), - ), - ), + showNewAppBar: true, + backgroundColor: Color(0xffF8F8F8), + showNewAppBarTitle: true, + body: Column( + children: [ + TabBar( + // isScrollable: true, + controller: _tabController, + indicatorWeight: 3.0, + indicatorSize: TabBarIndicatorSize.tab, + labelColor: Color(0xff2B353E), + unselectedLabelColor: Color(0xff575757), + labelPadding: EdgeInsets.only(top: 15, bottom: 13, left: 20, right: 20), + labelStyle: TextStyle( + fontSize: 15, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + ), + unselectedLabelStyle: TextStyle( + fontSize: 15, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + ), + tabs: [ + Text(TranslationBase.of(context).byClinic, style: TextStyle(fontFamily: projectViewModel.isArabic ? 'Cairo' : 'Poppins')), + Text(TranslationBase.of(context).byHospital, style: TextStyle(fontFamily: projectViewModel.isArabic ? 'Cairo' : 'Poppins')), + Text(TranslationBase.of(context).orderLog, style: TextStyle(fontFamily: projectViewModel.isArabic ? 'Cairo' : 'Poppins')), ], ), - ), - body: Column( - children: [ - Expanded( - child: TabBarView( - physics: BouncingScrollPhysics(), - controller: _tabController, - children: [ - PrescriptionsPage( - prescriptionsViewModel: model, - ), - PrescriptionsHistoryPage( - prescriptionsViewModel: model, - ) - ], - ), - ) - ], - ), + Expanded( + child: TabBarView( + physics: BouncingScrollPhysics(), + controller: _tabController, + children: [ + PrescriptionsPage( + FilterType.Clinic, + prescriptionsViewModel: model, + showOrderLog: () async { + _tabController.animateTo(2); + // await model.getPrescriptionsOrders(showLoading: true); + setState(() {}); + }, + ), + PrescriptionsPage( + FilterType.Hospital, + prescriptionsViewModel: model, + showOrderLog: () async { + _tabController.animateTo(2); + // await model.getPrescriptionsOrders(showLoading: true); + setState(() {}); + }, + ), + PrescriptionsHistoryPage( + prescriptionsViewModel: model, + showOrderLog: () async { + await model.getPrescriptionsOrders(showLoading: true); + setState(() {}); + }, + ) + ], + ), + ) + ], ), ), ); diff --git a/lib/pages/medical/prescriptions/prescriptions_page.dart b/lib/pages/medical/prescriptions/prescriptions_page.dart index abf68328..e550e1b0 100644 --- a/lib/pages/medical/prescriptions/prescriptions_page.dart +++ b/lib/pages/medical/prescriptions/prescriptions_page.dart @@ -1,10 +1,12 @@ import 'package:diplomaticquarterapp/core/enum/filter_type.dart'; +import 'package:diplomaticquarterapp/core/model/prescriptions/Prescriptions.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/prescription_items_page.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/data_display/medical/doctor_card.dart'; +import 'package:diplomaticquarterapp/widgets/new_design/my_tab_view.dart'; import 'package:diplomaticquarterapp/widgets/others/app_expandable_notifier.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; @@ -13,93 +15,68 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; class PrescriptionsPage extends StatelessWidget { - final PrescriptionsViewModel prescriptionsViewModel; + final VoidCallback? showOrderLog; + final FilterType filterType; + final PrescriptionsViewModel? prescriptionsViewModel; - const PrescriptionsPage({Key key, this.prescriptionsViewModel}) - : super(key: key); + const PrescriptionsPage(this.filterType, {Key? key, this.prescriptionsViewModel, this.showOrderLog}) : super(key: key); @override Widget build(BuildContext context) { - ProjectViewModel projectViewModel = Provider.of(context); return AppScaffold( - baseViewModel: prescriptionsViewModel, - body: FractionallySizedBox( - widthFactor: 1.0, - child: ListView( + baseViewModel: prescriptionsViewModel, + body: ListView.separated( + addAutomaticKeepAlives: true, physics: BouncingScrollPhysics(), - children: [ - Row( - children: [ - Expanded( - flex: 1, - child: InkWell( - onTap: () => - prescriptionsViewModel.setFilterType(FilterType.Clinic), - child: ListTile( - title: Text(TranslationBase.of(context).clinic), - leading: Radio( - value: FilterType.Clinic, - groupValue: prescriptionsViewModel.filterType, - onChanged: (FilterType value) { - prescriptionsViewModel.setFilterType(value); - }, - ), - ), - ), - ), - Expanded( - flex: 1, - child: InkWell( - onTap: () => prescriptionsViewModel - .setFilterType(FilterType.Hospital), - child: ListTile( - title: Text(TranslationBase.of(context).hospital), - leading: Radio( - value: FilterType.Hospital, - groupValue: prescriptionsViewModel.filterType, - onChanged: (FilterType value) { - prescriptionsViewModel.setFilterType(value); + padding: EdgeInsets.only(top: 12), + separatorBuilder: (context, index) { + return Container( + height: 12, + margin: EdgeInsets.only(left: 21, right: 21), + // color: Color(0xffD9D9D9), + ); + }, + itemBuilder: (context, index) { + List prescriptionsList = prescriptionsViewModel!.prescriptionsOrderListByValue(filterType)[index].prescriptionsList!; + return AppExpandableNotifier( + title: prescriptionsViewModel!.prescriptionsOrderListByValue(filterType)[index].filterName, + bodyWidget: ListView.separated( + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + padding: EdgeInsets.only(bottom: 14, top: 14, left: 21, right: 21), + itemBuilder: (context, _index) { + Prescriptions prescriptions = prescriptionsList[_index]; + + bool _isSortByClinic = filterType == FilterType.Clinic; + return DoctorCard( + onTap: () async { + final _shouldRecallApi = await Navigator.push( + context, + FadePage( + page: PrescriptionItemsPage( + prescriptions: prescriptions, + ), + ), + ); + if (_shouldRecallApi != null) { + showOrderLog!(); + } }, - ), - ), - ), - ) - ], - ), - ...List.generate( - prescriptionsViewModel.prescriptionsOrderList.length, - (index) => AppExpandableNotifier( - title: prescriptionsViewModel - .prescriptionsOrderList[index].filterName, - bodyWidget: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: prescriptionsViewModel - .prescriptionsOrderList[index].prescriptionsList - .map((prescriptions) { - return InkWell( - onTap: () => Navigator.push( - context, - FadePage( - page: PrescriptionItemsPage(prescriptions: prescriptions,), - ), - ), - child: DoctorCard( - name: prescriptions.doctorName, - profileUrl: prescriptions.doctorImageURL, - rat: prescriptions.actualDoctorRate.toDouble(), - subName: prescriptions.name, - isInOutPatient: prescriptions.isInOutPatient, - isLiveCareAppointment: prescriptions.isLiveCareAppointment, - date:projectViewModel.isArabic? DateUtil.getMonthDayYearDateFormattedAr( DateUtil.convertStringToDate(prescriptions.appointmentDate) ):DateUtil.getMonthDayYearDateFormatted(DateUtil.convertStringToDate(prescriptions.appointmentDate)), - ), - ); - }).toList(), - )), - ) - ], - ), - ), - ); + name: prescriptions.doctorName, + profileUrl: prescriptions.doctorImageURL, + rating: prescriptions.actualDoctorRate!.toDouble(), + subName: _isSortByClinic ? prescriptions.name : prescriptions.clinicDescription, + isSortByClinic: _isSortByClinic, + isInOutPatient: prescriptions.isInOutPatient, + isLiveCareAppointment: prescriptions.isLiveCareAppointment, + date: DateUtil.convertStringToDate(prescriptions.appointmentDate!) //projectViewModel.isArabic? DateUtil.getMonthDayYearDateFormattedAr( DateUtil.convertStringToDate(prescriptions.appointmentDate) ):DateUtil.getMonthDayYearDateFormatted(DateUtil.convertStringToDate(prescriptions.appointmentDate)), + ); + }, + separatorBuilder: (context, index) => SizedBox(height: 14), + itemCount: prescriptionsList.length), + ); + }, + itemCount: prescriptionsViewModel!.prescriptionsOrderListByValue(filterType).length, + )); } } diff --git a/lib/pages/medical/radiology/radiology_details_page.dart b/lib/pages/medical/radiology/radiology_details_page.dart index 742e3ddf..4d127148 100644 --- a/lib/pages/medical/radiology/radiology_details_page.dart +++ b/lib/pages/medical/radiology/radiology_details_page.dart @@ -1,13 +1,17 @@ import 'package:diplomaticquarterapp/config/config.dart'; -import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/radiology/final_radiology.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/radiology_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; +import 'package:diplomaticquarterapp/models/header_model.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'; -import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.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/dialogs/confirm_send_email_dialog.dart'; +import 'package:diplomaticquarterapp/widgets/new_design/doctor_header.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -15,97 +19,118 @@ import 'package:provider/provider.dart'; import 'package:url_launcher/url_launcher.dart'; class RadiologyDetailsPage extends StatelessWidget { - final FinalRadiology finalRadiology; + final FinalRadiology? finalRadiology; + bool? isRadiologyVidaPlus; - RadiologyDetailsPage({Key key, this.finalRadiology}); + RadiologyDetailsPage({Key? key, this.finalRadiology, this.isRadiologyVidaPlus}); @override Widget build(BuildContext context) { ProjectViewModel projectViewModel = Provider.of(context); return BaseView( onModelReady: (model) => model.getRadImageURL( - projectId: finalRadiology.projectID, - lineItem: finalRadiology.invoiceLineItemNo, - invoiceNo: finalRadiology.invoiceNo), + projectId: finalRadiology!.projectID!, + invoiceType: finalRadiology!.invoiceType, + lineItem: finalRadiology!.invoiceLineItemNo!, + invoiceNo: Utils.isVidaPlusProject(projectViewModel, finalRadiology!.projectID!) ? finalRadiology!.invoiceNo_VP : finalRadiology!.invoiceNo, + isVidaPlus: Utils.isVidaPlusProject(projectViewModel, finalRadiology!.projectID!), + examId: finalRadiology!.exam_Id!), builder: (_, model, widget) => AppScaffold( - appBarTitle: TranslationBase.of(context).report, - isShowAppBar: true, - baseViewModel: model, - body: SingleChildScrollView( - child: Column( - mainAxisSize: MainAxisSize.max, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Texts( - '${finalRadiology.reportData}', - textAlign: TextAlign.center, + appBarTitle: TranslationBase.of(context).report, + isShowAppBar: true, + baseViewModel: model, + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: Color(0xffF8F8F8), + body: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.max, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + DoctorHeader( + headerModel: new HeaderModel( + finalRadiology!.doctorName!, + finalRadiology!.doctorID!, + finalRadiology!.doctorImageURL!, + finalRadiology!.speciality ?? [""], + Utils.isVidaPlusProject(projectViewModel, finalRadiology!.projectID!) ? finalRadiology!.invoiceNo_VP.toString() : finalRadiology!.invoiceNo.toString(), + finalRadiology!.projectName!, + finalRadiology!.orderDate, + null, + finalRadiology!.nationalityFlagURL ?? "", + finalRadiology!.doctorRate, + finalRadiology!.actualDoctorRate, + finalRadiology!.noOfPatientsRate, + projectViewModel.user.emailAddress!, ), - Padding( - padding: const EdgeInsets.all(8.0), - child: Texts( - '${finalRadiology.reportData}', - textAlign: TextAlign.start, - fontSize: 17, + onTap: () async { + GifLoaderDialogUtils.showMyDialog(context); + await model.sendRadReportEmail(mes: TranslationBase.of(AppGlobal.context).sendSuc, finalRadiology: finalRadiology!, userObj: projectViewModel.user, isDownload: true); + GifLoaderDialogUtils.hideDialog(context); + // showConfirmMessage(finalRadiology: finalRadiology!, model: model, userObj: projectViewModel.user!, isDownload: true); + }, + buttonTitle: TranslationBase.of(context).download, + buttonIcon: "assets/images/new/download_1.svg", + showConfirmMessageDialog: false, + isDownload: true, + isNeedToShowButton: projectViewModel.havePrivilege(8), + // showConfirmMessageDialog: false, + ), + Container( + margin: EdgeInsets.all(24), + decoration: cardRadius(12), + child: Container( + width: double.infinity, + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + "General Result", + style: TextStyle( + fontSize: 16, + letterSpacing: -0.64, + fontWeight: FontWeight.w600, + ), + ), + mHeight(10), + Text( + '${finalRadiology!.reportData}', + style: TextStyle(fontSize: 12, letterSpacing: -0.48), + ), + mHeight(16), + (projectViewModel.havePrivilege(9) || projectViewModel.havePrivilege(8)) + ? (finalRadiology!.dIAPACSURL != "" && projectViewModel.havePrivilege(9)) + ? Container( + child: DefaultButton( + TranslationBase.of(context).openRad, + () => {launch(model.radImageURL)}, + textColor: Colors.white, + ), + ) + : Container() + : Container(), + ], + ), ), ), - SizedBox( - height: MediaQuery.of(context).size.height * 0.2, - ) - ], - ), + ), + ], ), - bottomSheet: (projectViewModel.havePrivilege(9) || - projectViewModel.havePrivilege(8)) - ? Container( - width: double.infinity, - height: finalRadiology.dIAPACSURL != "" - ? MediaQuery.of(context).size.height * 0.25 - : MediaQuery.of(context).size.height * 0.14, - color: Colors.grey[100], - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Divider(), - if (finalRadiology.dIAPACSURL != "" && projectViewModel.havePrivilege(9)) - Container( - width: MediaQuery.of(context).size.width * 0.8, - child: Button( - onTap: () { - launch(model.radImageURL); - }, - label: TranslationBase.of(context).openRad, - backgroundColor: Colors.grey[800], - ), - ), - if (projectViewModel.havePrivilege(8)) - Container( - width: MediaQuery.of(context).size.width * 0.8, - child: Button( - onTap: () { - showConfirmMessage( - finalRadiology: finalRadiology, model: model); - }, - label: TranslationBase.of(context).sendCopyRad, - loading: model.state == ViewState.BusyLocal, - backgroundColor: Theme.of(context).primaryColor, - ), - ) - ], - ), - ):Container()), + ), + ), ); } - void showConfirmMessage( - {FinalRadiology finalRadiology, RadiologyViewModel model}) { + void showConfirmMessage({FinalRadiology? finalRadiology, RadiologyViewModel? model, AuthenticatedUser? userObj, required bool isDownload}) { showDialog( context: AppGlobal.context, - child: ConfirmSendEmailDialog( - email: model.user.emailAddress, + builder: (cxt) => ConfirmSendEmailDialog( + email: model!.user!.emailAddress, onTapSendEmail: () { - model.sendRadReportEmail( - mes: TranslationBase.of(AppGlobal.context).sendSuc, - finalRadiology: finalRadiology); + model.sendRadReportEmail(mes: TranslationBase.of(AppGlobal.context).sendSuc, finalRadiology: finalRadiology!, userObj: userObj!, isDownload: isDownload); }, ), ); diff --git a/lib/pages/medical/radiology/radiology_home_page.dart b/lib/pages/medical/radiology/radiology_home_page.dart index 2123172a..fb60d5da 100644 --- a/lib/pages/medical/radiology/radiology_home_page.dart +++ b/lib/pages/medical/radiology/radiology_home_page.dart @@ -1,12 +1,14 @@ import 'package:diplomaticquarterapp/core/enum/filter_type.dart'; import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; +import 'package:diplomaticquarterapp/core/model/radiology/final_radiology.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/radiology_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/medical/radiology/radiology_details_page.dart'; -import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/data_display/medical/doctor_card.dart'; +import 'package:diplomaticquarterapp/widgets/new_design/my_tab_view.dart'; import 'package:diplomaticquarterapp/widgets/others/app_expandable_notifier.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; @@ -15,96 +17,124 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; class RadiologyHomePage extends StatelessWidget { - List imagesInfo = List(); + List imagesInfo =[]; + @override Widget build(BuildContext context) { ProjectViewModel projectViewModel = Provider.of(context); - imagesInfo.add(ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-radiology/en/0.png',imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-radiology/ar/0.png')); - imagesInfo.add(ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-radiology/en/1.png',imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-radiology/ar/1.png')); + imagesInfo.add( + ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-radiology/en/0.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-radiology/ar/0.png')); + imagesInfo.add( + ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-radiology/en/1.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-radiology/ar/1.png')); return BaseView( onModelReady: (model) => model.getPatientRadOrders(), builder: (_, model, widget) => AppScaffold( isShowAppBar: true, appBarTitle: TranslationBase.of(context).radiology, baseViewModel: model, + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: Color(0xffF8F8F8), description: TranslationBase.of(context).infoRadiology, imagesInfo: imagesInfo, - body: FractionallySizedBox( - widthFactor: 1.0, - child: ListView( - physics: BouncingScrollPhysics(), - children: [ - Row( - children: [ - Expanded( - flex: 1, - child: InkWell( - onTap: () => - model.setFilterType(FilterType.Clinic), - child: ListTile( - title: Text(TranslationBase.of(context).clinic), - leading: Radio( - value: FilterType.Clinic, - groupValue: model.filterType, - onChanged: (FilterType value) { - model.setFilterType(value); - }, - ), - ), - ), - ), - Expanded( - flex: 1, - child: InkWell( - onTap: () => model - .setFilterType(FilterType.Hospital), - child: ListTile( - title: Text(TranslationBase.of(context).hospital), - leading: Radio( - value: FilterType.Hospital, - groupValue: model.filterType, - onChanged: (FilterType value) { - model.setFilterType(value); - }, - ), - ), - ), - ) - ], + body: Column( + children: [ + Row( + children: [ + MyTabView(TranslationBase.of(context).byClinic, FilterType.Clinic, model.filterType, () { + model.setFilterType(FilterType.Clinic); + }), + MyTabView(TranslationBase.of(context).byHospital, FilterType.Hospital, model.filterType, () { + model.setFilterType(FilterType.Hospital); + }), + ], + ), + + Expanded( + child: FractionallySizedBox( + widthFactor: 1.0, + child: ListView.separated( + addAutomaticKeepAlives: true, + physics: BouncingScrollPhysics(), + padding: EdgeInsets.only(top: 12), + separatorBuilder: (context, index) { + return Container( + height: 12, + margin: EdgeInsets.only(left: 21, right: 21), + // color: Color(0xffD9D9D9), + ); + }, + itemBuilder: (context, index) { + return AppExpandableNotifier( + title: model.finalRadiologyList[index].filterName, + bodyWidget: ListView.separated( + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + padding: EdgeInsets.only(bottom: 14, top: 14, left: 21, right: 21), + itemBuilder: (context, _index) { + FinalRadiology radiology = model.finalRadiologyList[index].finalRadiologyList![_index]; + bool _isSortByClinic = model.filterType == FilterType.Clinic; + return DoctorCard( + onTap: () => Navigator.push( + context, + FadePage( + page: RadiologyDetailsPage( + finalRadiology: radiology, + isRadiologyVidaPlus: Utils.isVidaPlusProject(projectViewModel, radiology.projectID!), + ), + ), + ), + isInOutPatient: radiology.isInOutPatient, + name: TranslationBase.of(context).dr + " " + radiology.doctorName!, + billNo: Utils.isVidaPlusProject(projectViewModel, radiology.projectID!) ? radiology.invoiceNo_VP.toString() : radiology.invoiceNo.toString(), + // billNo: radiology.invoiceNo_VP.toString(), + profileUrl: radiology.doctorImageURL, + subName: _isSortByClinic ? radiology.projectName : radiology.clinicDescription, + isLiveCareAppointment: radiology.isLiveCareAppointment, + date: radiology.orderDate, + isSortByClinic: _isSortByClinic, + //projectViewModel.isArabic ? DateUtil.getMonthDayYearDateFormattedAr(labOrder.orderDate) : DateUtil.getMonthDayYearDateFormatted(labOrder.orderDate), + ); + }, + separatorBuilder: (context, index) => SizedBox(height: 14), + itemCount: model.finalRadiologyList[index].finalRadiologyList!.length), + ); + }, + itemCount: model.finalRadiologyList.length), ), - ...List.generate( - model.finalRadiologyList.length, - (index) => AppExpandableNotifier( - title: model - .finalRadiologyList[index].filterName, - bodyWidget: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: model - .finalRadiologyList[index].finalRadiologyList - .map((radiology) { - return InkWell( - onTap: () => Navigator.push( - context, - FadePage( - page: RadiologyDetailsPage(finalRadiology: radiology,), - ), - ), - child: DoctorCard( - isInOutPatient: radiology.isInOutPatient, - isLiveCareAppointment: radiology.isLiveCareAppointment, - name: radiology.doctorName, - profileUrl: radiology.doctorImageURL, - billNo: '${radiology.invoiceNo}', - subName: '${radiology.projectName}', - date: projectViewModel.isArabic? DateUtil.getMonthDayYearDateFormattedAr(radiology.orderDate):DateUtil.getMonthDayYearDateFormatted(radiology.orderDate), - ), - ); - }).toList(), - )), - ) - ], - ), + ), + // ...List.generate( + // model.finalRadiologyList.length, + // (index) => AppExpandableNotifier( + // title: model + // .finalRadiologyList[index].filterName, + // bodyWidget: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + // children: model + // .finalRadiologyList[index].finalRadiologyList + // .map((radiology) { + // return InkWell( + // onTap: () => Navigator.push( + // context, + // FadePage( + // page: RadiologyDetailsPage(finalRadiology: radiology,), + // ), + // ), + // child: DoctorCard( + // isInOutPatient: radiology.isInOutPatient, + // isLiveCareAppointment: radiology.isLiveCareAppointment, + // name: radiology.doctorName, + // profileUrl: radiology.doctorImageURL, + // billNo: '${radiology.invoiceNo}', + // subName: '${radiology.projectName}', + // date: radiology.orderDate//projectViewModel.isArabic? DateUtil.getMonthDayYearDateFormattedAr(radiology.orderDate):DateUtil.getMonthDayYearDateFormatted(radiology.orderDate), + // ), + // ); + // }).toList(), + // )), + // ) + ], ), ), ); diff --git a/lib/pages/medical/reports/inpatient_medical_reports_page.dart b/lib/pages/medical/reports/inpatient_medical_reports_page.dart new file mode 100644 index 00000000..af3ee6d9 --- /dev/null +++ b/lib/pages/medical/reports/inpatient_medical_reports_page.dart @@ -0,0 +1,132 @@ +import 'package:diplomaticquarterapp/core/model/reports/admission_for_medical_report.dart'; +import 'package:diplomaticquarterapp/core/viewModels/medical/reports_view_model.dart'; +import 'package:diplomaticquarterapp/extensions/string_extensions.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/pages/medical/reports/report_list_widget.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.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:flutter/material.dart'; + +class InPatientMedicalReports extends StatefulWidget { + final AdmissionMedicalReport admissionMedicalReport; + + InPatientMedicalReports({required this.admissionMedicalReport}); + + @override + State createState() => _InPatientMedicalReportsState(); +} + +class _InPatientMedicalReportsState extends State { + int _currentPage = 0; + + @override + void initState() { + super.initState(); + } + + @override + Widget build(BuildContext context) { + return BaseView( + onModelReady: (model) { + model.getInPatientReports(); + }, + builder: (_, model, widget) => AppScaffold( + isShowAppBar: true, + appBarTitle: TranslationBase.of(context).newMedReport, + title: TranslationBase.of(context).medReport, + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: Color(0xffF7F7F7), + body: Container( + child: Column( + children: [ + Padding( + padding: EdgeInsets.all(21), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + myRadioButton(TranslationBase.of(context).requested, 0), + myRadioButton(TranslationBase.of(context).ready, 1), + myRadioButton(TranslationBase.of(context).cancelled, 2), + ], + ), + ), + Expanded( + child: IndexedStack( + index: _currentPage, + children: [ + ReportListWidget(reportList: model.reportsInPatientOrderRequestList, emailAddress: model.user!.emailAddress!), + ReportListWidget(reportList: model.reportsInPatientOrderReadyList, emailAddress: model.user!.emailAddress!), + ReportListWidget(reportList: model.reportsInPatientOrderCanceledList, emailAddress: model.user!.emailAddress!), + ], + ), + ), + Padding( + padding: EdgeInsets.only(top: 16, bottom: 16, right: 21, left: 21), + child: DefaultButton( + TranslationBase.of(context).requestMedicalReport.toLowerCase().capitalizeFirstofEach, + () { + confirmBox(model); + }, + ), + ), + ], + ), + ), + ), + ); + } + + void confirmBox(ReportsViewModel reportsViewModel) { + showDialog( + context: context, + builder: (cxt) => ConfirmWithMessageDialog( + message: TranslationBase.of(context).confirmMsgReport, + onTap: () => reportsViewModel.insertRequestForInPatientMedicalReport(widget.admissionMedicalReport.clinicID!, widget.admissionMedicalReport.doctorID!, widget.admissionMedicalReport.setupID!, + widget.admissionMedicalReport.admissionNo!, widget.admissionMedicalReport.projectID!, TranslationBase.of(context).successSendReport), + ), + ); + return; + } + + Widget myRadioButton(String _label, int _value) { + return InkWell( + onTap: () { + setState(() { + _currentPage = _value; + }); + }, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox( + width: 22, + height: 22, + child: Radio( + value: _value, + activeColor: _value == _currentPage ? Color(0xffD02127) : Color(0xffE8E8E8), + groupValue: _currentPage, + onChanged: (index) { + setState(() { + _currentPage = index!; + }); + }, + ), + ), + SizedBox(width: 10), + Text( + _label, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + color: Color(0xff575757), + letterSpacing: -0.56, + ), + ), + ], + ), + ); + } +} diff --git a/lib/pages/medical/reports/monthly_reports.dart b/lib/pages/medical/reports/monthly_reports.dart index 4484bd5f..4b59d7a0 100644 --- a/lib/pages/medical/reports/monthly_reports.dart +++ b/lib/pages/medical/reports/monthly_reports.dart @@ -1,17 +1,18 @@ -import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/reports_monthly_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/medical/reports/user_agreement_page.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/input/custom_switch.dart'; -import 'package:diplomaticquarterapp/widgets/input/text_field.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; +import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; class MonthlyReportsPage extends StatefulWidget { @override @@ -24,174 +25,230 @@ class _MonthlyReportsPageState extends State { String email = ""; final formKey = GlobalKey(); + List imagesInfo = []; + + @override + void initState() { + imagesInfo.add(ImagesInfo( + imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/monthly-reports/en/0.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/monthly-reports/ar/0.png')); + imagesInfo.add(ImagesInfo( + imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/monthly-reports/en/1.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/monthly-reports/ar/1.png')); + super.initState(); + } + @override Widget build(BuildContext context) { - return BaseView( - builder: (_, model, w) => AppScaffold( + ProjectViewModel projectViewModel = Provider.of(context); + return BaseView(builder: (_, model, w) { + if (isSummary == null) { + isSummary = model.receiveHealthSummaryReport; + } + if (isAgree == null) { + isAgree = model.receiveHealthSummaryReport; + } + if (email == null) { + email = model.user.emailAddress ?? ""; + } + return AppScaffold( isShowAppBar: true, appBarTitle: TranslationBase.of(context).monthlyReports, + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: Color(0xffF7F7F7), + imagesInfo: imagesInfo, + description: TranslationBase.of(context).infoMonthReport, body: SingleChildScrollView( - child: Container( - padding: EdgeInsets.all(12), - child: Form( - key: formKey, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - padding: EdgeInsets.all(9), - height: 55, - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.all(Radius.circular(8)), - shape: BoxShape.rectangle, - border: Border.all(color: Colors.grey)), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - - Texts( - TranslationBase.of(context).patientHealthSummaryReport, - bold: true, + physics: BouncingScrollPhysics(), + padding: EdgeInsets.all(21), + child: Form( + key: formKey, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + padding: EdgeInsets.only(right: 12, left: 12, top: 14, bottom: 14), + decoration: BoxDecoration( + borderRadius: BorderRadius.all( + Radius.circular(10.0), + ), + boxShadow: [ + BoxShadow( + color: Color(0xff000000).withOpacity(.05), + //spreadRadius: 5, + blurRadius: 27, + offset: Offset(0, -3), ), - CustomSwitch( - value: isSummary, - activeColor: Colors.red, - inactiveColor: Colors.grey, - onChanged: () async { - setState(() { - isSummary = !isSummary; - }); - if(!isSummary) { - GifLoaderDialogUtils.showMyDialog(context); - await model.updatePatientHealthSummaryReport( - message: TranslationBase - .of(context) - .updateSuccessfully, isSummary: isSummary); - GifLoaderDialogUtils.hideDialog(context); - } - }, - ) ], - ), - ), - SizedBox( - height: 15, - ), - Container( - margin: EdgeInsets.all(8), - child: TextFields( - fillColor: Colors.red, - hintText: 'email@email.com', - fontSize: 20, - initialValue: model.user.emailAddress, - fontWeight: FontWeight.w600, - onChanged: (text) { - email = text; - }, - validator: (value) { - if (value.isEmpty) - return TranslationBase.of(context).enterEmail; - else - return null; - }, - ), - ), - Divider( - height: 10.4, - thickness: 1.0, - ), - SizedBox( - height: 15, - ), - Container( - margin: EdgeInsets.all(8), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Expanded( - child: Texts(TranslationBase.of(context) - .toViewTheTermsAndConditions), - ), - InkWell( - onTap: () { - Navigator.push( - context, - FadePage( - page: UserAgreementContent(), - ), - ); - }, - child: Texts( - TranslationBase.of(context).clickHere, - color: Colors.blue, - ), - ) - ], - ), - ), - SizedBox( - height: 5, - ), - Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.start, + color: Colors.white), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Checkbox( - value: isAgree, - onChanged: (value) { + Expanded( + child: Text( + TranslationBase.of(context).patientHealthSummaryReport, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64, height: 25 / 16), + ), + ), + CustomSwitch( + value: isSummary, + activeColor: Color(0xffD02127), + inactiveColor: Color(0xff28323A).withOpacity(0.3), + onChanged: () async { setState(() { - isAgree = !isAgree; + isSummary = !isSummary; }); + if (!isSummary) { + GifLoaderDialogUtils.showMyDialog(context); + print("is Summry: $isSummary"); + await model.updatePatientHealthSummaryReport(message: TranslationBase.of(context).updateSuccessfully, isSummary: isSummary); + model.receiveHealthSummaryReport = isSummary; + isAgree = isSummary; + model.user.emailAddress = ""; + GifLoaderDialogUtils.hideDialog(context); + } }, - activeColor: Colors.red, + ) + ], + ), + ), + SizedBox( + height: 15, + ), + 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: Row( + children: [ + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).email, + style: TextStyle( + fontSize: 11, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.44, + ), + ), + TextFormField( + scrollPadding: EdgeInsets.zero, + keyboardType: TextInputType.emailAddress, + // controller: _controller, + onChanged: (value) => {email = value}, + initialValue: email, + style: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: Color(0xff2B353E), + letterSpacing: -0.44, + ), + validator: (value) { + if (value!.isEmpty) + return TranslationBase.of(context).enterEmail; + else + return null; + }, + decoration: InputDecoration( + isDense: true, + hintText: "email@email.com", + 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, + ), + ), + ], + ), ), - Texts(TranslationBase.of(context).iAgreeToTheTermsAndConditions), ], ), - Container( - margin: EdgeInsets.all(8), - width: double.infinity, - child: SecondaryButton( - textColor: Colors.white, - label: TranslationBase.of(context).save, - disabled: (!isAgree || !isSummary ), - onTap: () async { - final form = formKey.currentState; - if (form.validate()) { - GifLoaderDialogUtils.showMyDialog(context); - await model.updatePatientHealthSummaryReport( - message: TranslationBase - .of(context) - .updateSuccessfully, - isSummary: isSummary, - isUpdateEmail: true, - email: email.isNotEmpty ? email : model.user - .emailAddress); - GifLoaderDialogUtils.hideDialog(context); - } + ), + SizedBox( + height: 12, + ), + RichText( + text: TextSpan( + text: TranslationBase.of(context).toViewTheTermsAndConditions + " ", + style: TextStyle( + fontSize: 16, fontWeight: FontWeight.w500, color: Color(0xff2B353E), letterSpacing: -0.64, height: 23 / 16, fontFamily: projectViewModel.isArabic ? 'Cairo' : 'Poppins'), + children: [ + TextSpan( + text: TranslationBase.of(context).clickHere, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Colors.blue, letterSpacing: -0.64, height: 23 / 16), + recognizer: new TapGestureRecognizer() + ..onTap = () => Navigator.push( + context, + FadePage( + page: UserAgreementContent(), + ), + ), + ) + ]), + ), + Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Checkbox( + value: isAgree, + onChanged: (value) { + setState(() { + isAgree = !isAgree; + }); }, + activeColor: Color(0xffD02127), ), - ), - Padding( - padding: const EdgeInsets.all(5.0), - child: Texts( - TranslationBase.of(context) - .instructionAgree, - fontWeight: FontWeight.normal, + Text( + TranslationBase.of(context).iAgreeToTheTermsAndConditions, + style: TextStyle(fontSize: 14, fontWeight: FontWeight.w400, color: Color(0xff2B353E), letterSpacing: -0.56, height: 21 / 14), ), - ), - SizedBox( - height: 12, - ), - Center(child: Image.asset('assets/images/report.jpg')) - ], - ), + ], + ), + DefaultButton( + TranslationBase.of(context).save, + () async { + final form = formKey.currentState; + if (form!.validate()) { + GifLoaderDialogUtils.showMyDialog(context); + await model.updatePatientHealthSummaryReport( + message: TranslationBase.of(context).updateSuccessfully, isSummary: isSummary, isUpdateEmail: true, email: email.isNotEmpty ? email : model.user!.emailAddress); + model.receiveHealthSummaryReport = isSummary; + model.user!.emailAddress = email.isNotEmpty ? email : model.user!.emailAddress; + GifLoaderDialogUtils.hideDialog(context); + } + }, + ), + SizedBox(height: 12), + Text( + TranslationBase.of(context).instructionAgree, + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.48, height: 18 / 12), + ), + SizedBox(height: 12), + Center(child: Image.asset('assets/images/report.jpg')) + ], ), ), ), - ), - ); + ); + }); } } diff --git a/lib/pages/medical/reports/report_home_page.dart b/lib/pages/medical/reports/report_home_page.dart index f9efb1a1..f70f0793 100644 --- a/lib/pages/medical/reports/report_home_page.dart +++ b/lib/pages/medical/reports/report_home_page.dart @@ -1,14 +1,21 @@ import 'dart:ui'; import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; +import 'package:diplomaticquarterapp/core/model/reports/admission_for_medical_report.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/reports_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/extensions/string_extensions.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/pages/medical/reports/inpatient_medical_reports_page.dart'; import 'package:diplomaticquarterapp/pages/medical/reports/report_list_widget.dart'; import 'package:diplomaticquarterapp/pages/medical/reports/reports_page.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.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/uitl/utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:diplomaticquarterapp/widgets/my_rich_text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; @@ -20,174 +27,324 @@ class HomeReportPage extends StatefulWidget { _HomeReportPageState createState() => _HomeReportPageState(); } -class _HomeReportPageState extends State - with SingleTickerProviderStateMixin { - TabController _tabController; - List imagesInfo = List(); +class _HomeReportPageState extends State with SingleTickerProviderStateMixin { + late TabController _tabController_new; + List imagesInfo =[]; + int _currentPage = 0; + ProjectViewModel? projectViewModel; @override void initState() { + _tabController_new = TabController(length: 2, vsync: this); super.initState(); - _tabController = TabController(length: 4, vsync: this); } @override void dispose() { super.dispose(); - _tabController.dispose(); + _tabController_new.dispose(); } @override Widget build(BuildContext context) { - ProjectViewModel projectViewModel = Provider.of(context); + projectViewModel = Provider.of(context); imagesInfo.add(ImagesInfo( - imageEn: - 'https://hmgwebservices.com/Images/MobileApp/imges-info/medical-reorts/en/0.png', - imageAr: - 'https://hmgwebservices.com/Images/MobileApp/imges-info/medical-reorts/ar/0.png')); + imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/medical-reorts/en/0.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/medical-reorts/ar/0.png')); imagesInfo.add(ImagesInfo( - imageEn: - 'https://hmgwebservices.com/Images/MobileApp/imges-info/medical-reorts/en/1.png', - imageAr: - 'https://hmgwebservices.com/Images/MobileApp/imges-info/medical-reorts/ar/1.png')); + imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/medical-reorts/en/1.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/medical-reorts/ar/1.png')); imagesInfo.add(ImagesInfo( - imageEn: - 'https://hmgwebservices.com/Images/MobileApp/imges-info/medical-reorts/en/2.png', - imageAr: - 'https://hmgwebservices.com/Images/MobileApp/imges-info/medical-reorts/ar/2.png')); + imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/medical-reorts/en/2.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/medical-reorts/ar/2.png')); return BaseView( - onModelReady: (model) => model.getReports(), //model.getPrescriptions(), + onModelReady: (model) { + model.getReports(projectViewModel!.isArabic ? 1 : 2); + }, builder: (_, model, widget) => AppScaffold( isShowAppBar: true, appBarTitle: TranslationBase.of(context).newMedReport, title: TranslationBase.of(context).medReport, description: TranslationBase.of(context).infoMonthReport, baseViewModel: model, + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: Color(0xffF7F7F7), imagesInfo: imagesInfo, - body: Scaffold( - extendBodyBehindAppBar: true, - appBar: PreferredSize( - preferredSize: Size.fromHeight(65.0), - child: Stack( - children: [ - Positioned( - bottom: 1, - left: 0, - right: 0, - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10), - child: Container( - color: Theme.of(context) - .scaffoldBackgroundColor - .withOpacity(0.8), - height: 70.0, - ), - ), - ), - Center( - child: Container( - height: 60.0, - margin: EdgeInsets.only(top: 10.0), - width: MediaQuery.of(context).size.width * 0.9, - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Theme.of(context).dividerColor, - width: 0.7), - ), - color: Colors.white), - child: Center( - child: TabBar( - isScrollable: true, - controller: _tabController, - indicatorWeight: 5.0, - indicatorSize: TabBarIndicatorSize.tab, - labelColor: Theme.of(context).primaryColor, - unselectedLabelColor: Colors.grey[800], - tabs: [ - Container( - width: MediaQuery.of(context).size.width * 0.20, - child: Center( - child: Texts(TranslationBase.of(context).requested,fontSize: 11,), - ), - ), - Container( - width: MediaQuery.of(context).size.width * 0.20, - child: Center( - child: Texts(TranslationBase.of(context).ready,fontSize: 11,), - ), - ), - Container( - width: MediaQuery.of(context).size.width * 0.20, - child: Center( - child: - Texts(TranslationBase.of(context).completed,fontSize: 11,), - ), - ), - Container( - width: MediaQuery.of(context).size.width * 0.20, - child: Center( - child: - Texts(TranslationBase.of(context).cancelled,fontSize: 11,), + body: Container( + child: Column( + children: [ + // TabBar( + // controller: _tabController_new, + // indicatorWeight: 3.0, + // indicatorSize: TabBarIndicatorSize.tab, + // labelColor: Color(0xff2B353E), + // unselectedLabelColor: Color(0xff575757), + // labelPadding: EdgeInsets.only(top: 15, bottom: 13, left: 20, right: 20), + // labelStyle: TextStyle( + // fontSize: 16, + // fontWeight: FontWeight.w600, + // letterSpacing: -0.48, + // ), + // unselectedLabelStyle: TextStyle( + // fontSize: 16, + // fontWeight: FontWeight.w600, + // letterSpacing: -0.48, + // ), + // onTap: (int value) { + // print(value); + // setState(() {}); + // }, + // tabs: [ + // Text( + // TranslationBase.of(context).outpatient, + // style: TextStyle(fontFamily: projectViewModel.isArabic ? 'Cairo' : 'Poppins'), + // ), + // Text( + // TranslationBase.of(context).inPatient, + // style: TextStyle(fontFamily: projectViewModel.isArabic ? 'Cairo' : 'Poppins'), + // ), + // ], + // ), + + + // TabBar( + // controller: _tabController_new, + // indicatorWeight: 3.0, + // indicatorSize: TabBarIndicatorSize.tab, + // labelColor: Color(0xff2B353E), + // unselectedLabelColor: Color(0xff575757), + // labelPadding: EdgeInsets.only(top: 15, bottom: 13, left: 20, right: 20), + // labelStyle: TextStyle( + // fontSize: 16, + // fontWeight: FontWeight.w600, + // letterSpacing: -0.48, + // ), + // unselectedLabelStyle: TextStyle( + // fontSize: 16, + // fontWeight: FontWeight.w600, + // letterSpacing: -0.48, + // ), + // onTap: (int value) { + // print(value); + // setState(() {}); + // }, + // tabs: [ + // Text( + // TranslationBase.of(context).outpatient, + // style: TextStyle(fontFamily: projectViewModel!.isArabic ? 'Cairo' : 'Poppins'), + // ), + // Text( + // TranslationBase.of(context).inPatient, + // style: TextStyle(fontFamily: projectViewModel!.isArabic ? 'Cairo' : 'Poppins'), + // ), + // ], + // ), + + + if (model.user != null) + Expanded( + child: TabBarView( + physics: BouncingScrollPhysics(), + controller: _tabController_new, + children: [ + Container( + child: Column( + children: [ + Padding( + padding: EdgeInsets.all(21), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + myRadioButton(TranslationBase.of(context).requested, 0), + myRadioButton(TranslationBase.of(context).ready, 1), + myRadioButton(TranslationBase.of(context).cancelled, 2), + ], + ), ), - ), - ], + Expanded( + child: IndexedStack( + index: _currentPage, + children: [ + ReportListWidget(reportList: model.reportsOrderRequestList, emailAddress: model.user.emailAddress), + ReportListWidget(reportList: model.reportsOrderReadyList, emailAddress: model.user.emailAddress), + ReportListWidget(reportList: model.reportsOrderCanceledList, emailAddress: model.user.emailAddress), + ], + ), + ) + ], + ), ), - ), + // InPatient Medical Reports + Container( + child: model.admissionsMedicalReportList.isNotEmpty + ? Column( + children: [ + Padding( + padding: const EdgeInsets.all(16.0), + child: Text( + TranslationBase.of(context).selectAdmissionText, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.64, height: 25 / 16), + ), + ), + ListView.separated( + physics: BouncingScrollPhysics(), + shrinkWrap: true, + padding: EdgeInsets.only(left: 21, right: 21, top: 12, bottom: 12), + itemBuilder: (context, index) { + AdmissionMedicalReport admissionMedicalReport = model.admissionsMedicalReportList[index]; + return InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: InPatientMedicalReports( + admissionMedicalReport: admissionMedicalReport, + ), + ), + ); + }, + child: Container( + // height: 100.0, + decoration: BoxDecoration( + borderRadius: BorderRadius.all( + Radius.circular(10.0), + ), + boxShadow: [ + BoxShadow( + color: Color(0xff000000).withOpacity(.05), + blurRadius: 27, + offset: Offset(0, -3), + ), + ], + color: Colors.white), + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).dr + " " + admissionMedicalReport.doctorNameObj!, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.64, height: 25 / 16), + ), + Column( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text(DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(admissionMedicalReport.admissionDate!)), + style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.48, height: 18 / 12)), + Text(admissionMedicalReport.projectName!, + style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.48, height: 18 / 12)), + ], + ), + ], + ), + Row( + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + if (admissionMedicalReport.clinicName != null) + MyRichText(TranslationBase.of(context).clinic + ":", admissionMedicalReport.clinicName!, projectViewModel!.isArabic), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + MyRichText( + TranslationBase.of(context).status + ":", + projectViewModel!.isArabic ? admissionMedicalReport.statusDescriptionN! : admissionMedicalReport.statusDescription!, + projectViewModel!.isArabic), + Icon( + Icons.arrow_forward, + color: Theme.of(context).primaryColor, + ) + ], + ), + ], + ), + ), + ], + ) + ], + ), + ), + ), + ); + }, + separatorBuilder: (context, index) => SizedBox( + height: 16.0, + ), + itemCount: model.admissionsMedicalReportList.length), + ], + ) + : getNoDataWidget(context), + ) + ], ), ), - ], - ), - ), - body: Column( - children: [ - if(model.user!=null) - Expanded( - child: TabBarView( - physics: BouncingScrollPhysics(), - controller: _tabController, - children: [ - ReportListWidget( - reportList: model.reportsOrderRequestList, - emailAddress: model.user.emailAddress - ), - ReportListWidget( - reportList: model.reportsOrderReadyList, - emailAddress: model.user.emailAddress - ), - ReportListWidget( - reportList: model.reportsOrderCompletedList, - emailAddress: model.user.emailAddress - ), - ReportListWidget( - reportList: model.reportsOrderCanceledList, - emailAddress: model.user.emailAddress - ), - ], - ), - ), - SizedBox( - height: 110, + if (projectViewModel!.havePrivilege(21) + // && _tabController_new.index == 0 ) + if (_tabController_new.index == 0) + Padding( + padding: EdgeInsets.only(top: 16, bottom: 16, right: 21, left: 21), + child: DefaultButton( + TranslationBase.of(context).requestMedicalReport.toLowerCase().capitalizeFirstofEach, + () => Navigator.push( + context, + FadePage( + page: MedicalReports(), + ), + ).then((value) { + model.getReports(projectViewModel!.isArabic ? 1 : 2); + }), + ), + ) ], ), - bottomSheet: projectViewModel.havePrivilege(21) ?Container( - width: double.infinity, - height: 90, - margin: EdgeInsets.all(8.0), - child: Button( - label: TranslationBase.of(context).requestMedicalReport, - backgroundColor: Colors.grey[800], - onTap: () => Navigator.push( - context, - FadePage( - page: MedicalReports(), - ), - ), - ), - ):null, ), ), ); } + + Widget myRadioButton(String _label, int _value) { + return InkWell( + onTap: () { + setState(() { + _currentPage = _value; + }); + }, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox( + width: 22, + height: 22, + child: Radio( + value: _value, + activeColor: _value == _currentPage ? Color(0xffD02127) : Color(0xffE8E8E8), + groupValue: _currentPage, + onChanged: (index) { + setState(() { + _currentPage = index!; + }); + }, + ), + ), + SizedBox(width: 10), + Text( + _label, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + color: Color(0xff575757), + letterSpacing: -0.56, + ), + ), + ], + ), + ); + } } diff --git a/lib/pages/medical/reports/report_list_widget.dart b/lib/pages/medical/reports/report_list_widget.dart index 72d0422b..5846b31f 100644 --- a/lib/pages/medical/reports/report_list_widget.dart +++ b/lib/pages/medical/reports/report_list_widget.dart @@ -1,105 +1,202 @@ +import 'dart:convert'; +import 'dart:io'; +import 'dart:typed_data'; + import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/core/model/reports/Reports.dart'; import 'package:diplomaticquarterapp/core/service/medical/reports_service.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/locator.dart'; +import 'package:diplomaticquarterapp/main.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.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/widgets/avatar/large_avatar.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/confirm_send_email_dialog.dart'; +import 'package:diplomaticquarterapp/widgets/my_rich_text.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_rating_bar/flutter_rating_bar.dart'; +import 'package:open_filex/open_filex.dart'; +import 'package:path_provider/path_provider.dart'; +import 'package:provider/provider.dart'; +import 'package:share_plus/share_plus.dart'; class ReportListWidget extends StatelessWidget { final List reportList; - final String emailAddress; + final String? emailAddress; + + ReportListWidget({required this.reportList, this.emailAddress}); - ReportListWidget({@required this.reportList, this.emailAddress}); + late ProjectViewModel projectViewModel; @override Widget build(BuildContext context) { - return Container( - child: ListView.builder( - itemBuilder: (context, index) => Padding( - padding: const EdgeInsets.all(8.0), - child: Container( - width: double.infinity, - margin: EdgeInsets.only(left: 8, right: 8, top: 3), - decoration: BoxDecoration( - color: Colors.white, - border: Border.all(color: Colors.white, width: 2), - shape: BoxShape.rectangle, - borderRadius: BorderRadius.all( - Radius.circular(8.0), - )), - child: Row( - children: [ - Expanded( - flex: 1, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: LargeAvatar( - name: reportList[index].doctorName, - url: reportList[index].doctorImageURL, + projectViewModel = Provider.of(context); + return reportList.length > 0 + ? ListView.separated( + physics: BouncingScrollPhysics(), + padding: EdgeInsets.only(bottom: 14, top: 14, left: 21, right: 21), + separatorBuilder: (context, index) => SizedBox(height: 14), + itemBuilder: (context, index) { + Reports report = reportList[index]; + return Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.all( + Radius.circular(10.0), ), - ), - ), - Expanded( - flex: 4, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Column( + boxShadow: [ + BoxShadow( + color: Color(0xff000000).withOpacity(.05), + //spreadRadius: 5, + blurRadius: 27, + offset: Offset(0, -3), + ), + ], + color: Colors.white), + child: Padding( + padding: const EdgeInsets.only(left: 12, right: 12, top: 12, bottom: 12), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (report.doctorName != null) + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 12, + children: [ + Text( + report.doctorName, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.64, height: 25 / 16), + ), + Column( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text(DateUtil.getDayMonthYearDateFormatted(report.requestDate!), + style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.48, height: 18 / 12)), + Text(DateUtil.formatDateToTimeLang(report.requestDate!, projectViewModel.isArabic), + style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.48, height: 18 / 12)), + ], ), - Texts(reportList[index].projectName), - Texts(reportList[index].clinicDescription), - Texts(TranslationBase.of(context).invoiceNo + - ': ${reportList[index].invoiceNo}'), - SizedBox(height: 12), ], ), - reportList[index].status == 2 - ? Container( - margin: - EdgeInsets.only(left: 15.0, right: 15.0), - child: InkWell( - onTap: () { - showConfirmMessage(reportList[index]); - // sendReportEmail(reportList[index]); - }, - child: Icon( - Icons.email, - color: Theme.of(context).primaryColor, - size: 35.0, - ), + if (report.doctorName != null) SizedBox(height: 6), + Row( + mainAxisSize: MainAxisSize.min, + children: [ + LargeAvatar( + name: report.doctorName, + url: report.doctorImageURL, + width: 48, + height: 48, + ), + SizedBox(width: 11), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + if (report.projectName != null) MyRichText(TranslationBase.of(context).hospital + ":", report.projectName!, projectViewModel.isArabic), + if (report.clinicDescription != null) MyRichText(TranslationBase.of(context).clinic + ":", report.clinicDescription!, projectViewModel.isArabic), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + mainAxisSize: MainAxisSize.max, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + RatingBar( + initialRating: report.actualDoctorRate == null ? 0.0 : report.actualDoctorRate!.toDouble(), + itemSize: 16, + ratingWidget: RatingWidget( + full: Icon( + Icons.star, + color: CustomColors.accentColor, + ), + half: Icon( + Icons.star_half, + color: CustomColors.accentColor, + ), + empty: Icon( + Icons.star_border, + color: CustomColors.accentColor, + ), + ), + onRatingUpdate: (double value) {}, + unratedColor: Colors.grey[500], + updateOnDrag: false, + tapOnlyMode: false, + ), + if (reportList[index].status == 2) + Row( + children: [ + InkWell( + onTap: () { + getMedicalReportPDF(report, false); + }, + child: Padding( + padding: const EdgeInsets.only(right: 11.0, left: 11.0), + child: Text(TranslationBase.of(context).download, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + fontStyle: FontStyle.italic, + color: CustomColors.accentColor, + letterSpacing: -0.48, + height: 18 / 12, + decoration: TextDecoration.underline)), + ), + ), + InkWell( + onTap: () { + getMedicalReportPDF(report, true); + }, + child: Padding( + padding: const EdgeInsets.only(right: 11.0, left: 11.0), + child: Text(TranslationBase.of(context).share, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + fontStyle: FontStyle.italic, + color: CustomColors.accentColor, + letterSpacing: -0.48, + height: 18 / 12, + decoration: TextDecoration.underline)), + ), + ), + // IconButton( + // icon: Icon(Icons.email), + // color: Color(0xff28323A), + // constraints: BoxConstraints(), + // padding: EdgeInsets.zero, + // onPressed: () { + // showConfirmMessage(reportList[index]); + // }) + ], + ), + ], ), - ) - : Container(), - ], - ), + ], + ), + ), + ], + ), + ], ), - ) - ], - ), - ), - ), - itemCount: reportList.length, - ), - ); + ), + ); + }, + itemCount: reportList.length, + ) + : getNoDataWidget(context); } void showConfirmMessage(Reports report) { showDialog( context: AppGlobal.context, - child: ConfirmSendEmailDialog( + builder: (cxt) => ConfirmSendEmailDialog( email: emailAddress, onTapSendEmail: () { sendReportEmail(report); @@ -108,26 +205,68 @@ class ReportListWidget extends StatelessWidget { ); } + void getMedicalReportPDF(Reports report, bool isShare) { + GifLoaderDialogUtils.showMyDialog(AppGlobal.context); + ReportsService _reportsService = locator(); + _reportsService + .getMedicalReportPDF( + report.projectName!, + report.clinicDescription!, + report.doctorName, + DateUtil.convertDateToString(report.requestDate!), + (Utils.isVidaPlusProject(projectViewModel, report.projectID!) ? report.invoiceNo_VP.toString() : report.invoiceNo.toString()), + report.projectID!, + DateUtil.convertDateToString(report.requestDate!), + report.setupId!) + .then((value) async { + GifLoaderDialogUtils.hideDialog(AppGlobal.context); + if (value["MedicalReportBase64"] != "" && value["MedicalReportBase64"] != null) { + String path = await _createFileFromString(value["MedicalReportBase64"], "pdf"); + if (isShare) { + Share.shareXFiles([XFile(path)], text: "Medical Report"); + } else { + try { + OpenFilex.open(path); + } catch (ex) { + AppToast.showErrorToast(message: "Cannot open file."); + } + } + } else { + AppToast.showErrorToast(message: "Cannot open file."); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(AppGlobal.context); + print(err); + }); + } + sendReportEmail(Reports report) { GifLoaderDialogUtils.showMyDialog(AppGlobal.context); ReportsService _reportsService = locator(); _reportsService .sendEmailForMedicalReport( - report.projectName, - report.clinicDescription, + report.projectName!, + report.clinicDescription!, report.doctorName, - DateUtil.convertDateToString(report.requestDate), - report.invoiceNo.toString(), - report.projectID, - DateUtil.convertDateToString(report.requestDate), - report.setupId) + DateUtil.convertDateToString(report.requestDate!), + Utils.isVidaPlusProject(projectViewModel, report.projectID!) ? report.invoiceNo_VP.toString() : report.invoiceNo.toString(), + report.projectID!, + DateUtil.convertDateToString(report.requestDate!), + report.setupId!) .then((value) { GifLoaderDialogUtils.hideDialog(AppGlobal.context); - AppToast.showSuccessToast( - message: TranslationBase.of(AppGlobal.context).emailSentSuccessfully); + AppToast.showSuccessToast(message: TranslationBase.of(AppGlobal.context).emailSentSuccessfully); }).catchError((err) { GifLoaderDialogUtils.hideDialog(AppGlobal.context); print(err); }); } + + Future _createFileFromString(String encodedStr, String ext) async { + Uint8List bytes = base64.decode(encodedStr); + String dir = (await getApplicationDocumentsDirectory()).path; + File file = File("$dir/" + DateTime.now().millisecondsSinceEpoch.toString() + "." + ext); + await file.writeAsBytes(bytes); + return file.path; + } } diff --git a/lib/pages/medical/reports/reports_page.dart b/lib/pages/medical/reports/reports_page.dart index 11d5fc82..6e1f5081 100644 --- a/lib/pages/medical/reports/reports_page.dart +++ b/lib/pages/medical/reports/reports_page.dart @@ -2,29 +2,35 @@ import 'package:diplomaticquarterapp/core/viewModels/medical/reports_view_model. import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/feedback/appointment_history.dart'; +import 'package:diplomaticquarterapp/theme/colors.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/avatar/large_avatar.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; -import 'package:diplomaticquarterapp/widgets/others/StarRating.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/ConfirmWithMessageDialog.dart'; +import 'package:diplomaticquarterapp/widgets/my_rich_text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_rating_bar/flutter_rating_bar.dart'; import 'package:provider/provider.dart'; class MedicalReports extends StatelessWidget { @override Widget build(BuildContext context) { - void confirmBox( - AppointmentHistory model, ReportsViewModel reportsViewModel) { + void confirmBox(AppointmentHistory model, ReportsViewModel reportsViewModel) { showDialog( context: context, - child: ConfirmDialog( - appointmentHistory: model, - onOkSelected: (model) => reportsViewModel.insertRequestForMedicalReport(model,TranslationBase.of(context).successSendReport), + builder: (cxt) => ConfirmWithMessageDialog( + message: TranslationBase.of(context).confirmMsgReport, + onTap: () => reportsViewModel.insertRequestForMedicalReport(model, TranslationBase.of(context).successSendReport), ), - ); + ).then((value) { + Navigator.pop(context); + }); + return; } + ProjectViewModel projectViewModel = Provider.of(context); return BaseView( onModelReady: (model) => model.getPatentAppointmentHistory(), @@ -32,173 +38,115 @@ class MedicalReports extends StatelessWidget { baseViewModel: model, isShowAppBar: true, appBarTitle: TranslationBase.of(context).medReport, - body: ListView.builder( - itemCount: model.appointHistoryList.length, - itemBuilder: (context, index) => Padding( - padding: const EdgeInsets.all(8.0), - child: Container( - width: double.infinity, - margin: EdgeInsets.only(left: 8, right: 8, top: 3), - decoration: BoxDecoration( - color: Colors.white, - border: Border.all(color: Colors.white, width: 2), - shape: BoxShape.rectangle, - borderRadius: BorderRadius.all( - Radius.circular(8.0), - )), - child: Row( - children: [ - Container( - margin: EdgeInsets.only(left: 5, right: 5), - child: LargeAvatar( - width: 50, - height: 50, - name: model.appointHistoryList[index].doctorNameObj, - url: model.appointHistoryList[index].doctorImageURL, - ), - ), - Expanded( - flex: 4, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 12, - ), - Texts(model.appointHistoryList[index].projectName), - Texts(model.appointHistoryList[index].clinicName), - Texts(projectViewModel.isArabic? DateUtil.getMonthDayYearDateFormattedAr(model.appointHistoryList[index].appointmentDate):DateUtil.getMonthDayYearDateFormatted(model.appointHistoryList[index].appointmentDate)), - StarRating( - totalAverage: model - .appointHistoryList[index].actualDoctorRate - .toDouble(), - forceStars: true), - SizedBox( - height: 12, - ), - ], - ), - ), - ), - InkWell( - onTap: () => - confirmBox(model.appointHistoryList[index], model), + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: Color(0xffF7F7F7), + body: model.appointHistoryList.isEmpty + ? getNoDataWidget(context) + : ListView.separated( + physics: BouncingScrollPhysics(), + itemCount: model.appointHistoryList.length, + padding: EdgeInsets.all(21), + separatorBuilder: (context, index) => SizedBox(height: 14), + itemBuilder: (context, index) { + AppointmentHistory _appointmenHistory = model.appointHistoryList[index]; + return InkWell( + onTap: () => confirmBox(model.appointHistoryList[index], model), child: Container( - width: 120, - height: 50, decoration: BoxDecoration( - color: Colors.black54, - border: - Border.all(color: Colors.transparent, width: 2), - shape: BoxShape.rectangle, - borderRadius: BorderRadius.all( - Radius.circular(8.0), - ), - ), - child: Center( - child: Texts( - TranslationBase.of(context).requestReport, - fontSize: 12, - color: Colors.white, - ), - ), - ), - ), - SizedBox( - width: 12, - ), - ], - ), - ), - ), - ), - ), - ); - } -} - -class ConfirmDialog extends StatefulWidget { - final Function(AppointmentHistory) onOkSelected; - final AppointmentHistory appointmentHistory; - - ConfirmDialog({this.onOkSelected, this.appointmentHistory}); - - @override - _ConfirmDialogState createState() => _ConfirmDialogState(); -} - -class _ConfirmDialogState extends State { - @override - Widget build(BuildContext context) { - return SimpleDialog( - title: Texts(TranslationBase.of(context).confirm), - children: [ - Container( - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Texts(TranslationBase.of(context).confirmMsgReport), - 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: const EdgeInsets.all(8.0), - child: Container( - child: Center( - child: Texts( - TranslationBase.of(context).cancel, - color: Colors.red, - ), + borderRadius: BorderRadius.all( + Radius.circular(10.0), ), - ), - ), - ), - ), - Container( - width: 1, - height: 30, - color: Colors.grey[500], - ), - Expanded( - flex: 1, - child: InkWell( - onTap: () { - widget.onOkSelected(widget.appointmentHistory); - Navigator.pop(context); - }, + boxShadow: [ + BoxShadow( + color: Color(0xff000000).withOpacity(.05), + //spreadRadius: 5, + blurRadius: 27, + offset: Offset(0, -3), + ), + ], + color: Colors.white), child: Padding( - padding: const EdgeInsets.all(8.0), - child: Center( - child: Texts( - TranslationBase.of(context).ok, - fontWeight: FontWeight.w400, - ), + padding: const EdgeInsets.only(left: 12, right: 12, top: 12, bottom: 12), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + if ((_appointmenHistory.doctorName ?? _appointmenHistory.doctorNameObj) != null) + Text( + _appointmenHistory.doctorTitle.toString() + " " + (_appointmenHistory.doctorName ?? _appointmenHistory.doctorNameObj), + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.64, height: 25 / 16), + ), + Text( + DateUtil.getDayMonthYearDateFormatted(_appointmenHistory.appointmentDate!), + style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.48, height: 18 / 12), + ), + ], + ), + if ((_appointmenHistory.doctorName ?? _appointmenHistory.doctorNameObj) != null) SizedBox(height: 6), + Row( + mainAxisSize: MainAxisSize.min, + children: [ + LargeAvatar( + name: _appointmenHistory.doctorName, + url: _appointmenHistory.doctorImageURL, + width: 48, + height: 48, + ), + SizedBox(width: 11), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + if (_appointmenHistory.projectName != null) MyRichText(TranslationBase.of(context).clinic + ":", _appointmenHistory.projectName!, projectViewModel.isArabic), + if (_appointmenHistory.clinicName != null) MyRichText(TranslationBase.of(context).hospital + ":", _appointmenHistory.clinicName!, projectViewModel.isArabic), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + mainAxisSize: MainAxisSize.max, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + RatingBar( + initialRating: _appointmenHistory.actualDoctorRate!.toDouble(), + itemSize: 16, + ratingWidget: RatingWidget( + full: Icon( + Icons.star, + color: CustomColors.accentColor, + ), + half: Icon( + Icons.star_half, + color: CustomColors.accentColor, + ), + empty: Icon( + Icons.star_border, + color: CustomColors.accentColor, + ), + ), + onRatingUpdate: (double value) {}, + unratedColor: Colors.grey[500], + updateOnDrag: false, + tapOnlyMode: false, + ), + Icon(Icons.email, color: Color(0xff2B353E)) + ], + ), + ], + ), + ), + ], + ), + ], ), ), ), - ), - ], - ) - ], - ), - ) - ], + ); + }, + ), + ), ); } } diff --git a/lib/pages/medical/reports/user_agreement_page.dart b/lib/pages/medical/reports/user_agreement_page.dart index 9bb886e3..d48ff16d 100644 --- a/lib/pages/medical/reports/user_agreement_page.dart +++ b/lib/pages/medical/reports/user_agreement_page.dart @@ -13,11 +13,13 @@ class UserAgreementContent extends StatelessWidget { builder: (_, model, w) => AppScaffold( isShowAppBar: true, baseViewModel: model, + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: Color(0xffF7F7F7), appBarTitle: TranslationBase.of(context).userAgreement, body: SingleChildScrollView( - child: Html( - data: model.userAgreementContent, - ), + physics: BouncingScrollPhysics(), + child: Html(data: model.userAgreementContent), ), ), ); diff --git a/lib/pages/medical/sickleave_workplace_update_page.dart b/lib/pages/medical/sickleave_workplace_update_page.dart new file mode 100644 index 00000000..ec7991cb --- /dev/null +++ b/lib/pages/medical/sickleave_workplace_update_page.dart @@ -0,0 +1,255 @@ +import 'package:diplomaticquarterapp/core/service/medical/labs_service.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:provider/provider.dart'; + +class WorkplaceUpdatePage extends StatefulWidget { + final int requestNumber; + final String setupID; + final int projectID; + + WorkplaceUpdatePage({required this.requestNumber, required this.setupID, required this.projectID}); + + @override + _WorkplaceUpdatePageState createState() => _WorkplaceUpdatePageState(); +} + +class _WorkplaceUpdatePageState extends State { + TextEditingController workplaceName = new TextEditingController(); + + TextEditingController workplaceNameAr = new TextEditingController(); + TextEditingController occupationNameEn = new TextEditingController(); + TextEditingController occupationNameAr = new TextEditingController(); + bool? _isButtonDisabled; + ProjectViewModel? projectViewModel; + + @override + void initState() { + super.initState(); + } + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + return AppScaffold( + appBarTitle: TranslationBase.of(context).sickLeaves, + isShowAppBar: true, + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: CustomColors.appBackgroudGrey2Color, + body: Container( + child: Column( + children: [ + Expanded( + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + mHeight(12), + SvgPicture.asset("assets/images/new/workplace-icon.svg", width: 40.0, fit: BoxFit.fill), + mHeight(12), + Text( + TranslationBase.of(context).enterWorkplaceName, + textAlign: TextAlign.start, + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.bold, + color: Colors.black, + letterSpacing: -0.64, + ), + ), + mHeight(8), + // inputWidget(TranslationBase.of(context).workplaceName, "", workplaceName), + inputWidget(TranslationBase.of(context).workplaceName, "", workplaceName, FilteringTextInputFormatter.allow(RegExp("[a-zA-Z ]"))), + mHeight(8), + inputWidget(TranslationBase.of(context).workplaceNameAr, "", workplaceNameAr, FilteringTextInputFormatter.allow(RegExp("[ء-ي ]"))), + mHeight(8), + inputWidget(TranslationBase.of(context).occupationNameEn, "", occupationNameEn, FilteringTextInputFormatter.allow(RegExp("[a-zA-Z ]"))), + mHeight(8), + inputWidget(TranslationBase.of(context).occupationNameAr, "", occupationNameAr, FilteringTextInputFormatter.allow(RegExp("[ء-ي ]"))), + ], + ), + ), + ), + ), + Card( + margin: EdgeInsets.zero, + elevation: 0, + child: Container( + padding: EdgeInsets.all(12), + child: FractionallySizedBox( + widthFactor: 1, + child: MaterialButton( + height: 50, + elevation: 0, + color: CustomColors.accentColor, + disabledColor: Colors.grey.withOpacity(0.25), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), + child: Text( + TranslationBase.of(context).submit, + style: TextStyle( + fontSize: 16.0, + letterSpacing: -0.64, + color: Colors.white, + ), + ), + onPressed: () { + // if (_isButtonDisabled == false) + if (workplaceNameAr.text.isNotEmpty && occupationNameAr.text.isNotEmpty) + // AppToast.showSuccessToast(message: "API Called"); + updateWorkplaceNameDialog(); + else + AppToast.showErrorToast(message: TranslationBase.of(context).enterDetailBelow); + }, + ), + ), + ), + ), + ], + ), + ), + ); + } + + Widget inputWidget(String _labelText, String _hintText, TextEditingController _controller, TextInputFormatter inputFormatter, {String? prefix, bool isEnable = true, bool hasSelection = false}) { + // Widget inputWidget(String _labelText, String _hintText, TextEditingController _controller, {String? prefix, bool isEnable = true, bool hasSelection = false}) { + return Container( + padding: EdgeInsets.only(left: 16, right: 16, bottom: 15, top: 15), + alignment: Alignment.center, + 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: TextInputType.name, + controller: _controller, + inputFormatters: [ + // projectViewModel!.isArabic ? FilteringTextInputFormatter.allow(RegExp("[ء-ي ]")) : FilteringTextInputFormatter.allow(RegExp("[a-zA-Z ]")), + inputFormatter + ], + onChanged: (value) => {_onPassportTextChanged(value)}, + 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, + ), + 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), + ], + ), + ), + ); + } + + _onPassportTextChanged(content) { + if (content.length >= 1) { + setState(() { + _isButtonDisabled = false; + }); + } else { + setState(() { + _isButtonDisabled = true; + }); + } + } + + updateWorkplaceNameDialog() { + var messageEn = "The workplace name you entered is: " + workplaceNameAr.text + ". Please confirm!"; + var messageAr = "اسم مكان العمل الذي أدخلته هو: " + workplaceNameAr.text + ". يرجى تأكيد!"; + ConfirmDialog dialog = new ConfirmDialog( + context: context, + confirmMessage: projectViewModel!.isArabic ? messageAr : messageEn, + okText: TranslationBase.of(context).confirm, + cancelText: TranslationBase.of(context).cancel_nocaps, + okFunction: () { + Navigator.of(context).pop(); + updateWorkplaceName(); + }, + cancelFunction: () => {}); + dialog.showAlertDialog(context); + } + + void updateWorkplaceName() { + LabsService service = new LabsService(); + GifLoaderDialogUtils.showMyDialog(context); + + service.updateWorkplaceName(workplaceName.text, workplaceNameAr.text, occupationNameEn.text, occupationNameAr.text, widget.requestNumber, widget.setupID, widget.projectID).then((res) { + // service + // .updateWorkplaceName(projectViewModel!.isArabic ? "-" : workplaceName.text, projectViewModel!.isArabic ? workplaceName.text : "-", widget.requestNumber, widget.setupID, widget.projectID) + // .then((res) { + GifLoaderDialogUtils.hideDialog(context); + Navigator.of(context).pop(true); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } +} diff --git a/lib/pages/medical/smart_watch_health_data/distance/distanceTracker.dart b/lib/pages/medical/smart_watch_health_data/distance/distanceTracker.dart new file mode 100644 index 00000000..432707ce --- /dev/null +++ b/lib/pages/medical/smart_watch_health_data/distance/distanceTracker.dart @@ -0,0 +1,577 @@ +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 { + late TabController _tabController; + + late 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 monthlyStepsList = []; + List yearlyStepsList = []; + + 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).monthlyTab), + 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(() { + if (avgWeeklyStepsValue != 0) { + 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(() { + if (avgMonthlyStepsValue != 0) { + 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(() { + if (avgYearlyStepsValue != 0) { + 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 ?? DateUtil.convertDateToString(DateTime.now())), + 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, + isWeeklyOrMonthly: true, + ), + ), + 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, + isWeeklyOrMonthly: true, + ), + ), + 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 ?? DateUtil.convertDateToString(DateTime.now())), + )} ', + 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 ea8746e9..664178a4 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,7 +1,12 @@ -import 'package:diplomaticquarterapp/pages/medical/smart_watch_health_data/stepsTracker.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; +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/data_display/medical/medical_profile_item.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'; @@ -11,8 +16,7 @@ class HealthDataList extends StatefulWidget { } class _HealthDataListState extends State { - - // List dataTypes = List(); + // List dataTypes =[]; @override void initState() { @@ -27,192 +31,97 @@ class _HealthDataListState extends State { @override Widget build(BuildContext context) { + List myMedicalList = myOptionsList(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)), - ), - ], - ), - ), - 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)), - ), - ], - ), - Divider( - color: Colors.grey[500], - ), - ], + appBarTitle: TranslationBase.of(context).smartWatches, + isShowAppBar: true, + showNewAppBar: true, + backgroundColor: Color(0xffF7F7F7), + showNewAppBarTitle: true, + body: Column( + children: [ + Expanded( + child: GridView.builder( + physics: BouncingScrollPhysics(), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, childAspectRatio: 2 / 2, crossAxisSpacing: 12, mainAxisSpacing: 12), + padding: EdgeInsets.all(21), + itemCount: myMedicalList.length, + itemBuilder: (BuildContext context, int index) { + return myMedicalList[index]; + }, ), ), - ), - bottomSheet: Container( - width: double.infinity, - height: MediaQuery - .of(context) - .size - .height * 0.1, - color: Colors.grey[100], - child: Column( - children: [ - Divider( - color: Colors.transparent, - ), - 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), - ), - child: Container( - padding: EdgeInsets.only(top: 10.0), - child: Text( - 'Sync Health Data' , textAlign: TextAlign.center,style: TextStyle( - color: Colors.white , fontSize: 18.0 - ), - ), - ),),), - ], - ), - )); + syncHealthDataButton(), + ], + ), + ); } + List myOptionsList(BuildContext context) { + List medical = []; + + 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: "", + 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: "", + isPngImage: true, + ), + )); - // 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 + medical.add(InkWell( + onTap: () => Navigator.push( + context, + FadePage(page: DistanceTracker()), + ), + child: MedicalProfileItem( + title: TranslationBase.of(context).distance, + imagePath: 'assets/images/SmartWatches/distance.png', + subTitle: "", + isPngImage: true, + ), + )); + + return medical; + } + +// 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/heartrate/heartrateTracker.dart b/lib/pages/medical/smart_watch_health_data/heartrate/heartrateTracker.dart new file mode 100644 index 00000000..97c61ee0 --- /dev/null +++ b/lib/pages/medical/smart_watch_health_data/heartrate/heartrateTracker.dart @@ -0,0 +1,578 @@ +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 { + late TabController _tabController; + + late 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 monthlyHearRateList = []; + List yearlyHearRateList = []; + + 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).monthlyTab), + 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 + ? avgWeeklyHearRateValue != 0 + ? getWeeklyHeartRateDetails() + : getNoDataWidget(context) + : Container(), + isMonthlyDataLoaded ? getMonthlyHeartRateDetails() : Container(), + isYearlyDataLoaded ? getYearlyHeartRateDetails() : 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) { + if (element['ValueAvg'] != null) { + weekyHearRateList.add(new WeeklyHeartRateResModel.fromJson(element)); + num value = element['ValueAvg']; + avgWeeklyHearRateValue += value.toInt(); + weeklyDataLength++; + } + }); + if (weekyHearRateList.isNotEmpty) generateWeekData(); + setState(() { + if (avgWeeklyHearRateValue != 0) { + 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(() { + if (avgMonthlyHearRateValue != 0) { + 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(3, 3, context).then((res) { + GifLoaderDialogUtils.hideDialog(context); + yearlyHearRateList.clear(); + res['Med_GetYearTransactionsStsList'].forEach((element) { + yearlyHearRateList.add(new YearlyHeartRateResModel.fromJson(element)); + if (element['ValueAvg'] != null) { + num value = element['ValueAvg']; + avgYearlyHearRateValue += value; + yearlyDataLength++; + } + }); + generateYearData(); + setState(() { + if (avgYearlyHearRateValue != 0) { + 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, + isWeeklyOrMonthly: true, + ), + ), + 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, + isWeeklyOrMonthly: true, + ), + ), + 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).avgHeartRate, style: TextStyle(fontSize: 18.0)), + ), + Container( + margin: EdgeInsets.only(bottom: 10.0), + child: Text(yearlyStatsAvgValue.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: [ + 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/smart_watch_instructions.dart b/lib/pages/medical/smart_watch_health_data/smart_watch_instructions.dart index 977b99df..8ca443be 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 @@ -1,10 +1,17 @@ import 'dart:io'; -import 'package:carousel_slider/carousel_slider.dart'; +// import 'package:carousel_slider/carousel_slider.dart'; +import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; +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/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'; import 'package:flutter/material.dart'; import 'package:url_launcher/url_launcher.dart'; @@ -15,14 +22,16 @@ class SmartWatchInstructions extends StatefulWidget { } class _SmartWatchInstructionsState extends State { - CarouselController buttonCarouselController = CarouselController(); + // CarouselController buttonCarouselController = CarouselController(); bool hasAlreadySynced = false; + AuthenticatedUserObject authenticatedUserObject = locator(); + @override void initState() { WidgetsBinding.instance.addPostFrameCallback((timeStamp) { - getLastPatientRecord(context); + if (authenticatedUserObject.isLogin) getLastPatientRecord(context); }); super.initState(); } @@ -30,387 +39,241 @@ class _SmartWatchInstructionsState extends State { @override Widget build(BuildContext context) { return AppScaffold( - appBarTitle: "Sync Health Data", - isShowAppBar: true, - body: Container( - child: Platform.isIOS - ? _getAppleWatchInstructions() - : _getGoogleWatchInstructions(), - )); + appBarTitle: TranslationBase.of(context).smartWatches, + isShowAppBar: true, + isShowDecPage: true, + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: Color(0xffF7F7F7), + 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: Column( + children: [ + Expanded( + child: Container( + child: Platform.isIOS ? _getAppleWatchInstructions() : _getGoogleWatchInstructions(), + ), + ), + DefaultButton( + TranslationBase.of(context).continues, + () { + _openHealthDataList(); + }, + color: Color(0xff359846), + ).insideContainer + ], + ), + ); } _getAppleWatchInstructions() { return SingleChildScrollView( + padding: EdgeInsets.all(21), + physics: BouncingScrollPhysics(), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ + Text( + TranslationBase.of(context).supportedWatches, + style: TextStyle( + fontSize: 20.0, + fontWeight: FontWeight.w600, + letterSpacing: -1.2, + color: Color(0xff2E303A), + ), + ), + 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)), + ), + ) + ], + ), + ), + ), + 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: 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), + 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)), ), - child: i == 1 - ? Column( - children: [ - Container( - margin: EdgeInsets.only(top: 10.0), - 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), - 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( - "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)), - ), - 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)), - ), - 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, - disabledTextColor: Colors.white, - disabledColor: new Color(0xFFbcc2c4), - onPressed: () { - buttonCarouselController.nextPage(); - }, - child: Text("CONTINUE", - style: TextStyle(fontSize: 18.0)), - ), - ), - ), - ], - ) - : Column( - children: [ - Container( - margin: EdgeInsets.only(top: 10.0), - child: Text("Watch Instructions:", - style: TextStyle( - fontSize: 22.0, - fontWeight: FontWeight.bold, - fontFamily: "WorkSans")), - ), - 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)), - ), - 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)), - ), - 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)), - ), - 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)), - ), - 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)), - ), - Container( - margin: EdgeInsets.fromLTRB( - 15.0, 110.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, - 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, - disabledTextColor: Colors.white, - disabledColor: new Color(0xFFbcc2c4), - onPressed: () { - _openHealthDataList(); - }, - child: Text("ALREADY SYNCED", - style: TextStyle(fontSize: 18.0)), - ), - ), - ): Container(), - ], - ), - )); - }, - ); - }).toList(), + ) + ], + ), + ), + ), + 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)), + ), + ) + ], + ), + ), + ), + ], + ), + ), + SizedBox(height: 12), + Text( + TranslationBase.of(context).syncInstructionsIntro1, + style: TextStyle( + fontSize: 14.0, + letterSpacing: -0.56, + fontWeight: FontWeight.w600, + color: Color(0xff575757), + ), + ), + SizedBox(height: 12), + Text( + TranslationBase.of(context).syncInstructionsIntro2, + style: TextStyle( + fontSize: 14.0, + letterSpacing: -0.56, + fontWeight: FontWeight.w600, + color: Color(0xff575757), ), - ) + ), + SizedBox(height: 12), + InkWell( + onTap: () { + showInstructionsDialog(); + }, + child: Text(TranslationBase.of(context).watchInstructions, + style: TextStyle(color: CustomColors.accentColor, fontWeight: FontWeight.w600, letterSpacing: -0.64, decoration: TextDecoration.underline)), + ), ], ), ); @@ -418,399 +281,341 @@ class _SmartWatchInstructionsState extends State { _getGoogleWatchInstructions() { return SingleChildScrollView( + padding: EdgeInsets.all(21), + physics: BouncingScrollPhysics(), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ + Text( + TranslationBase.of(context).supportedWatches, + style: TextStyle( + fontSize: 20.0, + fontWeight: FontWeight.w600, + letterSpacing: -1.2, + color: Color(0xff2E303A), + ), + ), + 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: CarouselSlider( - carouselController: buttonCarouselController, - options: CarouselOptions( - // enableInfiniteScroll: true, - viewportFraction: 0.99, - height: MediaQuery.of(context).size.height*1.02 ), - 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: 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)), + ) + ], + ), + ), + ), + ], + ), + ), + SizedBox(height: 12), + InkWell( + onTap: () { + launch("https://wearos.google.com/#find-your-watch"); + }, + child: Text( + TranslationBase.of(context).moreSupportedWatches, + style: TextStyle(fontSize: 14.0, color: Colors.blue, fontWeight: FontWeight.w600, decoration: TextDecoration.underline, letterSpacing: -0.56), + ), + ), + SizedBox(height: 12), + Text( + TranslationBase.of(context).syncInstructionsIntro1, + style: TextStyle( + fontSize: 14.0, + letterSpacing: -0.56, + fontWeight: FontWeight.w600, + color: Color(0xff575757), + ), + ), + SizedBox(height: 12), + Text( + TranslationBase.of(context).syncInstructionsIntro2, + style: TextStyle( + fontSize: 14.0, + letterSpacing: -0.56, + fontWeight: FontWeight.w600, + color: Color(0xff575757), + ), + ), + SizedBox(height: 12), + InkWell( + onTap: () { + showInstructionsDialog(); + }, + 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, + padding: EdgeInsets.all(21), + color: Colors.white, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + TranslationBase.of(context).smartWatches, + style: TextStyle(fontSize: 18.0, color: Color(0xff2E303A), fontWeight: FontWeight.w600, letterSpacing: -1.2), + ), + IconButton( + icon: Icon( + Icons.close, + color: Color(0xff2E303A), + ), + onPressed: () { + Navigator.pop(context); + }, + ), + ], + ), + Text( + TranslationBase.of(context).syncInstructionsIntro3, + style: TextStyle( + fontSize: 14.0, + letterSpacing: -0.56, + color: Color(0xff575757), + ), ), - child: i == 1 + SizedBox(height: 12), + Platform.isIOS ? 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")), - ), - 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)), - ) - ], - ), - ), - ), - ], + Text( + TranslationBase.of(context).iosInstructions1, + style: TextStyle( + fontSize: 14.0, + letterSpacing: -0.56, + color: Color(0xff575757), ), ), - InkWell( - onTap: () { - 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)), + SizedBox(height: 12), + Text( + TranslationBase.of(context).iosInstructions2, + style: TextStyle( + fontSize: 14.0, + letterSpacing: -0.56, + color: Color(0xff575757), ), ), - 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)), - ), - 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)), - ), - 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, - disabledTextColor: Colors.white, - disabledColor: new Color(0xFFbcc2c4), - onPressed: () { - buttonCarouselController.nextPage(); - }, - child: Text("CONTINUE", - style: TextStyle(fontSize: 18.0)), - ), + SizedBox(height: 12), + Text( + TranslationBase.of(context).iosInstructions3, + style: TextStyle( + fontSize: 14.0, + letterSpacing: -0.56, + color: Color(0xff575757), ), ), ], ) : 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")), - ), - 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)), - ), - 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)), - ), - 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)), - ), - 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)), - ), - 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)), + Text( + TranslationBase.of(context).androidInstructions1, + style: TextStyle( + fontSize: 14.0, + letterSpacing: -0.56, + color: Color(0xff575757), + ), ), - 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)), + SizedBox(height: 12), + Text( + TranslationBase.of(context).androidInstructions2, + style: TextStyle( + fontSize: 14.0, + letterSpacing: -0.56, + color: Color(0xff575757), + ), ), - 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, - disabledTextColor: Colors.white, - disabledColor: new Color(0xFFbcc2c4), - onPressed: () { - buttonCarouselController.nextPage(); - }, - child: Text("SYNC HEALTH DATA", - style: TextStyle(fontSize: 18.0)), - ), + SizedBox(height: 12), + Text( + TranslationBase.of(context).androidInstructions3, + style: TextStyle( + fontSize: 14.0, + letterSpacing: -0.56, + color: Color(0xff575757), ), ), - 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, - disabledTextColor: Colors.white, - disabledColor: new Color(0xFFbcc2c4), - onPressed: () { - _openHealthDataList(); - }, - child: Text("ALREADY SYNCED", - style: TextStyle(fontSize: 18.0)), - ), + SizedBox(height: 12), + Text( + TranslationBase.of(context).androidInstructions4, + style: TextStyle( + fontSize: 14.0, + letterSpacing: -0.56, + color: Color(0xff575757), ), - ) : Container(), + ), ], ), - )); - }, - ); - }).toList(), + ], + ), + ), + ], + ), + ), ), - ) - ], - ), - ); + ); + }, + transitionDuration: Duration(milliseconds: 500), + barrierDismissible: true, + barrierLabel: '', + context: context, + pageBuilder: (context, animation1, animation2) { + return SizedBox(); + //Chanbged By Aamir + }); } getLastPatientRecord(BuildContext context) { @@ -835,6 +640,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/steps/stepsTracker.dart b/lib/pages/medical/smart_watch_health_data/steps/stepsTracker.dart new file mode 100644 index 00000000..a9a19945 --- /dev/null +++ b/lib/pages/medical/smart_watch_health_data/steps/stepsTracker.dart @@ -0,0 +1,572 @@ +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 { + late TabController _tabController; + + late ProjectViewModel projectViewModel; + + int weeklyStatsAvgValue = 0; + int monthlyStatsAvgValue = 0; + int yearlyStatsAvgValue = 0; + + int avgWeeklyStepsValue = 0; + int avgMonthlyStepsValue = 0; + int avgYearlyStepsValue = 0; + + int weeklyDataLength = 0; + int monthlyDataLength = 0; + int yearlyDataLength = 0; + + List weekyStepsList =[]; + List monthlyStepsList =[]; + List yearlyStepsList =[]; + + 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((_) { + 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).monthlyTab), + Tab(text: TranslationBase.of(context).yearly), + ], + onTap: (value) { + if (value == 0) { + getWeeklyStepsData(); + } else if (value == 1) { + getMonthlyStepsData(); + } 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); + 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(() { + if (avgWeeklyStepsValue != 0) { + weeklyStatsAvgValue = avgWeeklyStepsValue ~/ weeklyDataLength; + } + isWeeklyDataLoaded = true; + }); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } + + 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(() { + if (avgMonthlyStepsValue != 0) { + monthlyStatsAvgValue = avgMonthlyStepsValue ~/ monthlyDataLength; + } + isMonthlyDataLoaded = true; + }); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } + + getYearlyStepsData() { + avgYearlyStepsValue = 0; + yearlyDataLength = 0; + DoctorsListService service = new DoctorsListService(); + GifLoaderDialogUtils.showMyDialog(context); + service.getPatientHealthDataStats(6, 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.toInt(); + yearlyDataLength++; + } + }); + generateYearData(); + setState(() { + if (avgYearlyStepsValue != 0) { + 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 ?? DateUtil.convertDateToString(DateTime.now())), + 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, + ), + ); + }, + ); + } + } + + generateYearData() { + if (yearlyStepsList.length > 0) { + yearlyTimeSeriesData.clear(); + yearlyStepsList.forEach( + (element) { + yearlyTimeSeriesData.add( + TimeSeriesSales2( + 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, + isWeeklyOrMonthly: true, + ), + ), + 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 SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + child: ShowChart( + title: "", + timeSeries: monthlyTimeSeriesData, + indexes: monthlyTimeSeriesData.length ~/ 5.5, + horizontalInterval: 8, + isWeeklyOrMonthly: true, + ), + ), + 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), + ), + ], + ), + ) + ], + ), + ), + ], + ), + ); + } + + 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 ?? DateUtil.convertDateToString(DateTime.now())), + )} ', + isCapitable: false, + mProjectViewModel: projectViewModel), + Utils.tableColumnValue(step.value.toString(), 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).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/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/pages/medical/smart_watch_health_data/syncHealthData.dart b/lib/pages/medical/smart_watch_health_data/syncHealthData.dart new file mode 100644 index 00000000..6d6fdf4f --- /dev/null +++ b/lib/pages/medical/smart_watch_health_data/syncHealthData.dart @@ -0,0 +1,210 @@ +import 'dart:io'; + +import 'package:collection/collection.dart'; +import 'package:diplomaticquarterapp/models/SmartWatch/HealthData.dart'; +import 'package:diplomaticquarterapp/services/permission/permission_service.dart'; +import 'package:diplomaticquarterapp/services/smartwatch_integration/SmartWatchIntegrationService.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:flutter/material.dart'; +import 'package:health/health.dart'; + +class syncHealthDataButton extends StatefulWidget { + syncHealthDataButton(); + + @override + _syncHealthDataButtonState createState() => _syncHealthDataButtonState(); +} + +class _syncHealthDataButtonState extends State { + List _healthDataList = []; + + List Med_InsertTransactionsInputsList = []; + List Med_InsertTransactionsInputsList2 = []; + + List sleepDataList = []; + + List healthDataList = []; + + int TransactionsListID = 1; + + int MedCategoryID = 0; + + // HealthFactory health = HealthFactory(); + List types = [HealthDataType.STEPS, HealthDataType.HEART_RATE, Platform.isAndroid ? HealthDataType.DISTANCE_DELTA : HealthDataType.DISTANCE_WALKING_RUNNING]; + + @override + void initState() { + super.initState(); + } + + @override + Widget build(BuildContext context) { + return DefaultButton(TranslationBase.of(context).syncHealthData, () => checkPermissions()).insideContainer; + } + + checkPermissions() async { + // if (Platform.isAndroid) { + // if (await PermissionService.isHealthDataPermissionEnabled()) { + // await health.requestAuthorization(types).then((value) { + // if (value) { + // readAll(); + // } + // }); + // } else { + // Utils.showPermissionConsentDialog(context, TranslationBase.of(context).physicalActivityPermission, () async { + // await health.requestAuthorization(types).then((value) { + // if (value) { + // readAll(); + // } + // }); + // }); + // } + // } else { + // await health.requestAuthorization(types).then((value) { + // if (value) { + // readAll(); + // } + // }); + // } + } + + void readAll() async { + TransactionsListID = 1; + var MedSubCategoryID = 0; + double value = 0.0; + + GifLoaderDialogUtils.showMyDialog(context); + Med_InsertTransactionsInputsList.clear(); + DateTime startDate = DateTime.now().subtract(new Duration(days: 30)); + + try { + // List healthData = await health.getHealthDataFromTypes(startDate, DateTime.now(), types); + // _healthDataList.addAll(healthData); + } catch (e) { + print("Caught exception in getHealthDataFromTypes: $e"); + } + + // _healthDataList = HealthFactory.removeDuplicates(_healthDataList); + + _healthDataList.forEach((x) { + if (x.type == HealthDataType.STEPS) { + Med_InsertTransactionsInputsList.add(healthData( + MedCategoryID: 6, + MedSubCategoryID: MedSubCategoryID, + MachineDate: DateUtil.convertDateToString(x.dateFrom), + Value: double.tryParse(x.value.toString()), + TransactionsListID: TransactionsListID++)); + } + if (x.type == HealthDataType.HEART_RATE) { + Med_InsertTransactionsInputsList.add(healthData( + MedCategoryID: 3, + MedSubCategoryID: MedSubCategoryID, + MachineDate: DateUtil.convertDateToString(x.dateFrom), + Value: double.tryParse(x.value.toString()), + TransactionsListID: TransactionsListID++)); + } + if (x.type == HealthDataType.DISTANCE_DELTA || x.type == HealthDataType.DISTANCE_WALKING_RUNNING) { + Med_InsertTransactionsInputsList.add(healthData( + MedCategoryID: 7, + MedSubCategoryID: MedSubCategoryID, + MachineDate: DateUtil.convertDateToString(x.dateFrom), + Value: double.tryParse(x.value.toString()), + TransactionsListID: TransactionsListID++)); + } + }); + + getAllHealthDataLists(); + } + + void getAllHealthDataLists() { + var totalSteps = 0.0; + var totalDistance = 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; + totalDistance += (element['Value'] * 0.001); + } else if (element['MedCategoryID'] == 3) { + MedCategoryID = 3; + counter++; + totalHeartRate += element['Value']; + } else if (element['MedCategoryID'] == 4) { + sleepDataList.add(new healthData( + MedCategoryID: 4, MedSubCategoryID: element['MedSubCategoryID'], MachineDate: DateUtil.convertDateToString(date), Value: element['Value'], TransactionsListID: TransactionsListID++)); + + Med_InsertTransactionsInputsList2.add(new healthData( + MedCategoryID: 4, MedSubCategoryID: element['MedSubCategoryID'], MachineDate: DateUtil.convertDateToString(date), Value: element['Value'], TransactionsListID: TransactionsListID++)); + } + }); + + 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.convertDateToStringLocation(date), Value: totalSteps, TransactionsListID: TransactionsListID++)); + Med_InsertTransactionsInputsList2.add( + new healthData(MedCategoryID: 7, MedSubCategoryID: 0, MachineDate: DateUtil.convertDateToStringLocation(date), Value: totalDistance, TransactionsListID: TransactionsListID++)); + Med_InsertTransactionsInputsList2.add( + new healthData(MedCategoryID: 3, MedSubCategoryID: 0, MachineDate: DateUtil.convertDateToStringLocation(date), Value: avgTotalHeartRate, TransactionsListID: TransactionsListID++)); + }); + + addInsertTransactionsInputsList(); + + GifLoaderDialogUtils.hideDialog(context); + } + + addInsertTransactionsInputsList() { + if (Med_InsertTransactionsInputsList2.isNotEmpty) { + GifLoaderDialogUtils.showMyDialog(context); + SmartWatchIntegrationService service = new SmartWatchIntegrationService(); + service.insertPatientHealthData(Med_InsertTransactionsInputsList2, context).then((res) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showSuccessToast(message: TranslationBase.of(context).syncSuccess); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } else { + return; + } + } +} diff --git a/lib/pages/medical/vital_sign/LineChartCurved.dart b/lib/pages/medical/vital_sign/LineChartCurved.dart index fe112767..e86f31bf 100644 --- a/lib/pages/medical/vital_sign/LineChartCurved.dart +++ b/lib/pages/medical/vital_sign/LineChartCurved.dart @@ -1,3 +1,4 @@ +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/widgets/charts/app_time_series_chart.dart'; import 'package:fl_chart/fl_chart.dart'; import 'package:flutter/material.dart'; @@ -7,15 +8,18 @@ import '../../../Constants.dart'; class LineChartCurved extends StatelessWidget { final String title; final List timeSeries; - final int indexes; + final int? indexes; + final double horizontalInterval; - LineChartCurved({this.title, this.timeSeries, this.indexes}); + LineChartCurved({required this.title, required this.timeSeries, this.indexes, this.horizontalInterval = 20.0}); - List xAxixs = List(); - List yAxixs = List(); + List xAxixs = []; + List yAxixs = []; double minY = 0; double maxY = 0; + double intialY = 0; + double lastY = 0; double minX = 0; double maxX = 0; @@ -25,9 +29,10 @@ class LineChartCurved extends StatelessWidget { Widget build(BuildContext context) { getXaxix(); getYaxix(); + getInitialY(); calculateMaxAndMin(); return AspectRatio( - aspectRatio: 1.1, + aspectRatio: 1.0, child: Container( decoration: const BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(18)), @@ -38,24 +43,26 @@ class LineChartCurved extends StatelessWidget { Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - const SizedBox( - height: 4, - ), - Text( - title, - style: TextStyle( - color: Colors.black, - fontSize: 15, - letterSpacing: 2), - textAlign: TextAlign.center, + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.all(16.0), + child: Text( + title!, + style: TextStyle(color: Colors.black, fontSize: 16, letterSpacing: -0.64, fontWeight: FontWeight.w600), + textAlign: TextAlign.center, + ), + ), + ], ), - SizedBox(height: 10,), + mHeight(10), Expanded( child: Padding( padding: const EdgeInsets.only(right: 18.0, left: 16.0), child: LineChart( sampleData1(context), - swapAnimationDuration: const Duration(milliseconds: 250), + duration: const Duration(milliseconds: 250), ), ), ), @@ -72,7 +79,7 @@ class LineChartCurved extends StatelessWidget { getXaxix() { for (int index = 0; index < timeSeries.length; index++) { - int mIndex = indexes * index; + int mIndex = indexes! * index; if (mIndex < timeSeries.length) { xAxixs.add(mIndex); } @@ -80,16 +87,8 @@ class LineChartCurved extends StatelessWidget { } getYaxix() { - // int indexess= (timeSeries.length*0.30).toInt(); - // for (int index = 0; index < timeSeries.length; index++) { - // int mIndex = indexess * index; - // if (mIndex < timeSeries.length) { - // yAxixs.add(timeSeries[mIndex].sales); - // } - // } - for (int index = 0; index < timeSeries.length; index++) { - int mIndex = indexes * index; + int mIndex = indexes! * index; if (mIndex < timeSeries.length) { yAxixs.add(timeSeries[mIndex].sales); } @@ -101,63 +100,69 @@ class LineChartCurved extends StatelessWidget { lineTouchData: LineTouchData( touchTooltipData: LineTouchTooltipData( tooltipBgColor: Colors.white, - ), - touchCallback: (LineTouchResponse touchResponse) {}, + touchCallback: (touchEvent, LineTouchResponse? touchResponse) {}, handleBuiltInTouches: true, ), - gridData: FlGridData( - show: true, drawVerticalLine: true, drawHorizontalLine: true), + gridData: FlGridData(show: true, drawVerticalLine: true, drawHorizontalLine: true, horizontalInterval: 14, verticalInterval: 14), titlesData: FlTitlesData( - bottomTitles: SideTitles( - showTitles: true, - getTextStyles: (value) => const TextStyle( - color: Colors.black, - fontSize: 10, - ), - 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 ''; - } 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}'; + bottomTitles: AxisTitles( + sideTitles: SideTitles( + showTitles: true, + // getTextStyles: (cxt, value) => const TextStyle( + // color: Colors.black, + // fontSize: 10, + // ), + + getTitlesWidget: (value, title) { + TextStyle style = TextStyle( + color: Colors.black, + fontSize: 10, + ); + + if (timeSeries.length < 15) { + if (timeSeries.length > value.toInt()) { + return Text( + '${timeSeries[value.toInt()].time.month}/ ${timeSeries[value.toInt()].time.year}', + style: style, + ); + } else + return SizedBox(); + } else { + if (value.toInt() == 0) + return Text( + '${timeSeries[value.toInt()].time.month}/ ${timeSeries[value.toInt()].time.year}', + style: style, + ); + if (value.toInt() == timeSeries.length - 1) + return Text( + '${timeSeries[value.toInt()].time.month}/ ${timeSeries[value.toInt()].time.year}', + style: style, + ); + if (xAxixs.contains(value.toInt())) { + return Text( + '${timeSeries[value.toInt()].time.month}/ ${timeSeries[value.toInt()].time.year}', + style: style, + ); + } } - } - return ''; - }, + return SizedBox(); + }, + // rotateAngle: -65, + // margin: 22, + ), ), - leftTitles: SideTitles( - showTitles: true, - getTextStyles: (value) => const TextStyle( - color: Colors.black, - fontWeight: FontWeight.bold, - fontSize: 10, + leftTitles: AxisTitles( + sideTitles: SideTitles( + showTitles: true, + /* getTextStyles: (cxt, value) => const TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold, + fontSize: 10, + ),*/ + interval: 3.0, + // margin: 12, ), - getTitles: (value) { - if (timeSeries.length < 15) { - return '${value.toInt()}'; - } else { - if (value == minY) - return '${value.toInt()}'; - if (value == getMaxY()) - return '${value.toInt()}'; - //if (yAxixs.contains(value)) { - return '${value.toInt()}'; - - return ''; - } - return '${value.toInt()}'; - }, - margin: 12, ), ), borderData: FlBorderData( @@ -180,48 +185,66 @@ class LineChartCurved extends StatelessWidget { ), minX: minX, maxX: maxX, - maxY: maxY, - minY: minY, + maxY: lastY + 1, + minY: intialY - 0.5, lineBarsData: getData(context), ); } - calculateMaxAndMin(){ + calculateMaxAndMin() { getMaxY(); getMaxX(); getMin(); getMinY(); - increasingY = ((maxY-minY)/timeSeries.length - 1)*15; + increasingY = ((maxY - minY) / timeSeries.length - 1) * 15; maxY += increasingY.abs(); minY -= increasingY.abs(); } double getMaxY() { - maxY = 0; + maxY = 0; timeSeries.forEach((element) { double resultValueDouble = element.sales; - if (resultValueDouble > maxY) maxY = resultValueDouble; + if (resultValueDouble > maxY) { + lastY = resultValueDouble; + maxY = resultValueDouble; + } }); + print("maxY " + lastY.toString()); + return maxY.roundToDouble(); + } + + double getInitialY() { + try { + intialY = timeSeries.first.sales; + timeSeries.forEach((element) { + double resultValueDouble = element.sales; + if (resultValueDouble < intialY) intialY = resultValueDouble; + }); + } catch (e) { + intialY = 0; + } - return maxY.roundToDouble() ; + print("minY " + intialY.toString()); + return intialY.roundToDouble(); } - getMaxX(){ + getMaxX() { maxX = (timeSeries.length - 1).toDouble(); } - double getMin(){ - minX = 0; + double getMin() { + minX = 0; timeSeries.forEach((element) { double resultValueDouble = element.sales; if (resultValueDouble < minX) minX = resultValueDouble; }); - return minX.roundToDouble() ; + return minX.roundToDouble(); } double getMinY() { - minY = 0; + minY = 0; timeSeries.forEach((element) { double resultValueDouble = element.sales; if (resultValueDouble < minY) minY = resultValueDouble; @@ -232,7 +255,7 @@ class LineChartCurved extends StatelessWidget { } List getData(context) { - List spots = List(); + List spots = []; for (int index = 0; index < timeSeries.length; index++) { spots.add(FlSpot(index.toDouble(), timeSeries[index].sales)); } @@ -240,8 +263,8 @@ class LineChartCurved extends StatelessWidget { final LineChartBarData lineChartBarData1 = LineChartBarData( spots: spots, isCurved: true, - colors: [secondaryColor], - barWidth: 3, + color: secondaryColor, + barWidth: 1.5, isStrokeCapRound: true, dotData: FlDotData( show: false, diff --git a/lib/pages/medical/vital_sign/LineChartCurvedBloodPressure.dart b/lib/pages/medical/vital_sign/LineChartCurvedBloodPressure.dart index 2d95f08c..7bcf8977 100644 --- a/lib/pages/medical/vital_sign/LineChartCurvedBloodPressure.dart +++ b/lib/pages/medical/vital_sign/LineChartCurvedBloodPressure.dart @@ -1,6 +1,7 @@ +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/widgets/charts/app_time_series_chart.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:fl_chart/fl_chart.dart'; import 'package:flutter/material.dart'; @@ -10,11 +11,10 @@ class LineChartCurvedBloodPressure extends StatelessWidget { final List timeSeries2; final int indexes; - LineChartCurvedBloodPressure( - {this.title, this.timeSeries1, this.indexes, this.timeSeries2}); + LineChartCurvedBloodPressure({required this.title, required this.timeSeries1, required this.indexes, required this.timeSeries2}); - List xAxixs = List(); - List yAxixs = List(); + List xAxixs = []; + List yAxixs = []; @override Widget build(BuildContext context) { @@ -32,24 +32,33 @@ class LineChartCurvedBloodPressure extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.stretch, children: [ const SizedBox( - height: 15, + height: 12, ), - Text( - title, - style: TextStyle( - color: Colors.black, fontSize: 15, letterSpacing: 2), - textAlign: TextAlign.center, + Padding( + padding: const EdgeInsets.only( + left: 20, + right: 20, + ), + child: Text( + title, + style: TextStyle( + color: Colors.black, + fontSize: 16, + letterSpacing: -0.64, + fontWeight: FontWeight.w600, + ), + textAlign: TextAlign.start, + ), ), SizedBox( height: 10, ), Expanded( child: Padding( - padding: - const EdgeInsets.only(right: 18.0, left: 16.0, top: 15), + padding: const EdgeInsets.only(right: 18.0, left: 16.0, top: 15), child: LineChart( sampleData1(context), - swapAnimationDuration: const Duration(milliseconds: 250), + duration: const Duration(milliseconds: 250), ), ), ), @@ -63,32 +72,53 @@ class LineChartCurvedBloodPressure extends StatelessWidget { Row( children: [ Container( - width: 20, - height: 20, - decoration: BoxDecoration( - shape: BoxShape.rectangle, - color: Theme.of(context).primaryColor), + width: 16, + height: 16, + decoration: containerRadius(Theme.of(context).primaryColor, 100), + ), + SizedBox( + width: 5, + ), + Text( + TranslationBase.of(context).systolicLng, + style: TextStyle( + color: Colors.black, + fontSize: 12, + letterSpacing: -0.64, + fontWeight: FontWeight.w600, + ), ), - SizedBox(width: 5,), - Texts(TranslationBase.of(context).systolicLng) ], ), - SizedBox(width: 15,), + SizedBox( + width: 15, + ), Row( children: [ Container( - width: 20, - height: 20, - decoration: BoxDecoration( - shape: BoxShape.rectangle, - color: Colors.red), + width: 16, + height: 16, + decoration: containerRadius(CustomColors.accentColor, 100), + ), + SizedBox( + width: 5, + ), + Text( + TranslationBase.of(context).diastolicLng, + style: TextStyle( + color: Colors.black, + fontSize: 12, + letterSpacing: -0.64, + fontWeight: FontWeight.w600, + ), ), - SizedBox(width: 5,), - Texts(TranslationBase.of(context).diastolicLng) ], ), ], - ) + ), + const SizedBox( + height: 12, + ), ], ), ], @@ -112,49 +142,68 @@ class LineChartCurvedBloodPressure extends StatelessWidget { touchTooltipData: LineTouchTooltipData( tooltipBgColor: Colors.white, ), - touchCallback: (LineTouchResponse touchResponse) {}, + touchCallback: (touchEvent, LineTouchResponse? touchResponse) {}, handleBuiltInTouches: true, ), - gridData: FlGridData( - show: true, drawVerticalLine: true, drawHorizontalLine: true), + gridData: FlGridData(show: true, drawVerticalLine: true, drawHorizontalLine: true, horizontalInterval: 14, verticalInterval: 14), titlesData: FlTitlesData( - bottomTitles: SideTitles( - showTitles: true, - getTextStyles: (value) => const TextStyle( - color: Colors.black, - fontSize: 10, - ), - rotateAngle: -65, - margin: 22, - getTitles: (value) { - if (timeSeries1.length < 15) { - if (timeSeries1.length > value.toInt()) { - return '${timeSeries1[value.toInt()].time.month}/ ${timeSeries1[value.toInt()].time.year}'; - } else - return ''; - } else { - if (value.toInt() == 0) - return '${timeSeries1[value.toInt()].time.month}/ ${timeSeries1[value.toInt()].time.year}'; - if (value.toInt() == timeSeries1.length - 1) - return '${timeSeries1[value.toInt()].time.month}/ ${timeSeries1[value.toInt()].time.year}'; - if (xAxixs.contains(value.toInt())) { - return '${timeSeries1[value.toInt()].time.month}/ ${timeSeries1[value.toInt()].time.year}'; + bottomTitles: AxisTitles( + sideTitles: SideTitles( + showTitles: true, + getTitlesWidget: (value, title) { + TextStyle style = TextStyle( + color: Colors.black, + fontSize: 10, + ); + + if (timeSeries1.length < 15) { + if (timeSeries1.length > value.toInt()) { + return Text( + '${timeSeries1[value.toInt()].time.month}/ ${timeSeries1[value.toInt()].time.year}', + style: style, + ); + } else + return SizedBox(); + } else { + if (value.toInt() == 0) + return Text( + '${timeSeries1[value.toInt()].time.month}/ ${timeSeries1[value.toInt()].time.year}', + style: style, + ); + if (value.toInt() == timeSeries1.length - 1) + return Text( + '${timeSeries1[value.toInt()].time.month}/ ${timeSeries1[value.toInt()].time.year}', + style: style, + ); + if (xAxixs.contains(value.toInt())) { + return Text( + '${timeSeries1[value.toInt()].time.month}/ ${timeSeries1[value.toInt()].time.year}', + style: style, + ); + } } - } - return ''; - }, + return SizedBox(); + }, + + // rotateAngle: -65, + // margin: 22, + ), ), - leftTitles: SideTitles( - showTitles: true, - getTextStyles: (value) => const TextStyle( - color: Colors.black, - fontWeight: FontWeight.bold, - fontSize: 10, + leftTitles: AxisTitles( + sideTitles: SideTitles( + showTitles: true, + // getTextStyles: (cxt, value) => const TextStyle( + // color: Colors.black, + // fontWeight: FontWeight.bold, + // fontSize: 10, + // ), + interval: getMaxY() - getMinY() <= 500 + ? 50 + : getMaxY() - getMinY() <= 1000 + ? 100 + : 200, + // margin: 12, ), - getTitles: (value) { - return '${value.toInt()}'; - }, - margin: 12, ), ), borderData: FlBorderData( @@ -178,7 +227,7 @@ class LineChartCurvedBloodPressure extends StatelessWidget { minX: 0, maxX: (timeSeries1.length - 1).toDouble(), maxY: getMaxY() + 15, - minY: getMinY()-15, + minY: getMinY() - 15, lineBarsData: getData(context), ); } @@ -214,12 +263,12 @@ class LineChartCurvedBloodPressure extends StatelessWidget { } List getData(context) { - List spots = List(); + List spots = []; for (int index = 0; index < timeSeries1.length; index++) { spots.add(FlSpot(index.toDouble(), timeSeries1[index].sales)); } - List spots2 = List(); + List spots2 = []; for (int index = 0; index < timeSeries2.length; index++) { spots2.add(FlSpot(index.toDouble(), timeSeries2[index].sales)); } @@ -227,8 +276,8 @@ class LineChartCurvedBloodPressure extends StatelessWidget { final LineChartBarData lineChartBarData1 = LineChartBarData( spots: spots, isCurved: true, - colors: [Colors.red], - barWidth: 5, + color: Colors.red, + barWidth: 1.5, isStrokeCapRound: true, dotData: FlDotData( show: false, @@ -240,8 +289,8 @@ class LineChartCurvedBloodPressure extends StatelessWidget { final LineChartBarData lineChartBarData2 = LineChartBarData( spots: spots2, isCurved: true, - colors: [Theme.of(context).primaryColor], - barWidth: 5, + color: Theme.of(context).primaryColor, + barWidth: 1.5, isStrokeCapRound: true, dotData: FlDotData( show: false, diff --git a/lib/pages/medical/vital_sign/vital_sign_details_blood_pressurewideget.dart b/lib/pages/medical/vital_sign/vital_sign_details_blood_pressurewideget.dart index e28b52e1..5f1cb5c5 100644 --- a/lib/pages/medical/vital_sign/vital_sign_details_blood_pressurewideget.dart +++ b/lib/pages/medical/vital_sign/vital_sign_details_blood_pressurewideget.dart @@ -5,7 +5,6 @@ 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:hexcolor/hexcolor.dart'; import 'package:provider/provider.dart'; class VitalSignBloodPressureWidget extends StatefulWidget { @@ -16,8 +15,7 @@ class VitalSignBloodPressureWidget extends StatefulWidget { final String viewKey1; final String viewKey2; - VitalSignBloodPressureWidget( - {Key key, this.vitalList, this.title1, this.title2, this.viewKey1, this.title3, this.viewKey2}); + VitalSignBloodPressureWidget({Key? key, required this.vitalList, required this.title1, required this.title2, required this.viewKey1, required this.title3, required this.viewKey2}); @override _VitalSignDetailsWidgetState createState() => _VitalSignDetailsWidgetState(); @@ -30,8 +28,7 @@ class _VitalSignDetailsWidgetState extends State { return Container( decoration: BoxDecoration( color: Colors.transparent, - borderRadius: BorderRadius.only( - topLeft: Radius.circular(10.0), topRight: Radius.circular(10.0)), + borderRadius: BorderRadius.only(topLeft: Radius.circular(10.0), topRight: Radius.circular(10.0)), border: Border.all(color: Colors.grey, width: 1), ), margin: EdgeInsets.all(20), @@ -42,7 +39,7 @@ class _VitalSignDetailsWidgetState extends State { children: [ Table( border: TableBorder.symmetric( - inside: BorderSide(width: 2.0, color: Colors.grey[300]), + inside: BorderSide(width: 2.0, color: Colors.grey[300]!), ), children: fullData(projectViewModel), ), @@ -60,9 +57,7 @@ class _VitalSignDetailsWidgetState extends State { decoration: BoxDecoration( color: Theme.of(context).primaryColor, borderRadius: BorderRadius.only( - topLeft:projectViewModel.isArabic? Radius.circular(0.0):Radius.circular(10.0), - topRight: projectViewModel.isArabic? Radius.circular(10.0):Radius.circular(0.0) - ), + topLeft: projectViewModel.isArabic ? Radius.circular(0.0) : Radius.circular(10.0), topRight: projectViewModel.isArabic ? Radius.circular(10.0) : Radius.circular(0.0)), ), child: Center( child: Texts( @@ -77,7 +72,6 @@ class _VitalSignDetailsWidgetState extends State { child: Container( decoration: BoxDecoration( color: Theme.of(context).primaryColor, - ), child: Center( child: Texts(widget.title2, color: Colors.white), @@ -89,9 +83,7 @@ class _VitalSignDetailsWidgetState extends State { decoration: BoxDecoration( color: Theme.of(context).primaryColor, borderRadius: BorderRadius.only( - topRight: projectViewModel.isArabic? Radius.circular(0.0):Radius.circular(10.0), - topLeft: projectViewModel.isArabic? Radius.circular(10.0):Radius.circular(0.0) - ), + topRight: projectViewModel.isArabic ? Radius.circular(0.0) : Radius.circular(10.0), topLeft: projectViewModel.isArabic ? Radius.circular(10.0) : Radius.circular(0.0)), ), child: Center( child: Texts(widget.title3, color: Colors.white), @@ -109,7 +101,7 @@ class _VitalSignDetailsWidgetState extends State { color: Colors.white, child: Center( child: Texts( - '${projectViewModel.isArabic ? DateUtil.getWeekDayArabic(vital.vitalSignDate.weekday) : DateUtil.getWeekDay(vital.vitalSignDate.weekday)}, ${vital.vitalSignDate.day} ${projectViewModel.isArabic ? DateUtil.getMonthArabic(vital.vitalSignDate.month) : DateUtil.getMonth(vital.vitalSignDate.month)}, ${vital.vitalSignDate.year} ', + '${projectViewModel.isArabic ? DateUtil.getWeekDayArabic(vital.vitalSignDate!.weekday) : DateUtil.getWeekDay(vital.vitalSignDate!.weekday)}, ${vital.vitalSignDate!.day} ${projectViewModel.isArabic ? DateUtil.getMonthArabic(vital.vitalSignDate!.month) : DateUtil.getMonth(vital.vitalSignDate!.month)}, ${vital.vitalSignDate!.year} ', textAlign: TextAlign.center, ), ), diff --git a/lib/pages/medical/vital_sign/vital_sign_details_screen.dart b/lib/pages/medical/vital_sign/vital_sign_details_screen.dart index 4d141b5f..a2f07522 100644 --- a/lib/pages/medical/vital_sign/vital_sign_details_screen.dart +++ b/lib/pages/medical/vital_sign/vital_sign_details_screen.dart @@ -1,202 +1,269 @@ +import 'package:auto_size_text/auto_size_text.dart'; import 'package:diplomaticquarterapp/core/enum/patient_lookup.dart'; import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/vital_sign_view_model.dart'; +import 'package:diplomaticquarterapp/models/vital_sign.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/medical/vital_sign/vital_sign_item.dart'; import 'package:diplomaticquarterapp/pages/medical/vital_sign/vital_sign_item_details_screen.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.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 '../../../d_q_icons_icons.dart'; +import 'package:flutter_svg/svg.dart'; class VitalSignDetailsScreen extends StatelessWidget { static const String url = "assets/images/"; - int appointmentNo; - int projectID; + int? appointmentNo; + int? projectID; bool isNotOneAppointment; - VitalSignDetailsScreen({this.appointmentNo, this.projectID,this.isNotOneAppointment=true}); - List imagesInfo = List(); + VitalSignDetailsScreen({this.appointmentNo, this.projectID, this.isNotOneAppointment = true}); + + List imagesInfo =[]; + List vitalSigns = []; + + initList(BuildContext context, VitalSignViewModel mode) { + vitalSigns.clear(); + vitalSigns.add(new VitalSign(TranslationBase.of(context).height, mode.heightCm, TranslationBase.of(context).cm, "assets/images/new/height.svg")); + vitalSigns.add(new VitalSign(TranslationBase.of(context).weight, mode.weightKg, TranslationBase.of(context).kg, "assets/images/new/weight.svg")); + // vitalSigns.add(new VitalSign(TranslationBase.of(context).body, mode.bodyMax, TranslationBase.of(context).mass, "assets/images/new/")); + vitalSigns.add(new VitalSign(TranslationBase.of(context).temperature, mode.temperatureCelcius, TranslationBase.of(context).tempC, "assets/images/new/temperature.svg")); + vitalSigns.add(new VitalSign(TranslationBase.of(context).heart, mode.hartRat, TranslationBase.of(context).bpm, "assets/images/new/heart_rate.svg")); + vitalSigns.add(new VitalSign(TranslationBase.of(context).respirationRate, mode.respirationBeatPerMinute, TranslationBase.of(context).respirationBPM, "assets/images/new/respiration_rate.svg")); + vitalSigns.add(new VitalSign(TranslationBase.of(context).bloodPressure, mode.bloodPressure, TranslationBase.of(context).sysDias, "assets/images/new/blood_pressure.svg")); + } @override Widget build(BuildContext context) { - imagesInfo.add(ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-vital-signs/en/0.png',imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-vital-signs/ar/0.png')); - imagesInfo.add(ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-vital-signs/en/1.png',imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-vital-signs/ar/1.png')); + imagesInfo.add(ImagesInfo( + imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-vital-signs/en/0.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-vital-signs/ar/0.png')); + imagesInfo.add(ImagesInfo( + imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-vital-signs/en/1.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-vital-signs/ar/1.png')); return BaseView( - onModelReady: appointmentNo != null && projectID != null - ? (model) => model.getPatientVitalSign( - appointmentNo: appointmentNo, projectID: projectID) - : (model) => model.getPatientVitalSign(), - builder: (_, mode, widget) => AppScaffold( - isShowAppBar: true, - appBarTitle: TranslationBase.of(context).vitalSigns, - baseViewModel: mode, - description: TranslationBase.of(context).infoSigns, - imagesInfo: imagesInfo, - body: mode.vitalSignResModelList.length > 0 - ? Container( - child: ListView( - children: [ - Row( - children: [ - InkWell( - onTap: () =>isNotOneAppointment? Navigator.push( - context, - FadePage( - page: VitalSignItemDetailsScreen( - pageKey: VitalSignDetails.Height, - pageTitle: TranslationBase.of(context).height, - vitalList: mode.vitalSignResModelList, - ), - ), - ):null, - child: Container( - child: VitalSignItem( - des: TranslationBase.of(context).height, - icon: DQIcons.height, - lastVal: mode.heightCm, - unit: TranslationBase.of(context).cm, - ), - ), - ), - InkWell( - onTap: () => isNotOneAppointment ? Navigator.push( - context, - FadePage( - page: VitalSignItemDetailsScreen( - pageKey: VitalSignDetails.Weight, - pageTitle: TranslationBase.of(context).weight, - vitalList: mode.vitalSignResModelList, - ), - ), - ):null, - child: VitalSignItem( - des: TranslationBase.of(context).weight, - icon: DQIcons.weight_scale, - unit: TranslationBase.of(context).kg, - lastVal: mode.weightKg, - ), - ), - ], - ), - Row( - children: [ - InkWell( - onTap: () => isNotOneAppointment ? Navigator.push( - context, - FadePage( - page: VitalSignItemDetailsScreen( - pageKey: VitalSignDetails.BodyMeasurements, - pageTitle: TranslationBase.of(context) - .bodyMeasurements, - vitalList: mode.vitalSignResModelList, - ), - ), - ): null, - child: VitalSignItem( - des: TranslationBase.of(context).body, - icon: DQIcons.bmi, - lastVal: mode.bodyMax, - unit: TranslationBase.of(context).mass, - ), - ), - InkWell( - onTap: () => isNotOneAppointment ? Navigator.push( - context, - FadePage( - page: VitalSignItemDetailsScreen( - pageKey: VitalSignDetails.Temperature, - pageTitle: - TranslationBase.of(context).temperature, - vitalList: mode.vitalSignResModelList, - ), - ), - ):null, - child: Container( - child: VitalSignItem( - des: TranslationBase.of(context).temperature, - icon: DQIcons.thermometer, - lastVal: mode.temperatureCelcius, - unit: TranslationBase.of(context).tempC, - ), - ), - ), - ], - ), - Row( - children: [ - InkWell( - onTap: () => isNotOneAppointment ? Navigator.push( - context, - FadePage( - page: VitalSignItemDetailsScreen( - pageKey: VitalSignDetails.heart, - pageTitle: TranslationBase.of(context).heart, - vitalList: mode.vitalSignResModelList, - ), + onModelReady: appointmentNo != null && projectID != null ? (model) => model.getPatientVitalSign(appointmentNo: appointmentNo, projectID: projectID!) : (model) => model.getPatientVitalSign(), + builder: (_, mode, widget) { + initList(context, mode); + return AppScaffold( + isShowAppBar: true, + appBarTitle: TranslationBase.of(context).vitalSigns, + baseViewModel: mode, + description: TranslationBase.of(context).infoSigns, + imagesInfo: imagesInfo, + showNewAppBar: true, + showNewAppBarTitle: true, + backgroundColor: Color(0xFFF7F7F7), + body: mode.vitalSignResModelList.length > 0 + ? Container( + width: double.infinity, + child: ListView( + children: [ + Container( + child: Container( + margin: EdgeInsets.only(left: 20, right: 20, top: 20, bottom: 6), + decoration: cardRadius(12), + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).bodyMassIndex + mode.bodyMax, + style: TextStyle( + fontSize: 16, + letterSpacing: -0.64, + fontWeight: FontWeight.w600, + ), + ), + mHeight(20), + Container( + height: MediaQuery.of(context).size.width / 2.8, + child: Row( + children: [ + showMass(context, TranslationBase.of(context).underWeight, "< 18.5", double.parse(mode.bodyMax) <= 18.5 ? Colors.red : Colors.black, 8), + mWidth(12), + showMass(context, TranslationBase.of(context).healthy, "18.5 - 24.9", (double.parse(mode.bodyMax) > 18.5 && double.parse(mode.bodyMax) < 25) ? Colors.red : Colors.black, 6), + mWidth(12), + showMass(context, TranslationBase.of(context).overWeight, "25 - 29.9", (double.parse(mode.bodyMax) >= 25 && double.parse(mode.bodyMax) < 30) ? Colors.red : Colors.black, 4), + mWidth(12), + showMass(context, TranslationBase.of(context).obese, "30 - 34.9", (double.parse(mode.bodyMax) >= 30 && double.parse(mode.bodyMax) < 35) ? Colors.red : Colors.black, 2), + mWidth(12), + showMass(context, TranslationBase.of(context).extremeObese, "> 35", (double.parse(mode.bodyMax) >= 35) ? Colors.red : Colors.black, 0), + ], + ), + ), + ], ), - ):null, - child: VitalSignItem( - des: TranslationBase.of(context).heart, - icon: DQIcons.heart, - lastVal: mode.hartRat, - unit: TranslationBase.of(context).bpm, ), ), - InkWell( - onTap: () => isNotOneAppointment ? Navigator.push( - context, - FadePage( - page: VitalSignItemDetailsScreen( - pageKey: VitalSignDetails.Respiration, - pageTitle: - TranslationBase.of(context).respirationRate, - vitalList: mode.vitalSignResModelList, - ), - ), - ):null, - child: VitalSignItem( - des: TranslationBase.of(context).respirationRate, - icon: DQIcons.outline, - lastVal: mode.respirationBeatPerMinute, - unit: TranslationBase.of(context).respirationSigns, - ), - ), - ], - ), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - InkWell( - onTap: () => isNotOneAppointment ? Navigator.push( - context, - FadePage( - page: VitalSignItemDetailsScreen( - pageKey: VitalSignDetails.BloodPressure, - pageTitle: TranslationBase.of(context).bloodPressure, - vitalList: mode.vitalSignResModelList, + ), + mHeight(2), + Container( + padding: EdgeInsets.only(left: 16, right: 16, bottom: 16), + child: GridView.builder( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, childAspectRatio: 2 / 2, crossAxisSpacing: 12, mainAxisSpacing: 12), + itemCount: vitalSigns.length, + padding: EdgeInsets.all(4), + physics: NeverScrollableScrollPhysics(), + shrinkWrap: true, + itemBuilder: (BuildContext context, int index) { + return InkWell( + onTap: () { + if (index == 0) { + if (isNotOneAppointment) { + Navigator.push( + context, + FadePage( + page: VitalSignItemDetailsScreen( + pageKey: VitalSignDetails.Height, + pageTitle: TranslationBase.of(context).height, + vitalList: mode.vitalSignResModelList, + ), + ), + ); + } + } else if (index == 1) { + if (isNotOneAppointment) { + Navigator.push( + context, + FadePage( + page: VitalSignItemDetailsScreen( + pageKey: VitalSignDetails.Weight, + pageTitle: TranslationBase.of(context).weight, + vitalList: mode.vitalSignResModelList, + ), + ), + ); + } + } else if (index == 2) { + if (isNotOneAppointment) { + Navigator.push( + context, + FadePage( + page: VitalSignItemDetailsScreen( + pageKey: VitalSignDetails.Temperature, + pageTitle: + TranslationBase.of(context).temperature, + vitalList: mode.vitalSignResModelList, + + ), + ), + ); + } + } else if (index == 3) { + if (isNotOneAppointment) { + Navigator.push( + context, + FadePage( + page: VitalSignItemDetailsScreen( + pageKey: VitalSignDetails.heart, + pageTitle: TranslationBase.of(context).heart, + vitalList: mode.vitalSignResModelList, + + ), + ), + ); + } + } else if (index == 4) { + if (isNotOneAppointment) { + Navigator.push( + context, + FadePage( + page: VitalSignItemDetailsScreen( + pageKey: VitalSignDetails.Respiration, + pageTitle: + TranslationBase.of(context).respirationRate, + vitalList: mode.vitalSignResModelList, + + ), + ), + ); + } + } else if (index == 5) { + if (isNotOneAppointment) { + Navigator.push( + context, + FadePage( + page: VitalSignItemDetailsScreen( + pageKey: VitalSignDetails.BloodPressure, + pageTitle: TranslationBase.of(context).bloodPressure, + vitalList: mode.vitalSignResModelList, + ), + ), + ); + } + } + }, + child: VitalSignItem( + vitalSign: vitalSigns[index], ), - ), - ):null, - child: VitalSignItem( - des: TranslationBase.of(context).bloodPressure, - icon: DQIcons.blood_pressure, - lastVal: mode.bloodPressure, - unit: TranslationBase.of(context).sysDias, - ), + ); + }, ), - ], - ), - ], + ), + ], + ), + ) + : Center( + child: Texts('No Data'), ), - ) - : Center( - child: Texts('No Data'), + ); + }, + ); + } + + Widget showMass(BuildContext context, String title, String weight, Color color, int f) { + return Expanded( + flex: 1, + child: Container( + height: double.infinity, + width: double.infinity, + child: Column( + children: [ + Flexible( + child: Row( + children: [ + mFlex(f), + Flexible( + flex: 10, + child: SvgPicture.asset( + "assets/images/new/mass/health_BMI.svg", + height: double.infinity, + width: double.infinity, + fit: BoxFit.fill, + color: color, + ), + ), + mFlex(f), + ], + ), + ), + mHeight(20), + AutoSizeText( + title, + maxLines: 1, + minFontSize: 6, + style: TextStyle( + color: color, + fontSize: 10, + letterSpacing: -0.6, + ), + ), + AutoSizeText( + weight, + maxLines: 1, + minFontSize: 6, + style: TextStyle( + color: color, + fontSize: 10, + letterSpacing: -0.6, ), + ) + ], + ), ), ); } diff --git a/lib/pages/medical/vital_sign/vital_sign_details_wideget.dart b/lib/pages/medical/vital_sign/vital_sign_details_wideget.dart index 113e29a6..0daaf104 100644 --- a/lib/pages/medical/vital_sign/vital_sign_details_wideget.dart +++ b/lib/pages/medical/vital_sign/vital_sign_details_wideget.dart @@ -5,17 +5,16 @@ 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:hexcolor/hexcolor.dart'; import 'package:provider/provider.dart'; class VitalSignDetailsWidget extends StatefulWidget { - final List vitalList; - final String title1; - final String title2; - final String viewKey; + final List? vitalList; + final String? title1; + final String? title2; + final String? viewKey; VitalSignDetailsWidget( - {Key key, this.vitalList, this.title1, this.title2, this.viewKey}); + {Key? key, this.vitalList, this.title1, this.title2, this.viewKey}); @override _VitalSignDetailsWidgetState createState() => _VitalSignDetailsWidgetState(); @@ -40,7 +39,7 @@ class _VitalSignDetailsWidgetState extends State { children: [ Table( border: TableBorder.symmetric( - inside: BorderSide(width: 2.0, color: Colors.grey[300]), + inside: BorderSide(width: 2.0, color: Colors.grey[300]!), ), children: fullData(projectViewModel), ), @@ -86,7 +85,7 @@ class _VitalSignDetailsWidgetState extends State { height: 60), ) ])); - widget.vitalList.forEach((vital) { + widget.vitalList!.forEach((vital) { var data = vital.toJson()[widget.viewKey]; if (data != 0) tableRow.add(TableRow(children: [ @@ -96,7 +95,7 @@ class _VitalSignDetailsWidgetState extends State { color: Colors.white, child: Center( child: Texts( - '${projectViewModel.isArabic ? DateUtil.getWeekDayArabic(vital.vitalSignDate.weekday) : DateUtil.getWeekDay(vital.vitalSignDate.weekday)}, ${vital.vitalSignDate.day} ${projectViewModel.isArabic ? DateUtil.getMonthArabic(vital.vitalSignDate.month) : DateUtil.getMonth(vital.vitalSignDate.month)}, ${vital.vitalSignDate.year} ', + '${projectViewModel.isArabic ? DateUtil.getWeekDayArabic(vital.vitalSignDate!.weekday) : DateUtil.getWeekDay(vital.vitalSignDate!.weekday)}, ${vital.vitalSignDate!.day} ${projectViewModel.isArabic ? DateUtil.getMonthArabic(vital.vitalSignDate!.month) : DateUtil.getMonth(vital.vitalSignDate!.month)}, ${vital.vitalSignDate!.year} ', textAlign: TextAlign.center, ), ), diff --git a/lib/pages/medical/vital_sign/vital_sign_item.dart b/lib/pages/medical/vital_sign/vital_sign_item.dart index fb44772d..9b89d7f7 100644 --- a/lib/pages/medical/vital_sign/vital_sign_item.dart +++ b/lib/pages/medical/vital_sign/vital_sign_item.dart @@ -1,94 +1,87 @@ -import 'package:diplomaticquarterapp/config/size_config.dart'; +import 'package:auto_size_text/auto_size_text.dart'; +import 'package:diplomaticquarterapp/models/vital_sign.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/widgets/card/rounded_container.dart'; import 'package:flutter/material.dart'; -import 'package:hexcolor/hexcolor.dart'; +import 'package:flutter_svg/flutter_svg.dart'; class VitalSignItem extends StatelessWidget { - const VitalSignItem( - {Key key, - @required this.des, - this.lastVal = 'N/A', - this.unit = '', - this.height, - this.width, - @required this.icon}) - : super(key: key); + const VitalSignItem({ + Key? key, + required this.vitalSign, + this.height, + this.width, + }) : super(key: key); - final String des; - final String lastVal; - final String unit; - final IconData icon; - final double height; - final double width; + final double? height; + final double? width; + final VitalSign vitalSign; @override Widget build(BuildContext context) { return RoundedContainer( - margin: 0.025 * SizeConfig.realScreenWidth, - height: 0.15 * SizeConfig.realScreenHeight, - width: 0.45 * SizeConfig.realScreenWidth, + margin: 0, + height: double.infinity, + width: double.infinity, child: Container( - padding: EdgeInsets.all(5), + padding: EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Container( - height: 0.10 * SizeConfig.realScreenHeight, - child: Row( - children: [ - Expanded( - flex: 2, - child: Align( - alignment: Alignment.topLeft, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Text( - des, - style: TextStyle( - fontSize: 1.7 * SizeConfig.textMultiplier, - color: HexColor('#B8382C'), - fontWeight: FontWeight.bold, - ), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AutoSizeText( + vitalSign.lastVal ?? 'N/A', + minFontSize: 10, + maxLines: 1, + style: TextStyle( + fontSize: 15, + color: Color(0xff2B353E), + letterSpacing: -0.45, + fontWeight: FontWeight.bold, ), ), - ), - ), - Expanded( - flex: 1, - child: Container( - child: Icon( - icon, - size: 40, + Text( + vitalSign.unit ?? "", + style: TextStyle( + fontSize: 9, + letterSpacing: -0.27, + color: CustomColors.accentColor, + fontWeight: FontWeight.w600, + ), ), - ), - ) - ], - ), - ), - Expanded( - child: Container( - width: double.infinity, - child: Align( - alignment: Alignment.topRight, - child: Container( - margin: EdgeInsets.only(left: 5, right: 5), - child: RichText( - text: TextSpan( - style: TextStyle(color: Colors.black), - children: [ - TextSpan(text: lastVal), - TextSpan( - text: unit, - style: TextStyle( - color: HexColor('#B8382C'), - ), - ), - ]), - ), + ], ), ), - ), + mWidth(4), + Container( + width: MediaQuery.of(context).size.width / 16, + height: MediaQuery.of(context).size.width / 16, + child: SvgPicture.asset( + vitalSign.icon, + color: Color(0xff2E303A), + ), + ), + ], ), + mFlex(1), + AutoSizeText( + vitalSign.des, + minFontSize: 8, + maxLines: 2, + style: TextStyle( + fontSize: 12, + letterSpacing: -0.33, + height: 1, + fontWeight: FontWeight.w600, + ), + ) ], ), ), diff --git a/lib/pages/medical/vital_sign/vital_sign_item_details_screen.dart b/lib/pages/medical/vital_sign/vital_sign_item_details_screen.dart index 6db865b6..07d3b39f 100644 --- a/lib/pages/medical/vital_sign/vital_sign_item_details_screen.dart +++ b/lib/pages/medical/vital_sign/vital_sign_item_details_screen.dart @@ -8,11 +8,11 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; class VitalSignItemDetailsScreen extends StatelessWidget { - final VitalSignDetails pageKey; + final VitalSignDetails? pageKey; final String pageTitle; - List VSchart; + List? VSchart; - VitalSignItemDetailsScreen({this.vitalList, this.pageKey, this.pageTitle}); + VitalSignItemDetailsScreen({required this.vitalList, this.pageKey, required this.pageTitle}); final List vitalList; @@ -30,7 +30,6 @@ class VitalSignItemDetailsScreen extends StatelessWidget { 'title2Ar': 'الكتلة', 'viewKey': 'BodyMassIndex', }, - ]; break; @@ -86,7 +85,6 @@ class VitalSignItemDetailsScreen extends StatelessWidget { 'title3Ar': 'الإنبساط', 'viewKey': 'BloodPressure', }, - ]; break; @@ -161,31 +159,33 @@ class VitalSignItemDetailsScreen extends StatelessWidget { return AppScaffold( appBarTitle: pageTitle, isShowAppBar: true, + showNewAppBarTitle: true, + showNewAppBar: true, + body: ListView( - children: VSchart.map((chartInfo) { + children: VSchart!.map((chartInfo) { var vitalListTemp = vitalList.where( (element) => element.toJson()[chartInfo['viewKey']] != null, ); - if(vitalListTemp.length != 0 && chartInfo['viewKey']=='BloodPressure'){ + if (vitalListTemp.length != 0 && chartInfo['viewKey'] == 'BloodPressure') { return VitalSingChartBloodPressure( - vitalList: vitalList, - name:projectViewModel.isArabic? chartInfo['nameAr']:chartInfo['name'], - title1: chartInfo['title1'], - title2:projectViewModel.isArabic?chartInfo['title2Ar']: chartInfo['title2'], - title3:projectViewModel.isArabic?chartInfo['title3Ar']: chartInfo['title3'], - viewKey1: 'BloodPressureHigher', - viewKey2: 'BloodPressureLower', - + vitalList: vitalList, + name: projectViewModel.isArabic ? chartInfo['nameAr'] : chartInfo['name'], + title1: chartInfo['title1'], + title2: projectViewModel.isArabic ? chartInfo['title2Ar'] : chartInfo['title2'], + title3: projectViewModel.isArabic ? chartInfo['title3Ar'] : chartInfo['title3'], + viewKey1: 'BloodPressureHigher', + viewKey2: 'BloodPressureLower', ); } return vitalListTemp.length != 0 ? VitalSingChartAndDetials( vitalList: vitalList, - name:projectViewModel.isArabic? chartInfo['nameAr']:chartInfo['name'], + name: projectViewModel.isArabic ? chartInfo['nameAr'] : chartInfo['name'], title1: chartInfo['title1'], - title2:projectViewModel.isArabic?chartInfo['title2Ar']: chartInfo['title2'], + title2: projectViewModel.isArabic ? chartInfo['title2Ar'] : chartInfo['title2'], viewKey: chartInfo['viewKey']) : Container(); }).toList(), diff --git a/lib/pages/medical/vital_sign/vital_sing_chart_and_detials.dart b/lib/pages/medical/vital_sign/vital_sing_chart_and_detials.dart index b09a579d..06df5e90 100644 --- a/lib/pages/medical/vital_sign/vital_sing_chart_and_detials.dart +++ b/lib/pages/medical/vital_sign/vital_sing_chart_and_detials.dart @@ -1,22 +1,25 @@ import 'package:diplomaticquarterapp/core/model/vital_sign/vital_sign_res_model.dart'; -import 'package:diplomaticquarterapp/pages/medical/vital_sign/vital_sign_details_wideget.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.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/charts/app_time_series_chart.dart'; -import 'package:diplomaticquarterapp/widgets/others/app_expandable_notifier.dart'; +import 'package:diplomaticquarterapp/widgets/charts/show_chart.dart'; +import 'package:diplomaticquarterapp/widgets/charts/sync_fu_chart.dart'; import 'package:flutter/material.dart'; - -import 'package:charts_flutter/flutter.dart' as charts; +import 'package:provider/provider.dart'; import 'LineChartCurved.dart'; -class VitalSingChartAndDetials extends StatelessWidget { +class VitalSingChartAndDetials extends StatefulWidget { VitalSingChartAndDetials({ - Key key, - @required this.vitalList, - @required this.name, - @required this.viewKey, - @required this.title1, - @required this.title2, + Key? key, + required this.vitalList, + required this.name, + required this.viewKey, + required this.title1, + required this.title2, }) : super(key: key); final List vitalList; @@ -24,38 +27,117 @@ class VitalSingChartAndDetials extends StatelessWidget { final String viewKey; final String title1; final String title2; + + @override + _VitalSingChartAndDetialsState createState() => _VitalSingChartAndDetialsState(); +} + +class _VitalSingChartAndDetialsState extends State { List timeSeriesData = []; + bool isExpended = true; + late ProjectViewModel projectViewModel; + + @override + void initState() { + // TODO: implement initState + super.initState(); + generateData(); + } @override Widget build(BuildContext context) { - generateData(); - return Column( - children: [ - AppExpandableNotifier( - isExpand: true, - headerWidget: LineChartCurved(title: name,timeSeries:timeSeriesData,indexes: timeSeriesData.length~/5.5,), - bodyWidget: VitalSignDetailsWidget( - vitalList: vitalList, - title1: title1, - title2: title2, - viewKey: viewKey, + projectViewModel = Provider.of(context); + return SingleChildScrollView( + child: Column( + children: [ + Container( + height: 400, + child: Container( + decoration: cardRadius(12), + margin: EdgeInsets.only(left: 16, top: 16, right: 16, bottom: 8), + child: ShowChart( + title: widget.name, + timeSeries: timeSeriesData, + indexes: timeSeriesData.length ~/ 5.5, + horizontalInterval: 8, + ), + // child: SyncFuChart(), + ), ), - ), - ], + Container( + decoration: cardRadius(12), + margin: EdgeInsets.only(left: 16, top: 8, right: 16, bottom: 16), + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).graphDetails, + style: TextStyle( + fontSize: 16, + letterSpacing: -0.64, + fontWeight: FontWeight.w600, + ), + ), + Table( + columnWidths: { + 0: FlexColumnWidth(2), + 1: FlexColumnWidth(1), + // 2: FlexColumnWidth(1), + }, + children: fullData(widget.vitalList, context), + ), + ], + ), + ), + ) + ], + ), ); } + List fullData(List labResultList, context) { + List tableRow = []; + tableRow.add( + TableRow( + children: [ + Utils.tableColumnTitle(widget.title1), + Utils.tableColumnTitle(widget.title2), + // Utils.tableColumnTitle(TranslationBase.of(context).range), + ], + ), + ); + + for (int i = 0; i < labResultList.length; i++) { + var data = labResultList[i].toJson()[widget.viewKey]; + if (data != 0) + tableRow.add( + TableRow( + children: [ + Utils.tableColumnValue( + "${projectViewModel.isArabic ? DateUtil.getWeekDayArabic(labResultList[i].vitalSignDate!.weekday) : DateUtil.getWeekDay(labResultList[i].vitalSignDate!.weekday)}, ${labResultList[i].vitalSignDate!.day} ${projectViewModel.isArabic ? DateUtil.getMonthArabic(labResultList[i].vitalSignDate!.month) : DateUtil.getMonth(labResultList[i].vitalSignDate!.month)}, ${labResultList[i].vitalSignDate!.year}", + isLast: i == (labResultList.length - 1), mProjectViewModel: projectViewModel), + Utils.tableColumnValue('${labResultList[i].toJson()[widget.viewKey]}', isLast: i == (labResultList.length - 1), mProjectViewModel: projectViewModel), + ], + ), + ); + } + + return tableRow; + } + generateData() { - if (vitalList.length > 0) { - vitalList.reversed.toList().forEach( - (element) { - if( element.toJson()[viewKey]!=null && element.toJson()[viewKey]?.toInt()!=0) - timeSeriesData.add( - TimeSeriesSales2( - new DateTime(element.vitalSignDate.year, element.vitalSignDate.month, element.vitalSignDate.day), - element.toJson()[viewKey].toDouble(), - ), - ); + if (widget.vitalList.length > 0) { + widget.vitalList.reversed.toList().forEach( + (element) { + if (element.toJson()[widget.viewKey] != null && element.toJson()[widget.viewKey]?.toInt() != 0) + timeSeriesData.add( + TimeSeriesSales2( + DateTime(element.vitalSignDate!.year, element.vitalSignDate!.month, element.vitalSignDate!.day), + element.toJson()[widget.viewKey].toDouble(), + ), + ); }, ); } diff --git a/lib/pages/medical/vital_sign/vital_sing_chart_blood_pressure.dart b/lib/pages/medical/vital_sign/vital_sing_chart_blood_pressure.dart index 84a2eb51..195afb0c 100644 --- a/lib/pages/medical/vital_sign/vital_sing_chart_blood_pressure.dart +++ b/lib/pages/medical/vital_sign/vital_sing_chart_blood_pressure.dart @@ -1,25 +1,25 @@ import 'package:diplomaticquarterapp/core/model/vital_sign/vital_sign_res_model.dart'; -import 'package:diplomaticquarterapp/pages/medical/vital_sign/vital_sign_details_blood_pressurewideget.dart'; -import 'package:diplomaticquarterapp/pages/medical/vital_sign/vital_sign_details_wideget.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.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/charts/app_time_series_chart.dart'; -import 'package:diplomaticquarterapp/widgets/others/app_expandable_notifier.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; -import 'package:charts_flutter/flutter.dart' as charts; - -import 'LineChartCurved.dart'; import 'LineChartCurvedBloodPressure.dart'; class VitalSingChartBloodPressure extends StatelessWidget { VitalSingChartBloodPressure({ - Key key, - @required this.vitalList, - @required this.name, - @required this.viewKey1, - @required this.viewKey2, - @required this.title1, - @required this.title2, - @required this.title3, + Key? key, + required this.vitalList, + required this.name, + required this.viewKey1, + required this.viewKey2, + required this.title1, + required this.title2, + required this.title3, }) : super(key: key); final List vitalList; @@ -31,33 +31,99 @@ class VitalSingChartBloodPressure extends StatelessWidget { final String title3; List timeSeriesData1 = []; List timeSeriesData2 = []; + late ProjectViewModel projectViewModel; @override Widget build(BuildContext context) { + projectViewModel = Provider.of(context); generateData(); - return Column( - children: [ - AppExpandableNotifier( - isExpand: true, - headerWidget: LineChartCurvedBloodPressure( - title: name, - timeSeries1: timeSeriesData1, - timeSeries2: timeSeriesData2, - indexes: timeSeriesData1.length ~/ 5.5, - ), - bodyWidget: VitalSignBloodPressureWidget( - vitalList: vitalList, - title1: title1, - title2: title2, - title3: title3, - viewKey1: viewKey1, - viewKey2: viewKey2, + return SingleChildScrollView( + child: Column( + children: [ + Container( + decoration: cardRadius(12), + margin: EdgeInsets.only(left: 16, top: 16, right: 16, bottom: 8), + child: LineChartCurvedBloodPressure( + title: name, + timeSeries1: timeSeriesData1, + timeSeries2: timeSeriesData2, + indexes: timeSeriesData1.length ~/ 5.5, + ), ), - ), - ], + + // VitalSignBloodPressureWidget( + // vitalList: vitalList, + // title1: title1, + // title2: title2, + // title3: title3, + // viewKey1: viewKey1, + // viewKey2: viewKey2, + // ), + Container( + decoration: cardRadius(12), + margin: EdgeInsets.only(left: 16, top: 8, right: 16, bottom: 16), + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).graphDetails, + style: TextStyle( + fontSize: 16, + letterSpacing: -0.64, + fontWeight: FontWeight.w600, + ), + ), + Table( + columnWidths: { + 0: FlexColumnWidth(2), + 1: FlexColumnWidth(1), + // 2: FlexColumnWidth(1), + }, + children: fullData(vitalList, context), + ), + ], + ), + ), + ) + ], + ), ); } + List fullData(List labResultList, context) { + List tableRow = []; + tableRow.add( + TableRow( + children: [ + Utils.tableColumnTitle(title1), + Utils.tableColumnTitle(title2), + Utils.tableColumnTitle(title3), + // Utils.tableColumnTitle(TranslationBase.of(context).range), + ], + ), + ); + + for (int i = 0; i < labResultList.length; i++) { + var data = labResultList[i].toJson()[viewKey1]; + if (data != 0) + tableRow.add( + TableRow( + children: [ + Utils.tableColumnValue( + "${projectViewModel.isArabic ? DateUtil.getWeekDayArabic(labResultList[i].vitalSignDate!.weekday) : DateUtil.getWeekDay(labResultList[i].vitalSignDate!.weekday)}, ${labResultList[i].vitalSignDate!.day} ${projectViewModel.isArabic ? DateUtil.getMonthArabic(labResultList[i].vitalSignDate!.month) : DateUtil.getMonth(labResultList[i].vitalSignDate!.month)}, ${labResultList[i].vitalSignDate!.year}", + isLast: i == (labResultList.length - 1), mProjectViewModel: projectViewModel), + Utils.tableColumnValue('${labResultList[i].toJson()[viewKey1]}', isLast: i == (labResultList.length - 1), mProjectViewModel: projectViewModel), + Utils.tableColumnValue('${labResultList[i].toJson()[viewKey2]}', isLast: i == (labResultList.length - 1), mProjectViewModel: projectViewModel), + ], + ), + ); + } + + return tableRow; + } + generateData() { if (vitalList.length > 0) { vitalList.reversed.toList().forEach( @@ -65,16 +131,14 @@ class VitalSingChartBloodPressure extends StatelessWidget { if (element.toJson()[viewKey1]?.toInt() != 0) timeSeriesData1.add( TimeSeriesSales2( - new DateTime(element.vitalSignDate.year, - element.vitalSignDate.month, element.vitalSignDate.day), + new DateTime(element.vitalSignDate!.year, element.vitalSignDate!.month, element.vitalSignDate!.day), element.toJson()[viewKey1].toDouble(), ), ); if (element.toJson()[viewKey2]?.toInt() != 0) timeSeriesData2.add( TimeSeriesSales2( - new DateTime(element.vitalSignDate.year, - element.vitalSignDate.month, element.vitalSignDate.day), + new DateTime(element.vitalSignDate!.year, element.vitalSignDate!.month, element.vitalSignDate!.day), element.toJson()[viewKey2].toDouble(), ), ); diff --git a/lib/pages/offers_categorise_page.dart b/lib/pages/offers_categorise_page.dart index f3875d1a..572978b9 100644 --- a/lib/pages/offers_categorise_page.dart +++ b/lib/pages/offers_categorise_page.dart @@ -1,12 +1,13 @@ -import 'package:diplomaticquarterapp/config/size_config.dart'; import 'package:diplomaticquarterapp/core/viewModels/offers_Categorise_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/StarRating.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_pharmacy_widget.dart'; -import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/others/network_base_view.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_rating_bar/flutter_rating_bar.dart'; import 'package:provider/provider.dart'; import 'base/base_view.dart'; @@ -28,634 +29,299 @@ class _OffersCategorisePageState extends State { @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); ProjectViewModel projectProvider = Provider.of(context); return BaseView( onModelReady: (model) => model.getOffersCategorise(), - builder: (BuildContext context, OffersCategoriseViewModel model, - Widget child) => - PharmacyAppScaffold( - appBarTitle: 'Offers', - isShowAppBar: true, - backgroundColor: Colors.white, - isShowDecPage: false, - baseViewModel: model, - body: model.categorise.length != 0 - ? Container( - //height: MediaQuery.of(context).size.height * 0.57, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: EdgeInsets.all(10.0), - child: Container( - child: Texts( - 'Categories', - fontWeight: FontWeight.w800, - ), - ), - ), - Divider( - thickness: 1.0, - color: Colors.grey.shade400, + builder: (BuildContext context, OffersCategoriseViewModel model, Widget? child) => PharmacyAppScaffold( + appBarTitle: TranslationBase.of(context).offers, + isShowAppBar: true, + backgroundColor: Colors.white, + isShowDecPage: false, + baseViewModel: model, + body: model.categorise.length != 0 + ? Container( + //height: MediaQuery.of(context).size.height * 0.57, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.all(10.0), + child: Container( + child: Texts( + 'Categories', + fontWeight: FontWeight.w800, ), - //Expanded widget heree if nassery - Container( - height: MediaQuery.of(context).size.height * 0.20, - child: ListView.builder( - scrollDirection: Axis.horizontal, - itemCount: model.categorise.length, - itemBuilder: - (BuildContext context, int index) { - return Padding( - padding: EdgeInsets.all(8.0), - child: Row( - children: [ - InkWell( - child: Column( - children: [ - Container( - height: 60.0, - width: 65.0, - decoration: BoxDecoration( - shape: BoxShape.circle, - color: Colors - .orange.shade200 - .withOpacity(0.45), - ), - child: Icon( - Icons.apps_sharp, - size: 32.0, - ), - ), - Container( - width: - MediaQuery.of(context) - .size - .width * - 0.2, - height: - MediaQuery.of(context) - .size - .height * - 0.09, - child: Center( - child: Texts( - model.categorise[index] - .name, - fontWeight: - FontWeight.w600, - fontSize: 13.8, - ), - ), + ), + ), + Divider( + thickness: 1.0, + color: Colors.grey.shade400, + ), + //Expanded widget heree if nassery + Container( + height: MediaQuery.of(context).size.height * 0.20, + child: ListView.builder( + scrollDirection: Axis.horizontal, + itemCount: model.categorise.length, + itemBuilder: (BuildContext context, int index) { + return Padding( + padding: EdgeInsets.all(8.0), + child: Row( + children: [ + InkWell( + child: Column( + children: [ + Container( + height: 60.0, + width: 65.0, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: Colors.orange.shade200.withOpacity(0.45), + ), + child: Icon( + Icons.apps_sharp, + size: 32.0, + ), + ), + Container( + width: MediaQuery.of(context).size.width * 0.2, + height: MediaQuery.of(context).size.height * 0.09, + child: Center( + child: Texts( + projectViewModel.isArabic ? model.categorise[index].namen : model.categorise[index].name, +// model.categorise[index].name, + fontWeight: FontWeight.w600, + fontSize: 13.8, ), - ], + ), ), - onTap: () { - model.getOffersProducts( - i: model - .categorise[index].id); - String ids = - model.categorise[index].id; + ], + ), + onTap: () { + model.getOffersProducts(i: model.categorise[index].id); + String ids = model.categorise[index].id!; - categoriseName = model - .categorise[index].name; - }), - ], - ), - ); - }), - ), - Divider( - thickness: 1.0, - color: Colors.grey.shade400, + categoriseName = projectViewModel.isArabic ? model.categorise[index].namen! : model.categorise[index].name!; + //model.categorise[index].name; + }), + ], + ), + ); + }), + ), + Divider( + thickness: 1.0, + color: Colors.grey.shade400, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: EdgeInsets.all(8.0), + child: Texts( + categoriseName, + fontWeight: FontWeight.w800, + ), ), Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ + Container( + height: 44.0, + child: VerticalDivider( + color: Colors.black45, + thickness: 0.7, + //width: 0.3, + // indent: 0.0, + ), + ), Padding( padding: EdgeInsets.all(8.0), - child: Texts( - categoriseName, - fontWeight: FontWeight.w800, + child: InkWell( + child: styleIcon, + onTap: () { + setState(() { + if (styleOne == true) { + styleOne = false; + styleTwo = true; + styleIcon = Icon( + Icons.auto_awesome_mosaic, + color: Colors.blue, + size: 29.0, + ); + } else { + styleOne = true; + styleTwo = false; + styleIcon = Icon( + Icons.widgets_sharp, + color: Colors.blue, + size: 29.0, + ); + } + }); + }, ), ), - Row( - children: [ - Container( - height: 44.0, - child: VerticalDivider( - color: Colors.black45, - thickness: 0.7, - //width: 0.3, - // indent: 0.0, - ), - ), - Padding( - padding: EdgeInsets.all(8.0), - child: InkWell( - child: styleIcon, - onTap: () { - setState(() { - if (styleOne == true) { - styleOne = false; - styleTwo = true; - styleIcon = Icon( - Icons.auto_awesome_mosaic, - color: Colors.blue, - size: 29.0, - ); - } else { - styleOne = true; - styleTwo = false; - styleIcon = Icon( - Icons.widgets_sharp, - color: Colors.blue, - size: 29.0, - ); - } - }); - }, - ), - ), - ], - ), ], ), - Divider( - thickness: 1.0, - color: Colors.grey.shade400, - ), - styleOne == true - ? Expanded( - child: Container( - height: - MediaQuery.of(context).size.height * - 0.50, - child: GridView.builder( - gridDelegate: - SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 2, - crossAxisSpacing: 0.5, - mainAxisSpacing: 2.0, - childAspectRatio: 0.85, - ), - itemCount: model.products.length, - itemBuilder: - (BuildContext context, int index) { - return NetworkBaseView( - baseViewModel: model, - child: Card( - color: model.products[index] - .discountName != - null - ? Color(0xffFFFF00) - : Colors.white, - elevation: 0, - shape: Border( - right: BorderSide( - color: Colors.grey.shade300, - width: 1, - ), - left: BorderSide( - color: Colors.grey.shade300, - width: 1, - ), - bottom: BorderSide( - color: Colors.grey.shade300, - width: 1, - ), - top: BorderSide( - color: Colors.grey.shade300, - width: 1, - ), - ), - margin: EdgeInsets.symmetric( - horizontal: 8, - vertical: 4, + ], + ), + Divider( + thickness: 1.0, + color: Colors.grey.shade400, + ), + styleOne == true + ? Expanded( + child: Container( + height: MediaQuery.of(context).size.height * 0.50, + child: GridView.builder( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + crossAxisSpacing: 0.5, + mainAxisSpacing: 2.0, + childAspectRatio: 0.85, + ), + itemCount: model.products.length, + itemBuilder: (BuildContext context, int index) { + return NetworkBaseView( + baseViewModel: model, + child: Card( + color: model.products[index].discountName != null ? Color(0xffFFFF00) : Colors.white, + elevation: 0, + shape: Border( + right: BorderSide( + color: Colors.grey.shade300, + width: 1, + ), + left: BorderSide( + color: Colors.grey.shade300, + width: 1, + ), + bottom: BorderSide( + color: Colors.grey.shade300, + width: 1, + ), + top: BorderSide( + color: Colors.grey.shade300, + width: 1, + ), + ), + margin: EdgeInsets.symmetric( + horizontal: 8, + vertical: 4, + ), + child: Container( + height: 250.0, + decoration: BoxDecoration( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(110.0), ), - child: Container( - height: 250.0, - decoration: BoxDecoration( - borderRadius: - BorderRadius.only( - topLeft: Radius.circular( - 110.0), - ), - color: Colors.white, - ), - padding: EdgeInsets.symmetric( - horizontal: 0), - width: MediaQuery.of(context) - .size - .width / - 3, - child: Column( - crossAxisAlignment: - CrossAxisAlignment - .start, + color: Colors.white, + ), + padding: EdgeInsets.symmetric(horizontal: 0), + width: MediaQuery.of(context).size.width / 3, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Stack( children: [ - Stack( - children: [ - if (model - .products[ - index] - .discountName != - null) - RotatedBox( - quarterTurns: 4, - child: Container( - decoration: - BoxDecoration(), - child: Padding( - padding: - EdgeInsets - .only( - right: 5.0, - top: 20.0, - bottom: 5.0, - ), - child: Texts( - 'offer' - .toUpperCase(), - color: Colors - .red, - fontSize: - 13.0, - fontWeight: - FontWeight - .w900, - ), - ), - transform: new Matrix4 - .rotationZ( - 5.837200), + if (model.products[index].discountName != null) + RotatedBox( + quarterTurns: 4, + child: Container( + decoration: BoxDecoration(), + child: Padding( + padding: EdgeInsets.only( + right: 5.0, + top: 20.0, + bottom: 5.0, + ), + child: Texts( + TranslationBase.of(context).offers.toUpperCase(), + color: Colors.red, + fontSize: 13.0, + fontWeight: FontWeight.w900, ), ), - Container( - margin: EdgeInsets - .fromLTRB(0, 16, - 0, 0), - alignment: Alignment - .center, - child: - Image.network( - model - .products[ - index] - .images - .isNotEmpty - ? model - .products[ - 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.cover, - height: 80, - ), - ), - Container( - width: model - .products[ - index] - .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: Texts( - model - .products[ - index] - .rxMessage != - null - ? model - .products[ - index] - .rxMessage - : "", - color: - Colors.white, - regular: true, - fontSize: 10, - fontWeight: - FontWeight - .w400, - ), + transform: new Matrix4.rotationZ(5.837200), ), - ], - ), + ), Container( - margin: EdgeInsets - .symmetric( - horizontal: 6, - vertical: 0, + margin: EdgeInsets.fromLTRB(0, 16, 0, 0), + alignment: Alignment.center, + child: Image.network( + model.products[index].images!.isNotEmpty + ? model.products[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.cover, + height: 80, ), - child: Column( - crossAxisAlignment: - CrossAxisAlignment - .start, - children: [ - if (model - .products[ - index] - .discountName != - null) - Container( - width: double - .infinity, - height: 22.0, - decoration: - BoxDecoration( - color: Color( - 0xff5AB145), - ), - child: Center( - child: Texts( - model - .products[ - index] - .discountName, - regular: - true, - color: Colors - .white, - fontSize: - 12.0, - fontWeight: - FontWeight - .w700, - ), - ), - ), - Texts( - model - .products[ - index] - .name, - regular: true, - fontSize: 12.58, - fontWeight: - FontWeight - .w600, - ), - Padding( - padding: - const EdgeInsets - .only( - top: 4, - bottom: - 4), - child: Texts( - "SAR ${model.products[index].price}", - bold: true, - fontSize: 14, - ), - ), - Row( - children: [ - StarRating( - totalAverage: model.products[index].approvedRatingSum > - 0 - ? (model.products[index].approvedRatingSum.toDouble() / model.products[index].approvedRatingSum.toDouble()) - .toDouble() - : 0, - forceStars: - true), - Texts( - "(${model.products[index].approvedTotalReviews})", + ), + Container( + width: model.products[index].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: model.products[index].rxMessage != null + ? Texts( + projectProvider.isArabic ? model.products[index].rxMessagen : model.products[index].rxMessage, + color: Colors.white, regular: true, fontSize: 10, - fontWeight: - FontWeight - .w400, + fontWeight: FontWeight.w400, ) - ], - ), - ], - ), - ), - ], - ), - ), - )); - }, - ), - ), - ) - : Expanded( - child: Container( - child: ListView.builder( - itemCount: model.products.length, - itemBuilder: (BuildContext context, - int index) { - return Card( - // color: - // model.products[index].discountName != - // null - // ? Color(0xffFFFF00) - // : Colors.white, - child: Row( - children: [ - Stack( - children: [ - Column( - children: [ - if (model - .products[ - index] - .discountName != - null) - Container( - decoration: - BoxDecoration(), - child: Padding( - padding: - EdgeInsets - .only( - left: 9.0, - top: 8.0, - right: 10.0, - ), - child: - Container( - color: Colors - .yellow, - height: 25.0, - width: 70.0, - child: Center( - child: - Texts( - 'offer' - .toUpperCase(), - color: Colors - .red, - fontSize: - 13.0, - fontWeight: - FontWeight - .w900, - ), - ), - ), - ), - transform: new Matrix4 - .rotationZ( - 6.15099), - ), - Container( - margin: EdgeInsets - .fromLTRB( - 0, 0, 0, 0), - alignment: Alignment - .center, - child: - Image.network( - model - .products[ - index] - .images - .isNotEmpty - ? model - .products[ - 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.cover, - height: 80, - ), + : Texts("") +// Texts( +// model.products[index].rxMessage != null ? +// model.products[index].rxMessage +// : "", +// color: +// Colors.white, +// regular: true, +// fontSize: 10, +// fontWeight: +// FontWeight +// .w400, +// ), ), - ], - ), - Column( - children: [ - Container( - width: model - .products[ - index] - .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: Texts( - model - .products[ - index] - .rxMessage != - null - ? model - .products[ - index] - .rxMessage - : "", - color: - Colors.white, - regular: true, - fontSize: 10, - fontWeight: - FontWeight - .w400, - ), - ), - ], - ), ], ), Container( - margin: - EdgeInsets.symmetric( + margin: EdgeInsets.symmetric( horizontal: 6, vertical: 0, ), child: Column( - crossAxisAlignment: - CrossAxisAlignment - .start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ - if (model - .products[index] - .discountName != - null) + if (model.products[index].discountName != null) Container( - width: 250.0, - height: 22.5, - decoration: - BoxDecoration( - color: Color( - 0xff5AB145), + width: double.infinity, + height: 22.0, + decoration: BoxDecoration( + color: Color(0xff5AB145), ), - child: Padding( - padding: EdgeInsets - .symmetric( - horizontal: 5.5, - ), + child: Center( child: Texts( - model - .products[ - index] - .discountName, + model.products[index].discountName, regular: true, - color: Colors - .white, + color: Colors.white, fontSize: 12.0, - fontWeight: - FontWeight - .w700, + fontWeight: FontWeight.w700, ), ), ), - SizedBox( - height: 4.0, - ), Texts( - model.products[index] - .name, + projectViewModel.isArabic ? model.products[index].namen : model.products[index].name, + // model.products[index].name, regular: true, - fontSize: 14.0, - fontWeight: - FontWeight.w600, - ), - SizedBox( - height: 8.0, + fontSize: 12.58, + fontWeight: FontWeight.w600, ), Padding( - padding: - const EdgeInsets - .only( - top: 4, - bottom: 4), + padding: const EdgeInsets.only(top: 4, bottom: 4), child: Texts( "SAR ${model.products[index].price}", bold: true, @@ -664,26 +330,42 @@ class _OffersCategorisePageState extends State { ), Row( children: [ - StarRating( - totalAverage: model - .products[ - index] - .approvedRatingSum > - 0 - ? (model.products[index].approvedRatingSum.toDouble() / - model.products[index].approvedRatingSum - .toDouble()) - .toDouble() - : 0, - forceStars: - true), +// StarRating( +// totalAverage: model.products[index].approvedRatingSum > +// 0 +// ? (model.products[index].approvedRatingSum.toDouble() / model.products[index].approvedRatingSum.toDouble()) +// .toDouble() +// : 0, +// forceStars: +// true), + + RatingBar( + initialRating: model.products[index].approvedRatingSum!.toDouble(), + ratingWidget: RatingWidget( + full: Icon( + Icons.star, + color: CustomColors.accentColor, + ), + half: Icon( + Icons.star_half, + color: CustomColors.accentColor, + ), + empty: Icon( + Icons.star_border, + color: CustomColors.accentColor, + ), + ), + onRatingUpdate: (double value) {}, + unratedColor: Colors.grey[500], + updateOnDrag: false, + tapOnlyMode: false, + ), + Texts( "(${model.products[index].approvedTotalReviews})", regular: true, fontSize: 10, - fontWeight: - FontWeight - .w500, + fontWeight: FontWeight.w400, ) ], ), @@ -692,17 +374,236 @@ class _OffersCategorisePageState extends State { ), ], ), - ); - }), - ), - ) - ], + ), + )); + }, + ), + ), + ) + : Expanded( + child: Container( + child: ListView.builder( + itemCount: model.products.length, + itemBuilder: (BuildContext context, int index) { + return Card( + // color: + // model.products[index].discountName != + // null + // ? Color(0xffFFFF00) + // : Colors.white, + child: Row( + children: [ + Stack( + children: [ + Column( + children: [ + if (model.products[index].discountName != null) + Container( + decoration: BoxDecoration(), + child: Padding( + padding: EdgeInsets.only( + left: 9.0, + top: 8.0, + right: 10.0, + ), + child: Container( + color: Colors.yellow, + height: 25.0, + width: 70.0, + child: Center( + child: Texts( + TranslationBase.of(context).offers.toUpperCase(), + color: Colors.red, + fontSize: 13.0, + fontWeight: FontWeight.w900, + ), + ), + ), + ), + transform: new Matrix4.rotationZ(6.15099), + ), + Container( + margin: EdgeInsets.fromLTRB(0, 0, 0, 0), + alignment: Alignment.center, + child: Image.network( + model.products[index].images!.isNotEmpty + ? model.products[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.cover, + height: 80, + ), + ), + ], + ), + Column( + children: [ + Container( + width: model.products[index].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: model.products[index].rxMessage != null + ? Texts( + projectProvider.isArabic ? model.products[index].rxMessagen : model.products[index].rxMessage, + color: Colors.white, + regular: true, + fontSize: 10, + fontWeight: FontWeight.w400, + ) + : Texts("") +// Texts( +// model.products[index].rxMessage != null +// ? model.products[index].rxMessage +// : "", +// color: +// Colors.white, +// regular: true, +// fontSize: 10, +// fontWeight: +// FontWeight +// .w400, +// ), + ), + ], + ), + ], + ), + Container( + margin: EdgeInsets.symmetric( + horizontal: 6, + vertical: 0, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (model.products[index].discountName != null) + Container( + width: 250.0, + height: 22.5, + decoration: BoxDecoration( + color: Color(0xff5AB145), + ), + child: Padding( + padding: EdgeInsets.symmetric( + horizontal: 5.5, + ), + child: Texts( + model.products[index].discountName, + regular: true, + color: Colors.white, + fontSize: 12.0, + fontWeight: FontWeight.w700, + ), + ), + ), + SizedBox( + height: 4.0, + ), + Texts( + projectViewModel.isArabic ? model.products[index].namen : model.products[index].name, + // model.products[index].name, + regular: true, + fontSize: 14.0, + fontWeight: FontWeight.w600, + ), + SizedBox( + height: 8.0, + ), + Padding( + padding: const EdgeInsets.only(top: 4, bottom: 4), + child: Texts( + "SAR ${model.products[index].price}", + bold: true, + fontSize: 14, + ), + ), + Row( + children: [ +// StarRating( +// totalAverage: model +// .products[ +// index] +// .approvedRatingSum > +// 0 +// ? (model.products[index].approvedRatingSum.toDouble() / +// model.products[index].approvedRatingSum +// .toDouble()) +// .toDouble() +// : 0, +// forceStars: +// true), + + RatingBar( + initialRating: model.products[index].approvedRatingSum!.toDouble(), + ratingWidget: RatingWidget( + full: Icon( + Icons.star, + color: CustomColors.accentColor, + ), + half: Icon( + Icons.star_half, + color: CustomColors.accentColor, + ), + empty: Icon( + Icons.star_border, + color: CustomColors.accentColor, + ), + ), + onRatingUpdate: (double value) {}, + unratedColor: Colors.grey[500], + updateOnDrag: false, + tapOnlyMode: false, + ), + + Texts( + "(${model.products[index].approvedTotalReviews})", + regular: true, + fontSize: 10, + fontWeight: FontWeight.w500, + ) + ], + ), + ], + ), + ), + ], + ), + ); + }), + ), + ) + ], + ), + ) + : 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, + ), ), - ) - : Center( - child: Texts( - "SORRY , there's no listed offers now :(", - color: Colors.green, - )))); + Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + TranslationBase.of(context).noOffersAvailable, +// '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/packages_offers/ClinicOfferAndPackagesPage.dart b/lib/pages/packages_offers/ClinicOfferAndPackagesPage.dart index 76688606..247203ad 100644 --- a/lib/pages/packages_offers/ClinicOfferAndPackagesPage.dart +++ b/lib/pages/packages_offers/ClinicOfferAndPackagesPage.dart @@ -1,27 +1,17 @@ import 'package:after_layout/after_layout.dart'; -import 'package:carousel_slider/carousel_slider.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/PackagesCategoriesResponseModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart'; import 'package:diplomaticquarterapp/core/viewModels/packages_offers/PackagesOffersViewModel.dart'; -import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/order_model_view_model.dart'; -import 'package:diplomaticquarterapp/locator.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; -import 'package:diplomaticquarterapp/pages/packages_offers/OfferAndPackageDetailPage.dart'; -import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/pages/packages_offers/packages_offers_tab_pager.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart' as utils; -import 'package:diplomaticquarterapp/widgets/loadings/ShimmerLoading.dart'; import 'package:diplomaticquarterapp/widgets/offers_packages/PackagesOfferCard.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:flutter/rendering.dart'; -import 'package:flutter_material_pickers/flutter_material_pickers.dart'; -import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; +// import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart' as grid_view; import 'CreateCustomerDailogPage.dart'; @@ -29,39 +19,33 @@ dynamic languageID; class ClinicPackagesPage extends StatefulWidget { List products; - ClinicPackagesPage({@required this.products}); + + ClinicPackagesPage({required this.products}); @override _ClinicPackagesPageState createState() => _ClinicPackagesPageState(); - - } -class _ClinicPackagesPageState extends State with AfterLayoutMixin{ - AppScaffold appScaffold; +class _ClinicPackagesPageState extends State with AfterLayoutMixin { + AppScaffold? appScaffold; List get _products => widget.products; - PackagesViewModel viewModel; - + PackagesViewModel? viewModel; 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(); - 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){ - appScaffold.appBar.badgeUpdater(viewModel.service.cartItemCount); - }).catchError((error) { + 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) {}).catchError((error) { utils.Utils.showErrorToast(error); }); } } - @override - void afterFirstLayout(BuildContext context) async{ - appScaffold.appBar.badgeUpdater(viewModel.service.cartItemCount); + void afterFirstLayout(BuildContext context) async { + // appScaffold.appBar.badgeUpdater(viewModel.service.cartItemCount); } @override @@ -69,13 +53,11 @@ class _ClinicPackagesPageState extends State with AfterLayo super.initState(); } - @override Widget build(BuildContext context) { - return BaseView( allowAny: true, - onModelReady: (model){ + onModelReady: (model) { viewModel = model; }, builder: (_, model, wi) => appScaffold = AppScaffold( @@ -87,22 +69,26 @@ class _ClinicPackagesPageState extends State with AfterLayo isOfferPackages: true, showOfferPackagesCart: true, isShowDecPage: false, + showNewAppBar: true, + showNewAppBarTitle: true, body: Padding( - padding: const EdgeInsets.all(5), - child: StaggeredGridView.countBuilder( - crossAxisCount:4, - itemCount: _products.length, - itemBuilder: (BuildContext context, int index) => new Container( - color: Colors.transparent, - child: PackagesItemCard( itemContentPadding: 10,itemModel: _products[index], onCartClick: onProductCartClick,) - ), - staggeredTileBuilder: (int index) => StaggeredTile.fit(2), - mainAxisSpacing: 20, - crossAxisSpacing: 10, - ) + padding: const EdgeInsets.all(12), + // child: grid_view.AlignedGridView.count( + // crossAxisCount: 4, + // itemCount: _products.length, + // itemBuilder: (BuildContext context, int index) => new Container( + // color: Colors.transparent, + // child: PackagesItemCard( + // itemContentPadding: 10, + // itemModel: _products[index], + // onCartClick: OFFERS_VIEW_ONLY ? onProductCartClick : (PackagesResponseModel) {}, + // )), + // // staggeredTileBuilder: (int index) => StaggeredTile.fit(2), + // mainAxisSpacing: 20, + // crossAxisSpacing: 10, + // ), ), ), ); } - } diff --git a/lib/pages/packages_offers/CreateCustomerDailogPage.dart b/lib/pages/packages_offers/CreateCustomerDailogPage.dart index 73e95d09..ce53c66b 100644 --- a/lib/pages/packages_offers/CreateCustomerDailogPage.dart +++ b/lib/pages/packages_offers/CreateCustomerDailogPage.dart @@ -1,51 +1,32 @@ import 'package:after_layout/after_layout.dart'; -import 'package:carousel_slider/carousel_slider.dart'; import 'package:diplomaticquarterapp/config/size_config.dart'; -import 'package:diplomaticquarterapp/core/model/packages_offers/requests/AddProductToCartRequestModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/requests/CreateCustomerRequestModel.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/PackagesCustomerResponseModel.dart'; -import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart'; import 'package:diplomaticquarterapp/core/viewModels/packages_offers/PackagesOffersViewModel.dart'; -import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/order_model_view_model.dart'; -import 'package:diplomaticquarterapp/locator.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; -import 'package:diplomaticquarterapp/pages/packages_offers/ClinicOfferAndPackagesPage.dart'; -import 'package:diplomaticquarterapp/pages/packages_offers/OfferAndPackageDetailPage.dart'; -import 'package:diplomaticquarterapp/pages/packages_offers/OfferAndPackagesCartPage.dart'; -import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; -import 'package:diplomaticquarterapp/uitl/utils.dart' as utils; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/AnimatedTextFields.dart'; -import 'package:diplomaticquarterapp/widgets/Loader/gif_loader_container.dart'; import 'package:diplomaticquarterapp/widgets/LoadingButton.dart'; -import 'package:diplomaticquarterapp/widgets/carousel_indicator/carousel_indicator.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; -import 'package:diplomaticquarterapp/widgets/loadings/ShimmerLoading.dart'; -import 'package:diplomaticquarterapp/widgets/offers_packages/PackagesOfferCard.dart'; -import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:flutter/rendering.dart'; -import 'package:flutter_material_pickers/flutter_material_pickers.dart'; dynamic languageID; var emailRegex = RegExp(r'^[^\s@]+@[^\s@]+\.[^\s@]+$'); class CreateCustomerDialogPage extends StatefulWidget { - final BuildContext context; + final BuildContext? context; CreateCustomerDialogPage({this.context}); - PackagesViewModel viewModel; + PackagesViewModel? viewModel; - Future show() async{ - await showDialog(context: context, builder: (context ){ + Future show() async{ + await showDialog(context: context!, builder: (context ){ return AlertDialog(content: this, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(20) ), elevation: 5, ); }); - return viewModel.service.customer; + return viewModel!.service!.customer; } @override @@ -54,8 +35,8 @@ class CreateCustomerDialogPage extends StatefulWidget { } class _CreateCustomerDialogPageState extends State with AfterLayoutMixin, TickerProviderStateMixin{ - AnimationController _loadingController; - AnimationController _submitController; + AnimationController? _loadingController; + AnimationController? _submitController; bool _enableInput = true; Interval _nameTextFieldLoadingAnimationInterval = const Interval(0, .85); @@ -80,7 +61,7 @@ class _CreateCustomerDialogPageState extends State wit bool verifyPin = false; - PackagesViewModel viewModel() => widget.viewModel; + PackagesViewModel viewModel() => widget.viewModel!; @override Widget build(BuildContext context) { @@ -93,14 +74,14 @@ class _CreateCustomerDialogPageState extends State wit } Widget verifyPinWidget(){ - +return SizedBox(); } Widget userDetailWidget(){ return Container( - width: SizeConfig.realScreenWidth * 0.8, + width: SizeConfig.realScreenWidth! * 0.8, height: 270, child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, @@ -124,7 +105,7 @@ class _CreateCustomerDialogPageState extends State wit FocusScope.of(context).requestFocus(_phoneFocusNode); }, validator: (value){ - return (value.isEmpty || !emailRegex.hasMatch(value)) + return (value!.isEmpty || !emailRegex.hasMatch(value)) ? 'Invalid email!' : null; }, @@ -145,7 +126,7 @@ class _CreateCustomerDialogPageState extends State wit FocusScope.of(context).requestFocus(_phoneFocusNode); }, validator: (value){ - return (value.isEmpty || !emailRegex.hasMatch(value)) + return (value!.isEmpty || !emailRegex.hasMatch(value)) ? 'Invalid email!' : null; }, @@ -155,7 +136,7 @@ class _CreateCustomerDialogPageState extends State wit AnimatedButton( color: Theme.of(context).primaryColor, loadingColor: Theme.of(context).primaryColor, - controller: _submitController, + controller: _submitController!, text: TranslationBase.of(context).done, onPressed: (){ createCustomer(); @@ -171,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)); } @@ -192,7 +173,7 @@ class _CreateCustomerDialogPageState extends State wit } loading(bool can){ - can ? _submitController.forward() : _submitController.reverse(); + can ? _submitController!.forward() : _submitController!.reverse(); } } diff --git a/lib/pages/packages_offers/OfferAndPackageDetailPage.dart b/lib/pages/packages_offers/OfferAndPackageDetailPage.dart index d0e69d14..14ddf937 100644 --- a/lib/pages/packages_offers/OfferAndPackageDetailPage.dart +++ b/lib/pages/packages_offers/OfferAndPackageDetailPage.dart @@ -1,221 +1,279 @@ -import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; -import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCategoriesResponseModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart'; import 'package:diplomaticquarterapp/core/viewModels/packages_offers/PackagesOffersViewModel.dart'; -import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/order_model_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/ProductCheckTypeWidget.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/uitl/utils.dart' as utils; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; -import 'package:diplomaticquarterapp/widgets/others/StarRating.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:expandable/expandable.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; +import 'package:flutter_rating_bar/flutter_rating_bar.dart'; +import 'package:html/parser.dart'; -import 'ClinicOfferAndPackagesPage.dart'; -class OfferAndPackagesDetail extends StatefulWidget{ - final dynamic model; +class OfferAndPackagesDetail extends StatefulWidget { + final PackagesResponseModel itemModel; + final Function(PackagesResponseModel product) onCartClick; + bool showAddToCartFooter = true; - const OfferAndPackagesDetail({@required this.model, Key key}) : super(key: key); + OfferAndPackagesDetail({required this.itemModel, required this.onCartClick, Key? key}) : super(key: key); @override State createState() => OfferAndPackagesDetailState(); } +class OfferAndPackagesDetailState extends State { + PackagesViewModel? viewModel; -class OfferAndPackagesDetailState extends State{ - - PackagesViewModel viewModel; + bool expandFlag = false; + var controller = new ExpandableController(); @override Widget build(BuildContext context) { - getLanguageID(); + final images = widget.itemModel.images ?? []; + String image = ""; + if(images.isNotEmpty) + image = widget.itemModel.images!.first.src ?? ""; return BaseView( - onModelReady: (model){ + onModelReady: (model) { viewModel = model; }, builder: (_, model, wi) => AppScaffold( - appBarTitle: TranslationBase.of(context).offerAndPackages, - isShowAppBar: true, - isPharmacy: false, - showPharmacyCart: false, - showHomeAppBarIcon: false, - isOfferPackages: true, - showOfferPackagesCart: true, - isShowDecPage: false, - body: Stack( - children: [ - Padding( - padding: const EdgeInsets.only(bottom: 60), - child: ListView( - children: [ - Padding( - padding: const EdgeInsets.all(5), - child: Stack( - children: [ - Padding( - padding: const EdgeInsets.all(10), - child: AspectRatio( - aspectRatio: 1/1, - child: utils.applyShadow( - child: ClipRRect( - borderRadius: BorderRadius.circular(10), - child: utils.Utils.loadNetworkImage(url: "https://wallpaperaccess.com/full/30103.jpg",) - ), - ) - ), - ), - Align( - alignment: Alignment.topLeft, - child: Image.asset( - 'assets/images/discount_${'en'}.png', - height: 70, - width: 70, - ), - ), - - ], - + appBarTitle: TranslationBase.of(context).offerAndPackages, + isShowAppBar: true, + isPharmacy: false, + showPharmacyCart: false, + showHomeAppBarIcon: false, + isOfferPackages: true, + showOfferPackagesCart: true, + isShowDecPage: false, + showNewAppBar: true, + showNewAppBarTitle: true, + body: Column( + children: [ + Expanded( + child: ListView( + physics: BouncingScrollPhysics(), + children: [ + Container( + color: Colors.white, + padding: const EdgeInsets.all(21.0), + child: AspectRatio( + aspectRatio: 333 / 333, + child: ClipRRect( + borderRadius: BorderRadius.circular(15.0), + child: Image.network( + image, + fit: BoxFit.fill, + errorBuilder: (a1,a2,a3) => Container(color: Colors.grey.withOpacity(0.25),), + ), ), ), - - Padding( - padding: const EdgeInsets.only(left: 20, right: 20, bottom: 20), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts( - "Child Dental Offer", - fontSize: 25, - fontWeight: FontWeight.normal, - color: Colors.black, + ), + Padding( + padding: const EdgeInsets.all(21.0), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + widget.itemModel.name!, + maxLines: 1, + style: TextStyle(fontSize: 19.0, fontWeight: FontWeight.bold, color: Color(0xff2E303A), letterSpacing: -1.14), + ), + Text( + widget.itemModel.shortDescription!, + style: TextStyle(fontSize: 14.0, fontWeight: FontWeight.w600, color: Color(0xff575757), letterSpacing: -.56), + ), + SizedBox(height: 9), + Row( + children: [ + // RatingBar.readOnly( + // initialRating: 4.5, + // // todo ask haroon about rating value + // size: 18.0, + // filledColor: Color(0XFFD02127), + // emptyColor: Color(0XFFD02127), + // isHalfAllowed: true, + // halfFilledIcon: Icons.star_half, + // filledIcon: Icons.star, + // emptyIcon: Icons.star_border, + // ), + RatingBar( + initialRating: 4.5, + direction: Axis.horizontal, + allowHalfRating: true, + itemCount: 5, + itemSize: 20, + ignoreGestures: true, + ratingWidget: RatingWidget( + full: Icon(Icons.star, color: CustomColors.accentColor,), + half: Icon(Icons.star_half, color: CustomColors.accentColor,), + empty: Icon(Icons.star, color: CustomColors.accentColor,), + ), + tapOnlyMode: true, + unratedColor: Colors.grey[500], + itemPadding: EdgeInsets.symmetric(horizontal: 4.0), + onRatingUpdate: (rating) { + print(rating); + }, + ) + ], + ), + SizedBox(height: 16), + SizedBox( + height: 34, + child: ListView.separated( + scrollDirection: Axis.horizontal, + shrinkWrap: true, + physics: BouncingScrollPhysics(), + itemCount: widget.itemModel.storeNames!.length, + separatorBuilder: (context, index) { + return mWidth(5.0); + }, + itemBuilder: (BuildContext context, int index) { + return contactButton(widget.itemModel.storeNames![index].toString()); + }, ), - - Stack( - children: [ - Texts( - "200 SAR", - fontWeight: FontWeight.normal, - decoration: TextDecoration.lineThrough, - color: Colors.grey, - fontSize: 12 + ), + ], + ), + ), + ExpandableNotifier( + initialExpanded: true, + child: Container( + color: Colors.white, + margin: EdgeInsets.only(bottom: 21), + child: Column( + children: [ + ScrollOnExpand( + scrollOnExpand: true, + scrollOnCollapse: false, + child: ExpandablePanel( + + theme: const ExpandableThemeData( + headerAlignment: ExpandablePanelHeaderAlignment.center, + tapBodyToCollapse: true, ), - Padding( - padding: const EdgeInsets.only(top: 15), - child: Texts( - "894.99 SAR", - fontWeight: FontWeight.bold, - color: Colors.green, - fontSize: 18 + header: InkWell( + onTap: () { + setState(() { + expandFlag = !expandFlag; + controller.expanded = expandFlag; + }); + }, + child: Padding( + padding: const EdgeInsets.all(21), + child: Row( + children: [ + Expanded( + child: Text( + TranslationBase.of(context).description, + maxLines: 1, + style: TextStyle(fontSize: 19.0, color: Color(0xff2E303A), fontWeight: FontWeight.bold, letterSpacing: -1.14), + ), + ), + Icon( + expandFlag ? Icons.keyboard_arrow_up : Icons.keyboard_arrow_down, + color: Color(0xff2E303A), + ), + ], + ), ), ), - ], - ), - - StarRating( - size: 20, - totalCount: null, - totalAverage: 5, - forceStars: true), - - - SizedBox(height: 20,), - - - Texts( - "Details", - fontWeight: FontWeight.bold, - color: Colors.grey, - fontSize: 20 - ), - - - - AspectRatio( - aspectRatio: 2/1, - child: Container( - color: Colors.grey[300], - child: Padding( - padding: const EdgeInsets.all(10), - child: Texts("Detail of offers written here"), - ) + builder: (_, collapsed, expanded) { + return Expandable( + controller: controller, + collapsed: collapsed, + expanded: Padding( + padding: const EdgeInsets.only(bottom: 21, left: 21, right: 21), + child: Text(parseHtmlString(widget.itemModel.fullDescription!), + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + letterSpacing: -0.56, + color: Color(0xff575757), + ), + overflow: TextOverflow.clip), + ), + theme: const ExpandableThemeData(crossFadePoint: 0), + ); + }, collapsed: SizedBox(), expanded: SizedBox(), ), ), - - - SizedBox(height: 10,), ], ), ), - ], - ), + ), + ], ), - - Padding( - padding: const EdgeInsets.all(10), - child: Align( - alignment: Alignment.bottomRight, - child: Row( + ), + if(widget.showAddToCartFooter && widget.onCartClick != null) + Row( + children: [ + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, children: [ - - Expanded( - child: RaisedButton.icon( - padding: EdgeInsets.only(top: 5, bottom: 5, left: 0, right: 0), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8.0), - side: BorderSide(color: Colors.red, width: 0.5) - ), - color: Colors.red, - icon: Icon( - Icons.add_shopping_cart_outlined, - size: 25, - color: Colors.white, - ), - label: Texts( - "Add to Cart", - fontSize: 17, color: Colors.white, fontWeight: FontWeight.normal, - ), - onPressed: (){},), - ), - - SizedBox(width: 15,), - - Expanded( - child: OutlineButton.icon( - padding: EdgeInsets.only(top: 5, bottom: 5, left: 0, right: 0), - borderSide: BorderSide(width: 1.0, color: Colors.red), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8.0), - ), - color: Colors.white, - icon: Icon( - Icons.favorite_rounded, - size: 25, - color: Colors.red, - ), - label: Texts( - "Add to Favorites", - fontSize: 17, color: Colors.red, fontWeight: FontWeight.normal - ), - onPressed: (){ - - },), - ), - + if (widget.itemModel.hasDiscountsApplied!) + Text(widget.itemModel.oldPrice.toString() + " " + TranslationBase.of(context).sar, + style: TextStyle(fontSize: 15.0, fontWeight: FontWeight.w600, letterSpacing: -0.6, decoration: TextDecoration.lineThrough, color: CustomColors.grey2)), + Text(widget.itemModel.price.toString().trim() + " " + TranslationBase.of(context).sar, + style: TextStyle(fontSize: 19.0, fontWeight: FontWeight.bold, letterSpacing: -0.76, color: Color(0xff2B353E))), ], ), ), - ) - + SizedBox(width: 8), + Expanded( + child: DefaultButton( + TranslationBase.of(context).addToCart, + () { + widget.onCartClick(widget.itemModel); + }, + svgIcon: "assets/images/new/add_to_cart.svg", + isTextExpanded: false, + ), + ), + ], + ).insideContainer + ], + ), + ), + ); + } + String parseHtmlString(String htmlString) { + var document = parse(htmlString); + String parsedString = parse(document.body!.text!).documentElement!.text!; + return parsedString; + } - ], - ) + Widget contactButton(String title) { + return Container( + height: 34, + padding: EdgeInsets.only(left: 12, right: 12, top: 8, bottom: 9), + alignment: Alignment.center, + decoration: BoxDecoration( + color: Colors.white, + border: Border.all(color: Color(0xffEAEAEA), width: 1), + borderRadius: BorderRadius.all( + Radius.circular(36.0), + ), + ), + child: Text( + title, + style: TextStyle( + fontSize: 10, + letterSpacing: -0.4, + fontWeight: FontWeight.w600, + color: Color(0xff535353), + ), + maxLines: 1, ), ); } } - diff --git a/lib/pages/packages_offers/OfferAndPackagesCartPage.dart b/lib/pages/packages_offers/OfferAndPackagesCartPage.dart index d39f726d..9f9d6858 100644 --- a/lib/pages/packages_offers/OfferAndPackagesCartPage.dart +++ b/lib/pages/packages_offers/OfferAndPackagesCartPage.dart @@ -1,42 +1,38 @@ import 'package:after_layout/after_layout.dart'; -import 'package:carousel_slider/carousel_slider.dart'; -import 'package:diplomaticquarterapp/core/enum/PaymentOptions.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/ResponseModel.dart'; +import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.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/viewModels/packages_offers/PackagesOffersViewModel.dart'; -import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/order_model_view_model.dart'; -import 'package:diplomaticquarterapp/locator.dart'; +import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/h2o/h20_setting.dart'; +import 'package:diplomaticquarterapp/pages/ToDoList/payment_method_select.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; -import 'package:diplomaticquarterapp/pages/packages_offers/ClinicOfferAndPackagesPage.dart'; -import 'package:diplomaticquarterapp/pages/packages_offers/OfferAndPackageDetailPage.dart'; import 'package:diplomaticquarterapp/pages/packages_offers/PackageOrderCompletedPage.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/pharmacy-terms-conditions-page.dart'; -import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart' as utils; -import 'package:diplomaticquarterapp/widgets/Loader/gif_loader_container.dart'; -import 'package:diplomaticquarterapp/widgets/carousel_indicator/carousel_indicator.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/radio_selection_dialog.dart'; import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart'; -import 'package:diplomaticquarterapp/widgets/loadings/ShimmerLoading.dart'; import 'package:diplomaticquarterapp/widgets/offers_packages/PackagesCartItemCard.dart'; -import 'package:diplomaticquarterapp/widgets/offers_packages/PackagesOfferCard.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:flutter/rendering.dart'; -import 'package:flutter_material_pickers/flutter_material_pickers.dart'; -import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; -import 'package:font_awesome_flutter/font_awesome_flutter.dart'; + +import '../../core/model/packages_offers/responses/PackagesCartItemsResponseModel.dart'; dynamic languageID; const _columnCount = 1; +bool _agreeTerms = false; +String? _selectedPaymentMethod; +Map? _selectedPaymentParams; -AnimationController _animationController; +AnimationController? _animationController; class PackagesCartPage extends StatefulWidget { PackagesCartPage(); @@ -50,6 +46,10 @@ class _PackagesCartPageState extends State with AfterLayoutMix languageID = await sharedPref.getString(APP_LANGUAGE); } + double? subtotal, tax, total; + int _selectedHospitalIndex = -1; + HospitalsModel? _selectedHospital; + @override void initState() { _agreeTerms = false; @@ -60,12 +60,12 @@ class _PackagesCartPageState extends State with AfterLayoutMix @override void dispose() { - _animationController.dispose(); - viewModel.cartItemList.clear(); + _animationController!.dispose(); + viewModel!.cartItemList.clear(); super.dispose(); } - PackagesViewModel viewModel; + PackagesViewModel? viewModel; bool loadWidgets = false; @@ -77,327 +77,326 @@ class _PackagesCartPageState extends State with AfterLayoutMix Navigator.push(context, FadePage(page: PharmacyTermsConditions())); } - onPayNowClick() async{ - await viewModel.service.placeOrder(context: context,paymentOption: _selectedPaymentMethod.toUpperCase()).then((orderId){ - if(orderId.runtimeType == int){ // result == order_id - var browser = MyInAppBrowser( - context: context, - onExitCallback: (data, isDone) => paymentClosed(orderId: orderId, withStatus: isDone, data: data) - ); - browser.openPackagesPaymentBrowser(customer_id: viewModel.service.customer.id, order_id: orderId); - - }else{ + onPayNowClick() async { + await viewModel!.service.placeOrder(context: context, projectID: _selectedHospital!.iD, paymentParams: _selectedPaymentParams!).then((orderId) { + if (orderId.runtimeType == int) { + var browser = MyInAppBrowser(context: context, onExitCallback: (data, isDone) => paymentClosed(orderId: orderId, withStatus: isDone, data: data)); + browser.openPackagesPaymentBrowser(customer_id: viewModel!.service.customer!.id, order_id: orderId); + } else { utils.Utils.showErrorToast('Failed to place order, please try again later'); } - - }).catchError((error){ - utils.Utils.showErrorToast(error); + }).catchError((error) { + utils.Utils.showErrorToast(error.toString()); }); } @override void afterFirstLayout(BuildContext context) { fetchData(); + viewModel!.service.getHospitals(); } @override Widget build(BuildContext context) { return BaseView( - allowAny: true, - onModelReady: (model) => viewModel = model, - builder: (_, model, wi) { - return AppScaffold( - appBarTitle: TranslationBase.of(context).offerAndPackages, - isShowAppBar: true, - isPharmacy: false, - showPharmacyCart: false, - showHomeAppBarIcon: false, - isOfferPackages: true, - showOfferPackagesCart: false, - isShowDecPage: false, - body: Column( - children: [ - Expanded( - child: Padding( - padding: const EdgeInsets.all(5), - child: StaggeredGridView.countBuilder( - crossAxisCount: (_columnCount * _columnCount), - itemCount: viewModel.cartItemList.length, - itemBuilder: (BuildContext context, int index) { - - var item = viewModel.cartItemList[index]; - return Dismissible( - key: Key(index.toString()), - direction: DismissDirection.startToEnd, - background: _cartItemDeleteContainer(), - secondaryBackground: _cartItemDeleteContainer(), - confirmDismiss: (direction) async { - bool status = await viewModel.service.deleteProductFromCart(item.id, context: context, showLoading: false); - return status; - }, - onDismissed: (direction) { - debugPrint('Index: $index'); - viewModel.cartItemList.removeAt(index); + allowAny: true, + onModelReady: (model) => viewModel = model, + builder: (_, model, wi) { + return AppScaffold( + appBarTitle: TranslationBase.of(context).offerAndPackages, + isShowAppBar: true, + isPharmacy: false, + showPharmacyCart: false, + showHomeAppBarIcon: false, + isOfferPackages: true, + showOfferPackagesCart: false, + isShowDecPage: false, + showNewAppBar: true, + showNewAppBarTitle: true, + body: viewModel!.cartItemList.length > 0 + ? Column( + children: [ + Expanded( + child: ListView.separated( + padding: EdgeInsets.all(21), + physics: BouncingScrollPhysics(), + itemBuilder: (cxt, index) { + var item = viewModel!.cartItemList[index]; + return PackagesCartItemCard( + itemModel: item, + viewModel: viewModel!, + getCartItems: fetchData, + shouldStepperChangeApply: (apply, total) async { + var request = AddProductToCartRequestModel(product_id: item.productId, quantity: apply); + ResponseModel? response = await viewModel!.service!.addProductToCart!(request, context: context, showLoading: false)!.catchError((error) { + utils.Utils.showErrorToast(error); + }); + if (response!.status!) { + fetchData(); + } + return response.status ?? false; }, - child: PackagesCartItemCard( - itemModel: item, - shouldStepperChangeApply: (apply,total) async{ - var request = AddProductToCartRequestModel(product_id: item.productId, quantity: apply); - ResponseModel response = await viewModel.service.addProductToCart(request, context: context, showLoading: false).catchError((error){ - utils.Utils.showErrorToast(error); - }); - return response.status ?? false; - }, - ) - ); - }, - staggeredTileBuilder: (int index) => StaggeredTile.fit(_columnCount), - mainAxisSpacing: 0, - crossAxisSpacing: 10, - )), - ), - Container( - height: 0.25, - color: Theme.of(context).primaryColor, - ), - Container( - color: Colors.white, - child: Column( - children: [ - Texts( - TranslationBase.of(context).selectPaymentOption, - fontSize: 10, - fontWeight: FontWeight.bold - ), - - Container(height: 0.25, width: 100, color: Colors.grey[300],), - - _paymentOptions(context, (paymentMethod) { - setState(() => _selectedPaymentMethod = paymentMethod); - }), - - Container(height: 0.25, color: Colors.grey[300],), + ); + }, + separatorBuilder: (cxt, index) => SizedBox(height: 12), + itemCount: viewModel!.cartItemList.length), + ), + Container( + height: 1, + color: Color(0xffEFEFEF), + ), + if (viewModel!.cartItemList.length > 0) + Container( + padding: EdgeInsets.only(left: 21, right: 21, top: 15, bottom: 15), + width: double.infinity, + color: Colors.white, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + CommonDropDownView( + TranslationBase.of(context).hospital, + getHospitalName(), + () => confirmSelectHospitalDialog(model.hospitals), + ).withBorderedContainer, + SizedBox(height: 12), + Text( + TranslationBase.of(context).YouCanPayByTheFollowingOptions, + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + SizedBox( + width: MediaQuery.of(context).size.width * 0.75, + child: getPaymentMethods(), + ), + Padding( + padding: EdgeInsets.only(top: 12.0, bottom: 12), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + SizedBox( + height: 16.0, + width: 16.0, + child: Checkbox( + value: _agreeTerms, + onChanged: (v) { + setState(() => _agreeTerms = v!); + }), + ), + SizedBox(width: 10), + Expanded( + child: Text( + TranslationBase.of(context).iAcceptTermsConditions, + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: CustomColors.textColor, letterSpacing: -0.48), + ), + ), + ], + ), + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _amountView(TranslationBase.of(context).patientShareToDo, (subtotal ?? 0.0).toStringAsFixed(2) + " " + TranslationBase.of(context).sar, isBold: true), + mDivider(Color(0xffEFEFEF)), + _amountView(TranslationBase.of(context).patientTaxToDo, (tax ?? 0.0).toStringAsFixed(2) + " " + TranslationBase.of(context).sar, isBold: true), + mDivider(Color(0xffEFEFEF)), + _amountView(TranslationBase.of(context).patientShareTotalToDo, (total ?? 0.0).toStringAsFixed(2) + " " + TranslationBase.of(context).sar, isBold: true, isTotal: true), + ], + ), + SizedBox(height: 12), + DefaultButton( + TranslationBase.of(context).payNow, + (_agreeTerms && _selectedHospital != null) + ? () { + Navigator.push(context, FadePage(page: PaymentMethod(onSelectedMethod: (String metohd) { + setState(() {}); + }))).then((value) { + print(value); + if (value != null) { + _selectedPaymentMethod = value; + _selectedPaymentParams = {"payment_method_system_name": "Payments.PayFort", "payment_option": value}; + onPayNowClick(); + } + }); + } + : null, + color: CustomColors.green, + disabledColor: CustomColors.grey2, + ), + ], + ), + ) + ], + ) + : getNoDataWidget(context), + ); + }, + ); + } - Container(height: 40, - child: _termsAndCondition(context, onSelected: onTermsClick, onInfoClick: onTermsInfoClick) - ), + 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, + builder: (cxt) => RadioSelectionDialog( + listData: list, + selectedIndex: _selectedHospitalIndex, + isScrollable: true, + onValueSelected: (index) { + _selectedHospitalIndex = index; + _selectedHospital = hospitals[index]; + setState(() {}); + }, + ), + ); + } - Container(height: 0.25, color: Colors.grey[300],), - _payNow(context, onPayNowClick: onPayNowClick) - ], - ), - ) - ], - ), - ); - }); + String getHospitalName() { + if (_selectedHospital != null) + return _selectedHospital!.name!; + else + return TranslationBase.of(context).selectHospital; } fetchData() async { - await viewModel.service.cartItems(context: context).catchError((error) {}); - setState((){}); + final cartResponse = await viewModel!.service.cartItems(context: context).catchError((error) {}); + if(cartResponse != null){ + subtotal = cartResponse['subtotal'] ?? 0.0; + tax = cartResponse['tax'] ?? 0.0; + total = cartResponse['total'] ?? 0.0; + viewModel!.service!.getTamaraOptions(context: context, showLoading: true).then((tamara_options){ + if(tamara_options != null || tamara_options.isNotEmpty) { + viewModel!.setTamaraIllegablity(total!); + setState(() {}); + } + }); + } } - paymentClosed({@required int orderId, @required bool withStatus, dynamic data}) async{ - viewModel.service.getOrderById(orderId, context: context).then((value){ + paymentClosed({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 subTitle = "Order# ${value.data.customOrderNumber}"; - Navigator.of(context).pushReplacement( - MaterialPageRoute(builder: (context) => PackageOrderCompletedPage(heading: heading, title: title, subTitle: subTitle)) - ); - - }).catchError((error){ - debugPrint(error); + 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(heading: heading, title: title, subTitle: subTitle))); + }).catchError((error) { + print(error); }); } -} - -// /* Payment Footer Widgets */ -// --------------------------- -String _selectedPaymentMethod; -Widget _paymentOptions(BuildContext context, Function(String) onSelected) { - double height = 30; - Widget buttonContent(bool isSelected, String imageName) { - return Container( - decoration: BoxDecoration( - color: Colors.white, - boxShadow: [ - BoxShadow( - color: isSelected ? Colors.green[50] : Colors.grey[200], - blurRadius: 1, - spreadRadius: 2, - ), - ], - borderRadius: BorderRadius.all(Radius.circular(5)), - border: Border.all(color: isSelected ? Colors.green : Colors.grey, width: isSelected ? 1 : 0.5) - ), - child: Padding( - padding: const EdgeInsets.all(4), - child: Image.asset('assets/images/new-design/$imageName'), - ) - ); - } +} +// 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( +// child: Row( +// crossAxisAlignment: CrossAxisAlignment.end, +// children: [ +// Padding( +// padding: const EdgeInsets.all(5), +// child: Column( +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// Texts('${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}: $_tax ${TranslationBase.of(context).sar}', heightFactor: 1.5, fontWeight: FontWeight.bold, color: Colors.grey, fontSize: 8), +// Padding( +// padding: const EdgeInsets.all(3), +// child: Container( +// height: 0.25, +// width: 120, +// color: Colors.grey[300], +// ), +// ), +// Texts('${TranslationBase.of(context).total}: $_total ${TranslationBase.of(context).sar}', heightFactor: 1.5, fontWeight: FontWeight.bold, color: Colors.black54, fontSize: 15) +// ], +// ), +// ), +// Expanded(child: Container()), +// RaisedButton( +// elevation: 0, +// child: Texts( +// TranslationBase.of(context).payNow, +// fontSize: 15, +// color: Colors.white, +// fontWeight: FontWeight.bold, +// ), +// padding: EdgeInsets.only(top: 5, bottom: 5, left: 0, right: 0), +// shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5), side: BorderSide(color: Theme.of(context).primaryColor, width: 0.5)), +// color: Theme.of(context).primaryColor, +// onPressed: isPayNowAQctive ? onPayNowClick : null, +// ), +// ], +// )), +// ); +// } +_amountView(String title, String value, {bool isBold = false, bool isTotal = false}) { return Padding( - padding: const EdgeInsets.all(5), - child: Container( - height: height, - color: Colors.transparent, - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - InkWell( - child: buttonContent(_selectedPaymentMethod == "mada", 'mada.png'), - onTap: () { - onSelected("mada"); - }, - ), - SizedBox( - width: 5, - ), - InkWell( - child: buttonContent(_selectedPaymentMethod == "visa", 'visa.png'), - onTap: () { - onSelected("visa"); - }, - ), - SizedBox( - width: 5, - ), - InkWell( - child: buttonContent(_selectedPaymentMethod == "mastercard", 'mastercard.png'), - onTap: () { - onSelected("mastercard"); - }, - ), - SizedBox( - width: 5, - ), - InkWell( - child: buttonContent(_selectedPaymentMethod == "installment", 'installment.png'), - onTap: () { - onSelected("installment"); - }, - ), - ], + padding: const EdgeInsets.only(top: 10, bottom: 10), + child: Row(children: [ + Expanded( + child: _getNormalText(title), ), - ), + Expanded( + child: _getNormalText(value, isBold: isBold, isTotal: isTotal), + ), + ]), ); } -bool _agreeTerms = false; -Widget _termsAndCondition(BuildContext context, {@required Function(bool) onSelected, @required VoidCallback onInfoClick}) { - return Padding( - padding: const EdgeInsets.all(5), - child: Row( - children: [ - InkWell( - child: Icon( - _agreeTerms ? Icons.check_circle : Icons.radio_button_unchecked_sharp, - size: 20, - color: _agreeTerms ? Colors.green[600] : Colors.grey[400], - ), - onTap: () { - onSelected(!_agreeTerms); - }, - ), - Expanded( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 8), - child: Texts( - TranslationBase.of(context).pharmacyServiceTermsCondition, - fontWeight: FontWeight.normal, fontSize: 13, - ), - )), - InkWell( - child: Icon( - Icons.info, - size: 20, - color: Colors.grey[600], - ), - onTap: () { - onInfoClick(); - }, - ), - ], +_getNormalText(text, {bool isBold = false, bool isTotal = false}) { + return Text( + text, + style: TextStyle( + fontSize: isBold + ? isTotal + ? 16 + : 12 + : 11, + letterSpacing: -0.5, + color: isBold ? Color(0xff2E303A) : Color(0xff575757), + fontWeight: isTotal ? FontWeight.bold : FontWeight.w600, ), ); } -Widget _payNow(BuildContext context, {@required VoidCallback onPayNowClick}) { - bool isPayNowAQctive = (_agreeTerms && (_selectedPaymentMethod != null)); - - return Padding( - padding: const EdgeInsets.all(5), - child: Container( - child: Row( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Padding( - padding: const EdgeInsets.all(5), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts('${TranslationBase.of(context).subtotal}: ${'999.9'} ${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}', heightFactor: 1.5, fontWeight: FontWeight.bold, color: Colors.grey, fontSize: 8), - Padding( - padding: const EdgeInsets.all(3), - child: Container( - height: 0.25, - width: 120, - color: Colors.grey[300], - ), - ), - Texts('${TranslationBase.of(context).total}: 999.99 ${TranslationBase.of(context).sar}', - heightFactor: 1.5, fontWeight: FontWeight.bold, color: Colors.black54, fontSize: 15) - ], - ), - ), - Expanded(child: Container()), - RaisedButton( - child: Texts( - TranslationBase.of(context).payNow, - fontSize: 15, color: Colors.white, fontWeight: FontWeight.bold, - ), - padding: EdgeInsets.only(top: 5, bottom: 5, left: 0, right: 0), - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5), side: BorderSide(color: Theme.of(context).primaryColor, width: 0.5)), - color: Theme.of(context).primaryColor, - onPressed: isPayNowAQctive ? onPayNowClick : null, - ), - ], - )), - ); -} -// ------------------- - Widget _cartItemDeleteContainer() { - _animationController.duration = Duration(milliseconds: 500); - _animationController.repeat(reverse: true); + _animationController!.duration = Duration(milliseconds: 500); + _animationController!.repeat(reverse: true); return FadeTransition( - opacity: _animationController, + opacity: _animationController!, child: Padding( padding: const EdgeInsets.all(5), child: Container( - decoration: BoxDecoration( - color: Colors.red, - boxShadow: [ - BoxShadow( - color: Colors.grey[500], - blurRadius: 2, - spreadRadius: 1, - ), - ], - borderRadius: BorderRadius.all(Radius.circular(5)), + decoration: BoxDecoration( + color: Colors.red, + boxShadow: [ + BoxShadow( + color: Colors.grey[500]!, + blurRadius: 2, + spreadRadius: 1, + ), + ], + borderRadius: BorderRadius.all(Radius.circular(5)), ), child: Center( child: Texts( "Deleting...", - fontWeight: FontWeight.normal, - fontSize: 15, - color: Colors.white, + fontWeight: FontWeight.normal, + fontSize: 15, + color: Colors.white, )), ), ), diff --git a/lib/pages/packages_offers/OfferAndPackagesPage.dart b/lib/pages/packages_offers/OfferAndPackagesPage.dart index c09e10ea..bad29b62 100644 --- a/lib/pages/packages_offers/OfferAndPackagesPage.dart +++ b/lib/pages/packages_offers/OfferAndPackagesPage.dart @@ -1,240 +1,240 @@ -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/CreateCustomerRequestModel.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/PackagesCustomerResponseModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCategoriesResponseModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/offers_stores_response_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/packages_offers/PackagesOffersViewModel.dart'; -import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/order_model_view_model.dart'; -import 'package:diplomaticquarterapp/locator.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; +import 'package:diplomaticquarterapp/models/Authentication/select_device_imei_res.dart'; +import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/h2o/h20_setting.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/pages/packages_offers/packages_offers_tab_pager.dart'; +import 'package:diplomaticquarterapp/pages/packages_offers/packages_orders_history.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/navigation_service.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart' as utils; -import 'package:diplomaticquarterapp/widgets/Loader/gif_loader_container.dart'; -import 'package:diplomaticquarterapp/widgets/carousel_indicator/carousel_indicator.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; -import 'package:diplomaticquarterapp/widgets/loadings/ShimmerLoading.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/radio_selection_dialog.dart'; import 'package:diplomaticquarterapp/widgets/offers_packages/PackagesOfferCard.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:flutter/rendering.dart'; -import 'package:flutter_material_pickers/flutter_material_pickers.dart'; - -dynamic languageID; +import 'package:provider/provider.dart'; class PackagesHomePage extends StatefulWidget { - dynamic offersModel; - PackagesHomePage({@required this.offersModel}); + final AuthenticatedUser user; + + PackagesHomePage(this.user); @override _PackagesHomePageState createState() => _PackagesHomePageState(); - } -class _PackagesHomePageState extends State with AfterLayoutMixin{ - getLanguageID() async { - languageID = await sharedPref.getString(APP_LANGUAGE); - } +class _PackagesHomePageState extends State { + ProjectViewModel? projectViewModel; @override void initState() { super.initState(); - getLanguageID(); - } - - @override - void afterFirstLayout(BuildContext context) async{ - viewModel.service.loadOffersPackagesDataForMainPage(context: context, completion: (){ - setState((){}); + WidgetsBinding.instance.addPostFrameCallback((timeStamp) { + viewModel!.service.patientUser = widget.user; + viewModel!.service.loadOffersPackagesDataForMainPage( + context: context, + completion: () { + setState(() {}); + }); }); } // Controllers var _searchTextController = TextEditingController(); - var _filterTextController = TextEditingController(); - var _carouselController = CarouselController(); - - int carouselIndicatorIndex = 0; - CarouselSlider _bannerCarousel; - TextField _textFieldSearch; - TextField _textFieldFilterSelection; + ListView? _listViewLatestOffers; + ListView? _listViewBestSeller; - ListView _listViewLatestOffers; - ListView _listViewBestSeller; + PackagesViewModel? viewModel; - PackagesViewModel viewModel; - - onCartClick(){ - if (viewModel.service.customer == null){ + onCartClick() { + if (viewModel!.service.customer == null) { utils.Utils.showErrorToast("Cart is empty for your current session"); return; } - Navigator.of(context).push( - MaterialPageRoute( - builder: (BuildContext context) => PackagesCartPage() - ) - ); + Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) => PackagesCartPage())); } 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){ - appScaffold.appBar.badgeUpdater(viewModel.service.cartItemCount); - }).catchError((error) { - utils.Utils.showErrorToast(error); + 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) {}).catchError((error) { + utils.Utils.showErrorToast(error.toString()); }); } } - AppScaffold appScaffold; + PackagesCategoriesResponseModel? selectedClinic; + OfferProject? selectedProject; + @override Widget build(BuildContext context) { + projectViewModel = Provider.of(context); return BaseView( - allowAny: true, - onModelReady: (model) => viewModel = model, - builder: (_, model, wi){ - return - appScaffold = - AppScaffold( - appBarTitle: TranslationBase.of(context).offerAndPackages, - isShowAppBar: true, - isPharmacy: false, - showPharmacyCart: false, - showHomeAppBarIcon: false, - isOfferPackages: true, - showOfferPackagesCart: true, - isShowDecPage: false, - body: ListView( - children: [ - - // Top Banner Carousel - AspectRatio( - aspectRatio: 2.2/1, - child: bannerCarousel() - ), - - Center( - child: CarouselIndicator( - activeColor: Theme.of(context).appBarTheme.color, - color: Colors.grey[300], - cornerRadius: 15, - width: 15, height: 15, - count: _bannerCarousel.itemCount, - index: carouselIndicatorIndex, - onClick: (index){ - debugPrint('onClick at ${index}'); - }, - ), - ), - - SizedBox(height: 10,), - - Padding( - padding: const EdgeInsets.all(15), - child: Column( - children: [ - // Search Textfield - searchTextField(), - - SizedBox(height: 10,), - - // Filter Selection - filterOptionSelection(), - - SizedBox(height: 20,), - - // Horizontal Scrollable Cards - Texts( - "Latest offers", - fontWeight: FontWeight.bold, - color: Colors.black87, - fontSize: 20 - ), - - // Latest Offers Horizontal Scrollable List - AspectRatio( - aspectRatio: 1.3/1, - child: LayoutBuilder(builder: (context, constraints){ - double itemContentPadding = 10; - double itemWidth = (constraints.maxWidth/2) - (itemContentPadding*2); - return latestOfferListView(itemWidth: itemWidth, itemContentPadding: itemContentPadding); - }), - ), - - SizedBox(height: 10,), - - Texts( - "Best sellers", - fontWeight: FontWeight.bold, - color: Colors.black87, - fontSize: 20 - ), - - - // Best Seller Horizontal Scrollable List - AspectRatio( - aspectRatio: 1.3/1, - child: LayoutBuilder(builder: (context, constraints){ - double itemContentPadding = 10; // 10 is content padding in each item - double itemWidth = (constraints.maxWidth/2) - (itemContentPadding*2 /* 2 = LeftRight */); - return bestSellerListView(itemWidth: itemWidth, itemContentPadding: itemContentPadding); - }), - ) - - ],), - ), - ], + allowAny: true, + onModelReady: (model) => viewModel = model, + builder: (_, model, wi) { + return Column( + children: [ + Expanded( + child: ListView( + padding: EdgeInsets.only(top: 21, bottom: 21), + physics: BouncingScrollPhysics(), + children: [ + if(OFFERS_VIEW_ONLY) + inputWidget(TranslationBase.of(context).search, "", _searchTextController, isInputTypeNum: false), + SizedBox(height: 12), + Padding( + padding: const EdgeInsets.only(left: 21, right: 21), + child: CommonDropDownView(TranslationBase.of(context).browseOffersByProject, selectedProject?.name ?? TranslationBase.of(context).selectProject, () => showHospitalSelectionList()) + .withBorderedContainer, ), - ) - .setOnAppBarCartClick(onCartClick); - } + SizedBox(height: 12), + Padding( + padding: const EdgeInsets.only(left: 21, right: 21), + child: CommonDropDownView(TranslationBase.of(context).browseOffers, selectedClinic?.name ?? TranslationBase.of(context).selectClinic, () => showClinicSelectionList()) + .withBorderedContainer, + ), + SizedBox(height: 12), + Container( + width: double.infinity, + height: MediaQuery.of(context).size.width * 0.8, + child: ListView.separated( + scrollDirection: Axis.horizontal, + shrinkWrap: true, + physics: BouncingScrollPhysics(), + padding: EdgeInsets.only(left: 21, right: 21), + itemCount: viewModel!.bestSellerList.length, + separatorBuilder: (context, index) { + return mWidth(9.0); + }, + itemBuilder: (BuildContext context, int index) { + return PackagesItemCard( + itemModel: viewModel!.bestSellerList[index], + onCartClick: OFFERS_VIEW_ONLY! ? onProductCartClick : (PackagesResponseModel){}, itemContentPadding: null, + ); + }, + ), + ), + SizedBox(height: 12), + Container( + width: double.infinity, + height: MediaQuery.of(context).size.width * 0.8, + child: ListView.separated( + scrollDirection: Axis.horizontal, + shrinkWrap: true, + physics: BouncingScrollPhysics(), + padding: EdgeInsets.only(left: 21, right: 21), + itemCount: viewModel!.latestOffersList.length, + separatorBuilder: (context, index) { + return mWidth(9.0); + }, + itemBuilder: (BuildContext context, int index) { + return PackagesItemCard( + itemModel: viewModel!.latestOffersList[index], + onCartClick: OFFERS_VIEW_ONLY ? onProductCartClick : (PackagesResponseModel){}, itemContentPadding: null, + ); + }, + ), + ), + ], + ), + ), + + if(OFFERS_VIEW_ONLY) + DefaultButton( + TranslationBase.of(context).myCart, + onCartClick, + svgIcon: "assets/images/new/cart.svg", + isTextExpanded: false, + count: viewModel?.service?.customer?.shoppingCartItems?.length ?? 0, + ).insideContainer + ], + ); + }, ); } - - + int _selectedClinic = -1; showClinicSelectionList() async { - var clinics = viewModel.service.categoryList; - if(clinics.isEmpty) { - GifLoaderDialogUtils.showMyDialog(context); - clinics = await viewModel.service.getAllCategories(OffersCategoriesRequestModel()); - GifLoaderDialogUtils.hideDialog(context); - } + var clinics = await viewModel!.service.getAllCategories(OffersCategoriesRequestModel()); + List list = [ + for (int i = 0; i < clinics.length; i++) RadioSelectionDialogModel(clinics![i].name!, i), + ]; + showDialog( + context: context, + builder: (cxt) => RadioSelectionDialog( + listData: list, + selectedIndex: _selectedClinic, + isScrollable: true, + onValueSelected: (index) async { + _selectedClinic = index; + selectedClinic = clinics[index]; + var clinicProducts = await viewModel!.service.getAllProducts(request: OffersProductsRequestModel(categoryId: selectedClinic!.id), context: context, showLoading: true); + if (clinicProducts.isNotEmpty) + Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) => ClinicPackagesPage(products: clinicProducts))); + else + utils.Utils.showErrorToast("No offers available for this clinic"); + setState(() {}); + }, + ), + ); + } + + int _selectedHospital = -1; - List options = clinics.map((e) => e.toString()).toList(); + showHospitalSelectionList() async { + GifLoaderDialogUtils.showMyDialog(context); + var hospitals = await viewModel!.service.getAllStores(); + GifLoaderDialogUtils.hideDialog(context); - showMaterialSelectionPicker( + List list = [ + for (int i = 0; i < hospitals.length; i++) RadioSelectionDialogModel(hospitals[i].name!, i), + ]; + showDialog( context: context, - title: "Select Clinic", - items: options, - selectedItem: options.first, - onChanged: (value) async { - var selectedClinic = clinics.firstWhere((element) => element.toString() == value); - var clinicProducts = await viewModel.service.getAllProducts(request: OffersProductsRequestModel(categoryId: selectedClinic.id), context: context, showLoading: true); - if(clinicProducts.isNotEmpty) - Navigator.of(context).push( - MaterialPageRoute( - builder: (BuildContext context) => ClinicPackagesPage(products: clinicProducts) - ) - ); - else - utils.Utils.showErrorToast("No offers available for this clinic"); - }, + builder: (cxt) => RadioSelectionDialog( + listData: list, + selectedIndex: _selectedHospital, + isScrollable: true, + onValueSelected: (index) async { + _selectedHospital = index; + selectedProject = hospitals[index]; + var request = OffersProductsRequestModel(storeId: selectedProject!.id); + request.sinceId = 0; + var products = await viewModel!.service.getAllProducts(request: request, context: context, showLoading: true); + if (products.isNotEmpty) + Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) => ClinicPackagesPage(products: products))); + else + utils.Utils.showErrorToast("No offers available for this clinic"); + setState(() {}); + }, + ), ); } @@ -242,177 +242,144 @@ class _PackagesHomePageState extends State with AfterLayoutMix // Main Widgets of Page //---------------------------------- - CarouselSlider bannerCarousel(){ - _bannerCarousel = CarouselSlider.builder( - carouselController: _carouselController, - itemCount: 10, - itemBuilder: (BuildContext context, int itemIndex) { - return Padding( - padding: const EdgeInsets.only(top: 10, bottom: 10, left: 15, right: 15), - child: FractionallySizedBox( - widthFactor: 1, - heightFactor: 1, - child: utils.applyShadow( - spreadRadius: 1, - blurRadius: 5, - child: InkWell( - child: ClipRRect( - borderRadius: BorderRadius.circular(10), - child: utils.Utils.loadNetworkImage(url: "https://wallpaperaccess.com/full/30103.jpg",) - ), - onTap: (){ - Navigator.of(context).push( - MaterialPageRoute( - builder: (BuildContext context) => OfferAndPackagesDetail(model: "",) - ) - ); - }, - ) - ), - ), + Widget latestOfferListView({required double itemWidth, required double itemContentPadding}) { + return _listViewLatestOffers = ListView.separated( + scrollDirection: Axis.horizontal, + shrinkWrap: true, + itemCount: viewModel!.bestSellerList.length, + itemBuilder: (BuildContext context, int index) { + return PackagesItemCard( + itemWidth: itemWidth, + itemContentPadding: itemContentPadding, + itemModel: viewModel!.bestSellerList[index], + onCartClick: onProductCartClick, ); }, - options: CarouselOptions( - autoPlayInterval: Duration(milliseconds: 3500), - enlargeStrategy: CenterPageEnlargeStrategy.scale, - enlargeCenterPage: true, - autoPlay: false, - autoPlayCurve: Curves.fastOutSlowIn, - enableInfiniteScroll: true, - autoPlayAnimationDuration: Duration(milliseconds: 1500), - viewportFraction: 1, - onPageChanged: (page, reason){ - setState(() { - carouselIndicatorIndex = page; - }); - }, - ), + separatorBuilder: separator, ); - return _bannerCarousel; } - TextField searchTextField(){ - return _textFieldSearch = - TextField( - controller: _searchTextController, - decoration: InputDecoration( - contentPadding: EdgeInsets.only(top: 0.0, bottom: 0.0, left: 10, right: 10), - enabledBorder: OutlineInputBorder( - borderSide: BorderSide( width: 0.5, color: Colors.grey), - borderRadius: const BorderRadius.all( - const Radius.circular(10.0), - ), - ), - focusedBorder: OutlineInputBorder( - borderSide: BorderSide( width: 1, color: Colors.grey), - borderRadius: const BorderRadius.all( - const Radius.circular(10.0), - ), - ), - filled: true, - fillColor: Colors.white, - hintText: "Search", - hintStyle: TextStyle(color: Colors.grey[350], fontWeight: FontWeight.bold), - suffixIcon: IconButton( - onPressed: (){ - // viewModel.search(text: _searchTextController.text); - }, - icon: Icon(Icons.search_rounded, size: 35,), - ), - ), + Widget bestSellerListView({required double itemWidth, required double itemContentPadding}) { + return _listViewLatestOffers = ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: viewModel!.bestSellerList.length, + itemBuilder: (BuildContext context, int index) { + return PackagesItemCard( + itemWidth: itemWidth, + itemContentPadding: itemContentPadding, + itemModel: viewModel!.bestSellerList[index], + onCartClick: onProductCartClick, ); - - } - - Widget filterOptionSelection(){ - _textFieldFilterSelection = - TextField( - enabled: false, - controller: _searchTextController, - decoration: InputDecoration( - contentPadding: EdgeInsets.only(top: 0.0, bottom: 0.0, left: 10, right: 10), - border: OutlineInputBorder( - borderSide: BorderSide(color: Colors.grey, width: 1), - borderRadius: const BorderRadius.all( - const Radius.circular(10.0), - ), - ), - disabledBorder: OutlineInputBorder( - borderSide: BorderSide( width: 0.5, color: Colors.grey), - borderRadius: const BorderRadius.all( - const Radius.circular(10.0), - ), - ), - focusedBorder: OutlineInputBorder( - borderRadius: const BorderRadius.all( - const Radius.circular(10.0), - ), - ), - filled: true, - fillColor: Colors.white, - hintText: "Browse offers by Clinic", - hintStyle: TextStyle(color: Colors.grey[350], fontWeight: FontWeight.bold), - suffixIcon: IconButton( - onPressed: (){ - showClinicSelectionList(); - }, - icon: Icon(Icons.keyboard_arrow_down_rounded, size: 35, color: Colors.grey,), - ), - ), - ); - - return InkWell( - child: _textFieldFilterSelection, - onTap: (){ - showClinicSelectionList(); }, + separatorBuilder: separator, ); - } - Widget latestOfferListView({@required double itemWidth, @required double itemContentPadding}){ - return _listViewLatestOffers = - ListView.separated( - scrollDirection: Axis.horizontal, - itemCount: viewModel.bestSellerList.length, - itemBuilder: (BuildContext context, int index) { - return PackagesItemCard(itemWidth: itemWidth, itemContentPadding: itemContentPadding, itemModel: viewModel.bestSellerList[index], onCartClick: onProductCartClick,); - }, - separatorBuilder: separator, - ); - + Widget separator(BuildContext context, int index) { + return Container( + width: 1, + decoration: BoxDecoration( + gradient: + LinearGradient(begin: Alignment(-1.0, -2.0), end: Alignment(1.0, 4.0), colors: [Colors.grey, Colors.grey[100]!, Colors.grey[200]!, Colors.grey[300]!, Colors.grey[400]!, Colors.grey[500]!])), + ); } - Widget bestSellerListView({@required double itemWidth, @required double itemContentPadding}){ - return _listViewLatestOffers = - ListView.separated( - scrollDirection: Axis.horizontal, - itemCount: viewModel.bestSellerList.length, - itemBuilder: (BuildContext context, int index) { - return PackagesItemCard(itemWidth: itemWidth, itemContentPadding: itemContentPadding, itemModel: viewModel.bestSellerList[index], onCartClick: onProductCartClick,); - }, - separatorBuilder: separator, - ); + 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, + ); + }); + } } - - Widget separator(BuildContext context, int index){ + Widget inputWidget(String _labelText, String _hintText, TextEditingController _controller, + {VoidCallback? suffixTap, bool isEnable = true, bool hasSelection = false, int? lines, bool isInputTypeNum = false}) { return Container( - width: 1, + padding: EdgeInsets.only(left: 16, right: 16, bottom: 15, top: 15), + margin: const EdgeInsets.only(left: 21, right: 21), + alignment: Alignment.center, decoration: BoxDecoration( - gradient: LinearGradient( - begin: Alignment(-1.0, -2.0), - end: Alignment(1.0, 4.0), - colors: [ - Colors.grey, - Colors.grey[100], - Colors.grey[200], - Colors.grey[300], - Colors.grey[400], - Colors.grey[500] - ] - )), + 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, + ), + contentPadding: EdgeInsets.zero, + border: InputBorder.none, + focusedBorder: InputBorder.none, + enabledBorder: InputBorder.none, + ), + ), + ], + ), + ), + Icon(Icons.search_outlined), + ], + ), + ), ); } } diff --git a/lib/pages/packages_offers/PackageOrderCompletedPage.dart b/lib/pages/packages_offers/PackageOrderCompletedPage.dart index 73baca4b..453de1fc 100644 --- a/lib/pages/packages_offers/PackageOrderCompletedPage.dart +++ b/lib/pages/packages_offers/PackageOrderCompletedPage.dart @@ -1,6 +1,7 @@ import 'package:diplomaticquarterapp/core/viewModels/packages_offers/PackagesOffersViewModel.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/custom_text_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -9,29 +10,29 @@ import 'package:flutter_svg/svg.dart'; dynamic languageID; -class PackageOrderCompletedPage extends StatelessWidget{ - double buttonHeight; - double buttonWidth; - Widget icon; - String heading; - String title; - String subTitle; - String actionTitle; +class PackageOrderCompletedPage extends StatelessWidget { + double? buttonHeight; + double? buttonWidth; + Widget? icon; + String? heading; + String? title; + String? subTitle; + String? actionTitle; - PackageOrderCompletedPage({this.buttonWidth, this.buttonHeight, @required this.heading, @required this.title, @required this.subTitle, this.actionTitle }); + PackageOrderCompletedPage({this.buttonWidth, this.buttonHeight, this.heading, this.title, this.subTitle, this.actionTitle}); @override Widget build(BuildContext context) { - assert((heading != null || title != null || subTitle != null), "Data missing in properties"); + assert((heading != null || title != null || subTitle != null), "Data missing in properties"); - buttonWidth = buttonWidth ?? MediaQuery.of(context).size.width/2; + buttonWidth = buttonWidth ?? MediaQuery.of(context).size.width / 2; buttonHeight = buttonHeight ?? 40; actionTitle = actionTitle ?? TranslationBase.of(context).done; return BaseView( allowAny: true, - onModelReady: (model){}, - builder: (_, model, wi){ + onModelReady: (model) {}, + builder: (_, model, wi) { return Container( color: Colors.white, child: Padding( @@ -39,98 +40,87 @@ class PackageOrderCompletedPage extends StatelessWidget{ child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - AspectRatio( - aspectRatio: 1.2/1, - child: - iconWidget(context), + aspectRatio: 1.2 / 1, + child: iconWidget(context), ), - headingWidget(context), - - AspectRatio( - aspectRatio: 1/1, + aspectRatio: 1 / 1, child: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ titleWidget(context), - SizedBox(height: 20,), + SizedBox( + height: 20, + ), subTitleWidget(context), - SizedBox(height: 50,), + SizedBox( + height: 50, + ), actionWidget(context) ], ), ), ) - ], ), ), ); - } - ); + }); } - Widget iconWidget(BuildContext context){ + Widget iconWidget(BuildContext context) { return Padding( padding: const EdgeInsets.all(50), - child: icon ?? SvgPicture.asset( - "assets/images/svg/success.svg", - semanticsLabel: 'icon' - ), + child: icon ?? SvgPicture.asset("assets/images/svg/success.svg", semanticsLabel: 'icon'), ); } Widget headingWidget(BuildContext context) => Texts( - heading, - textAlign: TextAlign.center, - maxLines: 1, - color: Theme.of(context).primaryColor, - fontSize: 35.0, - fontWeight: FontWeight.bold, - ); + heading, + textAlign: TextAlign.center, + maxLines: 1, + color: Theme.of(context).primaryColor, + fontSize: 35.0, + fontWeight: FontWeight.bold, + ); Widget titleWidget(BuildContext context) => Texts( - title, - textAlign: TextAlign.center, - maxLines: 2, - color: Theme.of(context).primaryColor, - fontSize: 25.0, - fontWeight: FontWeight.w200, - ); + title, + textAlign: TextAlign.center, + maxLines: 2, + color: Theme.of(context).primaryColor, + fontSize: 25.0, + fontWeight: FontWeight.w200, + ); Widget subTitleWidget(BuildContext context) => Texts( - subTitle, - textAlign: TextAlign.center, - maxLines: 2, - color: Theme.of(context).primaryColor, - fontSize: 15.0, - fontWeight: FontWeight.normal, - ); - + subTitle, + textAlign: TextAlign.center, + maxLines: 2, + color: Theme.of(context).primaryColor, + fontSize: 15.0, + fontWeight: FontWeight.normal, + ); Widget actionWidget(BuildContext context) => Container( - height: buttonHeight, - width: buttonWidth, - child: ElevatedButton( - style: ElevatedButton.styleFrom( - - shape:RoundedRectangleBorder( - borderRadius: new BorderRadius.circular(buttonHeight/2), - ) - ), - child: Texts( - actionTitle, + height: buttonHeight, + width: buttonWidth, + child: CustomTextButton( + shape: RoundedRectangleBorder( + borderRadius: new BorderRadius.circular(buttonHeight! / 2), + ), + child: Texts( + actionTitle, color: Colors.white, fontSize: 18.0, fontWeight: FontWeight.normal, - ), - onPressed: (){ - Navigator.of(context).pop(); - }, - ), - ); - + ), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ); } diff --git a/lib/pages/packages_offers/packages_offers_tab_pager.dart b/lib/pages/packages_offers/packages_offers_tab_pager.dart new file mode 100644 index 00000000..401d7852 --- /dev/null +++ b/lib/pages/packages_offers/packages_offers_tab_pager.dart @@ -0,0 +1,90 @@ +import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/pages/packages_offers/OfferAndPackagesPage.dart'; +import 'package:diplomaticquarterapp/pages/packages_offers/packages_orders_history.dart'; +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'; + +bool OFFERS_VIEW_ONLY = false; +class PackagesOfferTabPage extends StatefulWidget{ + + AuthenticatedUser user; + PackagesOfferTabPage(this.user); + + @override + State createState() => PackagesOfferTabPageState(); +} + +class PackagesOfferTabPageState extends State with SingleTickerProviderStateMixin{ + TabController? _tabController; + ProjectViewModel? _projectViewModel; + + @override + void initState() { + _tabController = TabController(length: 2, vsync: this); + super.initState(); + } + + @override + Widget build(BuildContext context) { + _projectViewModel = Provider.of(context); + return 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, + backgroundColor: Color(0xfff7f7f7), + showPharmacyCart: false, + isOfferPackages: true, + showOfferPackagesCart: false, + isShowDecPage: false, + showNewAppBar: true, + showNewAppBarTitle: true, + body: Column( + children: [ + SizedBox( + height: OFFERS_VIEW_ONLY ? null : 0, + child: TabBar( + controller: _tabController, + indicatorWeight: 3.0, + indicatorSize: TabBarIndicatorSize.tab, + labelColor: Color(0xff2B353E), + unselectedLabelColor: Color(0xff575757), + labelPadding: EdgeInsets.only(top: 15, bottom: 13, 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: [Text(TranslationBase.of(context).offerAndPackages), Text(TranslationBase.of(context).orderLog)], + ), + ), + Expanded( + child: TabBarView( + physics: OFFERS_VIEW_ONLY ? BouncingScrollPhysics() : NeverScrollableScrollPhysics(), + controller: _tabController, + children: [ + PackagesHomePage(widget.user), + PackagesOrdersHistory() + ], + ), + ) + ], + ), + ); + } + +} diff --git a/lib/pages/packages_offers/packages_orders_history.dart b/lib/pages/packages_offers/packages_orders_history.dart new file mode 100644 index 00000000..ea9ba403 --- /dev/null +++ b/lib/pages/packages_offers/packages_orders_history.dart @@ -0,0 +1,98 @@ +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCartItemsResponseModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart'; +import 'package:diplomaticquarterapp/core/viewModels/packages_offers/PackagesOffersViewModel.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.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/widgets/Loader/gif_loader_container.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/ConfirmWithMessageDialog.dart'; +import 'package:diplomaticquarterapp/widgets/offers_packages/PackagesOrderHistoryItemCard.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'; + +import 'OfferAndPackageDetailPage.dart'; +class PackagesOrdersHistory extends StatefulWidget{ + @override + State createState() => PackagesOrdersHistorySatate(); +} + +class PackagesOrdersHistorySatate extends State{ + ProjectViewModel? projectViewModel; + PackagesViewModel? packagesViewModel; + + List? orders; + + @override + void initState() { + Future.delayed(Duration(milliseconds: 200)).then((value) async{ + final orders_ = await packagesViewModel!.service.orderHistory(context: context); + setState(() => orders = orders_ ?? []); + }); + } + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + return BaseView( + allowAny: true, + onModelReady: (model) => packagesViewModel = model, + builder: (_, model, wi) { + return content(context); + } + ); + } + + Widget content(BuildContext context){ + if(orders == null){ + return SizedBox(); + }else if(orders!.isEmpty){ + return getNoDataWidget(context); + }else { + return ListView.separated( + padding: EdgeInsets.all(20), + itemCount: orders!.length, + itemBuilder: (ctx, idx) => item(ctx, order: orders![idx]), + separatorBuilder: (ctx, idx) => SizedBox(height: 10), + ); + } + } + + Widget item(BuildContext context, {required PackagesResponseModel order}){ + return InkWell( + child: PackagesOrderHistoryItemCard(itemModel: order, viewModel: packagesViewModel!), + onTap: (){ + final detailPage = OfferAndPackagesDetail(itemModel: order, onCartClick: (PackagesResponseModel){})..showAddToCartFooter = false; + Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) => detailPage)); + }, + ); + } + + void showConfirmMessage(BuildContext context, {required PackagesResponseModel order}){ + showDialog( + context: context, + builder: (cxt) => ConfirmWithMessageDialog( + message: TranslationBase.of(context).cancelOrderMsg, + onTap: () { + }, + ), + ); + return; + } + + Color color(int status){ + if (status == 1) { //pending + return Color(0xffCC9B14); + } else if (status == 2) { //processing + return Color(0xff2E303A); + } else if (status == 3) { //completed + return Color(0xff359846); + } else if (status == 4 || status == 6 || status == 7) { //cancel // Rejected + return Color(0xffD02127); + } + return Colors.transparent; + } +} \ No newline at end of file diff --git a/lib/pages/parent_categorise_page.dart b/lib/pages/parent_categorise_page.dart index a7e43241..83196fab 100644 --- a/lib/pages/parent_categorise_page.dart +++ b/lib/pages/parent_categorise_page.dart @@ -1,40 +1,55 @@ -import 'package:diplomaticquarterapp/config/size_config.dart'; +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/pharmacy/categorise_parent_model.dart'; +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/core/viewModels/project_view_model.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/product_detail.dart'; +import 'package:diplomaticquarterapp/locator.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/product-detail.dart'; +import 'package:diplomaticquarterapp/pages/sub_categories_modalsheet.dart'; import 'package:diplomaticquarterapp/pages/sub_categorise_page.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/buttons/button.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'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/others/entity_checkbox_list.dart'; import 'package:diplomaticquarterapp/widgets/others/network_base_view.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_rating_bar/flutter_rating_bar.dart'; import 'package:provider/provider.dart'; +import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'base/base_view.dart'; class ParentCategorisePage extends StatefulWidget { - String id; - String titleName; + String? id; + String? titleName; + + AuthenticatedUserObject authenticatedUserObject = locator(); ParentCategorisePage({this.id, this.titleName}); @override - _ParentCategorisePageState createState() => - _ParentCategorisePageState(id: id, titleName: titleName); + _ParentCategorisePageState createState() => _ParentCategorisePageState(id: id, titleName: titleName); } class _ParentCategorisePageState extends State { - String id; - String titleName; + String? id; + String? titleName; + final dynamic productID; - _ParentCategorisePageState({this.id, this.titleName}); + _ParentCategorisePageState({ + this.id, + this.titleName, + this.productID, + }); - Map values = {'huusam': false, 'ali': false, 'noor': false}; bool checkedBrands = false; bool checkedCategorise = false; String categoriseName = "Personal Care"; @@ -46,26 +61,48 @@ class _ParentCategorisePageState extends State { size: 29.0, ); - List entityList = List(); - List entityListBrands = List(); + int pageIndex = 1; + + List entityList = []; + List entityListBrands = []; + + RefreshController controller = RefreshController(); @override Widget build(BuildContext context) { TextEditingController minField = TextEditingController(); TextEditingController maxField = TextEditingController(); ProjectViewModel projectViewModel = Provider.of(context); + ProjectViewModel projectProvider = Provider.of(context); return BaseView( - onModelReady: (model) => model.getCategoriseParent(i: id), - builder: (BuildContext context, PharmacyCategoriseViewModel model, - Widget child) => - PharmacyAppScaffold( - appBarTitle: titleName, - isBottomBar: false, - isShowAppBar: true, - backgroundColor: Colors.white, - isShowDecPage: false, - baseViewModel: model, - body: SingleChildScrollView( + onModelReady: (model) => model.getCategoriseParent(i: id, pageIndex: pageIndex, isLoading: false, context: context), + allowAny: true, + builder: (BuildContext context, PharmacyCategoriseViewModel model, Widget? child) => AppScaffold( + isPharmacy: true, + appBarTitle: titleName!, + isBottomBar: true, + isShowAppBar: true, + backgroundColor: Colors.white, + isShowDecPage: false, + showPharmacyCart: false, + showHomeAppBarIcon: false, + baseViewModel: model, + body: SmartRefresher( + enablePullDown: false, + controller: controller, + enablePullUp: true, + onLoading: () async { + setState(() { + ++pageIndex; + }); + await model.getParentProducts(pageIndex: pageIndex, i: id, isLoading: true, context: context); + if (model.state != ViewState.BusyLocal && pageIndex < 5) { + controller.loadComplete(); + } else { + controller.loadFailed(); + } + }, + child: SingleChildScrollView( child: Container( child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -101,91 +138,33 @@ class _ParentCategorisePageState extends State { Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Padding( - padding: EdgeInsets.all(10.0), - child: InkWell( - child: Container( - child: Texts( - 'View All Categories', - fontWeight: FontWeight.w300, + InkWell( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: EdgeInsets.all(10.0), + child: Container( + child: Texts( + TranslationBase.of(context).viewCategorise, +// 'View All Categories', + fontWeight: FontWeight.w300, + ), ), ), - onTap: () { - showModalBottomSheet( - isScrollControlled: true, - context: context, - builder: (BuildContext context) { - return Container( - // height: MediaQuery.of(context) - // .size - // .height * - // 0.89, - color: Colors.white, - child: Center( - child: ListView.builder( - scrollDirection: - Axis.vertical, - itemCount: model - .categoriseParent.length, - itemBuilder: - (BuildContext context, - int index) { - return Container( - child: Padding( - padding: - EdgeInsets.all(4.0), - child: InkWell( - child: Column( - crossAxisAlignment: - CrossAxisAlignment - .start, - children: [ - Texts(model - .categoriseParent[ - index] - .name), - Divider( - thickness: 0.6, - color: Colors - .black12, - ) - ], - ), - onTap: () { - Navigator.push( - context, - FadePage( - page: - SubCategorisePage( - title: model - .categoriseParent[ - index] - .name, - id: model - .categoriseParent[ - index] - .id, - parentId: id, - )), - ); - }, - ), - ), - ); - }), - ), - ); - }, - ); - }, - ), + Icon(Icons.arrow_forward) + ], ), - Icon(Icons.arrow_forward) - ], - ), + onTap: () { + Navigator.push( + context, + FadePage( + page: SubCategoriseModalsheet( +// id: model.categorise[0].id, +// titleName: model.categorise[0].name, + )), + ); + }), Divider( thickness: 1.0, color: Colors.grey.shade400, @@ -201,28 +180,22 @@ class _ParentCategorisePageState extends State { child: Center( child: ListView.builder( scrollDirection: Axis.horizontal, - itemCount: model.categoriseParent.length > 8 - ? 8 - : model.categoriseParent.length, + itemCount: model.categoriseParent.length > 8 ? 8 : model.categoriseParent.length, itemBuilder: (BuildContext context, int index) { return Padding( - padding: - EdgeInsets.symmetric(horizontal: 8.0), + padding: EdgeInsets.symmetric(horizontal: 8.0), child: InkWell( child: Column( - crossAxisAlignment: - CrossAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, children: [ Padding( - padding: EdgeInsets.symmetric( - horizontal: 13.0), + padding: EdgeInsets.symmetric(horizontal: 13.0), child: Container( height: 60.0, width: 65.0, decoration: BoxDecoration( shape: BoxShape.circle, - color: Colors.orange.shade200 - .withOpacity(0.45), + color: Colors.orange.shade200.withOpacity(0.45), ), child: Center( child: Icon( @@ -233,23 +206,14 @@ class _ParentCategorisePageState extends State { ), ), Container( - width: MediaQuery.of(context) - .size - .width * - 0.197, + width: MediaQuery.of(context).size.width * 0.197, // height: MediaQuery.of(context) // .size // .height * // 0.08, child: Center( child: Texts( - projectViewModel.isArabic - ? model - .categoriseParent[index] - .namen - : model - .categoriseParent[index] - .name, + projectViewModel.isArabic ? model.categoriseParent[index].namen : model.categoriseParent[index].name, fontSize: 13.4, fontWeight: FontWeight.w600, maxLines: 3, @@ -263,10 +227,8 @@ class _ParentCategorisePageState extends State { context, FadePage( page: SubCategorisePage( - title: model - .categoriseParent[index].name, - id: model - .categoriseParent[index].id, + title: projectViewModel.isArabic ? model.categoriseParent[index].namen : model.categoriseParent[index].name, + id: model.categoriseParent[index].id, parentId: id, )), ); @@ -298,7 +260,7 @@ class _ParentCategorisePageState extends State { width: 10.0, ), Texts( - 'Refine', + TranslationBase.of(context).refine, fontWeight: FontWeight.w600, ), ], @@ -312,21 +274,16 @@ class _ParentCategorisePageState extends State { initialChildSize: 0.95, maxChildSize: 0.95, minChildSize: 0.9, - builder: (BuildContext context, - ScrollController scrollController) { + builder: (BuildContext context, ScrollController scrollController) { return SingleChildScrollView( controller: scrollController, child: Container( color: Colors.white, - height: MediaQuery.of(context) - .size - .height * - 1.95, + height: MediaQuery.of(context).size.height * 1.95, child: Column( children: [ Padding( - padding: - EdgeInsets.all(8.0), + padding: EdgeInsets.all(8.0), child: Row( children: [ Icon( @@ -336,24 +293,24 @@ class _ParentCategorisePageState extends State { width: 10.0, ), Texts( - 'Refine', - fontWeight: - FontWeight.w600, + TranslationBase.of(context).refine, +// 'Refine', + + fontWeight: FontWeight.w600, ), SizedBox( width: 250.0, ), InkWell( child: Texts( - 'Close', +// 'Close', + TranslationBase.of(context).closeIt, color: Colors.red, - fontWeight: - FontWeight.w600, + fontWeight: FontWeight.w600, fontSize: 15.0, ), onTap: () { - Navigator.pop( - context); + Navigator.pop(context); }, ), ], @@ -366,37 +323,22 @@ class _ParentCategorisePageState extends State { Column( children: [ ExpansionTile( - title: - Texts('Categorise'), + title: Texts(TranslationBase.of(context).group), children: [ ProcedureListWidget( model: model, - masterList: model - .categoriseParent, - removeHistory: - (item) { + masterList: model.categoriseParent, + removeHistory: (item) { setState(() { - entityList - .remove( - item); + entityList.remove(item); }); }, - addHistory: - (history) { + addHistory: (history) { setState(() { - entityList.add( - history); + entityList.add(history); }); }, - addSelectedHistories: - () { - //TODO build your fun herr - // widget.addSelectedHistories(); - }, - isEntityListSelected: - (master) => - isEntityListSelected( - master), + isEntityListSelected: (master) => isEntityListSelected(master), ) ], ), @@ -405,37 +347,22 @@ class _ParentCategorisePageState extends State { color: Colors.black12, ), ExpansionTile( - title: Texts('Brands'), + title: Texts(TranslationBase.of(context).brands), children: [ ProcedureListWidget( model: model, - masterList: model - .brandsList, - removeHistory: - (item) { + masterList: model.brandsList, + removeHistory: (item) { setState(() { - entityListBrands - .remove( - item); + entityListBrands.remove(item); }); }, - addHistory: - (history) { + addHistory: (history) { setState(() { - entityListBrands - .add( - history); + entityListBrands.add(history); }); }, - addSelectedHistories: - () { - //TODO build your fun herr - // widget.addSelectedHistories(); - }, - isEntityListSelected: - (master) => - isEntityListSelectedBrands( - master), + isEntityListSelected: (master) => isEntityListSelectedBrands(master), ) ], ), @@ -444,66 +371,43 @@ class _ParentCategorisePageState extends State { color: Colors.black12, ), ExpansionTile( - title: Texts('Price'), + title: Texts(TranslationBase.of(context).price), children: [ Container( - color: Color( - 0xffEEEEEE), + color: Color(0xffEEEEEE), child: Row( - mainAxisAlignment: - MainAxisAlignment - .spaceAround, + mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ Column( - mainAxisAlignment: - MainAxisAlignment - .start, + mainAxisAlignment: MainAxisAlignment.start, children: [ - Texts( - 'Min'), + Texts(TranslationBase.of(context).min), Container( - color: Colors - .white, - width: - 200, - height: - 40, - child: - TextFormField( - decoration: - InputDecoration( - border: - OutlineInputBorder(), + color: Colors.white, + width: 200, + height: 40, + child: TextFormField( + decoration: InputDecoration( + border: OutlineInputBorder(), ), - controller: - minField, + controller: minField, ), ), ], ), Column( - mainAxisAlignment: - MainAxisAlignment - .start, + mainAxisAlignment: MainAxisAlignment.start, children: [ - Texts( - 'Max'), + Texts(TranslationBase.of(context).max), Container( - color: Colors - .white, - width: - 200, - height: - 40, - child: - TextFormField( - decoration: - InputDecoration( - border: - OutlineInputBorder(), + color: Colors.white, + width: 200, + height: 40, + child: TextFormField( + decoration: InputDecoration( + border: OutlineInputBorder(), ), - controller: - maxField, + controller: maxField, ), ), ], @@ -518,82 +422,65 @@ class _ParentCategorisePageState extends State { color: Colors.black12, ), SizedBox( - height: MediaQuery.of( - context) - .size - .height * - 0.4, + height: MediaQuery.of(context).size.height * 0.4, ), Padding( - padding: - EdgeInsets.all(8.0), + padding: EdgeInsets.all(8.0), child: Row( - mainAxisAlignment: - MainAxisAlignment - .spaceEvenly, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ Container( - width: 100, + width: 150, child: Button( - label: 'Reset', - backgroundColor: - Colors.red, + label: TranslationBase.of(context).reset, + backgroundColor: Colors.red, + onTap: () { + setState(() { + entityList.clear(); + entityListBrands.clear(); + }); + minField.clear(); + maxField.clear(); + }, ), ), SizedBox( - width: 30, + width: 10, ), Container( - width: 200, + width: 150, child: Button( - onTap: () { - String - categoriesId = - ""; - for (CategoriseParentModel category - in entityList) { - if (categoriesId == - "") { - categoriesId = - category - .id; + onTap: () async { + String categoriesId = ""; + for (CategoriseParentModel category in entityList) { + if (categoriesId == "") { + categoriesId = category.id!; } else { - categoriesId = - "$categoriesId,${category.id}"; + categoriesId = "$categoriesId,${category.id}"; } } - String - brandIds = - ""; - for (CategoriseParentModel brand - in entityListBrands) { - if (brandIds == - "") { - brandIds = - brand - .id; + String brandIds = ""; + for (CategoriseParentModel brand in entityListBrands) { + if (brandIds == "") { + brandIds = brand.id!; } else { - brandIds = - "$brandIds,${brand.id}"; + brandIds = "$brandIds,${brand.id}"; } } - model.getFilteredProducts( - min: minField - .text - .toString(), - max: maxField - .text - .toString(), - categoryId: - categoriesId, - brandId: - brandIds); + GifLoaderDialogUtils.showMyDialog(context); + + await model.getFilteredProducts( + min: minField.text.isEmpty ? "" : "&price_min=" + minField.text.toString(), + max: maxField.text.isEmpty ? "" : "&price_max=" + maxField.text.toString(), + categoryId: categoriesId, + brandId: brandIds.isEmpty ? "" : "&manufacturerids=" + brandIds); + GifLoaderDialogUtils.hideDialog(context); + + Navigator.pop(context); }, - label: 'Apply', - backgroundColor: - Colors - .green, + label: TranslationBase.of(context).apply, + backgroundColor: Colors.green, ), ), ], @@ -632,7 +519,7 @@ class _ParentCategorisePageState extends State { styleTwo = true; styleIcon = Icon( Icons.auto_awesome_mosaic, - color: Colors.blue, + color: CustomColors.green, size: 29.0, ); } else { @@ -640,7 +527,7 @@ class _ParentCategorisePageState extends State { styleTwo = false; styleIcon = Icon( Icons.widgets_sharp, - color: Colors.blue, + color: CustomColors.green, size: 29.0, ); } @@ -657,223 +544,333 @@ class _ParentCategorisePageState extends State { thickness: 1.0, color: Colors.grey.shade400, ), - styleOne == true - ? Container( - height: model.parentProducts.length * - MediaQuery.of(context).size.height * - 0.15, - child: GridView.builder( - physics: NeverScrollableScrollPhysics(), - gridDelegate: - SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 2, - crossAxisSpacing: 0.5, - mainAxisSpacing: 2.0, - childAspectRatio: 0.9, - ), - itemCount: model.parentProducts.length, - itemBuilder: (BuildContext context, int index) { - return NetworkBaseView( - baseViewModel: model, - child: InkWell( - child: Card( - color: model.parentProducts[index] - .discountName != - null - ? Color(0xffFFFF00) - : Colors.white, - elevation: 0, - shape: Border( - right: BorderSide( - color: Colors.grey.shade300, - width: 1, - ), - left: BorderSide( - color: Colors.grey.shade300, - width: 1, - ), - bottom: BorderSide( - color: Colors.grey.shade300, - width: 1, - ), - top: BorderSide( - color: Colors.grey.shade300, - width: 1, - ), - ), - margin: EdgeInsets.symmetric( - horizontal: 8, - vertical: 4, - ), - child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.only( - topLeft: Radius.circular(110.0), + model.parentProducts.isNotEmpty + ? styleOne == true + ? Container( + height: model.parentProducts.length * MediaQuery.of(context).size.height * 0.15, + child: GridView.builder( + physics: NeverScrollableScrollPhysics(), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + crossAxisSpacing: 0.5, + mainAxisSpacing: 2.0, + childAspectRatio: 0.9, + ), + itemCount: model.parentProducts.length, + itemBuilder: (BuildContext context, int index) { + return NetworkBaseView( + baseViewModel: model, + child: InkWell( + child: Card( + color: model.parentProducts[index].discountName != null ? Color(0xffFFFF00) : Colors.white, + elevation: 0, + shape: Border( + right: BorderSide( + color: Colors.grey.shade300, + width: 1, + ), + left: BorderSide( + color: Colors.grey.shade300, + width: 1, + ), + bottom: BorderSide( + color: Colors.grey.shade300, + width: 1, + ), + top: BorderSide( + color: Colors.grey.shade300, + width: 1, + ), + ), + margin: EdgeInsets.symmetric( + horizontal: 8, + vertical: 4, + ), + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(110.0), + ), + color: Colors.white, + ), + padding: EdgeInsets.symmetric(horizontal: 0), + width: MediaQuery.of(context).size.width / 3, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Stack( + children: [ + if (model.parentProducts[index].discountName != null) + RotatedBox( + quarterTurns: 4, + child: Container( + decoration: BoxDecoration(), + child: Padding( + padding: EdgeInsets.only( + right: 5.0, + top: 20.0, + bottom: 5.0, + ), + child: Texts( + TranslationBase.of(context).offers.toUpperCase(), + color: Colors.red, + fontSize: 13.0, + fontWeight: FontWeight.w900, + ), + ), + transform: new Matrix4.rotationZ(5.837200), + ), + ), + Container( + margin: EdgeInsets.fromLTRB(0, 16, 0, 0), + alignment: Alignment.center, + child: Image.network( + model.parentProducts[index].images!.isNotEmpty + ? model.parentProducts[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.cover, + height: 80, + ), + ), +// Container( +// width: model.parentProducts[index].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:model.parentProducts[index].rxMessage != null ? +// Texts(projectProvider.isArabic +// ? model.parentProducts[index].rxMessagen +// : model.parentProducts[index].rxMessage, +// color: Colors.white, +// regular: true, +// fontSize: 10, +// fontWeight: FontWeight.w400, +// ) +// : Texts(""), +// // Texts( +// // model.parentProducts[index].rxMessage != +// null +// ? model +// .parentProducts[index] +// .rxMessage +// : "", +// // color: Colors +// .white, +// // regular: +// true, +// // fontSize: +// 10, +// // fontWeight: +// FontWeight +// .w400, +// // ), +// ), + ], + ), + Container( + margin: EdgeInsets.symmetric( + horizontal: 6, + vertical: 0, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (model.parentProducts[index].discountName != null) + Container( + width: double.infinity, + height: 13.0, + decoration: BoxDecoration( + color: Color(0xff5AB145), + ), + child: Center( + child: Texts( + model.parentProducts[index].discountName, + regular: true, + color: Colors.white, + fontSize: 10.4, + ), + ), + ), + Texts( + projectViewModel.isArabic ? model.parentProducts[index].namen : model.parentProducts[index].name, + regular: true, + fontSize: 12, + fontWeight: FontWeight.w700, + ), + Padding( + padding: const EdgeInsets.only(top: 4, bottom: 4), + child: Texts( + "SAR ${model.parentProducts[index].price}", + bold: true, + fontSize: 14, + ), + ), + Row( + children: [ +// StarRating( +// totalAverage: model.parentProducts[index].approvedRatingSum > 0 +// ? (model.parentProducts[index].approvedRatingSum.toDouble() / model.parentProducts[index].approvedRatingSum.toDouble()).toDouble() +// : 0, +// forceStars: true), + + RatingBar( + initialRating: model.parentProducts[index].approvedRatingSum!.toDouble(), + ratingWidget: RatingWidget( + full: Icon( + Icons.star, + color: CustomColors.accentColor, + ), + half: Icon( + Icons.star_half, + color: CustomColors.accentColor, + ), + empty: Icon( + Icons.star_border, + color: CustomColors.accentColor, + ), + ), + onRatingUpdate: (double value) {}, + unratedColor: Colors.grey[500], + updateOnDrag: false, + tapOnlyMode: false, + ), + + Texts( + "(${model.parentProducts[index].approvedTotalReviews})", + regular: true, + fontSize: 10, + fontWeight: FontWeight.w400, + ) + ], + ), + ], + ), + ), + ], + ), ), - color: Colors.white, ), - padding: EdgeInsets.symmetric( - horizontal: 0), - width: MediaQuery.of(context) - .size - .width / - 3, - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, + onTap: () => { + Navigator.push( + context, + FadePage( + page: ProductDetailPage(model.parentProducts[index]), + )), + }, + )); + }, + ), + ) + : Container( + height: model.parentProducts.length * MediaQuery.of(context).size.height * 0.122, + child: ListView.builder( + physics: NeverScrollableScrollPhysics(), + itemCount: model.parentProducts.length, + itemBuilder: (BuildContext context, int index) { + return InkWell( + child: Card( + child: Row( children: [ Stack( children: [ - if (model - .parentProducts[ - index] - .discountName != - null) - RotatedBox( - quarterTurns: 4, - child: Container( - decoration: - BoxDecoration(), + Column( + children: [ + Container( + decoration: BoxDecoration(), child: Padding( - padding: - EdgeInsets.only( - right: 5.0, - top: 20.0, - bottom: 5.0, - ), - child: Texts( - 'offer' - .toUpperCase(), - color: Colors.red, - fontSize: 13.0, - fontWeight: - FontWeight - .w900, + padding: EdgeInsets.only( + left: 9.0, + top: 8.0, + right: 10.0, ), ), - transform: new Matrix4 - .rotationZ( - 5.837200), ), - ), - Container( - margin: - EdgeInsets.fromLTRB( - 0, 16, 0, 0), - alignment: - Alignment.center, - child: Image.network( - model - .parentProducts[ - index] - .images - .isNotEmpty - ? model - .parentProducts[ - 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.cover, - height: 80, - ), + Container( + margin: EdgeInsets.fromLTRB(0, 0, 0, 0), + alignment: Alignment.center, + child: model.parentProducts[index].images!.isNotEmpty + ? Image.network( + model.parentProducts[index].images![0].thumb!, + fit: BoxFit.contain, + height: 70, + ) + : Text(TranslationBase.of(context).noImage), + ), + ], ), - Container( - width: model - .parentProducts[ - index] - .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: Texts( - model - .parentProducts[ - index] - .rxMessage != - null - ? model - .parentProducts[ - index] - .rxMessage - : "", - color: Colors.white, - regular: true, - fontSize: 10, - fontWeight: - FontWeight.w400, - ), + Column( + children: [ + Container( + width: model.parentProducts[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: model.parentProducts[index].rxMessage != null + ? Texts( + projectProvider.isArabic ? model.parentProducts[index].rxMessagen : model.parentProducts[index].rxMessage, + color: Colors.white, + regular: true, + fontSize: 10, + fontWeight: FontWeight.w400, + ) + : Texts(""), +// Texts( +// model.parentProducts[index].rxMessage != null ? model.parentProducts[index].rxMessage : "", +// color: Colors.white, +// regular: true, +// fontSize: 10, +// fontWeight: FontWeight.w400, +// ), + ), + ], ), ], ), Container( margin: EdgeInsets.symmetric( - horizontal: 6, + horizontal: 0, vertical: 0, ), child: Column( - crossAxisAlignment: - CrossAxisAlignment - .start, + mainAxisAlignment: MainAxisAlignment.spaceAround, + crossAxisAlignment: CrossAxisAlignment.start, children: [ - if (model - .parentProducts[ - index] - .discountName != - null) - Container( - width: - double.infinity, - height: 13.0, - decoration: - BoxDecoration( - color: Color( - 0xff5AB145), - ), - child: Center( - child: Texts( - model - .parentProducts[ - index] - .discountName, - regular: true, - color: - Colors.white, - fontSize: 10.4, - ), - ), + SizedBox( + height: 4.0, + ), + Container( + width: MediaQuery.of(context).size.width * 0.635, + child: Texts( + projectViewModel.isArabic ? model.parentProducts[index].namen : model.parentProducts[index].name, + regular: true, + fontSize: 13.2, + fontWeight: FontWeight.w500, + maxLines: 5, ), - Texts( - model - .parentProducts[ - index] - .name, - regular: true, - fontSize: 12, - fontWeight: - FontWeight.w700, + ), + SizedBox( + height: 8.0, ), Padding( - padding: - const EdgeInsets - .only( - top: 4, - bottom: 4), + padding: const EdgeInsets.only(top: 4, bottom: 4), child: Texts( "SAR ${model.parentProducts[index].price}", bold: true, @@ -882,251 +879,118 @@ class _ParentCategorisePageState extends State { ), Row( children: [ - StarRating( - totalAverage: model - .parentProducts[ - index] - .approvedRatingSum > - 0 - ? (model.parentProducts[index].approvedRatingSum - .toDouble() / - model - .parentProducts[index] - .approvedRatingSum - .toDouble()) - .toDouble() - : 0, - forceStars: true), +// StarRating( +// totalAverage: model.parentProducts[index].approvedRatingSum > 0 +// ? (model.parentProducts[index].approvedRatingSum.toDouble() / model.parentProducts[index].approvedRatingSum.toDouble()).toDouble() +// : 0, +// forceStars: true), + + RatingBar( + initialRating: model.parentProducts[index].approvedRatingSum!.toDouble(), + ratingWidget: RatingWidget( + full: Icon( + Icons.star, + color: CustomColors.accentColor, ), + half: Icon( + Icons.star_half, + color: CustomColors.accentColor, ), + empty: Icon( + Icons.star_border, + color: CustomColors.accentColor, ), + ), + onRatingUpdate: (double value) {}, + unratedColor: Colors.grey[500], + updateOnDrag: false, + tapOnlyMode: false, + ), + Texts( "(${model.parentProducts[index].approvedTotalReviews})", regular: true, fontSize: 10, - fontWeight: - FontWeight.w400, + fontWeight: FontWeight.w400, ) ], ), ], ), ), + widget.authenticatedUserObject.isLogin + ? Container( + child: IconButton( + icon: Icon( + Icons.shopping_cart, + size: 18, + color: CustomColors.green, + ), + onPressed: () async { + if (model.parentProducts[index].isRx == false) { + GifLoaderDialogUtils.showMyDialog(context); + await addToCartFunction(1, model.parentProducts[index].id); + GifLoaderDialogUtils.hideDialog(context); + Utils.navigateToCartPage(); + } else { + AppToast.showErrorToast(message: TranslationBase.of(context).needPrescription); + } + }), + ) + : Container(), ], ), ), - ), - onTap: () => { - Navigator.push( - context, - FadePage( - page: ProductDetailPage(model - .parentProducts[index]), - )), - }, - )); - }, - ), - ) - : Container( - height: model.parentProducts.length * - MediaQuery.of(context).size.height * - 0.122, - child: ListView.builder( - physics: NeverScrollableScrollPhysics(), - itemCount: model.parentProducts.length, - itemBuilder: - (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, - ), - ), - ), - Container( - margin: - EdgeInsets.fromLTRB( - 0, 0, 0, 0), - alignment: - Alignment.center, - child: Image.network( - model - .parentProducts[ - index] - .images - .isNotEmpty - ? model - .parentProducts[ - 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, - ), - ), - ], - ), - Column( - children: [ - Container( - width: model - .parentProducts[ - index] - .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: Texts( - model - .parentProducts[ - index] - .rxMessage != - null - ? model - .parentProducts[ - index] - .rxMessage - : "", - color: Colors.white, - regular: true, - fontSize: 10, - fontWeight: - FontWeight.w400, - ), - ), - ], - ), - ], - ), - Container( - 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 - .parentProducts[index] - .name, - regular: true, - fontSize: 13.2, - fontWeight: - FontWeight.w500, - maxLines: 5, - ), - ), - SizedBox( - height: 8.0, - ), - Padding( - padding: - const EdgeInsets.only( - top: 4, bottom: 4), - child: Texts( - "SAR ${model.parentProducts[index].price}", - bold: true, - fontSize: 14, - ), - ), - Row( - children: [ - StarRating( - totalAverage: model - .parentProducts[ - index] - .approvedRatingSum > - 0 - ? (model - .parentProducts[ - index] - .approvedRatingSum - .toDouble() / - model - .parentProducts[ - index] - .approvedRatingSum - .toDouble()) - .toDouble() - : 0, - forceStars: true), - Texts( - "(${model.parentProducts[index].approvedTotalReviews})", - regular: true, - fontSize: 10, - fontWeight: - FontWeight.w400, - ) - ], - ), - ], - ), - ), - ], + onTap: () => { + Navigator.push( + context, + FadePage( + page: ProductDetailPage(model.parentProducts[index]), + )), + }, + ); + }), + ) + : Padding( + padding: const EdgeInsets.all(12.0), + child: Container( + child: 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, ), ), - onTap: () => { - Navigator.push( - context, - FadePage( - page: ProductDetailPage( - model.parentProducts[index]), - )), - }, - ); - }), + Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + TranslationBase.of(context).noData, + // 'There is no data', + style: TextStyle(fontSize: 30), + ), + ) + ], + ), + ), + ), ) ], ), ), ), - )); + ))); + } + + addToCartFunction(quantity, itemID) async { + ProductDetailViewModel x = new ProductDetailViewModel(); + await x.addToCartData(quantity, itemID, context); } bool isEntityListSelected(CategoriseParentModel masterKey) { - Iterable history = - entityList.where((element) => masterKey.id == element.id); + Iterable history = entityList.where((element) => masterKey.id == element.id); if (history.length > 0) { return true; } @@ -1134,8 +998,7 @@ class _ParentCategorisePageState extends State { } bool isEntityListSelectedBrands(CategoriseParentModel masterKey) { - Iterable history = - entityListBrands.where((element) => masterKey.id == element.id); + Iterable history = entityListBrands.where((element) => masterKey.id == element.id); if (history.length > 0) { return true; } diff --git a/lib/pages/paymentService/payment_service.dart b/lib/pages/paymentService/payment_service.dart index 1b221454..29161b50 100644 --- a/lib/pages/paymentService/payment_service.dart +++ b/lib/pages/paymentService/payment_service.dart @@ -1,187 +1,220 @@ +import 'package:badges/badges.dart' as badge_import; +import 'package:diplomaticquarterapp/Constants.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart'; +import 'package:diplomaticquarterapp/models/InPatientServices/get_inpatient_advance_requests_response_model.dart'; +import 'package:diplomaticquarterapp/pages/InPatientServices/inpatient_advance_payment.dart'; import 'package:diplomaticquarterapp/pages/ToDoList/ToDo.dart'; import 'package:diplomaticquarterapp/pages/medical/balance/advance_payment_page.dart'; import 'package:diplomaticquarterapp/pages/medical/balance/my_balance_page.dart'; +import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.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/data_display/text.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'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:hexcolor/hexcolor.dart'; import 'package:provider/provider.dart'; class PaymentService extends StatelessWidget { - ToDoCountProviderModel model; - ProjectViewModel projectViewModel; + ToDoCountProviderModel? model; + late ProjectViewModel projectViewModel; + + InPatientAdvanceResponseModel inPatientAdvanceResponseModel = InPatientAdvanceResponseModel(); @override Widget build(BuildContext context) { projectViewModel = Provider.of(context); model = Provider.of(context); + List paymentServiceList = getPaymentServiceList(context); return AppScaffold( isShowAppBar: true, isShowDecPage: false, + showNewAppBarTitle: true, + showNewAppBar: true, appBarTitle: TranslationBase.of(context).paymentService, body: SingleChildScrollView( child: Container( - margin: EdgeInsets.all(12), + margin: EdgeInsets.all(20.0), child: Column( - crossAxisAlignment: CrossAxisAlignment.start, children: [ - Row( - children: [ - Expanded( - child: InkWell( - onTap: () => Navigator.push( - context, FadePage(page: AdvancePaymentPage())), - child: Container( - margin: EdgeInsets.all(5.0), - padding: EdgeInsets.all(9), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(8.0), - shape: BoxShape.rectangle), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts( - TranslationBase.of(context).payment, - color: HexColor('#B61422'), - bold: true, - ), - Texts( - TranslationBase.of(context).paymentOnline, - fontSize: 14, - fontWeight: FontWeight.normal, - ), - SizedBox( - height: 12, - ), - Container( - margin: EdgeInsets.only(left: 10, right: 10), - child: Image.asset( - 'assets/images/online_payment_icon.png', - fit: BoxFit.fill, - height: 55, - width: double.infinity, - ), - ), - ], - ), + 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: paymentServiceList.length, + itemBuilder: (BuildContext context, int index) { + return paymentServiceList[index]; + }, + ), + ), + ], + ), + ), + ), + ); + } + + List getPaymentServiceList(BuildContext context) { + List medical = []; + + medical.add( + InkWell( + onTap: () { + Navigator.push(context, FadePage(page: AdvancePaymentPage())); + projectViewModel!.analytics.advancePayments.payment_services(service_type: 'payment service'); + }, + child: MedicalProfileItem( + title: TranslationBase.of(context).onlinePayment, + imagePath: 'assets/images/new-design/online_payment_icon.png', + subTitle: TranslationBase.of(context).onlinePaymentSubtitle, + isPngImage: true, + width: 65.0, + height: 55.0, + ), + ), + ); + + medical.add( + InkWell( + onTap: () { + navigateToToDoPage(context); + projectViewModel!.analytics.advancePayments.payment_services(service_type: 'online check-in appointment'); + }, + child: Stack( + children: [ + MedicalProfileItem( + title: TranslationBase.of(context).pendingOnly, + imagePath: 'pendingPayment.svg', + subTitle: TranslationBase.of(context).paymentOnly, + isPngImage: false, + width: 45.0, + height: 45.0, + ), + projectViewModel!.isArabic + ? Positioned( + left: 8, + top: 4, + child: badge_import.Badge( + badgeStyle: badge_import.BadgeStyle( + shape: badge_import.BadgeShape.circle, + elevation: 0, + badgeColor: secondaryColor!.withOpacity(1.0), + borderRadius: BorderRadius.circular(8), ), - ), - ), - //if(!projectViewModel.havePrivilege(33)) - Expanded( - child: InkWell( - onTap: () => navigateToToDoPage(context), - child: Container( - margin: EdgeInsets.all(5.0), - padding: EdgeInsets.all(9), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(8.0), - shape: BoxShape.rectangle), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts( - TranslationBase.of(context).onlineCheckIn, - color: HexColor('#B61422'), - bold: true, - ), - Texts( - TranslationBase.of(context).appointment, - fontSize: 14, - fontWeight: FontWeight.normal, - ), - SizedBox( - height: 12, - ), - Align( - alignment: !projectViewModel.isArabic - ? Alignment.centerRight - : Alignment.centerLeft, - child: Image.asset( - 'assets/images/device_icon.png', - height: 55, - ), - ), - ], - ), + position: badge_import.BadgePosition.topEnd(), + badgeContent: Container( + padding: EdgeInsets.all(2.0), + child: Text(model!.count.toString(), style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 12.0)), ), ), ) - ], - ), - //if(!projectViewModel.havePrivilege(33)) - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: InkWell( - onTap: () => Navigator.push( - context, FadePage(page: MyBalancePage())), - child: Container( - margin: EdgeInsets.all(5.0), - padding: EdgeInsets.all(9), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(8.0), - shape: BoxShape.rectangle), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts( - TranslationBase.of(context).hmg, - color: HexColor('#B61422'), - bold: true, - ), - Texts( - TranslationBase.of(context).wallet, - fontSize: 14, - fontWeight: FontWeight.normal, - ), - SizedBox( - height: 12, - ), - Align( - alignment: !projectViewModel.isArabic - ? Alignment.centerRight - : Alignment.centerLeft, - child: Image.asset( - 'assets/images/new-design/check-in.png', - height: 55, - ), - ), - ], - ), + : Positioned( + right: 8, + top: 4, + child: badge_import.Badge( + position: badge_import.BadgePosition.topEnd(), + badgeStyle: badge_import.BadgeStyle( + shape: badge_import.BadgeShape.circle, + elevation: 0, + badgeColor: secondaryColor!.withOpacity(1.0), + borderRadius: BorderRadius.circular(8), + ), + badgeContent: Container( + padding: EdgeInsets.all(2.0), + child: Text(model!.count.toString(), style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 12.0)), ), ), - ), - Expanded( - child: Container(), ) - ], - ), - ], - ), + ], + ), + ), + ); + + medical.add( + InkWell( + onTap: () { + Navigator.push(context, FadePage(page: MyBalancePage())); + projectViewModel!.analytics.advancePayments.payment_services(service_type: 'alhabib wallet'); + }, + child: MedicalProfileItem( + title: TranslationBase.of(context).hmg, + imagePath: 'assets/images/check-in.png', + subTitle: TranslationBase.of(context).wallet, + isPngImage: true, + width: 45.0, + height: 45.0, ), ), ); + + // medical.add( + // InkWell( + // onTap: () { + // if(projectViewModel.isPatientAdmitted) { + // getInPatientAdvancePaymentRequests(context); + // projectViewModel.analytics.advancePayments.payment_services(service_type: 'inpatient advance payment'); + // } else { + // AppToast.showErrorToast(message: TranslationBase.of(context).onlyAdmitted); + // } + // }, + // child: MedicalProfileItem( + // title: "InPatient", + // imagePath: 'assets/images/inpatient_advance.png', + // subTitle: "Advance Payment", + // isPngImage: true, + // width: 45.0, + // height: 45.0, + // ), + // ), + // ); + + return medical; } - navigateToToDoPage(BuildContext context) { - if (projectViewModel.isLogin) { - if (model.count != 0) { - Navigator.push(context, FadePage(page: ToDo(isShowAppBar: true))); + void getInPatientAdvancePaymentRequests(BuildContext context) { + ClinicListService service = new ClinicListService(); + GifLoaderDialogUtils.showMyDialog(context); + service + .getInPatientAdvancePaymentRequests( + projectViewModel.inPatientProjectID, + projectViewModel.isPatientAdmitted ? projectViewModel.getAdmissionInfoResponseModel.admissionNo! : 0, + projectViewModel.isPatientAdmitted ? projectViewModel.getAdmissionInfoResponseModel.admissionRequestNo! : projectViewModel.getAdmissionRequestInfoResponseModel.admissionRequestNo!, + projectViewModel.isArabic ? 1 : 2, + context) + .then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res["MessageStatus"] == 1) { + if (res['responseInpatient'] != null) { + inPatientAdvanceResponseModel = InPatientAdvanceResponseModel.fromJson(res["responseInpatient"]); + Navigator.push(context, + FadePage(page: InPatientAdvancePayment(isHasData: inPatientAdvanceResponseModel.responseInpatientAdvanceInfo != null, inPatientAdvanceResponseModel: inPatientAdvanceResponseModel))); + } else { + AppToast.showErrorToast(message: TranslationBase.of(context).noData); + } } else { - AppToast.showErrorToast( - message: TranslationBase.of(context).upcomingEmpty); + Navigator.push(context, + FadePage(page: InPatientAdvancePayment(isHasData: inPatientAdvanceResponseModel.responseInpatientAdvanceInfo != null, inPatientAdvanceResponseModel: inPatientAdvanceResponseModel))); } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } + + navigateToToDoPage(BuildContext context) { + if (projectViewModel!.isLogin) { + // if (model.count != 0) { + Navigator.push(context, FadePage(page: ToDo(isShowAppBar: true))); + // } else { + // AppToast.showErrorToast(message: TranslationBase.of(context).upcomingEmpty); + // } } else { Navigator.push(context, FadePage(page: ToDo(isShowAppBar: true))); } diff --git a/lib/pages/pharmacies/ProductCheckTypeWidget.dart b/lib/pages/pharmacies/ProductCheckTypeWidget.dart index 878544e1..56c770a3 100644 --- a/lib/pages/pharmacies/ProductCheckTypeWidget.dart +++ b/lib/pages/pharmacies/ProductCheckTypeWidget.dart @@ -1,70 +1,61 @@ -import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; -import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/wishlist_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/widgets/pharmacy/product_tile.dart'; import 'package:flutter/material.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/product_detail_view_model.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:provider/provider.dart'; -AppSharedPreferences sharedPref = AppSharedPreferences(); -var languageID; -class ProductCheckTypeWidget extends StatelessWidget { - final List wishlist; - final bool isTrue; +class ProductCheckTypeWidget extends StatefulWidget { + final WishListViewModel? model; - ProductCheckTypeWidget(this.isTrue, this.wishlist); + ProductCheckTypeWidget({this.model}); + @override + _ProductCheckTypeWidgetState createState() => _ProductCheckTypeWidgetState(); +} - void initState() { - getLanguageID(); - } +class _ProductCheckTypeWidgetState extends State { @override Widget build(BuildContext context) { - return isTrue - ? ListView.builder( - itemCount: wishlist.length, - itemBuilder: (BuildContext context, int index) { - return Column( - children: [ - Container( - child: isTrue - ? productTile( - productName: languageID == 'ar' ? wishlist[index].product.namen : wishlist[index].product.name, - productPrice: wishlist[index].subtotal, - productRate: - double.parse(wishlist[index].subtotalVatRate), - productImage: wishlist[index].product.images[0].src, - showLine: isTrue, - productID: wishlist[index].product.id, - ) - : productTile( - productName: languageID == 'ar' ? wishlist[index].product.namen : wishlist[index].product.name, - productPrice: wishlist[index].subtotal, - productRate: - double.parse(wishlist[index].subtotalVatRate), - productImage: wishlist[index].product.images[0].src, - showLine: isTrue, - ), - ), - Divider(height: 1, color: Colors.grey) - ], - ); - }) - : GridView.count( - crossAxisCount: 2, - children: List.generate( - wishlist.length, - (index) => productTile( - productName: wishlist[index].product.name, - productPrice: wishlist[index].subtotal, - productRate: - double.parse(wishlist[index].subtotalVatRate), - productImage: wishlist[index].product.images[0].src, - showLine: isTrue, - )), + ProjectViewModel projectViewModel = Provider.of(context); + return ListView.builder( + itemCount: widget.model!.wishListList.length, + itemBuilder: (BuildContext context, int index) { + return Column( + children: [ + Container( + child: productTile( + productName: projectViewModel.isArabic + ? widget.model!.wishListList[index].product.namen + : widget.model!.wishListList[index].product.name, + productPrice: widget.model!.wishListList[index].subtotal, + // productRate: double.parse(widget.model.wishListList[index].subtotalVatRate), + productRate: widget.model!.wishListList[index].product.approvedRatingSum.toDouble(), + 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, + isRx:widget.model!.wishListList[index].product.isRx, + + ), + ), + Divider(height: 1, color: Colors.grey) + ], ); + }); } -} -getLanguageID() async { - languageID = await sharedPref.getString(APP_LANGUAGE); + deleteWishListItem(itemID) async { + ProductDetailViewModel x = new ProductDetailViewModel(); + GifLoaderDialogUtils.showMyDialog(context); + await x.deleteWishlistData(itemID, context); + await widget.model!.getWishlistData(isLocalLoader: true); + GifLoaderDialogUtils.hideDialog(context); + } + + + } diff --git a/lib/pages/pharmacies/compare-list.dart b/lib/pages/pharmacies/compare-list.dart index 37e2fc8c..be969678 100644 --- a/lib/pages/pharmacies/compare-list.dart +++ b/lib/pages/pharmacies/compare-list.dart @@ -1,26 +1,35 @@ +import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:flutter/material.dart'; -import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; class CompareList with ChangeNotifier { List _product = []; List get productListItems => _product; - void addItem(data) { + void addItem(data, context) { if (_product.length == 0) { _product.add(data); - AppToast.showSuccessToast(message: 'You have added a product to the Compare list'); + AppToast.showSuccessToast(message:TranslationBase.of(context).addToCompareMsg + // 'You have added a product to the Compare list' + ); } else { for (int i = 0; i < _product.length; i++) { - if (_product.length <= 4 && _product[i].id != data.id) { + if (_product.length < 3 && _product[i].id != data.id) { _product.add(data); - AppToast.showSuccessToast(message: 'You have added a product to the Compare list'); + AppToast.showSuccessToast(message:TranslationBase.of(context).addToCompareMsg + // 'You have added a product to the Compare list' + ); break; } else if(_product[i].id == data.id){ - AppToast.showErrorToast(message: 'the item is already in the list'); - } else if(_product.length == 4){ - AppToast.showErrorToast(message: 'your compare list is full'); + AppToast.showErrorToast(message:TranslationBase.of(context).itInListMsg + // 'the item is already in the list' + ); + } else if(_product.length == 3){ + AppToast.showErrorToast(message: TranslationBase.of(context).compareListFull + // 'your compare list is full' + ); } } } diff --git a/lib/pages/pharmacies/compare.dart b/lib/pages/pharmacies/compare.dart index 505533cb..f4f3e98d 100644 --- a/lib/pages/pharmacies/compare.dart +++ b/lib/pages/pharmacies/compare.dart @@ -1,12 +1,16 @@ -import 'package:flutter/material.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/compare-list.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:carousel_slider/carousel_slider.dart'; +import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/compare-list.dart'; -import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; import 'package:provider/provider.dart'; int counter = 0; +dynamic languageID; class ComparePage extends StatefulWidget { @override @@ -15,14 +19,28 @@ class ComparePage extends StatefulWidget { //CompareList compareItems = CompareList(); class _ComparePageState extends State { + getLanguageID() async { + languageID = await sharedPref.getString(APP_LANGUAGE); + } + + void initState() { + getLanguageID(); + super.initState(); + } + @override Widget build(BuildContext context) { return AppScaffold( - appBarTitle: 'Reviews page', + appBarTitle: TranslationBase.of(context).compare, isShowAppBar: true, isPharmacy: true, - body: Container( - child: compareList(), + showPharmacyCart: false, + showHomeAppBarIcon: false, + isBottomBar: true, + body: SingleChildScrollView( + child: Container( + child: compareList(), + ), ), ); } @@ -51,7 +69,7 @@ class compareList extends StatelessWidget { Padding( padding: const EdgeInsets.all(8.0), child: Text( - 'There is no data', + TranslationBase.of(context).noData, style: TextStyle(fontSize: 30), ), ) @@ -59,27 +77,11 @@ class compareList extends StatelessWidget { ), ), ) - : CarouselSlider( - options: CarouselOptions( - height: 800.0, - viewportFraction: 0.87, - enableInfiniteScroll: false), - items: productItem.map((i) { - return Builder( - builder: (BuildContext context) { - return Padding( - padding: const EdgeInsets.only(top: 8), - child: Container( - width: MediaQuery.of(context).size.width, - margin: EdgeInsets.symmetric(horizontal: 10.0), - child: productItem.length != 0 - ? slideDetail(productItem) - : Container(), - ), - ); - }, - ); - }).toList(), + : Container( + margin: EdgeInsets.only(top: 12.0), + width: double.infinity, + height: MediaQuery.of(context).size.height, + child: slideDetail(productItem), ); } } @@ -96,6 +98,7 @@ class slideDetail extends StatefulWidget { class _slideDetailState extends State { @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); return ListView.builder( scrollDirection: Axis.horizontal, itemCount: widget.data.length, @@ -105,7 +108,7 @@ class _slideDetailState extends State { mainAxisAlignment: MainAxisAlignment.center, children: [ Container( - height: 550, + height: 760, width: 150, margin: EdgeInsets.symmetric(horizontal: 10.0), decoration: BoxDecoration( @@ -128,8 +131,7 @@ class _slideDetailState extends State { icon: Icon(FontAwesomeIcons.trashAlt, size: 15), onPressed: () { setState(() { - Provider.of(context, listen: false) - .deleteItem(widget.data[index].id); + Provider.of(context, listen: false).deleteItem(widget.data[index].id); }); }, ), @@ -139,7 +141,7 @@ class _slideDetailState extends State { height: 20, ), Image.network( - widget.data[index].images[0].src.trim(), + widget.data[index].images![0].src!.trim(), fit: BoxFit.cover, width: 100, height: 60, @@ -157,30 +159,39 @@ class _slideDetailState extends State { child: Align( alignment: Alignment.topLeft, child: RichText( - text: TextSpan( - text: widget.data[index].name, - style: TextStyle( - fontWeight: FontWeight.bold, - color: Colors.black, - fontSize: 13), - ), + text: projectViewModel.isArabic + ? TextSpan( + text: widget.data[index].namen, + style: TextStyle(fontWeight: FontWeight.bold, color: Colors.black, fontSize: 13), + ) + : TextSpan( + text: widget.data[index].name, + style: TextStyle(fontWeight: FontWeight.bold, color: Colors.black, fontSize: 13), + ), ), ), ), Container( margin: EdgeInsets.all(5), - child: Align( - alignment: Alignment.topLeft, - child: RichText( - text: TextSpan( - text: widget.data[index].price.toString(), - style: TextStyle( - color: Colors.black54, - fontSize: 15, - fontWeight: FontWeight.bold), - ), - ), - ), + child: projectViewModel.isArabic + ? Align( + alignment: Alignment.topRight, + child: RichText( + text: TextSpan( + text: "SAR ${widget.data[index].price.toString()}", + style: TextStyle(color: Colors.black54, fontSize: 15, fontWeight: FontWeight.bold), + ), + ), + ) + : Align( + alignment: Alignment.topLeft, + child: RichText( + text: TextSpan( + text: "SAR ${widget.data[index].price.toString()}", + style: TextStyle(color: Colors.black54, fontSize: 15, fontWeight: FontWeight.bold), + ), + ), + ), ), Padding( padding: EdgeInsets.only(top: 8.0), @@ -191,39 +202,43 @@ class _slideDetailState extends State { ), ), Container( - margin: EdgeInsets.all(5), - child: Align( - alignment: Alignment.topLeft, - child: RichText( - text: TextSpan( - text: widget.data[index].specifications != null ? - widget.data[index].specifications[0].name : - "No data", - style: TextStyle( - fontWeight: FontWeight.bold, - color: Colors.black, - fontSize: 13), - ), - ), - ), - ), + margin: EdgeInsets.all(5), + child: projectViewModel.isArabic + ? Align( + alignment: Alignment.topRight, + child: RichText( + text: TextSpan( + text: widget.data[index].specifications != null ? widget.data[index].specifications![0].nameN : "", + style: TextStyle(fontWeight: FontWeight.bold, color: Colors.black, fontSize: 13), + )), + ) + : Align( + alignment: Alignment.topLeft, + child: RichText( + text: TextSpan( + text: widget.data[index].specifications != null ? widget.data[index].specifications![0].name : "", + style: TextStyle(fontWeight: FontWeight.bold, color: Colors.black, fontSize: 13), + )), + )), Container( - margin: EdgeInsets.all(5), - child: Align( - alignment: Alignment.topLeft, - child: RichText( - text: TextSpan( - text: widget.data[index].specifications != null ? - widget.data[index].specifications[1].name : - "No data", - style: TextStyle( - color: Colors.black54, - fontSize: 15, - fontWeight: FontWeight.bold), - ), - ), - ), - ), + margin: EdgeInsets.all(5), + child: projectViewModel.isArabic + ? Align( + alignment: Alignment.topRight, + child: RichText( + text: TextSpan( + text: widget.data[index].specifications != null ? widget.data[index].specifications![0].defaultValuen : "", + style: TextStyle(color: Colors.black54, fontSize: 15, fontWeight: FontWeight.bold), + )), + ) + : Align( + alignment: Alignment.topLeft, + child: RichText( + text: TextSpan( + text: widget.data[index].specifications != null ? widget.data[index].specifications![0].defaultValue : "", + style: TextStyle(color: Colors.black54, fontSize: 15, fontWeight: FontWeight.bold), + )), + )), Padding( padding: EdgeInsets.only(top: 8.0), child: Container( @@ -233,39 +248,43 @@ class _slideDetailState extends State { ), ), Container( - margin: EdgeInsets.all(5), - child: Align( - alignment: Alignment.topLeft, - child: RichText( - text: TextSpan( - text:widget.data[index].specifications != null ? - widget.data[index].specifications[2].name : - "No data", - style: TextStyle( - fontWeight: FontWeight.bold, - color: Colors.black, - fontSize: 13), - ), - ), - ), - ), + margin: EdgeInsets.all(5), + child: projectViewModel.isArabic + ? Align( + alignment: Alignment.topRight, + child: RichText( + text: TextSpan( + text: widget.data[index].specifications != null ? widget.data[index].specifications![1].nameN : "", + style: TextStyle(fontWeight: FontWeight.bold, color: Colors.black, fontSize: 13), + )), + ) + : Align( + alignment: Alignment.topLeft, + child: RichText( + text: TextSpan( + text: widget.data[index].specifications != null ? widget.data[index].specifications![1].name : "", + style: TextStyle(fontWeight: FontWeight.bold, color: Colors.black, fontSize: 13), + )), + )), Container( - margin: EdgeInsets.all(5), - child: Align( - alignment: Alignment.topLeft, - child: RichText( - text: TextSpan( - text: widget.data[index].specifications != null ? - widget.data[index].specifications[3].name : - "No data", - style: TextStyle( - color: Colors.black54, - fontSize: 15, - fontWeight: FontWeight.bold), - ), - ), - ), - ), + margin: EdgeInsets.all(5), + child: projectViewModel.isArabic + ? Align( + alignment: Alignment.topRight, + child: RichText( + text: TextSpan( + text: widget.data[index].specifications != null ? widget.data[index].specifications![1].defaultValuen : "", + style: TextStyle(color: Colors.black54, fontSize: 15, fontWeight: FontWeight.bold), + )), + ) + : Align( + alignment: Alignment.topLeft, + child: RichText( + text: TextSpan( + text: widget.data[index].specifications != null ? widget.data[index].specifications![1].defaultValue : "", + style: TextStyle(color: Colors.black54, fontSize: 15, fontWeight: FontWeight.bold), + )), + )), Padding( padding: EdgeInsets.only(top: 8.0), child: Container( @@ -275,39 +294,135 @@ class _slideDetailState extends State { ), ), Container( - margin: EdgeInsets.all(5), - child: Align( - alignment: Alignment.topLeft, - child: RichText( - text: TextSpan( - text:widget.data[index].specifications != null ? - widget.data[index].specifications[4].name : - "No data", - style: TextStyle( - fontWeight: FontWeight.bold, - color: Colors.black, - fontSize: 13), - ), - ), + margin: EdgeInsets.all(5), + child: projectViewModel.isArabic + ? Align( + alignment: Alignment.topRight, + child: RichText( + text: TextSpan( + text: widget.data[index].specifications != null ? widget.data[index].specifications![2].nameN : "", + style: TextStyle(fontWeight: FontWeight.bold, color: Colors.black, fontSize: 13), + )), + ) + : Align( + alignment: Alignment.topLeft, + child: RichText( + text: TextSpan( + text: widget.data[index].specifications != null ? widget.data[index].specifications![2].name : "", + style: TextStyle(fontWeight: FontWeight.bold, color: Colors.black, fontSize: 13), + )), + )), + Container( + margin: EdgeInsets.all(5), + child: projectViewModel.isArabic + ? Align( + alignment: Alignment.topRight, + child: RichText( + text: TextSpan( + text: widget.data[index].specifications != null ? widget.data[index].specifications![2].defaultValuen : "", + style: TextStyle(color: Colors.black54, fontSize: 15, fontWeight: FontWeight.bold), + )), + ) + : Align( + alignment: Alignment.topLeft, + child: RichText( + text: TextSpan( + text: widget.data[index].specifications != null ? widget.data[index].specifications![2].defaultValue : "", + style: TextStyle(color: Colors.black54, fontSize: 15, fontWeight: FontWeight.bold), + )), + )), + Padding( + padding: EdgeInsets.only(top: 8.0), + child: Container( + height: 1.0, + width: 300.0, + color: Colors.grey, ), ), Container( - margin: EdgeInsets.all(5), - child: Align( - alignment: Alignment.topLeft, - child: RichText( - text: TextSpan( - text:widget.data[index].specifications != null ? - widget.data[index].specifications[5].name : - "No data", - style: TextStyle( - color: Colors.black54, - fontSize: 15, - fontWeight: FontWeight.bold), - ), - ), + margin: EdgeInsets.all(5), + child: projectViewModel.isArabic + ? Align( + alignment: Alignment.topRight, + child: RichText( + text: TextSpan( + text: widget.data[index].specifications != null ? widget.data[index].specifications![3].nameN : "", + style: TextStyle(fontWeight: FontWeight.bold, color: Colors.black, fontSize: 13), + )), + ) + : Align( + alignment: Alignment.topLeft, + child: RichText( + text: TextSpan( + text: widget.data[index].specifications != null ? widget.data[index].specifications![3].name : "", + style: TextStyle(fontWeight: FontWeight.bold, color: Colors.black, fontSize: 13), + )), + )), + Container( + margin: EdgeInsets.all(5), + child: projectViewModel.isArabic + ? Align( + alignment: Alignment.topRight, + child: RichText( + text: TextSpan( + text: widget.data[index].specifications != null ? widget.data[index].specifications![3].defaultValuen : "", + style: TextStyle(color: Colors.black54, fontSize: 15, fontWeight: FontWeight.bold), + )), + ) + : Align( + alignment: Alignment.topLeft, + child: RichText( + text: TextSpan( + text: widget.data[index].specifications != null ? widget.data[index].specifications![3].defaultValue : "", + style: TextStyle(color: Colors.black54, fontSize: 15, fontWeight: FontWeight.bold), + )), + )), + Padding( + padding: EdgeInsets.only(top: 8.0), + child: Container( + height: 1.0, + width: 300.0, + color: Colors.grey, ), ), + Container( + margin: EdgeInsets.all(5), + child: projectViewModel.isArabic + ? Align( + alignment: Alignment.topRight, + child: RichText( + text: TextSpan( + text: widget.data[index].specifications != null ? widget.data[index].specifications![4].nameN : "", + style: TextStyle(fontWeight: FontWeight.bold, color: Colors.black, fontSize: 13), + )), + ) + : Align( + alignment: Alignment.topLeft, + child: RichText( + text: TextSpan( + text: widget.data[index].specifications != null ? widget.data[index].specifications![4].name : "", + style: TextStyle(fontWeight: FontWeight.bold, color: Colors.black, fontSize: 13), + )), + )), + Container( + margin: EdgeInsets.all(5), + child: projectViewModel.isArabic + ? Align( + alignment: Alignment.topRight, + child: RichText( + text: TextSpan( + text: widget.data[index].specifications != null ? widget.data[index].specifications![4].defaultValuen : "", + style: TextStyle(color: Colors.black54, fontSize: 15, fontWeight: FontWeight.bold), + )), + ) + : Align( + alignment: Alignment.topLeft, + child: RichText( + text: TextSpan( + text: widget.data[index].specifications != null ? widget.data[index].specifications![4].defaultValue : "", + style: TextStyle(color: Colors.black54, fontSize: 15, fontWeight: FontWeight.bold), + )), + )), Padding( padding: EdgeInsets.only(top: 8.0), child: Container( @@ -316,6 +431,44 @@ class _slideDetailState extends State { color: Colors.grey, ), ), + Container( + margin: EdgeInsets.all(5), + child: projectViewModel.isArabic + ? Align( + alignment: Alignment.topRight, + child: RichText( + text: TextSpan( + text: widget.data[index].specifications != null ? widget.data[index].specifications![5].nameN : "", + style: TextStyle(fontWeight: FontWeight.bold, color: Colors.black, fontSize: 13), + )), + ) + : Align( + alignment: Alignment.topLeft, + child: RichText( + text: TextSpan( + text: widget.data[index].specifications != null ? widget.data[index].specifications![5].name : "", + style: TextStyle(fontWeight: FontWeight.bold, color: Colors.black, fontSize: 13), + )), + )), + Container( + margin: EdgeInsets.all(5), + child: projectViewModel.isArabic + ? Align( + alignment: Alignment.topRight, + child: RichText( + text: TextSpan( + text: widget.data[index].specifications != null ? widget.data[index].specifications![5].defaultValuen : "", + style: TextStyle(color: Colors.black54, fontSize: 15, fontWeight: FontWeight.bold), + )), + ) + : Align( + alignment: Alignment.topLeft, + child: RichText( + text: TextSpan( + text: widget.data[index].specifications != null ? widget.data[index].specifications![5].defaultValue : "", + style: TextStyle(color: Colors.black54, fontSize: 15, fontWeight: FontWeight.bold), + )), + )), ], ), ), @@ -326,15 +479,3 @@ class _slideDetailState extends State { ); } } - -String returnString(data) { - for (int i = 0; i < data.length; i++) { - print(data[i]); -// if(data[i] == null){ -// if(counter == i){ -// -// } -// } - } - return "ENAD HILAL"; -} diff --git a/lib/pages/pharmacies/medicine_search_screen.dart b/lib/pages/pharmacies/medicine_search_screen.dart index 5c31f2de..e76425a4 100644 --- a/lib/pages/pharmacies/medicine_search_screen.dart +++ b/lib/pages/pharmacies/medicine_search_screen.dart @@ -1,20 +1,20 @@ import 'package:diplomaticquarterapp/config/size_config.dart'; import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacies_view_model.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/pharmacies_list_screen.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; -import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:diplomaticquarterapp/core/model/pharmacies/pharmacies_model.dart'; -import 'package:diplomaticquarterapp/core/viewModels/pharmacies_view_model.dart'; -import '../base/base_view.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; -import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/input/text_field.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/pharmacy/drug_item.dart'; -import 'package:diplomaticquarterapp/core/service/pharmacies_service.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/pharmacies_list_screen.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +import '../Blood/new_text_Field.dart'; +import '../base/base_view.dart'; class MedicineSearch extends StatelessWidget { final textController = TextEditingController(); @@ -24,7 +24,7 @@ class MedicineSearch extends StatelessWidget { return BaseView( allowAny: true, onModelReady: (model) => model.clearMedicineSearch(), - builder: (BuildContext context, PharmacyViewModel model, Widget child) => + builder: (BuildContext context, PharmacyViewModel model, Widget? child) => AppScaffold( baseViewModel: model, appBarTitle: TranslationBase.of(context).searchMedicine, @@ -36,14 +36,14 @@ class MedicineSearch extends StatelessWidget { children: [ Padding( padding: EdgeInsets.only( - bottom: SizeConfig.heightMultiplier * 1, - right: SizeConfig.heightMultiplier * 2.5, - top: SizeConfig.heightMultiplier * 4, - left: SizeConfig.heightMultiplier * 2.5, + bottom: SizeConfig.heightMultiplier! * 1, + right: SizeConfig.heightMultiplier! * 2.5, + top: SizeConfig.heightMultiplier! * 4, + left: SizeConfig.heightMultiplier! * 2.5, ), child: Form( key: _formKey, - child: TextFields( + child: NewTextFields( hintText: TranslationBase.of(context).searchMedicineHere, inputAction: TextInputAction.search, @@ -65,10 +65,10 @@ class MedicineSearch extends StatelessWidget { ), Container( margin: EdgeInsets.only( - bottom: SizeConfig.heightMultiplier * 0.0, - right: SizeConfig.heightMultiplier * 5, - top: SizeConfig.heightMultiplier * 1, - left: SizeConfig.heightMultiplier * 5, + bottom: SizeConfig.heightMultiplier! * 0.0, + right: SizeConfig.heightMultiplier! * 5, + top: SizeConfig.heightMultiplier! * 1, + left: SizeConfig.heightMultiplier! * 5, ), child: Wrap( children: [ @@ -87,7 +87,7 @@ class MedicineSearch extends StatelessWidget { if(model.pharmacy.isNotEmpty) Container( margin: EdgeInsets.only( - left: SizeConfig.heightMultiplier * 2), + left: SizeConfig.heightMultiplier! * 2), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -105,7 +105,7 @@ class MedicineSearch extends StatelessWidget { ), Expanded( child: Container( - width: SizeConfig.screenWidth * 0.85, + width: SizeConfig.screenWidth! * 0.85, //child: _getHospitals(model.pharmacy), child: ListView.builder( //physics: NeverScrollableScrollPhysics(), @@ -117,7 +117,7 @@ class MedicineSearch extends StatelessWidget { itemBuilder: (BuildContext context, int index) { return InkWell( child: MedicineItemWidget( - label: model.pharmacy[index].itemDes, + label: model.pharmacy[index].itemDes!, url: model.pharmacy[index].productImage), onTap: () { Navigator.push( @@ -145,7 +145,7 @@ class MedicineSearch extends StatelessWidget { searchMedicine(PharmacyViewModel model, BuildContext context) { Utils.hideKeyboard(context); - if (_formKey.currentState.validate()) + if (_formKey.currentState!.validate()) model.getMedicine(name: textController.text); } } diff --git a/lib/pages/pharmacies/my_reviews.dart b/lib/pages/pharmacies/my_reviews.dart index 7b17a359..dd36141d 100644 --- a/lib/pages/pharmacies/my_reviews.dart +++ b/lib/pages/pharmacies/my_reviews.dart @@ -1,9 +1,11 @@ +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/review_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:rating_bar/rating_bar.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; -import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_rating_bar/flutter_rating_bar.dart'; class MyReviewsPage extends StatefulWidget { @override @@ -22,9 +24,12 @@ class _MyReviewsPageState extends State { return BaseView( onModelReady: (model) => model.getReviewData(), builder: (_, model, wi) => AppScaffold( - appBarTitle: 'My Reviews', + appBarTitle: TranslationBase.of(context).reviews, isShowAppBar: true, isPharmacy: true, + showPharmacyCart: false, + showHomeAppBarIcon: false, + isBottomBar: true, baseViewModel: model, body: model.reviewListList.length == 0 ? Container( @@ -44,7 +49,8 @@ class _MyReviewsPageState extends State { Padding( padding: const EdgeInsets.all(8.0), child: Text( - 'There is no data', + TranslationBase.of(context).noData, +// 'There is no data', style: TextStyle(fontSize: 30), ), ) @@ -61,11 +67,8 @@ class _MyReviewsPageState extends State { Container( child: reviewDetails( model.reviewListList[index], - double.parse(model.reviewListList[index].product - .approvedTotalReviews - .toString()), - double.parse(model.reviewListList[index].rating - .toString()), + double.parse(model.reviewListList[index].product!.approvedTotalReviews!.toString()), + double.parse(model.reviewListList[index].rating.toString()), ), ), Divider(height: 1, color: Colors.grey) @@ -93,9 +96,7 @@ reviewDetails(data, rate, myRate) { Row( children: [ Container( - margin: languageID == 'ar' - ? EdgeInsets.only(top: 10, right: 10) - : EdgeInsets.only(top: 10, left: 10), + margin: languageID == 'ar' ? EdgeInsets.only(top: 10, right: 10) : EdgeInsets.only(top: 10, left: 10), child: Image.network( data.product.images[0].src.trim(), fit: BoxFit.cover, @@ -110,18 +111,11 @@ reviewDetails(data, rate, myRate) { Container( margin: EdgeInsets.all(5), child: Align( - alignment: languageID == 'ar' - ? Alignment.topRight - : Alignment.topLeft, + alignment: languageID == 'ar' ? Alignment.topRight : Alignment.topLeft, child: RichText( text: TextSpan( - text: languageID == 'ar' - ? data.product.namen - : data.product.name, - style: TextStyle( - color: Colors.black54, - fontSize: languageID == 'ar' ? 7 : 13, - fontWeight: FontWeight.bold), + text: languageID == 'ar' ? data.product.namen : data.product.name, + style: TextStyle(color: Colors.black54, fontSize: languageID == 'ar' ? 12 : 13, fontWeight: FontWeight.bold), ), ), ), @@ -131,18 +125,11 @@ reviewDetails(data, rate, myRate) { Container( margin: EdgeInsets.all(5), child: Align( - alignment: languageID == 'ar' - ? Alignment.topRight - : Alignment.topLeft, + alignment: languageID == 'ar' ? Alignment.topRight : Alignment.topLeft, child: RichText( text: TextSpan( - text: data.product.price.toString() + - " " + - data.product.currency, - style: TextStyle( - fontWeight: FontWeight.bold, - color: Colors.black, - fontSize: 13), + text: data.product.price.toString() + " " + data.product.currency, + style: TextStyle(fontWeight: FontWeight.bold, color: Colors.black, fontSize: 13), ), ), ), @@ -152,20 +139,46 @@ reviewDetails(data, rate, myRate) { Container( margin: EdgeInsets.all(5), child: Align( - alignment: languageID == 'ar' - ? Alignment.topRight - : Alignment.topLeft, - child: RatingBar.readOnly( - initialRating: rate, - size: 15.0, - filledColor: Colors.yellow[700], - emptyColor: Colors.grey[500], - isHalfAllowed: true, - halfFilledIcon: Icons.star_half, - filledIcon: Icons.star, - emptyIcon: Icons.star, - ), - ), + alignment: languageID == 'ar' ? Alignment.topRight : Alignment.topLeft, + child: RatingBar( + initialRating: rate, + direction: Axis.horizontal, + allowHalfRating: true, + itemCount: 5, + itemSize: 20, + ignoreGestures: true, + ratingWidget: RatingWidget( + full: Icon( + Icons.star, + color: CustomColors.accentColor, + ), + half: Icon( + Icons.star_half, + color: CustomColors.accentColor, + ), + empty: Icon( + Icons.star, + color: CustomColors.accentColor, + ), + ), + tapOnlyMode: true, + itemPadding: EdgeInsets.symmetric(horizontal: 4.0), + onRatingUpdate: (rating) { + print(rating); + }, + ) + // RatingBar.readOnly( + // initialRating: rate, + // size: 15.0, + // filledColor: Colors.yellow[700], + // emptyColor: Colors.grey[500], + // isHalfAllowed: true, + // halfFilledIcon: Icons.star_half, + // filledIcon: Icons.star, + // emptyIcon: Icons.star, + // ), + + ), ), ], ), @@ -182,11 +195,7 @@ reviewDetails(data, rate, myRate) { crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ - Container( - padding: languageID == 'ar' - ? EdgeInsets.only(right: 10) - : EdgeInsets.only(left: 10), - child: Text(data.createdOnUtc.toString())), + Container(padding: languageID == 'ar' ? EdgeInsets.only(right: 10) : EdgeInsets.only(left: 10), child: Text(data.createdOnUtc.toString().substring(0, 11))), ], ), ), @@ -196,20 +205,45 @@ reviewDetails(data, rate, myRate) { mainAxisAlignment: MainAxisAlignment.end, children: [ Container( - padding: languageID == 'ar' - ? EdgeInsets.only(right: 60) - : EdgeInsets.only(left: 60), - child: RatingBar.readOnly( - initialRating: myRate, - size: 15.0, - filledColor: Colors.yellow[700], - emptyColor: Colors.grey[500], - isHalfAllowed: true, - halfFilledIcon: Icons.star_half, - filledIcon: Icons.star, - emptyIcon: Icons.star, - ), - ), + padding: languageID == 'ar' ? EdgeInsets.only(right: 60) : EdgeInsets.only(left: 60), + child: RatingBar( + initialRating: myRate, + direction: Axis.horizontal, + allowHalfRating: true, + itemCount: 5, + itemSize: 20, + ignoreGestures: true, + ratingWidget: RatingWidget( + full: Icon( + Icons.star, + color: CustomColors.accentColor, + ), + half: Icon( + Icons.star_half, + color: CustomColors.accentColor, + ), + empty: Icon( + Icons.star, + color: CustomColors.accentColor, + ), + ), + tapOnlyMode: true, + itemPadding: EdgeInsets.symmetric(horizontal: 4.0), + onRatingUpdate: (rating) { + print(rating); + }, + ) + // RatingBar.readOnly( + // initialRating: myRate, + // size: 15.0, + // filledColor: Colors.yellow[700], + // emptyColor: Colors.grey[500], + // isHalfAllowed: true, + // halfFilledIcon: Icons.star_half, + // filledIcon: Icons.star, + // emptyIcon: Icons.star, + // ), + ), ], ), ), @@ -221,10 +255,8 @@ reviewDetails(data, rate, myRate) { ), Expanded( child: Container( - padding: languageID == 'ar' - ? EdgeInsets.only(right: 10) - : EdgeInsets.only(left: 10), - child: Text(fixingString(data.reviewText.toString())), + padding: languageID == 'ar' ? EdgeInsets.only(right: 10) : EdgeInsets.only(left: 10), + child: Text(getReview(data) ?? ""), ), ), ], @@ -234,6 +266,20 @@ reviewDetails(data, rate, myRate) { ); } +String getReview(data) { + String reviewTxt = ""; + + if (data.reviewText == null && data.replyText == null) { + reviewTxt = ""; + } + if (data.reviewText == null) + reviewTxt = data.replyText; + else + reviewTxt = data.reviewText; + + return reviewTxt; +} + fixingString(txt) { String stringTxt; String newTxt; diff --git a/lib/pages/pharmacies/pharmacies_list_screen.dart b/lib/pages/pharmacies/pharmacies_list_screen.dart index a35a77c9..92f5a277 100644 --- a/lib/pages/pharmacies/pharmacies_list_screen.dart +++ b/lib/pages/pharmacies/pharmacies_list_screen.dart @@ -15,9 +15,9 @@ import 'package:url_launcher/url_launcher.dart'; import '../base/base_view.dart'; class PharmaciesList extends StatelessWidget { - final int medicineID; - final String imageURL; - final String medicineDescription; + final int? medicineID; + final String? imageURL; + final String? medicineDescription; PharmaciesList({this.medicineID, this.imageURL, this.medicineDescription}); @@ -26,7 +26,7 @@ class PharmaciesList extends StatelessWidget { return BaseView( allowAny: true, onModelReady: (model) => model.getPharmacies(id: medicineID), - builder: (BuildContext context, PharmacyViewModel model, Widget child) => + builder: (BuildContext context, PharmacyViewModel model, Widget? child) => AppScaffold( appBarTitle: TranslationBase.of(context).pharmaciesList, baseViewModel: model, @@ -49,9 +49,9 @@ class PharmaciesList extends StatelessWidget { Radius.circular(7), ), child: Image.memory( - dataFromBase64String(imageURL), - height: SizeConfig.imageSizeMultiplier * 19, - width: SizeConfig.imageSizeMultiplier * 18, + dataFromBase64String(imageURL!), + height: SizeConfig.imageSizeMultiplier! * 19, + width: SizeConfig.imageSizeMultiplier! * 18, fit: BoxFit.cover, ), ), @@ -90,10 +90,10 @@ class PharmaciesList extends StatelessWidget { ), Container( margin: EdgeInsets.only( - top: SizeConfig.widthMultiplier * 2.0, - bottom: SizeConfig.widthMultiplier * 3.0, - right: SizeConfig.widthMultiplier * 4.0, - left: SizeConfig.widthMultiplier * 2.5, + top: SizeConfig.widthMultiplier! * 2.0, + bottom: SizeConfig.widthMultiplier! * 3.0, + right: SizeConfig.widthMultiplier! * 4.0, + left: SizeConfig.widthMultiplier! * 2.5, ), child: Align( alignment: Alignment.center, @@ -104,7 +104,7 @@ class PharmaciesList extends StatelessWidget { alignment: Alignment.topRight, ), Container( - width: SizeConfig.screenWidth * 1.0, + width: SizeConfig.screenWidth! * 1.0, child: ListView.builder( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), @@ -120,9 +120,9 @@ class PharmaciesList extends StatelessWidget { borderRadius: BorderRadius.all(Radius.circular(7)), child: Image.network( - model.pharmacyList[index].imageLocation, - height: SizeConfig.imageSizeMultiplier * 13.0, - width: SizeConfig.imageSizeMultiplier * 11.0, + model.pharmacyList[index].imageLocation!, + height: SizeConfig.imageSizeMultiplier! * 13.0, + width: SizeConfig.imageSizeMultiplier! * 11.0, fit: BoxFit.cover, ), ), @@ -151,7 +151,7 @@ class PharmaciesList extends StatelessWidget { color: Theme.of(context).primaryColor, ), onTap: () => launch("tel://" + - model.pharmacyList[index].phoneNumber), + model.pharmacyList[index].phoneNumber!), ), ), Padding( @@ -164,9 +164,9 @@ class PharmaciesList extends StatelessWidget { onTap: () { MapsLauncher.launchCoordinates( double.parse( - model.pharmacyList[index].latitude), + model.pharmacyList[index].latitude!), double.parse(model - .pharmacyList[index].longitude), + .pharmacyList[index].longitude!), ); }, ), diff --git a/lib/pages/pharmacies/product-brands.dart b/lib/pages/pharmacies/product-brands.dart index e2fefab0..198cf4b7 100644 --- a/lib/pages/pharmacies/product-brands.dart +++ b/lib/pages/pharmacies/product-brands.dart @@ -1,13 +1,12 @@ -import 'package:diplomaticquarterapp/config/config.dart'; -import 'package:diplomaticquarterapp/pages/final_products_page.dart'; -import 'package:diplomaticquarterapp/pages/login/register-info.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/brand_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/pages/final_products_page.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/search_brands_page.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/others/network_base_view.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; @@ -31,109 +30,127 @@ class _ProductBrandsPageState extends State { allowAny: true, onModelReady: (model) => model.getBrandsData(), builder: (_, model, wi) => AppScaffold( - appBarTitle: 'Brands page', + appBarTitle: TranslationBase.of(context).brands, isShowAppBar: true, isPharmacy: true, isShowDecPage: false, - body: Container( - child: Column( - children: [ - Container( - color: Colors.white, - alignment: - languageID == 'ar' ? Alignment.topRight : Alignment.topLeft, - padding: languageID == 'ar' - ? EdgeInsets.only(right: 10.0, top: 10.0) - : EdgeInsets.only(left: 10.0, top: 10.0), - child: Text( - TranslationBase.of(context).topBrands, - style: TextStyle( - fontWeight: FontWeight.bold, + body: SingleChildScrollView( + child: NetworkBaseView( + baseViewModel: model, + isLocalLoader:true, + child: Container( + child: Column( + children: [ + Container( + color: Colors.white, + alignment: languageID == 'ar' + ? Alignment.topRight + : Alignment.topLeft, + padding: languageID == 'ar' + ? EdgeInsets.only(right: 10.0, top: 10.0) + : EdgeInsets.only(left: 10.0, top: 10.0), + child: Text( + TranslationBase.of(context).topBrands, + style: TextStyle( + fontWeight: FontWeight.bold, + ), + ), ), - ), - ), - Container( - height: 220, - width: double.infinity, - color: Colors.white, - child: topBrand(context), - ), - SizedBox( - height: 10, - ), - Container( - height: MediaQuery.of(context).size.height * 0.056, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(5.0), - color: Colors.white, - ), - child: InkWell( - child: Padding( - padding: EdgeInsets.all(8.0), - child: Row( - //crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Icon(Icons.search, size: 25.0), - SizedBox( - width: 15.0, + Container( + height: 220, + width: double.infinity, + color: Colors.white, + child: topBrand(context), + ), + SizedBox( + height: 10, + ), + Container( + height: MediaQuery.of(context).size.height * 0.076, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5.0), + color: Colors.white, + ), + child: topBrand(context), + ), + SizedBox( + height: 10, + ), + Container( + height: MediaQuery.of(context).size.height * 0.066, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5.0), + color: Colors.white, + ), + child: InkWell( + child: Padding( + padding: EdgeInsets.all(8.0), + child: Row( + //crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Icon(Icons.search, size: 25.0), + SizedBox( + width: 15.0, + ), + Texts( + TranslationBase.of(context).searchProductHere, + fontSize: 13, + ) + ], ), - Texts( - TranslationBase.of(context).searchProductHere, - fontSize: 13, - ) - ], + ), + onTap: () { + Navigator.push( + context, + FadePage(page: SearchBrandsPage()), + ); + }, ), ), - onTap: () { - Navigator.push( - context, - FadePage(page: SearchBrandsPage()), - ); - }, - ), - ), - SizedBox( - height: 10, - ), - Container( - height: 290, - width: double.infinity, - color: Colors.white, - child: ListView.builder( - itemCount: model.brandsListList.length, - itemBuilder: (BuildContext context, int index) { - return InkWell( - child: Container( - margin: EdgeInsets.only(top: 50, left: 10), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - languageID == 'ar' - ? Text(model.brandsListList[index].namen) - : Text(model.brandsListList[index].name), - SizedBox( - height: 3, + SizedBox( + height: 10, + ), + Container( + height: 250, + width: double.infinity, + color: Colors.white, + child: ListView.builder( + itemCount: model.brandsListList.length, + itemBuilder: (BuildContext context, int index) { + return InkWell( + child: Container( + margin: EdgeInsets.only(top: 50, left: 10), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + languageID == 'ar' + ? Text(model.brandsListList[index].namen!) + : Text(model.brandsListList[index].name!), + SizedBox( + height: 3, + ), + Divider(height: 1, color: Colors.grey) + ], ), - Divider(height: 1, color: Colors.grey) - ], - ), - ), - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => FinalProductsPage( - id: model.brandsListList[index].id - .toString(), - )), + ), + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => FinalProductsPage( + id: model.brandsListList[index].id + .toString(), + )), + ); + }, ); - }, - ); - }), + }), + ), + ], ), - ], + ), ), ), ), @@ -174,12 +191,12 @@ topBrand(BuildContext context) { ), child: model.topBrandsListList[index].image != null ? Image.network( - model.topBrandsListList[index].image.src, + model.topBrandsListList[index].image!.src!, fit: BoxFit.cover, width: 60, height: 40, ) - : Text(model.topBrandsListList[index].name)), + : Text(model.topBrandsListList[index].name!)), ), ), ), @@ -226,7 +243,7 @@ class SearchBar extends SearchDelegate { progress: transitionAnimation, ), onPressed: () { - close(context, null); + close(context, ""); }, ); } diff --git a/lib/pages/pharmacies/product_detail.dart b/lib/pages/pharmacies/product_detail.dart deleted file mode 100644 index bd776355..00000000 --- a/lib/pages/pharmacies/product_detail.dart +++ /dev/null @@ -1,2152 +0,0 @@ -import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; -import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; -import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/pharmacy_module_view_model.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/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/data_display/text.dart'; -import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:diplomaticquarterapp/widgets/others/app_scafold_detail_page.dart'; -import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; -import 'package:flutter/material.dart'; -import 'package:font_awesome_flutter/font_awesome_flutter.dart'; -import 'package:provider/provider.dart'; -import 'package:rating_bar/rating_bar.dart'; - -import 'screens/cart-order-page.dart'; - -int price = 0; -var languageID; -bool isOverQuantity = false; -bool isInWishlit = false; -String itemID; -var customerId; -CompareList compareItems = new CompareList(); -PharmacyProduct specificationData; - -class ProductDetailPage extends StatefulWidget { - final PharmacyProduct product; - - ProductDetailPage(this.product); - - @override - __ProductDetailPageState createState() => __ProductDetailPageState(); -} - -class __ProductDetailPageState extends State { - bool isTrue = true; - bool isDetails = true; - bool isReviews = false; - bool isAvailabilty = false; - dynamic wishlistItems; - var model; - - // String ProductId="4561"; - String productId = ""; - - checkWishlist() async { - GifLoaderDialogUtils.showMyDialog(context); - ProductDetailViewModel x = new ProductDetailViewModel(); - await x.checkWishlistData(); - -// isInWishlit = x.wishListItems.map((e) => e.id.toString()).toList().contains(itemID); - - for (int i = 0; i < x.wishListItems.length; i++) { - if (itemID == x.wishListItems[i].product.id) { - isInWishlit = true; - break; - } else { - isInWishlit = false; - } - } - GifLoaderDialogUtils.hideDialog(context); - setState(() {}); - } - - void initState() { - price = 1; - specificationData = widget.product; - userInfo(); - super.initState(); - } - - void userInfo() async { - print(specificationData); - customerId = await sharedPref.getString(PHARMACY_CUSTOMER_ID); - if (customerId != null) { - itemID = widget.product.id; - checkWishlist(); -// getSpecificationData(itemID); - } - print("customerId:$customerId"); - - setState(() {}); -// getSpecificationData(itemID); - } - - Widget build(BuildContext context) { - return customerId != null - ? DetailPageScafold( - appBarTitle: 'product detail page', - isShowAppBar: true, - isPharmacy: true, - isShowDecPage: false, - body: SingleChildScrollView( - child: Column( - children: [ - Container( - width: double.infinity, - color: Colors.white, - child: Column( - children: [ - Image.network( - widget.product.images[0].src.trim(), - ), - widget.product.discountDescription != null - ? Container( - width: double.infinity, - height: 50, - color: Colors.yellowAccent, - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Expanded( - flex: 1, - child: Container( - alignment: Alignment.centerRight, - child: languageID == 'ar' - ? Text( - widget.product - .discountDescriptionn, - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 17), - ) - : Text( - widget.product - .discountDescription, - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 17), - ), - ), - ), - SizedBox( - width: 10, - ), - Expanded( - flex: 0, - child: Container( - child: Image( - image: AssetImage( - 'assets/images/offer.png'), - ), - ), - ), - ], - ), - ) - : Container(), - ], - ), - ), - SizedBox( - height: 4, - ), - Container( - width: 500, - height: 150, - color: Colors.white, - child: productNameAndPrice(context, widget.product), - ), - SizedBox( - height: 6, - ), - Container( - width: 500, - height: 120, - color: Colors.white, - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.all(8.0), - child: Container( - child: Text( - TranslationBase.of(context).specification, - style: TextStyle(fontWeight: FontWeight.bold), - ), - ), - ), - Divider(color: Colors.grey), - Padding( - padding: const EdgeInsets.all(8.0), - child: Container( - child: Text( - "there is no data", - ), - ), - ), - ], - ), - ), - SizedBox( - height: 6, - ), - Container( - width: 500, - margin: EdgeInsets.only(bottom: 6), -// height: 350, - color: Colors.white, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Column( - children: [ - FlatButton( - onPressed: () { - setState(() { - isDetails = true; - isReviews = false; - isAvailabilty = false; - }); - }, - child: Text( - TranslationBase.of(context).details, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold), - ), - color: Colors.white, - ), - isDetails - ? Container( - width: 100, - height: 5, - color: Colors.green, - ) - : Container() - ], - ), - SizedBox( - width: 20, - ), - Column( - children: [ - FlatButton( - onPressed: () { - setState(() { - isDetails = false; - isReviews = true; - isAvailabilty = false; - }); - }, - child: Text( - TranslationBase.of(context).reviews, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold), - ), - color: Colors.white, - ), - isReviews - ? Container( - width: 100, - height: 5, - color: Colors.green, - ) - : Container(), - ], - ), - SizedBox( - width: 20, - ), - Column( - children: [ - FlatButton( - onPressed: () { - setState(() { - isDetails = false; - isReviews = false; - isAvailabilty = true; - }); - }, - child: Text( - TranslationBase.of(context).availability, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold), - ), - color: Colors.white, - ), - isAvailabilty - ? Container( - width: 100, - height: 5, - color: Colors.green, - ) - : Container(), - ], - ), - ], - ), - SizedBox( - height: 10, - ), - isDetails - ? Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Container( - child: Text( - TranslationBase.of(context) - .description, - style: TextStyle( - fontSize: 17, - color: Colors.grey, - fontWeight: FontWeight.w600), - ), - ), - SizedBox( - height: 10, - ), - Divider(height: 1, color: Colors.grey), - SizedBox( - height: 15, - ), - Container( - child: Text( - languageID == 'ar' - ? widget.product.fullDescriptionn - : widget.product - .fullDescription ?? - "", - style: TextStyle( - fontSize: 16, - fontFamily: 'WorkSans-Regular'), - ), - ), - SizedBox( - height: 20, - ), - ]), - ) - -// Container( -// child: Text( -// languageID == 'ar' -// ? widget.product.fullDescriptionn -// : widget.product.fullDescription, -// style: TextStyle( -// fontSize: 16, -// fontFamily: 'WorkSans-Regular'), -// ), -// ), -// SizedBox( -// height: 10, -// ), -// Container( -// child: Text( -// TranslationBase.of(context).howToUse, -// style: TextStyle( -// fontSize: 17, -// color: Colors.grey, -// fontWeight: FontWeight.w600), -// ), -// ), -// SizedBox( -// height: 6, -// ), -// Divider( -// height: 2, -// color: Colors.grey), -// SizedBox( -// height: 10, -// ), -// Container( -// child: Text( -// languageID == 'ar' -// ? widget.product.shortDescriptionn -// : widget.product.shortDescription, -// style: TextStyle( -// fontSize: 16, -// fontFamily: 'WorkSans-Regular'), -// ), -// ), - // ], - // ), - // ) - : isReviews - ? BaseView( - onModelReady: (model) => - model.getProductReviewsData( - widget.product.id), - builder: (_, model, wi) => model - .productDetailService - .length != - 0 && - model.productDetailService[0] - .reviews.length != - 0 - ? ListView.builder( - physics: ScrollPhysics(), - itemCount: model - .productDetailService[0] - .reviews - .length, - scrollDirection: Axis.vertical, - shrinkWrap: true, - itemBuilder: (BuildContext context, - int index) { - return Padding( - padding: EdgeInsets.all(8.0), - child: Column( - mainAxisAlignment: - MainAxisAlignment.start, - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Container( - child: Row( - children: [ - Container( - child: Text( - model - .productDetailService[ - 0] - .reviews[ - index] - .customerId - .toString(), - style: TextStyle( - fontSize: 17, - color: Colors - .grey, - fontWeight: - FontWeight - .w600), - ), - ), - Container( - margin: - EdgeInsets.only( - left: 210), - child: RatingBar - .readOnly( - initialRating: model - .productDetailService[ - 0] - .reviews[ - index] - .rating - .toDouble(), - size: 15.0, - filledColor: - Colors.yellow[ - 700], - emptyColor: Colors - .grey[500], - isHalfAllowed: - true, - halfFilledIcon: - Icons - .star_half, - filledIcon: - Icons.star, - emptyIcon: - Icons.star, - ), - ), - ], - ), - ), - SizedBox( - height: 10, - ), - Container( - child: Text( - model - .productDetailService[ - 0] - .reviews[index] - .reviewText, - style: TextStyle( - fontSize: 20), - ), - ), - SizedBox( - height: 50, - ), - Divider( - height: 1, - color: Colors.grey), - ], - ), - ); - }, - ) - : Container( - padding: EdgeInsets.all(15), - alignment: Alignment.center, - child: Text('No Reviews Available'), - ), - ) - : isAvailabilty - ? BaseView( - onModelReady: (model) => - model.getProductLocationData(), - builder: (_, model, wi) => model - .productLocationService - .length == - 0 - ? Container( - padding: EdgeInsets.all(15), - alignment: Alignment.center, - child: Text( - 'No location Available'), - ) - : ListView.builder( - physics: ScrollPhysics(), - scrollDirection: Axis.vertical, - shrinkWrap: true, - itemCount: model - .productLocationService - .length, - itemBuilder: - (BuildContext context, - int index) { - return Padding( - padding: - EdgeInsets.all(8.0), - child: Column( -// crossAxisAlignment: CrossAxisAlignment.start, -// mainAxisAlignment: MainAxisAlignment.start, - children: [ - Row( -// crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: - MainAxisAlignment - .start, - children: [ - Expanded( - flex: 1, - child: Image.network(model - .productLocationService[ - index] - .projectImageUrl), - ), - SizedBox( - width: 10, - ), - Expanded( - flex: 4, - child: Text( - model - .productLocationService[ - index] - .locationDescription + - "\n" + - fixingString(model - .productLocationService[ - 0] - .cityName - .toString()), - style: TextStyle( - fontSize: - 12), - ), - ), - Expanded( - flex: 1, - child: IconButton( - icon: Icon(Icons - .location_on), - color: - Colors.red, - onPressed: - () {}, - ), - ), - Expanded( - flex: 1, - child: IconButton( - icon: Icon(Icons - .phone), - color: - Colors.red, - onPressed: - () {}, - ), - ), - ], - ), - Divider( - height: 1.2, - color: Colors.grey) - ], - ), - ); - }, - ), - ) - : Container(), - ], - ), - ), - Row( - children: [ -// Container( -// width: 500, -// height: 100, -// margin: EdgeInsets.only(bottom: 100), -// color: Colors.white, -// child: Text("ENAD TEST"), -// ), - Container( - width: 410, - height: 50, - // margin: EdgeInsets.only(bottom: 5), - color: Colors.white, - child: Texts( - TranslationBase.of(context).recommended, - bold: true, - ), - ), - ], - ), - SingleChildScrollView( - child: Container( - color: Colors.white, - child: Column( - // crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, -// mainAxisSize: MainAxisSize.min, - children: [ - Container( - color: Colors.white, - height: 210, - margin: EdgeInsets.only(bottom: 75), - padding: EdgeInsets.only(bottom: 5), - // margin: EdgeInsets.symmetric(horizontal: 6, vertical: 4), - child: BaseView( - onModelReady: (model) => - model.getRecommendedProducts( - widget.product.id.toString()), - builder: (_, model, wi) => Container( - child: -// Text(model.recommendedProductList[0].id), - model.recommendedProductList.length != - null - ? Expanded( - child: ListView.builder( - scrollDirection: - Axis.horizontal, - shrinkWrap: true, - physics: ScrollPhysics(), - // physics: NeverScrollableScrollPhysics(), - itemCount: model - .recommendedProductList - .length, - itemBuilder: - (context, index) { - return Card( - elevation: 2, - shape: RoundedRectangleBorder( - side: BorderSide( - color: Colors - .grey[ - 300], - width: 2), - borderRadius: - BorderRadius - .circular( - 10)), - margin: EdgeInsets - .symmetric( - horizontal: 8, - vertical: 0, - ), - child: Container( - decoration: - BoxDecoration( - borderRadius: - BorderRadius - .all( - Radius.circular( - 15), - ), - ), - padding: EdgeInsets - .symmetric( - horizontal: - 4), - width: MediaQuery.of( - context) - .size - .width / - 3, - child: Column( - crossAxisAlignment: - CrossAxisAlignment - .start, - children: [ - Stack( - children: [ - Container( - child: Align( - alignment: Alignment.topRight, - child: //true - itemID.contains(model.recommendedProductList[index].id) - // !isInWishlist - ? IconButton( - icon: Icon(Icons.favorite_border), - color: Colors.grey, - iconSize: 30, - onPressed: () { - setState(() { - addToWishlistFunction(itemID); - }); - }, - ) - : IconButton( - icon: Icon(Icons.favorite), - color: Colors.red, - iconSize: 30, - onPressed: () { - setState(() { - deleteFromWishlistFunction(itemID); - }); - }, - ) -// - ), - ), - Container( - margin: EdgeInsets.fromLTRB( - 0, - 16, - 10, - 16), - alignment: - Alignment.center, -// padding: EdgeInsets.only(left: 25, bottom: 20), - child: (model.recommendedProductList[index].images != null && - model.recommendedProductList[index].images.length > 0) - ? Image.network( - model.recommendedProductList[index].images[0].src.toString(), -// item.images[0].src, - fit: BoxFit.cover, - height: 60, - ) - : Image.asset( - "assets/images/no_image.png", - fit: BoxFit.cover, - height: 60, - ), - ), - Container( - width: model.recommendedProductList[index].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: - Texts( - model.recommendedProductList[index].rxMessage != null - ? model.recommendedProductList[index].rxMessage - : "", - color: - Colors.white, - regular: - true, - fontSize: - 10, - fontWeight: - FontWeight.w400, - ), - ), - ]), - Container( - margin: EdgeInsets - .symmetric( - horizontal: - 6, - vertical: 0, - ), - child: Column( - crossAxisAlignment: - CrossAxisAlignment - .start, - children: [ - Text( - languageID == - "ar" - ? model.recommendedProductList[index].namen - : model.recommendedProductList[index].name, - style: - TextStyle( - color: - Colors.black, - fontSize: - 13.0, -// fontWeight: FontWeight.bold, - ), - ), - Padding( -// padding: const EdgeInsets.only(top: 15, bottom: 10), - padding: const EdgeInsets.only( - top: - 10, - bottom: - 5), - child: - Texts( - "SAR ${model.recommendedProductList[index].price}", - bold: - true, - fontSize: - 14, - ), - ), - ], - ), - ), - Row( - crossAxisAlignment: - CrossAxisAlignment - .start, - children: < - Widget>[ - Container( - padding: - EdgeInsets.only(right: 10), -// margin: EdgeInsets.only(left: 5), - child: - Align( - alignment: - Alignment.topLeft, - child: - RatingBar.readOnly( - initialRating: - model.recommendedProductList[index].approvedRatingSum.toDouble(), -// initialRating: productRate, - size: - 13.0, - filledColor: - Colors.yellow[700], - emptyColor: - Colors.grey[500], - isHalfAllowed: - true, - halfFilledIcon: - Icons.star_half, - filledIcon: - Icons.star, - emptyIcon: - Icons.star, - ), - ), - ), - Texts( - "(${model.recommendedProductList[index].approvedTotalReviews.toString()})", -// bold: true, - fontSize: - 12, - ), - ]), - ], - ), - ), - ); - }), - ) - : Container( -// child: Text("NO DATA"), - ), - )), - ), - ], - ), - ), - ) - ], - ), - ), - bottomSheet: footerWidget( - widget.product.stockAvailability != 'Out of stock', - widget.product.orderMaximumQuantity, - widget.product.orderMinimumQuantity, - widget.product.stockQuantity, - widget.product), - ) - : AppScaffold( - appBarTitle: 'product detail page', - isShowAppBar: true, - isPharmacy: true, - isShowDecPage: false, - body: SingleChildScrollView( - child: Column( - children: [ - Container( - width: double.infinity, - color: Colors.white, - child: Column( - children: [ - Image.network( - widget.product.images[0].src.trim(), - ), - widget.product.discountDescription != null - ? Container( - width: double.infinity, - height: 50, - color: Colors.yellowAccent, - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Expanded( - flex: 1, - child: Container( - alignment: Alignment.centerRight, - child: languageID == 'ar' - ? Text( - widget.product - .discountDescriptionn, - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 17), - ) - : Text( - widget.product - .discountDescription, - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 17), - ), - ), - ), - SizedBox( - width: 10, - ), - Expanded( - flex: 0, - child: Container( - child: Image( - image: AssetImage( - 'assets/images/offer.png'), - ), - ), - ), - ], - ), - ) - : Container(), - ], - ), - ), - SizedBox( - height: 4, - ), - Container( - width: 500, - height: 150, - color: Colors.white, - child: productNameAndPrice(context, widget.product), - ), - SizedBox( - height: 6, - ), - Container( - width: 500, - height: 120, - color: Colors.white, - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.all(8.0), - child: Container( - child: Text( - TranslationBase.of(context).specification, - style: TextStyle(fontWeight: FontWeight.bold), - ), - ), - ), - Divider(color: Colors.grey) - ], - ), - ), - SizedBox( - height: 6, - ), - Container( - width: 500, - margin: EdgeInsets.only(bottom: 100), -// height: 350, - color: Colors.white, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Column( - children: [ - FlatButton( - onPressed: () { - setState(() { - isDetails = true; - isReviews = false; - isAvailabilty = false; - }); - }, - child: Text( - TranslationBase.of(context).details, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold), - ), - color: Colors.white, - ), - isDetails - ? Container( - width: 100, - height: 5, - color: Colors.green, - ) - : Container() - ], - ), - SizedBox( - width: 20, - ), - Column( - children: [ - FlatButton( - onPressed: () { - setState(() { - isDetails = false; - isReviews = true; - isAvailabilty = false; - }); - }, - child: Text( - TranslationBase.of(context).reviews, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold), - ), - color: Colors.white, - ), - isReviews - ? Container( - width: 100, - height: 5, - color: Colors.green, - ) - : Container(), - ], - ), - SizedBox( - width: 20, - ), - Column( - children: [ - FlatButton( - onPressed: () { - setState(() { - isDetails = false; - isReviews = false; - isAvailabilty = true; - }); - }, - child: Text( - TranslationBase.of(context).availability, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold), - ), - color: Colors.white, - ), - isAvailabilty - ? Container( - width: 100, - height: 5, - color: Colors.green, - ) - : Container(), - ], - ), - ], - ), - SizedBox( - height: 10, - ), - isDetails - ? Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - child: Text( - TranslationBase.of(context).description, - style: TextStyle( - fontSize: 17, - color: Colors.grey, - fontWeight: FontWeight.w600), - ), - ), - SizedBox( - height: 6, - ), - Divider(height: 1, color: Colors.grey), - SizedBox( - height: 10, - ), - Container( - child: Text( - languageID == 'ar' - ? widget.product.shortDescriptionn - : widget.product.shortDescription, - style: TextStyle( - fontSize: 16, - fontFamily: 'WorkSans-Regular'), - ), - ), - SizedBox( - height: 10, - ), - Container( - child: Text( - TranslationBase.of(context).howToUse, - style: TextStyle( - fontSize: 17, - color: Colors.grey, - fontWeight: FontWeight.w600), - ), - ), - SizedBox( - height: 6, - ), - Divider(height: 2, color: Colors.grey), - SizedBox( - height: 10, - ), - Container( - child: Text( - languageID == 'ar' - ? widget.product.fullDescriptionn - : widget.product.fullDescription, - style: TextStyle( - fontSize: 16, - fontFamily: 'WorkSans-Regular'), - ), - ), - ], - ), - ) - : isReviews - ? BaseView( - onModelReady: (model) => - model.getProductReviewsData( - widget.product.id), - builder: (_, model, wi) => model - .productDetailService - .length != - 0 && - model.productDetailService[0] - .reviews.length != - 0 - ? ListView.builder( - physics: ScrollPhysics(), - itemCount: model - .productDetailService[0] - .reviews - .length, - scrollDirection: Axis.vertical, - shrinkWrap: true, - itemBuilder: (BuildContext context, - int index) { - return Padding( - padding: EdgeInsets.all(8.0), - child: Column( - mainAxisAlignment: - MainAxisAlignment.start, - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Container( - child: Row( - children: [ - Container( - child: Text( - model - .productDetailService[ - 0] - .reviews[ - index] - .customerId - .toString(), - style: TextStyle( - fontSize: 17, - color: Colors - .grey, - fontWeight: - FontWeight - .w600), - ), - ), - Container( - margin: - EdgeInsets.only( - left: 210), - child: RatingBar - .readOnly( - initialRating: model - .productDetailService[ - 0] - .reviews[ - index] - .rating - .toDouble(), - size: 15.0, - filledColor: - Colors.yellow[ - 700], - emptyColor: Colors - .grey[500], - isHalfAllowed: - true, - halfFilledIcon: - Icons - .star_half, - filledIcon: - Icons.star, - emptyIcon: - Icons.star, - ), - ), - ], - ), - ), - SizedBox( - height: 10, - ), - Container( - child: Text( - model - .productDetailService[ - 0] - .reviews[index] - .reviewText, - style: TextStyle( - fontSize: 20), - ), - ), - SizedBox( - height: 50, - ), - Divider( - height: 1, - color: Colors.grey), - ], - ), - ); - }, - ) - : Container( - padding: EdgeInsets.all(15), - alignment: Alignment.center, - child: Text('No Reviews Available'), - ), - ) - : isAvailabilty - ? BaseView( - onModelReady: (model) => - model.getProductLocationData(), - builder: (_, model, wi) => - ListView.builder( - physics: ScrollPhysics(), - scrollDirection: Axis.vertical, - shrinkWrap: true, - itemCount: model - .productLocationService.length, - itemBuilder: (BuildContext context, - int index) { - return Padding( - padding: EdgeInsets.all(8.0), - child: Column( -// crossAxisAlignment: CrossAxisAlignment.start, -// mainAxisAlignment: MainAxisAlignment.start, - children: [ - Row( -// crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: - MainAxisAlignment.start, - children: [ - Expanded( - flex: 1, - child: Image.network(model - .productLocationService[ - index] - .projectImageUrl), - ), - SizedBox( - width: 10, - ), - Expanded( - flex: 4, - child: Text( - model - .productLocationService[ - index] - .locationDescription + - "\n" + - fixingString(model - .productLocationService[ - 0] - .cityName - .toString()), - style: TextStyle( - fontSize: 12), - ), - ), - Expanded( - flex: 1, - child: IconButton( - icon: Icon(Icons - .location_on), - color: Colors.red, - onPressed: () {}, - ), - ), - Expanded( - flex: 1, - child: IconButton( - icon: - Icon(Icons.phone), - color: Colors.red, - onPressed: () {}, - ), - ), - ], - ), - Divider( - height: 1.2, - color: Colors.grey) - ], - ), - ); - }, - ), - ) - : Container(), - ], - ), - ), -// ListView(scrollDirection: Axis.vertical, shrinkWrap: true, children: [Text('ENAD')]), - ], - ), - ), - bottomSheet: footerWidget( - widget.product.stockAvailability != 'Out of stock', - widget.product.orderMaximumQuantity, - widget.product.orderMinimumQuantity, - widget.product.stockQuantity, - widget.product), - ); - } -} - -class footerWidget extends StatefulWidget { - final bool isAvailble; - final int maxQuantity; - final int minQuantity; - final int quantityLimit; - final PharmacyProduct item; - - footerWidget(this.isAvailble, this.maxQuantity, this.minQuantity, - this.quantityLimit, this.item); - - @override - _footerWidgetState createState() => _footerWidgetState(); -} - -class _footerWidgetState extends State { - double quantityUI = 70; - bool showUI = false; - - @override - Widget build(BuildContext context) { - return Container( - width: double.infinity, - height: quantityUI, - color: Colors.white, - child: Column( - children: [ - showUI - ? Container( - width: double.infinity, - height: 90, - color: Colors.white, - child: Container( - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.all(8.0), - child: Text( - TranslationBase.of(context).quantity, - style: TextStyle( - fontSize: 15, fontWeight: FontWeight.bold), - ), - ), -// ListView( -// scrollDirection: Axis.horizontal, -// children: [ -// itemQuantity(), -// ], -// ), - Container( -// margin: EdgeInsets.symmetric(vertical: 20.0), - height: 50.0, - child: ListView( - scrollDirection: Axis.horizontal, - children: [ - InkWell( - child: Container( - alignment: Alignment.center, - width: 50.0, - color: Colors.white, - child: Text( - '1', - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 20), - ), - ), - onTap: () { - setState(() { - price = 1; - if (price >= widget.quantityLimit) { - isOverQuantity = true; - } else { - isOverQuantity = false; - return price; - } - }); - }, - ), - SizedBox( - width: 5, - ), - InkWell( - child: Container( - alignment: Alignment.center, - width: 50.0, - color: Colors.white, - child: Text( - '2', - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 20), - ), - ), - onTap: () { - setState(() { - price = 2; - if (price >= widget.quantityLimit) { - isOverQuantity = true; - } else { - isOverQuantity = false; - return price; - } - }); - }, - ), - SizedBox( - width: 5, - ), - InkWell( - child: Container( - alignment: Alignment.center, - width: 50.0, - color: Colors.white, - child: Text( - '3', - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 20), - ), - ), - onTap: () { - setState(() { - price = 3; - if (price >= widget.quantityLimit) { - isOverQuantity = true; - } else { - isOverQuantity = false; - return price; - } - }); - }, - ), - SizedBox( - width: 5, - ), - InkWell( - child: Container( - alignment: Alignment.center, - width: 50.0, - color: Colors.white, - child: Text( - '4', - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 20), - ), - ), - onTap: () { - setState(() { - price = 4; - if (price >= widget.quantityLimit) { - isOverQuantity = true; - } else { - isOverQuantity = false; - return price; - } - }); - }, - ), - SizedBox( - width: 5, - ), - InkWell( - child: Container( - alignment: Alignment.center, - width: 50.0, - color: Colors.white, - child: Text( - '5', - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 20), - ), - ), - onTap: () { - setState(() { - price = 5; - if (price >= widget.quantityLimit) { - isOverQuantity = true; - } else { - isOverQuantity = false; - return price; - } - }); - }, - ), - SizedBox( - width: 5, - ), - InkWell( - child: Container( - alignment: Alignment.center, - width: 50.0, - color: Colors.white, - child: Text( - '6', - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 20), - ), - ), - onTap: () { - setState(() { - price = 6; - if (price >= widget.quantityLimit) { - isOverQuantity = true; - } else { - isOverQuantity = false; - return price; - } - }); - }, - ), - SizedBox( - width: 5, - ), - InkWell( - child: Container( - alignment: Alignment.center, - width: 50.0, - color: Colors.white, - child: Text( - '7', - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 20), - ), - ), - onTap: () { - setState(() { - price = 7; - if (price >= widget.quantityLimit) { - isOverQuantity = true; - } else { - isOverQuantity = false; - return price; - } - }); - }, - ), - SizedBox( - width: 5, - ), - InkWell( - child: Container( - alignment: Alignment.center, - width: 50.0, - color: Colors.white, - child: Text( - '8', - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 20), - ), - ), - onTap: () { - setState(() { - price = 8; - if (price >= widget.quantityLimit) { - isOverQuantity = true; - } else { - isOverQuantity = false; - return price; - } - }); - }, - ), - SizedBox( - width: 5, - ), - InkWell( - child: Container( - alignment: Alignment.center, - width: 50.0, - color: Colors.white, - child: Text( - '9', - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 20), - ), - ), - onTap: () { - setState(() { - price = 9; - if (price >= widget.quantityLimit) { - isOverQuantity = true; - } else { - isOverQuantity = false; - return price; - } - }); - }, - ), - SizedBox( - width: 5, - ), - InkWell( - child: Container( - alignment: Alignment.center, - width: 50.0, - color: Colors.white, - child: Text( - '10', - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 20), - ), - ), - onTap: () { - setState(() { - price = 10; - if (price >= widget.quantityLimit) { - isOverQuantity = true; - } else { - isOverQuantity = false; - return price; - } - }); - }, - ), - SizedBox( - width: 5, - ), - Container( - width: 50.0, - child: TextField( - decoration: - InputDecoration(labelText: 'quantity #'), - onChanged: (text) { - print(price); - print(widget.quantityLimit); - if (int.tryParse(text) == null) { - text = ''; - } else { - setState(() { - price = int.parse(text); - if (price >= widget.quantityLimit) { - isOverQuantity = true; - } else { - isOverQuantity = false; - } - }); - } - }, - ), - ), - ], - ), - ) - ], - ), - ), - ) - : 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( - price.toString(), - style: TextStyle(fontSize: 20), - ), - ), - Expanded( - flex: 5, - child: Text( - TranslationBase.of(context).quantityShortcut, - style: TextStyle(fontSize: 16), - ), - ), - ], - ), - onPressed: () { - setState(() { - if (showUI) { - quantityUI = 70; - showUI = false; - } else { - quantityUI = 150; - showUI = true; - } - }); - }, - ), - ), - !widget.isAvailble && price > 0 || - price > widget.quantityLimit || - widget.item.rxMessage != null - ? Container( - width: 190, - height: 46, - color: Colors.grey, - child: Align( - alignment: Alignment.center, - child: Text( - TranslationBase.of(context).addToCart, - style: TextStyle( - color: Colors.white, - fontWeight: FontWeight.bold, - fontSize: 15), - ), - ), - ) - : InkWell( - onTap: () { - addToCartFunction(price, widget.item.id, context); - }, - child: Container( - alignment: Alignment.center, - width: 190, - height: 46, - color: Colors.green, - child: Text( - TranslationBase.of(context).addToCart, - style: TextStyle( - color: Colors.white, - fontWeight: FontWeight.bold, - fontSize: 15), - ), - ), - ), - SizedBox( - width: 5, - ), - !widget.isAvailble && price > 0 || - price > widget.quantityLimit || - widget.item.rxMessage != null - ? Container( - width: 120, - height: 46, - color: Colors.grey, - child: Align( - alignment: Alignment.center, - child: Text( - TranslationBase.of(context).buyNow, - style: TextStyle( - color: Colors.white, - fontWeight: FontWeight.bold, - fontSize: 15), - ), - ), - ) - : InkWell( - onTap: () { - print('buy now'); - addToCartFunction(price, widget.item.id, context); - Navigator.push( - context, - FadePage(page: CartOrderPage()), - ); - }, - child: Container( - alignment: Alignment.center, - width: 120, - height: 46, - color: Colors.blue, - child: Text( - TranslationBase.of(context).buyNow, - style: TextStyle( - color: Colors.white, - fontWeight: FontWeight.bold, - fontSize: 15), - ), - ), - ), - ], - ), - ], - ), - ); - } -} - -class productNameAndPrice extends StatefulWidget { - BuildContext context; - PharmacyProduct item; - - productNameAndPrice(this.context, this.item); - - @override - _productNameAndPriceState createState() => _productNameAndPriceState(); -} - -class _productNameAndPriceState extends State { - @override - Widget build(BuildContext context) { - return Column( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.all(8.0), - child: Row( - children: [ - Text( - widget.item.price.toString() + " " + "SAR", - style: TextStyle(fontWeight: FontWeight.bold, fontSize: 30), - ), - SizedBox( - width: 40, - ), - Text( - widget.item.stockAvailability, - style: widget.item.stockAvailability == 'Out of stock' - ? TextStyle(fontWeight: FontWeight.bold, color: Colors.red) - : TextStyle( - fontWeight: FontWeight.bold, color: Colors.green), - ), - SizedBox(width: 20), - widget.item.stockAvailability == 'Out of stock' && - customerId != null - ? InkWell( - onTap: () => - notifyMeWhenAvailable(context, widget.item.id), - child: Row(children: [ - Text( - TranslationBase.of(context).notifyMe, - style: TextStyle( - color: Colors.blue, - decoration: TextDecoration.underline, - ), - ), - SizedBox(width: 4), - Icon( - FontAwesomeIcons.bell, - color: Colors.blue, - size: 15.0, - ) - ]), - ) - : Container( - margin: languageID == 'ar' - ? EdgeInsets.only(right: 25) - : EdgeInsets.only(left: 25), - width: 40, - height: 40, - decoration: BoxDecoration( - color: Colors.grey, - borderRadius: BorderRadius.circular(30), - ), - child: IconButton( - icon: Icon(!isInWishlit - ? Icons.favorite_border - : Icons.favorite), - color: !isInWishlit ? Colors.white : Colors.red, - onPressed: () async { - if (customerId != null) { - if (!isInWishlit) { - await addToWishlistFunction(widget.item.id); - } else { - await deleteFromWishlistFunction(widget.item.id); - } - } else { - return; - } - setState(() {}); - }, - )), - ], - ), - ), - Padding( - padding: const EdgeInsets.all(8.0), - child: Container( - margin: EdgeInsets.only(left: 5), - child: Align( - alignment: - languageID == 'ar' ? Alignment.topRight : Alignment.topLeft, - child: Text( - languageID == 'ar' - ? widget.item.fullDescriptionn - : widget.item.fullDescription, - style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15), - ), - ), - ), - ), - Row( - children: [ - Expanded( - flex: 2, - child: Container( - margin: EdgeInsets.only(right: 150), - child: Align( - alignment: Alignment.bottomLeft, - child: RatingBar.readOnly( - initialRating: 3, - size: 15.0, - filledColor: Colors.yellow[700], - emptyColor: Colors.grey[500], - isHalfAllowed: true, - halfFilledIcon: Icons.star_half, - filledIcon: Icons.star, - emptyIcon: Icons.star, - ), - ), - ), - ), - Expanded( - flex: 1, - child: Container( - child: widget.item.rxMessage != null - ? Text( - languageID == 'ar' - ? widget.item.rxMessagen.toString() - : widget.item.rxMessage.toString(), - style: TextStyle(color: Colors.red, fontSize: 10), - ) - : Container()), - ), - widget.item.rxMessage != null - ? Icon( - FontAwesomeIcons.questionCircle, - color: Colors.red, - size: 15.0, - ) - : Container(), - ], - ), - ], - ); - } -} - -slideDetail() { - return Row( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.all(8.0), - child: Container( - padding: const EdgeInsets.symmetric(horizontal: 14.0, vertical: 15.0), - decoration: const BoxDecoration( - border: Border( - top: BorderSide(width: 0.5, color: Colors.grey), - left: BorderSide(width: 0.5, color: Colors.grey), - right: BorderSide(width: 0.5, color: Colors.grey), - bottom: BorderSide(width: 0.5, color: Colors.grey), - ), - color: Colors.white, - ), - child: const Text('1', - textAlign: TextAlign.center, - style: TextStyle(color: Color(0xFF000000))), - ), - ) - ], - ); -} - -fixingString(txt) { - String stringTxt; - String newTxt; - stringTxt = txt.toString(); - newTxt = stringTxt.split('.')[1]; - - return newTxt; -} - -getLanguageID() async { - languageID = await sharedPref.getString(APP_LANGUAGE); -} - -getSpecificationData(itemID) async { - ProductDetailViewModel x = new ProductDetailViewModel(); - specificationData = await x.productSpecificationData(itemID); -} - -addToCartFunction(quantity, itemID, BuildContext context) async { - GifLoaderDialogUtils.showMyDialog(context); - ProductDetailViewModel x = new ProductDetailViewModel(); - await x.addToCartData(quantity, itemID).then((value) { - GifLoaderDialogUtils.hideDialog(context); - }); -} - -notifyMeWhenAvailable(context, itemId) async { - ProductDetailViewModel x = new ProductDetailViewModel(); - await x.notifyMe(customerId, itemId); -} - -addToWishlistFunction(itemID) async { - ProductDetailViewModel x = new ProductDetailViewModel(); - isInWishlit = true; - await x.addToWishlistData(itemID); -} - -deleteFromWishlistFunction(itemID) async { - ProductDetailViewModel x = new ProductDetailViewModel(); - isInWishlit = false; - await x.deletWishlistData(itemID); -} - -checkWishlist() async { - ProductDetailViewModel x = new ProductDetailViewModel(); - await x.checkWishlistData(); - -// isInWishlit = x.wishListItems.map((e) => e.id.toString()).toList().contains(itemID); - - for (int i = 0; i < x.wishListItems.length; i++) { - if (itemID == x.wishListItems[i].product.id) { - isInWishlit = true; - break; - } else { - isInWishlit = false; - } - } -} - -class sttingModalBottomSheet extends StatelessWidget { - @override - Widget build(BuildContext context) { - return Container(); - } -} - -settingModalBottomSheet(context) { - showModalBottomSheet( - context: context, - builder: (BuildContext bc) { - return Container( - child: new Wrap( - children: [ - new ListTile( - leading: Icon(Icons.shopping_cart), - title: Text('Add to cart'), - onTap: () => { - if (price > 0) - {addToCartFunction(price, itemID, context)} - else - { - AppToast.showErrorToast( - message: "you should add quantity") - } - }), - ListTile( - leading: Icon(Icons.favorite_border), - title: Text('Add to wishlist'), - onTap: () => {addToWishlistFunction(itemID)}, - ), - ListTile( - leading: Icon(Icons.compare), - title: Text('Compare'), - onTap: () => { - Provider.of(context, listen: false) - .addItem(specificationData), - }, - ), - ], - ), - ); - }); -} diff --git a/lib/pages/pharmacies/screens/address-select-page.dart b/lib/pages/pharmacies/screens/address-select-page.dart index 6c39ba3f..6b0b1140 100644 --- a/lib/pages/pharmacies/screens/address-select-page.dart +++ b/lib/pages/pharmacies/screens/address-select-page.dart @@ -1,5 +1,5 @@ import 'package:diplomaticquarterapp/core/model/pharmacies/Addresses.dart'; -import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/OrderPreviewViewModel.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/custom_text_button.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/material.dart'; @@ -17,14 +17,16 @@ class AddressSelectPageTest extends StatelessWidget { body: Column( children: [ Container( - child: RaisedButton( + child: CustomTextButton( onPressed: () => {Navigator.pop(context, addresses[0])}, child: new Text( "Set address", style: new TextStyle(color: Colors.white, fontSize: 14), ), - color: Colors.blueAccent, - disabledColor: Colors.blueAccent, + elevation: 0, + backgroundColor: Colors.blueAccent, + disabledForegroundColor: Colors.blueAccent.withOpacity(0.38), + disabledBackgroundColor: Colors.blueAccent.withOpacity(0.12), ), ), ], diff --git a/lib/pages/pharmacies/screens/cart-order-page.dart b/lib/pages/pharmacies/screens/cart-order-page.dart deleted file mode 100644 index f672cc66..00000000 --- a/lib/pages/pharmacies/screens/cart-order-page.dart +++ /dev/null @@ -1,390 +0,0 @@ -import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; -import 'package:diplomaticquarterapp/core/model/pharmacies/Addresses.dart'; -import 'package:diplomaticquarterapp/core/model/pharmacies/ShoppingCartResponse.dart'; -import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/OrderPreviewViewModel.dart'; -import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; -import 'package:diplomaticquarterapp/pages/base/base_view.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/screens/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/transitions/fade_page.dart'; -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; - -class CartOrderPage extends StatelessWidget { - @override - Widget build(BuildContext context) { - final mediaQuery = MediaQuery.of(context); - - final height = mediaQuery.size.height - 60 - mediaQuery.padding.top; - - return BaseView( - onModelReady: (model) => model.getOrderPreviewData(), - builder: (_, model, wi) => ChangeNotifierProvider.value( - value: model.cartResponse, - child: AppScaffold( - appBarTitle: TranslationBase.of(context).shoppingCart, - isShowAppBar: true, - isPharmacy: true, - baseViewModel: model, - backgroundColor: Colors.white, - body: !(model.cartResponse.shoppingCarts == null || - model.cartResponse.shoppingCarts.length == 0) - ? Container( - height: height * 0.85, - width: double.infinity, - child: Consumer( - builder: (ctx, cart, _) => Container( - 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( - cart.shoppingCarts != null - ? cart.shoppingCarts.length - : 0, - (index) => ProductOrderItem( - cart.shoppingCarts[index], () { - print(cart.shoppingCarts[index] - .quantity); - model - .changeProductQuantity( - cart.shoppingCarts[index]) - .then((value) { - if (model.state == - ViewState.ErrorLocal) { - Utils.showErrorToast( - model.error); - } - }); - }, - () => model.deleteProduct( - cart.shoppingCarts[index]))) - ], - ), - ), - 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} ${(cart.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} ${(cart.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} ${(cart.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, - ) - ], - ), - ), - ), - ), - ), - ) - : 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( - '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), - ), - ), - ), - ); - } -} - -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); - - return Container( - margin: EdgeInsets.symmetric(horizontal: 10, vertical: 0), - child: Consumer( - builder: (ctx, cart, _) => !(cart.shoppingCarts == null || - cart.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.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.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), - ), - color: Color(0xff005aff), - disabledColor: Color(0xff005aff), - ), - ], - ), - ), - ], - ) - : Container(), - )); - } -} 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 5d271a1a..00000000 --- a/lib/pages/pharmacies/screens/cart-order-preview.dart +++ /dev/null @@ -1,947 +0,0 @@ -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/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/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/transitions/fade_page.dart'; -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; - -class OrderPreviewPage extends StatelessWidget { - final List addresses; - - OrderPreviewPage(this.addresses); - - MyInAppBrowser browser; - - @override - Widget build(BuildContext context) { - final mediaQuery = MediaQuery.of(context); - final height = mediaQuery.size.height - 60 - mediaQuery.padding.top; - - return BaseView( - onModelReady: (model) => model.getShoppingCart(), - builder: (_, model, wi) => ChangeNotifierProvider.value( - value: model.paymentCheckoutData, - child: AppScaffold( - appBarTitle: "${TranslationBase.of(context).checkOut}", - isShowAppBar: true, - isPharmacy: true, - isShowDecPage: false, - backgroundColor: Colors.white, - baseViewModel: model, - body: Container( - height: height * 0.90, - child: SingleChildScrollView( - child: Container( - color: Color(0xFFF1F1F1), - child: Column( - children: [ - SelectAddressWidget(model, addresses), - SizedBox( - height: 10, - ), - SelectPaymentOptionWidget(model), - SizedBox( - height: 10, - ), - Consumer( - builder: (ctx, paymentData, _) => - paymentData.lacumInformation != null - ? Container( - child: Column( - children: [ - LakumWidget(model), - SizedBox( - height: 10, - ), - ], - ), - ) - : Container()), - Container( - color: Colors.white, - width: double.infinity, - padding: EdgeInsets.all(8), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts( - TranslationBase - .of(context) - .reviewOrder, - fontSize: 14, - fontWeight: FontWeight.bold, - color: Colors.black, - ), - ...List.generate( - model.cartResponse.shoppingCarts != null - ? model.cartResponse.shoppingCarts.length - : 0, - (index) => - ProductOrderPreviewItem( - model.cartResponse - .shoppingCarts[index]), - ), - ], - ), - ), - Container( - width: double.infinity, - padding: EdgeInsets.all(8), - child: model.cartResponse.subtotal != null - ? Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Texts( - TranslationBase - .of(context) - .orderSummary, - fontSize: 14, - fontWeight: FontWeight.bold, - color: Colors.black, - ), - SizedBox( - height: 20, - ), - 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) - .shipping}", - fontSize: 14, - color: Colors.black, - fontWeight: FontWeight.w500, - ), - Texts( - "${TranslationBase - .of(context) - .sar} ${(model - .totalAdditionalShippingCharge) - .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, - ), - ], - ), - SizedBox( - height: 10, - ), - ], - ) - : Container(), - ) - ], - ), - ), - ), - ), - bottomSheet: Container( - height: model.cartResponse.shoppingCarts != null - ? height * 0.10 - : 0, - color: Colors.white, - child: PaymentBottomWidget(model), - ), - ), - )); - } -} - -class SelectAddressWidget extends StatefulWidget { - final OrderPreviewViewModel model; - final List addresses; - - SelectAddressWidget(this.model, this.addresses); - - @override - _SelectAddressWidgetState createState() => _SelectAddressWidgetState(); -} - -class _SelectAddressWidgetState extends State { - Addresses address; - - _navigateToAddressPage() { - Navigator.push(context, FadePage(page: PharmacyAddressesPage())) - .then((result) { - if (result != null) { - address = result; - widget.model.paymentCheckoutData.address = address; - widget.model.getInformationsByAddress(); - } - - /* 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; - } - super.initState(); - } - - @override - Widget build(BuildContext context) { - return Consumer( - builder: (ctx, paymentData, _) => - Container( - color: Colors.white, - child: address == null - ? InkWell( - onTap: () => {_navigateToAddressPage()}, - child: Container( - margin: EdgeInsets.symmetric(vertical: 12, horizontal: 12), - child: Row( - children: [ - Image.asset( - "assets/images/pharmacy_module/ic_shipping_address.png", - width: 30.0, - height: 30.0, - fit: BoxFit.scaleDown, - ), - Expanded( - child: Container( - padding: - EdgeInsets.symmetric(vertical: 0, horizontal: 6), - child: Texts( - TranslationBase - .of(context) - .selectAddress, - fontSize: 14, - fontWeight: FontWeight.bold, - color: Color(0xff0000ff), - ), - ), - ), - Icon( - Icons.arrow_forward_ios, - size: 20, - color: Colors.grey.shade400, - ), - ], - ), - ), - ) - : Container( - child: Container( - margin: EdgeInsets.symmetric(vertical: 12, horizontal: 12), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - Image.asset( - "assets/images/pharmacy_module/ic_shipping_mark.png", - width: 30.0, - height: 30.0, - fit: BoxFit.scaleDown, - ), - Expanded( - child: Container( - padding: EdgeInsets.symmetric( - vertical: 0, horizontal: 6), - child: Texts( - TranslationBase - .of(context) - .shippingAddress, - fontSize: 14, - fontWeight: FontWeight.bold, - color: Colors.black, - ), - ), - ), - InkWell( - onTap: () => {_navigateToAddressPage()}, - child: Texts( - TranslationBase - .of(context) - .changeAddress, - fontSize: 12, - fontWeight: FontWeight.normal, - color: Color(0xff0000ff), - ), - ), - ], - ), - Padding( - padding: const EdgeInsets.symmetric(vertical: 8), - child: Texts( - "${address.firstName} ${address.lastName}", - fontSize: 14, - fontWeight: FontWeight.bold, - color: Colors.black, - ), - ), - Padding( - padding: const EdgeInsets.symmetric(vertical: 8), - child: Texts( - "${address.address1} ${address.address2} ${address - .address2},, ${address.city}, ${address - .country} ${address.zipPostalCode}", - fontSize: 12, - fontWeight: FontWeight.normal, - color: Colors.grey.shade500, - ), - ), - Row( - children: [ - Container( - margin: const EdgeInsets.only(right: 8), - child: Icon( - Icons.phone, - size: 20, - color: Colors.black, - ), - ), - Texts( - "${address.phoneNumber}", - fontSize: 14, - fontWeight: FontWeight.bold, - color: Colors.grey, - ), - ], - ), - Container( - margin: EdgeInsets.symmetric(vertical: 8), - child: SizedBox( - height: 2, - width: double.infinity, - child: Container( - color: Color(0xffefefef), - ), - ), - ), - Row( - children: [ - Image.asset( - "assets/images/pharmacy_module/ic_shipping_truck.png", - width: 30.0, - height: 30.0, - fit: BoxFit.scaleDown, - ), - Container( - padding: EdgeInsets.symmetric( - vertical: 0, horizontal: 6), - child: Texts( - "${TranslationBase - .of(context) - .shipBy}", - fontSize: 12, - fontWeight: FontWeight.bold, - color: Colors.black, - ), - ), - Container( - child: Image.asset( - paymentData.shippingOption - .shippingRateComputationMethodSystemName == - "Shipping.FixedOrByWeight" - ? "assets/images/pharmacy_module/payment/hmg_shipping_logo.png" - : "assets/images/pharmacy_module/payment/aramex_shipping_logo.png", - fit: BoxFit.contain, - ), - margin: EdgeInsets.symmetric(horizontal: 8), - ), - ], - ), - ], - ), - ), - ), // ic_shipping_mark.png - ), - ); - } -} - -class SelectPaymentOptionWidget extends StatefulWidget { - final OrderPreviewViewModel model; - - SelectPaymentOptionWidget(this.model); - - @override - _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; - widget.model.paymentCheckoutData.updateData(); - } - }) - }); - } - - @override - void initState() { - if (widget.model.paymentCheckoutData.paymentOption != null) { - paymentOption = widget.model.paymentCheckoutData.paymentOption; - } - super.initState(); - } - - @override - Widget build(BuildContext context) { - return Container( - color: Colors.white, - child: paymentOption == null - ? InkWell( - onTap: () => {_navigateToPaymentOption()}, - child: Container( - margin: EdgeInsets.symmetric(vertical: 12, horizontal: 12), - child: Row( - children: [ - Image.asset( - "assets/images/pharmacy_module/ic_payment_option.png", - width: 30.0, - height: 30.0, - fit: BoxFit.scaleDown, - ), - Expanded( - child: Container( - padding: - EdgeInsets.symmetric(vertical: 0, horizontal: 6), - child: Texts( - TranslationBase - .of(context) - .selectPaymentOption, - fontSize: 14, - fontWeight: FontWeight.bold, - color: Color(0xff0000ff), - ), - ), - ), - Icon( - Icons.arrow_forward_ios, - size: 20, - color: Colors.grey.shade400, - ), - ], - ), - ), - ) - : Container( - margin: EdgeInsets.symmetric(vertical: 12, horizontal: 12), - child: Row( - children: [ - Image.asset( - "assets/images/pharmacy_module/ic_payment_option.png", - width: 30.0, - height: 30.0, - fit: BoxFit.scaleDown, - ), - Container( - margin: EdgeInsets.symmetric(horizontal: 8), - padding: EdgeInsets.symmetric(horizontal: 4, vertical: 0), - decoration: new BoxDecoration( - color: Colors.grey.shade100, - shape: BoxShape.rectangle, - ), - child: Image.asset( - widget.model.getPaymentOptionImage(paymentOption), - width: 30.0, - height: 30.0, - fit: BoxFit.scaleDown, - ), - ), - Expanded( - child: Container( - padding: EdgeInsets.symmetric(vertical: 0, horizontal: 6), - child: Texts( - widget.model.getPaymentOptionName(paymentOption), - fontSize: 14, - fontWeight: FontWeight.bold, - color: Colors.black, - ), - ), - ), - InkWell( - onTap: () => {_navigateToPaymentOption()}, - child: Texts( - TranslationBase - .of(context) - .changeMethod, - fontSize: 12, - fontWeight: FontWeight.normal, - color: Color(0xff0000ff), - ), - ), - ], - ), - ), - ); - } -} - -class LakumWidget extends StatefulWidget { - final OrderPreviewViewModel model; - - LakumWidget(this.model); - - @override - _LakumWidgetState createState() => _LakumWidgetState(); -} - -class _LakumWidgetState extends State { - TextEditingController _pointsController = new TextEditingController(); - - @override - Widget build(BuildContext context) { - ProjectViewModel projectProvider = Provider.of(context); - - return Container( - color: Colors.white, - padding: EdgeInsets.symmetric(vertical: 12, horizontal: 12), - child: Row( - children: [ - Image.asset( - "assets/images/pharmacy_module/lakum/lakum_checkout.png", - width: 30.0, - fit: BoxFit.scaleDown, - ), - Container( - decoration: BoxDecoration(color: Color(0x99ffffff)), - padding: const EdgeInsets.symmetric(horizontal: 8), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts( - "${TranslationBase - .of(context) - .lakumPoints}", - fontSize: 12, - fontWeight: FontWeight.bold, - ), - Texts( - "${widget.model.paymentCheckoutData.lacumInformation - .lakumInquiryInformationObjVersion.pointsBalanceAmount}", - fontSize: 12, - fontWeight: FontWeight.normal, - ), - ], - ), - ), - Expanded( - child: Container( - decoration: BoxDecoration(color: Color(0x99ffffff)), - padding: const EdgeInsets.symmetric(horizontal: 8), - child: Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - Texts( - "${TranslationBase - .of(context) - .riyal}", - fontSize: 12, - fontWeight: FontWeight.bold, - ), - Container( - margin: projectProvider.isArabic - ? EdgeInsets.only(right: 4) - : EdgeInsets.only(left: 4), - width: 60, - height: 50, - child: TextField( - decoration: InputDecoration( - border: OutlineInputBorder( - borderSide: - BorderSide(color: Colors.black, width: 0.2), - gapPadding: 0, - borderRadius: projectProvider.isArabic - ? BorderRadius.only( - topRight: Radius.circular(8), - bottomRight: Radius.circular(8)) - : BorderRadius.only( - topLeft: Radius.circular(8), - bottomLeft: Radius.circular(8)), - ), - disabledBorder: OutlineInputBorder( - borderSide: - BorderSide(color: Colors.black, width: 0.4), - gapPadding: 0, - borderRadius: BorderRadius.only( - topLeft: Radius.circular(8), - bottomLeft: Radius.circular(8)), - ), - ), - controller: _pointsController, - keyboardType: TextInputType.number, - style: TextStyle( - fontSize: 14, - color: widget - .model - .paymentCheckoutData - .lacumInformation - .lakumInquiryInformationObjVersion - .pointsBalanceAmount > - 0 - ? Colors.black - : Colors.grey, - ), - enabled: widget - .model - .paymentCheckoutData - .lacumInformation - .lakumInquiryInformationObjVersion - .pointsBalanceAmount == - 0 - ? false - : true, - onChanged: (val) { - var value = int.tryParse(val); - if (value != null && - value <= - widget - .model - .paymentCheckoutData - .lacumInformation - .lakumInquiryInformationObjVersion - .pointsBalanceAmount) { - widget.model.paymentCheckoutData.usedLakumPoints = - value; - } else { - widget.model.paymentCheckoutData.usedLakumPoints = 0; - } - _pointsController.text = - "${widget.model.paymentCheckoutData.usedLakumPoints}"; - }, - ), - ), - Container( - height: 50, - padding: EdgeInsets.symmetric(horizontal: 8, vertical: 12), - decoration: new BoxDecoration( - color: Color(0xff3666E0), - shape: BoxShape.rectangle, - borderRadius: projectProvider.isArabic - ? BorderRadius.only( - topLeft: Radius.circular(6), - bottomLeft: Radius.circular(6)) - : BorderRadius.only( - topRight: Radius.circular(6), - bottomRight: Radius.circular(6)), - border: Border.fromBorderSide(BorderSide( - color: Color(0xff3666E0), - width: 0.8, - )), - ), - child: Texts( - "${TranslationBase - .of(context) - .use}", - fontSize: 12, - color: Colors.white, - fontWeight: FontWeight.bold, - ), - ), - ], - ), - ), - ), - ], - ), - ); - } -} - -class PaymentBottomWidget extends StatelessWidget { - final OrderPreviewViewModel model; - - BuildContext context; - MyInAppBrowser browser; - - PaymentBottomWidget(this.model); - - @override - Widget build(BuildContext context) { - final scaffold = Scaffold.of(context); - this.context = context; - - return Container( - margin: EdgeInsets.symmetric(horizontal: 10, vertical: 0), - child: Consumer( - builder: (ctx, paymentData, _) => - paymentData.cartDataVisible - ? Container( - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Container( - margin: - EdgeInsets.symmetric(horizontal: 0, vertical: 4), - child: Row( - children: [ - Texts( - "${TranslationBase - .of(context) - .sar} ${(model.cartResponse.subtotal) - .toStringAsFixed(2)}", - fontSize: 14, - fontWeight: FontWeight.bold, - color: Color(0xff929295), - ), - Padding( - padding: - const EdgeInsets.symmetric(horizontal: 4), - child: Texts( - "${TranslationBase - .of(context) - .inclusiveVat}", - fontSize: 8, - color: Color(0xff929295), - fontWeight: FontWeight.w600, - ), - ), - ], - ), - ), - Texts( - "${model.cartResponse.quantityCount} ${TranslationBase - .of(context) - .items}", - fontSize: 10, - color: Colors.grey, - fontWeight: FontWeight.bold, - ), - ], - ), - Container( - child: RaisedButton( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8), - side: BorderSide( - color: Color(0xff929295), - width: 1, - ), - ), - onPressed: (paymentData.address != null && - paymentData.paymentOption != null) - ? () async { - await model.makeOrder(); - if (model.state == ViewState.Idle) { - AppToast.showSuccessToast( - message: "Order has been placed successfully!!"); - openPayment(model.orderListModel[0], model.user); - } else { - AppToast.showErrorToast(message: model.error); - } - Navigator.pop(context); - Navigator.pop(context); - } - : null, - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 16), - child: new Text( - "${TranslationBase - .of(context) - .proceedPay}", - style: new TextStyle( - color: (paymentData.address != null && - paymentData.paymentOption != null) - ? Colors.white - : Colors.grey.shade400, - fontWeight: FontWeight.bold, - fontSize: 12), - ), - ), - color: (paymentData.address != null && - paymentData.paymentOption != null) - ? Colors.green - : Color(0xff929295), - disabledColor: (paymentData.address != null && - paymentData.paymentOption != null) - ? Colors.green - : Color(0xff929295), - ), - ), - ], - ), - ) - : Container(), - ), - ); - } - - openPayment(OrderDetailModel order, - AuthenticatedUser authenticatedUser,) { - browser = new MyInAppBrowser( - onExitCallback: onBrowserExit, onLoadStartCallback: onBrowserLoadStart); - - browser.openPharmacyPaymentBrowser( - order, - order.orderTotal, - 'ePharmacy Order', - order.id, - order.billingAddress.email, - order.customValuesXml, - "${authenticatedUser.firstName} ${authenticatedUser - .middleName} ${authenticatedUser.lastName}", - authenticatedUser.patientID, - authenticatedUser, - browser); - } - - onBrowserLoadStart(String url) { - print("onBrowserLoadStart"); - print(url); - - MyInAppBrowser.successURLS.forEach((element) { - if (url.contains(element)) { - if (browser.isOpened()) browser.close(); - MyInAppBrowser.isPaymentDone = true; - return; - } - }); - - MyInAppBrowser.errorURLS.forEach((element) { - if (url.contains(element)) { - if (browser.isOpened()) browser.close(); - MyInAppBrowser.isPaymentDone = false; - return; - } - }); - } - - onBrowserExit(AppoitmentAllHistoryResultList appo, bool isPaymentMade) { - print("onBrowserExit Called!!!!"); - if (isPaymentMade) { - AppToast.showSuccessToast( - message: "شكراً\nPayment status for your order is Paid"); - Navigator.pop(context); - Navigator.pop(context); - } else { - AppToast.showErrorToast( - message: - "Transaction Failed!\Your transaction is field to some reason please try again or contact to the administration"); - } - } -} diff --git a/lib/pages/pharmacies/screens/cart-page/cart-order-page.dart b/lib/pages/pharmacies/screens/cart-page/cart-order-page.dart new file mode 100644 index 00000000..98ff43e1 --- /dev/null +++ b/lib/pages/pharmacies/screens/cart-page/cart-order-page.dart @@ -0,0 +1,458 @@ +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +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/pharmacy-terms-conditions-page.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/widgets/ProductOrderItem.dart'; +import 'package:diplomaticquarterapp/pages/pharmacy/order/Order.dart'; +import 'package:diplomaticquarterapp/pages/pharmacy/pharmacyAddresses/PharmacyAddresses.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'; +import 'package:diplomaticquarterapp/widgets/buttons/GestureIconButton.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/custom_text_button.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: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 void Function(int)? changeTab; + + CartOrderPage({Key? key, this.changeTab}) : super(key: key); + + @override + _CartOrderPageState createState() => _CartOrderPageState(); +} + +class _CartOrderPageState extends State { + bool isLoading = true; + late String customerId; + late String customerGUID; + + @override + void initState() { + super.initState(); + getCustomer(); + 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; + return AppScaffold( + appBarTitle: TranslationBase.of(context).shoppingCart, + isShowAppBar: true, + isPharmacy: true, + showHomeAppBarIcon: false, + isShowDecPage: false, + isMainPharmacyPages: true, + showPharmacyCart: false, + baseViewModel: model, + backButtonTab:(){ + widget.changeTab!; + } + , + + backgroundColor: Colors.white, + body: NetworkBaseView( + isLoading: isLoading, + isLocalLoader: true, + child: !(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: ListView.builder( + itemCount: model.cartResponse.shoppingCarts!.length, + scrollDirection: Axis.vertical, + shrinkWrap: true, + physics: ScrollPhysics(), + // physics: const AlwaysScrollableScrollPhysics(), + itemBuilder: (context, index) { + return ProductOrderItem( + item: model.cartResponse.shoppingCarts![index], + changeCartItems: () async { + GifLoaderDialogUtils.showMyDialog(context); + await model.changeProductQuantity(model.cartResponse.shoppingCarts![index]); + if (model.state != ViewState.Error) {} + if (model.state == ViewState.ErrorLocal) { + Utils.showErrorToast(model.error); + } + GifLoaderDialogUtils.hideDialog(context); + }, + deleteCartItems: () async { + GifLoaderDialogUtils.showMyDialog(context); + await model.deleteProduct(model.cartResponse.shoppingCarts![index]).then((value) { + if (model.state == ViewState.ErrorLocal) { + Utils.showErrorToast(model.error); + } + GifLoaderDialogUtils.hideDialog(context); + }); + }, + model: model, + ); + }), + ), + 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.subtotalWithVat)!.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.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, + style: TextStyle(fontSize: 30), + ), + ), + Padding( + padding: const EdgeInsets.fromLTRB(60.0, 8.0, 60.0, 0.0), + child: DefaultButton( + TranslationBase.of(context).ordersDashboard, + () { + Navigator.push(context, FadePage(page: OrderPage(customerID: customerId, customerGUID: customerGUID))); + }, + color: Colors.green, + ), + ), + ], + ), + ), + ), + bottomSheet: Container( + height: !(model.cartResponse.shoppingCarts == null || model.cartResponse.shoppingCarts!.length == 0) ? height * 0.15 : 0, + color: Colors.white, + child: OrderBottomWidget(model.addresses, height, model, isLoading), + ), + ); + } + + getCustomer() async { + String custID; + String custGUID; + custID = await sharedPref.getString(PHARMACY_CUSTOMER_ID); + custGUID = await sharedPref.getObject(PHARMACY_CUSTOMER_GUID); + setState(() { + customerId = custID; + customerGUID = custGUID; + }); + print("customer Id is" + customerId); + print("customer GUID is" + customerGUID); + return customerId; + } + + void getData() async { + await Provider.of(context, listen: false).getShoppingCart(); + setState(() { + isLoading = false; + }); + } +} + +class OrderBottomWidget extends StatefulWidget { + final List addresses; + final double height; + final OrderPreviewViewModel model; + final bool isLoading; + + OrderBottomWidget(this.addresses, this.height, this.model, this.isLoading); + + @override + _OrderBottomWidgetState createState() => _OrderBottomWidgetState(); +} + +class _OrderBottomWidgetState extends State { + bool isAgree = false; + + @override + Widget build(BuildContext context) { + ProjectViewModel projectProvider = Provider.of(context); + + return !widget.isLoading && !(widget.model.cartResponse.shoppingCarts == null || widget.model.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.only(left: 15.0, right: 15.0), + 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(0xFF4CAF50), +// color: Color(0xff005aff), + ), + ), + ), + ], + ), + ), + Container( + height: widget.height * 0.065, + margin: EdgeInsets.only(top: 5.0, bottom: 5.0), + padding: EdgeInsets.only(left: 20.0, right: 20.0), + 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} ${(widget.model.cartResponse.subtotalWithVat)!.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( + "${widget.model.cartResponse.quantityCount} ${TranslationBase.of(context).items}", + fontSize: 10, + color: Colors.grey, + fontWeight: FontWeight.bold, + ), + ], + ), + ), + CustomTextButton( + backgroundColor: Color(0xFF4CAF50), + disabledForegroundColor: Color(0xFF848484).withOpacity(0.38), + disabledBackgroundColor: Color(0xFF848484).withOpacity(0.12), + onPressed: isAgree + ? () => { + if (widget.model.isCartItemsOutOfStock()) + {AppToast.showErrorToast(message: TranslationBase.of(context).outOfStockMsg)} + else + {_navigateToAddressPage(projectProvider.user!.patientIdentificationNo!)} + } + : null, + child: new Text( + "${TranslationBase.of(context).checkOut}", + style: new TextStyle(color: isAgree ? Colors.white : Colors.grey.shade300, fontSize: 14), + ), + +// disabledColor: Color(0xff005aff), + ) + ], + ), + ), + ], + ) + : Container(); + } + + _navigateToAddressPage(String identificationNo) { + Navigator.push( + context, + FadePage( + page: PharmacyAddressesPage( + orderPreviewViewModel: widget.model, + isShippingAddress: true, + ))).then((result) async { + if (result != null) { + GifLoaderDialogUtils.showMyDialog(context); + var address = result; + widget.model.paymentCheckoutData.address = Addresses.fromJson(address.toJson()); + await widget.model.getInformationsByAddress(identificationNo); + await widget.model.getShoppingCart(); + // widget.changeMainState(); + GifLoaderDialogUtils.hideDialog(context); + } + }); + } +} diff --git a/lib/pages/pharmacies/screens/cart-page/cart-order-preview.dart b/lib/pages/pharmacies/screens/cart-page/cart-order-preview.dart new file mode 100644 index 00000000..782cd05c --- /dev/null +++ b/lib/pages/pharmacies/screens/cart-page/cart-order-preview.dart @@ -0,0 +1,369 @@ +import 'dart:ui'; + +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/payment_bottom_widget.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/screens/cart-page/select_address_widget.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/screens/cart-page/select_payment_option_widget.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/widgets/ProductOrderPreviewItem.dart'; +import 'package:diplomaticquarterapp/theme/colors.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:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class OrderPreviewPage extends StatefulWidget { + final List? addresses; + final OrderPreviewViewModel? model; + + OrderPreviewPage({this.addresses, this.model}); + + @override + _OrderPreviewPageState createState() => _OrderPreviewPageState(); +} + +class _OrderPreviewPageState extends State { + MyInAppBrowser? browser; + bool isLoading = true; + bool isChecked = false; + + @override + void initState() { + super.initState(); + getData(); + } + + void getData() async { + if (isLoading) await Provider.of(context, listen: false).getShoppingCart(); + setState(() { + isLoading = false; + }); + } + + @override + Widget build(BuildContext context) { + final mediaQuery = MediaQuery.of(context); + final height = mediaQuery.size.height - 60 - mediaQuery.padding.top; + ProjectViewModel projectViewModel = Provider.of(context); + return AppScaffold( + appBarTitle: "${TranslationBase.of(context).checkOut}", + isShowAppBar: true, + isPharmacy: true, + isShowDecPage: false, + isLoading: isLoading, + isLocalLoader: true, + backgroundColor: Colors.white, + // baseViewModel: widget.model, + body: Container( + color: Color(0xFFF1F1F1), + height: height * 0.90, + child: SingleChildScrollView( + child: Container( + color: Color(0xFFF1F1F1), + child: Column( + children: [ + SelectAddressWidget( + widget.model!, + widget.addresses!, + changeMainState, + isUpdating: true, + ), + SizedBox( + height: 10, + ), + SelectPaymentOptionWidget( + widget.model!, + changeMainState, + isUpdating: true, + ), + SizedBox( + height: 10, + ), + widget.model!.paymentCheckoutData.lacumInformation != null + ? Stack( + children: [ + Container( + child: Column( + children: [ + Container( + color: Colors.white, + padding: EdgeInsets.symmetric(vertical: 12, horizontal: 12), + child: Row( + children: [ + Row( + children: [ + SizedBox( + height: 24.0, + width: 24.0, + child: Checkbox( + activeColor: CustomColors.green, + value: isChecked, + onChanged: (bool? value) { + setState(() { + isChecked = value!; + if (value!) { + PaymentBottomWidget.isChecked = true; + } else { + PaymentBottomWidget.isChecked = false; + } + setState(() {}); + }); + }, + ), + ), + Padding( + padding: const EdgeInsets.only(left: 8.0, right: 8.0), + child: Text( + TranslationBase.of(context).useLakumPoints + + " (${widget.model!.paymentCheckoutData.lacumInformation!.lakumInquiryInformationObjVersion!.pointsBalance.toString() + " " + TranslationBase.of(context).points})", + style: TextStyle(fontSize: 12.0, fontWeight: FontWeight.w600, letterSpacing: -0.56)), + ), + ], + ), + Expanded( + child: Container( + decoration: BoxDecoration(color: Color(0x99ffffff)), + padding: const EdgeInsets.symmetric(horizontal: 8), + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Container( + decoration: BoxDecoration(color: Color(0x99ffffff)), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Texts( + "${TranslationBase.of(context).availableBalance}", + fontSize: 12, + fontWeight: FontWeight.bold, + ), + Text( + "${TranslationBase.of(context).sar + " " + widget.model!.paymentCheckoutData.lacumInformation!.lakumInquiryInformationObjVersion!.pointsBalanceAmount.toString()}", + style: TextStyle(fontSize: 12.0, fontWeight: FontWeight.w600, letterSpacing: -0.56)), + ], + ), + ), + ], + ), + ), + ), + ], + ), + ), + SizedBox( + height: 10, + ), + ], + ), + ), + projectViewModel.havePrivilege(83) + ? Container() + : Container( + height: MediaQuery.of(context).size.height * .10, + color: Colors.white.withOpacity(0.6), + ) + ], + ) + : Container(), + Container( + color: Colors.white, + width: double.infinity, + padding: EdgeInsets.all(8), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Texts( + TranslationBase.of(context).reviewOrder, + fontSize: 14, + fontWeight: FontWeight.bold, + color: Colors.black, + ), + ...List.generate( + widget.model!.cartResponse.shoppingCarts != null ? widget.model!.cartResponse.shoppingCarts!.length : 0, + (index) => ProductOrderPreviewItem(widget.model!.cartResponse.shoppingCarts![index]), + ), + ], + ), + ), + Container( + width: double.infinity, + padding: EdgeInsets.all(8), + child: widget.model!.cartResponse.subtotal != null + ? Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Texts( + TranslationBase.of(context).orderSummary, + fontSize: 14, + fontWeight: FontWeight.bold, + color: Colors.black, + ), + SizedBox( + height: 20, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Texts( + "${TranslationBase.of(context).subtotal}", + fontSize: 14, + color: Colors.black, + fontWeight: FontWeight.w500, + ), + Texts( + "${TranslationBase.of(context).sar} ${(widget.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).shipping}", + fontSize: 14, + color: Colors.black, + fontWeight: FontWeight.w500, + ), + Texts( + "${TranslationBase.of(context).sar} ${(widget.model!.totalAdditionalShippingCharge).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} ${(widget.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, + ), + isChecked + ? Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Texts( + "${TranslationBase.of(context).lakum}", + fontSize: 14, + color: Colors.green, + fontWeight: FontWeight.w500, + ), + Texts( + "- ${TranslationBase.of(context).sar} ${(widget.model!.paymentCheckoutData.lacumInformation!.lakumInquiryInformationObjVersion!.pointsBalanceAmount)!.toStringAsFixed(2)}", + fontSize: 14, + color: Colors.green, + fontWeight: FontWeight.w500, + ), + ], + ) + : Container(), + isChecked + ? const Divider( + color: Color(0xFFD6D6D6), + height: 20, + thickness: 1, + indent: 0, + endIndent: 0, + ) + : Container(), + isChecked + ? Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Texts( + TranslationBase.of(context).total, + fontSize: 14, + color: Colors.black, + fontWeight: FontWeight.bold, + ), + Texts( + " ${TranslationBase.of(context).sar}" + "${(widget.model!.cartResponse.totalAmount! - widget.model!.paymentCheckoutData!.lacumInformation!.lakumInquiryInformationObjVersion!.pointsBalanceAmount!)!.toStringAsFixed(2)}", + fontSize: 14, + color: Colors.black, + fontWeight: FontWeight.bold, + ), + ], + ) + : Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Texts( + TranslationBase.of(context).total, + fontSize: 14, + color: Colors.black, + fontWeight: FontWeight.bold, + ), + Texts( + " ${TranslationBase.of(context).sar} ${(widget.model!.cartResponse.totalAmount)!.toStringAsFixed(2)}", + fontSize: 14, + color: Colors.black, + fontWeight: FontWeight.bold, + ), + ], + ), + SizedBox( + height: 10, + ), + ], + ) + : Container(), + ), + SizedBox( + height: widget.model!.cartResponse.shoppingCarts != null ? height * 0.10 : 0, + ) + ], + ), + ), + ), + ), + bottomSheet: Container( + height: widget.model!.cartResponse.shoppingCarts != null ? height * 0.10 : 0, + color: Colors.white, + child: PaymentBottomWidget(widget.model), + ), + ); + } + + changeMainState() { + setState(() {}); + } +} diff --git a/lib/pages/pharmacies/screens/cart-page/lakum_widget.dart b/lib/pages/pharmacies/screens/cart-page/lakum_widget.dart new file mode 100644 index 00000000..a9034553 --- /dev/null +++ b/lib/pages/pharmacies/screens/cart-page/lakum_widget.dart @@ -0,0 +1,189 @@ +import 'dart:ui'; + +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/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class LakumWidget extends StatefulWidget { + final OrderPreviewViewModel model; + + + LakumWidget(this.model); + + @override + _LakumWidgetState createState() => _LakumWidgetState(); +} + +class _LakumWidgetState extends State { + TextEditingController _pointsController = new TextEditingController(); + bool useLakumWidgets = false; + + @override + Widget build(BuildContext context) { + ProjectViewModel projectProvider = Provider.of(context); + _pointsController.text = widget.model.paymentCheckoutData.lacumInformation!.lakumInquiryInformationObjVersion!.pointsBalanceAmount.toString(); + + return Container( + color: Colors.white, + padding: EdgeInsets.symmetric(vertical: 12, horizontal: 12), + child: Row( + children: [ + Row( + children: [ + SizedBox( + height: 24.0, + width: 24.0, + child: Checkbox( + activeColor: CustomColors.green, + value: useLakumWidgets, + onChanged: (bool? value) { + setState(() { + useLakumWidgets = value!; + print(useLakumWidgets); +// if (value){ +// // isChecked; +// OrderPreviewPage.isChecked = true; +// print(value); +// }else{ +// OrderPreviewPage.isChecked = false; +// } + setState(() { + }); + }); + }, + ), + ), + Padding( + padding: const EdgeInsets.only(left: 8.0, right: 8.0), + child: Text( + TranslationBase.of(context).useLakumPoints + + " (${widget.model.paymentCheckoutData.lacumInformation!.lakumInquiryInformationObjVersion!.pointsBalance.toString() + " " + TranslationBase.of(context).points})", + style: TextStyle(fontSize: 12.0, fontWeight: FontWeight.w600, letterSpacing: -0.56)), + ), + ], + ), + Expanded( + child: Container( + decoration: BoxDecoration(color: Color(0x99ffffff)), + padding: const EdgeInsets.symmetric(horizontal: 8), + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Container( + decoration: BoxDecoration(color: Color(0x99ffffff)), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Texts( + "${TranslationBase.of(context).availableBalance}", + fontSize: 12, + fontWeight: FontWeight.bold, + ), + Text( + "${TranslationBase.of(context).sar + " " + widget.model.paymentCheckoutData.lacumInformation!.lakumInquiryInformationObjVersion!.pointsBalanceAmount.toString()}", + style: TextStyle(fontSize: 12.0, fontWeight: FontWeight.w600, letterSpacing: -0.56) + ), + ], + ), + ), + ], + ), + // child: Row( + // mainAxisAlignment: MainAxisAlignment.end, + // children: [ + // Texts( + // "${TranslationBase.of(context).riyal}", + // fontSize: 12, + // fontWeight: FontWeight.bold, + // ), + // Container( + // margin: projectProvider.isArabic ? EdgeInsets.only(right: 4) : EdgeInsets.only(left: 4), + // width: 60, + // height: 50, + // child: TextField( + // decoration: InputDecoration( + // border: OutlineInputBorder( + // borderSide: BorderSide(color: Colors.black, width: 0.2), + // gapPadding: 0, + // borderRadius: projectProvider.isArabic + // ? BorderRadius.only(topRight: Radius.circular(8), bottomRight: Radius.circular(8)) + // : BorderRadius.only(topLeft: Radius.circular(8), bottomLeft: Radius.circular(8)), + // ), + // disabledBorder: OutlineInputBorder( + // borderSide: BorderSide(color: Colors.black, width: 0.4), + // gapPadding: 0, + // borderRadius: BorderRadius.only(topLeft: Radius.circular(8), bottomLeft: Radius.circular(8)), + // ), + // ), + // controller: _pointsController, + // keyboardType: TextInputType.number, + // style: TextStyle( + // fontSize: 14, + // color: widget.model.paymentCheckoutData.lacumInformation.lakumInquiryInformationObjVersion.pointsBalanceAmount > 0 ? Colors.black : Colors.grey, + // ), + // enabled: widget.model.paymentCheckoutData.lacumInformation.lakumInquiryInformationObjVersion.pointsBalanceAmount == 0 ? false : true, + // onChanged: (val) { + // var value = int.tryParse(val); + // if (value != null && value <= widget.model.paymentCheckoutData.lacumInformation.lakumInquiryInformationObjVersion.pointsBalanceAmount) { + // widget.model.paymentCheckoutData.usedLakumPoints = value; + // } else { + // widget.model.paymentCheckoutData.usedLakumPoints = 0; + // } + // _pointsController.text = "${widget.model.paymentCheckoutData.usedLakumPoints}"; + // }, + // ), + // ), + // Container( + // height: 50, + // padding: EdgeInsets.symmetric(horizontal: 8, vertical: 12), + // decoration: new BoxDecoration( + // color: Color(0xff3666E0), + // shape: BoxShape.rectangle, + // borderRadius: projectProvider.isArabic + // ? BorderRadius.only(topLeft: Radius.circular(6), bottomLeft: Radius.circular(6)) + // : BorderRadius.only(topRight: Radius.circular(6), bottomRight: Radius.circular(6)), + // border: Border.fromBorderSide(BorderSide( + // color: Color(0xff3666E0), + // width: 0.8, + // )), + // ), + // child: Texts( + // "${TranslationBase.of(context).use}", + // fontSize: 12, + // color: Colors.white, + // fontWeight: FontWeight.bold, + // ), + // ), + // ], + // ), + ), + ), +// useLakumWidgets ? +// Row( +// mainAxisAlignment: MainAxisAlignment.spaceBetween, +// children: [ +// Texts( +// "${TranslationBase.of(context).lakum}", +// fontSize: 14, +// color: Colors.black, +// fontWeight: FontWeight.w500, +// ), +// Texts( +// "${TranslationBase.of(context).sar} ${(widget.model.paymentCheckoutData.lacumInformation.lakumInquiryInformationObjVersion.pointsBalance).toStringAsFixed(2)}", +// fontSize: 14, +// color: Colors.black, +// fontWeight: FontWeight.w500, +// ), +// ], +// ) +// :Container() + ], + ), + ); + } +} diff --git a/lib/pages/pharmacies/screens/cart-page/payment_bottom_widget.dart b/lib/pages/pharmacies/screens/cart-page/payment_bottom_widget.dart new file mode 100644 index 00000000..b6856a26 --- /dev/null +++ b/lib/pages/pharmacies/screens/cart-page/payment_bottom_widget.dart @@ -0,0 +1,183 @@ +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/order_detail.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/OrderPreviewViewModel.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/locator.dart'; +import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; +import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; +import 'package:diplomaticquarterapp/pages/landing/landing_page_pharmcy.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/navigation_service.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/custom_text_button.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class PaymentBottomWidget extends StatelessWidget { + final OrderPreviewViewModel? model; + static bool isChecked = true; + + BuildContext? context; + MyInAppBrowser? browser; + + PaymentBottomWidget(this.model); + + @override + Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + this.context = context; + OrderPreviewViewModel orderPreviewViewModel = Provider.of(context); + return Container( + margin: EdgeInsets.symmetric(horizontal: 10, vertical: 0), + child: orderPreviewViewModel!.paymentCheckoutData!.cartDataVisible! + ? Container( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Container( + margin: EdgeInsets.symmetric(horizontal: 0, vertical: 4), + child: Row( + children: [ + isChecked + ? Texts( + "${TranslationBase.of(context).sar} ${model!.cartResponse.totalAmount}", + fontSize: 14, + fontWeight: FontWeight.bold, + color: Color(0xff929295), + ) + : Texts( + "${TranslationBase.of(context).sar} ${(model!.cartResponse.totalAmount)!.toStringAsFixed(2)}", + fontSize: 14, + fontWeight: FontWeight.bold, + color: Color(0xff929295), + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 4), + child: Texts( + "${TranslationBase.of(context).inclusiveVat}", + fontSize: 8, + color: Color(0xff929295), + fontWeight: FontWeight.w600, + ), + ), + ], + ), + ), + Texts( + "${model!.cartResponse.quantityCount} ${TranslationBase.of(context).items}", + fontSize: 10, + color: Colors.grey, + fontWeight: FontWeight.bold, + ), + ], + ), + Container( + child: CustomTextButton( + elevation: 0, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + side: BorderSide( + color: Color(0xff929295), + width: 1, + ), + ), + disabledForegroundColor: (orderPreviewViewModel.paymentCheckoutData.address != null && orderPreviewViewModel.paymentCheckoutData.paymentOption != null) + ? Colors.green + : Color(0xff929295).withOpacity(0.38), + disabledBackgroundColor: (orderPreviewViewModel.paymentCheckoutData.address != null && orderPreviewViewModel.paymentCheckoutData.paymentOption != null) + ? Colors.green + : Color(0xff929295).withOpacity(0.12), + backgroundColor: + (orderPreviewViewModel.paymentCheckoutData.address != null && orderPreviewViewModel.paymentCheckoutData.paymentOption != null) ? Colors.green : Color(0xff929295), + onPressed: (orderPreviewViewModel.paymentCheckoutData.address != null && orderPreviewViewModel.paymentCheckoutData.paymentOption != null) + ? () async { + GifLoaderDialogUtils.showMyDialog(context); + await model!.makeOrder(projectViewModel.havePrivilege(83)); + if (model!.state == ViewState.Idle) { + AppToast.showSuccessToast(message: TranslationBase.of(context).compeleteOrderMsg); + GifLoaderDialogUtils.hideDialog(context); + openPayment(model!.orderListModel[0], model!.authenticatedUserObject.user!); + } else { + AppToast.showErrorToast(message: model!.error); + } + navigateToCartPage(); + // Navigator.pop(context); + // Navigator.pop(context); + // Navigator.pop(context); + // Navigator.pop(context); + } + : null, + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 16), + child: new Text( + "${TranslationBase.of(context).proceedPay}", + style: new TextStyle( + color: + (orderPreviewViewModel.paymentCheckoutData.address != null && orderPreviewViewModel.paymentCheckoutData.paymentOption != null) ? Colors.white : Colors.grey.shade400, + fontWeight: FontWeight.bold, + fontSize: 12), + ), + ), + ), + ), + ], + ), + ) + : Container(), + ); + } + + openPayment( + OrderDetailModel order, + AuthenticatedUser authenticatedUser, + ) { + browser = new MyInAppBrowser(onExitCallback: onBrowserExit, onLoadStartCallback: onBrowserLoadStart); + + browser!.openPharmacyPaymentBrowser!(order, order.orderTotal, 'ePharmacy Order', order.id!, order!.billingAddress!.email!, order.customValuesXml!, + "${authenticatedUser.firstName} ${authenticatedUser.middleName} ${authenticatedUser.lastName}", authenticatedUser.patientID, authenticatedUser, browser!); + } + + onBrowserLoadStart(String url) { + print("onBrowserLoadStart"); + print(url); + + MyInAppBrowser.successURLS.forEach((element) { + if (url.contains(element)) { + if (browser!.isOpened()) browser!.close(); + MyInAppBrowser.isPaymentDone = true; + return; + } + }); + + MyInAppBrowser.errorURLS.forEach((element) { + if (url.contains(element)) { + if (browser!.isOpened()) browser!.close(); + MyInAppBrowser.isPaymentDone = false; + return; + } + }); + } + + navigateToCartPage() { + Navigator.pushAndRemoveUntil(locator().navigatorKey.currentContext!, MaterialPageRoute(builder: (context) => LandingPagePharmacy(currentTab: 0)), (Route r) => false); + } + + onBrowserExit(AppoitmentAllHistoryResultList appo, bool isPaymentMade) { + print("onBrowserExit Called!!!!"); + AppToast.showSuccessToast(message: "شكراً\nPayment status for your order is Paid"); + // Navigator.pop(context); + // Navigator.pop(context); + // } else { + // AppToast.showErrorToast(message: "Transaction Failed!\Your transaction is field to some reason please try again or contact to the administration"); + // // Navigator.pop(context); + // // Navigator.pop(context); + // } + } +} diff --git a/lib/pages/pharmacies/screens/cart-page/select_address_widget.dart b/lib/pages/pharmacies/screens/cart-page/select_address_widget.dart new file mode 100644 index 00000000..592d0e78 --- /dev/null +++ b/lib/pages/pharmacies/screens/cart-page/select_address_widget.dart @@ -0,0 +1,207 @@ +import 'package:diplomaticquarterapp/core/model/pharmacies/Addresses.dart'; +import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/customer_addresses_service.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/OrderPreviewViewModel.dart'; +import 'package:diplomaticquarterapp/pages/pharmacy/pharmacyAddresses/PharmacyAddresses.dart'; +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/transitions/fade_page.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class SelectAddressWidget extends StatefulWidget { + final OrderPreviewViewModel model; + final List addresses; + final Function changeMainState; + final bool isUpdating; + + SelectAddressWidget(this.model, this.addresses, this.changeMainState, + {this.isUpdating = false}); + + @override + _SelectAddressWidgetState createState() => _SelectAddressWidgetState(); +} + +class _SelectAddressWidgetState extends State { + AddressInfo? address; + + _navigateToAddressPage(String identificationNo) { + Navigator.push(context, FadePage(page: PharmacyAddressesPage(orderPreviewViewModel: widget.model,isUpdate: widget.isUpdating,changeMainState: widget.changeMainState,))).then((result) async { + if (result != null) { + GifLoaderDialogUtils.showMyDialog(context); + address = result; + widget.model.paymentCheckoutData.address = Addresses.fromJson(address!.toJson()); + await widget.model.getInformationsByAddress(identificationNo); + await widget.model.getShoppingCart(); + widget.changeMainState(); + GifLoaderDialogUtils.hideDialog(context); + } + }); + } + + @override + void initState() { + super.initState(); + } + + @override + Widget build(BuildContext context) { + OrderPreviewViewModel model = Provider.of(context); + if (widget.model.paymentCheckoutData.address != null) { + address = AddressInfo.fromJson(widget.model.paymentCheckoutData.address!.toJson()); + } + return Container( + color: Colors.white, + child: address == null + ? InkWell( + onTap: () => {_navigateToAddressPage(model.user!.patientIdentificationNo!)}, + child: Container( + margin: EdgeInsets.symmetric(vertical: 12, horizontal: 12), + child: Row( + children: [ + Image.asset( + "assets/images/pharmacy_module/ic_shipping_address.png", + width: 30.0, + height: 30.0, + fit: BoxFit.scaleDown, + ), + Expanded( + child: Container( + padding: EdgeInsets.symmetric(vertical: 0, horizontal: 6), + child: Texts( + TranslationBase.of(context).selectAddress, + fontSize: 14, + fontWeight: FontWeight.bold, + color: Color(0xff0000ff), + ), + ), + ), + Icon( + Icons.arrow_forward_ios, + size: 20, + color: Colors.grey.shade400, + ), + ], + ), + ), + ) + : Container( + child: Container( + margin: EdgeInsets.symmetric(vertical: 12, horizontal: 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Image.asset( + "assets/images/pharmacy_module/ic_shipping_mark.png", + width: 30.0, + height: 30.0, + fit: BoxFit.scaleDown, + ), + Expanded( + child: Container( + padding: EdgeInsets.symmetric(vertical: 0, horizontal: 6), + child: Texts( + TranslationBase.of(context).shippingAddress, + fontSize: 14, + fontWeight: FontWeight.bold, + color: Colors.black, + ), + ), + ), + InkWell( + onTap: () => {_navigateToAddressPage(model.authenticatedUserObject.user!.patientIdentificationNo!)}, + child: Texts( + TranslationBase.of(context).changeAddress, + fontSize: 12, + fontWeight: FontWeight.normal, + color: Color(0xff0000ff), + ), + ), + ], + ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 8), + child: Texts( + "${address!.firstName} ${address!.lastName!}", + fontSize: 14, + fontWeight: FontWeight.bold, + color: Colors.black, + ), + ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 8), + child: Texts( + "${address!.address1} ${address!.address2} ${address!.address2},, ${address!.city}, ${address!.country} ${address!.zipPostalCode}", + fontSize: 12, + fontWeight: FontWeight.normal, + color: Colors.grey.shade500, + ), + ), + Row( + children: [ + Container( + margin: const EdgeInsets.only(right: 8), + child: Icon( + Icons.phone, + size: 20, + color: Colors.black, + ), + ), + Texts( + "${address!.phoneNumber}", + fontSize: 14, + fontWeight: FontWeight.bold, + color: Colors.grey, + ), + ], + ), + Container( + margin: EdgeInsets.symmetric(vertical: 8), + child: SizedBox( + height: 2, + width: double.infinity, + child: Container( + color: Color(0xffefefef), + ), + ), + ), + Row( + children: [ + Image.asset( + "assets/images/pharmacy_module/ic_shipping_truck.png", + width: 30.0, + height: 30.0, + fit: BoxFit.scaleDown, + ), + Container( + padding: EdgeInsets.symmetric(vertical: 0, horizontal: 6), + child: Texts( + "${TranslationBase.of(context).shipBy}", + fontSize: 12, + fontWeight: FontWeight.bold, + color: Colors.black, + ), + ), + Container( + child: Image.asset( + model.paymentCheckoutData.shippingOption == null + ? "" + : model.paymentCheckoutData.shippingOption!.shippingRateComputationMethodSystemName == "Shipping.FixedOrByWeight" + ? "assets/images/pharmacy_module/payment/LogoParmacyGreen.png" + : "assets/images/pharmacy_module/payment/aramex_shipping_logo.png", + fit: BoxFit.contain, + width: 100, + ), + margin: EdgeInsets.symmetric(horizontal: 8), + ), + ], + ), + ], + ), + ), + ), // ic_shipping_mark.png + ); + } +} 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 new file mode 100644 index 00000000..d6f162d8 --- /dev/null +++ b/lib/pages/pharmacies/screens/cart-page/select_payment_option_widget.dart @@ -0,0 +1,132 @@ +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/OrderPreviewViewModel.dart'; +import 'package:diplomaticquarterapp/pages/ToDoList/payment_method_select.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/screens/payment-method-select-page.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +import 'package:flutter/material.dart'; + +class SelectPaymentOptionWidget extends StatefulWidget { + final OrderPreviewViewModel model; + final VoidCallback? changeMainState; + final bool isUpdating; + + + SelectPaymentOptionWidget(this.model, this.changeMainState, {this.isUpdating = false}); + + @override + _SelectPaymentOptionWidgetState createState() => _SelectPaymentOptionWidgetState(); +} + +class _SelectPaymentOptionWidgetState extends State { + PaymentOption? paymentOption; + + _navigateToPaymentOption() { + Navigator.push(context, FadePage(page: PaymentMethodSelectPage(model: widget.model,changeMainState:widget.changeMainState,isUpdating: widget.isUpdating,))) + .then((result) => { + setState(() { + if (result != null) { + paymentOption = result; + widget.model.paymentCheckoutData.paymentOption = + paymentOption; + } + widget.changeMainState!(); + }) + }); + } + + @override + void initState() { + super.initState(); + } + + @override + Widget build(BuildContext context) { + if (widget.model.paymentCheckoutData.paymentOption != null) { + paymentOption = widget.model.paymentCheckoutData.paymentOption; + } + return Container( + color: Colors.white, + child: paymentOption == null + ? InkWell( + onTap: () => {_navigateToPaymentOption()}, + child: Container( + margin: EdgeInsets.symmetric(vertical: 12, horizontal: 12), + child: Row( + children: [ + Image.asset( + "assets/images/pharmacy_module/ic_payment_option.png", + width: 30.0, + height: 30.0, + fit: BoxFit.scaleDown, + ), + Expanded( + child: Container( + padding: EdgeInsets.symmetric(vertical: 0, horizontal: 6), + child: Texts( + TranslationBase.of(context).selectPaymentOption, + fontSize: 14, + fontWeight: FontWeight.bold, + color: Color(0xff0000ff), + ), + ), + ), + Icon( + Icons.arrow_forward_ios, + size: 20, + color: Colors.grey.shade400, + ), + ], + ), + ), + ) + : Container( + margin: EdgeInsets.symmetric(vertical: 12, horizontal: 12), + child: Row( + children: [ + Image.asset( + "assets/images/pharmacy_module/ic_payment_option.png", + width: 30.0, + height: 30.0, + fit: BoxFit.scaleDown, + ), + Container( + margin: EdgeInsets.symmetric(horizontal: 8), + padding: EdgeInsets.symmetric(horizontal: 4, vertical: 0), + decoration: new BoxDecoration( + color: Colors.grey.shade100, + shape: BoxShape.rectangle, + ), + child: Image.asset( + widget.model.getPaymentOptionImage(paymentOption!), + width: 30.0, + height: 30.0, + fit: BoxFit.scaleDown, + ), + ), + Expanded( + child: Container( + padding: EdgeInsets.symmetric(vertical: 0, horizontal: 6), + child: Texts( + widget.model.getPaymentOptionName(paymentOption!), + fontSize: 14, + fontWeight: FontWeight.bold, + color: Colors.black, + ), + ), + ), + InkWell( + onTap: () => {_navigateToPaymentOption()}, + child: Texts( + TranslationBase.of(context).changeMethod, + fontSize: 12, + fontWeight: FontWeight.normal, + color: Color(0xff0000ff), + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/pages/pharmacies/screens/lacum-activitaion-vida-page.dart b/lib/pages/pharmacies/screens/lacum-activitaion-vida-page.dart index 9e281694..e0c6b517 100644 --- a/lib/pages/pharmacies/screens/lacum-activitaion-vida-page.dart +++ b/lib/pages/pharmacies/screens/lacum-activitaion-vida-page.dart @@ -1,22 +1,24 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/lacum-registration-viewModel.dart'; +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/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/borderedButton.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 'lacum-registration-page.dart'; +import 'package:provider/provider.dart'; class LakumActivationVidaPage extends StatelessWidget { - TextEditingController _identificationNumberController = - new TextEditingController(); + ProjectViewModel? projectViewModel; + TextEditingController _identificationNumberController = new TextEditingController(); @override Widget build(BuildContext context) { final mediaQuery = MediaQuery.of(context); + projectViewModel = Provider.of(context); return BaseView( builder: (_, model, wi) => AppScaffold( @@ -24,6 +26,9 @@ class LakumActivationVidaPage extends StatelessWidget { isShowAppBar: true, isPharmacy: true, isShowDecPage: false, + showPharmacyCart: false, + showHomeAppBarIcon: false, + isBottomBar: false, backgroundColor: Colors.white, baseViewModel: model, body: Container( @@ -43,10 +48,7 @@ class LakumActivationVidaPage extends StatelessWidget { padding: const EdgeInsets.all(8.0), child: TextField( controller: _identificationNumberController, - decoration: new InputDecoration( - hintText: TranslationBase.of(context) - .enterIdentificationNumber, - ), + decoration: new InputDecoration(hintText: TranslationBase.of(context).enterIdentificationNumber, focusColor: CustomColors.green), keyboardType: TextInputType.number, style: TextStyle( fontSize: 16, @@ -60,39 +62,38 @@ class LakumActivationVidaPage extends StatelessWidget { margin: EdgeInsets.only(top: 4), child: BorderedButton( TranslationBase.of(context).accountActivation, - backgroundColor: - _identificationNumberController.text != null && - _identificationNumberController.text != "" - ? Color(0xff60686b) - : Color(0xffb0b4b5), + // backgroundColor: _identificationNumberController.text != null && _identificationNumberController.text != "" ? CustomColors.green : Color(0xffb0b4b5), textColor: Colors.white, + backgroundColor: CustomColors.green, + borderColor: CustomColors.green, fontSize: 16, hPadding: 8, vPadding: 12, - handler: _identificationNumberController.text != null && - _identificationNumberController.text != "" + handler: _identificationNumberController.text != null || _identificationNumberController.text != "" ? () { - model - .checkLacumAccountActivation( - _identificationNumberController.text) - .then((_) => { - if (model.state == ViewState.Idle) - { - Navigator.push( - context, - FadePage( - page: LakumRegistrationPage( - _identificationNumberController - .text))) - .then((status) => { - if (status == 200) - {Navigator.pop(context, "")} - // back to previous page - }) - } + model.checkLacumAccountActivation(_identificationNumberController.text).then((_) { + if (model.state == ViewState.Idle) { + if (model.lacumInformation!.status != "Hold") { + AppToast.showErrorToast(message: TranslationBase.of(context).lakumUnhold); + if (model.lacumInformation!.status != "Discontinue") { + AppToast.showErrorToast(message: TranslationBase.of(context).lakumDiscontinue); + } + } else { + if (model.lacumInformation!.status == "Hold") { + model.makeAccountActivate(projectViewModel!.user!.patientIdentificationNo!).then((value) { + AppToast.showSuccessToast(message: TranslationBase.of(context).lakumSuccess); + Navigator.of(context).pop(); }); + } + } + // Navigator.push(context, FadePage(page: LakumRegistrationPage(_identificationNumberController.text))).then((status) => { + // if (status == 200) {model.makeAccountActivate(projectViewModel.user.patientIdentificationNo)} + // // back to previous page + // }) + } + }); } - : () {}, + : null, ), ), ], diff --git a/lib/pages/pharmacies/screens/lacum-registration-page.dart b/lib/pages/pharmacies/screens/lacum-registration-page.dart index c40771b8..4e03d7ef 100644 --- a/lib/pages/pharmacies/screens/lacum-registration-page.dart +++ b/lib/pages/pharmacies/screens/lacum-registration-page.dart @@ -27,9 +27,9 @@ class _LakumRegistrationPageState extends State { final TextEditingController _mobileNumberController = TextEditingController(); - List languages = List(); + List languages =[]; - IdNamePair selectedLanguage; + IdNamePair? selectedLanguage; @override Widget build(BuildContext context) { @@ -48,18 +48,18 @@ class _LakumRegistrationPageState extends State { return BaseView( builder: (_, model, wi) => AppScaffold( - appBarTitle: - "${TranslationBase.of(context).register} ${TranslationBase.of(context).lakum}", + appBarTitle: "${TranslationBase.of(context).register} ${TranslationBase.of(context).lakum}", isShowAppBar: true, isShowDecPage: false, + isPharmacy: true, + showPharmacyCart: false, backgroundColor: Colors.white, baseViewModel: model, body: Container( width: double.infinity, child: SingleChildScrollView( child: SizedBox( - height: - mediaQuery.size.height - 60 - mediaQuery.padding.top, + height: mediaQuery.size.height - 60 - mediaQuery.padding.top, child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -130,35 +130,26 @@ class _LakumRegistrationPageState extends State { height: 10, ), Texts( - TranslationBase.of(context) - .prefferedLanguage, + TranslationBase.of(context).prefferedLanguage, fontSize: 13, fontWeight: FontWeight.normal, color: Color(0xff8a8a8a), ), InkWell( onTap: () { - RadioGroupDialog dialog = - new RadioGroupDialog( - context: context, - title: TranslationBase.of(context) - .prefferedLanguage, - okText: - TranslationBase.of(context) - .confirm, - cancelText: - TranslationBase.of(context) - .cancel_nocaps, - list: languages, - okFunction: (selectedValue) { - setState(() { - selectedLanguage = - selectedValue; - }); - print( - "selectedLanguage = ${selectedValue.name}"); - }, - cancelFunction: () => {}); + RadioGroupDialog dialog = new RadioGroupDialog( + context: context, + title: TranslationBase.of(context).prefferedLanguage, + okText: TranslationBase.of(context).confirm, + cancelText: TranslationBase.of(context).cancel_nocaps, + list: languages, + okFunction: (selectedValue) { + setState(() { + selectedLanguage = selectedValue; + }); + print("selectedLanguage = ${selectedValue.name}"); + }, + cancelFunction: () => {}); showDialog( barrierDismissible: false, context: context, @@ -170,11 +161,8 @@ class _LakumRegistrationPageState extends State { child: TextField( enabled: false, decoration: InputDecoration( - suffixIcon: - Icon(Icons.arrow_drop_down), - hintText: selectedLanguage == null - ? "${TranslationBase.of(context).prefferedLanguage}" - : "${selectedLanguage.name}", + suffixIcon: Icon(Icons.arrow_drop_down), + hintText: selectedLanguage == null ? "${TranslationBase.of(context).prefferedLanguage}" : "${selectedLanguage!.name!}", hintStyle: TextStyle( fontSize: 16, color: Colors.black, @@ -192,12 +180,10 @@ class _LakumRegistrationPageState extends State { ), Container( color: Colors.green, - margin: EdgeInsets.all(8), + margin: EdgeInsets.all(40), child: BorderedButton( TranslationBase.of(context).register, - backgroundColor: canSubmit - ? Color(0xff339933) - : Color(0xff99cc99), + backgroundColor: canSubmit ? Color(0xff339933) : Color(0xff99cc99), textColor: Colors.white, fontSize: 16, hPadding: 8, @@ -208,18 +194,13 @@ class _LakumRegistrationPageState extends State { context, FadePage( page: LakumTermsConditions( - widget - .patientIdentificationNo, - _firstNameController.text, - _lastNameController.text, - _mobileNumberController - .text, - selectedLanguage.id))) - .then((status) => { - if (status == 200) - {Navigator.pop(context, "")} - // back to previous page - }); + widget.patientIdentificationNo, _firstNameController.text, _lastNameController.text, _mobileNumberController.text, selectedLanguage!.id))) + .then( + (status) => { + if (status == 200) {Navigator.pop(context, "")} + // back to previous page + }, + ); } : null, ), diff --git a/lib/pages/pharmacies/screens/lacum-setting-page.dart b/lib/pages/pharmacies/screens/lacum-setting-page.dart index 4f7f5fd6..17ebc7e2 100644 --- a/lib/pages/pharmacies/screens/lacum-setting-page.dart +++ b/lib/pages/pharmacies/screens/lacum-setting-page.dart @@ -1,6 +1,7 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/LacumAccountInformation.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/lacum-viewmodel.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/widgets/lacum-banner-widget.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; @@ -10,6 +11,7 @@ import 'package:diplomaticquarterapp/widgets/buttons/borderedButton.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; class LakumSettingPage extends StatefulWidget { final LacumAccountInformation lacumInformation; @@ -26,19 +28,22 @@ class _LakumSettingPageState extends State { TextEditingController _nameController = new TextEditingController(); TextEditingController _phoneController = new TextEditingController(); + ProjectViewModel? projectViewModel; + @override void initState() { _lakumAccountActivated = widget.lacumGroupInformation - .lakumInquiryInformationObjVersion.accountStatus == + .lakumInquiryInformationObjVersion!.accountStatus == "Active"; super.initState(); - _nameController.text = widget.lacumGroupInformation.lakumInquiryInformationObjVersion.memberName; - _phoneController.text = widget.lacumGroupInformation.lakumInquiryInformationObjVersion.mobileNumber; + _nameController.text = widget.lacumGroupInformation!.lakumInquiryInformationObjVersion!.memberName!; + _phoneController.text = widget.lacumGroupInformation!.lakumInquiryInformationObjVersion!.mobileNumber!; } @override Widget build(BuildContext context) { final mediaQuery = MediaQuery.of(context); + projectViewModel = Provider.of(context); return BaseView( onModelReady: (model) => model.setLakumData( @@ -68,8 +73,8 @@ class _LakumSettingPageState extends State { _buildSettingScreen(MediaQueryData mediaQuery, LacumViewModel model) { bool canUpdate = (_nameController.text != "" && _phoneController.text != "" && - (_nameController.text != widget.lacumGroupInformation.lakumInquiryInformationObjVersion.memberName || - _phoneController.text != widget.lacumGroupInformation.lakumInquiryInformationObjVersion.mobileNumber)); + (_nameController.text != widget.lacumGroupInformation.lakumInquiryInformationObjVersion!.memberName || + _phoneController.text != widget.lacumGroupInformation.lakumInquiryInformationObjVersion!.mobileNumber)); return Column( crossAxisAlignment: CrossAxisAlignment.stretch, @@ -112,8 +117,8 @@ class _LakumSettingPageState extends State { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Texts( - "Activate LAKUM Account", + Texts(TranslationBase.of(context).ActivateLAKUMAccount, +// "Activate LAKUM Account", fontSize: 16, fontWeight: FontWeight.normal, color: Colors.black, @@ -126,9 +131,9 @@ class _LakumSettingPageState extends State { value: _lakumAccountActivated, onChanged: (val) { if (_lakumAccountActivated) { - model.makeAccountDeactivate(); + model.makeAccountDeactivate(projectViewModel!.user!.patientIdentificationNo!); } else { - model.makeAccountActivate(); + model.makeAccountActivate(projectViewModel!.user!.patientIdentificationNo!); } setState(() { _lakumAccountActivated = val; diff --git a/lib/pages/pharmacies/screens/lacum-transfer-page.dart b/lib/pages/pharmacies/screens/lacum-transfer-page.dart index f05c6da4..9123a1c2 100644 --- a/lib/pages/pharmacies/screens/lacum-transfer-page.dart +++ b/lib/pages/pharmacies/screens/lacum-transfer-page.dart @@ -18,8 +18,7 @@ class LacumTransferPage extends StatefulWidget { } class _LacumTransferPageState extends State { - TextEditingController _beneficieryAccountController = - new TextEditingController(); + TextEditingController _beneficieryAccountController = new TextEditingController(); TextEditingController _transferPointsController = new TextEditingController(); @override @@ -34,21 +33,22 @@ class _LacumTransferPageState extends State { final mediaQuery = MediaQuery.of(context); return BaseView( - onModelReady: (model) => model.setLakumData( - widget.lacumInformation, widget.lacumGroupInformation), + onModelReady: (model) => model.setLakumData(widget.lacumInformation, widget.lacumGroupInformation), builder: (_, model, wi) => AppScaffold( appBarTitle: "${TranslationBase.of(context).lakumTransfer}", isShowAppBar: true, isPharmacy: true, isShowDecPage: false, + showHomeAppBarIcon: false, + isBottomBar: true, + showPharmacyCart: false, backgroundColor: Colors.white, baseViewModel: model, body: Container( width: double.infinity, child: SingleChildScrollView( child: SizedBox( - height: - mediaQuery.size.height - 58 - mediaQuery.padding.top, + height: mediaQuery.size.height - 58 - mediaQuery.padding.top, child: Padding( padding: const EdgeInsets.all(16.0), child: Column( @@ -62,22 +62,20 @@ class _LacumTransferPageState extends State { Container( height: 100, width: mediaQuery.size.width / 2 - 26, - padding: EdgeInsets.only( - top: 12, left: 8, right: 8, bottom: 4), + padding: EdgeInsets.only(top: 12, left: 8, right: 8, bottom: 4), decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: Border.fromBorderSide(BorderSide( - color: Color(0xffe1e1e1), - width: 0.4, - )), - color: Color(0xff6294ed), - ), + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(8), + border: Border.fromBorderSide(BorderSide( + color: Color(0xffe1e1e1), + width: 0.4, + )), + color: Colors.green + //(0xff6294ed), + ), child: Row( - crossAxisAlignment: - CrossAxisAlignment.start, - mainAxisAlignment: - MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( child: Column( @@ -95,16 +93,13 @@ class _LacumTransferPageState extends State { ), Expanded( child: Container( - padding: EdgeInsets.symmetric( - vertical: 8), + padding: EdgeInsets.symmetric(vertical: 8), child: Column( - mainAxisAlignment: - MainAxisAlignment.end, - crossAxisAlignment: - CrossAxisAlignment.end, + mainAxisAlignment: MainAxisAlignment.end, + crossAxisAlignment: CrossAxisAlignment.end, children: [ Texts( - "0", + "${model.lacumGroupInformation!.lakumInquiryInformationObjVersion!.pointsBalance}", fontSize: 14, fontWeight: FontWeight.bold, color: Colors.white, @@ -122,8 +117,7 @@ class _LacumTransferPageState extends State { Container( height: 100, width: mediaQuery.size.width / 2 - 26, - padding: EdgeInsets.only( - top: 12, left: 8, right: 8, bottom: 4), + padding: EdgeInsets.only(top: 12, left: 8, right: 8, bottom: 4), decoration: BoxDecoration( shape: BoxShape.rectangle, borderRadius: BorderRadius.circular(8), @@ -134,10 +128,8 @@ class _LacumTransferPageState extends State { color: Color(0xff339933), ), child: Row( - crossAxisAlignment: - CrossAxisAlignment.start, - mainAxisAlignment: - MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( child: Column( @@ -155,16 +147,13 @@ class _LacumTransferPageState extends State { ), Expanded( child: Container( - padding: EdgeInsets.symmetric( - vertical: 8), + padding: EdgeInsets.symmetric(vertical: 8), child: Column( - mainAxisAlignment: - MainAxisAlignment.end, - crossAxisAlignment: - CrossAxisAlignment.end, + mainAxisAlignment: MainAxisAlignment.end, + crossAxisAlignment: CrossAxisAlignment.end, children: [ Texts( - "0", + "${model.lacumGroupInformation!.lakumInquiryInformationObjVersion!.pointsBalanceAmount}", fontSize: 14, fontWeight: FontWeight.bold, color: Colors.white, @@ -195,47 +184,34 @@ class _LacumTransferPageState extends State { margin: EdgeInsets.only(top: 4), child: BorderedButton( TranslationBase.of(context).checkBeneficiary, - backgroundColor: - _beneficieryAccountController.text != "" - ? Color(0xff60686b) - : Color(0xffb0b4b5), + backgroundColor: _beneficieryAccountController.text.isNotEmpty ? Color(0xff60686b) : Color(0xffb0b4b5), textColor: Colors.white, fontSize: 16, hPadding: 8, vPadding: 12, - handler: - _beneficieryAccountController.text != "" - ? () { - model.getLacumGroupDataBuAccountId( - _beneficieryAccountController - .text); - } - : (){}, + handler: _beneficieryAccountController.text.isNotEmpty + ? () { + model.getLacumGroupDataBuAccountId(_beneficieryAccountController.text); + } + : () {}, ), ), - (model.lacumReceiverInformation != null && - model.lacumReceiverInformation - .lakumInquiryInformationObjVersion != - null) + (model.lacumReceiverInformation != null && model.lacumReceiverInformation!.lakumInquiryInformationObjVersion != null) ? Container( margin: EdgeInsets.only(top: 8), child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ Texts( - TranslationBase.of(context) - .beneficiaryName, + TranslationBase.of(context).beneficiaryName, color: Colors.black, ), Padding( - padding: const EdgeInsets.symmetric( - horizontal: 8), + padding: const EdgeInsets.symmetric(horizontal: 8), child: TextField( enabled: false, decoration: new InputDecoration( - hintText: - "${model.lacumReceiverInformation.lakumInquiryInformationObjVersion.memberName}", + hintText: "${model.lacumReceiverInformation!.lakumInquiryInformationObjVersion!.memberName}", hintStyle: TextStyle( fontSize: 16, color: Colors.grey.shade600, @@ -255,11 +231,9 @@ class _LacumTransferPageState extends State { color: Colors.black, ), Padding( - padding: const EdgeInsets.symmetric( - horizontal: 8), + padding: const EdgeInsets.symmetric(horizontal: 8), child: TextField( - controller: - _transferPointsController, + controller: _transferPointsController, decoration: new InputDecoration( focusColor: Colors.green, hintStyle: TextStyle( @@ -278,10 +252,7 @@ class _LacumTransferPageState extends State { : Container() ], ), - if (model.lacumReceiverInformation != null && - model.lacumReceiverInformation - .lakumInquiryInformationObjVersion != - null) + if (model.lacumReceiverInformation != null && model.lacumReceiverInformation!.lakumInquiryInformationObjVersion != null) Container( margin: EdgeInsets.all(8), child: BorderedButton( @@ -294,14 +265,9 @@ class _LacumTransferPageState extends State { vPadding: 16, fontWeight: FontWeight.w600, handler: () { - model - .transferYaHalaLoyaltyPoints( - _transferPointsController.text) - .then((status) => { - if (status == 200) - {Navigator.pop(context, "")} - // back to previous page - }); + model.transferYaHalaLoyaltyPoints(_transferPointsController.text).then((status) => { + {Navigator.pop(context)} + }); }, ), ) diff --git a/lib/pages/pharmacies/screens/lakum-main-page.dart b/lib/pages/pharmacies/screens/lakum-main-page.dart index fdf3cc78..3d9cbf87 100644 --- a/lib/pages/pharmacies/screens/lakum-main-page.dart +++ b/lib/pages/pharmacies/screens/lakum-main-page.dart @@ -1,313 +1,278 @@ -import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/PointsAmountPerYear.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/lacum-viewmodel.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/screens/lacum-registration-page.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/lacum-setting-page.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/lacum-transfer-page.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/lakum-points-year-page.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/widgets/lacum-banner-widget.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/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; import 'lacum-activitaion-vida-page.dart'; class LakumMainPage extends StatelessWidget { + ProjectViewModel? projectViewModel; + @override Widget build(BuildContext context) { final mediaQuery = MediaQuery.of(context); + projectViewModel = Provider.of(context); return BaseView( - onModelReady: (model) => model.getLacumData(), - builder: (_, model, wi) => AppScaffold( - appBarTitle: TranslationBase.of(context).lakum, - isShowAppBar: true, - isPharmacy: true, - isShowDecPage: false, - backgroundColor: Colors.white, - baseViewModel: model, - appBarIcons: _buildAppBarICons(context, model), - // preferredSize: mediaQuery.size.height * 0.20, - body: Container( - width: double.infinity, - child: SingleChildScrollView( - child: (model.lacumGroupInformation != null && - model.lacumGroupInformation - .lakumInquiryInformationObjVersion != - null) - ? Column( - children: [ - Stack( - children: [ - Container( - height: mediaQuery.size.height * 0.15, - color: Colors.green, - ), - Column( - children: [ - SizedBox( - height: mediaQuery.size.height * 0.05, - ), - Container( - width: mediaQuery.size.width * 1, - child: LakumBannerWidget( - model, mediaQuery, true)), - ], - ) - ], - ), - SizedBox( - height: 20, - ), - LakumHomeButtons(mediaQuery, model), - SizedBox( - height: 20, - ), - Container( - height: 100, - margin: EdgeInsets.symmetric(horizontal: 16), - child: ListView( - scrollDirection: Axis.horizontal, - children: [ - LacumPointsWidget( - mediaQuery, - 1, - TranslationBase.of(context).balance, - model - .lacumGroupInformation - .lakumInquiryInformationObjVersion - .pointsBalanceAmount, - model - .lacumGroupInformation - .lakumInquiryInformationObjVersion - .pointsBalance, - null), - SizedBox( - width: 8, - ), - LacumPointsWidget( - mediaQuery, - 2, - TranslationBase.of(context).gained, - model - .lacumGroupInformation - .lakumInquiryInformationObjVersion - .pointsBalanceAmount, - model - .lacumGroupInformation - .lakumInquiryInformationObjVersion - .gainedPoints, - model - .lacumGroupInformation - .lakumInquiryInformationObjVersion - .gainedPointsAmountPerYear), - SizedBox( - width: 8, - ), - LacumPointsWidget( - mediaQuery, - 3, - TranslationBase.of(context).consumed, - model - .lacumGroupInformation - .lakumInquiryInformationObjVersion - .consumedPointsAmount != - null - ? int.parse(model - .lacumGroupInformation - .lakumInquiryInformationObjVersion - .consumedPointsAmount) - : 0, - model - .lacumGroupInformation - .lakumInquiryInformationObjVersion - .consumedPoints, - model - .lacumGroupInformation - .lakumInquiryInformationObjVersion - .consumedPointsAmountPerYear), - SizedBox( - width: 8, - ), - LacumPointsWidget( - mediaQuery, - 4, - TranslationBase.of(context).transferred, - 0, - model - .lacumGroupInformation - .lakumInquiryInformationObjVersion - .transferPoints, - model - .lacumGroupInformation - .lakumInquiryInformationObjVersion - .transferPointsAmountPerYear), - ], + onModelReady: (model) async { + await model.getLacumData(projectViewModel!.user!.patientIdentificationNo!); + if (model.lacumInformation!.yahalaAccountNo == 0 || model.lacumInformation!.yahalaAccountNo == null) { + navigateToLakumRegister(context); + } else { + if (model.lacumInformation!.status == "Hold") { + Navigator.pushReplacement(context, FadePage(page: LakumActivationVidaPage())); + } + } + }, + builder: (_, model, wi) => AppScaffold( + appBarTitle: TranslationBase.of(context).lakum, + isShowAppBar: true, + isPharmacy: true, + showPharmacyCart: false, + isShowDecPage: false, + showHomeAppBarIcon: false, + isBottomBar: true, + backgroundColor: Colors.white, + baseViewModel: model, + appBarIcons: _buildAppBarICons(context, model), + // preferredSize: mediaQuery.size.height * 0.20, + body: Container( + width: double.infinity, + child: SingleChildScrollView( + child: (model.lacumGroupInformation != null && model.lacumGroupInformation!.lakumInquiryInformationObjVersion != null) + ? Column( + children: [ + Stack( + children: [ + Container( + height: mediaQuery.size.height * 0.15, + color: Colors.green, + ), + Column( + children: [ + SizedBox( + height: mediaQuery.size.height * 0.02, ), + Container(width: mediaQuery.size.width * 1, height: mediaQuery.size.width * .6, child: LakumBannerWidget(model, mediaQuery, true)), + ], + ) + ], + ), + SizedBox( + height: 12, + ), + LakumHomeButtons(mediaQuery, model, projectViewModel!), + SizedBox( + height: 12, + ), + Container( + height: 110, + margin: EdgeInsets.symmetric(horizontal: 16, vertical: 12.0), + child: ListView( + scrollDirection: Axis.horizontal, + children: [ + LacumPointsWidget(mediaQuery, 1, TranslationBase.of(context).balance, model.lacumGroupInformation!.lakumInquiryInformationObjVersion!.pointsBalanceAmount!, + model.lacumGroupInformation!.lakumInquiryInformationObjVersion!.pointsBalance!, []), + SizedBox( + width: 8, ), + LacumPointsWidget(mediaQuery, 2, TranslationBase.of(context).gained, model.lacumGroupInformation!.lakumInquiryInformationObjVersion!.gainedPointsAmount!, + model.lacumGroupInformation!.lakumInquiryInformationObjVersion!.gainedPoints!, model.lacumGroupInformation!.lakumInquiryInformationObjVersion!.gainedPointsAmountPerYear!), SizedBox( - height: 20, + width: 8, ), + LacumPointsWidget( + mediaQuery, + 3, + TranslationBase.of(context).consumed, + model.lacumGroupInformation!.lakumInquiryInformationObjVersion!.consumedPointsAmount! != null + ? num.parse(model.lacumGroupInformation!.lakumInquiryInformationObjVersion!.consumedPointsAmount!) + : 0, + model.lacumGroupInformation!.lakumInquiryInformationObjVersion!.consumedPoints!, + model.lacumGroupInformation!.lakumInquiryInformationObjVersion!.consumedPointsAmountPerYear!), SizedBox( - height: 8, - width: double.infinity, - child: Container( - color: Color(0xffefefef), - ), + width: 8, ), - Container( - margin: EdgeInsets.symmetric( - vertical: 16, horizontal: 8), - child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - Image.asset( - "assets/images/pharmacy_module/lakum/expired_icon.png", - fit: BoxFit.fill, - width: 25, - height: 25, - ), - Padding( - padding: - EdgeInsets.symmetric(horizontal: 8), - child: Texts( - "Expired", - fontSize: 14, - ), - ) - ], - ), - Texts( - "${model.lacumGroupInformation.lakumInquiryInformationObjVersion.expiredPoints} Points", - fontWeight: FontWeight.bold, + LacumPointsWidget(mediaQuery, 4, TranslationBase.of(context).transferred, 0, model.lacumGroupInformation!.lakumInquiryInformationObjVersion!.transferPoints!, + model.lacumGroupInformation!.lakumInquiryInformationObjVersion!.transferPointsAmountPerYear!), + ], + ), + ), + // LacumPointsWidget( + // mediaQuery, + // 3, + // TranslationBase.of(context).consumed, + // model.lacumGroupInformation.lakumInquiryInformationObjVersion.consumedPointsAmount != null + // ? int.parse(model.lacumGroupInformation.lakumInquiryInformationObjVersion.consumedPointsAmount) + // : 0, + // model.lacumGroupInformation.lakumInquiryInformationObjVersion.consumedPoints, + // model.lacumGroupInformation.lakumInquiryInformationObjVersion.consumedPointsAmountPerYear), + SizedBox( + width: 8, + ), + SizedBox( + height: 8, + width: double.infinity, + child: Container( + color: Color(0xffefefef), + ), + ), + Container( + margin: EdgeInsets.symmetric(vertical: 16, horizontal: 8), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + Image.asset( + "assets/images/pharmacy_module/lakum/expired_icon.png", + fit: BoxFit.fill, + width: 25, + height: 25, + ), + Padding( + padding: EdgeInsets.symmetric(horizontal: 8), + child: Texts( + TranslationBase.of(context).expiryPoints, +// "Expired", fontSize: 14, ), - ], - ), + ) + ], ), - SizedBox( - height: 2, - width: double.infinity, - child: Container( - color: Color(0xffefefef), - ), + Texts( + "${model.lacumGroupInformation!.lakumInquiryInformationObjVersion!.expiredPoints} ${TranslationBase.of(context).lakumPoint} ", + fontWeight: FontWeight.bold, + fontSize: 14, ), - Container( - margin: EdgeInsets.symmetric( - vertical: 16, horizontal: 8), - child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - Image.asset( - "assets/images/pharmacy_module/lakum/waiting_gained_icon.png", - fit: BoxFit.fill, - width: 20, - height: 25, - ), - Padding( - padding: - EdgeInsets.symmetric(horizontal: 8), - child: Texts( - "Waiting gained", - fontSize: 14, - ), - ) - ], - ), - Texts( - "${model.lacumGroupInformation.lakumInquiryInformationObjVersion.waitingPoints} Points", - fontWeight: FontWeight.bold, + ], + ), + ), + // Texts( + // "${model.lacumGroupInformation.lakumInquiryInformationObjVersion.expiredPoints} Points", + // fontWeight: FontWeight.bold, + // fontSize: 14, + // ), + Container( + margin: EdgeInsets.symmetric(vertical: 16, horizontal: 8), + child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ + Row( + children: [ + Image.asset( + "assets/images/pharmacy_module/lakum/waiting_gained_icon.png", + fit: BoxFit.fill, + width: 20, + height: 25, + ), + Padding( + padding: EdgeInsets.symmetric(horizontal: 8), + child: Texts( + TranslationBase.of(context).Waitinggained, +// "Waiting gained", fontSize: 14, ), - ], - ), + ) + ], ), - SizedBox( - height: 2, - width: double.infinity, - child: Container( - color: Color(0xffefefef), - ), + Texts( + "${model.lacumGroupInformation!.lakumInquiryInformationObjVersion!.waitingPoints} ${TranslationBase.of(context).lakumPoint}", + fontWeight: FontWeight.bold, + fontSize: 14, ), - Container( - margin: EdgeInsets.symmetric( - vertical: 16, horizontal: 8), - child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - Image.asset( - "assets/images/pharmacy_module/lakum/will_be_expired_icon.png", - fit: BoxFit.fill, - width: 25, - height: 25, - ), - Padding( - padding: - EdgeInsets.symmetric(horizontal: 8), - child: Texts( - "Will Be Expired", - fontSize: 14, - ), - ) - ], - ), - Texts( - "${model.lacumGroupInformation.lakumInquiryInformationObjVersion.pointsWillBeExpired} Points", - fontWeight: FontWeight.bold, + ])), + // Texts( + // "${model.lacumGroupInformation.lakumInquiryInformationObjVersion.waitingPoints} Points", + // fontWeight: FontWeight.bold, + // fontSize: 14, + // ), + Container( + margin: EdgeInsets.symmetric(vertical: 16, horizontal: 8), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + Image.asset( + "assets/images/pharmacy_module/lakum/will_be_expired_icon.png", + fit: BoxFit.fill, + width: 25, + height: 25, + ), + Padding( + padding: EdgeInsets.symmetric(horizontal: 8), + child: Texts( + TranslationBase.of(context).WillBeExpired, +// "Will Be Expired", fontSize: 14, ), - ], - ), + ) + ], ), - SizedBox( - height: 2, - width: double.infinity, - child: Container( - color: Color(0xffefefef), - ), + Texts( + "${model.lacumGroupInformation!.lakumInquiryInformationObjVersion!.pointsWillBeExpired} ${TranslationBase.of(context).lakumPoint}", + fontWeight: FontWeight.bold, + fontSize: 14, ), ], - ) - : Container(), - ), - ), - )); + ), + // Texts( + // "${model.lacumGroupInformation.lakumInquiryInformationObjVersion.pointsWillBeExpired} Points", + // fontWeight: FontWeight.bold, + // fontSize: 14, + // ), + ), + + SizedBox( + height: 2, + width: double.infinity, + child: Container( + color: Color(0xffefefef), + ), + ), + ], + ) + : Container(), + ), + ), + ), + ); } -} -List _buildAppBarICons(BuildContext context, LacumViewModel model) { - return [ - IconButton( - icon: Icon(Icons.settings), - color: Colors.white, - onPressed: () { - Navigator.push( - context, - FadePage( - page: LakumSettingPage( - model.lacumInformation, model.lacumGroupInformation))) - .then((result) => {model.getLacumGroupData()}); - }, - ), - ]; + navigateToLakumRegister(BuildContext context) { + Navigator.pushReplacement(context, FadePage(page: LakumRegistrationPage(projectViewModel!.user!.patientIdentificationNo!))); + } + + List _buildAppBarICons(BuildContext context, LacumViewModel model) { + return [ + IconButton( + icon: Icon(Icons.settings), + color: Colors.white, + onPressed: () { + Navigator.push(context, FadePage(page: LakumSettingPage(model.lacumInformation!, model.lacumGroupInformation!))).then((result) => {model.getLacumGroupData(projectViewModel!.user!.patientIdentificationNo!)}); + }, + ), + ]; + } } class LakumHomeButtons extends StatelessWidget { final MediaQueryData mediaQuery; final LacumViewModel model; + ProjectViewModel projectViewModel; - LakumHomeButtons(this.mediaQuery, this.model); + LakumHomeButtons(this.mediaQuery, this.model, this.projectViewModel); @override Widget build(BuildContext context) { @@ -317,12 +282,12 @@ class LakumHomeButtons extends StatelessWidget { children: [ Expanded( child: InkWell( - onTap: () { - print("Account activate click"); - Navigator.push( - context, FadePage(page: LakumActivationVidaPage())) - .then((result) => {model.getLacumGroupData()}); - }, +// onTap: () { +// print("Account activate click"); +// Navigator.push( +// context, FadePage(page: LakumActivationVidaPage())) +// .then((result) => {model.getLacumGroupData()}); +// }, child: Container( padding: EdgeInsets.symmetric(horizontal: 8), decoration: BoxDecoration( @@ -363,13 +328,9 @@ class LakumHomeButtons extends StatelessWidget { Expanded( child: InkWell( onTap: () { - print("Lacum transfer click"); - Navigator.push( - context, - FadePage( - page: LacumTransferPage(model.lacumInformation, - model.lacumGroupInformation))) - .then((result) => {model.getLacumGroupData()}); + Navigator.push(context, FadePage(page: LacumTransferPage(model.lacumInformation!, model.lacumGroupInformation!))).then((result) { + model.getLacumGroupData(projectViewModel.user!.patientIdentificationNo!); + }); }, child: Container( padding: EdgeInsets.symmetric(horizontal: 8), @@ -385,7 +346,8 @@ class LakumHomeButtons extends StatelessWidget { child: Row( children: [ Image.asset( - "assets/images/pharmacy_module/lakum/Lakum_transfer_icon.png", + "assets/images/pharmacy_module/lakum/akum_transfer.png", + // "assets/images/pharmacy_module/lakum/Lakum_transfer_icon.png", fit: BoxFit.fill, width: 35, height: 30, @@ -415,19 +377,19 @@ class LacumPointsWidget extends StatelessWidget { final MediaQueryData mediaQuery; final int pointType; // 1. balance, 2. gained, 3. consume, 4. transfer final String title; - final int riyal; - final int point; - Color titleColor; + final num riyal; + final num point; + Color? titleColor; final List pointsAmountPerYear; - LacumPointsWidget(this.mediaQuery, this.pointType, this.title, this.riyal, - this.point, this.pointsAmountPerYear) { + LacumPointsWidget(this.mediaQuery, this.pointType, this.title, this.riyal, this.point, this.pointsAmountPerYear) { if (pointType == 1) { titleColor = Color(0xffefefef); } else if (pointType == 2) { - titleColor = Color(0xff004bcc); - } else if (pointType == 3) { + // titleColor = Color(0xff004bcc); titleColor = Color(0xff339933); + } else if (pointType == 3) { + titleColor = Colors.grey; } else { titleColor = Color(0xffffa500); } @@ -439,16 +401,16 @@ class LacumPointsWidget extends StatelessWidget { onTap: () { if (pointType != 1) { if (pointsAmountPerYear != null && pointsAmountPerYear.length > 0) { - Navigator.push(context, - FadePage(page: LakumPointsYearPage(pointsAmountPerYear))); + Navigator.push(context, FadePage(page: LakumPointsYearPage(pointsAmountPerYear))); } else { + AppToast.showErrorToast(message: TranslationBase.of(context).lakumMsg); // show snackBar No Details Points are there } } }, child: Container( - width: mediaQuery.size.width / 2 - 16, - padding: EdgeInsets.only(top: 12, left: 8, right: 8, bottom: 4), + width: mediaQuery.size.width / 2 - 25, + padding: EdgeInsets.only(top: 12, left: 8, right: 8, bottom: 8), decoration: BoxDecoration( shape: BoxShape.rectangle, borderRadius: BorderRadius.circular(8), @@ -456,13 +418,13 @@ class LacumPointsWidget extends StatelessWidget { color: Color(0xffe1e1e1), width: 0.4, )), - color: pointType == 1 ? Color(0xff004bcc) : Color(0xffefefef), + color: pointType == 1 ? Color(0xff339933) : Color(0xffefefef), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Expanded( + Container( + margin: EdgeInsets.only(bottom: 10.0), child: Column( children: [ Row( @@ -488,14 +450,15 @@ class LacumPointsWidget extends StatelessWidget { ), Expanded( child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ if (pointType != 4) Expanded( child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + // crossAxisAlignment: CrossAxisAlignment.start, children: [ Texts( - "RIYAL", + TranslationBase.of(context).sar, fontSize: 13, fontWeight: FontWeight.bold, color: pointType == 1 ? Colors.white : Colors.black, @@ -521,12 +484,12 @@ class LacumPointsWidget extends StatelessWidget { ), Expanded( child: Container( - margin: EdgeInsets.only(left: 4), + margin: EdgeInsets.only(left: 8, right: 8), child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + // crossAxisAlignment: CrossAxisAlignment.start, children: [ Texts( - "POINT", + TranslationBase.of(context).points, fontSize: 12, fontWeight: FontWeight.bold, color: pointType == 1 ? Colors.white : Colors.black, diff --git a/lib/pages/pharmacies/screens/lakum-points-month-page.dart b/lib/pages/pharmacies/screens/lakum-points-month-page.dart index 47270eee..5e6952ec 100644 --- a/lib/pages/pharmacies/screens/lakum-points-month-page.dart +++ b/lib/pages/pharmacies/screens/lakum-points-month-page.dart @@ -2,10 +2,10 @@ import 'package:diplomaticquarterapp/core/model/pharmacies/PointsAmountPerMonth. import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/lacum-viewmodel.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/widgets/lakum-point-table-row-widget.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.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:flutter/cupertino.dart'; import 'package:flutter/material.dart'; class LakumPointMonthPage extends StatefulWidget { @@ -26,9 +26,13 @@ class _LakumPointsMonthPageState extends State { return BaseView( builder: (_, model, wi) => AppScaffold( - title: "Lakum points", + appBarTitle: TranslationBase.of(context).LakumPoint, isShowAppBar: true, + isPharmacy: true, + showPharmacyCart: false, isShowDecPage: false, + showHomeAppBarIcon: false, + isBottomBar: true, backgroundColor: Colors.white, baseViewModel: model, body: Container( @@ -50,16 +54,14 @@ class _LakumPointsMonthPageState extends State { children: [ Container( height: mediaQuery.size.height * 0.06, - margin: EdgeInsets.symmetric( - vertical: 16, horizontal: 24), + margin: EdgeInsets.symmetric(vertical: 16, horizontal: 24), child: Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ Expanded( child: Column( mainAxisAlignment: MainAxisAlignment.end, - crossAxisAlignment: - CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ Texts( TranslationBase.of(context).month, @@ -78,15 +80,12 @@ class _LakumPointsMonthPageState extends State { Expanded( child: Row( crossAxisAlignment: CrossAxisAlignment.end, - mainAxisAlignment: - MainAxisAlignment.spaceEvenly, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ Expanded( child: Column( - mainAxisAlignment: - MainAxisAlignment.end, - crossAxisAlignment: - CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.end, + crossAxisAlignment: CrossAxisAlignment.center, children: [ Texts( TranslationBase.of(context).point, @@ -110,10 +109,8 @@ class _LakumPointsMonthPageState extends State { ), Expanded( child: Column( - mainAxisAlignment: - MainAxisAlignment.end, - crossAxisAlignment: - CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.end, + crossAxisAlignment: CrossAxisAlignment.center, children: [ Texts( TranslationBase.of(context).riyal, @@ -143,16 +140,14 @@ class _LakumPointsMonthPageState extends State { SizedBox( height: 10, ), - LakumPointTableRowWidget(true, "DAY", 0, 0, null, 0), + LakumPointTableRowWidget(true, "DATE", 0, 0, (){}, 0), ...List.generate( - widget.pointsAmountPerMonth.pointsAmountPerday.length, + widget.pointsAmountPerMonth.pointsAmountPerday!.length, (index) => LakumPointTableRowWidget( false, - widget.pointsAmountPerMonth.pointsAmountPerday[index].day, - widget.pointsAmountPerMonth.pointsAmountPerday[index] - .pointsPerDay, - widget.pointsAmountPerMonth.pointsAmountPerday[index] - .amountPerDay, + DateUtil.getWeekDayMonthDayYearDateFormatted(DateUtil.convertStringToDate(widget.pointsAmountPerMonth!.pointsAmountPerday![index].transationDate!), "en"), + widget.pointsAmountPerMonth.pointsAmountPerday![index].pointsPerDay!, + widget.pointsAmountPerMonth.pointsAmountPerday![index].amountPerDay!, () { setState(() { if (widget.expandedItemIndex == index) { @@ -167,22 +162,11 @@ class _LakumPointsMonthPageState extends State { collapsed: Column( children: [ ...List.generate( - widget.pointsAmountPerMonth.pointsAmountPerday[index] - .pointsDetails.length, + widget.pointsAmountPerMonth.pointsAmountPerday![index].pointsDetails!.length, (index) => DayPointsDetailWidget( - widget - .pointsAmountPerMonth - .pointsAmountPerday[index] - .pointsDetails[index] - .subTransactionTypeDescription, - widget - .pointsAmountPerMonth - .pointsAmountPerday[index] - .pointsDetails[index].purchasePoints, - widget - .pointsAmountPerMonth - .pointsAmountPerday[index] - .pointsDetails[index].amount), + widget.pointsAmountPerMonth!.pointsAmountPerday![index].pointsDetails![index].subTransactionTypeDescription!, + widget.pointsAmountPerMonth.pointsAmountPerday![index].pointsDetails![index].purchasePoints!, + widget.pointsAmountPerMonth.pointsAmountPerday![index]!.pointsDetails![index].amount!), ), ], ), @@ -199,8 +183,8 @@ class _LakumPointsMonthPageState extends State { class DayPointsDetailWidget extends StatelessWidget { final String rowTitle; - final double points; - final double riyal; + final num points; + final num riyal; DayPointsDetailWidget(this.rowTitle, this.points, this.riyal); @@ -237,7 +221,6 @@ class DayPointsDetailWidget extends StatelessWidget { ), )), Expanded( - child: Container( child: Texts( "$points", diff --git a/lib/pages/pharmacies/screens/lakum-points-year-page.dart b/lib/pages/pharmacies/screens/lakum-points-year-page.dart index f7b6d9e6..a5111e5e 100644 --- a/lib/pages/pharmacies/screens/lakum-points-year-page.dart +++ b/lib/pages/pharmacies/screens/lakum-points-year-page.dart @@ -2,6 +2,7 @@ import 'package:diplomaticquarterapp/core/model/pharmacies/PointsAmountPerYear.d import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/lacum-viewmodel.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/widgets/lakum-point-table-row-widget.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'; @@ -26,9 +27,13 @@ class _LakumPointsYearPageState extends State { return BaseView( builder: (_, model, wi) => AppScaffold( - title: "Lakum points", + appBarTitle: TranslationBase.of(context).LakumPoint, isShowAppBar: true, + isPharmacy: true, + showPharmacyCart: false, isShowDecPage: false, + showHomeAppBarIcon: false, + isBottomBar: true, backgroundColor: Colors.white, baseViewModel: model, body: Container( @@ -58,22 +63,22 @@ class _LakumPointsYearPageState extends State { SizedBox( height: 0, ), - LakumPointTableRowWidget(true, "MONTH", 0, 0, null, 0), + LakumPointTableRowWidget(true, "MONTH", 0, 0, (){}, 0), ...List.generate( widget.pointsAmountPerYear[widget.selectedIndexYear] - .pointsAmountPerMonth.length, + .pointsAmountPerMonth!.length, (index) => LakumPointTableRowWidget( false, widget.pointsAmountPerYear[widget.selectedIndexYear] - .pointsAmountPerMonth[index].month, - widget.pointsAmountPerYear[widget.selectedIndexYear] - .pointsAmountPerMonth[index].pointsPerMonth, - widget.pointsAmountPerYear[widget.selectedIndexYear] - .pointsAmountPerMonth[index].amountPerMonth, + .pointsAmountPerMonth![index].month.toString(), + widget.pointsAmountPerYear![widget.selectedIndexYear]! + .pointsAmountPerMonth![index].pointsPerMonth!, + widget.pointsAmountPerYear[widget.selectedIndexYear]! + .pointsAmountPerMonth![index].amountPerMonth!, (){ Navigator.push(context, FadePage(page: LakumPointMonthPage(widget.pointsAmountPerYear[widget.selectedIndexYear] - .pointsAmountPerMonth[index], widget.pointsAmountPerYear[widget.selectedIndexYear].year))); + .pointsAmountPerMonth![index], widget.pointsAmountPerYear![widget.selectedIndexYear!].year!))); }, index), ), @@ -90,7 +95,7 @@ class LacumPointsYearWidget extends StatelessWidget { final MediaQueryData mediaQuery; final bool isSelected; final PointsAmountPerYear yearPoints; - final Function yearOnTap; + final VoidCallback yearOnTap; LacumPointsYearWidget( this.mediaQuery, this.isSelected, this.yearPoints, this.yearOnTap); @@ -102,6 +107,7 @@ class LacumPointsYearWidget extends StatelessWidget { child: Container( width: mediaQuery.size.width / 2 - 16, padding: EdgeInsets.only(top: 12, left: 8, right: 8, bottom: 4), + margin: EdgeInsets.only(right: 8.0), decoration: BoxDecoration( shape: BoxShape.rectangle, borderRadius: BorderRadius.circular(8), @@ -143,8 +149,8 @@ class LacumPointsYearWidget extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Texts( - "POINT", + Texts(TranslationBase.of(context).point, +// "POINT", fontSize: 12, fontWeight: FontWeight.bold, color: isSelected ? Colors.white : Colors.black, @@ -172,9 +178,9 @@ class LacumPointsYearWidget extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ - Texts( - "RIYAL", - fontSize: 13, + Texts(TranslationBase.of(context).sar, +// "RIYAL", + fontSize: 12, fontWeight: FontWeight.bold, color: isSelected ? Colors.white : Colors.black, ), diff --git a/lib/pages/pharmacies/screens/lakum-terms-conditions-page.dart b/lib/pages/pharmacies/screens/lakum-terms-conditions-page.dart index 228b0874..ab1a902e 100644 --- a/lib/pages/pharmacies/screens/lakum-terms-conditions-page.dart +++ b/lib/pages/pharmacies/screens/lakum-terms-conditions-page.dart @@ -1,6 +1,7 @@ import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/lacum-registration-viewModel.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/borderedButton.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; @@ -12,8 +13,7 @@ class LakumTermsConditions extends StatelessWidget { final String firstName, lastName, mobileNo, identificationNo; final int languageId; - LakumTermsConditions(this.identificationNo, this.firstName, this.lastName, - this.mobileNo, this.languageId); + LakumTermsConditions(this.identificationNo, this.firstName, this.lastName, this.mobileNo, this.languageId); @override Widget build(BuildContext context) { @@ -37,13 +37,9 @@ class LakumTermsConditions extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ - if (model.listUserAgreement != null && - model.listUserAgreement.userAgreementLAKUM != - null) + if (model.listUserAgreement != null && model.listUserAgreement.userAgreementLAKUM != null) Html( - data: projectProvider.isArabic - ? model.listUserAgreement.userAgreementLAKUMn - : model.listUserAgreement.userAgreementLAKUM, + data: projectProvider.isArabic ? model.listUserAgreement.userAgreementLAKUMn : model.listUserAgreement.userAgreementLAKUM, ), ], ), @@ -62,9 +58,12 @@ class LakumTermsConditions extends StatelessWidget { vPadding: 12, handler: () { model.createNewLakumAccount("$firstName $lastName", mobileNo, identificationNo, languageId).then((status) => { - if (status == 200) {Navigator.pop(context, "")} - // back to previous page - }); + if (status == 200) {Navigator.pop(context, "")} else { + Navigator.pop(context, ""), + AppToast.showErrorToast(message: model.error) + } + // back to previous page + }); }, ), ), diff --git a/lib/pages/pharmacies/screens/order-preview-page.dart b/lib/pages/pharmacies/screens/order-preview-page.dart deleted file mode 100644 index d9646fcf..00000000 --- a/lib/pages/pharmacies/screens/order-preview-page.dart +++ /dev/null @@ -1,48 +0,0 @@ -import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/OrderPreviewViewModel.dart'; -import 'package:diplomaticquarterapp/pages/base/base_view.dart'; -import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/GestureIconButton.dart'; -import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:flutter/material.dart'; - -class OrderPreviewPage extends StatelessWidget { - @override - Widget build(BuildContext context) { - return BaseView( - builder: (_, model, wi) => AppScaffold( - title: "Shopping Cart", - isShowAppBar: true, - isShowDecPage: false, - baseViewModel: model, - backgroundColor: Colors.white, - body: Container( - 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.shade800,), - onTap: () => {}, - ), - const Divider( - color: Colors.grey, - height: 20, - thickness: 1, - indent: 0, - endIndent: 0, - ), - - ], - ), - ), - ), - ), - ), - ); - } -} - diff --git a/lib/pages/pharmacies/screens/payment-method-select-page.dart b/lib/pages/pharmacies/screens/payment-method-select-page.dart index 8cdbaf3c..0aa86c6b 100644 --- a/lib/pages/pharmacies/screens/payment-method-select-page.dart +++ b/lib/pages/pharmacies/screens/payment-method-select-page.dart @@ -1,18 +1,29 @@ +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:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; +import 'cart-page/cart-order-preview.dart'; + class PaymentMethodSelectPage extends StatefulWidget { + final OrderPreviewViewModel? model; + final bool isUpdating; + final VoidCallback? changeMainState; + + const PaymentMethodSelectPage({Key? key, this.model, this.isUpdating = false, this.changeMainState}) : super(key: key); + @override - _PaymentMethodSelectPageState createState() => - _PaymentMethodSelectPageState(); + _PaymentMethodSelectPageState createState() => _PaymentMethodSelectPageState(); } class _PaymentMethodSelectPageState extends State { - PaymentOption selectedPaymentOption; + PaymentOption? selectedPaymentOption; @override Widget build(BuildContext context) { @@ -20,8 +31,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 +42,67 @@ 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), - selectedPaymentOption, - PaymentOption.installments, + 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.installments; + selectedPaymentOption = PaymentOption.mastercard; }) }), + widget.model!.cartResponse.totalAmount! > 1000 + ? PaymentMethodCard( + cardWidth, + selectedPaymentOption!, + PaymentOption.installments, + () => { + setState(() { + selectedPaymentOption = PaymentOption.installments; + }) + }) + : Container(), + if (Platform.isIOS) + PaymentMethodCard( + cardWidth, + selectedPaymentOption!, + PaymentOption.applepay, + () => { + setState(() { + selectedPaymentOption = PaymentOption.applepay; + }) + }), ], ), ), @@ -103,18 +110,31 @@ 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)} + selectedPaymentOption != null + ? () { + widget.model!.paymentCheckoutData!.paymentOption = selectedPaymentOption; + if (widget.isUpdating) { + widget.changeMainState!(); + Navigator.pop(context); + return; + } else { + Navigator.push( + context, + FadePage( + page: OrderPreviewPage( + model: widget.model!, + ), + ), + ); + } + // Navigator.pop(context, selectedPaymentOption); + } : null, + color: Color(0xff5AB154), ), ), ); @@ -125,63 +145,70 @@ class PaymentMethodCard extends StatelessWidget { final double cardWidth; final PaymentOption selectedPaymentOption; final PaymentOption paymentOption; - final Function selectMethod; + final VoidCallback 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, + ), + ), + ), + ], + ), + ), ), ), ); } 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 +217,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 ""; diff --git a/lib/pages/pharmacies/screens/pharmacy-terms-conditions-page.dart b/lib/pages/pharmacies/screens/pharmacy-terms-conditions-page.dart index 87c1b97c..6c58970c 100644 --- a/lib/pages/pharmacies/screens/pharmacy-terms-conditions-page.dart +++ b/lib/pages/pharmacies/screens/pharmacy-terms-conditions-page.dart @@ -2,7 +2,6 @@ import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/tems-conditi import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/borderedButton.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/material.dart'; import 'package:flutter_html/flutter_html.dart'; diff --git a/lib/pages/pharmacies/screens/pharmacy_module_page.dart b/lib/pages/pharmacies/screens/pharmacy_module_page.dart index e4830583..cbf228de 100644 --- a/lib/pages/pharmacies/screens/pharmacy_module_page.dart +++ b/lib/pages/pharmacies/screens/pharmacy_module_page.dart @@ -1,33 +1,16 @@ -import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; -import 'package:diplomaticquarterapp/config/size_config.dart'; -import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; -import 'package:diplomaticquarterapp/core/model/pharmacies/recommendedProduct_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/OrderPreviewViewModel.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart'; -import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/product_detail_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; -import 'package:diplomaticquarterapp/pages/landing/home_page.dart'; -import 'package:diplomaticquarterapp/pages/medical/prescriptions/prescriptions_home_page.dart'; -import 'package:diplomaticquarterapp/pages/offers_categorise_page.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/product-brands.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/product_detail.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/screens/lacum-activitaion-vida-page.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/screens/lakum-main-page.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/screens/recommended-product-page.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/widgets/BannerPager.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/widgets/ProductTileItem.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/widgets/manufacturerItem.dart'; -import 'package:diplomaticquarterapp/pages/pharmacy/pharmacyAddresses/PharmacyAddresses.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/pages/pharmacies/widgets/home/BannerPager.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/widgets/home/BestSellerWidget.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/widgets/home/GridViewButtons.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/widgets/home/MostViewedWidget.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/widgets/home/PrescriptionsWidget.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/widgets/home/RecentlyViewedWidget.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/widgets/home/ShopByBrandWidget.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:rating_bar/rating_bar.dart'; -import '../../final_products_page.dart'; -import 'lacum-activitaion-vida-page.dart'; +import 'package:provider/provider.dart'; bool isInWishlist = false; int price = 0; @@ -36,877 +19,55 @@ var product; var customerId; var item; dynamic languageID; -List wishlistData; +List? wishlistData; class PharmacyPage extends StatefulWidget { -// final PharmacyProduct product; -// PharmacyPage(this.product); - @override _PharmacyPageState createState() => _PharmacyPageState(); } class _PharmacyPageState extends State { -// dynamic wishlistVar; - - getLanguageID() async { - languageID = await sharedPref.getString(APP_LANGUAGE); - } - - List recommendedProductList = []; - List wishList = []; - - var model; -// String ProductId="4561"; - //String id ="3608"; - String productId = ""; - String id = ""; - @override - void initState() { - checkWishlist(); - // userInfo(widget.product.id, widget.product); - userInfo(id, product); - print("-------------this--------------"); - print(itemID); - } - - @override - Widget build(BuildContext context) { - return BaseView( - onModelReady: (model) => model.getPharmacyHomeData(), - allowAny: true, - builder: (_, model, wi) => AppScaffold( - title: "", - isShowAppBar: false, - isShowDecPage: false, - baseViewModel: model, - backgroundColor: Colors.white, - body: Container( - width: double.infinity, - child: SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - BannerPager(model), - // GridViewButtons(model), - Container( - margin: EdgeInsets.fromLTRB(10, 10, 10, 10), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Texts( - TranslationBase.of(context).myPrescription, - bold: true, - ), - BorderedButton( - TranslationBase.of(context).viewAll, - hasBorder: true, - borderColor: Colors.green, - textColor: Colors.green, - vPadding: 6, - hPadding: 4, - handler: () { - Navigator.push( - context, FadePage(page: HomePrescriptionsPage())); - }, - ), - ], - ), - ), - Container( - height: model.prescriptionsList.length > 0 - ? MediaQuery.of(context).size.height * 0.28 - : 0, - padding: - EdgeInsets.symmetric(horizontal: 18.0, vertical: 14.0), -// height: MediaQuery.of(context).size.height * 0.28, -// width: 200.0, -// height: MediaQuery.of(context).size.height / 4 + 20, - margin: EdgeInsets.only(left: 10), - child: BaseView( - onModelReady: (model) => model.getPrescription(), - builder: (_, model, wi) => model.prescriptionsList.length != - 0 -// model.getPrescription(); - ? ListView.builder( - scrollDirection: Axis.horizontal, - shrinkWrap: true, - physics: ScrollPhysics(), - // physics: NeverScrollableScrollPhysics(), - itemCount: model.prescriptionsList.length, - itemBuilder: (context, index) { - return Container( -// width: 160.0, - height: - MediaQuery.of(context).size.height * 0.6, - padding: EdgeInsets.only( - bottom: 5.0, left: 5.0, right: 8.0), - margin: EdgeInsets.only(right: 10.0), - decoration: BoxDecoration( - border: Border.all( - color: Colors.grey, - style: BorderStyle.solid, - width: 1.0, - ), - color: Colors.white, - borderRadius: BorderRadius.circular(10.0)), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - 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( -// // crossAxisAlignment: CrossAxisAlignment.center, -// children: [ -// Container( -// margin: EdgeInsets.only(left: 1), -// padding: EdgeInsets.only( -// top: 10.0, -// left: 10.0, -// right: 3.0, -// bottom: 15.0, -// ), -// child: Image.network( -// model.prescriptionsList[index] -// .doctorImageURL, -// width: 60, -// height: 60, -// ), -// ), -// ]), - Column( -// crossAxisAlignment: CrossAxisAlignment.center, - 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( - languageID == "ar" - ? model - .prescriptionsList[ - index] - .isInOutPatientDescriptionN - .toString() - : model - .prescriptionsList[ - index] - .isInOutPatientDescription - .toString(), - style: TextStyle( - color: Colors.white, - fontSize: 15.0, -// fontWeight: FontWeight.bold, - ), - )), - 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, -// 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: 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, - ), - ), - ) - ]), - ]), - ); - }) - : Container(), - ), - ), -// Container( -// margin: EdgeInsets.fromLTRB(10, 10, 10, 10), -// child: Row( -// mainAxisAlignment: MainAxisAlignment.spaceBetween, -// children: [ -// Texts( -// TranslationBase.of(context).recommended, -// bold: true, -// ), -// BorderedButton( -// TranslationBase.of(context).viewAll, -// hasBorder: true, -// borderColor: Colors.green, -// textColor: Colors.green, -// vPadding: 6, -// hPadding: 4, -// handler: () { -// Navigator.push( -// context, -// MaterialPageRoute( -// builder: (context) => -// RecommendedProductPage(productId : "2316"))); -// }, -// ), -// ], -// ), -// ), -// Container( -// height: model.recommendedProductList.length > 0 -// ? MediaQuery.of(context).size.height * 0.32 -// : 0, -// margin: EdgeInsets.symmetric(horizontal: 6, vertical: 4), -//// padding: EdgeInsets.symmetric(horizontal: 5.0, vertical: 22.0), -//// margin: EdgeInsets.only(left: 10), -// child: BaseView( -// onModelReady: (model) => -// model.getRecommendedProducts(productId), -// builder: (_, model, wi) => model -// .recommendedProductList.length != -// null -// ? ListView.builder( -// scrollDirection: Axis.horizontal, -// shrinkWrap: true, -// physics: ScrollPhysics(), -// // physics: NeverScrollableScrollPhysics(), -// itemCount: model.recommendedProductList.length, -// itemBuilder: (context, index) { -// return Card( -// elevation: 2, -// shape: RoundedRectangleBorder( -// side: BorderSide( -// color: Colors.grey[300], width: 2), -// borderRadius: BorderRadius.circular(10)), -// margin: EdgeInsets.symmetric( -// horizontal: 8, -// vertical: 0, -// ), -// child: Container( -// decoration: BoxDecoration( -// borderRadius: BorderRadius.all( -// Radius.circular(15), -// ), -// ), -// padding: EdgeInsets.symmetric(horizontal: 4), -// width: MediaQuery.of(context).size.width / 3, -// child: Column( -// crossAxisAlignment: -// CrossAxisAlignment.start, -// children: [ -// Stack(children: [ -// Container( -// child: Align( -// alignment: Alignment.topRight, -// child: //true -// itemID.contains(model.recommendedProductList[index].id) -// // !isInWishlist -// ? IconButton( -// icon: Icon(Icons -// .favorite_border), -// color: Colors.grey, -// iconSize: 30, -// onPressed: () { -// setState(() { -// addToWishlistFunction( -// itemID); -// }); -// }, -// ) -// : IconButton( -// icon: Icon( -// Icons.favorite), -// color: Colors.red, -// iconSize: 30, -// onPressed: () { -// setState(() { -// deleteFromWishlistFunction( -// itemID); -// }); -// }, -// ) -//// -// ), -// ), -// Container( -// margin: EdgeInsets.fromLTRB( -// 0, 16, 10, 16), -// alignment: Alignment.center, -//// padding: EdgeInsets.only(left: 25, bottom: 20), -// child: (model.recommendedProductList[index].images != null && -// model.recommendedProductList[index].images.length > 0) -// ? Image.network( -// model.recommendedProductList[index].images[0].src.toString(), -//// item.images[0].src, -// fit: BoxFit.cover, -// height: 60, -// ) -// : Image.asset( -// "assets/images/no_image.png", -// fit: BoxFit.cover, -// height: 60, -// ), -// ), -// Container( -// width: model -// .recommendedProductList[ -// index] -// .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: Texts( -// model.recommendedProductList[index] -// .rxMessage != -// null -// ? model -// .recommendedProductList[ -// index] -// .rxMessage -// : "", -// color: Colors.white, -// regular: true, -// fontSize: 10, -// fontWeight: FontWeight.w400, -// ), -// ), -// ]), -// Container( -// margin: EdgeInsets.symmetric( -// horizontal: 6, -// vertical: 0, -// ), -// child: Column( -// crossAxisAlignment: -// CrossAxisAlignment.start, -// children: [ -// Text( -// languageID == "ar" -// ? model.recommendedProductList[index].namen -// : model.recommendedProductList[index].name, -// style: TextStyle( -// color: Colors.black, -// fontSize: 13.0, -//// fontWeight: FontWeight.bold, -// ), -// ), -// Padding( -//// padding: const EdgeInsets.only(top: 15, bottom: 10), -// padding: const EdgeInsets.only( -// top: 10, bottom: 5), -// child: Texts( -// "SAR ${model.recommendedProductList[index].price}", -// bold: true, -// fontSize: 14, -// ), -// ), -// ], -// ), -// ), -// Row( -// crossAxisAlignment: -// CrossAxisAlignment.start, -// children: [ -// Container( -// padding: -// EdgeInsets.only(right: 10), -//// margin: EdgeInsets.only(left: 5), -// child: Align( -// alignment: Alignment.topLeft, -// child: RatingBar.readOnly( -// initialRating: model -// .recommendedProductList[ -// index] -// .approvedRatingSum -// .toDouble(), -//// initialRating: productRate, -// size: 13.0, -// filledColor: -// Colors.yellow[700], -// emptyColor: Colors.grey[500], -// isHalfAllowed: true, -// halfFilledIcon: -// Icons.star_half, -// filledIcon: Icons.star, -// emptyIcon: Icons.star, -// ), -// ), -// ), -// Texts( -// "(${model.recommendedProductList[index].approvedTotalReviews.toString()})", -//// bold: true, -// fontSize: 12, -// ), -// ]), -// ], -// ), -// ), -// ); -// }) -// : Container( -//// child: Text("NO DATA"), -// ), -// ), -// ), - Container( - margin: EdgeInsets.fromLTRB(10, 10, 10, 0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Texts( - TranslationBase.of(context).shopByBrands, - bold: true, - ), - BorderedButton( - TranslationBase.of(context).viewAll, - hasBorder: true, - vPadding: 6, - hPadding: 4, - borderColor: Colors.green, - textColor: Colors.green, - handler: () => { - Navigator.push( - context, FadePage(page: ProductBrandsPage())), - }, - ), - ], - ), - ), - Container( - height: 60, - child: ListView.builder( - itemBuilder: (ctx, i) => - ManufacturerItem(model.manufacturerList[i]), - scrollDirection: Axis.horizontal, - itemCount: model.manufacturerList.length, - ), - ), - Container( - margin: EdgeInsets.fromLTRB(10, 10, 10, 10), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Texts( - TranslationBase.of(context).recentlyViewed, - bold: true, - ), - BorderedButton( - TranslationBase.of(context).viewAll, - hasBorder: true, - vPadding: 6, - hPadding: 4, - borderColor: Colors.green, - textColor: Colors.green, - handler: () { - Navigator.push( - context, - FadePage( - page: FinalProductsPage( - id: "", - productType: 3, - ), - ), - ); - }, - ), - ], - ), - ), - Container( - height: model.lastVisitedProducts.length > 0 - ? MediaQuery.of(context).size.height / 4 + 20 - : 0, - child: ListView.builder( - itemBuilder: (ctx, i) => - ProductTileItem(model.lastVisitedProducts[i]), - scrollDirection: Axis.horizontal, - itemCount: model.lastVisitedProducts.length, - ), - ), - Container( - margin: EdgeInsets.fromLTRB(10, 10, 10, 10), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Texts( - TranslationBase.of(context).bestSellers, - bold: true, - ), - BorderedButton( - TranslationBase.of(context).viewAll, - hasBorder: true, - borderColor: Colors.green, - textColor: Colors.green, - vPadding: 6, - hPadding: 4, - handler: () => { - Navigator.push( - context, - FadePage( - page: FinalProductsPage( - id: "", - productType: 4, - ), - ), - ), - }, - ), - ], - ), - ), - Container( - height: MediaQuery.of(context).size.height / 4 + 20, - child: ListView.builder( - itemBuilder: (ctx, i) => - ProductTileItem(model.bestSellerProduct[i]), - scrollDirection: Axis.horizontal, - itemCount: model.bestSellerProduct.length, - ), - ), - ], - ), - ), - ), - ), - ); - } - - addToWishlistFunction(itemID) async { - ProductDetailViewModel x = new ProductDetailViewModel(); - isInWishlist = true; - await x.addToWishlistData(itemID); - } - - deleteFromWishlistFunction(itemID) async { - ProductDetailViewModel x = new ProductDetailViewModel(); - isInWishlist = false; - await x.addToWishlistData(itemID); - } - - checkWishlist() async { - ProductDetailViewModel x = new ProductDetailViewModel(); - await x.checkWishlistData(); - for (int i = 0; i < x.wishListItems.length; i++) { - // itemID = x.wishListItems[i].id; - print("-------------wishlist---------------"); - print(itemID); -// print(product.id); - print(x.wishListItems[i].productId); - if (itemID == x.wishListItems[i].productId) { - isInWishlist = true; -// print('in wishlist'); - break; - } else { - isInWishlist = false; -// print('not in wishlist'); - } - } - } - - Future userInfo(id, product) async { - customerId = await sharedPref.getString(PHARMACY_CUSTOMER_ID); - if (customerId != null) { - itemID = id; - product = product; - checkWishlist(); - } - print("customerId:$customerId"); - return customerId; - } -} - -class GridViewButtons extends StatelessWidget { - final PharmacyModuleViewModel model; - - GridViewButtons(this.model); - @override Widget build(BuildContext context) { - final gridHeight = (MediaQuery.of(context).size.width * 0.3) * 1.8; - return Container( - child: SizedBox( - height: gridHeight, - child: GridView.count( - childAspectRatio: 2.2, - crossAxisSpacing: 10, - mainAxisSpacing: 10, - controller: new ScrollController(keepScrollOffset: false), - shrinkWrap: true, - padding: const EdgeInsets.all(4.0), - crossAxisCount: 2, - children: [ - DashboardItem( - imageName: 'pharmacy_module/bg_1.png', - hasColorFilter: false, - opacity: 0.8, - child: GridViewCard( - TranslationBase.of(context).offersAndPromotions, - 'assets/images/pharmacy_module/offer_icon.png', () { - 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', () { - 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: PharmacyAddressesPage())); - }), - ), - 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', - () {}), - ), - ], - ), - ), - ); - } -} - -class GridViewCard extends StatelessWidget { - final String text; - final String cardImage; - final Function handler; - - GridViewCard(this.text, this.cardImage, this.handler); - - @override - Widget build(BuildContext context) { - return Padding( - padding: const EdgeInsets.all(4.0), - child: Container( - child: Row( - children: [ - Expanded( - flex: 2, + OrderPreviewViewModel orderPreviewViewModel = Provider.of(context); + return WillPopScope( + onWillPop: () async { + return false; + }, + child: BaseView( + onModelReady: (model) async { + await model.getSavedLanguage(); + await model.getBannerList(); + if (model.isLogin) await orderPreviewViewModel.getShoppingCart(); + }, + allowAny: true, + builder: (_, model, wi) => AppScaffold( + title: "", + isShowDecPage: false, + baseViewModel: model, + isMainPharmacyPages: true, + isPharmacy: true, + isShowPharmacyAppbar: true, + backgroundColor: Color(0xffFEFEFE), + body: Container( + width: double.infinity, + child: SingleChildScrollView( child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - flex: 2, - child: Padding( - padding: const EdgeInsets.all(6), - child: Texts( - text, - color: Colors.white, - fontSize: SizeConfig.textMultiplier * 1.5, - ), - ), - ), - Row( - children: [ - BorderedButton( - TranslationBase.of(context).viewAll, - handler: handler, - tPadding: 0, - bPadding: 0, - ), - Expanded(child: Container()), - ], - ), + //crossAxisAlignment: CrossAxisAlignment.start, + children: [ + BannerPager(model), + PrescriptionsWidget(), + //ShopByBrandWidget(), + MostViewedWidget(), + RecentlyViewedWidget(), + BestSellerWidget(), + //ShopByBrandWidget(), ], ), ), - Expanded( - child: Align( - alignment: Alignment.centerRight, - child: Image.asset( - cardImage, - fit: BoxFit.cover, - ), - ), - ), - ], + ), ), ), ); } - - String getDate(String date) { - DateTime dateObj = DateUtil.convertStringToDate(date); - return DateUtil.getWeekDay(dateObj.weekday) + - ", " + - dateObj.day.toString() + - " " + - DateUtil.getMonth(dateObj.month) + - " " + - dateObj.year.toString(); - } -} - -class test extends StatefulWidget { - @override - _testState createState() => _testState(); -} - -class _testState extends State { - @override - Widget build(BuildContext context) { - return Container(); - } } -//addWishlistData() async { -// ProductDetailViewModel x = new ProductDetailViewModel(); -// await wishlistData.add(x.checkWishlistData()); -// print("-------------testWishlist---------------"); -// -//} - -// checkWishlist() async { -// ProductDetailViewModel x = new ProductDetailViewModel(); -// wishlistVar = await x.checkWishlistData(); -// print("wishlistVar>>>>>>>>>>>>>>>"); -// print(wishlistVar); -// -// } diff --git a/lib/pages/pharmacies/screens/product-details/availability_info.dart b/lib/pages/pharmacies/screens/product-details/availability_info.dart new file mode 100644 index 00000000..4c635507 --- /dev/null +++ b/lib/pages/pharmacies/screens/product-details/availability_info.dart @@ -0,0 +1,97 @@ +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/product_detail_view_model.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:map_launcher/map_launcher.dart'; +import 'package:url_launcher/url_launcher.dart'; + +class AvailabilityInfo extends StatelessWidget { + final ProductDetailViewModel? previousModel; + + final InAppBrowser browser = new InAppBrowser(); + + AvailabilityInfo({Key? key, this.previousModel}) : super(key: key); + + @override + Widget build(BuildContext context) { + return previousModel!.productLocationService.length == 0 + ? Container( + padding: EdgeInsets.all(15), + alignment: Alignment.center, + child: Text( + TranslationBase.of(context).noLocationAvailable, + ), + ) + : Container( + margin: EdgeInsets.only(bottom: 40), + child: ListView.builder( + physics: ScrollPhysics(), + scrollDirection: Axis.vertical, + shrinkWrap: true, + itemCount: previousModel!.productLocationService.length, + itemBuilder: (BuildContext context, int index) { + return Padding( + padding: EdgeInsets.all(8), + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Expanded( + flex: 1, + child: Image.network(previousModel!.productLocationService![index].projectImageUrl!), + ), + SizedBox( + width: 10, + ), + Expanded( + flex: 4, + child: Text( + previousModel!.productLocationService![index].locationDescription! + "\n" + previousModel!.productLocationService[index].cityName.toString(), + style: TextStyle(fontSize: 12), + ), + ), + Expanded( + flex: 1, + child: IconButton( + icon: Icon(Icons.location_on), + color: Colors.red, + onPressed: () async { + await MapLauncher.showMarker( + mapType: MapType.google, + coords: Coords(double.parse(previousModel!.productLocationService[index].latitude!), double.parse(previousModel!.productLocationService[index]!.longitude!)), + title: previousModel!.productLocationService![index].locationDescription!, + ); + }, + ), + ), + Expanded( + flex: 1, + child: IconButton( + icon: Icon(Icons.phone), + color: Colors.red, + onPressed: () { + launch("tel://" + previousModel!.productLocationService[index]!.phoneNumber!); + }, + ), + ), + ], + ), + Divider(height: 1.2, color: Colors.grey) + ], + ), + ); + }, + ), + ); + } + + convertCityName(txt) { + String stringTxt; + String newTxt; + stringTxt = txt.toString(); + newTxt = stringTxt.split('.')[1]; + + return newTxt; + } +} diff --git a/lib/pages/pharmacies/screens/product-details/details_info.dart b/lib/pages/pharmacies/screens/product-details/details_info.dart new file mode 100644 index 00000000..95c6ca4b --- /dev/null +++ b/lib/pages/pharmacies/screens/product-details/details_info.dart @@ -0,0 +1,57 @@ +import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.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/material.dart'; +import 'package:provider/provider.dart'; + +class DetailsInfo extends StatelessWidget { + + final PharmacyProduct? product; + + const DetailsInfo({Key? key, this.product}) : super(key: key); + + + @override + Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + return Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ +// Container( +// child: Texts( +// TranslationBase.of(context) +// .description, +// fontSize: 17, +// color: Colors.grey, +// ), +// ), +// SizedBox( +// height: 10, +// ), +// Divider(height: 1, color: Colors.grey), + SizedBox( + height: 10, + ), + Container( + margin: EdgeInsets.only(left: 10, right: 10), + child: Text( + projectViewModel.isArabic + ? product!.fullDescriptionn! + : product! + .fullDescription! ?? + "", + style: TextStyle(fontWeight: FontWeight.w600, fontSize: 14, letterSpacing:-0.56), + ), + ), + SizedBox( + height: 60, + ), + ]), + ); + } +} diff --git a/lib/pages/pharmacies/screens/product-details/discount_description.dart b/lib/pages/pharmacies/screens/product-details/discount_description.dart new file mode 100644 index 00000000..10233b1c --- /dev/null +++ b/lib/pages/pharmacies/screens/product-details/discount_description.dart @@ -0,0 +1,47 @@ +import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; +import 'package:flutter/material.dart'; + +class DiscountDescription extends StatelessWidget { + final PharmacyProduct? product; + + const DiscountDescription({Key? key, this.product}) : super(key: key); + @override + Widget build(BuildContext context) { + return Container( + width: double.infinity, + height: 50, + color: Colors.yellowAccent, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( + flex: 1, + child: Container( + alignment: Alignment.centerRight, + child: Text( + product! + .discountDescription!, + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 17), + ), + ), + ), + SizedBox( + width: 10, + ), + Expanded( + flex: 0, + child: Container( + child: Image( + image: AssetImage( + 'assets/images/offer.png'), + ), + ), + ), + ], + ), + ); + } +} diff --git a/lib/pages/pharmacies/screens/product-details/footor/footer-widget.dart b/lib/pages/pharmacies/screens/product-details/footor/footer-widget.dart new file mode 100644 index 00000000..f4928e49 --- /dev/null +++ b/lib/pages/pharmacies/screens/product-details/footor/footer-widget.dart @@ -0,0 +1,358 @@ +import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +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/models/Authentication/select_device_imei_res.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/footor/quantity_box.dart'; +import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; +import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/text/app_texts_widget.dart'; +import 'package:flutter/material.dart'; + +import '../../../../../locator.dart'; +import '../../../../../routes.dart'; + +class FooterWidget extends StatefulWidget { + final bool isAvailable; + final int maxQuantity; + final int minQuantity; + final int quantityLimit; + final PharmacyProduct item; + final Function? addToCartFunction; + final Function? addToShoppingCartFunction; + final ProductDetailViewModel? model; + + 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}); + + @override + _FooterWidgetState createState() => _FooterWidgetState(); +} + +class _FooterWidgetState extends State { + double quantityUI = 80; + bool showUI = false; + + static final GlobalKey _key = GlobalKey(); + AuthenticatedUserObject authenticatedUserObject = + locator(); + AppSharedPreferences sharedPref = new AppSharedPreferences(); + + @override + void initState() { + super.initState(); + if (!isBuyNowDisable() || !isAddToCartDisable()) { + quantityUI = 160; + showUI = true; + } + } + + @override + Widget build(BuildContext context) { + return Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all( + Radius.circular(0.0), + ), + boxShadow: [ + BoxShadow( + color: Color(0xFFCCCCCC), + spreadRadius: 0, + blurRadius: 4, + offset: Offset(2, 2), // changes position of shadow + ), + ], + // border: Border.all(color: Color(0xFF707070), width: 0), + ), + width: double.infinity, + height: quantityUI, + child: Column( + children: [ + !showUI + ? Container( + height: 10, + ) + : Container( + width: double.infinity, + height: 100, + color: Colors.white, + child: Container( + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: 10, + ), + Row( + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Texts( + TranslationBase.of(context).productQuantity, + fontSize: 15, + fontWeight: FontWeight.bold, + color: Color(0xFF575757)), + ), + InkWell( + child: Icon(Icons.close, color: Colors.black), + onTap: () { + setState(() { + quantityUI = 80; + showUI = false; + }); + }, + ) + ], + mainAxisAlignment: MainAxisAlignment.spaceBetween, + ), + Container( + height: 35.0, + child: ListView( + scrollDirection: Axis.horizontal, + children: [ + SizedBox( + width: 5, + ), + for (int i = 1; i <= 10; i++) + QuantityBox( + label: i, + onTapFunc: onChangeValue, + isSelected: widget.quantity == i), + Container( + width: 100, + decoration: BoxDecoration( + border: Border.all(color: Colors.grey[300]!), + color: Colors.white, + ), + child: TextField( + key: _key, + keyboardType: TextInputType.number, + textAlign: TextAlign.center, + decoration: + InputDecoration(hintText: ' Quantity # '), + onChanged: (text) { + if (int.tryParse(text) == null) { + text = ''; + } else { + setState(() { + widget.quantity = int.parse(text); + if (widget.quantity! >= + widget.quantityLimit) { + widget.isOverQuantity = true; + } else { + widget.isOverQuantity = false; + } + }); + } + }, + ), + ), + ], + ), + ) + ], + ), + ), + ), + Container( + height: 58, + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + height: 60, + child: TextButton( + child: Row( + children: [ + Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AppText( + TranslationBase.of(context).productQuantity, + fontSize: 10, + fontWeight: FontWeight.w600, + ), + Row( + children: [ + AppText( + widget.quantity.toString(), + fontSize: 16, + fontWeight: FontWeight.bold, + ), + SizedBox( + width: 20, + ), + Icon( + Icons.keyboard_arrow_down, + color: Color(0xFF2E303A), + size: 25, + ) + ], + ), + ], + ), + SizedBox( + width: 10, + ), + SizedBox( + height: 40, + width: 1, + child: Container( + color: Color(0xFFEFEFEF), + ), + ), + ], + ), + onPressed: widget.isAvailable && !widget.item.isRx! + ? () { + setState(() { + if (showUI) { + quantityUI = 80; + showUI = false; + } else { + quantityUI = 160; + showUI = true; + } + }); + } + : null, + ), + ), + SizedBox( + width: 10, + ), + Container( + width: MediaQuery.of(context).size.width * 0.35, + margin: EdgeInsets.symmetric(vertical: 4.0), + child: SecondaryButton( + label: TranslationBase.of(context).addToCart, + disabled: isAddToCartDisable(), + fontSize: 15, + onTap: () async { + if (!authenticatedUserObject.isLogin) { + login(); + } else + await widget.addToCartFunction!( + quantity: widget.quantity, + itemID: widget.item.id, + model: widget.model); + }, + fontWeight: FontWeight.w600, + borderRadius: 6, + disableColor: Color(0xFFD6D6D6), + textColor: + isAddToCartDisable() ? Color(0xFFACACAC) : Colors.white, + color: Color(0xFF535353), + ), + ), + SizedBox( + width: 5, + ), + Container( + width: MediaQuery.of(context).size.width * 0.35, + margin: EdgeInsets.symmetric(vertical: 4.0), + child: SecondaryButton( + label: TranslationBase.of(context).buyNow, + fontSize: 15, + disabled: isBuyNowDisable(), + onTap: () async { + if (!authenticatedUserObject.isLogin) { + login(); + } else { + await widget.addToShoppingCartFunction!( + quantity: widget.quantity, + itemID: widget.item.id, + model: widget.model); + } + }, + textColor: + isBuyNowDisable() ? Color(0xFFACACAC) : Colors.white, + fontWeight: FontWeight.w600, + borderRadius: 6, + disableColor: Color(0xFFD6D6D6), + color: Color(0xFF5AB145), + ), + ), + ], + ), + ), + ], + ), + ); + } + + bool isBuyNowDisable() { + return (!widget.isAvailable && widget.quantity! > 0) || + (widget.quantity! > widget.quantityLimit) || + widget.item.isRx!; + } + + bool isAddToCartDisable() { + return (!widget.isAvailable && widget.quantity! > 0) || + widget.quantity! > widget.quantityLimit || + widget.item.isRx!; + } + + void setUserValues(value) async { + if (value != null) sharedPref.setObject(IMEI_USER_DATA, value); + } + + login() async { + final authService = new AuthProvider(); + 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); + authService + .selectDeviceImei(DEVICE_TOKEN) + .then((SelectDeviceIMEIRES? value) { + GifLoaderDialogUtils.hideDialog(context); + if (value != null) { + setUserValues(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, + ); + }); + } + } + + onChangeValue(int i) { + setState(() { + widget.quantity = i; + if (widget.quantity! >= widget.quantityLimit) { + widget.isOverQuantity = true; + } else { + widget.isOverQuantity = false; + //return widget.quantity!; + } + + }); + } +} diff --git a/lib/pages/pharmacies/screens/product-details/footor/quantity_box.dart b/lib/pages/pharmacies/screens/product-details/footor/quantity_box.dart new file mode 100644 index 00000000..3ece6cc5 --- /dev/null +++ b/lib/pages/pharmacies/screens/product-details/footor/quantity_box.dart @@ -0,0 +1,42 @@ +import 'package:flutter/material.dart'; + +class QuantityBox extends StatelessWidget { + final int? label; + final bool? isSelected; + final Function(int)? onTapFunc; + + QuantityBox({ + Key? key, + this.label, + this.onTapFunc, this.isSelected = false, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return Row( + children: [ + InkWell( + child: Container( + decoration: BoxDecoration( + border: Border.all(color:isSelected!?Colors.green: Colors.grey[300]!), + color: Colors.white, + ), + alignment: Alignment.center, + width: 50.0, + + child: Text( + '$label', + style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20), + ), + ), + onTap:(){ + onTapFunc!(label!)!; + } + ), + SizedBox( + width: 5, + ) + ], + ); + } +} diff --git a/lib/pages/pharmacies/screens/product-details/product-detail.dart b/lib/pages/pharmacies/screens/product-details/product-detail.dart new file mode 100644 index 00000000..fa49cc51 --- /dev/null +++ b/lib/pages/pharmacies/screens/product-details/product-detail.dart @@ -0,0 +1,413 @@ +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/product_detail_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/product-name-and-price.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/reviews_info.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/shared/custom-divider.dart'; +import 'package:diplomaticquarterapp/uitl/app_shared_preferences.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/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/text/app_texts_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +import 'availability_info.dart'; +import 'details_info.dart'; +import 'discount_description.dart'; +import 'footor/footer-widget.dart'; +import 'shared/product_details_app_bar.dart'; + +late String itemID; +late PharmacyProduct specificationData; + +class ProductDetailPage extends StatefulWidget { + final PharmacyProduct product; + + ProductDetailPage(this.product); + + @override + __ProductDetailPageState createState() => __ProductDetailPageState(); +} + +class __ProductDetailPageState extends State { + AppSharedPreferences sharedPref = AppSharedPreferences(); + + bool isTrue = true; + bool isDetails = true; + bool isReviews = false; + bool isAvailability = false; + String? customerId; + bool isSelected = true; + bool isOverQuantity = false; + bool isInWishList = false; + int quantity = 0; + + checkWishlist() async { + GifLoaderDialogUtils.showMyDialog(context); + ProductDetailViewModel model = new ProductDetailViewModel(); + await model.checkWishlistData(); + + for (int i = 0; i < model.wishListItems.length; i++) { + if (itemID == model.wishListItems[i].product.id) { + isInWishList = true; + break; + } else { + isInWishList = false; + } + } + GifLoaderDialogUtils.hideDialog(context); + setState(() {}); + } + + void initState() { + quantity = 1; + specificationData = widget.product; + + userInfo(); + super.initState(); + } + + @override + void dispose() { + super.dispose(); + } + + void userInfo() async { + print(specificationData); + customerId = await sharedPref.getString(PHARMACY_CUSTOMER_ID); + if (customerId != null) { + itemID = widget.product.id; + checkWishlist(); + } + setState(() {}); + } + + Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + return BaseView( + allowAny: true, + onModelReady: (model) async { + await model.getProductReviewsData(widget.product.id).then((value) {}); + }, + builder: (_, model, wi) => AppScaffold( + appBarTitle: TranslationBase.of(context).productDetails, + isShowAppBar: true, + isPharmacy: true, + isShowDecPage: false, + customAppBar: ProductAppBar( + product: widget.product, + quantity: quantity, + model: model, + addToWishlistFunction: () async { + await addToWishlistFunction(itemID: itemID, model: model); + }, + deleteFromWishlistFunction: () async { + await deleteFromWishlistFunction(itemID: itemID, model: model); + }, + isInWishList: isInWishList, + addToCartFunction: addToCartFunction, + ), + body: SingleChildScrollView( + child: Column( + children: [ + Container( + width: double.infinity, + color: Colors.white, + child: Column( + children: [ + if (widget.product.images!.isNotEmpty) + Stack( + children: [ + Container( + height: MediaQuery.of(context).size.height * .40, + child: Center( + child: Image.network( + widget.product.images![0].src!.trim(), + fit: BoxFit.contain, + ), + ), + ), + if (model.isStockAvailable && !model.isStockAvailable) + Container( + height: MediaQuery.of(context).size.height * .40, + color: Colors.white.withOpacity(0.6), + // child: AppText("Out of Stock"), + ), + if (model.isStockAvailable && !model.isStockAvailable) + Positioned( + // bottom: 10, + top: MediaQuery.of(context).size.height * .088, + left: MediaQuery.of(context).size.width * .32, + child: Center( + child: Container( + height: MediaQuery.of(context).size.height * .40, + // color: Colors.white.withOpacity(0.75), + child: RotationTransition( + turns: new AlwaysStoppedAnimation(310 / 360), + child: AppText( + TranslationBase.of(context).productOutOfStock, + color: Color(0xFF000000).withOpacity(0.19), + fontSize: projectViewModel.isArabic ? 40 : 50, + fontWeight: FontWeight.bold, + )), + ), + ), + ), + ], + ), + if (widget.product.discountDescription != null) DiscountDescription(product: widget.product) + ], + ), + ), + SizedBox( + height: 4, + ), + Container( + color: Colors.white, + child: ProductNameAndPrice( + context, + widget.product, + customerId: customerId, + addToWishlistFunction: (item) { + addToWishlistFunction(itemID: item, model: model); + setState(() {}); + }, + deleteFromWishlistFunction: (item) { + deleteFromWishlistFunction(itemID: item, model: model); + setState(() {}); + }, + notifyMeWhenAvailable: (context, itemId) { + notifyMeWhenAvailable(itemId: itemId, customerId: customerId, model: model); + }, + isInWishList: isInWishList, + isStockAvailable: model.isStockAvailable, + stockAvailability: projectViewModel.isArabic ? model.stockAvailabilityn : model.stockAvailability, + ), + ), + SizedBox( + height: 10, + ), +// Container( +// color: Colors.white, +// child: Column( +// mainAxisAlignment: MainAxisAlignment.start, +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// Container( +// padding: EdgeInsets.symmetric(vertical: 15, horizontal: 10), +// child: Texts( +// TranslationBase.of(context).specification, +// fontSize: 15, +// fontWeight: FontWeight.bold, +// ), +// width: double.infinity, +// ), +// // Divider(color: Colors.grey), +// ], +// ), +// ), +// SizedBox( +// height: 6, +// ), + Container( + // width: 500, + margin: EdgeInsets.only(bottom: 10), + padding: EdgeInsets.only(bottom: 10), + color: Colors.white, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Column( + children: [ + TextButton( + onPressed: () { + setState(() { + isDetails = true; + isReviews = false; + isAvailability = false; + }); + }, + child: Text( + TranslationBase.of(context).details, + style: TextStyle(fontWeight: FontWeight.w600, fontSize: 14, letterSpacing: -0.84), + ), + style: TextButton.styleFrom( + backgroundColor: Colors.white, + ), + ), + CustomDivider( + color: isDetails ? Colors.green : Colors.transparent, + ) + ], + ), + SizedBox( + width: 20, + ), + Column( + children: [ + TextButton( + onPressed: () async { + if (widget.product.approvedTotalReviews > 0) { + GifLoaderDialogUtils.showMyDialog(context); + await model.getProductReviewsData(widget.product.id); + GifLoaderDialogUtils.hideDialog(context); + } else { + model.clearReview(); + } + setState(() { + isDetails = false; + isReviews = true; + isAvailability = false; + }); + }, + child: Text( + TranslationBase.of(context).reviews, + style: TextStyle(fontWeight: FontWeight.w600, fontSize: 14, letterSpacing: -0.84), + ), + style: TextButton.styleFrom( + backgroundColor: Colors.white, + ), + ), + CustomDivider( + color: isReviews ? Colors.green : Colors.transparent, + ), + ], + ), + SizedBox( + width: 20, + ), + Column( + children: [ + TextButton( + onPressed: model.isStockAvailable != null && model.isStockAvailable + ? () async { + GifLoaderDialogUtils.showMyDialog(context); + await model.getProductLocationData(widget.product.sku); + GifLoaderDialogUtils.hideDialog(context); +// + setState(() { + isDetails = false; + isReviews = false; + isAvailability = true; + }); + } + : null, + child: Text( + TranslationBase.of(context).availability, + style: TextStyle(fontWeight: FontWeight.w600, fontSize: 14, letterSpacing: -0.84), + ), + style: TextButton.styleFrom( + backgroundColor: Colors.white, + ), ), + CustomDivider( + color: isAvailability ? Colors.green : Colors.transparent, + ), + ], + ), + ], + ), + SizedBox( + height: 10, + ), + isDetails + ? DetailsInfo( + product: widget.product, + ) + : isReviews + ? ReviewsInfo( + product: widget.product, + previousModel: model, + ) + : isAvailability + //&& widget.product.stockAvailability != "Out of stock" + ? AvailabilityInfo(previousModel: model) +// : isAvailability && widget.product.stockAvailability == "Out of stock" +// ? Container( +// // padding: EdgeInsets.all(15), +// padding: EdgeInsets.fromLTRB(15, 15, 15, 20), +// margin: EdgeInsets.only(bottom: 20), +// alignment: Alignment.center, +// child: Text( +// TranslationBase.of(context).noLocationAvailable, +// ), +// ) + : Container(), + ], + ), + ), + SizedBox( + height: 10, + ), +// if (projectViewModel.isLogin) +// RecommendedProducts( +// product: widget.product, +// productDetailViewModel: model, +// addToWishlistFunction: (itemID) async { +// await addToWishlistFunction(itemID: itemID, model: model); +// }, +// deleteFromWishlistFunction: (itemID) async { +// await deleteFromWishlistFunction(itemID: itemID, model: model); +// }, +// ) + ], + ), + ), + // : AppCircularProgressIndicator(), + bottomSheet: model.state == ViewState.Idle || model.state == ViewState.ErrorLocal + ? FooterWidget( + model.isStockAvailable, + widget.product.orderMaximumQuantity!, + widget.product.orderMinimumQuantity!, + model.stockQuantity!.toInt(), + widget.product, + quantity: quantity, + isOverQuantity: isOverQuantity, + addToCartFunction: addToCartFunction, + addToShoppingCartFunction: addToShoppingCartFunction, + model: model, + ) + : SizedBox(), + )); + } + + addToShoppingCartFunction({quantity, itemID, ProductDetailViewModel? model}) async { + GifLoaderDialogUtils.showMyDialog(context); + await model?.addToCartData(quantity, itemID, context); + GifLoaderDialogUtils.hideDialog(context); + if (model?.state != ViewState.ErrorLocal) Utils.navigateToCartPage(); + } + + addToWishlistFunction({itemID, ProductDetailViewModel? model}) async { + isInWishList = true; + await model?.addToWishlistData!(itemID, context); + setState(() {}); + } + + deleteFromWishlistFunction({itemID, ProductDetailViewModel? model}) async { + isInWishList = false; + await model?.deleteWishlistData!(itemID, context); + setState(() {}); + } + + addToCartFunction({ + quantity, + itemID, + ProductDetailViewModel? model, + }) async { + GifLoaderDialogUtils.showMyDialog(context); + await model?.addToCartData!(quantity, itemID, context); + GifLoaderDialogUtils.hideDialog(context); + } + + notifyMeWhenAvailable({itemId, customerId, ProductDetailViewModel? model}) async { + await model?.notifyMe!(customerId, itemId); + } +} diff --git a/lib/pages/pharmacies/screens/product-details/product-name-and-price.dart b/lib/pages/pharmacies/screens/product-details/product-name-and-price.dart new file mode 100644 index 00000000..6bea9208 --- /dev/null +++ b/lib/pages/pharmacies/screens/product-details/product-name-and-price.dart @@ -0,0 +1,371 @@ +import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; +import 'package:diplomaticquarterapp/core/service/AuthenticatedUserObject.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/borderedButton.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_rating_bar/flutter_rating_bar.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +import 'package:provider/provider.dart'; + +import '../../../../locator.dart'; +import 'shared/icon_with_bg.dart'; + +class ProductNameAndPrice extends StatefulWidget { + BuildContext context; + PharmacyProduct item; + final customerId; + final bool? isInWishList; + final Function? notifyMeWhenAvailable; + final Function? addToWishlistFunction; + final Function? deleteFromWishlistFunction; + final bool isStockAvailable; + final String? stockAvailability; + + AuthenticatedUserObject authenticatedUserObject = + locator(); + + ProductNameAndPrice(this.context, this.item, + {this.customerId, + this.isInWishList, + this.notifyMeWhenAvailable, + this.addToWishlistFunction, + this.deleteFromWishlistFunction, + this.isStockAvailable = true, + this.stockAvailability}); + + @override + _ProductNameAndPriceState createState() => _ProductNameAndPriceState(); +} + +class _ProductNameAndPriceState extends State { + @override + Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + + return Container( + color: Color(0xffF7F7F7), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + SizedBox( + height: 10, + ), + widget.item.rxMessage != null + ? Container( + // width: widget.item.rxMessage != null ? MediaQuery.of(context).size.width / 2.8 : 0, + width: double.infinity, + height: 40, + padding: EdgeInsets.all(4), + decoration: BoxDecoration( + color: Color(0xffD02127), + // color: Colors.red[700] + // borderRadius: BorderRadius.only(topLeft: Radius.circular(6)), + ), + child: Row( + children: [ + Padding( + padding: const EdgeInsets.only(left: 8, right: 8), + child: Icon( + Icons.warning, + color: Colors.white, + ), + ), + Text( + projectViewModel.isArabic + ? widget.item.rxMessagen.toString() + : widget.item.rxMessage.toString(), + style: TextStyle( + color: Colors.white, + // regular: true, + fontSize: 17, + fontWeight: FontWeight.w600, + letterSpacing:-0.68 + // textAlign: TextAlign.center, + )), + ], + )) + : Container(), + FractionallySizedBox( + widthFactor: 0.93, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ +// Texts(widget.item.price.toString() + " " + TranslationBase.of(context).sar, fontWeight: FontWeight.bold, fontSize: 20), + if (widget.stockAvailability != null) + Container( + margin: EdgeInsets.only(top: 10.0, right: 10.0), + padding: EdgeInsets.only( + left: 11.0, right: 11.0, top: 0, bottom: 0), + decoration: BoxDecoration( + border: Border.all( + color: getStatusBackgroundColor(), + style: BorderStyle.solid, + width: 5.0, + ), + color: getStatusBackgroundColor(), + borderRadius: BorderRadius.circular(30.0)), + // child: Text( + // widget.stockAvailability, + // style: TextStyle( + // fontWeight: FontWeight.w600, + // fontSize: 11, + // color: Color(0xffFFFFFF), + // ), + // color: getStatusBackgroundColor(), + // borderRadius: BorderRadius.circular(30.0)), + child: Text( + widget.stockAvailability!, + style: TextStyle(fontWeight: FontWeight.w600, fontSize: 11, color: Color(0xffFFFFFF),letterSpacing:-0.44)), + //color: widget.isStockAvailable ? Colors.white : Colors.red, + ), + // SizedBox(width: 20), + if ( + widget.authenticatedUserObject.isLogin) + widget.stockAvailability != null && + !widget.isStockAvailable && + widget.customerId != null + ? Container( + child: Row( + children: [ + IconButton( + iconSize: 25, + icon: Icon(Icons.notifications_active), + color: new Color(0xff2E303A), + onPressed: () { + widget!.notifyMeWhenAvailable!( + context, widget.item.id); + }, + ), + IconButton( + icon: Icon(!widget.isInWishList! + ? Icons.favorite_border + : Icons.favorite), + color: !widget.isInWishList! + ? Color(0xff2E303A) + : Color(0xffD02127), + onPressed: () async { + { + if (widget.customerId != null) { + if (!widget.isInWishList!) { + await widget + .addToWishlistFunction!(widget.item.id); + } else { + await widget.deleteFromWishlistFunction!( + widget.item.id); + } + } else { + return; + } + setState(() {}); + } + }, + ) + ], + ), + ) + : IconButton( + icon: Icon(!widget.isInWishList! + ? Icons.favorite_border + : Icons.favorite), + color: !widget.isInWishList! + ? Color(0xff2E303A) + : Color(0xffD02127), + onPressed: () async { + { + if (widget.customerId != null) { + if (!widget.isInWishList!) { + await widget + .addToWishlistFunction!(widget.item.id); + } else { + await widget.deleteFromWishlistFunction!( + widget.item.id); + } + } else { + return; + } + setState(() {}); + } + }, + ) +// BorderedButton( +// TranslationBase.of(context).notifyMe, +// hasBorder: true, +// borderColor: Colors.green, +// textColor: Colors.green, +// fontWeight: FontWeight.bold, +// vPadding: 6, +// hPadding: 14, +// handler: () => widget.notifyMeWhenAvailable(context, widget.item.id), +// ) +// InkWell( +// onTap: () => widget.notifyMeWhenAvailable(context, widget.item.id), +// child: Row(children: [ +// Texts( +// TranslationBase.of(context).notifyMe, +// decoration: TextDecoration.underline, +// color: Colors.blue, +// ), +// SizedBox(width: 4), +// Icon( +// FontAwesomeIcons.bell, +// color: Colors.blue, +// size: 15.0, +// ) +// ]), +// ) +// : IconWithBg( +// icon: !widget.isInWishList ? Icons.favorite_border : Icons.favorite, +// color: !widget.isInWishList ? Colors.white : Colors.red[800], +// onPress: () async { +// { +// if (widget.customerId != null) { +// if (!widget.isInWishList) { +// await widget.addToWishlistFunction(widget.item.id); +// } else { +// await widget.deleteFromWishlistFunction(widget.item.id); +// } +// } else { +// return; +// } +// setState(() {}); +// } +// }, +// ) + ], + ), + ), + Padding( + padding: + const EdgeInsets.only(left: 8, right: 8, top: 1, bottom: 12), + child: Container( + margin: EdgeInsets.only(left: 10, right: 10), + child: Align( + alignment: projectViewModel.isArabic + ? Alignment.topRight + : Alignment.topLeft, + child: Text( + projectViewModel.isArabic + ? widget.item.namen + : widget.item.name, + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 16, + letterSpacing: -0.96), + ), + ), + ), + ), + Padding( + padding: const EdgeInsets.only(left: 8, right: 8), + child: Container( + margin: EdgeInsets.only(left: 10, right: 10), + child: Align( + alignment: projectViewModel.isArabic + ? Alignment.topRight + : Alignment.topLeft, + child: Text( + TranslationBase.of(context).sar + + " " + + widget.item.price.toString(), + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 19, + letterSpacing: -0.76), + ), + ), + ), + ), + FractionallySizedBox( + widthFactor: 0.95, + child: Row( + children: [ + Container( + margin: EdgeInsets.only(left: 8, right: 8), + child: Align( + alignment: Alignment.bottomLeft, + child: Row( + children: [ + // RatingBar.readOnly( + // initialRating: double.parse( + // widget.item.approvedRatingSum.toString()), + // size: 18.0, + // filledColor: Color(0XFFD02127), + // emptyColor: Color(0XFFD02127), + // isHalfAllowed: true, + // halfFilledIcon: Icons.star_half, + // filledIcon: Icons.star, + // emptyIcon: Icons.star_border, + // ), + RatingBar( + initialRating: double.parse( + widget.item.approvedRatingSum.toString()), + direction: Axis.horizontal, + allowHalfRating: true, + itemCount: 5, + itemSize: 20, + ignoreGestures: true, + ratingWidget: RatingWidget( + full: Icon(Icons.star, color: CustomColors.accentColor,), + half: Icon(Icons.star_half, color: CustomColors.accentColor,), + empty: Icon(Icons.star, color: CustomColors.accentColor,), + ), + tapOnlyMode: true, + unratedColor: Colors.grey[500], + itemPadding: EdgeInsets.symmetric(horizontal: 4.0), + onRatingUpdate: (rating) { + print(rating); + }, + ), + SizedBox( + width: 5, + ), +// Texts( +// "${widget.item.approvedRatingSum}", +// fontWeight: FontWeight.bold, +// fontSize: 12, +// ), +// SizedBox( +// width: 30, +// ), + Text( + "(${widget.item.approvedTotalReviews}${TranslationBase.of(context).review})", + style: TextStyle( + fontWeight: FontWeight.w600, fontSize: 12), + ), + SizedBox( + width: 70, + ), +// if (widget.item.rxMessage != null) +// Row( +// children: [ +// Text( +// projectViewModel.isArabic ? widget.item.rxMessagen.toString() : widget.item.rxMessage.toString(), +// style: TextStyle(color: Colors.red, fontSize: 10), +// ), +// ], +// ) + ], + ), + ), + ), + ], + ), + ), + SizedBox( + height: 20, + ), + ], + ), + ); + } + + Color getStatusBackgroundColor() { + if (widget.isStockAvailable) + return Color(0xFF5AB145); + else + return Color(0xFFD02127); + } +} diff --git a/lib/pages/pharmacies/screens/product-details/recommended_products.dart b/lib/pages/pharmacies/screens/product-details/recommended_products.dart new file mode 100644 index 00000000..7f646971 --- /dev/null +++ b/lib/pages/pharmacies/screens/product-details/recommended_products.dart @@ -0,0 +1,371 @@ +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/recommendedProduct_model.dart'; +import 'package:diplomaticquarterapp/core/service/AuthenticatedUserObject.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/product_detail_view_model.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/pharmacies/screens/product-details/product-detail.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.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:flutter_rating_bar/flutter_rating_bar.dart'; +import 'package:provider/provider.dart'; + +class RecommendedProducts extends StatefulWidget { + final PharmacyProduct? product; + final String? customerId; + final ProductDetailViewModel? productDetailViewModel; + final bool isOverQuantity; + final bool isInWishList; + final VoidCallback? addToWishlistFunction; + final VoidCallback? deleteFromWishlistFunction; + + AuthenticatedUserObject authenticatedUserObject = + locator(); + + RecommendedProducts( + {Key? key, + this.product, + this.productDetailViewModel, + this.customerId, + this.isOverQuantity = false, + this.isInWishList = false, + this.addToWishlistFunction, + this.deleteFromWishlistFunction}) + : super(key: key); + + @override + _RecommendedProductsState createState() => _RecommendedProductsState(); +} + +class _RecommendedProductsState extends State { + @override + Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + return SingleChildScrollView( + child: Container( + width: 410, + color: Colors.white, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + margin: EdgeInsets.only(top: 9), + width: 410, + color: Colors.white, + child: Texts( + TranslationBase.of(context).recommended, + fontWeight: FontWeight.bold, fontSize: 16 + ), + ), + Container( + color: Colors.white, + height: 210, + margin: EdgeInsets.only(bottom: 75), + padding: EdgeInsets.only(bottom: 5), + // margin: EdgeInsets.symmetric(horizontal: 6, vertical: 4), + child: BaseView( + onModelReady: (model) => + model.getRecommendedProducts(widget.product!.id!), + builder: (_, model, wi) => NetworkBaseView( + isLocalLoader: true, + baseViewModel: model, + child: Container( + child: model.state== ViewState.BusyLocal?Container( + height: 80, + child: Center( + child: CircularProgressIndicator( + backgroundColor: Colors.white, + valueColor: AlwaysStoppedAnimation( + Colors.grey[500]!, + ), + ), + ), + ):model.recommendedProductList.length != null + ? ListView.builder( + scrollDirection: Axis.horizontal, + shrinkWrap: true, + physics: ScrollPhysics(), + // physics: NeverScrollableScrollPhysics(), + itemCount: model.recommendedProductList.length, + itemBuilder: (context, index) { + return InkWell( + onTap: () async { + GifLoaderDialogUtils.showMyDialog(context); + RecommendedProductModel data = + model.recommendedProductList[index]; + var json = data.toJson(); + PharmacyProduct product = + new PharmacyProduct.fromJson(json); + await Navigator.pushReplacement( + context, + FadePage( + page: ProductDetailPage(product), + ), + ); + GifLoaderDialogUtils.hideDialog(context); + }, + child: Card( + elevation: 2, + shape: RoundedRectangleBorder( + side: BorderSide( + color: Colors.grey[300]!, width: 2), + borderRadius: BorderRadius.circular(10), + ), + margin: EdgeInsets.symmetric( + horizontal: 8, + vertical: 0, + ), + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.all( + Radius.circular(15), + ), + ), + padding: EdgeInsets.symmetric(horizontal: 4), + width: MediaQuery.of(context).size.width / 3, + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Stack(children: [ + Container( + child: Align( + alignment: Alignment.topRight, + child: IconButton( + icon: Icon(model.recommendedProductList[index].isinwishlist != true + ? Icons.favorite_border : Icons.favorite), + color: model.recommendedProductList[index].isinwishlist != true + ? Colors.grey : Colors.red, + onPressed: () async { + if (widget.authenticatedUserObject.isLogin + ) { + if (!widget.isInWishList && model.recommendedProductList[index].isinwishlist != true) { + GifLoaderDialogUtils.showMyDialog(context); + widget.addToWishlistFunction!( + ); + GifLoaderDialogUtils.hideDialog(context); + setState(() { + model.recommendedProductList[index].isinwishlist = true;}); + } else { + GifLoaderDialogUtils.showMyDialog(context); + widget.deleteFromWishlistFunction!( + ); + GifLoaderDialogUtils.hideDialog(context); + setState(() { + model.recommendedProductList[index].isinwishlist = false; + }); + } + } else { + return; + } + setState(() { + // checkWishlist(); + }); + }, + ), + ), + ), + Container( + margin: EdgeInsets.fromLTRB( + 0, 16, 10, 16), + alignment: Alignment.center, + child: (model + .recommendedProductList[ + index] + .images != + null && + model + .recommendedProductList[ + index] + .images! + .length > + 0) + ? Image.network( + model + .recommendedProductList[ + index] + .images![0] + .src + .toString(), + fit: BoxFit.cover, + height: 60, + ) + : Image.asset( + "assets/images/no_image.png", + fit: BoxFit.cover, + height: 60, + ), + ), + Container( + width: model + .recommendedProductList[ + index] + .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: model + .recommendedProductList[ + index] + .rxMessage != + null + ? Texts( + projectViewModel.isArabic + ? model + .recommendedProductList[ + index] + .rxMessagen + : model + .recommendedProductList[ + index] + .rxMessage, + color: Colors.white, + regular: true, + fontSize: 10, + fontWeight: FontWeight.w400, + ) + : Texts(""), + ), + ]), + Container( + margin: EdgeInsets.symmetric( + horizontal: 6, + vertical: 0, + ), + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Text( + projectViewModel.isArabic + ? model + .recommendedProductList[ + index] + .namen + : model + .recommendedProductList[ + index] + .name, + style: TextStyle( + color: Colors.black, + fontSize: 13.0, +// fontWeight: FontWeight.bold, + ), + ), + Padding( +// padding: const EdgeInsets.only(top: 15, bottom: 10), + padding: const EdgeInsets.only( + top: 10, bottom: 5), + child: Texts( + "SAR ${model.recommendedProductList[index].price}", + bold: true, + fontSize: 14, + ), + ), + ], + ), + ), + Row( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Container( + padding: + EdgeInsets.only(right: 10), + child: Align( + alignment: Alignment.topLeft, + child: RatingBar( + initialRating:model + .recommendedProductList[ + index] + .approvedRatingSum + .toDouble(), + direction: Axis.horizontal, + allowHalfRating: true, + itemCount: 5, + itemSize: 20, + ignoreGestures: true, + ratingWidget: RatingWidget( + full: Icon(Icons.star, color: CustomColors.accentColor,), + half: Icon(Icons.star_half, color: CustomColors.accentColor,), + empty: Icon(Icons.star, color: CustomColors.accentColor,), + ), + tapOnlyMode: true, + unratedColor: Colors.grey[500], + itemPadding: EdgeInsets.symmetric(horizontal: 4.0), + onRatingUpdate: (rating) { + print(rating); + }, + ) + + // RatingBar.readOnly( + // initialRating: model + // .recommendedProductList[ + // index] + // .approvedRatingSum + // .toDouble(), + // size: 13.0, + // filledColor: + // Colors.yellow[700], + // emptyColor: Colors.grey[500], + // isHalfAllowed: true, + // halfFilledIcon: + // Icons.star_half, + // filledIcon: Icons.star, + // emptyIcon: Icons.star, + // ), + ), + ), + Texts( + "(${model.recommendedProductList[index].notApprovedTotalReviews.toString()})", +// bold: true, + fontSize: 12, + ), + ]), + ], + ), + ), + ), + ); + }) + : Container( + // color: Colors.white, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + // crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Texts( + TranslationBase.of(context).nonRecommended, + color: Colors.black, + ), + ], + ), + ), + ), + ), + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/pages/pharmacies/screens/product-details/reviews_info.dart b/lib/pages/pharmacies/screens/product-details/reviews_info.dart new file mode 100644 index 00000000..0fdac7a9 --- /dev/null +++ b/lib/pages/pharmacies/screens/product-details/reviews_info.dart @@ -0,0 +1,147 @@ +import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/product_detail_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_rating_bar/flutter_rating_bar.dart'; +import 'package:provider/provider.dart'; + +class ReviewsInfo extends StatelessWidget { + final PharmacyProduct? product; + final ProductDetailViewModel? previousModel; + + const ReviewsInfo({Key? key, this.product, this.previousModel}) + : super(key: key); + + @override + Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + return previousModel?.productDetailService.length != 0 && + previousModel?.productDetailService[0].reviews!.length != 0 + ? ListView.builder( + physics: ScrollPhysics(), + itemCount: previousModel?.productDetailService[0].reviews!.length, + scrollDirection: Axis.vertical, + shrinkWrap: true, + itemBuilder: (BuildContext context, int index) { + return Padding( + padding: EdgeInsets.all(8.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + child: Row( + children: [ + Expanded( + child: Container( + child: Text(previousModel!.productDetailService[0].reviews![index].customer!.firstName != null + && previousModel!.productDetailService[0].reviews![index].customer!.firstName != null + ? previousModel!.productDetailService[0].reviews![index].customer!.firstName.toString() + " " + + previousModel!.productDetailService[0].reviews![index].customer!.lastName.toString() + :"", +// previousModel.productDetailService[0] +// .reviews[index].customerId +// .toString(), + style: TextStyle( + fontSize: 14, + color: Colors.black, + fontWeight: FontWeight.w600), + ), + ), + ), + Container( + // margin: EdgeInsets.only(left: 210), + child: projectViewModel.isArabic? + Align( + alignment: Alignment.topLeft, + child: + + // RatingBar.readOnly( + // initialRating: previousModel + // .productDetailService[0].reviews[index].rating + // .toDouble(), + // size: 15.0, + // filledColor: Colors.yellow[700], + // emptyColor: Colors.grey[500], + // isHalfAllowed: true, + // halfFilledIcon: Icons.star_half, + // filledIcon: Icons.star, + // emptyIcon: Icons.star, + // ), + RatingBar( + initialRating: previousModel! + .productDetailService[0].reviews![index].rating!.toDouble(), + direction: Axis.horizontal, + allowHalfRating: true, + itemCount: 5, + itemSize: 20, + ignoreGestures: true, + ratingWidget: RatingWidget( + full: Icon(Icons.star, color: CustomColors.accentColor,), + half: Icon(Icons.star_half, color: CustomColors.accentColor,), + empty: Icon(Icons.star, color: CustomColors.accentColor,), + ), + tapOnlyMode: true, + unratedColor: Colors.grey[500], + itemPadding: EdgeInsets.symmetric(horizontal: 4.0), + onRatingUpdate: (rating) { + print(rating); + }, + ) + + ): RatingBar( + initialRating: previousModel! + .productDetailService[0].reviews![index].rating!.toDouble(), + direction: Axis.horizontal, + allowHalfRating: true, + itemCount: 5, + itemSize: 20, + ignoreGestures: true, + ratingWidget: RatingWidget( + full: Icon(Icons.star, color: CustomColors.accentColor,), + half: Icon(Icons.star_half, color: CustomColors.accentColor,), + empty: Icon(Icons.star, color: CustomColors.accentColor,), + ), + tapOnlyMode: true, + unratedColor: Colors.grey[500], + itemPadding: EdgeInsets.symmetric(horizontal: 4.0), + onRatingUpdate: (rating) { + print(rating); + }, + ))]) + , + ), + + + + Padding( + padding: const EdgeInsets.all(8.0), + child: Container( + child: Text( + previousModel! + .productDetailService[0].reviews![index].replyText, + style: TextStyle(fontSize: 20), + ), + ), + ), + SizedBox( + height: 50, + ), + Divider(height: 1, color: Colors.grey), + + ])); + }, + ) + : Container( + padding: EdgeInsets.fromLTRB(15,15,15,20), + margin: EdgeInsets.only(bottom: 40), + alignment: Alignment.center, + child: Text( + TranslationBase.of(context).noReviewsAvailable, + ), +// Text('No Reviews Available'), + ); + } +} diff --git a/lib/pages/pharmacies/screens/product-details/shared/custom-divider.dart b/lib/pages/pharmacies/screens/product-details/shared/custom-divider.dart new file mode 100644 index 00000000..3bb6a047 --- /dev/null +++ b/lib/pages/pharmacies/screens/product-details/shared/custom-divider.dart @@ -0,0 +1,19 @@ +import 'package:flutter/material.dart'; + +class CustomDivider extends StatelessWidget { + const CustomDivider({ + Key? key, + this.color, + }) : super(key: key); + + final Color? color; + + @override + Widget build(BuildContext context) { + return Container( + width: 120, + height: 2, + color: color, + ); + } +} \ No newline at end of file diff --git a/lib/pages/pharmacies/screens/product-details/shared/icon_with_bg.dart b/lib/pages/pharmacies/screens/product-details/shared/icon_with_bg.dart new file mode 100644 index 00000000..de97f3fb --- /dev/null +++ b/lib/pages/pharmacies/screens/product-details/shared/icon_with_bg.dart @@ -0,0 +1,44 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class IconWithBg extends StatelessWidget { + final IconData? icon; + final Color? color; + final VoidCallback? onPress; + final bool hasPadding; + + IconWithBg( + {Key? key, this.icon, this.color, this.onPress, this.hasPadding = false}) + : super(key: key); + + @override + Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + return Container( + width: 40, + height: 40, + decoration: BoxDecoration( + color: Colors.grey[200], + borderRadius: BorderRadius.circular(30), + ), + child: Center( + child: Padding( + padding: EdgeInsets.only( + left: !projectViewModel.isArabic ? (hasPadding ? 4 : 0) : 0, + right: projectViewModel.isArabic ? (hasPadding ? 4 : 0) : 0 + ), + child: IconButton( + icon: Icon( + icon, + size: 20, + ), + color: color, + onPressed: () async { + onPress!(); + }, + ), + ), + )); + } +} 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 new file mode 100644 index 00000000..afb2cd3a --- /dev/null +++ b/lib/pages/pharmacies/screens/product-details/shared/product_details_app_bar.dart @@ -0,0 +1,210 @@ +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/landing/landing_page_pharmcy.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/product-detail.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/navigation_service.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +import 'package:provider/provider.dart'; + +import '../../../../../locator.dart'; +import '../../../compare-list.dart'; +import 'icon_with_bg.dart'; + +class ProductAppBar extends StatelessWidget implements PreferredSizeWidget { + final PharmacyProduct? product; + + final ProductDetailViewModel? model; + final VoidCallback? addToWishlistFunction; + final VoidCallback? deleteFromWishlistFunction; + final int? quantity; + 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); + + AuthenticatedUserObject authenticatedUserObject = + locator(); + + @override + Widget build(BuildContext context) { + OrderPreviewViewModel orderPreviewViewModel = Provider.of(context); + return Container( + color: Colors.white, + child: FractionallySizedBox( + widthFactor: 0.95, + child: Column( + children: [ + SizedBox( + height: 30, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + IconWithBg( + icon: Icons.arrow_back_ios, + hasPadding: true, + color: Color(0xFF2B353E), + onPress: () { + Navigator.pop(context); + }, + ), + ], + ), + if (authenticatedUserObject.isLogin) + Row( + children: [ + Stack( + children: [ + IconWithBg( + icon: Icons.shopping_cart, + color: Color(0xFF2B353E), + onPress: () { + Navigator.pushAndRemoveUntil( + locator() + .navigatorKey + .currentContext!, + MaterialPageRoute( + builder: (context) => + LandingPagePharmacy(currentTab: 3)), + (Route r) => false); + // Navigator.push( + // context, + // 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), + ), + 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( + width: 10, + ), + IconWithBg( + icon: FontAwesomeIcons.ellipsisV, + color: Color(0xFF2B353E), + onPress: () { + settingModalBottomSheet(context); + }, + ), + ], + ) + ], + ), + ], + ), + ), + ); + } + + @override + Size get preferredSize => Size(double.maxFinite, 50); + + settingModalBottomSheet(context) { + showModalBottomSheet( + context: context, + builder: (BuildContext bc) { + return Container( + child: new Wrap( + children: [ + if (product!.stockAvailability! != 'Out of stock' && product!.isRx! != true) + new ListTile( + leading: Icon(Icons.shopping_cart), + title: Text( + TranslationBase.of(context).addToCart, + ), + onTap: () async { + if (quantity! > 0) { + { + addToCartFunction!( + quantity: quantity!, + itemID: itemID!, + model: model!); + + Navigator.of(context).pop(); + } + } else { + AppToast.showErrorToast( + message: TranslationBase.of(context).addQuantity + // "you should add quantity" + ); + } + }), + ListTile( + leading: Icon( + !isInWishList! ? Icons.favorite_border : Icons.favorite, + color: !isInWishList! ? Colors.white : Colors.red[800], + ), + title: Text( + isInWishList! + ? TranslationBase.of(context).removeFromWishlist + : TranslationBase.of(context).addToWishlist, + ), + onTap: () async { + if (isInWishList!) + deleteFromWishlistFunction!(); + else + addToWishlistFunction!(); + Navigator.of(context).pop(); + }), + ListTile( + leading: Icon(Icons.compare), + title: Text( + TranslationBase.of(context).compare, + ), + onTap: () { + Provider.of(context, listen: false) + .addItem(specificationData, context); + Navigator.of(context).pop(); + }, + ), + ], + ), + ); + }); + } +} diff --git a/lib/pages/pharmacies/screens/recommended-product-page.dart b/lib/pages/pharmacies/screens/recommended-product-page.dart index 28e3cce3..d8b488c2 100644 --- a/lib/pages/pharmacies/screens/recommended-product-page.dart +++ b/lib/pages/pharmacies/screens/recommended-product-page.dart @@ -1,14 +1,8 @@ +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/recommendedProduct_model.dart'; -import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/product_detail_view_model.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:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; -import 'package:rating_bar/rating_bar.dart'; -import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; dynamic languageID; bool isInWishlist = false; @@ -18,17 +12,17 @@ var product; var customerId; class RecommendedProductPage extends StatefulWidget { - String productId ; + String? productId ; RecommendedProductPage({this.productId}); @override - _RecommendedProductPageState createState() => _RecommendedProductPageState(productId: productId); + _RecommendedProductPageState createState() => _RecommendedProductPageState(productId: productId!); } class _RecommendedProductPageState extends State with SingleTickerProviderStateMixin { List recommendedProductList = []; - String productId; + late String? productId; _RecommendedProductPageState({this.productId}); String id = ""; bool styleOne = true; @@ -59,896 +53,451 @@ class _RecommendedProductPageState extends State var size = MediaQuery.of(context).size; final double itemHeight = ((size.height - kToolbarHeight - 24) * 0.80) / 2; final double itemWidth = size.width / 2; - return BaseView( - onModelReady: (model) => model.getRecommendedProducts(productId), - builder: (_, model, wi) => AppScaffold( - appBarTitle: TranslationBase.of(context).recommended, - baseViewModel: model, - isShowAppBar: true, - isPharmacy: true, - backgroundColor: Colors.white, - body: SingleChildScrollView( - child: Column(children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Container( - padding: EdgeInsets.only( - top: 8, - bottom: 10, - left: 10, - ), - child: Text( - model.recommendedProductList.length.toString(), - style: TextStyle( - color: Colors.black, - fontSize: 14.0, - ), - ), - ), - Container( - padding: EdgeInsets.only(top: 8, bottom: 10, left: 8), - child: Text( - TranslationBase.of(context).result, - style: TextStyle( - color: Colors.black, - fontSize: 14.0, - ), - ), - ), - ], - ), - Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - Padding( - padding: const EdgeInsets.symmetric(vertical: 8), - child: SizedBox( - child: Container( - width: 1, - color: Colors.grey, - ), - ), - ), - Container( - child: Image.asset( - 'assets/images/pharmacy/sort.png', - width: 20, - height: 20, -// color: Colors.red, - ), - ), - Container( - child: Text( - TranslationBase.of(context).sort, - style: TextStyle( - color: Colors.black, - fontSize: 14.0, - ), - ), - ), - Padding( - padding: const EdgeInsets.symmetric(vertical: 8), - child: SizedBox( - child: Container( - width: 1, - color: Colors.grey, - ), - ), - ), - Divider( - thickness: 1.0, - color: Colors.black12, - ), - Padding( - padding: EdgeInsets.all(8.0), - child: InkWell( - child: styleIcon, - onTap: () { - setState(() { - if (styleOne == true) { - styleOne = false; - styleTwo = true; - styleIcon = Icon( - Icons.auto_awesome_mosaic, - color: Colors.blue, - size: 29.0, - ); - } else { - styleOne = true; - styleTwo = false; - styleIcon = Icon( - Icons.widgets_sharp, - color: Colors.blue, - size: 29.0, - ); - } - }); - }, - ), - ), - ], - ), - ]), - SizedBox( - height: 2, - ), - Divider( - color: Colors.grey[350], - height: 10, - thickness: 6, - indent: 0, - endIndent: 0, - ), - styleOne == true - ? Container( - margin: EdgeInsets.all(5.0), - child: model.recommendedProductList.length != null - ? CustomScrollView( - primary: false, - shrinkWrap: true, - physics: NeverScrollableScrollPhysics(), - slivers: [ - SliverPadding( - padding: const EdgeInsets.fromLTRB(0, 0, 0, 0), - sliver: SliverGrid.count( - crossAxisCount: 2, - childAspectRatio: (itemWidth / itemHeight), - children: model.recommendedProductList - .map((e) => Card( - elevation: 2, - shape: RoundedRectangleBorder( - side: BorderSide( - color: Colors.grey[300], - width: 2), - borderRadius: - BorderRadius.circular( - 10)), - margin: EdgeInsets.symmetric( - horizontal: 8, - vertical: 11, - ), - child: Container( - decoration: BoxDecoration( - borderRadius: - BorderRadius.all( - Radius.circular(15), - ), - ), - padding: EdgeInsets.symmetric( - horizontal: 4), - width: MediaQuery.of(context) - .size.width / 3, -// - child: Column( - crossAxisAlignment: - CrossAxisAlignment - .start, - children: [ - Stack(children: [ - Container( - child: Align( - alignment: - Alignment - .topRight, - child: - itemID.contains(e.id) - // !isInWishlist - ? IconButton( - icon: - Icon(Icons.favorite_border), - color: - Colors.grey, - iconSize: - 30, - onPressed: - () { - setState(() { - addToWishlistFunction(itemID); - }); - }, - ) - : - IconButton( - icon: - Icon(Icons.favorite), - color: - Colors.red, - iconSize: - 30, - onPressed: - () { - setState(() { - deleteFromWishlistFunction(itemID); - }); - }, - ) -// - ), - ), - Container( - margin: EdgeInsets - .fromLTRB(0, 16, - 10, 16), - alignment: - Alignment.center, -// padding: EdgeInsets.only(left: 25, bottom: 20), - child: (e.images != - null && - e.images.length > - 0) - ? Image.network( - e.images[0] - .src - .toString(), -// item.images[0].src, - fit: BoxFit - .cover, - height: 60, - ) - : Image.asset( - "assets/images/no_image.png", - fit: BoxFit - .cover, - height: 60, - ), - ), - Container( - width: e.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: Texts( - e.rxMessage != null - ? e.rxMessage - : "", - color: Colors.white, - regular: true, - fontSize: 10, - fontWeight: - FontWeight.w400, - ), - ), - ]), - Container( - margin: EdgeInsets - .symmetric( - horizontal: 6, - vertical: 0, - ), - child: Column( - crossAxisAlignment: - CrossAxisAlignment - .start, - children: [ - Text( - languageID == "ar" - ? e.namen - : e.name, - style: TextStyle( - color: Colors - .black, - fontSize: 13.0, -// fontWeight: FontWeight.bold, - ), - ), - Padding( -// padding: const EdgeInsets.only(top: 15, bottom: 10), - padding: - const EdgeInsets - .only( - top: 10, - bottom: - 5), - child: Texts( - "SAR ${e.price}", - bold: true, - fontSize: 14, - ), - ), - ], - ), - ), - Row( - crossAxisAlignment: - CrossAxisAlignment - .start, - children: [ - Container( - padding: EdgeInsets - .only( - right: - 10), -// margin: EdgeInsets.only(left: 5), - child: Align( - alignment: - Alignment - .topLeft, - child: RatingBar - .readOnly( - initialRating: e - .approvedRatingSum - .toDouble(), -// initialRating: productRate, - size: 13.0, - filledColor: - Colors.yellow[ - 700], - emptyColor: - Colors.grey[ - 500], - isHalfAllowed: - true, - halfFilledIcon: - Icons - .star_half, - filledIcon: - Icons - .star, - emptyIcon: - Icons - .star, - ), - ), - ), - Texts( - "(${e.approvedTotalReviews.toString()})", -// bold: true, - fontSize: 12, - ), - ]), - ], - ), - ), - ) -// Column( -// crossAxisAlignment: -// CrossAxisAlignment.start, -// children: [ -// Container( -// child: Align( -// alignment: Alignment.topRight, -// child: !isInWishlist -// ? IconButton( -// icon: Icon(Icons.favorite_border), -// color: Colors.grey, -// iconSize: 30, -// onPressed: () { -// setState(() { -// addToWishlistFunction(itemID); -// }); -// }, -// ) -// : IconButton( -// icon: Icon(Icons.favorite), -// color: Colors.red, -// iconSize: 30, -// onPressed: () { -// setState(() { -// deleteFromWishlistFunction(itemID); -// }); -// }, -// ) -//// -// ),), -// Container( -// padding: EdgeInsets.only( -// left: 25, bottom: 20), -//// margin: EdgeInsets.fromLTRB(0, 16, 0, 0), -//// alignment: Alignment.centerLeft, -// child: (e.images != null && -// e.images.length > 0) -// ? Image.network( -// e.images[0].src -// .toString(), -//// item.images[0].src, -// fit: BoxFit.cover, -// height: 80, -// ) -// : Image.asset( -// "assets/images/no_image.png", -// fit: BoxFit.cover, -// height: 80, -// ), -// ), -// Text( -// e.name, -//// model.recommendedProduct[0].products[index].shortDescription -//// .toString(), -// style: TextStyle( -// color: Colors.black, -// fontSize: 15.0, -//// fontWeight: FontWeight.bold, -// ), -// ), -// Padding( -// padding: const EdgeInsets.only( -// top: 15, bottom: 10), -// child: Texts( -// "SAR ${e.price}", -// bold: true, -// fontSize: 14, -// ), -// ), -// Row( -// crossAxisAlignment: -// CrossAxisAlignment.start, -// children: [ -// Container( -// padding: EdgeInsets.only( -// right: 10), -//// margin: EdgeInsets.only(left: 5), -// child: Align( -// alignment: -// Alignment.topLeft, -// child: RatingBar.readOnly( -// initialRating: e -// .approvedRatingSum -// .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, -// ), -// ), -// ), -// Texts( -// "(${e.approvedTotalReviews.toString()})", -//// bold: true, -// fontSize: 12, -// ), -// ]), -// ], -// ), - ) - .toList(), -// children:[ -// ListView.builder( -// scrollDirection: Axis.vertical, -// shrinkWrap: true, -// physics: ScrollPhysics(), -// itemCount: model.recommendedProductList.length, -// itemBuilder: (context, index) { -// return Container( -// height: 30, -// padding: EdgeInsets.only( left: 15.0, top: 10, right: 10), -// margin: EdgeInsets.only(right: 10.0), -// decoration: BoxDecoration( -// border: Border.all( -// color: Colors.grey, -// style: BorderStyle.solid, -// width: 1.0, -// ), -// color: Colors.white, -// borderRadius: BorderRadius.circular(10.0)), -// child: Column( -// crossAxisAlignment: CrossAxisAlignment.start, -// children: [ -// Container( -// child: Align( -// alignment: Alignment.topRight, -// child:!isInWishlist -// ? InkWell( -// onTap: () { -// }, -// child: SvgPicture.asset( -// 'assets/images/pharmacy/heart-empty.svg', -// width: 20, -// height: 20, -// color: Colors.grey, -// ), -// ) -// : InkWell( -// onTap: () { -// }, -// child: SvgPicture.asset( -// 'assets/images/pharmacy/Redheart.svg', -// width: 20, -// height: 20, + return Container(); +// BaseView( +// onModelReady: (model) => model.getRecommendedProducts(productId), +// builder: (_, model, wi) => AppScaffold( +// appBarTitle: TranslationBase.of(context).recommended, +// baseViewModel: model, +// isShowAppBar: true, +// isPharmacy: true, +// backgroundColor: Colors.white, +// body: SingleChildScrollView( +// child: Column(children: [ +// Row( +// mainAxisAlignment: MainAxisAlignment.spaceBetween, +// children: [ +// Row( +// mainAxisAlignment: MainAxisAlignment.start, +// children: [ +// Container( +// padding: EdgeInsets.only( +// top: 8, +// bottom: 10, +// left: 10, +// ), +// child: Text( +// model.recommendedProductList.length.toString(), +// style: TextStyle( +// color: Colors.black, +// fontSize: 14.0, +// ), +// ), +// ), +// Container( +// padding: EdgeInsets.only(top: 8, bottom: 10, left: 8), +// child: Text( +// TranslationBase.of(context).result, +// style: TextStyle( +// color: Colors.black, +// fontSize: 14.0, +// ), +// ), +// ), +// ], +// ), +// Row( +// mainAxisAlignment: MainAxisAlignment.end, +// children: [ +// Padding( +// padding: const EdgeInsets.symmetric(vertical: 8), +// child: SizedBox( +// child: Container( +// width: 1, +// color: Colors.grey, +// ), +// ), +// ), +// Container( +// child: Image.asset( +// 'assets/images/pharmacy/sort.png', +// width: 20, +// height: 20, //// color: Colors.red, +// ), +// ), +// Container( +// child: Text( +// TranslationBase.of(context).sort, +// style: TextStyle( +// color: Colors.black, +// fontSize: 14.0, +// ), +// ), +// ), +// Padding( +// padding: const EdgeInsets.symmetric(vertical: 8), +// child: SizedBox( +// child: Container( +// width: 1, +// color: Colors.grey, +// ), +// ), +// ), +// Divider( +// thickness: 1.0, +// color: Colors.black12, +// ), +// Padding( +// padding: EdgeInsets.all(8.0), +// child: InkWell( +// child: styleIcon, +// onTap: () { +// setState(() { +// if (styleOne == true) { +// styleOne = false; +// styleTwo = true; +// styleIcon = Icon( +// Icons.auto_awesome_mosaic, +// color: Colors.blue, +// size: 29.0, +// ); +// } else { +// styleOne = true; +// styleTwo = false; +// styleIcon = Icon( +// Icons.widgets_sharp, +// color: Colors.blue, +// size: 29.0, +// ); +// } +// }); +// }, +// ), +// ), +// ], +// ), +// ]), +// SizedBox( +// height: 2, +// ), +// Divider( +// color: Colors.grey[350], +// height: 10, +// thickness: 6, +// indent: 0, +// endIndent: 0, +// ), +// styleOne == true +// ? Container( +// margin: EdgeInsets.all(5.0), +// child: model.recommendedProductList.length != null +// ? CustomScrollView( +// primary: false, +// shrinkWrap: true, +// physics: NeverScrollableScrollPhysics(), +// slivers: [ +// SliverPadding( +// padding: const EdgeInsets.fromLTRB(0, 0, 0, 0), +// sliver: SliverGrid.count( +// crossAxisCount: 2, +// childAspectRatio: (itemWidth / itemHeight), +// children: model.recommendedProductList +// .map((e) => Card( +// elevation: 2, +// shape: RoundedRectangleBorder( +// side: BorderSide( +// color: Colors.grey[300], +// width: 2), +// borderRadius: +// BorderRadius.circular( +// 10)), +// margin: EdgeInsets.symmetric( +// horizontal: 8, +// vertical: 11, +// ), +// child: Container( +// decoration: BoxDecoration( +// borderRadius: +// BorderRadius.all( +// Radius.circular(15), +// ), // ), -// ) -// ), -// ), -// Container( -// padding: EdgeInsets.only(left: 25, bottom: 20), -//// margin: EdgeInsets.fromLTRB(0, 16, 0, 0), -//// alignment: Alignment.centerLeft, -// child: (model.recommendedProductList[index].images != null && -// model.recommendedProductList[index].images.length > 0) -// ? Image.network( -// model.recommendedProductList[index].images[0].src.toString(), +// padding: EdgeInsets.symmetric( +// horizontal: 4), +// width: MediaQuery.of(context) +// .size.width / 3, +//// +// child: Column( +// crossAxisAlignment: +// CrossAxisAlignment +// .start, +// children: [ +// Stack(children: [ +// Container( +// child: Align( +// alignment: Alignment.topRight, +// child: itemID.contains(e.id) +// // !isInWishlist +// ? IconButton(icon: Icon(Icons.favorite_border), +// color: Colors.grey, iconSize: 30, +// onPressed: +// () { +// setState(() {addToWishlistFunction(itemID); +// }); +// }, +// ) +// : IconButton(icon: Icon(Icons.favorite), +// color: Colors.red, iconSize: 30, +// onPressed: +// () {setState(() { +// deleteFromWishlistFunction(itemID); +// }); +// }, +// ) +//// +// ), +// ), +// Container(margin: EdgeInsets.fromLTRB(0, 16, 10, 16), +// alignment: Alignment.center, +//// padding: EdgeInsets.only(left: 25, bottom: 20), +// child: (e.images != null && e.images.length > 0) +// ? Image.network(e.images[0].src.toString(), //// item.images[0].src, -// fit: BoxFit.cover, -// height: 80, -// ) -// : Image.asset( -// "assets/images/no_image.png", -// fit: BoxFit.cover, -// height: 80, -// ), -// ), -// Text( -// model.recommendedProductList[index].name, -//// model.recommendedProduct[0].products[index].shortDescription -//// .toString(), -// style: TextStyle( -// color: Colors.black, -// fontSize: 15.0, +// fit: BoxFit.cover, height: 60,) +// : Image.asset("assets/images/no_image.png", fit: BoxFit.cover, height: 60, +// ), +// ), +// Container(width: e.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: Texts(e.rxMessage != null ? e.rxMessage : "", +// color: Colors.white, +// regular: true, +// fontSize: 10, +// fontWeight: FontWeight.w400, +// ), +// ), +// ]), +// Container( +// margin: EdgeInsets +// .symmetric(horizontal: 6, vertical: 0, +// ), +// child: Column( +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// Text( +// languageID == "ar" ? e.namen : e.name, +// style: TextStyle( +// color: Colors.black, fontSize: 13.0, //// fontWeight: FontWeight.bold, -// ), -// ), -// Padding( -// padding: const EdgeInsets.only(top: 15, bottom: 10), -// child: Texts( -// "SAR ${model.recommendedProductList[index].price}", -// bold: true, -// fontSize: 14, -// ), -// ), -// Row( -// crossAxisAlignment: -// CrossAxisAlignment.start, -// children: [ -// Container( -// padding: EdgeInsets.only(right: 10), +// ), +// ), +// Padding( +//// padding: const EdgeInsets.only(top: 15, bottom: 10), +// padding: const EdgeInsets.only(top: 10, bottom: 5), +// child: Texts("SAR ${e.price}", +// bold: true, fontSize: 14, +// ), +// ), +// ], +// ), +// ), +// Row( +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// Container( +// padding: EdgeInsets.only(right: 10), //// margin: EdgeInsets.only(left: 5), -// child: Align( -// alignment: Alignment.topLeft, -// child: RatingBar.readOnly( -// initialRating: -// model.recommendedProductList[index].approvedRatingSum.toDouble(), +// child: Align(alignment: Alignment.topLeft, +// child: RatingBar.readOnly(initialRating: e.approvedRatingSum.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, -// ), -// ), -// ), -// Texts( -// "(${model.recommendedProductList[index].approvedTotalReviews.toString()})", +// size: 13.0, filledColor: Colors.yellow[700], +// emptyColor: Colors.grey[500], +// isHalfAllowed: true, +// halfFilledIcon: Icons.star_half, +// filledIcon: Icons.star, +// emptyIcon: Icons.star, +// ), +// ), +// ), +// Texts("(${e.approvedTotalReviews.toString()})", //// bold: true, -// fontSize: 12, +// fontSize: 12, +// ), +// ]), +// ], +// ), // ), -// ]), -// ], -// ), -// ); -// } -// ), -// ] - ), - ), - ]) - : Container(), - ) - : Container( - height: model.recommendedProductList.length > 0 - ? MediaQuery.of(context).size.height * 0.60 - : 0, - child: ListView.builder( - physics: ScrollPhysics(), -// physics: NeverScrollableScrollPhysics(), - itemCount: model.recommendedProductList.length, - itemBuilder: (context, index) { - return Card( - elevation: 2, - shape: RoundedRectangleBorder( - side: - BorderSide(color: Colors.grey[300], width: 2), - borderRadius: BorderRadius.circular(10)), -// - margin: EdgeInsets.symmetric( - horizontal: 8, - vertical: 4, - ), - child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.all( - Radius.circular(15), - ), - ), - padding: EdgeInsets.symmetric(horizontal: 5), - width: MediaQuery.of(context).size.width / 3, +// ) // - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Stack(children: [ - Container( - child: Align( - alignment: Alignment.topRight, - child: //true - //wishlistVar[index].id.contains(model.recommendedProductList[index].id) - !isInWishlist - ? IconButton( - icon: Icon( - Icons.favorite_border), - color: Colors.grey, - iconSize: 30, - onPressed: () { - setState(() { - addToWishlistFunction( - itemID); - }); - }, - ) - : IconButton( - icon: Icon(Icons.favorite), - color: Colors.red, - iconSize: 30, - onPressed: () { - setState(() { - deleteFromWishlistFunction( - itemID); - }); - }, - ) +// ) +// .toList(), // - ), - ), - Container( - margin: EdgeInsets.fromLTRB(0, 16, 10, 16), - alignment: Alignment.center, -// padding: EdgeInsets.only(left: 25, bottom: 20), - child: (model.recommendedProductList[index] - .images != - null && - model.recommendedProductList[index] - .images.length > - 0) - ? Image.network( - model.recommendedProductList[index] - .images[0].src - .toString(), -// item.images[0].src, - fit: BoxFit.cover, - height: 60, - ) - : Image.asset( - "assets/images/no_image.png", - fit: BoxFit.cover, - height: 60, - ), - ), - Container( - width: model.recommendedProductList[index] - .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: Texts( - model.recommendedProductList[index] - .rxMessage != - null - ? model.recommendedProductList[index] - .rxMessage - : "", - color: Colors.white, - regular: true, - fontSize: 10, - fontWeight: FontWeight.w400, - ), - ), - ]), - Container( - margin: EdgeInsets.symmetric( - horizontal: 6, - vertical: 2, - ), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Text( - model - .recommendedProductList[index].name, - style: TextStyle( - color: Colors.black, - fontSize: 13.0, -// fontWeight: FontWeight.bold, - ), - ), - Padding( -// padding: const EdgeInsets.only(top: 15, bottom: 10), - padding: const EdgeInsets.only( - top: 10, bottom: 5), - child: Texts( - "SAR ${model.recommendedProductList[index].price}", - bold: true, - fontSize: 14, - ), - ), - ], - ), - ), - Row( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Container( - padding: EdgeInsets.only( - right: 10, bottom: 10), -// margin: EdgeInsets.only(left: 5), - child: Align( - alignment: Alignment.topLeft, - child: RatingBar.readOnly( - initialRating: model - .recommendedProductList[index] - .approvedRatingSum - .toDouble(), -// initialRating: productRate, - size: 13.0, - filledColor: Colors.yellow[700], - emptyColor: Colors.grey[500], - isHalfAllowed: true, - halfFilledIcon: Icons.star_half, - filledIcon: Icons.star, - emptyIcon: Icons.star, - ), - ), - ), - Texts( - "(${model.recommendedProductList[index].approvedTotalReviews.toString()})", -// bold: true, - fontSize: 12, - ), - ]), - ], - ), - ), - ); -// Container( -// height: 30, -// padding: EdgeInsets.only( left: 10.0, top: 10, right: 10), -//// margin: EdgeInsets.only(right: 10.0), -// decoration: BoxDecoration( -// border: Border.all( -// color: Colors.grey, -// style: BorderStyle.solid, -// width: 1.0, -// ), -// color: Colors.white, -// borderRadius: BorderRadius.circular(10.0)), -// child: Column( -// crossAxisAlignment: CrossAxisAlignment.start, -// children: [ -// Container( -// child: Align( -// alignment: Alignment.topRight, -// child:!isInWishlist -// ? InkWell( -// onTap: () { -// }, -// child: SvgPicture.asset( -// 'assets/images/pharmacy/heart-empty.svg', -// width: 20, -// height: 20, -// color: Colors.grey, -// ), -// ) -// : InkWell( -// onTap: () { -// }, -// child: SvgPicture.asset( -// 'assets/images/pharmacy/Redheart.svg', -// width: 20, -// height: 20, -//// color: Colors.red, -// ), -// ) +// ), // ), -// ), -// Container( -// padding: EdgeInsets.only(left: 25, bottom: 20), -//// margin: EdgeInsets.fromLTRB(0, 16, 0, 0), -//// alignment: Alignment.centerLeft, -// child: (model.recommendedProductList[index].images != null && -// model.recommendedProductList[index].images.length > 0) -// ? Image.network( -// model.recommendedProductList[index].images[0].src.toString(), -//// item.images[0].src, -// fit: BoxFit.cover, -// height: 80, -// ) -// : Image.asset( -// "assets/images/no_image.png", -// fit: BoxFit.cover, -// height: 80, -// ), -// ), -// Text( -// model.recommendedProductList[index].name, -//// model.recommendedProduct[0].products[index].shortDescription -//// .toString(), -// style: TextStyle( -// color: Colors.black, -// fontSize: 15.0, -//// fontWeight: FontWeight.bold, -// ), -// ), -// Padding( -// padding: const EdgeInsets.only(top: 15, bottom: 10), -// child: Texts( -// "SAR ${model.recommendedProductList[index].price}", -// bold: true, -// fontSize: 14, +// ]) +// : Container(), +// ) +// : Container( +// height: model.recommendedProductList.length > 0 +// ? MediaQuery.of(context).size.height * 0.60 +// : 0, +// child: ListView.builder( +// physics: ScrollPhysics(), +//// physics: NeverScrollableScrollPhysics(), +// itemCount: model.recommendedProductList.length, +// itemBuilder: (context, index) { +// return Card( +// elevation: 2, +// shape: RoundedRectangleBorder( +// side: BorderSide(color: Colors.grey[300], width: 2), +// borderRadius: BorderRadius.circular(10)), +//// +// margin: EdgeInsets.symmetric( +// horizontal: 8, +// vertical: 4, +// ), +// child: Container( +// decoration: BoxDecoration( +// borderRadius: BorderRadius.all( +// Radius.circular(15), // ), // ), -// Row( -// crossAxisAlignment: -// CrossAxisAlignment.start, -// children: [ +// padding: EdgeInsets.symmetric(horizontal: 5), +// width: MediaQuery.of(context).size.width / 3, +//// +// child: Column( +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// Stack(children: [ // Container( -// padding: EdgeInsets.only(right: 10), -//// margin: EdgeInsets.only(left: 5), // child: Align( -// alignment: Alignment.topLeft, -// child: RatingBar.readOnly( -// initialRating: -// model.recommendedProductList[index].approvedRatingSum.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, -// ), -// ), +// alignment: Alignment.topRight, +// child: //true +// //wishlistVar[index].id.contains(model.recommendedProductList[index].id) +// !isInWishlist +// ? IconButton( +// icon: Icon(Icons.favorite_border), +// color: Colors.grey, +// iconSize: 30, +// onPressed: () { +// setState(() { +// addToWishlistFunction(itemID); +// }); +// }, +// ) +// : IconButton( +// icon: Icon(Icons.favorite), +// color: Colors.red, +// iconSize: 30, +// onPressed: () { +// setState(() { +// deleteFromWishlistFunction(itemID); +// }); +// }, +// ) +//// +// ), // ), -// Texts( -// "(${model.recommendedProductList[index].approvedTotalReviews.toString()})", -//// bold: true, -// fontSize: 12, +// Container( +// margin: EdgeInsets.fromLTRB(0, 16, 10, 16), +// alignment: Alignment.center, +//// padding: EdgeInsets.only(left: 25, bottom: 20), +// child: (model.recommendedProductList[index].images != null && +// model.recommendedProductList[index].images.length > 0) +// ? Image.network(model.recommendedProductList[index].images[0].src.toString(), +//// item.images[0].src, +// fit: BoxFit.cover, +// height: 60, +// ) +// : Image.asset("assets/images/no_image.png", +// fit: BoxFit.cover, +// height: 60, +// ), +// ), +// Container( +// width: model.recommendedProductList[index].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: Texts( +// model.recommendedProductList[index].rxMessage != null +// ? model.recommendedProductList[index].rxMessage +// : "", +// color: Colors.white, +// regular: true, +// fontSize: 10, +// fontWeight: FontWeight.w400, +// ), // ), // ]), -// ], -// ), -// ); - }), - ), - ]), - ), - ), - ); +// Container( +// margin: EdgeInsets.symmetric( +// horizontal: 6, +// vertical: 2, +// ), +// child: Column( +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// Text(model.recommendedProductList[index].name, +// style: TextStyle( +// color: Colors.black, +// fontSize: 13.0, +//// fontWeight: FontWeight.bold, +// ), +// ), +// Padding( +//// padding: const EdgeInsets.only(top: 15, bottom: 10), +// padding: const EdgeInsets.only( +// top: 10, bottom: 5), +// child: Texts( +// "SAR ${model.recommendedProductList[index].price}", +// bold: true, +// fontSize: 14, +// ), +// ), +// ], +// ), +// ), +// Row( +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// Container( +// padding: EdgeInsets.only( +// right: 10, bottom: 10), +//// margin: EdgeInsets.only(left: 5), +// child: Align( +// alignment: Alignment.topLeft, +// child: RatingBar.readOnly( +// initialRating: model.recommendedProductList[index].approvedRatingSum.toDouble(), +//// initialRating: productRate, +// size: 13.0, +// filledColor: Colors.yellow[700], +// emptyColor: Colors.grey[500], +// isHalfAllowed: true, +// halfFilledIcon: Icons.star_half, +// filledIcon: Icons.star, +// emptyIcon: Icons.star, +// ), +// ), +// ), +// Texts( +// "(${model.recommendedProductList[index].approvedTotalReviews.toString()})", +//// bold: true, +// fontSize: 12, +// ), +// ]), +// ], +// ), +// ), +// ); +// +// }), +// ), +// ]), +// ), +// ), +// ); } checkWishlist() async { ProductDetailViewModel x = new ProductDetailViewModel(); @@ -985,13 +534,13 @@ class _RecommendedProductPageState extends State addToWishlistFunction(itemID) async { ProductDetailViewModel x = new ProductDetailViewModel(); isInWishlist = true; - await x.addToWishlistData(itemID); + await x.addToWishlistData(itemID, context); } deleteFromWishlistFunction(itemID) async { ProductDetailViewModel x = new ProductDetailViewModel(); isInWishlist = false; - await x.addToWishlistData(itemID); + await x.addToWishlistData(itemID, context); } } diff --git a/lib/pages/pharmacies/search_brands_page.dart b/lib/pages/pharmacies/search_brands_page.dart index 8f771490..44e261d6 100644 --- a/lib/pages/pharmacies/search_brands_page.dart +++ b/lib/pages/pharmacies/search_brands_page.dart @@ -1,16 +1,18 @@ import 'package:diplomaticquarterapp/config/size_config.dart'; -import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/brand_view_model.dart'; -import 'package:diplomaticquarterapp/core/viewModels/pharmacy_categorise_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/input/text_field.dart'; -import 'package:diplomaticquarterapp/widgets/others/StarRating.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_pharmacy_widget.dart'; -import 'package:diplomaticquarterapp/widgets/others/network_base_view.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:provider/provider.dart'; + +import '../Blood/new_text_Field.dart'; class SearchBrandsPage extends StatefulWidget { @override @@ -24,11 +26,12 @@ class _SearchBrandsPageState extends State { @override Widget build(BuildContext context) { + ProjectViewModel projectProvider = Provider.of(context); return BaseView( - onModelReady: (model) => model.searchProducts(), - builder: (BuildContext context, model, Widget child) => + onModelReady: (model) => model!.searchProducts(productName: ''), + builder: (BuildContext context, model, Widget? child) => PharmacyAppScaffold( - appBarTitle: 'Search', + appBarTitle: TranslationBase.of(context).search, isBottomBar: false, isShowAppBar: true, backgroundColor: Colors.white, @@ -47,9 +50,9 @@ class _SearchBrandsPageState extends State { width: MediaQuery.of(context).size.width * 0.79, child: Form( key: _formKey, - child: TextFields( + child: NewTextFields( autoFocus: true, - hintText: 'Search', + hintText: TranslationBase.of(context).search, fontSize: 19.0, prefixIcon: Icon(Icons.search), inputAction: TextInputAction.search, @@ -58,15 +61,15 @@ class _SearchBrandsPageState extends State { }, onSubmit: (value) { searchMedicine(model, context); - msg = 'No Result Found'; + msg = TranslationBase.of(context).noSearchResultFound; }, 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; +// }, ), ), ), @@ -75,7 +78,7 @@ class _SearchBrandsPageState extends State { ), InkWell( child: Texts( - 'Cancel', + TranslationBase.of(context).cancel, fontSize: 17.0, fontWeight: FontWeight.w500, ), @@ -100,7 +103,7 @@ class _SearchBrandsPageState extends State { model.searchList.length == 0 ? Container( child: Text( - 'no data' + model.searchList.length.toString()), + TranslationBase.of(context).noData + model.searchList.length.toString()), ) : Expanded( child: Container( @@ -108,22 +111,24 @@ class _SearchBrandsPageState extends State { itemCount: model.searchList.length, itemBuilder: (BuildContext ctx, index) { return Padding( - padding:EdgeInsets.all(8.0), + padding: EdgeInsets.all(8.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ - Padding( - padding: const EdgeInsets.all(8.0), - child: Container( - child: Text( - model.searchList[index].name, - style: TextStyle(fontSize: 20), + Padding( + padding: const EdgeInsets.all(8.0), + child: Container( + child: Text( projectProvider.isArabic! + ? model.searchList[index].namen! + :model.searchList[index].name!, + style: TextStyle(fontSize: 20), + ), ), ), - ), - Divider(height: 1, color: Colors.grey) - ],), + Divider(height: 1, color: Colors.grey) + ], + ), ); }, ), @@ -139,7 +144,7 @@ class _SearchBrandsPageState extends State { searchMedicine(model, BuildContext context) { Utils.hideKeyboard(context); - if (_formKey.currentState.validate()) + if (_formKey.currentState!.validate()) model.searchProducts(productName: textController.text); } } diff --git a/lib/pages/pharmacies/widgets/BannerPager.dart b/lib/pages/pharmacies/widgets/BannerPager.dart deleted file mode 100644 index b088eefb..00000000 --- a/lib/pages/pharmacies/widgets/BannerPager.dart +++ /dev/null @@ -1,95 +0,0 @@ -import 'package:carousel_slider/carousel_slider.dart'; -import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart'; -import 'package:diplomaticquarterapp/pages/offers_categorise_page.dart'; -import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; -import 'package:flutter/material.dart'; -import 'package:diplomaticquarterapp/uitl/utils.dart'; - -class BannerPager extends StatefulWidget { - final PharmacyModuleViewModel _model; - - BannerPager(this._model); - - @override - _BannerPagerState createState() => _BannerPagerState(); -} - -class _BannerPagerState extends State { - int _current = 0; - - @override - Widget build(BuildContext context) { - return Container( - child: Column( - children: [ - CarouselSlider( - options: CarouselOptions( - aspectRatio: 7 / 2, - enlargeCenterPage: true, - enableInfiniteScroll: false, - initialPage: 0, - autoPlay: true, - autoPlayInterval: Duration(seconds: 3), - autoPlayAnimationDuration: Duration(milliseconds: 800), - autoPlayCurve: Curves.decelerate, - onPageChanged: (index, reason) { - setState(() { - _current = index; - }); - }, - ), - 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, - ) - : Image.network( - item, - fit: BoxFit.cover, - ), - ), - ), - ), - ), - ) - .toList(), - ), - Padding( - padding: const EdgeInsets.all(8.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: widget._model - .getBannerImagesUrl() - .mapIndexed( - (item, index) => Container( - width: 12.0, - height: 4.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), - ), - ), - ) - .toList(), - ), - ) - ], - )); - } -} diff --git a/lib/pages/pharmacies/widgets/ProductOrderItem.dart b/lib/pages/pharmacies/widgets/ProductOrderItem.dart index d7a82cc6..6a22cc84 100644 --- a/lib/pages/pharmacies/widgets/ProductOrderItem.dart +++ b/lib/pages/pharmacies/widgets/ProductOrderItem.dart @@ -1,17 +1,22 @@ +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/ShoppingCart.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/OrderPreviewViewModel.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'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:provider/provider.dart'; class ProductOrderItem extends StatefulWidget { - final ShoppingCart item; - final VoidCallback changeCartItems; - final VoidCallback deleteCartItems; + final ShoppingCart? item; + final VoidCallback? changeCartItems; + final VoidCallback? deleteCartItems; + final OrderPreviewViewModel? model; - ProductOrderItem(this.item, this.changeCartItems, this.deleteCartItems); + ProductOrderItem( + {this.item, this.changeCartItems, this.deleteCartItems, this.model}); @override _ProductOrderItemState createState() => _ProductOrderItemState(); @@ -23,42 +28,45 @@ class _ProductOrderItemState extends State { @override void initState() { - _quantityController.text = "${widget.item.quantity}"; - _totalPrice = - "${(widget.item.product.price * widget.item.quantity).toStringAsFixed(2)}"; super.initState(); } @override Widget build(BuildContext context) { + _quantityController.text = "${widget.item!.quantity!}"; + _totalPrice = + "${(widget.item!.product!.price! * widget.item!.quantity!).toStringAsFixed(2)}"; ProjectViewModel projectProvider = Provider.of(context); return Column( children: [ ListTile( leading: InkWell( - onTap: () => {widget.deleteCartItems()}, + onTap: () => {widget.deleteCartItems!()}, child: Icon( - Icons.delete_outline_sharp, + FontAwesomeIcons.trashAlt, + size: 15, color: Colors.grey.shade700, ), ), title: Container( child: Row( +// widget.item.product.stock_quantity===0 crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.max, children: [ - (widget.item.product.images != null && widget.item.product.images.length > 0) + (widget.item!.product!.images! != null && + widget.item!.product!.images!.length > 0) ? Image.network( - widget.item.product.images[0].src, - fit: BoxFit.cover, - height: 80, - ) + widget!.item!.product!.images![0]!.src!, + fit: BoxFit.cover, + height: 80, + ) : Image.asset( - "assets/images/no_image.png", - fit: BoxFit.cover, - height: 80, - ), + "assets/images/no_image.png", + fit: BoxFit.cover, + height: 80, + ), Expanded( child: Container( margin: @@ -71,8 +79,8 @@ class _ProductOrderItemState extends State { Container( child: Texts( projectProvider.isArabic - ? widget.item.product.namen - : "${widget.item.product.name}", + ? widget.item!.product!.namen! + : "${widget.item!.product!.name!}", regular: true, textAlign: TextAlign.justify, fontSize: 12, @@ -82,7 +90,7 @@ class _ProductOrderItemState extends State { ), Container( child: Texts( - "${(widget.item.product.price).toStringAsFixed(2)} ${projectProvider.isArabic ? widget.item.currencyn : widget.item.currency}", + "${(widget.item!.product!.price!).toStringAsFixed(2)} ${projectProvider.isArabic ? widget.item!.currencyn! : widget.item!.currency}", fontSize: 14, fontWeight: FontWeight.bold, ), @@ -99,7 +107,9 @@ class _ProductOrderItemState extends State { width: 25, height: 25, child: Icon( - Icons.remove, color: Colors.grey.shade400, size: 20, + Icons.remove, + color: Colors.grey.shade400, + size: 20, ), decoration: BoxDecoration( border: Border.all( @@ -125,12 +135,13 @@ class _ProductOrderItemState extends State { setState(() { var value = int.tryParse(text); if (value == null) { - widget.item.quantity = 0; + widget!.item!.quantity = 0; } else { - widget.item.quantity = int.parse(text); + widget.item!.quantity = + int.parse(text); } _totalPrice = - "${(widget.item.product.price * widget.item.quantity).toStringAsFixed(2)}"; + "${(widget.item!.product!.price! * widget.item!.quantity!).toStringAsFixed(2)}"; }); }, )), @@ -142,7 +153,9 @@ class _ProductOrderItemState extends State { width: 25, height: 25, child: Icon( - Icons.add, color: Colors.grey.shade400, size: 20, + Icons.add, + color: Colors.grey.shade400, + size: 20, ), decoration: BoxDecoration( border: Border.all( @@ -163,13 +176,25 @@ class _ProductOrderItemState extends State { fontSize: 12, ), Texts( - "$_totalPrice ${projectProvider.isArabic ? widget.item.currencyn : widget.item.currency}", + "$_totalPrice ${projectProvider.isArabic ? widget.item!.currencyn! : widget.item!.currency!}", fontSize: 12, fontWeight: FontWeight.bold, - ) + ), + widget.item!.product!.stockQuantity == 0 + ? Texts( + projectProvider.isArabic + ? widget.item!.product! + .stockAvailabilityn! + : widget.item!.product! + .stockAvailability, + fontWeight: FontWeight.normal, + fontSize: 13, + color: Colors.red, + ) + : Texts(""), ], ), - ) + ), ], ), ) @@ -195,17 +220,17 @@ class _ProductOrderItemState extends State { _quantityOnChangeClick(Operation operation) { int newValue = 0; - setState(() { + setState(() async { switch (operation) { case Operation.inc: { - newValue = widget.item.quantity + 1; + newValue = widget.item!.quantity! + 1; } break; case Operation.dec: { - newValue = widget.item.quantity - 1; + newValue = widget.item!.quantity! - 1; } break; default: @@ -215,15 +240,21 @@ class _ProductOrderItemState extends State { break; } if (newValue > 0) { - widget.item.quantity = newValue; - _quantityController.text = "${widget.item.quantity}"; + widget.item!.quantity = newValue; + widget!.changeCartItems!(); + if (widget.model!.state == ViewState.ErrorLocal) { + if (operation == Operation.dec) { + newValue = widget.item!.quantity! + 1; + } else { + newValue = widget.item!.quantity! - 1; + } + widget.item!.quantity = newValue; + } + _quantityController.text = "${widget.item!.quantity!}"; _totalPrice = - "${(widget.item.product.price * widget.item.quantity).toStringAsFixed(2)}"; + "${(widget.item!.product!.price! * widget.item!.quantity!).toStringAsFixed(2)}"; } }); - if (newValue > 0) { - widget.changeCartItems(); - } } @override diff --git a/lib/pages/pharmacies/widgets/ProductOrderPreviewItem.dart b/lib/pages/pharmacies/widgets/ProductOrderPreviewItem.dart index d38f437c..6977a1a8 100644 --- a/lib/pages/pharmacies/widgets/ProductOrderPreviewItem.dart +++ b/lib/pages/pharmacies/widgets/ProductOrderPreviewItem.dart @@ -22,9 +22,9 @@ class ProductOrderPreviewItem extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.max, children: [ - (item.product.images != null && item.product.images.length > 0) + (item.product!.images != null && item.product!.images!.length > 0) ? Image.network( - item.product.images[0].src, + item.product!.images![0].src!, fit: BoxFit.cover, height: 80, ) @@ -44,8 +44,8 @@ class ProductOrderPreviewItem extends StatelessWidget { Container( child: Texts( projectProvider.isArabic - ? item.product.namen - : item.product.name, + ? item.product!.namen + : item.product!.name, regular: true, textAlign: TextAlign.justify, fontSize: 12, @@ -55,7 +55,7 @@ class ProductOrderPreviewItem extends StatelessWidget { ), Container( child: Texts( - "${(item.product.price).toStringAsFixed(2)} ${projectProvider.isArabic ? item.currencyn : item.currency}", + "${(item.product!.price)!.toStringAsFixed(2)} ${projectProvider.isArabic ? item.currencyn : item.currency}", fontSize: 14, fontWeight: FontWeight.bold, ), @@ -83,7 +83,7 @@ class ProductOrderPreviewItem extends StatelessWidget { child: Container( alignment: Alignment.centerRight, child: Texts( - "${(item.product.price * item.quantity).toStringAsFixed(2)} ${projectProvider.isArabic ? item.currencyn : item.currency}", + "${(item.product!.price! * item.quantity!).toStringAsFixed(2)} ${projectProvider.isArabic ? item.currencyn : item.currency}", fontSize: 14, fontWeight: FontWeight.bold, ), diff --git a/lib/pages/pharmacies/widgets/ProductTileItem.dart b/lib/pages/pharmacies/widgets/ProductTileItem.dart index 20d6b730..9e303152 100644 --- a/lib/pages/pharmacies/widgets/ProductTileItem.dart +++ b/lib/pages/pharmacies/widgets/ProductTileItem.dart @@ -1,20 +1,29 @@ +import 'package:auto_size_text/auto_size_text.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/product_detail.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/screens/phramacy-product-detail-page.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/product-detail.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/shared/icon_with_bg.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/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/StarRating.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_rating_bar/flutter_rating_bar.dart'; +import 'package:flutter_svg/svg.dart'; import 'package:provider/provider.dart'; +import 'dart:math' as math; + class ProductTileItem extends StatelessWidget { final AppSharedPreferences sharedPref = AppSharedPreferences(); final PharmacyProduct item; + final double itemHeight; - ProductTileItem(this.item); + ProductTileItem(this.item, this.itemHeight); void productOnClick(BuildContext ctx) { _saveLastVisitProducts(); @@ -24,6 +33,7 @@ class ProductTileItem extends StatelessWidget { void _saveLastVisitProducts() async { String lastVisited = ""; bool isIdExist = false; + List items = []; if (await this.sharedPref.getString(PHARMACY_LAST_VISITED_PRODUCTS) != null) { lastVisited = @@ -32,8 +42,26 @@ class ProductTileItem extends StatelessWidget { if (id == item.id) { isIdExist = true; } + items.add(id); }); } + + if (items.length >= 15) { + items.removeAt(0); + // lastVisited = lastVisited.replaceFirst(RegExp('$itemToRemove'), ''); + } + + lastVisited = ""; + for (int i = items.length - 1; i >= 0; i--) { + if (lastVisited == "") { + // it means there is no lastVisited yet + lastVisited = "${items[i]}"; + } else { + // there is lastVisited id's and this product id is not found + lastVisited += ",${items[i]}"; + } + } + if (!isIdExist) { if (lastVisited == "") { // it means there is no lastVisited yet @@ -42,8 +70,8 @@ class ProductTileItem extends StatelessWidget { // there is lastVisited id's and this product id is not found lastVisited += ",${item.id}"; } - sharedPref.setString(PHARMACY_LAST_VISITED_PRODUCTS, lastVisited); } + sharedPref.setString(PHARMACY_LAST_VISITED_PRODUCTS, lastVisited); } @override @@ -51,103 +79,268 @@ class ProductTileItem extends StatelessWidget { ProjectViewModel projectProvider = Provider.of(context); return InkWell( onTap: () => productOnClick(context), - splashColor: Theme.of(context).primaryColor, - child: Card( - elevation: 2, - shape: Border(right: BorderSide(color: Colors.grey.shade300, width: 1)), - margin: EdgeInsets.symmetric( - horizontal: 8, - vertical: 4, + child: Container( + margin: EdgeInsets.all(7), + decoration: BoxDecoration( + border: Border.all(color: Colors.grey.shade300, width: 0.2), + borderRadius: BorderRadius.circular(10), + color: Colors.white, + shape: BoxShape.rectangle, + boxShadow: [ + BoxShadow( + color: Color(0xffF1F1F1), + spreadRadius: 4, + blurRadius: 5.5, + offset: Offset(0, 3), // changes position of shadow + ), + ], ), - child: Container( - padding: EdgeInsets.symmetric(horizontal: 0), - width: MediaQuery.of(context).size.width / 3, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Stack( - children: [ - Container( - margin: EdgeInsets.fromLTRB(0, 16, 0, 0), - alignment: Alignment.center, - child: (item.images != null && item.images.length > 0) - ? Image.network( - item.images[0].src, - fit: BoxFit.cover, - height: 80, - ) - : Image.asset( - "assets/images/no_image.png", - fit: BoxFit.cover, - height: 80, + padding: EdgeInsets.symmetric(horizontal: 4), + width: MediaQuery.of(context).size.width / 2.8, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Stack( + // children: [ + // Container( + // margin: EdgeInsets.fromLTRB(0, 0, 0, 0), + // alignment: Alignment.center, + // child: (item.images != null && item.images.length > 0) + // ? Image.network( + // item.images[0].src, + // fit: BoxFit.cover, + // height: itemHeight / 2, + // ) + // : Image.asset( + // "assets/images/no_image.png", + // fit: BoxFit.cover, + // height: itemHeight / 2, + // ), + // ), + // ], + // ), + + Container( + width: double.infinity, + height: MediaQuery.of(context).size.width * 0.3, + padding: + EdgeInsets.only(left: 10, right: 10, top: 7, bottom: 3.5), + color: Colors.white, + child: Container( + width: double.infinity, + height: double.infinity, + clipBehavior: Clip.antiAlias, + decoration: containerRadiusWithGradientServices(0.0, + prescriptionRequired: item.rxMessage != null, + isProduct: true, + isEnglish: !projectProvider.isArabic, + lightColor: Colors.transparent, + darkColor: Colors.transparent), + child: Stack( + children: [ + Stack( + children: [ + Container( + decoration: BoxDecoration( + border: Border.all( + color: Color(0xffF0F0F0), width: 1.0), + borderRadius: BorderRadius.only( + topRight: Radius.circular( + item.rxMessage != null && + projectProvider.isArabic + ? 20 + : 8), + bottomLeft: Radius.circular(8), + bottomRight: Radius.circular(8), + topLeft: Radius.circular(item.rxMessage != null && + !projectProvider.isArabic + ? 20 + : 8), + ), ), - ), - 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: Texts( - item.rxMessage != null ? item.rxMessage : "", - color: Colors.white, - regular: true, - fontSize: 10, - fontWeight: FontWeight.w400, + margin: EdgeInsets.fromLTRB(0, 0, 0, 0), + alignment: Alignment.center, + child: (item.images != null && item.images!.length > 0) + ? Padding( + padding: EdgeInsets.all(12.0), + child: Image.network( + item.images![0].src!, + fit: BoxFit.cover, + height: itemHeight / 2, + ), + ) + : Padding( + padding: EdgeInsets.all(8.0), + child: Image.asset( + "assets/images/no_image.png", + fit: BoxFit.cover, + height: itemHeight / 2, + ), + ), + ), + ], ), - ) - ], + if (item.rxMessage != null) + projectProvider.isArabic + ? Positioned( + right: -16, + top: 2, + child: Transform.rotate( + angle: math.pi / 4, + child: Container( + color: CustomColors.accentColor, + padding: EdgeInsets.only( + left: 18, right: 18, top: 6, bottom: 3), + child: Padding( + padding: EdgeInsets.all(2.0), + child: Text( + "الوصفة\n مطلوبة", + style: TextStyle( + color: Colors.white, + fontSize: 7.0, + height: 0.8, + fontWeight: FontWeight.w600, + letterSpacing: -0.27, + ), + ), + ), + ), + ), + ) + : Positioned( + left: -24, + top: 2, + child: Transform.rotate( + angle: -math.pi / 4, + child: Container( + padding: EdgeInsets.only( + left: 18, right: 18, top: 6, bottom: 3), + color: CustomColors.accentColor, + child: Text( + "\n E-Prescription \n Is required", + style: TextStyle( + color: Colors.white, + fontSize: 7.0, + //letterSpacing: -0.27, + height: 1.2, + fontWeight: FontWeight.w600, + ), + ), + ), + ), + ), + ], + ), + ), + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 10.0), + child: Container( + height: MediaQuery.of(context).size.height * 0.075, + child: Texts( + projectProvider.isArabic ? item.namen : item.name, + //regular: true, + fontSize: 10, + color: Color(0xff2B353E), + fontWeight: FontWeight.w600, + ), ), - Container( + ), + SizedBox( + height: 7.0, + ), + Expanded( + child: Container( margin: EdgeInsets.symmetric( - horizontal: 6, + horizontal: 4, vertical: 0, ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, + //mainAxisAlignment: MainAxisAlignment.end, children: [ - Texts( - projectProvider.isArabic ? item.namen : item.name, - regular: true, - fontSize: 12, - fontWeight: FontWeight.w400, - ), Padding( - padding: const EdgeInsets.only(top: 4, bottom: 4), + padding: const EdgeInsets.symmetric( + horizontal: 10, vertical: 2), child: Texts( "SAR ${item.price}", - bold: true, - fontSize: 14, + fontWeight: FontWeight.w700, + fontSize: 11, + color: Color(0xff2B353E), ), ), - Row( - children: [ - Expanded( - child: StarRating( - totalAverage: item.approvedTotalReviews > 0 - ? (item.approvedRatingSum.toDouble() / - item.approvedTotalReviews.toDouble()) - .toDouble() - : 0, - forceStars: true), - ), - /*Texts( - "(${item.approvedTotalReviews})", - regular: true, - fontSize: 10, - fontWeight: FontWeight.w400, - ),*/ - ], + Padding( + padding: EdgeInsets.symmetric(horizontal: 5), + child: Row( + children: [ + // Expanded( + // RatingBar.readOnly( + // initialRating: item.approvedRatingSum.toDouble(), + // size: 13.0, + // filledColor: Color(0XFFD02127), + // emptyColor: Color(0XFFD02127), + // isHalfAllowed: true, + // halfFilledIcon: Icons.star_half, + // filledIcon: Icons.star, + // emptyIcon: Icons.star_border, + // ), + // + // + + RatingBar( + initialRating: item.approvedRatingSum!.toDouble(), + direction: Axis.horizontal, + allowHalfRating: true, + itemCount: 5, + itemSize: 20, + ignoreGestures: true, + ratingWidget: RatingWidget( + full: Icon(Icons.star, color: CustomColors.accentColor,), + half: Icon(Icons.star_half, color: CustomColors.accentColor,), + empty: Icon(Icons.star, color: CustomColors.accentColor,), + ), + tapOnlyMode: true, + unratedColor: Colors.grey[500], + itemPadding: EdgeInsets.symmetric(horizontal: 4.0), + onRatingUpdate: (rating) { + print(rating); + }, + ), + Texts( + "(${item.approvedTotalReviews})", + regular: true, + fontSize: 10, + fontWeight: FontWeight.w400, + ), + + SizedBox( + width: 9.0, + ), + Icon( + Icons.arrow_forward, + size: 15, + color: Color(0xff2D2F39), + ), + +// StarRating( +// totalAverage: item.approvedTotalReviews > 0 +// ? (item.approvedRatingSum.toDouble() / +// item.approvedTotalReviews.toDouble()) +// .toDouble() +// : 0, +// forceStars: true), + // ), + ], + ), ), ], ), - ) - ], - ), + ), + ), + SizedBox( + height: 1, + ), + ], ), ), ); diff --git a/lib/pages/pharmacies/widgets/home/BannerPager.dart b/lib/pages/pharmacies/widgets/home/BannerPager.dart new file mode 100644 index 00000000..ae9811e0 --- /dev/null +++ b/lib/pages/pharmacies/widgets/home/BannerPager.dart @@ -0,0 +1,123 @@ +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/screens/lacum-activitaion-vida-page.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/screens/lacum-registration-page.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/screens/lakum-main-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; + + BannerPager(this._model); + + @override + _BannerPagerState createState() => _BannerPagerState(); +} + +class _BannerPagerState extends State { + int _current = 0; + + @override + Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + return Container( + child: Column( + children: [ + // CarouselSlider( + // options: CarouselOptions( + // aspectRatio: 5 / 2, + // enlargeCenterPage: true, + // enableInfiniteScroll: false, + // viewportFraction: 1.0, + // initialPage: 0, + // autoPlay: true, + // autoPlayInterval: Duration(seconds: 3), + // autoPlayAnimationDuration: Duration(milliseconds: 800), + // autoPlayCurve: Curves.decelerate, + // onPageChanged: (index, reason) { + // setState(() { + // _current = index; + // }); + // }, + // ), + // items: widget._model.getBannerImagesUrl(projectViewModel).mapIndexed( + // (item, index) { + // return InkWell( + // onTap: () { + // bannerNavigator(index); + // }, + // 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(), + // ), + Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: widget._model + .getBannerImagesUrl(projectViewModel) + .mapIndexed( + (item, index) => Container( + width: 12.0, + height: 4.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), + ), + ), + ) + .toList(), + ), + ) + ], + )); + } + + bannerNavigator(index){ + switch(index) { + case 1: { + Navigator.push(context, FadePage(page: OffersCategorisePage())); + } + break; + case 2: { + // Navigator.push(context, FadePage(page: LakumActivationVidaPage())); + Navigator.push(context, FadePage(page: LakumMainPage())); + } + break; + case 5: { + Navigator.push(context, FadePage(page: OffersCategorisePage())); + } + break; + + default: { + + } + break; + } + + } +} diff --git a/lib/pages/pharmacies/widgets/home/BestSellerWidget.dart b/lib/pages/pharmacies/widgets/home/BestSellerWidget.dart new file mode 100644 index 00000000..23aa2558 --- /dev/null +++ b/lib/pages/pharmacies/widgets/home/BestSellerWidget.dart @@ -0,0 +1,58 @@ +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/BestSellerViewModel.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/others/network_base_view.dart'; +import 'package:flutter/material.dart'; + +import '../../../final_products_page.dart'; +import '../ProductTileItem.dart'; +import 'ViewAllHomeWidget.dart'; + +class BestSellerWidget extends StatelessWidget { + @override + Widget build(BuildContext context) { + return BaseView( + onModelReady: (model) => model.getBestSellerProducts(), + allowAny: true, + builder: (_, model, wi) => NetworkBaseView( + isLocalLoader: true, + baseViewModel: model, + child: Container( + child: Column( + children: [ + ViewAllHomeWidget( + TranslationBase.of(context).bestSellers, + FinalProductsPage( + id: "", + productType: 20, + )), + if (model.state != ViewState.BusyLocal) + Container( + height: MediaQuery.of(context).size.height / 3 + 1, + child: ListView.builder( + itemBuilder: (ctx, i) => ProductTileItem( + model.bestSellerProduct[i], + MediaQuery.of(context).size.height / 4 + 20), + scrollDirection: Axis.horizontal, + itemCount: model.bestSellerProduct.length, + ), + ) + else + Container( + height: 80, + child: Center( + child: CircularProgressIndicator( + backgroundColor: Colors.white, + valueColor: AlwaysStoppedAnimation( + Colors.grey[500]!, + ), + ), + ), + ), + ], + ), + ), + )); + } +} diff --git a/lib/pages/pharmacies/widgets/home/GridViewButtons.dart b/lib/pages/pharmacies/widgets/home/GridViewButtons.dart new file mode 100644 index 00000000..8a549b48 --- /dev/null +++ b/lib/pages/pharmacies/widgets/home/GridViewButtons.dart @@ -0,0 +1,85 @@ +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'; + +import '../../../offers_categorise_page.dart'; +import 'GridViewCard.dart'; + +class GridViewButtons extends StatelessWidget { + final PharmacyModuleViewModel model; + + GridViewButtons(this.model); + + @override + Widget build(BuildContext context) { + final gridHeight = (MediaQuery.of(context).size.width * 0.3) * 1.8; + return Container( + child: SizedBox( + height: gridHeight, + child: GridView.count( + childAspectRatio: 2.2, + crossAxisSpacing: 10, + mainAxisSpacing: 10, + controller: new ScrollController(keepScrollOffset: false), + shrinkWrap: true, + padding: const EdgeInsets.all(4.0), + crossAxisCount: 2, + children: [ + DashboardItem( + imageName: 'pharmacy_module/bg_1.png', + hasColorFilter: false, + opacity: 0.8, + child: GridViewCard( + TranslationBase.of(context).offersAndPromotions, + 'assets/images/pharmacy_module/offer_icon.png', () { + 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()));}), + // ), + ], + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/pages/pharmacies/widgets/home/GridViewCard.dart b/lib/pages/pharmacies/widgets/home/GridViewCard.dart new file mode 100644 index 00000000..b58956af --- /dev/null +++ b/lib/pages/pharmacies/widgets/home/GridViewCard.dart @@ -0,0 +1,84 @@ +import 'package:diplomaticquarterapp/config/size_config.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:flutter/material.dart'; + +class GridViewCard extends StatelessWidget { + final String text; + final String cardImage; + final Function handler; + + GridViewCard(this.text, this.cardImage, this.handler); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.all(4.0), + child: Container( + child: Row( + children: [ + Expanded( + flex: 2, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + flex: 2, + child: Padding( + padding: const EdgeInsets.all(6), + child: Column( + children: [ + Texts( + text, + color: Colors.white, + bold: true, + fontSize: SizeConfig.textMultiplier! * 1.3, + ), + ], + ), + ), + ), + Row( + children: [ + BorderedButton( + TranslationBase.of(context).viewAll, + handler: handler, + tPadding: 0, + textColor: Color(0xFF5ab145), + bPadding: 0, + ), + Expanded(child: Container()), + ], + ), + ], + ), + ), + Expanded( + child: Align( + alignment: Alignment.centerRight, + child: Image.asset( + cardImage, + fit: BoxFit.cover, + ), + ), + ), + ], + ), + ), + ); + } + + String getDate(String date) { + DateTime dateObj = DateUtil.convertStringToDate(date); + return DateUtil.getWeekDay(dateObj.weekday) + + ", " + + dateObj.day.toString() + + " " + + DateUtil.getMonth(dateObj.month) + + " " + + dateObj.year.toString(); + } +} \ No newline at end of file diff --git a/lib/pages/pharmacies/widgets/home/MostViewedWidget.dart b/lib/pages/pharmacies/widgets/home/MostViewedWidget.dart new file mode 100644 index 00000000..7b260ec0 --- /dev/null +++ b/lib/pages/pharmacies/widgets/home/MostViewedWidget.dart @@ -0,0 +1,60 @@ +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/MostViewedViewModel.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/pages/final_products_page.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/widgets/ProductTileItem.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/widgets/home/ViewAllHomeWidget.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/others/network_base_view.dart'; +import 'package:flutter/material.dart'; + +class MostViewedWidget extends StatelessWidget { + const MostViewedWidget({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return BaseView( + onModelReady: (model) => model.getMostViewedProducts(), + allowAny: true, + builder: (_, model, wi) => NetworkBaseView( + isLocalLoader: true, + baseViewModel: model, + child: Container( + child: Column( + children: [ + ViewAllHomeWidget( + TranslationBase.of(context).mostViewed, + FinalProductsPage( + id: "", + productType: 4, + )), + if (model.state != ViewState.BusyLocal) + Container( + height: MediaQuery.of(context).size.height / 3 + 1, + child: ListView.builder( + itemBuilder: (ctx, i) => ProductTileItem( + model.mostViewedProducts[i], + MediaQuery.of(context).size.height / 4 + 20), + scrollDirection: Axis.horizontal, + itemCount: model.mostViewedProducts.length, + ), + ) + else + Container( + height: 80, + child: Center( + child: CircularProgressIndicator( + backgroundColor: Colors.white, + valueColor: AlwaysStoppedAnimation( + Colors.grey[500]!, + ), + ), + ), + ), + ], + ), + ), + )); + } +} diff --git a/lib/pages/pharmacies/widgets/home/PrescriptionsWidget.dart b/lib/pages/pharmacies/widgets/home/PrescriptionsWidget.dart new file mode 100644 index 00000000..3eee39e6 --- /dev/null +++ b/lib/pages/pharmacies/widgets/home/PrescriptionsWidget.dart @@ -0,0 +1,219 @@ +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/prescription_items_page.dart'; +import 'package:diplomaticquarterapp/pages/medical/prescriptions/prescriptions_home_page.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/widgets/home/ViewAllHomeWidget.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.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:flutter_rating_bar/flutter_rating_bar.dart'; +import 'package:provider/provider.dart'; + + +class PrescriptionsWidget extends StatelessWidget { + AuthenticatedUserObject authenticatedUserObject = locator(); + + @override + Widget build(BuildContext context) { + + ProjectViewModel projectProvider = Provider.of(context); + return BaseView( + onModelReady: (model) async { + if (Provider.of(context, listen: false).isLogin) { + model.getPrescription(); + } + }, + allowAny: true, + builder: (_, model, wi) => model.prescriptionsList.length > 0 && authenticatedUserObject.isLogin + ? NetworkBaseView( + isLocalLoader: true, + baseViewModel: model, + child: Container( + child: Column( + children: [ + ViewAllHomeWidget(TranslationBase.of(context).myPrescription, HomePrescriptionsPage()), + Container( + margin: EdgeInsets.only(right: 10.0, left: 10.0), + height: MediaQuery.of(context).size.height * 0.30, + child: ListView.builder( + scrollDirection: Axis.horizontal, + shrinkWrap: true, + physics: ScrollPhysics(), + itemCount: model.prescriptionsList.length, + itemBuilder: (context, index) { + return InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: PrescriptionItemsPage( + prescriptions: model.prescriptionsList[index], + ), + ), + ); + }, + child: Container( + 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, + style: BorderStyle.solid, + width: 1.0, + ), + color: Colors.white, + borderRadius: BorderRadius.circular(10.0)), + child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ + Row( + children: [ + Container( + padding: EdgeInsets.only( + top: 10.0, + left: 10.0, + right: 10.0, + bottom: 10.0, + ), + child: CircleAvatar( + radius: 30, + backgroundColor: Colors.transparent, + child: Image.network( + model.prescriptionsList[index].doctorImageURL!, + width: 50, + height: 50, + ), + ), + ), + Column( + children: [ + Container( + padding: EdgeInsets.only(left: 15.0, right: 15.0), + decoration: BoxDecoration( + border: Border.all( + color: Colors.green, + style: BorderStyle.solid, + width: 3.0, + ), + color: Colors.green, + borderRadius: BorderRadius.circular(30.0)), + child: Text( + projectProvider.isArabic + ? 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, + ), + ) + ]), + ], + ), + ], + ), + 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, + ), + ), + ]), + ), + Container( + margin: EdgeInsets.only(left: 5), + child: Text( + model.prescriptionsList[index].clinicDescription.toString(), + style: TextStyle( + color: Colors.green, + fontSize: 15.0, + ), + ), + ), + Row(children: [ + Container( + margin: EdgeInsets.only(left: 5), + child: + RatingBar( + initialRating: model.prescriptionsList[index].actualDoctorRate!.toDouble(), + direction: Axis.horizontal, + allowHalfRating: true, + itemCount: 5, + itemSize: 20, + ignoreGestures: true, + ratingWidget: RatingWidget( + full: Icon(Icons.star, color: CustomColors.accentColor,), + half: Icon(Icons.star_half, color: CustomColors.accentColor,), + empty: Icon(Icons.star, color: CustomColors.accentColor,), + ), + unratedColor: Colors.grey[500], + tapOnlyMode: true, + itemPadding: EdgeInsets.symmetric(horizontal: 4.0), + onRatingUpdate: (rating) { + print(rating); + }, + ) + + /* RatingBar.readOnly( + initialRating: model.prescriptionsList[index].actualDoctorRate.toDouble(), + size: 15.0, + filledColor: Colors.yellow[700], + emptyColor: Colors.grey[500], + isHalfAllowed: true, + halfFilledIcon: Icons.star_half, + filledIcon: Icons.star, + emptyIcon: Icons.star, + ),*/ + ), + SizedBox( + width: 130.0, + ), + Container( + child: Icon( + Icons.arrow_forward, + color: Theme.of(context).primaryColor, + )), + ]), + ]), + ), + ); + }, + ), + ), + ], + ), + ), + ) + : Container(), + ); + } +} diff --git a/lib/pages/pharmacies/widgets/home/RecentlyViewedWidget.dart b/lib/pages/pharmacies/widgets/home/RecentlyViewedWidget.dart new file mode 100644 index 00000000..8b459a76 --- /dev/null +++ b/lib/pages/pharmacies/widgets/home/RecentlyViewedWidget.dart @@ -0,0 +1,63 @@ +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/LastVisitedViewModel.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/others/network_base_view.dart'; +import 'package:flutter/material.dart'; + +import '../../../final_products_page.dart'; +import '../ProductTileItem.dart'; +import 'ViewAllHomeWidget.dart'; + +class RecentlyViewedWidget extends StatelessWidget { + @override + Widget build(BuildContext context) { + return BaseView( + onModelReady: (model) => model.getLastVisitedProducts(), + allowAny: true, + builder: (_, model, wi) => NetworkBaseView( + isLocalLoader: true, + baseViewModel: model, + child: model.lastVisitedProducts.isNotEmpty + ? Container( + child: Column( + children: [ + ViewAllHomeWidget( + TranslationBase.of(context).recentlyViewed, + FinalProductsPage( + id: "", + productType: 3, + )), + if (model.state != ViewState.BusyLocal) + Container( + height: model.lastVisitedProducts.length > 0 + ? MediaQuery.of(context).size.height / 3 + 1 + : 0, + child: ListView.builder( + itemBuilder: (ctx, i) => ProductTileItem( + model.lastVisitedProducts[i], + MediaQuery.of(context).size.height / 4 + + 20), + scrollDirection: Axis.horizontal, + itemCount: model.lastVisitedProducts.length, + ), + ) + else + Container( + height: 80, + child: Center( + child: CircularProgressIndicator( + backgroundColor: Colors.white, + valueColor: AlwaysStoppedAnimation( + Colors.grey[500]!, + ), + ), + ), + ), + ], + ), + ) + : Container(), + )); + } +} diff --git a/lib/pages/pharmacies/widgets/home/ShopByBrandWidget.dart b/lib/pages/pharmacies/widgets/home/ShopByBrandWidget.dart new file mode 100644 index 00000000..38250c0a --- /dev/null +++ b/lib/pages/pharmacies/widgets/home/ShopByBrandWidget.dart @@ -0,0 +1,53 @@ +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/BrandViewModel.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/others/network_base_view.dart'; +import 'package:flutter/material.dart'; + +import '../../product-brands.dart'; +import '../manufacturerItem.dart'; +import 'ViewAllHomeWidget.dart'; + +class ShopByBrandWidget extends StatelessWidget { + @override + Widget build(BuildContext context) { + return BaseView( + onModelReady: (model) => model.getTopManufacturerList(), + allowAny: true, + builder: (_, model, wi) => NetworkBaseView( + isLocalLoader: true, + baseViewModel: model, + child: Container( + child: Column( + children: [ + ViewAllHomeWidget(TranslationBase.of(context).shopByBrands, + ProductBrandsPage()), + if (model.state != ViewState.BusyLocal) + Container( + height: 150, + child: ListView.builder( + itemBuilder: (ctx, i) => + ManufacturerItem(model.manufacturerList[i]), + scrollDirection: Axis.horizontal, + itemCount: model.manufacturerList.length, + ), + ) + else + Container( + height: 80, + child: Center( + child: CircularProgressIndicator( + backgroundColor: Colors.white, + valueColor: AlwaysStoppedAnimation( + Colors.grey[500]!, + ), + ), + ), + ), + ], + ), + ), + )); + } +} diff --git a/lib/pages/pharmacies/widgets/home/ViewAllHomeWidget.dart b/lib/pages/pharmacies/widgets/home/ViewAllHomeWidget.dart new file mode 100644 index 00000000..2b73a15a --- /dev/null +++ b/lib/pages/pharmacies/widgets/home/ViewAllHomeWidget.dart @@ -0,0 +1,55 @@ +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:flutter/material.dart'; + +class ViewAllHomeWidget extends StatelessWidget { + final String title; + final Widget navigationWidget; + + ViewAllHomeWidget(this.title, this.navigationWidget); + + @override + Widget build(BuildContext context) { + return Container( + margin: EdgeInsets.fromLTRB(16, 10, 16, 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Texts( + title, + color: Color(0xff2E303A), + fontWeight: FontWeight.w700, + fontSize: 19, + ), + InkWell( + onTap: () { + Navigator.push(context, + MaterialPageRoute(builder: (context) => navigationWidget)); + }, + child: Texts( + TranslationBase.of(context).viewAll, + color: Color(0xffD02127), + decoration: TextDecoration.underline, + fontWeight: FontWeight.w600, + fontSize: 12.0, + ), + ), + // BorderedButton( + // TranslationBase.of(context).viewAll, + // hasBorder: true, + // borderColor: Colors.green, + // textColor: Colors.green, + // fontWeight: FontWeight.bold, + // vPadding: 6, + // hPadding: 14, + // handler: () { + // Navigator.push(context, + // MaterialPageRoute(builder: (context) => navigationWidget)); + // }, + // ), + ], + ), + ); + } +} diff --git a/lib/pages/pharmacies/widgets/lacum-banner-widget.dart b/lib/pages/pharmacies/widgets/lacum-banner-widget.dart index 14a53e72..42ca3d07 100644 --- a/lib/pages/pharmacies/widgets/lacum-banner-widget.dart +++ b/lib/pages/pharmacies/widgets/lacum-banner-widget.dart @@ -1,4 +1,4 @@ -import 'package:carousel_slider/carousel_slider.dart'; +// import 'package:carousel_slider/carousel_slider.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/lacum-viewmodel.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/borderedButton.dart'; @@ -24,225 +24,231 @@ class _LakumBannerWidgetState extends State { return Container( child: Stack( children: [ - CarouselSlider( - options: CarouselOptions( - enableInfiniteScroll: false, - enlargeCenterPage: false, - viewportFraction: 1.0, - scrollPhysics: widget.isLacumHomePage - ? ScrollPhysics() - : NeverScrollableScrollPhysics(), - initialPage: 0, - onPageChanged: (index, reason) { - setState(() { - _current = index; - }); - }, - ), - items: [ - Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(4), - border: Border.fromBorderSide(BorderSide( - color: Colors.grey, - width: 0.4, - )), - ), - margin: EdgeInsets.symmetric(horizontal: 16), - child: Stack( - children: [ - Image.asset( - "assets/images/pharmacy_module/lakum/lakum_card_front_bg.png", - fit: BoxFit.fill, - width: widget.mediaQuery.size.width * 1.0, - height: widget.mediaQuery.size.width * 1.0, - ), - Container( - margin: EdgeInsets.fromLTRB(12, 70, 12, 4), - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts( - widget.model.lacumGroupInformation.lakumInquiryInformationObjVersion.memberName, - fontSize: 14, - fontWeight: FontWeight.bold, - color: Colors.black, - ), - Texts( - "${widget.model.lacumInformation.yahalaAccountNo}", - fontSize: 16, - fontWeight: FontWeight.normal, - color: Colors.black, - ), - ], - ), - BorderedButton( - widget.model.lacumGroupInformation.lakumInquiryInformationObjVersion.accountStatus == "Active" - ? TranslationBase.of(context).active - : TranslationBase.of(context).inactive, - textColor: widget.model.lacumInformation - .accountStatus == - 1 - ? Colors.green - : Colors.red, - hasBorder: true, - borderColor: widget.model.lacumInformation - .accountStatus == - 1 - ? Colors.green - : Colors.red, - radius: 16, - rPadding: 16, - icon: widget.model.lacumInformation - .accountStatus == - 1 - ? Icon( - Icons.check_circle, - size: 25, - color: Colors.green, - ) - : Image.asset( - "assets/images/pharmacy_module/lakum/inactive_cross.png", - fit: BoxFit.fill, - width: 25, - height: 25, - ), - ), - ], - ), - SizedBox( - height: 10, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts( - "IDENTIFICATION #", - fontSize: 14, - fontWeight: FontWeight.bold, - color: Colors.black, - ), - Texts( - widget.model.lacumInformation - .identificationNo, - fontSize: 16, - fontWeight: FontWeight.normal, - color: Colors.black, - ), - ], - ), - Column( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Texts( - "MEMBER SINCE", - fontSize: 14, - fontWeight: FontWeight.bold, - color: Colors.black, - ), - Texts( - widget.model.formatCreatedDateToString(), - fontSize: 16, - fontWeight: FontWeight.normal, - color: Colors.black, - ), - ], - ), - ], - ), - SizedBox( - height: 10, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts( - "MOBILE #", - fontSize: 14, - fontWeight: FontWeight.bold, - color: Colors.black, - ), - Texts( - widget.model.lacumGroupInformation.lakumInquiryInformationObjVersion.mobileNumber, - fontSize: 16, - fontWeight: FontWeight.normal, - color: Colors.black, - ), - ], - ), - Column( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Texts( - TranslationBase.of(context).language, - fontSize: 14, - fontWeight: FontWeight.bold, - color: Colors.black, - ), - Texts( - widget.model.lacumInformation.prefLang == - "1" - ? TranslationBase.of(context).lanEnglish - : TranslationBase.of(context).lanArabic, - fontSize: 16, - fontWeight: FontWeight.normal, - color: Colors.black, - ), - ], - ), - ], - ), - ], - ), - ), - ], - ), - ), - widget.isLacumHomePage - ? Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(4), - border: Border.fromBorderSide(BorderSide( - color: Colors.grey, - width: 0.4, - )), - ), - margin: EdgeInsets.symmetric(horizontal: 16), - child: Stack( - children: [ - Image.asset( - "assets/images/pharmacy_module/lakum/lakum_card_front_bg.png", - fit: BoxFit.fill, - width: widget.mediaQuery.size.width * 1.0, - height: widget.mediaQuery.size.width * 1.0, - ), - Container( - margin: EdgeInsets.fromLTRB(12, 70, 12, 4), - child: widget.model.convertBase64ToBarCodeImage() != - null - ? Image.memory( - widget.model.convertBase64ToBarCodeImage()) - : Container(), - ), - ], - ), - ) - : Container(), - ], - ), +// CarouselSlider( +// options: CarouselOptions( +// enableInfiniteScroll: false, +// enlargeCenterPage: false, +// viewportFraction: 1.0, +// scrollPhysics: widget.isLacumHomePage +// ? ScrollPhysics() +// : NeverScrollableScrollPhysics(), +// initialPage: 0, +// onPageChanged: (index, reason) { +// setState(() { +// _current = index; +// }); +// }, +// ), +// items: [ +// Container( +// decoration: BoxDecoration( +// shape: BoxShape.rectangle, +// borderRadius: BorderRadius.circular(4), +// border: Border.fromBorderSide(BorderSide( +// color: Colors.grey, +// width: 0.4, +// )), +// ), +// margin: EdgeInsets.symmetric(horizontal: 16), +// child: Stack( +// children: [ +// Image.asset( +// "assets/images/pharmacy_module/lakum/lakum_card_front_bg.png", +// fit: BoxFit.fill, +// width: widget.mediaQuery.size.width * 1.0, +// height: widget.mediaQuery.size.width * 1.0, +// ), +// Container( +// margin: EdgeInsets.fromLTRB(12, 75, 12, 0), +// child: Column( +// children: [ +// Row( +// mainAxisAlignment: MainAxisAlignment.spaceBetween, +// children: [ +// Column( +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// Texts( +// widget.model.lacumGroupInformation!.lakumInquiryInformationObjVersion!.memberName, +// fontSize: 13, +// fontWeight: FontWeight.bold, +// color: Colors.black, +// ), +// Texts( +// "${widget.model.lacumInformation!.yahalaAccountNo}", +// fontSize: 13, +// fontWeight: FontWeight.normal, +// color: Colors.black, +// ), +// ], +// ), +// BorderedButton( +// widget.model.lacumGroupInformation!.lakumInquiryInformationObjVersion!.accountStatus == "Active" +// ? TranslationBase.of(context).active +// : TranslationBase.of(context).inactive, +// textColor: widget.model.lacumInformation! +// .accountStatus == +// 1 +// ? Colors.green +// : Colors.red, +// hasBorder: true, +// borderColor: widget.model.lacumInformation! +// .accountStatus == +// 1 +// ? Colors.green +// : Colors.red, +// radius: 16, +// rPadding: 16, +// icon: widget.model.lacumInformation! +// .accountStatus == +// 1 +// ? Icon( +// Icons.check_circle, +// size: 25, +// color: Colors.green, +// ) +// : Image.asset( +// "assets/images/pharmacy_module/lakum/inactive_cross.png", +// fit: BoxFit.fill, +// width: 25, +// height: 25, +// ), +// ), +// ], +// ), +// SizedBox( +// height: 5, +// ), +// Row( +// mainAxisAlignment: MainAxisAlignment.spaceBetween, +// children: [ +// Column( +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// Texts(TranslationBase.of(context).identificationNumber, +// // "IDENTIFICATION #", +// fontSize: 13, +// fontWeight: FontWeight.bold, +// color: Colors.black, +// ), +// Texts( +// widget.model.lacumInformation! +// .identificationNo, +// fontSize: 13, +// fontWeight: FontWeight.normal, +// color: Colors.black, +// ), +// ], +// ), +// Column( +// crossAxisAlignment: CrossAxisAlignment.end, +// children: [ +// Texts(TranslationBase.of(context).MEMBERSINCE, +// // "MEMBER SINCE", +// fontSize: 13, +// fontWeight: FontWeight.bold, +// color: Colors.black, +// ), +// Texts( +// widget.model.formatCreatedDateToString(), +// fontSize: 13, +// fontWeight: FontWeight.normal, +// color: Colors.black, +// ), +// ], +// ), +// ], +// ), +// SizedBox( +// height: 5, +// ), +// Row( +// mainAxisAlignment: MainAxisAlignment.spaceBetween, +// children: [ +// Column( +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// Texts(TranslationBase.of(context).lakumMobile, +// // "MOBILE #", +// fontSize: 13, +// fontWeight: FontWeight.bold, +// color: Colors.black, +// ), +// Texts( +// widget.model.lacumGroupInformation!.lakumInquiryInformationObjVersion!.mobileNumber, +// fontSize: 13, +// fontWeight: FontWeight.normal, +// color: Colors.black, +// ), +// ], +// ), +// Column( +// crossAxisAlignment: CrossAxisAlignment.end, +// children: [ +// Texts( +// TranslationBase.of(context).language, +// fontSize: 13, +// fontWeight: FontWeight.bold, +// color: Colors.black, +// ), +// Texts( +// widget.model.lacumInformation!.prefLang == +// "2" +// ? TranslationBase.of(context).lanEnglish +// : TranslationBase.of(context).lanArabic, +// fontSize: 13, +// fontWeight: FontWeight.normal, +// color: Colors.black, +// ), +// ], +// ), +// ], +// ), +// ], +// ), +// ), +// ], +// ), +// ), +// widget.isLacumHomePage +// ? Container( +// decoration: BoxDecoration( +// shape: BoxShape.rectangle, +// borderRadius: BorderRadius.circular(4), +// border: Border.fromBorderSide(BorderSide( +// color: Colors.grey, +// width: 0.4, +// )), +// ), +// margin: EdgeInsets.symmetric(horizontal: 16), +// child: Stack( +// children: [ +// Image.asset( +// "assets/images/pharmacy_module/lakum/lakum_card_front_bg.png", +// fit: BoxFit.fill, +// width: widget.mediaQuery.size.width * 1.0, +// height: widget.mediaQuery.size.width * 1.0, +// ), +// Center( +// child: Container( +// margin: EdgeInsets.fromLTRB(5, 70, 5, 4), +// child: widget.model.convertBase64ToBarCodeImage() != +// null +// ? Image.memory( +// widget.model.convertBase64ToBarCodeImage(), +// fit: BoxFit.fill, +// height: 100.0, +// width: 180.0 +// ) +// : Container(), +// ), +// ), +// ], +// ), +// ) +// : Container(), +// ], +// ), widget.isLacumHomePage ? Positioned( bottom: 1, diff --git a/lib/pages/pharmacies/widgets/lakum-banner-widget.dart b/lib/pages/pharmacies/widgets/lakum-banner-widget.dart index 14a53e72..3fc5d14b 100644 --- a/lib/pages/pharmacies/widgets/lakum-banner-widget.dart +++ b/lib/pages/pharmacies/widgets/lakum-banner-widget.dart @@ -1,4 +1,4 @@ -import 'package:carousel_slider/carousel_slider.dart'; +// import 'package:carousel_slider/carousel_slider.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/lacum-viewmodel.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/borderedButton.dart'; @@ -24,225 +24,225 @@ class _LakumBannerWidgetState extends State { return Container( child: Stack( children: [ - CarouselSlider( - options: CarouselOptions( - enableInfiniteScroll: false, - enlargeCenterPage: false, - viewportFraction: 1.0, - scrollPhysics: widget.isLacumHomePage - ? ScrollPhysics() - : NeverScrollableScrollPhysics(), - initialPage: 0, - onPageChanged: (index, reason) { - setState(() { - _current = index; - }); - }, - ), - items: [ - Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(4), - border: Border.fromBorderSide(BorderSide( - color: Colors.grey, - width: 0.4, - )), - ), - margin: EdgeInsets.symmetric(horizontal: 16), - child: Stack( - children: [ - Image.asset( - "assets/images/pharmacy_module/lakum/lakum_card_front_bg.png", - fit: BoxFit.fill, - width: widget.mediaQuery.size.width * 1.0, - height: widget.mediaQuery.size.width * 1.0, - ), - Container( - margin: EdgeInsets.fromLTRB(12, 70, 12, 4), - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts( - widget.model.lacumGroupInformation.lakumInquiryInformationObjVersion.memberName, - fontSize: 14, - fontWeight: FontWeight.bold, - color: Colors.black, - ), - Texts( - "${widget.model.lacumInformation.yahalaAccountNo}", - fontSize: 16, - fontWeight: FontWeight.normal, - color: Colors.black, - ), - ], - ), - BorderedButton( - widget.model.lacumGroupInformation.lakumInquiryInformationObjVersion.accountStatus == "Active" - ? TranslationBase.of(context).active - : TranslationBase.of(context).inactive, - textColor: widget.model.lacumInformation - .accountStatus == - 1 - ? Colors.green - : Colors.red, - hasBorder: true, - borderColor: widget.model.lacumInformation - .accountStatus == - 1 - ? Colors.green - : Colors.red, - radius: 16, - rPadding: 16, - icon: widget.model.lacumInformation - .accountStatus == - 1 - ? Icon( - Icons.check_circle, - size: 25, - color: Colors.green, - ) - : Image.asset( - "assets/images/pharmacy_module/lakum/inactive_cross.png", - fit: BoxFit.fill, - width: 25, - height: 25, - ), - ), - ], - ), - SizedBox( - height: 10, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts( - "IDENTIFICATION #", - fontSize: 14, - fontWeight: FontWeight.bold, - color: Colors.black, - ), - Texts( - widget.model.lacumInformation - .identificationNo, - fontSize: 16, - fontWeight: FontWeight.normal, - color: Colors.black, - ), - ], - ), - Column( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Texts( - "MEMBER SINCE", - fontSize: 14, - fontWeight: FontWeight.bold, - color: Colors.black, - ), - Texts( - widget.model.formatCreatedDateToString(), - fontSize: 16, - fontWeight: FontWeight.normal, - color: Colors.black, - ), - ], - ), - ], - ), - SizedBox( - height: 10, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts( - "MOBILE #", - fontSize: 14, - fontWeight: FontWeight.bold, - color: Colors.black, - ), - Texts( - widget.model.lacumGroupInformation.lakumInquiryInformationObjVersion.mobileNumber, - fontSize: 16, - fontWeight: FontWeight.normal, - color: Colors.black, - ), - ], - ), - Column( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Texts( - TranslationBase.of(context).language, - fontSize: 14, - fontWeight: FontWeight.bold, - color: Colors.black, - ), - Texts( - widget.model.lacumInformation.prefLang == - "1" - ? TranslationBase.of(context).lanEnglish - : TranslationBase.of(context).lanArabic, - fontSize: 16, - fontWeight: FontWeight.normal, - color: Colors.black, - ), - ], - ), - ], - ), - ], - ), - ), - ], - ), - ), - widget.isLacumHomePage - ? Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(4), - border: Border.fromBorderSide(BorderSide( - color: Colors.grey, - width: 0.4, - )), - ), - margin: EdgeInsets.symmetric(horizontal: 16), - child: Stack( - children: [ - Image.asset( - "assets/images/pharmacy_module/lakum/lakum_card_front_bg.png", - fit: BoxFit.fill, - width: widget.mediaQuery.size.width * 1.0, - height: widget.mediaQuery.size.width * 1.0, - ), - Container( - margin: EdgeInsets.fromLTRB(12, 70, 12, 4), - child: widget.model.convertBase64ToBarCodeImage() != - null - ? Image.memory( - widget.model.convertBase64ToBarCodeImage()) - : Container(), - ), - ], - ), - ) - : Container(), - ], - ), + // CarouselSlider( + // options: CarouselOptions( + // enableInfiniteScroll: false, + // enlargeCenterPage: false, + // viewportFraction: 1.0, + // scrollPhysics: widget.isLacumHomePage + // ? ScrollPhysics() + // : NeverScrollableScrollPhysics(), + // initialPage: 0, + // onPageChanged: (index, reason) { + // setState(() { + // _current = index; + // }); + // }, + // ), + // items: [ + // Container( + // decoration: BoxDecoration( + // shape: BoxShape.rectangle, + // borderRadius: BorderRadius.circular(4), + // border: Border.fromBorderSide(BorderSide( + // color: Colors.grey, + // width: 0.4, + // )), + // ), + // margin: EdgeInsets.symmetric(horizontal: 16), + // child: Stack( + // children: [ + // Image.asset( + // "assets/images/pharmacy_module/lakum/lakum_card_front_bg.png", + // fit: BoxFit.fill, + // width: widget.mediaQuery.size.width * 1.0, + // height: widget.mediaQuery.size.width * 1.0, + // ), + // Container( + // margin: EdgeInsets.fromLTRB(12, 70, 12, 4), + // child: Column( + // children: [ + // Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + // children: [ + // Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // Texts( + // widget.model.lacumGroupInformation!.lakumInquiryInformationObjVersion!.memberName, + // fontSize: 14, + // fontWeight: FontWeight.bold, + // color: Colors.black, + // ), + // Texts( + // "${widget.model.lacumInformation!.yahalaAccountNo}", + // fontSize: 16, + // fontWeight: FontWeight.normal, + // color: Colors.black, + // ), + // ], + // ), + // BorderedButton( + // widget.model.lacumGroupInformation!.lakumInquiryInformationObjVersion!.accountStatus == "Active" + // ? TranslationBase.of(context).active + // : TranslationBase.of(context).inactive, + // textColor: widget.model.lacumInformation! + // .accountStatus! == + // 1 + // ? Colors.green + // : Colors.red, + // hasBorder: true, + // borderColor: widget.model.lacumInformation! + // .accountStatus == + // 1 + // ? Colors.green + // : Colors.red, + // radius: 16, + // rPadding: 16, + // icon: widget.model.lacumInformation! + // .accountStatus == + // 1 + // ? Icon( + // Icons.check_circle, + // size: 25, + // color: Colors.green, + // ) + // : Image.asset( + // "assets/images/pharmacy_module/lakum/inactive_cross.png", + // fit: BoxFit.fill, + // width: 25, + // height: 25, + // ), + // ), + // ], + // ), + // SizedBox( + // height: 10, + // ), + // Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + // children: [ + // Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // Texts( + // "IDENTIFICATION #", + // fontSize: 14, + // fontWeight: FontWeight.bold, + // color: Colors.black, + // ), + // Texts( + // widget.model.lacumInformation! + // .identificationNo, + // fontSize: 16, + // fontWeight: FontWeight.normal, + // color: Colors.black, + // ), + // ], + // ), + // Column( + // crossAxisAlignment: CrossAxisAlignment.end, + // children: [ + // Texts( + // "MEMBER SINCE", + // fontSize: 14, + // fontWeight: FontWeight.bold, + // color: Colors.black, + // ), + // Texts( + // widget.model.formatCreatedDateToString(), + // fontSize: 16, + // fontWeight: FontWeight.normal, + // color: Colors.black, + // ), + // ], + // ), + // ], + // ), + // SizedBox( + // height: 10, + // ), + // Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + // children: [ + // Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // Texts( + // "MOBILE #", + // fontSize: 14, + // fontWeight: FontWeight.bold, + // color: Colors.black, + // ), + // Texts( + // widget.model.lacumGroupInformation!.lakumInquiryInformationObjVersion!.mobileNumber, + // fontSize: 16, + // fontWeight: FontWeight.normal, + // color: Colors.black, + // ), + // ], + // ), + // Column( + // crossAxisAlignment: CrossAxisAlignment.end, + // children: [ + // Texts( + // TranslationBase.of(context).language, + // fontSize: 14, + // fontWeight: FontWeight.bold, + // color: Colors.black, + // ), + // Texts( + // widget.model.lacumInformation!.prefLang == + // "1" + // ? TranslationBase.of(context).lanEnglish + // : TranslationBase.of(context).lanArabic, + // fontSize: 16, + // fontWeight: FontWeight.normal, + // color: Colors.black, + // ), + // ], + // ), + // ], + // ), + // ], + // ), + // ), + // ], + // ), + // ), + // widget.isLacumHomePage + // ? Container( + // decoration: BoxDecoration( + // shape: BoxShape.rectangle, + // borderRadius: BorderRadius.circular(4), + // border: Border.fromBorderSide(BorderSide( + // color: Colors.grey, + // width: 0.4, + // )), + // ), + // margin: EdgeInsets.symmetric(horizontal: 16), + // child: Stack( + // children: [ + // Image.asset( + // "assets/images/pharmacy_module/lakum/lakum_card_front_bg.png", + // fit: BoxFit.fill, + // width: widget.mediaQuery.size.width * 1.0, + // height: widget.mediaQuery.size.width * 1.0, + // ), + // Container( + // margin: EdgeInsets.fromLTRB(12, 70, 12, 4), + // child: widget.model.convertBase64ToBarCodeImage() != + // null + // ? Image.memory( + // widget.model.convertBase64ToBarCodeImage()) + // : Container(), + // ), + // ], + // ), + // ) + // : Container(), + // ], + // ), widget.isLacumHomePage ? Positioned( bottom: 1, diff --git a/lib/pages/pharmacies/widgets/lakum-point-table-row-widget.dart b/lib/pages/pharmacies/widgets/lakum-point-table-row-widget.dart index 6e4e2309..4fb722e3 100644 --- a/lib/pages/pharmacies/widgets/lakum-point-table-row-widget.dart +++ b/lib/pages/pharmacies/widgets/lakum-point-table-row-widget.dart @@ -1,17 +1,15 @@ import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; -import 'package:diplomaticquarterapp/widgets/others/app_expandable_notifier.dart'; import 'package:diplomaticquarterapp/widgets/others/points-expandable-notifier.dart'; -import 'package:expandable/expandable.dart'; import 'package:flutter/material.dart'; class LakumPointTableRowWidget extends StatefulWidget { final bool isTableTitle; // true : title , false: row final String rowTitle; - final double points; - final double riyal; - final Function onTap; + final num points; + final num riyal; + final VoidCallback onTap; final int rowIndex; - final Widget collapsed; + final Widget? collapsed; final bool expandFlag; LakumPointTableRowWidget(this.isTableTitle, this.rowTitle, this.points, diff --git a/lib/pages/pharmacies/widgets/lakum_point_table_row_widget.dart b/lib/pages/pharmacies/widgets/lakum_point_table_row_widget.dart index bddd2e3b..757cf03a 100644 --- a/lib/pages/pharmacies/widgets/lakum_point_table_row_widget.dart +++ b/lib/pages/pharmacies/widgets/lakum_point_table_row_widget.dart @@ -1,7 +1,5 @@ import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; -import 'package:diplomaticquarterapp/widgets/others/app_expandable_notifier.dart'; import 'package:diplomaticquarterapp/widgets/others/points-expandable-notifier.dart'; -import 'package:expandable/expandable.dart'; import 'package:flutter/material.dart'; class LakumPointTableRowWidget extends StatefulWidget { @@ -9,9 +7,9 @@ class LakumPointTableRowWidget extends StatefulWidget { final String rowTitle; final double points; final double riyal; - final Function onTap; + final VoidCallback? onTap; final int rowIndex; - final Widget collapsed; + final Widget? collapsed; final bool expandFlag; LakumPointTableRowWidget(this.isTableTitle, this.rowTitle, this.points, @@ -27,7 +25,7 @@ class _LakumPointTableRowWidgetState extends State { @override Widget build(BuildContext context) { return InkWell( - onTap: widget.onTap, + onTap: widget.onTap!, child: Column( children: [ Column( diff --git a/lib/pages/pharmacies/widgets/manufacturerItem.dart b/lib/pages/pharmacies/widgets/manufacturerItem.dart index 574c37c5..739e90bc 100644 --- a/lib/pages/pharmacies/widgets/manufacturerItem.dart +++ b/lib/pages/pharmacies/widgets/manufacturerItem.dart @@ -1,4 +1,5 @@ import 'package:diplomaticquarterapp/core/model/pharmacies/Manufacturer.dart'; +import 'package:diplomaticquarterapp/widgets/text/app_texts_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; @@ -23,28 +24,33 @@ class ManufacturerItem extends StatelessWidget { ), ); }, - child: Card( - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + child: Container( + width: 100, margin: EdgeInsets.symmetric( - horizontal: 8, + horizontal: 12, vertical: 4, ), - child: Container( - decoration: BoxDecoration( - border: Border( - right: BorderSide(color: Colors.grey.shade300, width: 1), - bottom: BorderSide(color: Colors.grey.shade300, width: 1), - left: BorderSide(color: Colors.grey.shade300, width: 1), - top: BorderSide(color: Colors.grey.shade300, width: 1)), - ), - child: Padding( - padding: EdgeInsets.symmetric(horizontal: 8), - child: Image.network( - item.image.src, - fit: BoxFit.cover, - ), - ), + decoration: BoxDecoration( + borderRadius:BorderRadius.circular(12) , + border: Border( + right: BorderSide(color: Colors.grey.shade300, width: 1), + bottom: BorderSide(color: Colors.grey.shade300, width: 1), + left: BorderSide(color: Colors.grey.shade300, width: 1), + top: BorderSide(color: Colors.grey.shade300, width: 1)), ), + child: item.image == null + ? Container( + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 10), + alignment: Alignment.topCenter, + child: AppText(item.name!, fontWeight: FontWeight.w500,fontSize: 14,), + ) + : Padding( + padding: EdgeInsets.symmetric(horizontal: 8), + child: Image.network( + item.image!.src!, + fit: BoxFit.cover, + ), + ), ), ); } diff --git a/lib/pages/pharmacies/wishlist.dart b/lib/pages/pharmacies/wishlist.dart index 000e8404..d7a7df05 100644 --- a/lib/pages/pharmacies/wishlist.dart +++ b/lib/pages/pharmacies/wishlist.dart @@ -1,71 +1,68 @@ import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/wishlist_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/ProductCheckTypeWidget.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:flutter/material.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -class WishlistPage extends StatefulWidget { - bool showBar; - WishlistPage(this.showBar); - @override - _WishlistPageState createState() => _WishlistPageState(); -} - -class _WishlistPageState extends State { - bool isTrue = true; +class WishlistPage extends StatelessWidget { + const WishlistPage({Key? key}) : super(key: key); + @override Widget build(BuildContext context) { return BaseView( onModelReady: (model) => model.getWishlistData(), builder: (_, model, wi) => AppScaffold( - appBarTitle: 'Wishlist page', - isShowAppBar: widget.showBar, + appBarTitle: TranslationBase.of(context).wishlist, + isShowAppBar: true, isShowDecPage: false, isPharmacy: true, + showPharmacyCart: false, + showHomeAppBarIcon: false, + isBottomBar: true, baseViewModel: model, body: model.wishListList.length == 0 ? Container( - child: 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( - 'There is no data', - style: TextStyle(fontSize: 30), - ), - ) - ], + child: 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), + ), + ) + ], + ), + ), + ) : Container( - child: Column( - children: [ - Expanded( - flex: 20, - child: Container( - width: double.infinity, - height: - MediaQuery.of(context).size.height * 0.85, //250, - child: - ProductCheckTypeWidget(isTrue, model.wishListList), - ), - ), - ], + child: Column( + children: [ + Expanded( + flex: 20, + child: Container( + width: double.infinity, + height: MediaQuery.of(context).size.height * 0.85, //250, + child: ProductCheckTypeWidget(model: model,), ), ), + ], + ), + ), ), ); } } + diff --git a/lib/pages/pharmacy/order/Order.dart b/lib/pages/pharmacy/order/Order.dart index 2ba92674..09e9c8b7 100644 --- a/lib/pages/pharmacy/order/Order.dart +++ b/lib/pages/pharmacy/order/Order.dart @@ -1,6 +1,7 @@ import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/orders_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/order_model_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/pharmacy/order/OrderDetails.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; @@ -8,22 +9,23 @@ 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:provider/provider.dart'; dynamic languageID; class OrderPage extends StatefulWidget { // orderList({this.customerId, this.pageId}); - String customerID; + String? customerID; + String? customerGUID; - OrderPage({@required this.customerID}); + OrderPage({required this.customerID, this.customerGUID}); @override _OrderPageState createState() => _OrderPageState(); } -class _OrderPageState extends State - with SingleTickerProviderStateMixin { +class _OrderPageState extends State with SingleTickerProviderStateMixin { String pageID = "1"; String customerId = ""; String order = ""; @@ -36,7 +38,7 @@ class _OrderPageState extends State List cancelledOrderList = []; List pendingOrderList = []; - TabController _tabController; + TabController? _tabController; // AppSharedPreferences sharedPref = AppSharedPreferences(); getLanguageID() async { @@ -56,20 +58,24 @@ class _OrderPageState extends State @override Widget build(BuildContext context) { - print("customerID" + widget.customerID); return BaseView( - onModelReady: (model) => model.getOrder(widget.customerID, pageID), + onModelReady: (model) => + model.getOrder(widget.customerID, widget.customerGUID, pageID), builder: (_, model, wi) => AppScaffold( appBarTitle: TranslationBase.of(context).order, baseViewModel: model, isShowAppBar: true, isPharmacy: true, + showPharmacyCart: false, + showHomeAppBarIcon: false, + isBottomBar: true, body: Container( child: Column( children: [ 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), @@ -105,6 +111,8 @@ class _OrderPageState extends State } Widget getDeliveredOrder(OrderModelViewModel model) { + ProjectViewModel projectViewModel = Provider.of(context); + deliveredOrderList.clear(); for (int i = 0; i < model.orders.length; i++) { if (model.orders[i].orderStatusId == 30 || model.orders[i].orderStatusId == 997 || @@ -114,7 +122,7 @@ class _OrderPageState extends State } return Container( width: MediaQuery.of(context).size.width, - child: model.orders.length != 0 + child: deliveredOrderList.length != 0 ? SingleChildScrollView( child: Column( children: [ @@ -127,96 +135,99 @@ 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]), + )).then((value) { + model.getOrder(widget.customerID, + widget.customerGUID, pageID); + getDeliveredOrder(model); + }); + }, + 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]), - )); - }, - child: SvgPicture.asset( - languageID == "ar" - ? 'assets/images/pharmacy/arrow_left.svg' - : 'assets/images/pharmacy/arrow_right.svg', - height: 20, - width: 20, + Container( + margin: EdgeInsets.all(8.0), + child: Icon( + Icons.arrow_forward, + size: 18, + color: Colors.grey[500], ), ), - ), - ], + ], + ), ), Divider( color: Colors.grey[350], @@ -236,16 +247,24 @@ class _OrderPageState extends State left: 13.0, right: 13.0), decoration: BoxDecoration( border: Border.all( - color: Colors.blue[700], + color: Color(0xFF4CAF50), style: BorderStyle.solid, width: 5.0, ), - color: Colors.blue[700], - borderRadius: - BorderRadius.circular(30.0)), - child: deliveredOrderList[index] - .orderStatusId == - 30 + color: Color(0xFF4CAF50), + borderRadius: BorderRadius.circular( + 30.0)), + child: deliveredOrderList[ + index] + .orderStatusId == + 30 || + deliveredOrderList[index] + .orderStatusId == + 997 || + deliveredOrderList[index] + .orderStatusId == + 994 +// deliveredOrderList[index].orderStatusId == 30 ? Text( // deliveredOrderList[0].orderStatus.toString().substring(12), TranslationBase.of(context) @@ -370,6 +389,8 @@ class _OrderPageState extends State } Widget getProcessingOrder(OrderModelViewModel model) { + ProjectViewModel projectViewModel = Provider.of(context); + processingOrderList.clear(); for (int i = 0; i < model.orders.length; i++) { if (model.orders[i].orderStatusId == 20 || model.orders[i].orderStatusId == 995 || @@ -378,9 +399,10 @@ class _OrderPageState extends State processingOrderList.add(model.orders[i]); } } + _tabController!.index = 1; return Container( width: MediaQuery.of(context).size.width, - child: model.orders.length != 0 + child: processingOrderList.length != 0 ? SingleChildScrollView( child: Column( children: [ @@ -393,95 +415,103 @@ 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]))) + .then((value) { + model + .getOrder(widget.customerID, + widget.customerGUID, pageID) + .then((value) { + getProcessingOrder(model); + }); + }); + }, + 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]))); - }, - child: SvgPicture.asset( - languageID == "ar" - ? 'assets/images/pharmacy/arrow_left.svg' - : 'assets/images/pharmacy/arrow_right.svg', - height: 20, - width: 20, + Container( + margin: EdgeInsets.all(8.0), + child: Icon( + Icons.arrow_forward, + size: 18, + color: Colors.grey[500], ), ), - ), - ], + ], + ), ), Divider( color: Colors.grey[350], @@ -501,16 +531,27 @@ class _OrderPageState extends State left: 13.0, right: 13.0), decoration: BoxDecoration( border: Border.all( - color: Colors.green, + color: Colors.grey[500]!, style: BorderStyle.solid, width: 5.0, ), - color: Colors.green, - borderRadius: - BorderRadius.circular(30.0)), - child: processingOrderList[index] - .orderStatusId == - 20 + color: Colors.grey[500], + borderRadius: BorderRadius.circular( + 30.0)), + child: processingOrderList[ + index] + .orderStatusId == + 20 || + processingOrderList[index] + .orderStatusId == + 995 || + processingOrderList[index] + .orderStatusId == + 998 || + processingOrderList[index] + .orderStatusId == + 999 +// processingOrderList[index].orderStatusId == 20 ? Text( // deliveredOrderList[0].orderStatus.toString().substring(12), TranslationBase.of(context) @@ -814,13 +855,16 @@ class _OrderPageState extends State } Widget getPendingOrder(OrderModelViewModel model) { + ProjectViewModel projectViewModel = Provider.of(context); + pendingOrderList.clear(); for (int i = 0; i < model.orders.length; i++) { if (model.orders[i].orderStatusId == 10) { pendingOrderList.add(model.orders[i]); } } + _tabController!.animateTo(2); return Container( - child: model.orders.length != 0 + child: pendingOrderList.length != 0 ? SingleChildScrollView( child: Column( children: [ @@ -834,97 +878,105 @@ 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]))) + .then((value) { + model + .getOrder(widget.customerID, + widget.customerGUID, pageID) + .then((value) { + getPendingOrder(model); + }); + }); + }, + 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]))); - }, - child: SvgPicture.asset( - languageID == "ar" - ? 'assets/images/pharmacy/arrow_left.svg' - : 'assets/images/pharmacy/arrow_right.svg', - height: 20, - width: 20, + Container( + margin: EdgeInsets.all(8.0), + child: Icon( + Icons.arrow_forward, + size: 18, + color: Colors.grey[500], ), ), - ), - ], + ], + ), ), Divider( color: Colors.grey[350], @@ -943,7 +995,7 @@ class _OrderPageState extends State left: 13.0, right: 13.0), decoration: BoxDecoration( border: Border.all( - color: Colors.orange[300], + color: Colors.orange[300]!, style: BorderStyle.solid, width: 5.0, ), @@ -1081,15 +1133,17 @@ class _OrderPageState extends State } Widget getCancelledOrder(OrderModelViewModel model) { + ProjectViewModel projectViewModel = Provider.of(context); + cancelledOrderList.clear(); for (int i = 0; i < model.orders.length; i++) { if (model.orders[i].orderStatusId == 40 || - model.orders[i].orderStatus == 996 || + model.orders[i].orderStatusId == 996 || model.orders[i].orderStatusId == 200) { cancelledOrderList.add(model.orders[i]); } } return Container( - child: model.orders.length != 0 + child: cancelledOrderList.length != 0 ? SingleChildScrollView( child: Column( children: [ @@ -1103,97 +1157,98 @@ 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]))); - }, - child: SvgPicture.asset( - languageID == "ar" - ? 'assets/images/pharmacy/arrow_left.svg' - : 'assets/images/pharmacy/arrow_right.svg', - height: 20, - width: 20, + Container( + margin: EdgeInsets.all(8.0), + child: Icon( + Icons.arrow_forward, + size: 18, + color: Colors.grey[500], ), ), - ), - ], + ], + ), ), Divider( color: Colors.grey[350], @@ -1216,7 +1271,7 @@ class _OrderPageState extends State left: 10.0, right: 10.0), decoration: BoxDecoration( border: Border.all( - color: Colors.red[900], + color: Colors.red[900]!, style: BorderStyle.solid, width: 5.0, ), @@ -1360,5 +1415,5 @@ class _OrderPageState extends State class Test { static const values = {"1": 1, "2": 2, "3": 3}; - int operator [](String key) => values[key]; + int operator [](String key) => values[key]!; } diff --git a/lib/pages/pharmacy/order/OrderDetails.dart b/lib/pages/pharmacy/order/OrderDetails.dart index 2f113e50..e773f586 100644 --- a/lib/pages/pharmacy/order/OrderDetails.dart +++ b/lib/pages/pharmacy/order/OrderDetails.dart @@ -2,13 +2,14 @@ import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/order_detail.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/orders_model.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/pharmacy/order/Order.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets//pharmacy/product_tile.dart'; -import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; @@ -16,13 +17,14 @@ import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:flutter/src/widgets/image.dart' as flutterImage; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:provider/provider.dart'; dynamic languageID; class OrderDetailsPage extends StatefulWidget { Orders orderModel; - OrderDetailsPage({@required this.orderModel}); + OrderDetailsPage({required this.orderModel}); // Orders orderModel; // OrderModel orderModelDetails; @@ -38,7 +40,7 @@ class _OrderDetailsPageState extends State { } // AppSharedPreferences sharedPref = AppSharedPreferences(); - String customerId; + late String customerId; List ordersList = []; List cancelledOrderList = []; @@ -50,9 +52,9 @@ class _OrderDetailsPageState extends State { var isActiveDelivery = false; var dataIsCancel; var dataIsRefund; - BuildContext context; + late BuildContext context; - MyInAppBrowser browser; + MyInAppBrowser? browser; @override void initState() { @@ -61,19 +63,20 @@ class _OrderDetailsPageState extends State { // print(widget.orderModel.orderItems.length); getCancelOrder(widget.orderModel.id); - print("ID is" + widget.orderModel.id); + print("ID is" + widget.orderModel.id!); // cancelOrderDetail(order) } @override Widget build(BuildContext context) { + ProjectViewModel projectProvider = Provider.of(context); + ProjectViewModel projectViewModel = Provider.of(context); this.context = context; return BaseView( onModelReady: (model) { - model.getOrderDetails(widget.orderModel.id).then((value) { + model.getOrderDetails(widget.orderModel.id, widget.orderModel.orderGuid).then((value) { setState(() { - isActiveDelivery = (value.orderStatusId == 995 && - (value.driverID != null && value.driverID.isNotEmpty)); + isActiveDelivery = (value.orderStatusId == 995 && (value.driverID != null && value.driverID!.isNotEmpty)); }); }); }, @@ -81,6 +84,9 @@ class _OrderDetailsPageState extends State { appBarTitle: TranslationBase.of(context).orderDetail, isShowAppBar: true, isPharmacy: true, + showPharmacyCart: false, + showHomeAppBarIcon: false, + isBottomBar: true, baseViewModel: model, body: model.orderListModel.length > 0 ? Container( @@ -111,85 +117,90 @@ class _OrderDetailsPageState extends State { ), ), Container( - margin: EdgeInsets.only(top: 15.0, right: 10.0), - padding: EdgeInsets.only(left: 11.0, right: 11.0), - decoration: BoxDecoration( - border: Border.all( + margin: EdgeInsets.only(top: 15.0, right: 10.0), + padding: EdgeInsets.only(left: 11.0, right: 11.0), + decoration: BoxDecoration( + border: Border.all( + color: getStatusBackgroundColor()!, + style: BorderStyle.solid, + width: 5.0, + ), color: getStatusBackgroundColor(), - style: BorderStyle.solid, - width: 5.0, - ), - color: getStatusBackgroundColor(), - borderRadius: BorderRadius.circular(30.0)), - child: Text( - languageID == "ar" - ? model.orderListModel[0].orderStatusn - : model.orderListModel[0].orderStatus, -// TranslationBase.of(context).delivered, - style: TextStyle( - color: Colors.white, - fontSize: 13.0, - fontWeight: FontWeight.bold, + borderRadius: BorderRadius.circular(30.0)), + child: model.orderListModel[0].orderStatusId == 30 || model.orderListModel[0].orderStatusId == 997 || model.orderListModel[0].orderStatusId == 994 +// deliveredOrderList[index].orderStatusId == 30 + ? Text( +// deliveredOrderList[0].orderStatus.toString().substring(12), + TranslationBase.of(context).deliveredOrder, + style: TextStyle( + color: Colors.white, + fontSize: 15.0, + fontWeight: FontWeight.bold, + ), + ) + : Text( + projectProvider.isArabic ? model.orderListModel[0].orderStatusn.toString() : model.orderListModel[0].orderStatus.toString(), + style: TextStyle( + color: Colors.white, + fontSize: 13.0, + fontWeight: FontWeight.bold, + ), + ) +// Text( +// languageID == "ar" +// ? model.orderListModel[0].orderStatusn +// : model.orderListModel[0].orderStatus, +//// TranslationBase.of(context).delivered, +// style: TextStyle( +// color: Colors.white, +// fontSize: 13.0, +// fontWeight: FontWeight.bold, +// ), +// ), ), - ), - ), ], ), Container( margin: EdgeInsets.only(left: 10.0, top: 13.0), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - "${model.orderListModel[0].shippingAddress.firstName} ${model.orderListModel[0].shippingAddress.lastName}", - style: TextStyle( - fontSize: 15.0, - fontWeight: FontWeight.bold, - ), - ), - ]), + child: Row(crossAxisAlignment: CrossAxisAlignment.start, children: [ + Text( + "${model.orderListModel[0].shippingAddress!.firstName} ${model.orderListModel[0].shippingAddress!.lastName}", + style: TextStyle( + fontSize: 15.0, + fontWeight: FontWeight.bold, + ), + ), + ]), ), Container( margin: EdgeInsets.fromLTRB(10.0, 5.0, 1.0, 5.0), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - model.orderListModel[0].shippingAddress.address1 - .toString() - , - style: TextStyle( - fontSize: 10.0, - fontWeight: FontWeight.bold, - color: Colors.grey, - ), - ), - ]), + child: Row(crossAxisAlignment: CrossAxisAlignment.start, children: [ + Text( + model.orderListModel[0].shippingAddress!.address1.toString(), + style: TextStyle( + fontSize: 10.0, + fontWeight: FontWeight.bold, + color: Colors.grey, + ), + ), + ]), ), Container( margin: EdgeInsets.fromLTRB(10.0, 5.0, 1.0, 5.0), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - model.orderListModel[0].shippingAddress.address2 - .toString() - + - ' ' + - model.orderListModel[0].shippingAddress - .country - .toString() + - ' ' + - model.orderListModel[0].shippingAddress - .zipPostalCode - .toString(), - style: TextStyle( - fontSize: 10.0, - fontWeight: FontWeight.bold, - color: Colors.grey, - ), - ), - ]), + child: Row(crossAxisAlignment: CrossAxisAlignment.start, children: [ + Text( + model.orderListModel[0].shippingAddress!.address2.toString() + + ' ' + + model.orderListModel[0].shippingAddress!.country.toString() + + ' ' + + model.orderListModel[0].shippingAddress!.zipPostalCode.toString(), + style: TextStyle( + fontSize: 10.0, + fontWeight: FontWeight.bold, + color: Colors.grey, + ), + ), + ]), ), Container( child: Row( @@ -204,9 +215,7 @@ class _OrderDetailsPageState extends State { Container( margin: EdgeInsets.only(top: 5.0, bottom: 5.0), child: Text( - model.orderListModel[0].shippingAddress - .phoneNumber - .toString(), + model.orderListModel[0].shippingAddress!.phoneNumber.toString(), style: TextStyle( fontSize: 15.0, ), @@ -244,13 +253,10 @@ class _OrderDetailsPageState extends State { ), Container( child: flutterImage.Image.asset( - model.orderListModel[0] - .shippingRateComputationMethodSystemName != - "Shipping.Aramex" + model.orderListModel[0].shippingRateComputationMethodSystemName != "Shipping.Aramex" ? "assets/images/pharmacy_module/payment/LogoParmacyGreen.png" : "assets/images/pharmacy_module/payment/aramex_shipping_logo.png", fit: BoxFit.contain, -// height: 100, width: 100, ), ), @@ -297,9 +303,7 @@ class _OrderDetailsPageState extends State { Container( margin: EdgeInsets.only(bottom: 10.0, top: 10.0), child: Text( - model.orderListModel[0].paymentName - .toString() - .substring(12), + model.orderListModel[0].paymentName.toString(), style: TextStyle( fontSize: 13.0, fontWeight: FontWeight.bold, @@ -335,22 +339,24 @@ class _OrderDetailsPageState extends State { scrollDirection: Axis.vertical, shrinkWrap: true, physics: ScrollPhysics(), - itemCount: model.orderListModel[0].orderItems.length, + itemCount: model.orderListModel[0].orderItems!.length, itemBuilder: (context, index) { return Container( child: productTile( - productName: model.orderListModel[0].orderItems[index].product.name.toString(), - productPrice: model.orderListModel[0].orderItems[index].product.price.toString(), - productRate: model.orderListModel[0].orderItems[index].product.approvedRatingSum.toDouble(), - productReviews: model.orderListModel[0].orderItems[index].product.approvedTotalReviews, - totalPrice: "${(model.orderListModel[0].orderItems[index].product.price * model.orderListModel[0].orderItems[index].quantity).toStringAsFixed(2)}", - qyt: model.orderListModel[0].orderItems[index].quantity.toString(), + productName: projectViewModel.isArabic ? + model.orderListModel[0].orderItems![index].product!.namen.toString() + :model.orderListModel[0].orderItems![index].product!.name.toString(), + productPrice: model.orderListModel[0].orderItems![index!].product!.price!.toString(), + productRate: model.orderListModel[0].orderItems![index].product!.approvedRatingSum!.toDouble(), + productReviews: model.orderListModel[0].orderItems![index].product!.approvedTotalReviews, + totalPrice: "${(model.orderListModel[0].orderItems![index].product!.price! * model.orderListModel![0].orderItems![index].quantity!).toStringAsFixed(2)}", + qyt: model.orderListModel[0].orderItems![index].quantity.toString(), isOrderDetails: true, - imgs: model.orderListModel[0].orderItems[index].product.images != null && - model.orderListModel[0].orderItems[index].product.images.length != 0 - ? model.orderListModel[0].orderItems[index].product.images[0].src.toString() : null, + imgs: model.orderListModel[0].orderItems![index].product!.images != null && model.orderListModel[0].orderItems![index].product!.images!.length != 0 + ? model.orderListModel[0].orderItems![index].product!.images![0].src.toString() + : null, status: model.orderListModel[0].orderStatusId, - product: model.orderListModel[0].orderItems[index].product, + product: model.orderListModel[0].orderItems![index].product, ), ); }), @@ -399,8 +405,7 @@ class _OrderDetailsPageState extends State { ), ), Text( - model.orderListModel[0].orderSubtotalExclTax - .toString(), + model.orderListModel[0].orderSubtotalExclTax.toString(), style: TextStyle( fontSize: 13.0, ), @@ -438,8 +443,7 @@ class _OrderDetailsPageState extends State { ), ), Text( - model.orderListModel[0].orderShippingExclTax - .toString(), + model.orderListModel[0].orderShippingExclTax.toString(), style: TextStyle( fontSize: 13.0, ), @@ -529,27 +533,16 @@ class _OrderDetailsPageState extends State { model.orderListModel[0].orderStatusId == 10 ? InkWell( onTap: () { - print(widget.orderModel.toString()); - print(model.orderListModel.toString()); - print("calc = ${5.9 * 3}"); - // TODO MOSA - openPayment( - model.orderListModel[0], model.user); + openPayment(model.orderListModel[0], model.user!); }, child: Container( -// margin: EdgeInsets.only(top: 20.0), + padding: EdgeInsets.only(left: 10.0, right: 10.0), height: 50.0, color: Colors.transparent, child: Container( - padding: EdgeInsets.only( - left: 130.0, right: 130.0), - decoration: BoxDecoration( - border: Border.all( - color: Colors.green, - style: BorderStyle.solid, - width: 4.0), - color: Colors.green, - borderRadius: BorderRadius.circular(5.0)), + padding: EdgeInsets.only(left: 130.0, right: 130.0), + decoration: + BoxDecoration(border: Border.all(color: Colors.green, style: BorderStyle.solid, width: 4.0), color: Colors.green, borderRadius: BorderRadius.circular(5.0)), child: Center( child: Text( TranslationBase.of(context).payOnline, @@ -567,10 +560,7 @@ class _OrderDetailsPageState extends State { isCancel ? InkWell( onTap: () { - presentConfirmDialog( - model, widget.orderModel.id); - // model.orderListModel[0].id//(widget.orderModel.id)); -// + presentConfirmDialog(model, widget.orderModel.id); }, child: Container( // padding: EdgeInsets.only(left: 13.0, right: 13.0, top: 5.0), @@ -579,10 +569,7 @@ class _OrderDetailsPageState extends State { child: Center( child: Text( TranslationBase.of(context).cancelOrder, - style: TextStyle( - color: Colors.red[900], - fontWeight: FontWeight.bold, - decoration: TextDecoration.underline), + style: TextStyle(color: Colors.red[900], fontWeight: FontWeight.bold, decoration: TextDecoration.underline), ), ), ), @@ -601,12 +588,8 @@ class _OrderDetailsPageState extends State { color: Colors.transparent, child: Center( child: Text( - TranslationBase.of(context) - .trackDeliveryDriver, - style: TextStyle( - color: Colors.green[900], - fontWeight: FontWeight.normal, - decoration: TextDecoration.none), + TranslationBase.of(context).trackDeliveryDriver, + style: TextStyle(color: Colors.green[900], fontWeight: FontWeight.normal, decoration: TextDecoration.none), ), ), ), @@ -621,37 +604,30 @@ class _OrderDetailsPageState extends State { ); } - Color getStatusBackgroundColor() { + Color? getStatusBackgroundColor() { print(widget.orderModel.orderStatusId); // if(orderStatus == 'delivered') - if (widget.orderModel.orderStatusId == 30 || - widget.orderModel.orderStatusId == 997 || - widget.orderModel.orderStatusId == 994) - return Colors.blue[700]; - else if (widget.orderModel.orderStatusId == 20 || - widget.orderModel.orderStatusId == 995 || - widget.orderModel.orderStatusId == 998 || - widget.orderModel.orderStatusId == 999) - return Colors.green; + if (widget.orderModel.orderStatusId == 30 || widget.orderModel.orderStatusId == 997 || widget.orderModel.orderStatusId == 994) + return Color(0xFF4CAF50); + else if (widget.orderModel.orderStatusId == 20 || widget.orderModel.orderStatusId == 995 || widget.orderModel.orderStatusId == 998 || widget.orderModel.orderStatusId == 999) + return Colors.grey[500]!; else if (widget.orderModel.orderStatusId == 10) - return Colors.orange[300]; - else if (widget.orderModel.orderStatusId == 40 || - widget.orderModel.orderStatusId == 996 || - widget.orderModel.orderStatusId == 200) return Colors.red[900]; + return Colors.orange[300]!; + else if (widget.orderModel.orderStatusId == 40 || widget.orderModel.orderStatusId == 996 || widget.orderModel.orderStatusId == 200) return Colors.red[900]!; } getCancelOrder(dataIsCancel) { - if (widget.orderModel.canCancel && widget.orderModel.canRefund) { + if (widget.orderModel.canCancel! && widget.orderModel.canRefund!) { setState(() { isCancel = true; isRefund = false; }); - } else if (widget.orderModel.canCancel) { + } else if (widget.orderModel.canCancel!) { setState(() { isCancel = true; isRefund = false; }); - } else if (widget.orderModel.canRefund) { + } else if (widget.orderModel.canRefund!) { setState(() { isCancel = false; isRefund = true; @@ -671,26 +647,19 @@ class _OrderDetailsPageState extends State { confirmMessage: TranslationBase.of(context).confirmCancellation, okText: TranslationBase.of(context).confirm, cancelText: TranslationBase.of(context).cancel_nocaps, - okFunction: () => - cancelFunction.getCanceledOrder(id, context).then((value) { - print(":D"); - print(value); -// Navigator.pop(context); - Navigator.push( - context, - FadePage( - page: OrderPage( -// customerID: model.ordersList[0].customerId.toString() - customerID: widget.orderModel.customerId.toString())), - ); - }), + okFunction: () { + Navigator.pop(context); + cancelFunction.getCanceledOrder(id, context).then((value) { + Navigator.pop(context); + }); + }, cancelFunction: () => {}); dialog.showAlertDialog(context); } getCanceledOrder(order) { Navigator.pop(context); - if (widget.orderModel.canCancel && widget.orderModel.canRefund == false) { + if (widget.orderModel.canCancel! && widget.orderModel.canRefund == false) { // getCanceledOrder(order); // AppToast.showSuccessToast(message: "Request Sent Successfully"); // Navigator.push(context, @@ -699,29 +668,14 @@ class _OrderDetailsPageState extends State { } } - /*** - * - * Online payment methods - */ - openPayment( OrderDetailModel order, AuthenticatedUser authenticatedUser, ) { - browser = new MyInAppBrowser( - onExitCallback: onBrowserExit, onLoadStartCallback: onBrowserLoadStart); + browser = new MyInAppBrowser(onExitCallback: onBrowserExit, onLoadStartCallback: onBrowserLoadStart); - browser.openPharmacyPaymentBrowser( - order, - order.orderTotal, - 'ePharmacy Order', - order.id, - order.billingAddress.email, - order.customValuesXml, - "${authenticatedUser.firstName} ${authenticatedUser.middleName} ${authenticatedUser.lastName}", - authenticatedUser.patientID, - authenticatedUser, - browser); + browser?.openPharmacyPaymentBrowser(order, order.orderTotal, 'ePharmacy Order', order.id!, order.billingAddress!.email!, order.customValuesXml!, + "${authenticatedUser.firstName} ${authenticatedUser.middleName} ${authenticatedUser.lastName}", authenticatedUser.patientID, authenticatedUser, browser!); } onBrowserLoadStart(String url) { @@ -730,7 +684,7 @@ class _OrderDetailsPageState extends State { MyInAppBrowser.successURLS.forEach((element) { if (url.contains(element)) { - if (browser.isOpened()) browser.close(); + if (browser!.isOpened()) browser!.close(); MyInAppBrowser.isPaymentDone = true; return; } @@ -738,7 +692,7 @@ class _OrderDetailsPageState extends State { MyInAppBrowser.errorURLS.forEach((element) { if (url.contains(element)) { - if (browser.isOpened()) browser.close(); + if (browser!.isOpened()) browser!.close(); MyInAppBrowser.isPaymentDone = false; return; } @@ -748,14 +702,11 @@ class _OrderDetailsPageState extends State { onBrowserExit(AppoitmentAllHistoryResultList appo, bool isPaymentMade) { print("onBrowserExit Called!!!!"); if (isPaymentMade) { - AppToast.showSuccessToast( - message: "شكراً\nPayment status for your order is Paid"); + AppToast.showSuccessToast(message: "شكراً\nPayment status for your order is Paid"); Navigator.pop(context); Navigator.pop(context); } else { - AppToast.showErrorToast( - message: - "Transaction Failed!\Your transaction is field to some reason please try again or contact to the administration"); + AppToast.showErrorToast(message: "Transaction Failed!\Your transaction is field to some reason please try again or contact to the administration\فشلت العملية حاول مره اخرى"); } } } diff --git a/lib/pages/pharmacy/order/ProductReview.dart b/lib/pages/pharmacy/order/ProductReview.dart index 7f58fa21..6e086f34 100644 --- a/lib/pages/pharmacy/order/ProductReview.dart +++ b/lib/pages/pharmacy/order/ProductReview.dart @@ -2,15 +2,14 @@ import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart' import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/order_model_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/pharmacy/profile/profile.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'; import 'package:flutter/material.dart'; -import 'package:diplomaticquarterapp/core/model/pharmacies/order_model.dart'; -import 'package:flutter_svg/svg.dart'; -import 'package:intl/intl.dart'; -import 'package:rating_bar/rating_bar.dart'; import 'package:flutter/src/widgets/image.dart' as flutterImage; +import 'package:flutter_rating_bar/flutter_rating_bar.dart'; +import 'package:flutter_svg/svg.dart'; class ProductReviewPage extends StatefulWidget { final PharmacyProduct product; @@ -36,6 +35,9 @@ class _ProductReviewPageState extends State { appBarTitle: TranslationBase.of(context).writeReview, isShowAppBar: true, isPharmacy: true, + showPharmacyCart: false, + showHomeAppBarIcon: false, + isBottomBar: true, body: Container( color: Colors.white, child: !finishReview ? SingleChildScrollView( @@ -48,7 +50,7 @@ class _ProductReviewPageState extends State { children: [ widget.product.images != null ? flutterImage.Image.network( - widget.product.images[0].src, + widget.product.images![0]!.src!, fit: BoxFit.cover, height: 80, ) @@ -98,16 +100,39 @@ class _ProductReviewPageState extends State { Container( child: Align( alignment: Alignment.topLeft, - child: RatingBar.readOnly( + child: + + // RatingBar.readOnly( + // initialRating: ratingValue, + // size: 15.0, + // filledColor: Colors.yellow[700], + // emptyColor: Colors.grey[500], + // isHalfAllowed: true, + // halfFilledIcon: Icons.star_half, + // filledIcon: Icons.star, + // emptyIcon: Icons.star, + // ), + // + // + RatingBar( initialRating: ratingValue, - size: 15.0, - filledColor: Colors.yellow[700], - emptyColor: Colors.grey[500], - isHalfAllowed: true, - halfFilledIcon: Icons.star_half, - filledIcon: Icons.star, - emptyIcon: Icons.star, - ), + direction: Axis.horizontal, + allowHalfRating: true, + itemCount: 5, + itemSize: 20, + ignoreGestures: true, + ratingWidget: RatingWidget( + full: Icon(Icons.star, color: CustomColors.accentColor,), + half: Icon(Icons.star_half, color: CustomColors.accentColor,), + empty: Icon(Icons.star, color: CustomColors.accentColor,), + ), + tapOnlyMode: true, + unratedColor: Colors.grey[500], + itemPadding: EdgeInsets.symmetric(horizontal: 4.0), + onRatingUpdate: (rating) { + print(rating); + }, + ) ), ), SizedBox( @@ -118,7 +143,7 @@ class _ProductReviewPageState extends State { child: RichText( text: TextSpan( text: - '(${widget.product.approvedTotalReviews} reviews)', + '(${widget.product.approvedTotalReviews} ${TranslationBase.of(context).reviews})', style: TextStyle( fontWeight: FontWeight.bold, color: Colors.grey, @@ -149,18 +174,39 @@ class _ProductReviewPageState extends State { mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisSize: MainAxisSize.max, children: [ + // RatingBar( + // size: 40.0, + // filledColor: Colors.yellow[700], + // emptyColor: Colors.grey[500], + // isHalfAllowed: true, + // halfFilledIcon: Icons.star_half, + // filledIcon: Icons.star, + // emptyIcon: Icons.star, + // onRatingChanged: (rating) { + // currentRating = rating; + // }, + // ), + RatingBar( - size: 40.0, - filledColor: Colors.yellow[700], - emptyColor: Colors.grey[500], - isHalfAllowed: true, - halfFilledIcon: Icons.star_half, - filledIcon: Icons.star, - emptyIcon: Icons.star, - onRatingChanged: (rating) { - currentRating = rating; + initialRating: ratingValue, + direction: Axis.horizontal, + allowHalfRating: true, + itemCount: 5, + itemSize: 20, + ignoreGestures: true, + ratingWidget: RatingWidget( + full: Icon(Icons.star, color: CustomColors.accentColor,), + half: Icon(Icons.star_half, color: CustomColors.accentColor,), + empty: Icon(Icons.star, color: CustomColors.accentColor,), + ), + tapOnlyMode: true, + unratedColor: Colors.grey[500], + itemPadding: EdgeInsets.symmetric(horizontal: 4.0), + onRatingUpdate: (rating) { + print(rating); }, - ), + ) + ], ), ), @@ -178,13 +224,13 @@ class _ProductReviewPageState extends State { focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(5.0), borderSide: - BorderSide(width: 1, color: Colors.grey[400]), + BorderSide(width: 1, color: Colors.grey[400]!), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(5.0)), borderSide: - BorderSide(color: Colors.grey[400], width: 1), + BorderSide(color: Colors.grey[400]!, width: 1), ), ), onChanged: (value) { @@ -219,9 +265,9 @@ class _ProductReviewPageState extends State { child: Container( decoration: BoxDecoration( border: Border.all( - color: _reviewController.value.text != null && - _reviewController.value.text != "" - ? Colors.yellow[700] + color: _reviewController!.value.text! != null && + _reviewController!.value.text! != "" + ? Colors.yellow[700]! : Color(0xFFf5d69c), style: BorderStyle.solid, width: 1.0), @@ -326,41 +372,41 @@ class _ProductReviewPageState extends State { ], ), ), - Container( - margin: EdgeInsets.only(top: 20.0), - child: InkWell( - onTap: () { - Navigator.push( - context, - MaterialPageRoute(builder: (context) { - return PharmacyProfilePage(); - }), - ); - }, - child: Container( - height: 50.0, - color: Colors.transparent, - child: Container( - decoration: BoxDecoration( - border: Border.all( - color: Colors.orange, - style: BorderStyle.solid, - width: 1.0), - color: Colors.transparent, - borderRadius: BorderRadius.circular(5.0)), - child: Center( - child: Text( - TranslationBase.of(context).backMyAccount, - style: TextStyle( - color: Colors.orange, - fontWeight: FontWeight.bold, - ), - ), - ), - ), - ), - ), - ), + // Container( + // margin: EdgeInsets.only(top: 20.0), + // child: InkWell( + // onTap: () { + // Navigator.push( + // context, + // MaterialPageRoute(builder: (context) { + // return PharmacyProfilePage(moveToOrder: true); + // }), + // ); + // }, + // child: Container( + // height: 50.0, + // color: Colors.transparent, + // child: Container( + // decoration: BoxDecoration( + // border: Border.all( + // color: Colors.orange, + // style: BorderStyle.solid, + // width: 1.0), + // color: Colors.transparent, + // borderRadius: BorderRadius.circular(5.0)), + // child: Center( + // child: Text( + // TranslationBase.of(context).backMyAccount, + // style: TextStyle( + // color: Colors.orange, + // fontWeight: FontWeight.bold, + // ), + // ), + // ), + // ), + // ), + // ), + // ), ], ); } diff --git a/lib/pages/pharmacy/order/TrackDriver.dart b/lib/pages/pharmacy/order/TrackDriver.dart index 587ba9a6..21b2572f 100644 --- a/lib/pages/pharmacy/order/TrackDriver.dart +++ b/lib/pages/pharmacy/order/TrackDriver.dart @@ -1,344 +1,341 @@ -import 'dart:async'; -import 'dart:typed_data'; -import 'dart:ui' as ui; - -import 'package:async/async.dart'; -import 'package:diplomaticquarterapp/config/config.dart'; -import 'package:diplomaticquarterapp/core/model/pharmacies/order_detail.dart'; -import 'package:diplomaticquarterapp/core/model/pharmacies/order_model.dart'; -import 'package:diplomaticquarterapp/core/service/parmacyModule/order-preview-service.dart'; -import 'package:diplomaticquarterapp/locator.dart'; -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:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter_animarker/lat_lng_interpolation.dart'; -import 'package:flutter_animarker/models/lat_lng_delta.dart'; -import 'package:flutter_animarker/models/lat_lng_info.dart'; -import 'package:flutter_polyline_points/flutter_polyline_points.dart'; -import 'package:geolocator/geolocator.dart'; -import 'package:google_maps_flutter/google_maps_flutter.dart'; -import 'package:location/location.dart'; -import 'package:flutter_animarker/streams/lat_lng_stream.dart'; - -class TrackDriver extends StatefulWidget { - final OrderDetailModel order; - TrackDriver({this.order}); - - @override - State createState() => _TrackDriverState(); -} - -class _TrackDriverState extends State { - OrderPreviewService _orderServices = locator(); - OrderDetailModel _order; - - Completer _controller = Completer(); - - - double CAMERA_ZOOM = 14; - double CAMERA_TILT = 0; - double CAMERA_BEARING = 30; - LatLng SOURCE_LOCATION = null; - LatLng DEST_LOCATION = null; - - // for my drawn routes on the map - Set _polylines = Set(); - List polylineCoordinates = []; - PolylinePoints polylinePoints; - - Set _markers = Set(); - - BitmapDescriptor sourceIcon; // for my custom marker pins - BitmapDescriptor destinationIcon; // for my custom marker pins - Location location;// wrapper around the location API - - - int locationUpdateFreq = 2; - LatLngInterpolationStream _latLngStream; - StreamGroup subscriptions; - - @override - void initState() { - super.initState(); - - _order = widget.order; - DEST_LOCATION = _order.shippingAddress.getLocation(); - location = new Location(); - polylinePoints = PolylinePoints(); - setSourceAndDestinationIcons(); - - initMarkerUpdateStream(); - startUpdatingDriverLocation(); - - } - - @override - void dispose() { - super.dispose(); - subscriptions.close(); - _latLngStream.cancel(); - stopUpdatingDriverLocation(); - } - - initMarkerUpdateStream(){ - _latLngStream = LatLngInterpolationStream(movementDuration: Duration(seconds: locationUpdateFreq+1)); - subscriptions = StreamGroup(); - - subscriptions.add(_latLngStream.getAnimatedPosition('sourcePin')); - subscriptions.stream.listen((LatLngDelta delta) { - //Update the marker with animation - setState(() { - //Get the marker Id for this animation - var markerId = MarkerId(delta.markerId); - Marker sourceMarker = Marker( - markerId: markerId, - // rotation: delta.rotation, - icon: sourceIcon, - position: LatLng( - delta.from.latitude, - delta.from.longitude, - ), - onTap: onSourceMarkerTap - ); - - _markers.removeWhere((m) => m.markerId.value == 'sourcePin'); - _markers.add(sourceMarker); - }); - }); - } - - @override - Widget build(BuildContext context) { - - return AppScaffold( - appBarTitle: TranslationBase.of(context).deliveryDriverTrack, - isShowAppBar: true, - isPharmacy: true, - showPharmacyCart: false, - showHomeAppBarIcon: false, - body: GoogleMap( - myLocationEnabled: true, - compassEnabled: true, - markers: _markers, - polylines: _polylines, - mapType: MapType.normal, - initialCameraPosition: CameraPosition(target: DEST_LOCATION, zoom: 4), - onMapCreated: (GoogleMapController controller) { - _controller.complete(controller); - // showPinsOnMap(); - }, - ), - // floatingActionButton: FloatingActionButton.extended( - // onPressed: _goToDriver, - // label: Text('To the lake!'), - // icon: Icon(Icons.directions_boat), - // ), - ); - } - - - void setSourceAndDestinationIcons() async { - final Uint8List srcMarkerBytes = await getBytesFromAsset('assets/images/map_markers/source_map_marker.png', getMarkerIconSize()); - final Uint8List destMarkerBytes = await getBytesFromAsset('assets/images/map_markers/destination_map_marker.png', getMarkerIconSize()); - sourceIcon = await BitmapDescriptor.fromBytes(srcMarkerBytes); - destinationIcon = await BitmapDescriptor.fromBytes(destMarkerBytes); - } - - CameraPosition _orderDeliveryLocationCamera(){ - if(DEST_LOCATION != null){ - final CameraPosition orderDeliveryLocCamera = CameraPosition( - bearing: CAMERA_BEARING, - target: DEST_LOCATION, - tilt: CAMERA_TILT, - zoom: CAMERA_ZOOM); - return orderDeliveryLocCamera; - } - return null; - } - - CameraPosition _driverLocationCamera(){ - if(DEST_LOCATION != null) { - final CameraPosition driverLocCamera = CameraPosition( - bearing: CAMERA_BEARING, - target: SOURCE_LOCATION, - tilt: CAMERA_TILT, - zoom: CAMERA_ZOOM); - return driverLocCamera; - } - return null; - } - - - Future _goToOrderDeliveryLocation() async { - final GoogleMapController controller = await _controller.future; - final CameraPosition orderDeliveryLocCamera = _orderDeliveryLocationCamera(); - controller.animateCamera(CameraUpdate.newCameraPosition(orderDeliveryLocCamera)); - } - - Future _goToDriver() async { - final GoogleMapController controller = await _controller.future; - final CameraPosition driverLocCamera = _driverLocationCamera(); - controller.animateCamera(CameraUpdate.newCameraPosition(driverLocCamera)); - } - - - void showPinsOnMap() { - // source pin - if(SOURCE_LOCATION != null){ - setState(() { - var pinPosition = SOURCE_LOCATION; - _markers.removeWhere((m) => m.markerId.value == 'sourcePin'); - _markers.add(Marker( - markerId: MarkerId('sourcePin'), - position: pinPosition, - icon: sourceIcon, - infoWindow: InfoWindow(title: TranslationBase.of(context).driver), - onTap: onSourceMarkerTap - )); - }); - } - - // destination pin - if(DEST_LOCATION != null){ - setState(() { - var destPosition = DEST_LOCATION; - _markers.removeWhere((m) => m.markerId.value == 'destPin'); - _markers.add(Marker( - markerId: MarkerId('destPin'), - position: destPosition, - icon: destinationIcon, - infoWindow: InfoWindow(title: TranslationBase.of(context).deliveryLocation), - onTap: onDestinationMarkerTap - )); - }); - } - // set the route lines on the map from source to destination - // for more info follow this tutorial - // drawRoute(); - } - - void updatePinOnMap() async { - _latLngStream.addLatLng(LatLngInfo(SOURCE_LOCATION.latitude, SOURCE_LOCATION.longitude, "sourcePin")); - drawRoute(); - } - - void drawRoute() async { - return; // Ignore draw Route - - List result = await polylinePoints.getRouteBetweenCoordinates( - GOOGLE_API_KEY, - SOURCE_LOCATION.latitude, - SOURCE_LOCATION.longitude, - DEST_LOCATION.latitude, - DEST_LOCATION.longitude); - if(result.isNotEmpty){ - result.forEach((PointLatLng point){ - polylineCoordinates.add( - LatLng(point.latitude,point.longitude) - ); - }); - setState(() { - _polylines.add(Polyline( - width: 5, // set the width of the polylines - polylineId: PolylineId('poly'), - color: Color.fromARGB(255, 40, 122, 198), - points: polylineCoordinates - )); - }); - } - } - - bool isLocationUpdating = false; - startUpdatingDriverLocation({int frequencyInSeconds = 2}) async{ - isLocationUpdating = true; - int driverId = int.tryParse(_order.driverID); - - Future.doWhile(() async{ - if(isLocationUpdating){ - - await Future.delayed(Duration(seconds: frequencyInSeconds)); - - showLoading(); - LatLng driverLocation = (await _orderServices.getDriverLocation(driverId)); - hideLoading(); - - if(driverLocation != null){ - if(SOURCE_LOCATION == null || DEST_LOCATION == null){ - SOURCE_LOCATION = driverLocation; - DEST_LOCATION = _order.shippingAddress.getLocation(); - showPinsOnMap(); - } - SOURCE_LOCATION = driverLocation; - updatePinOnMap(); - updateMapCamera(); - }else{ - GifLoaderDialogUtils.hideDialog(context); - } - } - return isLocationUpdating; - - }); - } - - showLoading(){ - if(SOURCE_LOCATION == null){ - GifLoaderDialogUtils.showMyDialog(context); - } - } - - hideLoading(){ - if(SOURCE_LOCATION == null){ - GifLoaderDialogUtils.hideDialog(context); - } - } - - stopUpdatingDriverLocation(){ - isLocationUpdating = false; - } - - Future getBytesFromAsset(String path, int width) async { - ByteData data = await rootBundle.load(path); - ui.Codec codec = await ui.instantiateImageCodec(data.buffer.asUint8List(), targetWidth: width); - ui.FrameInfo fi = await codec.getNextFrame(); - return (await fi.image.toByteData(format: ui.ImageByteFormat.png)).buffer.asUint8List(); - } - - int getMarkerIconSize(){ - return 140; - } - - updateMapCamera() async{ - if(SOURCE_LOCATION != null && DEST_LOCATION != null){ - - // 'package:google_maps_flutter_platform_interface/src/types/location.dart': Failed assertion: line 72 pos 16: 'southwest.latitude <= northeast.latitude': is not true. - LatLngBounds bound; - if(SOURCE_LOCATION.latitude <= DEST_LOCATION.latitude){ - bound = LatLngBounds(southwest: SOURCE_LOCATION, northeast: DEST_LOCATION); - }else{ - bound = LatLngBounds(southwest: DEST_LOCATION, northeast: SOURCE_LOCATION); - } - - if(bound == null) - return; - - CameraUpdate camera = CameraUpdate.newLatLngBounds(bound, 50); - final GoogleMapController controller = await _controller.future; - controller.animateCamera(camera); - } - } - - bool showSrcMarkerTitle = false; - onSourceMarkerTap() async{ - // showSrcMarkerTitle = !showSrcMarkerTitle; - } - - bool showDestMarkerTitle = false; - onDestinationMarkerTap() async{ - // showDestMarkerTitle = !showDestMarkerTitle; - // Marker m = _markers.firstWhere((m) => m.markerId.value == 'destPin'); - // if(showDestMarkerTitle){ - // } - } -} +// import 'dart:async'; +// import 'dart:typed_data'; +// import 'dart:ui' as ui; +// +// import 'package:async/async.dart'; +// import 'package:diplomaticquarterapp/config/config.dart'; +// import 'package:diplomaticquarterapp/core/model/pharmacies/order_detail.dart'; +// import 'package:diplomaticquarterapp/core/service/parmacyModule/order-preview-service.dart'; +// import 'package:diplomaticquarterapp/locator.dart'; +// 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:flutter/material.dart'; +// import 'package:flutter/services.dart'; +// import 'package:flutter_animarker/lat_lng_interpolation.dart'; +// import 'package:flutter_animarker/models/lat_lng_delta.dart'; +// import 'package:flutter_animarker/models/lat_lng_info.dart'; +// import 'package:flutter_polyline_points/flutter_polyline_points.dart'; +// import 'package:google_maps_flutter/google_maps_flutter.dart'; +// import 'package:location/location.dart'; +// +// class TrackDriver extends StatefulWidget { +// final OrderDetailModel order; +// TrackDriver({this.order}); +// +// @override +// State createState() => _TrackDriverState(); +// } +// +// class _TrackDriverState extends State { +// OrderPreviewService _orderServices = locator(); +// OrderDetailModel _order; +// +// Completer _controller = Completer(); +// +// +// double CAMERA_ZOOM = 14; +// double CAMERA_TILT = 0; +// double CAMERA_BEARING = 30; +// LatLng SOURCE_LOCATION = null; +// LatLng DEST_LOCATION = null; +// +// // for my drawn routes on the map +// Set _polylines = Set(); +// List polylineCoordinates = []; +// PolylinePoints polylinePoints; +// +// Set _markers = Set(); +// +// BitmapDescriptor sourceIcon; // for my custom marker pins +// BitmapDescriptor destinationIcon; // for my custom marker pins +// Location location;// wrapper around the location API +// +// +// int locationUpdateFreq = 2; +// LatLngInterpolationStream _latLngStream; +// StreamGroup subscriptions; +// +// @override +// void initState() { +// super.initState(); +// +// _order = widget.order; +// DEST_LOCATION = _order.shippingAddress.getLocation(); +// location = new Location(); +// polylinePoints = PolylinePoints(); +// setSourceAndDestinationIcons(); +// +// initMarkerUpdateStream(); +// startUpdatingDriverLocation(); +// +// } +// +// @override +// void dispose() { +// super.dispose(); +// subscriptions.close(); +// _latLngStream.cancel(); +// stopUpdatingDriverLocation(); +// } +// +// initMarkerUpdateStream(){ +// _latLngStream = LatLngInterpolationStream(movementDuration: Duration(seconds: locationUpdateFreq+1)); +// subscriptions = StreamGroup(); +// +// subscriptions.add(_latLngStream.getAnimatedPosition('sourcePin')); +// subscriptions.stream.listen((LatLngDelta delta) { +// //Update the marker with animation +// setState(() { +// //Get the marker Id for this animation +// var markerId = MarkerId(delta.markerId); +// Marker sourceMarker = Marker( +// markerId: markerId, +// // rotation: delta.rotation, +// icon: sourceIcon, +// position: LatLng( +// delta.from.latitude, +// delta.from.longitude, +// ), +// onTap: onSourceMarkerTap +// ); +// +// _markers.removeWhere((m) => m.markerId.value == 'sourcePin'); +// _markers.add(sourceMarker); +// }); +// }); +// } +// +// @override +// Widget build(BuildContext context) { +// +// return AppScaffold( +// appBarTitle: TranslationBase.of(context).deliveryDriverTrack, +// isShowAppBar: true, +// isPharmacy: true, +// showPharmacyCart: false, +// showHomeAppBarIcon: false, +// body: GoogleMap( +// myLocationEnabled: true, +// compassEnabled: true, +// markers: _markers, +// polylines: _polylines, +// mapType: MapType.normal, +// initialCameraPosition: CameraPosition(target: DEST_LOCATION, zoom: 4), +// onMapCreated: (GoogleMapController controller) { +// _controller.complete(controller); +// // showPinsOnMap(); +// }, +// ), +// // floatingActionButton: FloatingActionButton.extended( +// // onPressed: _goToDriver, +// // label: Text('To the lake!'), +// // icon: Icon(Icons.directions_boat), +// // ), +// ); +// } +// +// +// void setSourceAndDestinationIcons() async { +// final Uint8List srcMarkerBytes = await getBytesFromAsset('assets/images/map_markers/source_map_marker.png', getMarkerIconSize()); +// final Uint8List destMarkerBytes = await getBytesFromAsset('assets/images/map_markers/destination_map_marker.png', getMarkerIconSize()); +// sourceIcon = await BitmapDescriptor.fromBytes(srcMarkerBytes); +// destinationIcon = await BitmapDescriptor.fromBytes(destMarkerBytes); +// } +// +// CameraPosition _orderDeliveryLocationCamera(){ +// if(DEST_LOCATION != null){ +// final CameraPosition orderDeliveryLocCamera = CameraPosition( +// bearing: CAMERA_BEARING, +// target: DEST_LOCATION, +// tilt: CAMERA_TILT, +// zoom: CAMERA_ZOOM); +// return orderDeliveryLocCamera; +// } +// return null; +// } +// +// CameraPosition _driverLocationCamera(){ +// if(DEST_LOCATION != null) { +// final CameraPosition driverLocCamera = CameraPosition( +// bearing: CAMERA_BEARING, +// target: SOURCE_LOCATION, +// tilt: CAMERA_TILT, +// zoom: CAMERA_ZOOM); +// return driverLocCamera; +// } +// return null; +// } +// +// +// Future _goToOrderDeliveryLocation() async { +// final GoogleMapController controller = await _controller.future; +// final CameraPosition orderDeliveryLocCamera = _orderDeliveryLocationCamera(); +// controller.animateCamera(CameraUpdate.newCameraPosition(orderDeliveryLocCamera)); +// } +// +// Future _goToDriver() async { +// final GoogleMapController controller = await _controller.future; +// final CameraPosition driverLocCamera = _driverLocationCamera(); +// controller.animateCamera(CameraUpdate.newCameraPosition(driverLocCamera)); +// } +// +// +// void showPinsOnMap() { +// // source pin +// if(SOURCE_LOCATION != null){ +// setState(() { +// var pinPosition = SOURCE_LOCATION; +// _markers.removeWhere((m) => m.markerId.value == 'sourcePin'); +// _markers.add(Marker( +// markerId: MarkerId('sourcePin'), +// position: pinPosition, +// icon: sourceIcon, +// infoWindow: InfoWindow(title: TranslationBase.of(context).driver), +// onTap: onSourceMarkerTap +// )); +// }); +// } +// +// // destination pin +// if(DEST_LOCATION != null){ +// setState(() { +// var destPosition = DEST_LOCATION; +// _markers.removeWhere((m) => m.markerId.value == 'destPin'); +// _markers.add(Marker( +// markerId: MarkerId('destPin'), +// position: destPosition, +// icon: destinationIcon, +// infoWindow: InfoWindow(title: TranslationBase.of(context).deliveryLocation), +// onTap: onDestinationMarkerTap +// )); +// }); +// } +// // set the route lines on the map from source to destination +// // for more info follow this tutorial +// // drawRoute(); +// } +// +// void updatePinOnMap() async { +// _latLngStream.addLatLng(LatLngInfo(SOURCE_LOCATION.latitude, SOURCE_LOCATION.longitude, "sourcePin")); +// drawRoute(); +// } +// +// void drawRoute() async { +// return; // Ignore draw Route +// +// List result = await polylinePoints.getRouteBetweenCoordinates( +// GOOGLE_API_KEY, +// SOURCE_LOCATION.latitude, +// SOURCE_LOCATION.longitude, +// DEST_LOCATION.latitude, +// DEST_LOCATION.longitude); +// if(result.isNotEmpty){ +// result.forEach((PointLatLng point){ +// polylineCoordinates.add( +// LatLng(point.latitude,point.longitude) +// ); +// }); +// setState(() { +// _polylines.add(Polyline( +// width: 5, // set the width of the polylines +// polylineId: PolylineId('poly'), +// color: Color.fromARGB(255, 40, 122, 198), +// points: polylineCoordinates +// )); +// }); +// } +// } +// +// bool isLocationUpdating = false; +// startUpdatingDriverLocation({int frequencyInSeconds = 2}) async{ +// isLocationUpdating = true; +// int driverId = int.tryParse(_order.driverID); +// +// Future.doWhile(() async{ +// if(isLocationUpdating){ +// +// await Future.delayed(Duration(seconds: frequencyInSeconds)); +// +// showLoading(); +// LatLng driverLocation = (await _orderServices.getDriverLocation(driverId)); +// hideLoading(); +// +// if(driverLocation != null){ +// if(SOURCE_LOCATION == null || DEST_LOCATION == null){ +// SOURCE_LOCATION = driverLocation; +// DEST_LOCATION = _order.shippingAddress.getLocation(); +// showPinsOnMap(); +// } +// SOURCE_LOCATION = driverLocation; +// updatePinOnMap(); +// updateMapCamera(); +// }else{ +// GifLoaderDialogUtils.hideDialog(context); +// } +// } +// return isLocationUpdating; +// +// }); +// } +// +// showLoading(){ +// if(SOURCE_LOCATION == null){ +// GifLoaderDialogUtils.showMyDialog(context); +// } +// } +// +// hideLoading(){ +// if(SOURCE_LOCATION == null){ +// GifLoaderDialogUtils.hideDialog(context); +// } +// } +// +// stopUpdatingDriverLocation(){ +// isLocationUpdating = false; +// } +// +// Future getBytesFromAsset(String path, int width) async { +// ByteData data = await rootBundle.load(path); +// ui.Codec codec = await ui.instantiateImageCodec(data.buffer.asUint8List(), targetWidth: width); +// ui.FrameInfo fi = await codec.getNextFrame(); +// return (await fi.image.toByteData(format: ui.ImageByteFormat.png)).buffer.asUint8List(); +// } +// +// int getMarkerIconSize(){ +// return 140; +// } +// +// updateMapCamera() async{ +// if(SOURCE_LOCATION != null && DEST_LOCATION != null){ +// +// // 'package:google_maps_flutter_platform_interface/src/types/location.dart': Failed assertion: line 72 pos 16: 'southwest.latitude <= northeast.latitude': is not true. +// LatLngBounds bound; +// if(SOURCE_LOCATION.latitude <= DEST_LOCATION.latitude){ +// bound = LatLngBounds(southwest: SOURCE_LOCATION, northeast: DEST_LOCATION); +// }else{ +// bound = LatLngBounds(southwest: DEST_LOCATION, northeast: SOURCE_LOCATION); +// } +// +// if(bound == null) +// return; +// +// CameraUpdate camera = CameraUpdate.newLatLngBounds(bound, 50); +// final GoogleMapController controller = await _controller.future; +// controller.animateCamera(camera); +// } +// } +// +// bool showSrcMarkerTitle = false; +// onSourceMarkerTap() async{ +// // showSrcMarkerTitle = !showSrcMarkerTitle; +// } +// +// bool showDestMarkerTitle = false; +// onDestinationMarkerTap() async{ +// // showDestMarkerTitle = !showDestMarkerTitle; +// // Marker m = _markers.firstWhere((m) => m.markerId.value == 'destPin'); +// // if(showDestMarkerTitle){ +// // } +// } +// } diff --git a/lib/pages/pharmacy/pharmacyAddresses/AddAddress.dart b/lib/pages/pharmacy/pharmacyAddresses/AddAddress.dart index 7569ed43..de0b65b2 100644 --- a/lib/pages/pharmacy/pharmacyAddresses/AddAddress.dart +++ b/lib/pages/pharmacy/pharmacyAddresses/AddAddress.dart @@ -1,17 +1,25 @@ -import 'package:diplomaticquarterapp/core/model/pharmacies/Addresses.dart'; +import 'dart:async'; + +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/customer_addresses_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/PharmacyAddressesViewModel.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/borderedButton.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; +import 'package:diplomaticquarterapp/uitl/location_util.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/app_map/google_huawei_map.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:diplomaticquarterapp/widgets/pickupLocation/PickupLocationFromMap.dart'; import 'package:flutter/material.dart'; -import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:geolocator/geolocator.dart'; -import 'package:google_maps_place_picker/google_maps_place_picker.dart'; +import 'package:geocoding/geocoding.dart'; +import 'package:google_maps_flutter/google_maps_flutter.dart'; +import 'package:provider/provider.dart'; class AddAddressPage extends StatefulWidget { - final Addresses editedAddress; - final Function(PickResult) onPick; + final AddressInfo editedAddress; + final Function(Placemark, String) onPick; AddAddressPage(this.editedAddress, this.onPick); @@ -20,39 +28,99 @@ class AddAddressPage extends StatefulWidget { } class _AddAddressPageState extends State { - double _latitude; - double _longitude; + double? _latitude; + double? _longitude; + AppMap? appMap; + AppSharedPreferences? sharedPref = AppSharedPreferences(); + LatLng? currentPostion; + Completer mapController = Completer(); + Placemark? selectedPlace; + LocationUtils? locationUtils; + + static CameraPosition _kGooglePlex = CameraPosition( + target: LatLng(37.42796133580664, -122.085749655962), + zoom: 14.4746, + ); @override void initState() { super.initState(); - if (widget.editedAddress != null && - widget.editedAddress.latLong != null && - widget.editedAddress.latLong != "") { - List latLng = widget.editedAddress.latLong.split(","); + + if (widget.editedAddress != null && widget.editedAddress.latLong != null && widget.editedAddress.latLong != "") { + List latLng = widget.editedAddress.latLong!.split(","); _latitude = double.parse(latLng[0]); _longitude = double.parse(latLng[1]); } else { _getCurrentLocation(); } + // setState(() {}); + + appMap = AppMap( + _kGooglePlex!.toMap() as Map, + onCameraMove: () { + _updatePosition(_kGooglePlex); + }, + onMapCreated: () { + currentPostion = LatLng(_latitude!, _longitude!); + // latitude = widget.latitude; + // longitude = widget.longitude; + setMap(); + setState(() {}); + }, + onCameraIdle: () async { + List placemarks = await placemarkFromCoordinates(_latitude!, _longitude!); + selectedPlace = placemarks[0]; + print(selectedPlace); + }, + ); } - _getCurrentLocation() async { - await Geolocator.getLastKnownPosition().then((value) { - _latitude = value.latitude; - _longitude = value.longitude; - }).catchError((e) { - _longitude = 0; - _latitude = 0; + setMap() { + setState(() { + _kGooglePlex = CameraPosition( + target: currentPostion!, + zoom: 14.4746, + ); + appMap!.moveTo(cameraPostion: _kGooglePlex); }); } + void _updatePosition(CameraPosition _position) { + _latitude = _position.target.latitude; + _longitude = _position.target.longitude; + print(_position); + } + + _getCurrentLocation() async { + if (await this.sharedPref!.getDouble(USER_LAT) != null && await this.sharedPref!.getDouble(USER_LONG) != null) { + var lat = await this.sharedPref!.getDouble(USER_LAT); + var long = await this.sharedPref!.getDouble(USER_LONG); + _latitude = lat; + _longitude = long; + currentPostion = LatLng(lat, long); + setMap(); + } else { + locationUtils = new LocationUtils(isShowConfirmDialog: true, context: context); + locationUtils!.getCurrentLocation(callBack: (value) { + print(value); + setMap(); + }); + } + + // await Geolocator.getLastKnownPosition().then((value) { + // _latitude = value.latitude; + // _longitude = value.longitude; + // }).catchError((e) { + // _longitude = 0; + // _latitude = 0; + // }); + } + @override Widget build(BuildContext context) { final mediaQuery = MediaQuery.of(context); - final height = mediaQuery.size.height - - 60 - - mediaQuery.padding.top; + final height = mediaQuery.size.height - 60 - mediaQuery.padding.top; + ProjectViewModel projectViewModel = Provider.of(context); return BaseView( builder: (_, model, wi) => AppScaffold( @@ -60,20 +128,78 @@ class _AddAddressPageState extends State { isShowAppBar: true, isPharmacy: true, backgroundColor: Colors.white, - body: Container( - height: height * 1, - child: PickupLocationFromMap( - latitude: _latitude, - longitude: _longitude, - isWithAppBar: false, - buttonColor: Color(0xFF5AB145), - buttonLabel: TranslationBase.of(context).save, - onPick: (value) { - widget.onPick(value); - }, - ), + showNewAppBarTitle: true, + showNewAppBar: true, + body: Column( + children: [ + Expanded( + child: Stack( + alignment: Alignment.center, + children: [ + if (appMap != null) appMap!, + Container( + margin: EdgeInsets.only(bottom: 50.0), + child: Icon( + Icons.place, + color: CustomColors.accentColor, + size: 50, + ), + ), + ], + ), + ), + Container( + padding: const EdgeInsets.only(left: 20, right: 20, top: 14, bottom: 14), + child: DefaultButton(TranslationBase.of(context).addNewAddress, () async { + // AddNewAddressRequestModel addNewAddressRequestModel = new AddNewAddressRequestModel( + // customer: Customer(addresses: [ + // Addresses( + // address1: selectedPlace.name, + // address2: selectedPlace.street, + // customerAttributes: "", + // city: selectedPlace.locality, + // createdOnUtc: "", + // id: "0", + // faxNumber: "", + // phoneNumber: projectViewModel.user.mobileNumber, + // province: selectedPlace.locality, + // countryId: 69, + // latLong: "$_latitude,$_longitude", + // country: selectedPlace.country, + // zipPostalCode: selectedPlace.postalCode, + // email: projectViewModel.user.emailAddress) + // ]), + // ); + + widget.onPick(selectedPlace!, "$_latitude,$_longitude"); + Navigator.of(context).pop(); + + // await model.addAddressInfo(addNewAddressRequestModel: addNewAddressRequestModel); + // if (model.state == ViewState.ErrorLocal) { + // Utils.showErrorToast(model.error); + // } else { + // AppToast.showSuccessToast(message: "Address Added Successfully"); + // } + // Navigator.of(context).pop(addNewAddressRequestModel); + }), + ), + ], ), + + // Container( + // height: height * 1, + // child: PickupLocationFromMap( + // latitude: _latitude ?? 0, + // longitude: _longitude ?? 0, + // isWithAppBar: false, + // buttonColor: Color(0xFF5AB145), + // buttonLabel: TranslationBase.of(context).save, + // onPick: (value) { + // widget.onPick(value); + // }, + // ), ), ); + // ); } } diff --git a/lib/pages/pharmacy/pharmacyAddresses/PharmacyAddresses.dart b/lib/pages/pharmacy/pharmacyAddresses/PharmacyAddresses.dart index 51256e11..36f5578e 100644 --- a/lib/pages/pharmacy/pharmacyAddresses/PharmacyAddresses.dart +++ b/lib/pages/pharmacy/pharmacyAddresses/PharmacyAddresses.dart @@ -1,7 +1,14 @@ import 'package:diplomaticquarterapp/core/model/pharmacies/Addresses.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/PharmacyAddressesViewModel.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/screens/payment-method-select-page.dart'; +import 'package:diplomaticquarterapp/pages/pharmacy/pharmacyAddresses/AddAddress.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'; import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; @@ -9,39 +16,54 @@ 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:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/pages/pharmacy/pharmacyAddresses/AddAddress.dart'; +import 'package:provider/provider.dart'; +///TODO Elham* split this to tow files class PharmacyAddressesPage extends StatefulWidget { + final OrderPreviewViewModel? orderPreviewViewModel; + final Function? changeMainState; + + final bool isUpdate; + final bool isShippingAddress; + + const PharmacyAddressesPage({Key? key, this.orderPreviewViewModel, this.isUpdate = false, this.isShippingAddress = false, this.changeMainState}) : super(key: key); + @override _PharmacyAddressesState createState() => _PharmacyAddressesState(); } class _PharmacyAddressesState extends State { - void navigateToAddressPage( - BuildContext ctx, PharmacyAddressesViewModel model, Addresses address) { + void navigateToAddressPage(BuildContext ctx, PharmacyAddressesViewModel model, AddressInfo address) { Navigator.push( - ctx, - FadePage( - page: AddAddressPage(address, (pickResult) { - model.addEditAddress(pickResult, address); - }))); + ctx, + FadePage( + page: AddAddressPage( + address, + (pickResult, latLong) async { + await model.addEditAddress(pickResult, address, latLong: latLong); + }, + ), + ), + ).then((value) async { + // await model.getAddressesList(); + }); } Widget build(BuildContext context) { final mediaQuery = MediaQuery.of(context); final height = mediaQuery.size.height - 60 - mediaQuery.padding.top; + ProjectViewModel projectProvider = Provider.of(context); return BaseView( onModelReady: (model) => model.getAddressesList(), builder: (_, model, wi) => AppScaffold( - appBarTitle: TranslationBase.of(context).changeAddress, + appBarTitle: widget.isUpdate ? TranslationBase.of(context).changeAddress : TranslationBase.of(context).addAddress, isShowAppBar: true, isPharmacy: true, baseViewModel: model, backgroundColor: Colors.white, body: Container( - height: height * 0.90, + height: widget.isShippingAddress ? height * 0.90 : height * 0.99, child: SingleChildScrollView( child: Column( children: [ @@ -74,63 +96,105 @@ class _PharmacyAddressesState extends State { vPadding: 12, hasShadow: true, handler: () { - navigateToAddressPage(context, model, null); + navigateToAddressPage(context, model, AddressInfo()); }, ), ), + SizedBox( + height: height * 0.10, + ) ], ), ), ), - bottomSheet: Container( - height: height * 0.10, - color: Colors.white, - child: Column( - children: [ - Divider( - color: Colors.grey.shade300, - height: 1, - thickness: 1, - indent: 0, - endIndent: 0, - ), - Container( - padding: EdgeInsets.symmetric(horizontal: 12, vertical: 8), - child: BorderedButton( - TranslationBase.of(context).confirmAddress, - hasBorder: true, - borderColor: Color(0xFF5AB145), - textColor: Colors.white, - fontWeight: FontWeight.bold, - backgroundColor: Color(0xFF5AB145), - fontSize: 14, - vPadding: 8, - handler: () { - model.saveSelectedAddressLocally( - model.addresses[model.selectedAddressIndex]); - Navigator.pop( - context, model.addresses[model.selectedAddressIndex]); - }, + bottomSheet: widget.isShippingAddress + ? Container( + height: height * 0.10, + color: Colors.white, + child: Column( + children: [ + Divider( + color: Colors.grey.shade300, + height: 1, + thickness: 1, + indent: 0, + endIndent: 0, + ), + Container( + padding: EdgeInsets.symmetric(horizontal: 12, vertical: 8), + child: BorderedButton( + TranslationBase.of(context).confirmAddress, + hasBorder: true, + borderColor: Color(0xFF5AB145), + textColor: Colors.white, + fontWeight: FontWeight.bold, + backgroundColor: Color(0xFF5AB145), + fontSize: 14, + vPadding: 8, + handler: () async { + widget.orderPreviewViewModel!.paymentCheckoutData.address = Addresses.fromJson(model.addresses[model.selectedAddressIndex].toJson()); + GifLoaderDialogUtils.showMyDialog(context); + await widget.orderPreviewViewModel!.getInformationsByAddress(projectProvider.user!.patientIdentificationNo!); + if (widget.orderPreviewViewModel!.error == "") { + await widget.orderPreviewViewModel!.getShoppingCart(); + GifLoaderDialogUtils.hideDialog(context); + model.saveSelectedAddressLocally(model.addresses[model.selectedAddressIndex]); + _navigateToPaymentOption(model); + } else { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: widget.orderPreviewViewModel!.error); + return; + } + }, + ), + ), + ], ), - ), - ], - ), - ), + ) + : SizedBox(), ), ); } + + _navigateToPaymentOption(model) { + if (widget.isUpdate) { + widget.orderPreviewViewModel!.paymentCheckoutData.address = Addresses.fromJson(model.addresses[model.selectedAddressIndex].toJson()); + widget.changeMainState!(); + Navigator.pop(context); + + return; + } + Navigator.push( + context, + FadePage( + page: PaymentMethodSelectPage( + model: widget.orderPreviewViewModel!, + ))).then((result) => { + setState(() { + if (result != null) { + var paymentOption = result; + widget.orderPreviewViewModel!.paymentCheckoutData!.paymentOption = paymentOption; + } + // widget.changeMainState(); + }) + }); + } } -class AddressItemWidget extends StatelessWidget { +class AddressItemWidget extends StatefulWidget { final PharmacyAddressesViewModel model; - final Addresses address; - final Function selectAddress; + final AddressInfo address; + final VoidCallback selectAddress; final bool isSelected; - final Function(Addresses) onTabEditAddress; + final Function(AddressInfo) onTabEditAddress; - AddressItemWidget(this.model, this.address, this.selectAddress, - this.isSelected, this.onTabEditAddress); + AddressItemWidget(this.model, this.address, this.selectAddress, this.isSelected, this.onTabEditAddress); + + @override + _AddressItemWidgetState createState() => _AddressItemWidgetState(); +} +class _AddressItemWidgetState extends State { @override Widget build(BuildContext context) { return Container( @@ -146,27 +210,22 @@ class AddressItemWidget extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ InkWell( - onTap: selectAddress, + onTap: widget!.selectAddress!, child: Container( margin: EdgeInsets.only(left: 16, right: 16), child: Padding( padding: const EdgeInsets.all(5.0), child: Container( decoration: new BoxDecoration( - color: !isSelected ? Colors.white : Colors.green, + color: !widget.isSelected ? Colors.white : Colors.green, shape: BoxShape.circle, - border: Border.all( - color: Colors.grey, - style: BorderStyle.solid, - width: 1.0), + border: Border.all(color: Colors.grey, style: BorderStyle.solid, width: 1.0), ), child: Padding( padding: const EdgeInsets.all(0.0), child: Icon( Icons.check, - color: isSelected - ? Colors.white - : Colors.transparent, + color: widget.isSelected ? Colors.white : Colors.transparent, size: 25, ), ), @@ -179,15 +238,14 @@ class AddressItemWidget extends StatelessWidget { Expanded( child: Container( child: Container( - margin: - EdgeInsets.symmetric(vertical: 12, horizontal: 12), + margin: EdgeInsets.symmetric(vertical: 12, horizontal: 12), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.symmetric(vertical: 0), child: Texts( - "${address.firstName} ${address.lastName}", + "${widget.address.firstName} ${widget.address.lastName}", fontSize: 14, fontWeight: FontWeight.bold, color: Colors.black, @@ -196,7 +254,7 @@ class AddressItemWidget extends StatelessWidget { Padding( padding: const EdgeInsets.symmetric(vertical: 4), child: Texts( - "${address.address1} ${address.address2} ${address.address2},, ${address.city}, ${address.country} ${address.zipPostalCode}", + "${widget.address.address1} ${widget.address.address2} ${widget.address.address2},, ${widget.address.city}, ${widget.address.country} ${widget.address.zipPostalCode}", fontSize: 12, fontWeight: FontWeight.normal, color: Colors.grey.shade500, @@ -213,7 +271,7 @@ class AddressItemWidget extends StatelessWidget { ), ), Texts( - "${address.phoneNumber}", + "${widget.address.phoneNumber}", fontSize: 14, fontWeight: FontWeight.bold, color: Colors.grey, @@ -234,7 +292,7 @@ class AddressItemWidget extends StatelessWidget { borderColor: Colors.transparent, textColor: Color(0x990000FF), handler: () { - onTabEditAddress(address); + widget.onTabEditAddress(widget.address); }, icon: Icon( Icons.edit, @@ -243,8 +301,7 @@ class AddressItemWidget extends StatelessWidget { ), ), Padding( - padding: - const EdgeInsets.symmetric(horizontal: 8), + padding: const EdgeInsets.symmetric(horizontal: 8), child: SizedBox( child: Container( width: 1, @@ -261,23 +318,20 @@ class AddressItemWidget extends StatelessWidget { handler: () { ConfirmDialog dialog = new ConfirmDialog( context: context, - title: "Are you sure want to delete", - confirmMessage: - "${address.address1} ${address.address2}", - okText: - TranslationBase.of(context).delete, - cancelText: TranslationBase.of(context) - .cancel_nocaps, + title: TranslationBase.of(context).deleteAddress, + confirmMessage: "${widget.address.address1} ${widget.address.address2}", + okText: TranslationBase.of(context).delete, + cancelText: TranslationBase.of(context).cancel_nocaps, okFunction: () => { - model - .deleteAddresses(address) - .then((_) { - ConfirmDialog.closeAlertDialog( - context); - AppToast.showErrorToast( - message: - "Address has been deleted"); - }) + ConfirmDialog.closeAlertDialog(context), + setState(() { + widget.model.deleteAddresses(widget.address).then((_) { + AppToast.showSuccessToast( + message: TranslationBase.of(context).deletedAddress, + ); + // widget.model.getAddressesList(); + }); + }), }, cancelFunction: () => {}); dialog.showAlertDialog(context); diff --git a/lib/pages/pharmacy/pharmacyContacts.dart b/lib/pages/pharmacy/pharmacyContacts.dart new file mode 100644 index 00000000..ab9e56d7 --- /dev/null +++ b/lib/pages/pharmacy/pharmacyContacts.dart @@ -0,0 +1,329 @@ +import 'dart:io' show Platform; + +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:maps_launcher/maps_launcher.dart'; +import 'package:provider/provider.dart'; +import 'package:url_launcher/url_launcher.dart'; +import 'package:map_launcher/map_launcher.dart'; +import 'dart:io' show Platform; + +class pharmacyContactsPage extends StatefulWidget { + @override + _pharmacyContactsPageState createState() => _pharmacyContactsPageState(); +} + +class _pharmacyContactsPageState extends State { + @override + Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + final latitude = "24.704016"; + final longitude = "46.676691"; + final phone = "+966112833400"; + final whatsApp = "+966558434444"; + final whatappURL_android = "whatsapp://send?phone=" + whatsApp; + final whatappURL_ios = "https://wa.me/$whatsApp"; + final locationDescription = "Main Pharmacy OLAYA"; + + return AppScaffold( + appBarTitle: TranslationBase.of(context).contactUs, + isShowAppBar: true, + isShowDecPage: false, + isPharmacy: true, + showPharmacyCart: false, + showHomeAppBarIcon: false, + isMainPharmacyPages: true, + isBottomBar: true, + body: Column( + children: [ + Card( + elevation: 2, + shape: RoundedRectangleBorder( + side: BorderSide(color: Colors.grey[300]!, width: 2), + borderRadius: BorderRadius.circular(10), + ), + margin: EdgeInsets.symmetric( + horizontal: 8, + vertical: 8, + ), + child: Container( + margin: EdgeInsets.all(10), + padding: EdgeInsets.fromLTRB(5, 15, 5, 5), + decoration: BoxDecoration( + borderRadius: BorderRadius.all( + Radius.circular(15), + ), + ), + child: Column( + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: projectViewModel.isArabic ? + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text("أوقات عمل مركز الخدمات الصيدلانية:", + //TranslationBase.of(context).contactUsTime, + style: TextStyle( + color: Colors.grey[700], + fontSize: 18, + fontWeight: FontWeight.bold, + letterSpacing: -0.68)), + SizedBox(height: 8), + Text(" السبت - الأربعاء : من 8 صباحاً إلى 10 مساءً ", + //TranslationBase.of(context).contactUsTime, + style: TextStyle( + color: Colors.grey[700], + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.68)), + SizedBox(height: 5), + Text("الــــخـــمــــيـــس : من 8 صباحاً إلى 8 مساءً", + //TranslationBase.of(context).contactUsTime, + style: TextStyle( + color: Colors.grey[700], + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.68)), + SizedBox(height: 5), + Text("الـــجــــمـــــعـــــة : من 2 ظـهـراً إلى 8 مساءً", + //TranslationBase.of(context).contactUsTime, + style: TextStyle( + color: Colors.grey[700], + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.68)), + ], + ):Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text("Pharmaceutical Service Center working hours: ", + //TranslationBase.of(context).contactUsTime, + style: TextStyle( + color: Colors.grey[700], + fontSize: 16, + fontWeight: FontWeight.bold, + letterSpacing: -0.68)), + SizedBox(height: 8), + Text("Sat – Wed: from 8 AM to 10 PM", + //TranslationBase.of(context).contactUsTime, + style: TextStyle( + color: Colors.grey[700], + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.68)), + SizedBox(height: 5), + Text("Thursday: from 8 AM to 8 PM", + //TranslationBase.of(context).contactUsTime, + style: TextStyle( + color: Colors.grey[700], + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.68)), + SizedBox(height: 5), + Text("Friday : from 2 PM to 8 PM", + //TranslationBase.of(context).contactUsTime, + style: TextStyle( + color: Colors.grey[700], + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.68)), + ], + ), + + ), + SizedBox( + height: 20, + ), + Row( + children: [ + InkWell( + onTap: () { + launch("tel://" + phone); + }, + child: SvgPicture.asset( + 'assets/images/pharmacy/call.svg', + width: 20, + height: 20, + ), + ), + SizedBox( + width: 20, + ), + Text(TranslationBase.of(context).phone, + style: TextStyle( + color: Colors.grey[700], + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.68)), + SizedBox( + width: 30, + ), + Directionality( + textDirection: TextDirection.ltr, + child: Text("+966" +"-11-2833400", + style: TextStyle( + color: Colors.grey[700], + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.68)), + ), + ], + ), + SizedBox( + height: 30, + ), + Row( + children: [ + InkWell( + onTap: () { + // launch('whatsapp://send?phone='+whatsApp); + openWhatsApp(); + }, + child: SvgPicture.asset( + 'assets/images/pharmacy/whatsapp.svg', + width: 20, + height: 20, + ), + ), + SizedBox( + width: 20, + ), + Text(TranslationBase.of(context).whatsApp, + style: TextStyle( + color: Colors.grey[700], + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.68)), + SizedBox( + width: 30, + ), + Text(projectViewModel.isArabic ? "558434444 " + " 966+" :"+966 " + " 558434444", + style: TextStyle( + color: Colors.grey[700], + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.68)), + ], + ), + SizedBox( + height: 30, + ), + Padding( + padding: const EdgeInsets.all(5.0), + child: Row( + children: [ + InkWell( + onTap: () { + if (Platform.isIOS) { MapLauncher.showMarker( + mapType: MapType.apple, + coords: Coords(double.parse(latitude), + double.parse(longitude)), + title: locationDescription,); + } else { MapLauncher.showMarker( + mapType: MapType.google, + coords: Coords(double.parse(latitude), + double.parse(longitude)), + title: locationDescription, + // description: location.locationName, + ); } + // MapsLauncher.launchCoordinates(double.parse(previousModel.productLocationService[index].latitude), double.parse(previousModel.productLocationService[index].longitude), previousModel.productLocationService[index].locationDescription); + }, +// MapsLauncher.launchCoordinates( +// double.parse(latitude), +// double.parse(longitude)); +// }, + child: SvgPicture.asset( + 'assets/images/pharmacy/location.svg', + width: 20, + height: 20, + ), + ), + SizedBox( + width: 20, + ), + Expanded( + child: Text( + TranslationBase.of(context).contactUsLocation, + style: TextStyle( + color: Colors.grey[700], + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.68)), + ), + ], + ), + ), + SizedBox( + height: 50, + ), + Center( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + IconButton( + icon: new Image.asset( + 'assets/images/new-design/facebook.png'), + tooltip: 'facebook', + iconSize: 48, + onPressed: () { + setState(() { + launch("https://facebook.com/HMG.pharmacy"); + // launch("https://www.facebook.com/DrSulaimanAlHabib?ref=tn_tnmn"); + }); + }, + ), + IconButton( + icon: new Image.asset( + 'assets/images/new-design/twitter.png'), + tooltip: 'Twitter', + iconSize: 48, + onPressed: () { + setState(() { + launch("https://twitter.com/HMG_pharmacy"); + }); + }, + ), + IconButton( + icon: new Image.asset( + 'assets/images/pharmacy/instagram.png'), + tooltip: 'Instagram', + iconSize: 48, + onPressed: () { + setState(() { + launch("https://instagram.com/HMG_pharmacy"); + }); + }, + ), + ]), + ) + ], + ), + ), + ), + ], + ), + ); + } + + openWhatsApp() async { + // bool Platform.isIOS = Theme.of(context).platform == TargetPlatform.iOS; + var whatsapp = "+966558434444"; + var whatsappURL_android = "whatsapp://send?phone=" + whatsapp; + var whatappURL_ios = "https://wa.me/$whatsapp"; + if (Platform.isIOS) { + // for iOS phone only + // if (await canLaunch(whatappURL_ios)) { + await launch(whatappURL_ios, forceSafariVC: false); + // } else {} + } else { + // android + // if (await canLaunch(whatsappURL_android)) { + await launch(whatsappURL_android); + // } else {} + } + } +} diff --git a/lib/pages/pharmacy/profile/profile.dart b/lib/pages/pharmacy/profile/profile.dart index cd5c6ec7..a844e0d2 100644 --- a/lib/pages/pharmacy/profile/profile.dart +++ b/lib/pages/pharmacy/profile/profile.dart @@ -9,12 +9,14 @@ import 'package:diplomaticquarterapp/pages/login/welcome.dart'; import 'package:diplomaticquarterapp/pages/medical/prescriptions/prescriptions_home_page.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/compare.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/my_reviews.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/screens/lacum-activitaion-vida-page.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/lakum-main-page.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/lakum-terms-conditions-page.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/pharmacy-terms-conditions-page.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/wishlist.dart'; import 'package:diplomaticquarterapp/pages/pharmacy/order/Order.dart'; import 'package:diplomaticquarterapp/pages/pharmacy/pharmacyAddresses/PharmacyAddresses.dart'; +import 'package:diplomaticquarterapp/pages/pharmacy/pharmacyContacts.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; @@ -27,6 +29,12 @@ import 'package:flutter_svg/flutter_svg.dart'; dynamic languageID; class PharmacyProfilePage extends StatefulWidget { + final bool moveToOrder; + + final void Function()? changeTab; + + PharmacyProfilePage({required this.moveToOrder, this.changeTab}); + @override _ProfilePageState createState() => _ProfilePageState(); } @@ -35,24 +43,27 @@ class _ProfilePageState extends State { AppSharedPreferences sharedPref = AppSharedPreferences(); String page_id = ""; - AuthenticatedUser user; - bool isLogin = false; - String firstName; - String customerId; - String lastName, mobileNo, identificationNo; - int languageId; + AuthenticatedUser? user; + bool? isLogin = false; + String? firstName; + String? customerId; + String? customerGUID; + String? lastName, mobileNo, identificationNo; + int? languageId; getLanguageID() async { languageID = await sharedPref.getString(APP_LANGUAGE); } getCustomer() async { - String custID; + String? custID; + String? custGUID; custID = await sharedPref.getString(PHARMACY_CUSTOMER_ID); + custGUID = await sharedPref.getObject(PHARMACY_CUSTOMER_GUID); setState(() { customerId = custID; + customerGUID = custGUID; }); - print("customer Id is" + customerId); return customerId; } @@ -61,9 +72,7 @@ class _ProfilePageState extends State { if (userData != null) { user = AuthenticatedUser.fromJson(userData); setState(() { - firstName = user.firstName.toString(); - print("this is user" + user.firstName.toString()); - print("this is user" + user.firstNameN.toString()); + firstName = user!.firstName!.toString(); }); } else { if (userData == null) { @@ -73,8 +82,6 @@ class _ProfilePageState extends State { ); } } - -// this.isLogin = user != null; } void initState() { @@ -82,568 +89,521 @@ class _ProfilePageState extends State { getLanguageID(); super.initState(); getUser(); + if (widget.moveToOrder) { + Navigator.push(context, FadePage(page: OrderPage(customerID: customerId!, customerGUID: customerGUID!))); + } } @override Widget build(BuildContext context) { return BaseView( - onModelReady: (model) async { - var customerId = await sharedPref.getString(PHARMACY_CUSTOMER_ID); - model.getOrder(customerId, page_id); - }, - builder: (_, model, wi) => AppScaffold( - appBarTitle: TranslationBase.of(context).myAccount, - isShowAppBar: false, - isShowDecPage: false, - isPharmacy: true, - body: user != null - ? Container( - child: SingleChildScrollView( - child: Column( + onModelReady: (model) async { + // var customerId = await sharedPref.getString(PHARMACY_CUSTOMER_ID); + // var customerGUID = await sharedPref.getObject(PHARMACY_CUSTOMER_GUID); + // GifLoaderDialogUtils.showMyDialog(context); + // model.getOrder(customerId, customerGUID, page_id); + // GifLoaderDialogUtils.hideDialog(context); + }, + builder: (_, model, wi) => AppScaffold( + appBarTitle: TranslationBase.of(context).myAccount, + isShowAppBar: true, + isShowDecPage: false, + isPharmacy: true, + showPharmacyCart: false, + showHomeAppBarIcon: false, + isMainPharmacyPages: true, + backButtonTab: widget.changeTab!, + body: user != null + ? Container( + color: Colors.white, + child: SingleChildScrollView( + child: Column( + children: [ + Container( + child: Row( children: [ Container( child: Row( children: [ Container( - child: Row( - children: [ - Container( - padding: EdgeInsets.only( - top: 20.0, - left: 10.0, - right: 10.0, - bottom: 10.0, - ), - child: LargeAvatar( - name: user.firstName.toString(), - url: '', - ), - ), - Column(children: [ - Row(children: [ - Text( - TranslationBase.of(context) - .welcome, - style: TextStyle( - fontSize: 14.0, - fontWeight: FontWeight.bold, - color: Colors.grey), - ), - ]), - SizedBox( - height: 10, - ), - Row(children: [ - Text( - languageID == "ar" - ? user.firstNameN.toString() + - " " + - user.lastNameN.toString() - : user.firstName.toString() + - " " + - user.lastName.toString(), - style: TextStyle( - fontSize: 14.0, - fontWeight: FontWeight.bold), - ), - ]), - ]), - ], + padding: EdgeInsets.only( + top: 20.0, + left: 10.0, + right: 10.0, + bottom: 10.0, ), - ) - ], - ), - ), - Divider( - color: Colors.grey[350], - height: 20, - thickness: 5, - indent: 0, - endIndent: 0, - ), - SizedBox( - height: 15, - ), - Container( - child: Row( - children: [ - Expanded( - child: InkWell( - onTap: () { - if (customerId == null) { - AppToast.showErrorToast( - message: "Customer not found"); - return; - } - Navigator.push( - context, - FadePage( - page: OrderPage( - customerID: customerId))); - }, - child: Column( - children: [ -// Image(image: AssetImage('assets/images/pharmacy/orders_icon.svg')), - SvgPicture.asset( - 'assets/images/pharmacy/orders_icon.svg', - width: 50, - height: 50, - ), - SizedBox( - height: 5, - ), - Text( - TranslationBase.of(context).orders, - style: TextStyle( - fontSize: 13.0, - fontWeight: FontWeight.bold, - ), - ), - ], + child: LargeAvatar( + name: user!.firstName.toString(), + url: '', ), ), - ), - Expanded( - child: InkWell( - onTap: () { - Navigator.push(context, - FadePage(page: LakumMainPage())); - }, - child: Column( - children: [ - SvgPicture.asset( - 'assets/images/pharmacy/lakum_icon.svg', - width: 50, - height: 50, - ), - SizedBox( - height: 5, - ), - Text( - TranslationBase.of(context).lakum, - style: TextStyle( - fontSize: 13.0, - fontWeight: FontWeight.bold), - ), - ], + Column(children: [ + Row(children: [ + Text( + TranslationBase.of(context).welcome, + style: TextStyle(fontSize: 14.0, fontWeight: FontWeight.bold, color: Colors.grey), + ), + ]), + SizedBox( + height: 10, ), + Row(children: [ + Text( + languageID == "ar" ? user!.firstNameN!.toString() + " " + user!.lastNameN!.toString() : user!.firstName!.toString() + " " + user!.lastName!.toString(), + style: TextStyle(fontSize: 14.0, fontWeight: FontWeight.bold), + ), + ]), + ]), + ], + ), + ) + ], + ), + ), + Divider( + color: Colors.grey[350], + height: 20, + thickness: 5, + indent: 0, + endIndent: 0, + ), + SizedBox( + height: 15, + ), + Container( + child: Row( + children: [ + Expanded( + child: InkWell( + onTap: () { + if (customerId == null) { + AppToast.showErrorToast(message: "Customer not found"); + return; + } + Navigator.push(context, FadePage(page: OrderPage(customerID: customerId!, customerGUID: customerGUID!))); + }, + child: Column( + children: [ +// Image(image: AssetImage('assets/images/pharmacy/orders_icon.svg')), + SvgPicture.asset( + 'assets/images/pharmacy/orders_icon.svg', + width: 50, + height: 50, ), - ), - Expanded( - child: InkWell( - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => - WishlistPage(true))); - }, - child: Column( - children: [ - SvgPicture.asset( - 'assets/images/pharmacy/wishlist_icon.svg', - width: 50, - height: 50, - ), - SizedBox( - height: 5, - ), - Text( - TranslationBase.of(context).wishlist, - style: TextStyle( - fontSize: 13.0, - fontWeight: FontWeight.bold, - ), - ), - ], - ), + SizedBox( + height: 5, ), - ), - Expanded( - child: InkWell( - onTap: () { - Navigator.push(context, - FadePage(page: MyReviewsPage())); - }, - child: Column( - children: [ - SvgPicture.asset( - 'assets/images/pharmacy/review_icon.svg', - width: 50, - height: 50, - ), - SizedBox( - height: 5, - ), - Text( - TranslationBase.of(context).reviews, - style: TextStyle( - fontSize: 13.0, - fontWeight: FontWeight.bold, - ), - ), - ], + Text( + TranslationBase.of(context).orders, + style: TextStyle( + fontSize: 13.0, + fontWeight: FontWeight.bold, ), ), - ), - ], - )), - SizedBox( - height: 15, - ), - Divider( - color: Colors.grey[350], - height: 20, - thickness: 5, - indent: 0, - endIndent: 0, - ), - SizedBox( - height: 10, + ], + ), ), - Container( - padding: EdgeInsets.only(left: 10.0), + ), + Expanded( + child: InkWell( + onTap: () { + if (customerId == null || customerId == '') + Navigator.push(context, FadePage(page: LakumActivationVidaPage())); + else + Navigator.push(context, FadePage(page: LakumMainPage())); + }, child: Column( - crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - TranslationBase.of(context).myAccount, - style: TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.bold), + SvgPicture.asset( + 'assets/images/pharmacy/lakum_icon.svg', + width: 50, + height: 50, ), SizedBox( - height: 10, + height: 5, ), - Divider( - color: Colors.grey, - height: 20, + Text( + TranslationBase.of(context).lakum, + style: TextStyle(fontSize: 13.0, fontWeight: FontWeight.bold), ), - InkWell( - onTap: () { - Navigator.push( - context, - FadePage( - page: HomePrescriptionsPage())); - }, - child: Row( - children: [ - SvgPicture.asset( - 'assets/images/pharmacy/my_prescription_icon.svg', - width: 28, - height: 28, - ), - SizedBox( - width: 15, - ), - Text( - TranslationBase.of(context) - .myPrescription, - style: TextStyle( - fontSize: 13.0, - ), - ), - ], - ), + ], + ), + ), + ), + Expanded( + child: InkWell( + onTap: () { + Navigator.push(context, FadePage(page: WishlistPage())); + }, + child: Column( + children: [ + SvgPicture.asset( + 'assets/images/pharmacy/wishlist_icon.svg', + width: 50, + height: 50, ), SizedBox( height: 5, ), - Divider( - color: Colors.grey, - height: 20, - ), - InkWell( - onTap: () { - Navigator.push(context, - FadePage(page: ComparePage())); - }, - child: Row( - children: [ - Image.asset( - 'assets/images/pharmacy/compare.png', - width: 35, - height: 35), - SizedBox( - width: 15, - ), - Text( - TranslationBase.of(context).compare, - style: TextStyle( - fontSize: 13.0, - ), - ), - ], + Text( + TranslationBase.of(context).wishlist, + style: TextStyle( + fontSize: 13.0, + fontWeight: FontWeight.bold, ), ), + ], + ), + ), + ), + Expanded( + child: InkWell( + onTap: () { + Navigator.push(context, FadePage(page: MyReviewsPage())); + }, + child: Column( + children: [ + SvgPicture.asset( + 'assets/images/pharmacy/review_icon.svg', + width: 50, + height: 50, + ), SizedBox( height: 5, ), - Divider( - color: Colors.grey, - height: 20, - ), - InkWell( - onTap: () { - Navigator.push( - context, - FadePage( - page: HomePrescriptionsPage())); - }, - child: Row( - children: [ - SvgPicture.asset( - 'assets/images/pharmacy/medication_refill_icon.svg', - width: 30, - height: 30, - ), - SizedBox( - width: 20, - ), - Text( - TranslationBase.of(context) - .medicationsRefill, - style: TextStyle( - fontSize: 13.0, - ), - ), - ], + Text( + TranslationBase.of(context).reviews, + style: TextStyle( + fontSize: 13.0, + fontWeight: FontWeight.bold, ), ), - SizedBox( - height: 5, + ], + ), + ), + ), + ], + )), + SizedBox( + height: 15, + ), + Divider( + color: Colors.grey[350], + height: 20, + thickness: 5, + indent: 0, + endIndent: 0, + ), + SizedBox( + height: 10, + ), + Container( + padding: EdgeInsets.only(left: 10.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).myAccount, + style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold), + ), + SizedBox( + height: 10, + ), + Divider( + color: Colors.grey, + height: 20, + ), + InkWell( + onTap: () { + Navigator.push(context, FadePage(page: HomePrescriptionsPage())); + }, + child: Row( + children: [ + SvgPicture.asset( + 'assets/images/pharmacy/my_prescription_icon.svg', + width: 28, + height: 28, ), - Divider( - color: Colors.grey, - height: 20, + SizedBox( + width: 15, ), - InkWell( - onTap: () { - Navigator.push( - context, FadePage(page: MyFamily())); - }, - child: Row( - children: [ - SvgPicture.asset( - 'assets/images/pharmacy/my_family_icon.svg', - width: 20, - height: 20, - ), - SizedBox( - width: 20, - ), - Text( - TranslationBase.of(context).family, - style: TextStyle( - fontSize: 13.0, - ), - ), - ], + Text( + TranslationBase.of(context).myPrescription, + style: TextStyle( + fontSize: 13.0, ), ), + ], + ), + ), + SizedBox( + height: 5, + ), + Divider( + color: Colors.grey, + height: 20, + ), + InkWell( + onTap: () { + Navigator.push(context, FadePage(page: ComparePage())); + }, + child: Row( + children: [ + Image.asset('assets/images/pharmacy/compare.png', width: 35, height: 35), SizedBox( - height: 5, - ), - Divider( - color: Colors.grey, - height: 20, + width: 15, ), - InkWell( - onTap: () { - Navigator.push( - context, - FadePage( - page: PharmacyAddressesPage())); - }, - child: Row( - children: [ - SvgPicture.asset( - 'assets/images/pharmacy/shipping_addresses_icon.svg', - width: 30, - height: 30, - ), - SizedBox( - width: 20, - ), - Text( - TranslationBase.of(context) - .shippingAddresses, - style: TextStyle( - fontSize: 13.0, - ), - ), - ], + Text( + TranslationBase.of(context).compare, + style: TextStyle( + fontSize: 13.0, ), ), + ], + ), + ), + SizedBox( + height: 5, + ), + Divider( + color: Colors.grey, + height: 20, + ), + InkWell( + onTap: () { + Navigator.push(context, FadePage(page: HomePrescriptionsPage())); + }, + child: Row( + children: [ + SvgPicture.asset( + 'assets/images/pharmacy/medication_refill_icon.svg', + width: 30, + height: 30, + ), SizedBox( - height: 5, + width: 20, ), - Divider( - color: Colors.grey, + Text( + TranslationBase.of(context).medicationsRefill, + style: TextStyle( + fontSize: 13.0, + ), + ), + ], + ), + ), + SizedBox( + height: 5, + ), + Divider( + color: Colors.grey, + height: 20, + ), + InkWell( + onTap: () { + Navigator.push(context, FadePage(page: MyFamily())); + }, + child: Row( + children: [ + SvgPicture.asset( + 'assets/images/pharmacy/my_family_icon.svg', + width: 20, height: 20, ), - InkWell( - onTap: () { - Navigator.push( - context, - FadePage( - page: PharmacyTermsConditions())); - }, - child: Row( - children: [ - Image.asset( - 'assets/images/pharmacy/terms.png', - width: 25, - height: 25, - ), - SizedBox( - width: 10, - ), - Text( - TranslationBase.of(context) - .conditionsHMG, - style: TextStyle( - fontSize: 13.0, - ), - ), - ], + SizedBox( + width: 20, + ), + Text( + TranslationBase.of(context).family, + style: TextStyle( + fontSize: 13.0, ), ), - SizedBox( - height: 5, + ], + ), + ), + SizedBox( + height: 5, + ), + Divider( + color: Colors.grey, + height: 20, + ), + InkWell( + onTap: () { + Navigator.push(context, FadePage(page: PharmacyAddressesPage(isShippingAddress: false))); + }, + child: Row( + children: [ + SvgPicture.asset( + 'assets/images/pharmacy/shipping_addresses_icon.svg', + width: 30, + height: 30, ), - Divider( - color: Colors.grey, - height: 20, + SizedBox( + width: 20, ), - InkWell( - onTap: () { - Navigator.push( - context, - FadePage( - page: LakumTermsConditions( - this.identificationNo, - this.firstName, - this.lastName, - this.mobileNo, - this.languageId))); - }, - child: Row( - children: [ - Image.asset( - 'assets/images/pharmacy/terms.png', - width: 25, - height: 25, - ), -// IconButton(icon: Icon(Icons.error_outline), iconSize: 30, -// color: Colors.black,), - SizedBox( - width: 10, - ), - Text( - TranslationBase.of(context) - .conditions, - style: TextStyle( - fontSize: 13.0, - ), - ), - ], + Text( + TranslationBase.of(context).shippingAddresses, + style: TextStyle( + fontSize: 13.0, ), ), ], ), ), SizedBox( - height: 10, + height: 5, ), Divider( - color: Colors.grey[350], + color: Colors.grey, height: 20, - thickness: 5, - indent: 0, - endIndent: 0, + ), + InkWell( + onTap: () { + Navigator.push(context, FadePage(page: PharmacyTermsConditions())); + }, + child: Row( + children: [ + Image.asset( + 'assets/images/pharmacy/terms.png', + width: 25, + height: 25, + ), + SizedBox( + width: 10, + ), + Text( TranslationBase.of(context).termOfService, + // TranslationBase.of(context).conditionsHMG, + style: TextStyle( + fontSize: 13.0, + ), + ), + ], + ), ), SizedBox( - height: 10, + height: 5, ), - Container( - padding: EdgeInsets.only(left: 10.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + Divider( + color: Colors.grey, + height: 20, + ), + InkWell( + onTap: () { + Navigator.push(context, FadePage(page: LakumTermsConditions(this.identificationNo!, this.firstName!, this.lastName!, this.mobileNo!, this.languageId!))); + }, + child: Row( children: [ + Image.asset( + 'assets/images/pharmacy/terms.png', + width: 25, + height: 25, + ), +// IconButton(icon: Icon(Icons.error_outline), iconSize: 30, +// color: Colors.black,), + SizedBox( + width: 10, + ), Text( - TranslationBase.of(context).reachUs, + TranslationBase.of(context).conditions, style: TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.bold), + fontSize: 13.0, + ), + ), + ], + ), + ), + ], + ), + ), + SizedBox( + height: 10, + ), + Divider( + color: Colors.grey[350], + height: 20, + thickness: 5, + indent: 0, + endIndent: 0, + ), + SizedBox( + height: 10, + ), + Container( + padding: EdgeInsets.only(left: 10.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).reachUs, + style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold), + ), + SizedBox( + height: 5, + ), + Divider( + color: Colors.grey, + height: 20, + ), + InkWell( + onTap: () { + Navigator.push(context, FadePage(page: pharmacyContactsPage())); + }, + child: Row( + children: [ + SvgPicture.asset( + 'assets/images/pharmacy/contact_us_icon.svg', + width: 20, + height: 20, ), SizedBox( - height: 5, + width: 20, ), - Divider( - color: Colors.grey, - height: 20, + Text( + TranslationBase.of(context).contactUs, + style: TextStyle(fontSize: 13.0), ), - InkWell( - onTap: () { - Navigator.push(context, - FadePage(page: LiveChatPage())); - }, - child: Row( - children: [ - SvgPicture.asset( - 'assets/images/pharmacy/contact_us_icon.svg', - width: 20, - height: 20, - ), - SizedBox( - width: 20, - ), - Text( - TranslationBase.of(context).contactUs, - style: TextStyle(fontSize: 13.0), - ), - ], - ), + ], + ), + ), + SizedBox( + height: 5, + ), + Divider( + color: Colors.grey, + height: 20, + ), + InkWell( + onTap: () { + Navigator.push(context, FadePage(page: FindUsPage())); + }, + child: Row( + children: [ + SvgPicture.asset( + 'assets/images/pharmacy/our_locations_icon.svg', + width: 30, + height: 30, ), SizedBox( - height: 5, + width: 20, ), - Divider( - color: Colors.grey, - height: 20, + Text( + TranslationBase.of(context).ourLocations, + style: TextStyle(fontSize: 13.0), ), - InkWell( - onTap: () { - Navigator.push(context, - FadePage(page: FindUsPage())); - }, - child: Row( - children: [ - SvgPicture.asset( - 'assets/images/pharmacy/our_locations_icon.svg', - width: 30, - height: 30, - ), - SizedBox( - width: 20, - ), - Text( - TranslationBase.of(context) - .ourLocations, - style: TextStyle(fontSize: 13.0), - ), - ], - ), - ) ], ), ) ], ), - ), - ) - : Container(), - )); + ) + ], + ), + ), + ) + : Container(), + ), + ); } } diff --git a/lib/pages/pharmacy_categorise.dart b/lib/pages/pharmacy_categorise.dart index ff1920dc..a748ed90 100644 --- a/lib/pages/pharmacy_categorise.dart +++ b/lib/pages/pharmacy_categorise.dart @@ -1,6 +1,6 @@ import 'dart:convert'; -import 'package:barcode_scan_fix/barcode_scan.dart'; +import 'package:barcode_scan2/barcode_scan2.dart'; import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacy_categorise_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; @@ -23,17 +23,20 @@ class PharmacyCategorisePage extends StatefulWidget { } class _PharmacyCategorisePageState extends State { - String idCategorise; + String? idCategorise; @override Widget build(BuildContext context) { ProjectViewModel projectViewModel = Provider.of(context); return BaseView( onModelReady: (model) => model.getCategorise(), - builder: (BuildContext context, PharmacyCategoriseViewModel model, - Widget child) => - AppScaffold( + allowAny: true, + builder: (BuildContext context, PharmacyCategoriseViewModel model, Widget? child) => AppScaffold( isShowDecPage: false, + isShowAppBar: false, + isMainPharmacyPages: true, + isPharmacy: true, + isShowPharmacyAppbar: true, baseViewModel: model, body: Column( children: [ @@ -61,9 +64,7 @@ class _PharmacyCategorisePageState extends State { child: Padding( padding: EdgeInsets.symmetric(horizontal: 10.0), child: Texts( - projectViewModel.isArabic - ? model.categorise[index].namen - : model.categorise[index].name, + projectViewModel.isArabic ? model.categorise[index].namen : model.categorise[index].name, fontWeight: FontWeight.w600, ), ), @@ -75,7 +76,8 @@ class _PharmacyCategorisePageState extends State { page: model.categorise[index].id != '12' ? ParentCategorisePage( id: model.categorise[index].id, - titleName: model.categorise[index].name, + titleName: projectViewModel.isArabic ? model.categorise[index].namen : model.categorise[index].name, + // titleName: model.categorise[index].name, ) : FinalProductsPage( id: model.categorise[index].id, @@ -93,10 +95,7 @@ class _PharmacyCategorisePageState extends State { height: 140, child: Column( children: [ - Divider( - height: 2.0, - thickness: 1.0, - color: Colors.black12.withOpacity(0.14)), + Divider(height: 2.0, thickness: 1.0, color: Colors.black12.withOpacity(0.14)), SizedBox( height: 10.0, ), @@ -122,16 +121,12 @@ class _PharmacyCategorisePageState extends State { width: 55.0, decoration: BoxDecoration( borderRadius: BorderRadius.circular(5.0), - color: - Colors.green.shade300.withOpacity(0.34), + color: Colors.green.shade300.withOpacity(0.34), ), child: Padding( - padding: - EdgeInsets.symmetric(horizontal: 10.0), + padding: EdgeInsets.symmetric(horizontal: 10.0), child: Texts( - projectViewModel.isArabic - ? 'الاكثر مبيعا' - : 'Best Sellers', + projectViewModel.isArabic ? 'الاكثر مبيعا' : 'Best Sellers', fontWeight: FontWeight.w600, ), ), @@ -158,17 +153,13 @@ class _PharmacyCategorisePageState extends State { height: 50.0, width: 55.0, decoration: BoxDecoration( - color: Colors.orangeAccent.shade200 - .withOpacity(0.34), + color: Colors.orangeAccent.shade200.withOpacity(0.34), borderRadius: BorderRadius.circular(5.0), ), child: Padding( - padding: - EdgeInsets.symmetric(horizontal: 10.0), + padding: EdgeInsets.symmetric(horizontal: 10.0), child: Texts( - projectViewModel.isArabic - ? 'الاكثر مشاهدة' - : 'Most Viewed', + projectViewModel.isArabic ? 'الاكثر مشاهدة' : 'Most Viewed', fontWeight: FontWeight.w600, ), ), @@ -203,12 +194,9 @@ class _PharmacyCategorisePageState extends State { borderRadius: BorderRadius.circular(5.0), ), child: Padding( - padding: - EdgeInsets.symmetric(horizontal: 10.0), + padding: EdgeInsets.symmetric(horizontal: 10.0), child: Texts( - projectViewModel.isArabic - ? 'منتجات جديدة' - : 'New Products', + projectViewModel.isArabic ? 'منتجات جديدة' : 'New Products', fontWeight: FontWeight.w600, ), ), @@ -235,17 +223,13 @@ class _PharmacyCategorisePageState extends State { height: 50.0, width: 55.0, decoration: BoxDecoration( - color: - Colors.purple.shade200.withOpacity(0.34), + color: Colors.purple.shade200.withOpacity(0.34), borderRadius: BorderRadius.circular(5.0), ), child: Padding( - padding: - EdgeInsets.symmetric(horizontal: 10.0), + padding: EdgeInsets.symmetric(horizontal: 10.0), child: Texts( - projectViewModel.isArabic - ? 'شوهد مؤخرا' - : 'Recently Viewed', + projectViewModel.isArabic ? 'شوهد مؤخرا' : 'Recently Viewed', fontWeight: FontWeight.w600, ), ), @@ -271,7 +255,9 @@ class _PharmacyCategorisePageState extends State { /// When give qr we will change this method to get data /// var result = await BarcodeScanner.scan(); /// int patientID = get from qr result - String result = await BarcodeScanner.scan(); + String result = await BarcodeScanner.scan().then((value) { + return value.rawContent; + }); var data = json.decode(result); if (data != null) { var qRParkingID = data['QRParkingID']; @@ -279,7 +265,7 @@ class _PharmacyCategorisePageState extends State { if (model.state == ViewState.ErrorLocal) { Utils.showErrorToast(model.error); } else { - AppToast.showSuccessToast(message: model.scanList[0].id); + AppToast.showSuccessToast(message: model.scanList[0].id!); { Navigator.push( context, diff --git a/lib/pages/rateAppointment/rate_appointment_clinic.dart b/lib/pages/rateAppointment/rate_appointment_clinic.dart index bf0f4b4e..4dbc3edd 100644 --- a/lib/pages/rateAppointment/rate_appointment_clinic.dart +++ b/lib/pages/rateAppointment/rate_appointment_clinic.dart @@ -1,31 +1,28 @@ -import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/rate/appointment_details.dart'; -import 'package:diplomaticquarterapp/core/model/rate/appoitment_rated.dart'; import 'package:diplomaticquarterapp/core/viewModels/appointment_rate_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; -import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/theme/colors.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/avatar/large_avatar.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; -import 'package:diplomaticquarterapp/widgets/drawer/app_drawer_widget.dart'; -import 'package:diplomaticquarterapp/widgets/input/text_field.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:diplomaticquarterapp/widgets/my_rich_text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; -import 'package:eva_icons_flutter/eva_icons_flutter.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:hexcolor/hexcolor.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:provider/provider.dart'; class RateAppointmentClinic extends StatefulWidget { - final AppointmentDetails appointmentDetails; - final String doctorNote; - final int doctorRate; + late final AppointmentDetails? appointmentDetails; + late final String? doctorNote; + late final int? doctorRate; - RateAppointmentClinic( - {this.appointmentDetails, this.doctorRate, this.doctorNote}); + RateAppointmentClinic({this.appointmentDetails, this.doctorRate, this.doctorNote}); @override _RateAppointmentClinicState createState() => _RateAppointmentClinicState(); @@ -35,204 +32,233 @@ class _RateAppointmentClinicState extends State { final formKey = GlobalKey(); String note = ""; int rating = 0; + late ProjectViewModel projectViewModel; @override Widget build(BuildContext context) { + projectViewModel = Provider.of(context); return BaseView( builder: (_, model, w) => AppScaffold( + isShowAppBar: true, + showNewAppBar: true, + showNewAppBarTitle: true, baseViewModel: model, - body: Scaffold( - backgroundColor: Colors.grey[200], - appBar: AppBar( - elevation: 0, - textTheme: TextTheme( - headline6: - TextStyle(color: Colors.white, fontWeight: FontWeight.bold), - ), - title: Text('Rate'), - leading: Builder( - builder: (BuildContext context) { - return IconButton( - icon: Icon(Icons.menu), - color: Colors.white, - onPressed: () => Scaffold.of(context).openDrawer(), - ); - }, - ), - centerTitle: true, - ), - drawer: SafeArea(child: AppDrawer()), - body: FractionallySizedBox( - widthFactor: 1, - child: SingleChildScrollView( - child: Container( - padding: EdgeInsets.all(12), - child: Column( - children: [ - SizedBox( - height: 25, - ), - Texts( - TranslationBase.of(context).lastAppointment, - bold: true, - color: Colors.black, - ), - SizedBox( - height: 25, + appBarTitle: TranslationBase.of(context).rateAppointment, + body: SingleChildScrollView( + child: Container( + padding: EdgeInsets.all(12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).lastAppointment, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64, height: 23 / 16), + ), + SizedBox( + height: 25, + ), + Container( + decoration: cardRadius(10), + child: Padding( + padding: const EdgeInsets.only(left: 12, right: 12, top: 12, bottom: 12), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + margin: EdgeInsets.only(bottom: 10.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + model.appointmentDetails.projectName ?? '', + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.64, height: 25 / 16), + ), + Text( + model.appointmentDetails.startTime != "" ? model.appointmentDetails.startTime.toString().substring(0, 5) : "", + style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.64, height: 25 / 16), + ), + ], + ), + ), + Row( + mainAxisSize: MainAxisSize.min, + children: [ + LargeAvatar( + url: 'https://hmgwebservices.com/Images/Hospitals/' + model.appointmentDetails.projectID.toString() + '.jpg', + width: 48, + height: 48, + ), + SizedBox(width: 11), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + MyRichText(TranslationBase.of(context).clinic + ":", model.appointmentDetails.projectName ?? "", projectViewModel.isArabic), + MyRichText(TranslationBase.of(context).date + ":", DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(model.appointmentDetails.appointmentDate)), + projectViewModel.isArabic), + ], + ), + ), + ], + ), + ], ), - Container( - width: double.infinity, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(15), - color: Colors.white, - shape: BoxShape.rectangle, - border: Border.all(color: Colors.white, width: 0.5), - ), + ), + ), + SizedBox( + height: 12, + ), + Container( + width: double.infinity, + child: Container( + decoration: cardRadius(10), + child: Padding( + padding: const EdgeInsets.all(12.0), child: Column( - children: [ - SizedBox( - height: 8, - ), - LargeAvatar( - name: model.appointmentDetails.clinicName, - width: 110, - height: 110, - ), - SizedBox( - height: 22, - ), - Texts( - model.appointmentDetails.projectName, - bold: true, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).rateClinic, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64, height: 23 / 16), ), SizedBox( - height: 4, + height: 12, ), - Texts( - model.appointmentDetails.clinicName, - bold: true, + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ...List.generate( + 5, + (index) => AnimatedSwitcher( + duration: Duration(milliseconds: 300), + switchInCurve: Curves.elasticOut, + switchOutCurve: Curves.elasticIn, + transitionBuilder: (Widget child, Animation animation) { + return ScaleTransition(child: child, scale: animation); + }, + child: rating == (index + 1) + ? Container( + margin: EdgeInsets.only(left: 3.0, right: 3.0), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(100), border: Border.all(width: 3, color: CustomColors.green)), + key: ValueKey(rating), + child: IconButton( + onPressed: () { + setState(() { + rating = index + 1; + }); + }, + iconSize: 35, + icon: SvgPicture.asset('assets/images/new/appointment-rating/' + (index + 1).toString() + '.svg'), + ), + ) + : Container( + key: ValueKey(rating), + child: IconButton( + onPressed: () { + setState(() { + rating = index + 1; + }); + }, + iconSize: 35, + icon: SvgPicture.asset('assets/images/new/appointment-rating/' + (index + 1).toString() + '.svg'), + ), + ), + ), + ) + ], ), - SizedBox( - height: 8, - ) ], ), ), - SizedBox( - height: 12, - ), - Center( - child: Texts( - TranslationBase.of(context).rateClinic, - textAlign: TextAlign.center, - )), - SizedBox( - height: 12, - ), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - ...List.generate( - 5, - (index) => AnimatedSwitcher( - duration: Duration(milliseconds: 1000), - switchInCurve: Curves.elasticOut, - switchOutCurve: Curves.elasticIn, - transitionBuilder: - (Widget child, Animation animation) { - return ScaleTransition( - child: child, scale: animation); - }, - child: Container( - key: ValueKey(rating), - child: IconButton( - iconSize: 45.0, - onPressed: () { - setState(() { - rating = index + 1; - }); - }, - color: rating >= (index + 1) - ? Color.fromRGBO(255, 186, 0, 1.0) - : Colors.grey[400], - // Theme.of(context).hintColor, - icon: Icon(rating >= (index + 1) - ? EvaIcons.star - : EvaIcons.star)), - ), - ), - ) - ], - ), - SizedBox(height: 12), - SizedBox( - height: 12, - ), - ], - ), - ), - ), - ), - bottomSheet: Container( - height: MediaQuery.of(context).size.height * 0.15, - width: double.infinity, - color: Colors.grey[200], - child: Column( - children: [ - Container( - width: MediaQuery.of(context).size.width * 0.9, - child: SecondaryButton( - onTap: () async { - if (rating > 0) { - model - .sendAppointmentRate( - rating, - widget.appointmentDetails.appointmentNo, - widget.appointmentDetails.projectID, - widget.appointmentDetails.doctorID, - widget.appointmentDetails.clinicID, - note) - .then( - (value) => { - Navigator.pushReplacement( - context, - FadePage( - page: LandingPage(), - ), - ) - }, - ); - } else { - AppToast.showErrorToast( - message: 'please rate the clinic'); - } - }, - label: TranslationBase.of(context).submit, - disabled: (model.state == ViewState.Busy || rating==0), - // loading: model.state == ViewState.BusyLocal, - textColor: Theme.of(context).backgroundColor), + ), ), + SizedBox(height: 12), SizedBox( height: 12, ), - InkWell( - onTap: () { + ], + ), + ), + ), + bottomSheet: Container( + color: Colors.white, + padding: EdgeInsets.only(top: 16, bottom: 16, right: 21, left: 21), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Expanded( + child: DefaultButton( + TranslationBase.of(context).later, + () { Navigator.pushReplacement( context, FadePage( page: LandingPage(), ), ); + // if (projectViewModel.isLoginChild) { + // Navigator.pushReplacement( + // context, + // FadePage( + // page: LandingPage(), + // ), + // ); + // } else { + // Navigator.pop( + // context, + // // FadePage( + // // page: LandingPage(), + // // ), + // ); + // } }, - child: Texts( - TranslationBase.of(context).later, - decoration: TextDecoration.underline, - color: HexColor('#151DFE'), - fontSize: 18, - ), - ) - ], - ), + color: CustomColors.accentColor, + textColor: Colors.white, + ), + ), + SizedBox(width: 10), + Expanded( + child: DefaultButton( + TranslationBase.of(context).submit, + rating <= 0 + ? null + : () { + int languageID = projectViewModel.isArabic ? 1 : 2; + model + .sendAppointmentRate(rating, widget.appointmentDetails!.appointmentNo!, widget.appointmentDetails!.projectID!, widget.appointmentDetails!.doctorID!, + widget.appointmentDetails!.clinicID!, note, languageID) + .then( + (value) => { + model + .sendDoctorRate( + widget.doctorRate!, + widget.appointmentDetails!.appointmentNo!, + widget.appointmentDetails!.projectID!, + widget.appointmentDetails!.doctorID!, + widget.appointmentDetails!.clinicID!, + note, + widget.appointmentDetails!.appointmentDate, + widget.appointmentDetails!.doctorName, + widget.appointmentDetails!.projectName, + widget.appointmentDetails!.clinicName) + .then((value) { + Navigator.pushReplacement( + context, + FadePage( + page: LandingPage(), + ), + ); + }), + }, + ); + }, + color: Color(0xff359846), + disabledColor: Colors.grey, + ), + ), + ], ), ), ), diff --git a/lib/pages/rateAppointment/rate_appointment_doctor.dart b/lib/pages/rateAppointment/rate_appointment_doctor.dart index 71aacae2..fba43fbe 100644 --- a/lib/pages/rateAppointment/rate_appointment_doctor.dart +++ b/lib/pages/rateAppointment/rate_appointment_doctor.dart @@ -1,23 +1,29 @@ -import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; -import 'package:diplomaticquarterapp/core/model/rate/appointment_details.dart'; import 'package:diplomaticquarterapp/core/viewModels/appointment_rate_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/widgets/DoctorView.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/pages/insurance/insurance_update_screen.dart'; import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; import 'package:diplomaticquarterapp/pages/rateAppointment/rate_appointment_clinic.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/widgets/avatar/large_avatar.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; -import 'package:diplomaticquarterapp/widgets/drawer/app_drawer_widget.dart'; -import 'package:diplomaticquarterapp/widgets/input/text_field.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; -import 'package:eva_icons_flutter/eva_icons_flutter.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:hexcolor/hexcolor.dart'; +import 'package:provider/provider.dart'; class RateAppointmentDoctor extends StatefulWidget { + + bool isFromRegistration; + + RateAppointmentDoctor({Key? key, this.isFromRegistration = false}) : super(key: key); + @override _RateAppointmentDoctorState createState() => _RateAppointmentDoctorState(); } @@ -26,219 +32,234 @@ class _RateAppointmentDoctorState extends State { final formKey = GlobalKey(); String note = ""; int rating = 0; + ProjectViewModel? projectViewModel; @override Widget build(BuildContext context) { + projectViewModel = Provider.of(context); return BaseView( builder: (_, model, w) => AppScaffold( + isShowAppBar: true, + showNewAppBar: true, + showNewAppBarTitle: true, baseViewModel: model, - body: Scaffold( - backgroundColor: Colors.grey[200], - appBar: AppBar( - elevation: 0, - textTheme: TextTheme( - headline6: - TextStyle(color: Colors.white, fontWeight: FontWeight.bold), - ), - title: Text(TranslationBase.of(context).rate), - leading: Builder( - builder: (BuildContext context) { - return IconButton( - icon: Icon(Icons.menu), - color: Colors.white, - onPressed: () => Scaffold.of(context).openDrawer(), - ); - }, - ), - centerTitle: true, - ), - drawer: SafeArea(child: AppDrawer()), - body: FractionallySizedBox( - widthFactor: 1, - child: SingleChildScrollView( - child: Container( - padding: EdgeInsets.all(12), - child: Column( - children: [ - SizedBox( - height: 25, //5598 - ), - Texts( - TranslationBase.of(context).lastVisit, - bold: true, - color: Colors.black, - ), - SizedBox( - height: 25, - ), - Container( - width: double.infinity, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(15), - color: Colors.white, - shape: BoxShape.rectangle, - border: Border.all(color: Colors.white, width: 0.5), - ), + appBarTitle: TranslationBase.of(context).rateDoctor, + body: SingleChildScrollView( + child: Container( + padding: EdgeInsets.all(12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).lastVisit, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + height: 23 / 16), + ), + SizedBox( + height: 25, + ), + Container( + child: DoctorView( + doctor: getDoctorObject(model), + isLiveCareAppointment: false, + isShowFlag: false, + ), + ), + SizedBox( + height: 12, + ), + Container( + width: double.infinity, + child: Container( + decoration: cardRadius(10), + child: Padding( + padding: const EdgeInsets.all(12.0), child: Column( - children: [ - SizedBox( - height: 8, - ), - LargeAvatar( - name: model.appointmentDetails.doctorName, - url: model.appointmentDetails.doctorImageURL, - width: 110, - height: 110, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).tapTitle, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + height: 23 / 16), ), SizedBox( - height: 22, - ), - Texts( - TranslationBase.of(context).dr + " " + model.appointmentDetails.doctorName, - bold: true, - ), - SizedBox( - height: 4, + height: 12, ), - Texts( - model.appointmentDetails.clinicName != null ? model.appointmentDetails.clinicName : "", - bold: true, + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ...List.generate( + 5, + (index) => AnimatedSwitcher( + duration: Duration(milliseconds: 1000), + switchInCurve: Curves.elasticOut, + switchOutCurve: Curves.elasticIn, + transitionBuilder: (Widget child, + Animation animation) { + return ScaleTransition( + child: child, scale: animation); + }, + child: Container( + key: ValueKey(rating), + child: IconButton( + iconSize: 45.0, + onPressed: () { + setState(() { + rating = index + 1; + }); + }, + color: rating >= (index + 1) + ? Color.fromRGBO(255, 186, 0, 1.0) + : Colors.grey[400], + icon: Icon(rating >= (index + 1) + ? Icons.star + : Icons.star)), + ), + ), + ) + ], ), - SizedBox( - height: 8, - ) ], ), ), - SizedBox( - height: 12, - ), - Center( - child: Texts( - TranslationBase.of(context).tapTitle, - textAlign: TextAlign.center, - )), - SizedBox( - height: 12, - ), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - ...List.generate( - 5, - (index) => AnimatedSwitcher( - duration: Duration(milliseconds: 1000), - switchInCurve: Curves.elasticOut, - switchOutCurve: Curves.elasticIn, - transitionBuilder: - (Widget child, Animation animation) { - return ScaleTransition( - child: child, scale: animation); - }, - child: Container( - key: ValueKey(rating), - child: IconButton( - iconSize: 45.0, - onPressed: () { - setState(() { - rating = index + 1; - }); - }, - color: rating >= (index + 1) - ? Color.fromRGBO(255, 186, 0, 1.0) - : Colors.grey[400], - // Theme.of(context).hintColor, - icon: Icon(rating >= (index + 1) - ? EvaIcons.star - : EvaIcons.star)), - ), - ), - ) - ], - ), - SizedBox( - height: 12, - ), - Form( - key: formKey, - child: TextFields( - hintText: TranslationBase.of(context).notes, - minLines: 4, - maxLines: 4, - // validator: (value) { - // if (value.isEmpty) - // return 'Please enter your note'; - // else if (rating == 0) return 'Rating cannot be \"0\"'; - // return null; - // }, - onChanged: (value) { - setState(() { - note = value; + ), + ), + SizedBox( + height: 12, + ), + Container( + decoration: cardRadius(10), + child: Padding( + padding: EdgeInsets.all(8.0), + child: TextField( + maxLines: 5, + decoration: InputDecoration.collapsed( + hintText: TranslationBase.of(context).notes, + hintStyle: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + height: 23 / 16)), + onChanged: (value) { + setState(() { + note = value; + }); + }, + ))), + ], + ), + ), + ), + bottomSheet: Container( + color: Colors.white, + padding: EdgeInsets.only(top: 16, bottom: 16, right: 21, left: 21), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Expanded( + child: DefaultButton( + TranslationBase.of(context).later, + () { + if(widget.isFromRegistration) { + ConfirmDialog dialog = new ConfirmDialog( + context: context, + confirmMessage: TranslationBase.of(context).validInsurance, + okText: TranslationBase.of(context).yes, + cancelText: TranslationBase.of(context).no, + okFunction: () { + ConfirmDialog.closeAlertDialog(context); + Navigator.pushAndRemoveUntil( + context, + MaterialPageRoute(builder: (context) => LandingPage()), + (Route route) => false, + ); + Navigator.push(context, FadePage(page: InsuranceUpdate())); + }, + cancelFunction: () { + Navigator.pushAndRemoveUntil( + context, + MaterialPageRoute(builder: (context) => LandingPage()), + (Route route) => false, + ); }); - }, - ), - ), - SizedBox( - height: 12, - ), - Container( - width: double.infinity, - child: Column( - children: [ - Container( - width: MediaQuery.of(context).size.width * 0.9, - child: SecondaryButton( - onTap: () async { - final form = formKey.currentState; - if (form.validate() && rating>0 ) { - form.save(); - Navigator.push( - context, - FadePage( - page: RateAppointmentClinic( - appointmentDetails: - model.appointmentDetails, - doctorNote: note, - doctorRate: rating, - ), - ), - ); - } - }, - label: TranslationBase.of(context).next, - disabled: (model.state == ViewState.BusyLocal || rating==0), - loading: model.state == ViewState.BusyLocal, - textColor: Theme.of(context).backgroundColor), - ), - SizedBox( - height: 12, - ), - InkWell( - onTap: () { - Navigator.pushReplacement( - context, - FadePage( - page: LandingPage(), - ), - ); - }, - child: Texts( - TranslationBase.of(context).later, - decoration: TextDecoration.underline, - color: HexColor('#151DFE'), - fontSize: 18, + dialog.showAlertDialog(context); + } else { + Navigator.pushReplacement( + context, + FadePage( + page: LandingPage(), + ), + ); + // if(projectViewModel.isLoginChild) { + // Navigator.pushReplacement( + // context, + // FadePage( + // page: LandingPage(), + // ), + // ); + // } else { + // Navigator.pop( + // context, + // // FadePage( + // // page: LandingPage(), + // // ), + // ); + // } + } + }, + color: CustomColors.accentColor, + textColor: Colors.white, + ), + ), + SizedBox(width: 10), + Expanded( + child: DefaultButton( + TranslationBase.of(context).next, + rating <= 0 + ? null + : () { + Navigator.push( + context, + FadePage( + page: RateAppointmentClinic( + appointmentDetails: model.appointmentDetails, + doctorNote: note, + doctorRate: rating, + ), ), - ) - ], - ), - ) - ], + ); + }, + // iconData: Icons.notifications_active, + color: Color(0xff359846), + disabledColor: Colors.grey, ), ), - ), + ], ), ), ), ); } + + DoctorList getDoctorObject(AppointmentRateViewModel model) { + DoctorList doctor = new DoctorList(); + + doctor.name = model.appointmentDetails.doctorName; + doctor.doctorImageURL = model.appointmentDetails.doctorImageURL; + doctor.clinicName = model.appointmentDetails.clinicName; + doctor.projectName = model.appointmentDetails.projectName; + doctor.date = model.appointmentDetails.appointmentDate; + doctor.actualDoctorRate = 5; + + return doctor; + } } diff --git a/lib/pages/search_products_page.dart b/lib/pages/search_products_page.dart index 73b17558..974b5b98 100644 --- a/lib/pages/search_products_page.dart +++ b/lib/pages/search_products_page.dart @@ -1,19 +1,26 @@ import 'package:diplomaticquarterapp/config/size_config.dart'; -import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacy_categorise_view_model.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/product-brands.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/product_detail.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/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/buttons/button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/input/text_field.dart'; import 'package:diplomaticquarterapp/widgets/others/StarRating.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_pharmacy_widget.dart'; import 'package:diplomaticquarterapp/widgets/others/network_base_view.dart'; +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/services.dart'; +import 'package:provider/provider.dart'; +import 'Blood/new_text_Field.dart'; import 'base/base_view.dart'; +import 'package:intl/intl.dart' as international; class SearchProductsPage extends StatefulWidget { @override @@ -24,15 +31,16 @@ class _SearchProductsPageState extends State { final textController = TextEditingController(); final _formKey = GlobalKey(); String msg = ''; + String validText = ""; + bool isTextValid = true; @override Widget build(BuildContext context) { + ProjectViewModel projectProvider = Provider.of(context); return BaseView( onModelReady: (model) => model.clearSearchList(), - builder: (BuildContext context, PharmacyCategoriseViewModel model, - Widget child) => - PharmacyAppScaffold( - appBarTitle: 'Search', + builder: (BuildContext context, PharmacyCategoriseViewModel model, Widget? child) => PharmacyAppScaffold( + appBarTitle: TranslationBase.of(context).search, isBottomBar: false, isShowAppBar: true, backgroundColor: Colors.white, @@ -51,9 +59,9 @@ class _SearchProductsPageState extends State { width: MediaQuery.of(context).size.width * 0.70, child: Form( key: _formKey, - child: TextFields( + child: NewTextFields( autoFocus: true, - hintText: 'Search', + hintText: TranslationBase.of(context).search, fontSize: 14.5, prefixIcon: Icon(Icons.search), inputAction: TextInputAction.search, @@ -62,24 +70,28 @@ class _SearchProductsPageState extends State { }, onSubmit: (value) { searchMedicine(model, context); - msg = 'No Result Found'; +// msg = 'No Result Found'; + msg = TranslationBase.of(context).noSearchResultFound; }, controller: textController, - validator: (value) { - if (value.isEmpty) { - return 'please Enter Product Name'; - } - return null; - }, ), + // SizedBox( + // width: 10.0, + // ), + // if(!isTextValid) + // AppText( TranslationBase.of(context) + // .noArabicLetters, color: Colors.red,), + // ], + // ), ), ), + SizedBox( width: 10.0, ), InkWell( child: Texts( - 'Cancel', + TranslationBase.of(context).cancel, fontSize: 17.0, fontWeight: FontWeight.w500, ), @@ -110,8 +122,7 @@ class _SearchProductsPageState extends State { height: MediaQuery.of(context).size.height * 0.80, child: GridView.builder( //physics: NeverScrollableScrollPhysics(), - gridDelegate: - SliverGridDelegateWithFixedCrossAxisCount( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, crossAxisSpacing: 0.5, mainAxisSpacing: 2.0, @@ -121,11 +132,7 @@ class _SearchProductsPageState extends State { itemBuilder: (BuildContext context, int index) { return InkWell( child: Card( - color: model.searchList[index] - .discountName != - null - ? Color(0xffFFFF00) - : Colors.white, + color: model.searchList[index].discountName != null ? Color(0xffFFFF00) : Colors.white, elevation: 0, shape: Border( right: BorderSide( @@ -156,64 +163,53 @@ class _SearchProductsPageState extends State { ), color: Colors.white, ), - padding: - EdgeInsets.symmetric(horizontal: 0), - width: - MediaQuery.of(context).size.width / - 3, + padding: EdgeInsets.symmetric(horizontal: 0), + width: MediaQuery.of(context).size.width / 3, child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ Stack( children: [ Container( - margin: EdgeInsets.fromLTRB( - 0, 16, 0, 0), + margin: EdgeInsets.fromLTRB(0, 16, 0, 0), alignment: Alignment.center, child: Image.network( - model.searchList[index] - .images.isNotEmpty - ? model - .searchList[index] - .images[0] - .thumb + model.searchList[index].images!.isNotEmpty + ? model.searchList[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.cover, height: 80, ), ), Container( - width: model.searchList[index] - .rxMessage != - null - ? MediaQuery.of(context) - .size - .width / - 5 - : 0, + width: model.searchList[index].rxMessage != null ? MediaQuery.of(context).size.width / 3 : 0, padding: EdgeInsets.all(4), decoration: BoxDecoration( color: Color(0xffb23838), - borderRadius: - BorderRadius.only( - topLeft: - Radius.circular( - 6)), - ), - child: Texts( - model.searchList[index] - .rxMessage != - null - ? model - .searchList[index] - .rxMessage - : "", - color: Colors.white, - regular: true, - fontSize: 10, - fontWeight: FontWeight.w400, + borderRadius: BorderRadius.only(topLeft: Radius.circular(6)), ), + child: model.searchList[index].rxMessage != null + ? Texts( + projectProvider.isArabic ? model.searchList[index].rxMessagen : model.searchList[index].rxMessage, + color: Colors.white, + regular: true, + fontSize: 10, + fontWeight: FontWeight.w400, + ) + : Texts(""), +// Texts( +// model.searchList[index] +// .rxMessage != +// null +// ? model +// .searchList[index] +// .rxMessage +// : "", +// color: Colors.white, +// regular: true, +// fontSize: 10, +// fontWeight: FontWeight.w400, +// ), ), ], ), @@ -223,20 +219,18 @@ class _SearchProductsPageState extends State { vertical: 0, ), child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ Texts( - model - .searchList[index].name, + projectProvider.isArabic ? model.searchList[index].namen : model.searchList[index].name, + + // model.searchList[index].name, regular: true, fontSize: 12, fontWeight: FontWeight.w400, ), Padding( - padding: - const EdgeInsets.only( - top: 4, bottom: 4), + padding: const EdgeInsets.only(top: 4, bottom: 4), child: Texts( "SAR ${model.searchList[index].price}", bold: true, @@ -246,30 +240,15 @@ class _SearchProductsPageState extends State { Row( children: [ StarRating( - totalAverage: model - .searchList[ - index] - .approvedRatingSum > - 0 - ? (model - .searchList[ - index] - .approvedRatingSum - .toDouble() / - model - .searchList[ - index] - .approvedRatingSum - .toDouble()) - .toDouble() + totalAverage: model.searchList[index].approvedRatingSum! > 0 + ? (model.searchList[index].approvedRatingSum!.toDouble() / model.searchList[index].approvedRatingSum!.toDouble()).toDouble() : 0, forceStars: true), Texts( "(${model.searchList[index].approvedTotalReviews})", regular: true, fontSize: 10, - fontWeight: - FontWeight.w400, + fontWeight: FontWeight.w400, ) ], ), @@ -284,8 +263,7 @@ class _SearchProductsPageState extends State { Navigator.push( context, FadePage( - page: ProductDetailPage( - model.searchList[index]), + page: ProductDetailPage(model.searchList[index]), )), }, ); @@ -304,9 +282,12 @@ class _SearchProductsPageState extends State { ); } + bool isRTL(String text) { + return international.Bidi.detectRtlDirectionality(text); + } + searchMedicine(PharmacyCategoriseViewModel model, BuildContext context) { Utils.hideKeyboard(context); - if (_formKey.currentState.validate()) - model.searchProducts(productName: textController.text); + if (_formKey.currentState!.validate()) model.searchProducts(productName: textController.text); } } diff --git a/lib/pages/settings/InfoPage.dart b/lib/pages/settings/InfoPage.dart new file mode 100644 index 00000000..04cc670e --- /dev/null +++ b/lib/pages/settings/InfoPage.dart @@ -0,0 +1,10 @@ +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; + +class AboutApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return AppScaffold(isShowAppBar: true, appBarTitle: TranslationBase.of(context).aboutApp, isShowDecPage: false, body: Container()); + } +} diff --git a/lib/pages/settings/general_setting.dart b/lib/pages/settings/general_setting.dart index 0a6b0e73..9cac9df0 100644 --- a/lib/pages/settings/general_setting.dart +++ b/lib/pages/settings/general_setting.dart @@ -1,24 +1,23 @@ -import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/services/permission/permission_service.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/theme/theme_notifier.dart'; import 'package:diplomaticquarterapp/theme/theme_value.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'; -import 'package:diplomaticquarterapp/widgets/text/app_texts_widget.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:geolocator/geolocator.dart'; import 'package:provider/provider.dart'; -import 'package:screen/screen.dart'; +import 'package:screen_brightness/screen_brightness.dart'; class GeneralSettings extends StatefulWidget { @override _GeneralSettings createState() => _GeneralSettings(); } -class _GeneralSettings extends State - with TickerProviderStateMixin { +class _GeneralSettings extends State with TickerProviderStateMixin { var themeNotifier; int blindValue = 0; bool vibration = false; @@ -27,10 +26,12 @@ class _GeneralSettings extends State bool location = false; var sharedPref = new AppSharedPreferences(); var permission = new PermissionService(); + LocationPermission? locationPermission; var mediaQueryData; + @override void initState() { - getValues(); + this.getValues(); super.initState(); } @@ -38,193 +39,235 @@ class _GeneralSettings extends State mediaQueryData = MediaQuery.of(context); themeNotifier = Provider.of(context); return Container( - child: ListView(scrollDirection: Axis.vertical, children: [ - Container( - color: Theme.of(context).scaffoldBackgroundColor, - padding: EdgeInsets.all(10), - child: AppText( - TranslationBase.of(context).modes, - fontWeight: FontWeight.bold, - ), - ), - Container( - color: Theme.of(context).scaffoldBackgroundColor, - padding: EdgeInsets.all(10), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - AppText(TranslationBase.of(context).vibration), - Switch( - value: vibration, - onChanged: (value) { - setState(() { - vibration = value; - }); - setVibration(value); - }, - activeTrackColor: Colors.lightGreenAccent, - activeColor: Colors.green, - ) - ], - )), - Container( - color: Theme.of(context).scaffoldBackgroundColor, - padding: EdgeInsets.all(10), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - AppText(TranslationBase.of(context).accessibility), - Switch( - value: accsibility, - onChanged: (value) { - setState(() { - accsibility = value; - }); - //setAccisibility(value); - }, - activeTrackColor: Colors.lightGreenAccent, - activeColor: Colors.green, - ) - ], - )), - Container( - color: Theme.of(context).scaffoldBackgroundColor, - padding: EdgeInsets.all(10), - child: AppText( - TranslationBase.of(context).blindMode, - fontWeight: FontWeight.bold, - ), - ), - new Container( - color: Theme.of(context).scaffoldBackgroundColor, - padding: EdgeInsets.all(8.0), - child: new Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - new Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - new Text( - TranslationBase.of(context).offTheme, - style: new TextStyle(fontSize: 16.0), - ), - Radio( - value: 0, - groupValue: blindValue, - onChanged: (value) { - setState(() => {this.blindValue = value}); + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(21.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Text( + // TranslationBase.of(context).modes, + // style: TextStyle( + // fontSize: 16, + // fontWeight: FontWeight.w600, + // letterSpacing: -0.64, + // ), + // ), + // Row( + // children: [ + // Checkbox( + // value: vibration, + // onChanged: (value) { + // setState(() { + // vibration = value!; + // }); + // }, + // activeColor: CustomColors.accentColor, + // ), + // Text( + // TranslationBase.of(context).vibration, + // style: TextStyle( + // fontSize: 12, + // letterSpacing: -0.48, + // ), + // ), + // ], + // ), + // Row( + // children: [ + // Checkbox( + // value: accsibility, + // onChanged: (value) { + // setState(() { + // accsibility = value!; + // }); + // }, + // activeColor: CustomColors.accentColor, + // ), + // Text( + // TranslationBase.of(context).accessibility, + // style: TextStyle( + // fontSize: 12, + // letterSpacing: -0.48, + // ), + // ), + // ], + // ), + // mHeight(16), + // mHeight(12), + Text( + TranslationBase.of(context).blindMode, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.64, + ), + ), + Column( + children: [ + Row( + children: [ + new Radio( + value: 0, + groupValue: blindValue, + onChanged: (value) { + setState(() { + blindValue = value!; setTheme(value); - }, - ), - ], - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - new Text( - TranslationBase.of(context).invertTheme, - style: new TextStyle( - fontSize: 16.0, - ), + }); + }, + ), + Text( + TranslationBase.of(context).offTheme, + style: TextStyle( + fontSize: 12, + letterSpacing: -0.48, ), - new Radio( - value: 1, - groupValue: blindValue, - onChanged: (value) { - setState(() => {this.blindValue = value}); + ), + ], + ), + Row( + children: [ + Radio( + value: 1, + groupValue: blindValue, + onChanged: (value) { + setState(() { + blindValue = value!; setTheme(value); - }, - ) - ], - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - new Text( - TranslationBase.of(context).dimTheme, - style: new TextStyle(fontSize: 16.0), + }); + }, + ), + Text( + TranslationBase.of(context).invertTheme, + style: TextStyle( + fontSize: 12, + letterSpacing: -0.48, ), - new Radio( - value: 2, - groupValue: blindValue, - onChanged: (value) { - setState(() => {this.blindValue = value}); + ), + ], + ), + Row( + children: [ + Radio( + value: 2, + groupValue: blindValue, + onChanged: (value) { + setState(() { + blindValue = value!; setTheme(value); - }, - ), - ], - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - new Text( - TranslationBase.of(context).bwTheme, - style: new TextStyle(fontSize: 16.0), + }); + }, + ), + Text( + TranslationBase.of(context).dimTheme, + style: TextStyle( + fontSize: 12, + letterSpacing: -0.48, ), - new Radio( - value: 3, - groupValue: blindValue, - onChanged: (value) { - setState(() => {this.blindValue = value}); - + ), + ], + ), + Row( + children: [ + Radio( + value: 1, + groupValue: blindValue, + onChanged: (value) { + setState(() { + blindValue = value!; setTheme(value); - }, + }); + }, + ), + Text( + TranslationBase.of(context).bwTheme, + style: TextStyle( + fontSize: 12, + letterSpacing: -0.48, ), - ], + ), + ], + ), + ], + ), + mHeight(12), + mHeight(12), + Text( + TranslationBase.of(context).permissions, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.64, + ), + ), + Row( + children: [ + Checkbox( + value: camera, + onChanged: (value) { + setState(() { + camera = value!; + }); + this.permission.openSettings(); + }, + activeColor: CustomColors.accentColor, + ), + Text( + TranslationBase.of(context).cameraPermission, + style: TextStyle( + fontSize: 12, + letterSpacing: -0.48, + ), + ), + ], + ), + Row( + children: [ + Checkbox( + value: location, + onChanged: (value) { + if (value == true) { + Navigator.pop(context); + this.setLocationPermission(); + } else { + Geolocator.openLocationSettings(); + } + }, + activeColor: CustomColors.accentColor, + ), + Text( + TranslationBase.of(context).locationPermission, + style: TextStyle( + fontSize: 12, + letterSpacing: -0.48, ), - ], - ) - ])), - Container( - color: Theme.of(context).scaffoldBackgroundColor, - padding: EdgeInsets.all(10), - child: AppText( - TranslationBase.of(context).permissions, - fontWeight: FontWeight.bold, + ), + ], + ), + mHeight(16), + ], + ), ), ), - Container( - color: Theme.of(context).scaffoldBackgroundColor, - padding: EdgeInsets.all(10), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - AppText(TranslationBase.of(context).cameraPermission), - Switch( - value: camera, - onChanged: (value) { - setState(() { - camera = value; - }); - }, - activeTrackColor: Colors.lightGreenAccent, - activeColor: Colors.green, - ) - ], - )), - Container( - color: Theme.of(context).scaffoldBackgroundColor, - padding: EdgeInsets.all(10), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - AppText(TranslationBase.of(context).locationPermission), - Switch( - value: location, - onChanged: (value) { - setState(() { - location = value; - }); - }, - activeTrackColor: Colors.lightGreenAccent, - activeColor: Colors.green, - ) - ], - )) - ])); + ); + } + + setLocationPermission() async { + locationPermission = await Geolocator.checkPermission(); + if (locationPermission == LocationPermission.denied) { + locationPermission = await Geolocator.requestPermission(); + if (locationPermission != LocationPermission.denied) { + setState(() { + location = true; + }); + } else { + this.location = false; + } + } else { + Geolocator.openLocationSettings(); + this.location = true; + } } setTheme(value) async { @@ -232,7 +275,7 @@ class _GeneralSettings extends State case 0: { themeNotifier.setTheme(await getTheme(value)); - Screen.setBrightness(1.0); + setBrightness(1.0); } break; case 1: @@ -243,24 +286,33 @@ class _GeneralSettings extends State break; case 2: themeNotifier.setTheme(await getTheme(value)); - Screen.setBrightness(0.01); + setBrightness(0.01); break; case 3: { themeNotifier.setTheme(await getTheme(value)); - Screen.setBrightness(1.0); + setBrightness(1.0); } break; default: { themeNotifier.setTheme(await getTheme(value)); - Screen.setBrightness(1.0); + setBrightness(1.0); } break; } permission.setTheme(value); } + setBrightness(double brightness) async { + try { + await ScreenBrightness().setScreenBrightness(brightness); + } catch (e) { + print(e); + throw 'Failed to set brightness'; + } + } + setVibration(value) { permission.setVibrationPermission(value); } @@ -272,31 +324,26 @@ class _GeneralSettings extends State getValues() async { if (permission.isThemeEnabled() != null) { - blindValue = - permission.isThemeEnabled() == null ? 0 : permission.isThemeEnabled(); - vibration = permission.isVibrationEnabled() == null - ? false - : permission.isVibrationEnabled(); - accsibility = mediaQueryData.accessibleNavigation; - setTheme(blindValue); + blindValue = permission.isThemeEnabled() == null ? 0 : permission.isThemeEnabled(); + vibration = permission.isVibrationEnabled() == null ? false : permission.isVibrationEnabled(); + // accsibility = mediaQueryData.accessibleNavigation; + //setTheme(blindValue); } + var camera = await PermissionService.isCameraEnabled(); + var location = await PermissionService.isLocationEnabled(); + setState(() { + this.camera = camera; + this.location = location; + }); } getTheme(value) async { if (value == 1) { - return invertThemes( - fontName: Provider.of(context, listen: false).isArabic ? 'Cairo' : 'WorkSans' - ); + return invertThemes(fontName: Provider.of(context, listen: false).isArabic ? 'Cairo' : 'Poppins'); } else if (value == 3) { - return bwThemes( - fontName: Provider.of(context, listen: false).isArabic ? 'Cairo' : 'WorkSans' - ); + return bwThemes(fontName: Provider.of(context, listen: false).isArabic ? 'Cairo' : 'Poppins'); } else { - return defaultTheme( - fontName: - Provider.of(context, listen: false).isArabic - ? 'Cairo' - : 'WorkSans'); + return defaultTheme(fontName: Provider.of(context, listen: false).isArabic ? 'Cairo' : 'Poppins'); } } } diff --git a/lib/pages/settings/profile_setting.dart b/lib/pages/settings/profile_setting.dart index 833cdf2b..911ab0e3 100644 --- a/lib/pages/settings/profile_setting.dart +++ b/lib/pages/settings/profile_setting.dart @@ -1,16 +1,19 @@ -import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/core/viewModels/dashboard_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/services/authentication/auth_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/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/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; import 'package:diplomaticquarterapp/widgets/text/app_texts_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:provider/provider.dart'; class ProfileSettings extends StatefulWidget { @@ -18,8 +21,7 @@ class ProfileSettings extends StatefulWidget { _ProfileSettings createState() => _ProfileSettings(); } -class _ProfileSettings extends State - with TickerProviderStateMixin { +class _ProfileSettings extends State with TickerProviderStateMixin { bool smsAlert = true; bool emailAlert = true; int language = 1; @@ -27,211 +29,355 @@ class _ProfileSettings extends State TextEditingController emergencyContact = new TextEditingController(); TextEditingController emailController = new TextEditingController(); TextEditingController emergencyContactName = new TextEditingController(); + ProjectViewModel? projectProvider; + @override void initState() { - Future.delayed(new Duration(seconds: 0), () { - ProjectViewModel projectProvider; - projectProvider = Provider.of(context); - if (projectProvider.isLogin == true) getSettings(context); - }); super.initState(); } Widget build(BuildContext context) { + projectProvider = Provider.of(context); return BaseView( - onModelReady: (model) => {}, - builder: (_, model, wi) => Container( - child: model.user != null - ? ListView(scrollDirection: Axis.vertical, children: [ - Container( - color: Theme.of(context).primaryColor, - padding: EdgeInsets.all(15), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - AppText( - TranslationBase.of(context).fileNo, - color: Colors.black, - ), - AppText( - model.user.patientID.toString(), - color: Colors.black, - ), - ], - ), - ), - SizedBox( - height: 1, - width: MediaQuery.of(context).size.width, - child: Container( - color: Colors.grey[300], + onModelReady: (model) => {getSettings()}, + builder: (_, model, wi) => Container( + child: model.user != null + ? Column( + children: [ + Expanded( + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.only(left: 21, right: 21, top: 21), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + decoration: cardRadius(8), + margin: EdgeInsets.zero, + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).fileNo + ": ", + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.64, + ), + ), + Text( + model.user!.patientID.toString(), + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.64, + ), + ), + ], + ), + ), + ), + mHeight(12), + Text( + TranslationBase.of(context).languageSetting, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.64, + ), + ), + Text( + TranslationBase.of(context).selectLanguage, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + ), + ), + Row( + children: [ + Expanded( + child: Row( + children: [ + new Radio( + value: 2, + groupValue: language, + onChanged: (value) { + setState(() { + language = value!; + }); + }, + ), + Text( + TranslationBase.of(context).english, + style: TextStyle( + fontSize: 12, + letterSpacing: -0.48, + ), + ), + ], + ), + ), + Expanded( + child: Row( + children: [ + Radio( + value: 1, + groupValue: language, + onChanged: (value) { + setState(() { + language = value!; + }); + }, + ), + Text( + TranslationBase.of(context).arabic, + style: TextStyle( + fontSize: 12, + letterSpacing: -0.48, + ), + ), + ], + ), + ), + ], + ), + mHeight(12), + Text( + TranslationBase.of(context).alert, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.64, + ), + ), + Text( + TranslationBase.of(context).recAlert, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + ), + ), + Row( + children: [ + Checkbox( + value: emailAlert, + onChanged: (value) { + setState(() { + emailAlert = value!; + }); + }, + activeColor: CustomColors.accentColor, + ), + Text( + TranslationBase.of(context).emailAlert, + style: TextStyle( + fontSize: 12, + letterSpacing: -0.48, + ), + ), + ], + ), + Row( + children: [ + Checkbox( + value: smsAlert, + onChanged: (value) { + setState(() { + smsAlert = value!; + }); + }, + activeColor: CustomColors.accentColor, + ), + Text( + TranslationBase.of(context).smsAlert, + style: TextStyle( + fontSize: 12, + letterSpacing: -0.48, + ), + ), + ], + ), + mHeight(16), + Text( + TranslationBase.of(context).contactInfo, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.64, + ), + ), + mHeight(12), + inputWidget(TranslationBase.of(context).email, "", emailController), + mHeight(8), + inputWidget(TranslationBase.of(context).emergencyName, "", emergencyContactName), + mHeight(8), + inputWidget(TranslationBase.of(context).emergencyContact, "", emergencyContact), + mHeight(10), + // InkWell( + // onTap: () { + // deactivateAccount(); + // }, + // child: Text( + // TranslationBase.of(context).deleteAccount, + // style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, letterSpacing: -0.64, color: Color(0xffD02127), decoration: TextDecoration.underline), + // ), + // ), + mHeight(8), + ], + ), ), ), - Padding( - child: AppText( - TranslationBase.of(context).languageSetting, - fontWeight: FontWeight.bold), - padding: EdgeInsets.all(10), + ), + Container( + padding: EdgeInsets.all(12), + color: Colors.white, + child: Flex( + direction: Axis.horizontal, + children: [ + Expanded( + child: DefaultButton( + TranslationBase.of(context).deleteAccount, + () { + deactivateAccount(); + }, + ), + ), + mWidth(12), + Expanded( + child: DefaultButton( + TranslationBase.of(context).save, + () { + saveSettings(); + }, + color: CustomColors.green, + ), + ), + ], ), - Container( - color: Theme.of(context).primaryColor, - padding: EdgeInsets.only( - top: 0, left: 10, right: 10, bottom: 0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - AppText(TranslationBase.of(context).english), - new Radio( - value: 2, - groupValue: language, - onChanged: (value) { - setState(() { - language = value; - }); - }, - ) - ], - )), - Container( - color: Theme.of(context).primaryColor, - padding: EdgeInsets.only( - top: 0, left: 10, right: 10, bottom: 0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - AppText(TranslationBase.of(context).arabic), - new Radio( - value: 1, - groupValue: language, - onChanged: (value) { - setState(() { - language = value; - }); - }, - ) - ], - )), - Padding( - child: AppText(TranslationBase.of(context).alert), - padding: EdgeInsets.all(10), + ), + ], + ) + : Center( + child: AppText(TranslationBase.of(context).loginToUseService), + ), + ), + ); + } + + 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(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, ), - Container( - color: Theme.of(context).primaryColor, - padding: EdgeInsets.only( - top: 0, left: 10, right: 10, bottom: 0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - AppText(TranslationBase.of(context).emailAlert), - Switch( - value: emailAlert, - onChanged: (value) { - setState(() { - emailAlert = value; - }); - }, - activeTrackColor: Colors.lightGreenAccent, - activeColor: Colors.green, - ) - ], - )), - Container( - color: Theme.of(context).primaryColor, - padding: EdgeInsets.only( - top: 0, left: 10, right: 10, bottom: 0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - AppText(TranslationBase.of(context).smsAlert), - Switch( - value: smsAlert, - onChanged: (value) { - setState(() { - smsAlert = value; - }); - }, - activeTrackColor: Colors.lightGreenAccent, - activeColor: Colors.green, - ) - ], - )), - Padding( - child: AppText(TranslationBase.of(context).contactInfo), - padding: EdgeInsets.all(10), + ), + TextField( + enabled: isEnable, + scrollPadding: EdgeInsets.zero, + keyboardType: TextInputType.emailAddress, + controller: _controller, + // onChanged: (value) => {validateForm()}, + style: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: Color(0xff2B353E), + letterSpacing: -0.44, ), - Container( - color: Theme.of(context).primaryColor, - padding: EdgeInsets.only( - top: 0, left: 10, right: 10, bottom: 0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AppText(TranslationBase.of(context).email), - TextField( - controller: emailController, - decoration: InputDecoration( - suffixIcon: Icon(Icons.edit), - )) - ], - )), - Container( - color: Theme.of(context).primaryColor, - padding: EdgeInsets.only( - top: 0, left: 10, right: 10, bottom: 0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AppText(TranslationBase.of(context).emergencyName), - TextField( - controller: emergencyContactName, - decoration: InputDecoration( - suffixIcon: Icon(Icons.edit), - )) - ], - )), - Container( - color: Theme.of(context).primaryColor, - padding: EdgeInsets.only( - top: 0, left: 10, right: 10, bottom: 0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AppText( - TranslationBase.of(context).emergencyContact), - TextField( - controller: emergencyContact, - decoration: InputDecoration( - suffixIcon: Icon(Icons.edit), + decoration: InputDecoration( + isDense: true, + hintText: _hintText, + hintStyle: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: Color(0xff575757), + 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, ), - ) - ], - )), - Container( - padding: EdgeInsets.all(10), - child: Row( - children: [ - Expanded( - child: DefaultButton( - TranslationBase.of(context).save, - () { - saveSettings(); - }, - )), - ], - )) - ]) - : Center( - child: - AppText(TranslationBase.of(context).loginToUseService), - ))); + ), + contentPadding: EdgeInsets.zero, + border: InputBorder.none, + focusedBorder: InputBorder.none, + enabledBorder: InputBorder.none, + ), + ), + ], + ), + ), + if (hasSelection) Icon(Icons.keyboard_arrow_down_outlined), + ], + ), + ), + ); + } + + deactivateAccount() { + ConfirmDialog dialog = new ConfirmDialog( + context: context, + confirmMessage: TranslationBase.of(context).deactivateAccount, + okText: TranslationBase.of(context).yes, + cancelText: TranslationBase.of(context).no, + okFunction: () { + Navigator.of(context).pop(); + callDeactivateAccountAPI(); + }, + cancelFunction: () => {}); + dialog.showAlertDialog(context); } - getSettings(context) { + callDeactivateAccountAPI() { GifLoaderDialogUtils.showMyDialog(context); - authService.getSettings().then((result) => { - GifLoaderDialogUtils.hideDialog(context), - setValue(result["PateintInfoForUpdateList"][0]) - }); + Map request = {}; + request["IsActive"] = false; + request["PatientIdentificationID"] = projectProvider!.user!.patientIdentificationNo!; + request["PatientMobileNumber"] = Utils.getPhoneNumberWithoutZero(projectProvider!.user!.mobileNumber!); + authService.deactivateAccount(request, false).then((result) { + AppToast.showSuccessToast(message: TranslationBase.of(context).accountDeactivated); + GifLoaderDialogUtils.hideDialog(context); + }); + } + + getSettings() { + authService.getSettings().then((result) => {setValue(result["PateintInfoForUpdateList"][0])}); } setValue(value) { @@ -254,10 +400,12 @@ class _ProfileSettings extends State request["IsEmailAlertRequired"] = this.emailAlert; request["IsSMSAlertRequired"] = this.smsAlert; request["PreferredLanguage"] = this.language.toString(); - authService.saveSettings(request).then((result) => { - AppToast.showSuccessToast( - message: TranslationBase.of(context).profileUpdate), - GifLoaderDialogUtils.hideDialog(context) - }); + authService.saveSettings(request).then((result) { + AppToast.showSuccessToast(message: TranslationBase.of(context).profileUpdate); + GifLoaderDialogUtils.hideDialog(context); + AuthenticatedUser authUser = projectProvider!.user!; + authUser.emailAddress = this.emailController.text; + projectProvider!.setUser(authUser); + }); } } diff --git a/lib/pages/settings/settings.dart b/lib/pages/settings/settings.dart index b578eb3f..9b3dfc3f 100644 --- a/lib/pages/settings/settings.dart +++ b/lib/pages/settings/settings.dart @@ -1,7 +1,9 @@ import 'package:diplomaticquarterapp/config/config.dart'; -import 'package:diplomaticquarterapp/pages/settings/profile_setting.dart'; import 'package:diplomaticquarterapp/pages/settings/general_setting.dart'; +import 'package:diplomaticquarterapp/pages/settings/profile_setting.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/others/arrow_back.dart'; import 'package:flutter/material.dart'; @@ -9,20 +11,20 @@ class Settings extends StatefulWidget { final int type; Settings({this.type = 0}); + @override _Settings createState() => _Settings(); } class _Settings extends State with TickerProviderStateMixin { - TabController _tabController; + TabController? _tabController; @override void initState() { - _tabController = - new TabController(length: 2, vsync: this, initialIndex: widget.type); + _tabController = new TabController(length: 2, vsync: this, initialIndex: widget.type); if (widget.type == 1) { - _tabController.animateTo(1); + _tabController!.animateTo(1); } super.initState(); @@ -31,38 +33,45 @@ class _Settings extends State with TickerProviderStateMixin { @override Widget build(BuildContext context) { AppGlobal.context = context; - return Scaffold( - appBar: AppBar( - bottom: TabBar( - // isScrollable: true, + return AppScaffold( + isShowAppBar: false, + isShowDecPage: false, + showNewAppBarTitle: true, + showNewAppBar: true, + appBarTitle: TranslationBase.of(context).settings, + backgroundColor: Color(0xFFF7F7F7), + body: Column( + children: [ + TabBar( + // isScrollable: true, - indicatorWeight: 5.0, - //indicatorSize: TabBarIndicatorSize.label, - // indicatorSize: TabBarIndicatorSize.tab, + indicatorWeight: 3.0, + //indicatorSize: TabBarIndicatorSize.label, + // indicatorSize: TabBarIndicatorSize.tab, - indicatorColor: Theme.of(context).primaryColor, - // labelColor: Theme.of(context).primaryColor, - tabs: [ - Tab(text: TranslationBase.of(context).general), - Tab( - text: TranslationBase.of(context).profile, - ) - ], - controller: _tabController, - ), - title: Text(TranslationBase.of(context).settings, - style: - TextStyle(color: Theme.of(context).textTheme.bodyText2.color)), - leading: Builder( - builder: (BuildContext context) { - return ArrowBack(); - }, - ), + indicatorColor: CustomColors.accentColor, + labelColor: Colors.black, + unselectedLabelColor: CustomColors.grey, + // labelColor: Theme.of(context).primaryColor, + tabs: [ + Tab(text: TranslationBase.of(context).general), + Tab( + text: TranslationBase.of(context).profile, + ) + ], + controller: _tabController, + ), + Expanded( + child: TabBarView( + physics: NeverScrollableScrollPhysics(), + children: [ + GeneralSettings(), + ProfileSettings(), + ], + controller: _tabController), + ), + ], ), - body: TabBarView( - physics: NeverScrollableScrollPhysics(), - children: [GeneralSettings(), ProfileSettings()], - controller: _tabController), ); } } diff --git a/lib/pages/sub_categories_modalsheet.dart b/lib/pages/sub_categories_modalsheet.dart new file mode 100644 index 00000000..64b48fd1 --- /dev/null +++ b/lib/pages/sub_categories_modalsheet.dart @@ -0,0 +1,115 @@ + +import 'package:diplomaticquarterapp/core/model/pharmacy/categorise_parent_model.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacy/pharmacy_categorise.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacy_categorise_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/pages/sub_categorise_page.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_pharmacy_widget.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +import 'package:flutter/material.dart'; +import 'base/base_view.dart'; +import 'package:provider/provider.dart'; + + + + +class SubCategoriseModalsheet extends StatefulWidget { + String? id; + String? titleName; + + SubCategoriseModalsheet({this.id, this.titleName}); + @override + _SubCategoriseModalsheetState createState() => _SubCategoriseModalsheetState(id: id, titleName: titleName); + +} + +class _SubCategoriseModalsheetState extends State { + String? id; + String? titleName; +// List categoriesList = []; + _SubCategoriseModalsheetState({this.id, this.titleName}); + + @override + Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + return BaseView( + onModelReady: (model) => model.getCategoriseParent(i: id), + builder: (_, model, wi) => AppScaffold( + // appBarTitle: titleName, + appBarTitle: TranslationBase.of(context).categorise, + isBottomBar: true, + isShowAppBar: true, + isPharmacy: true, + backgroundColor: Colors.white, + isShowDecPage: false, + showPharmacyCart: false, + showHomeAppBarIcon: false, + baseViewModel: model, + body: Container( + color: Colors.white, + child: Center( + child: ListView.builder( + scrollDirection: Axis.vertical, + itemCount: model.categoriseParent.length, + itemBuilder: (BuildContext context, int index) { + return Container( + child: Padding( + padding: EdgeInsets.all(4.0), + child: InkWell( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Texts(projectViewModel.isArabic + ? model.categoriseParent[index].namen + : model.categoriseParent[index].name), + SizedBox( + height: 10, + ), + Divider( + thickness: 0.6, + color: Colors.black12, + ) + ], + ), + onTap: () { + Navigator.push( + context, + FadePage( + page: SubCategorisePage( + title: projectViewModel + .isArabic + ? model.categoriseParent[index].namen + : model.categoriseParent[index].name, + // title: model.categoriseParent[index].name, + id: model.categoriseParent[index].id, + parentId: id, + )), + ); + }, + ), + ), + ); + }), + ), + ), + + ), + ); + } +// getCatName() { +// +// if (widget.id == '1' ) +// return Texts("text1"); +// else if (widget.id == '2' ) +// return Texts("text2"); +// else if (widget.id == '3') +// return Texts("text3"); +// else if (widget.id == '4' ) +// return Texts("text4"); +// } + + +} \ No newline at end of file diff --git a/lib/pages/sub_categorise_page.dart b/lib/pages/sub_categorise_page.dart index cc374b96..7c1f398e 100644 --- a/lib/pages/sub_categorise_page.dart +++ b/lib/pages/sub_categorise_page.dart @@ -1,36 +1,51 @@ +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/pharmacy/categorise_parent_model.dart'; +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/pages/pharmacies/product_detail.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/locator.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/product-detail.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/buttons/button.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'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/others/entity_checkbox_list.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:flutter_rating_bar/flutter_rating_bar.dart'; +import 'package:provider/provider.dart'; +import 'package:pull_to_refresh/pull_to_refresh.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart' as utils; import 'base/base_view.dart'; import 'final_products_page.dart'; class SubCategorisePage extends StatefulWidget { - String id; - String title; - String parentId; + String? id; + String? title; + String? parentId; + + AuthenticatedUserObject authenticatedUserObject = locator(); SubCategorisePage({this.id, this.parentId, this.title}); @override - _SubCategorisePageState createState() => - _SubCategorisePageState(id: id, title: title, parentId: parentId); + _SubCategorisePageState createState() => _SubCategorisePageState(id: id, title: title, parentId: parentId); } class _SubCategorisePageState extends State { bool checkedBrands = false; bool checkedCategorise = false; - String id; - String title; - String parentId; + String? id; + String? title; + String? parentId; _SubCategorisePageState({this.title, this.parentId, this.id}); @@ -42,986 +57,1146 @@ class _SubCategorisePageState extends State { color: Colors.blue, size: 29.0, ); - List entityList = List(); - List entityListBrands = List(); + + int pageIndex = 1; + + RefreshController controller = RefreshController(); + List entityList = []; + List entityListBrands = []; + @override Widget build(BuildContext context) { TextEditingController minField = TextEditingController(); TextEditingController maxField = TextEditingController(); + ProjectViewModel projectViewModel = Provider.of(context); + ProjectViewModel projectProvider = Provider.of(context); return BaseView( - onModelReady: (model) => model.getSubCategorise(i: id), - builder: (BuildContext context, PharmacyCategoriseViewModel model, - Widget child) => - PharmacyAppScaffold( - appBarTitle: title, - isBottomBar: false, + onModelReady: (model) => model.getSubCategorise(i: id, pageIndex: pageIndex, isLoading: false, context: context), + allowAny: true, + builder: (BuildContext context, PharmacyCategoriseViewModel model, Widget? child) => AppScaffold( + isPharmacy: true, + appBarTitle: title!, + isBottomBar: true, isShowAppBar: true, backgroundColor: Colors.white, isShowDecPage: false, + showPharmacyCart: false, + showHomeAppBarIcon: false, baseViewModel: model, - body: SingleChildScrollView( - child: Container( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - child: Image.network( - parentId == '1' - ? 'https://uat.hmgwebservices.com/epharmacy/content/images/thumbs/0089188_personal-care_2.png' - : parentId == '2' - ? 'https://uat.hmgwebservices.com/epharmacy/content/images/thumbs/0089189_skin-care_2.png' - : parentId == '3' - ? 'https://uat.hmgwebservices.com/epharmacy/content/images/thumbs/0089190_health-care_2.png' - : parentId == '4' - ? 'https://uat.hmgwebservices.com/epharmacy/content/images/thumbs/0089191_sexual-health_2.png' - : parentId == '5' - ? 'https://uat.hmgwebservices.com/epharmacy/content/images/thumbs/0089192_beauty_2.png' - : parentId == '6' - ? 'https://uat.hmgwebservices.com/epharmacy/content/images/thumbs/0089193_baby-child_2.png' - : parentId == '7' - ? 'https://uat.hmgwebservices.com/epharmacy/content/images/thumbs/0089194_vitamins-supplements_2.png' - : parentId == '8' - ? 'https://uat.hmgwebservices.com/epharmacy/content/images/thumbs/0089195_diet-nutrition_2.png' - : parentId == '9' - ? 'https://uat.hmgwebservices.com/epharmacy/content/images/thumbs/0089196_household_2.png' - : parentId == - '10' - ? 'https://uat.hmgwebservices.com/epharmacy/content/images/thumbs/0089197_home-care-appliances_2.png' - : '', - fit: BoxFit.fill, - height: 160.0, - width: double.infinity), - ), - if (model.subCategorise.length > 8) - Column( - children: [ - InkWell( - child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Padding( - padding: EdgeInsets.all(10.0), - child: Container( - child: Texts('View All Categories'), + body: SmartRefresher( + controller: controller, + enablePullDown: false, + enablePullUp: true, + onLoading: () async { + setState(() { + ++pageIndex; + }); + await model.getSubProducts(pageIndex: pageIndex, i: id, isLoading: true, context: context); + if (model.state != ViewState.BusyLocal && pageIndex < 5) { + controller.loadComplete(); + } else { + controller.loadFailed(); + } + }, + child: SingleChildScrollView( + child: Container( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + child: Image.network( + parentId == '1' + ? 'https://uat.hmgwebservices.com/epharmacy/content/images/thumbs/0089188_personal-care_2.png' + : parentId == '2' + ? 'https://uat.hmgwebservices.com/epharmacy/content/images/thumbs/0089189_skin-care_2.png' + : parentId == '3' + ? 'https://uat.hmgwebservices.com/epharmacy/content/images/thumbs/0089190_health-care_2.png' + : parentId == '4' + ? 'https://uat.hmgwebservices.com/epharmacy/content/images/thumbs/0089191_sexual-health_2.png' + : parentId == '5' + ? 'https://uat.hmgwebservices.com/epharmacy/content/images/thumbs/0089192_beauty_2.png' + : parentId == '6' + ? 'https://uat.hmgwebservices.com/epharmacy/content/images/thumbs/0089193_baby-child_2.png' + : parentId == '7' + ? 'https://uat.hmgwebservices.com/epharmacy/content/images/thumbs/0089194_vitamins-supplements_2.png' + : parentId == '8' + ? 'https://uat.hmgwebservices.com/epharmacy/content/images/thumbs/0089195_diet-nutrition_2.png' + : parentId == '9' + ? 'https://uat.hmgwebservices.com/epharmacy/content/images/thumbs/0089196_household_2.png' + : parentId == '10' + ? 'https://uat.hmgwebservices.com/epharmacy/content/images/thumbs/0089197_home-care-appliances_2.png' + : '', + fit: BoxFit.fill, + height: 160.0, + width: double.infinity), + ), + if (model.subCategorise.length > 8) + Column( + children: [ + InkWell( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: EdgeInsets.all(10.0), + child: Container( + child: Texts(TranslationBase.of(context).viewSubCategorise), + ), ), - ), - Icon(Icons.arrow_forward) - ], - ), - onTap: () { - showModalBottomSheet( - isScrollControlled: true, - context: context, - builder: (BuildContext context) { - return Container( - height: - MediaQuery.of(context).size.height * - 0.89, - color: Colors.white, - child: Center( - child: ListView.builder( - scrollDirection: Axis.vertical, - itemCount: - model.subCategorise.length, - itemBuilder: (BuildContext context, - int index) { - return Container( - child: Padding( - padding: EdgeInsets.all(8.0), - child: InkWell( - child: Column( - crossAxisAlignment: - CrossAxisAlignment - .start, - children: [ - Texts(model - .subCategorise[ - index] - .name), - Divider( - thickness: 0.6, - color: Colors.black12, - ) - ], - ), - onTap: () { - Navigator.push( - context, - FadePage( - page: - FinalProductsPage( - id: model - .subCategorise[ - index] - .id, + Icon(Icons.arrow_forward) + ], + ), + onTap: () { + showModalBottomSheet( + isScrollControlled: true, + context: context, + builder: (BuildContext context) { + return Container( + height: MediaQuery.of(context).size.height * 0.89, + color: Colors.white, + child: Center( + child: ListView.builder( + scrollDirection: Axis.vertical, + itemCount: model.subCategorise.length, + itemBuilder: (BuildContext context, int index) { + return Container( + child: Padding( + padding: EdgeInsets.all(8.0), + child: InkWell( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Texts( + projectViewModel.isArabic ? model.subCategorise[index].namen : model.subCategorise[index].name, +// model.subCategorise[index].name ), - ), - ); - }, + Divider( + thickness: 0.6, + color: Colors.black12, + ) + ], + ), + onTap: () { + Navigator.push( + context, + FadePage( + page: FinalProductsPage( + id: model.subCategorise[index].id!, + ), + ), + ); + }, + ), ), - ), - ); - }), - ), - ); - }, - ); - }, - ), - Divider( - thickness: 1.0, - color: Colors.grey.shade400, - ), - ], - ), + ); + }), + ), + ); + }, + ); + }, + ), + Divider( + thickness: 1.0, + color: Colors.grey.shade400, + ), + ], + ), //Expanded widget heree if nassery - Padding( - padding: EdgeInsets.only(top: 35.0), - child: Container( - height: MediaQuery.of(context).size.height * 0.2, - child: Center( - child: ListView.builder( - scrollDirection: Axis.horizontal, - itemCount: model.subCategorise.length, - itemBuilder: (BuildContext context, int index) { - return Padding( - padding: - EdgeInsets.symmetric(horizontal: 8.0), - child: InkWell( - child: Column( - crossAxisAlignment: - CrossAxisAlignment.center, - children: [ - Padding( - padding: EdgeInsets.symmetric( - horizontal: 13.0), - child: Container( - height: 60.0, - width: 65.0, - decoration: BoxDecoration( - shape: BoxShape.circle, - color: Colors.orange.shade200 - .withOpacity(0.45), + Padding( + padding: EdgeInsets.only(top: 35.0), + child: Container( + height: MediaQuery.of(context).size.height * 0.2, + child: Center( + child: ListView.builder( + scrollDirection: Axis.horizontal, + itemCount: model.subCategorise.length, + itemBuilder: (BuildContext context, int index) { + return Padding( + padding: EdgeInsets.symmetric(horizontal: 8.0), + child: InkWell( + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Padding( + padding: EdgeInsets.symmetric(horizontal: 13.0), + child: Container( + height: 60.0, + width: 65.0, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: Colors.orange.shade200.withOpacity(0.45), + ), + child: Center( + child: Icon( + Icons.apps_sharp, + size: 32.0, + ), + ), ), + ), + Container( + width: MediaQuery.of(context).size.width * 0.17, + height: MediaQuery.of(context).size.height * 0.10, child: Center( - child: Icon( - Icons.apps_sharp, - size: 32.0, + child: Texts( + projectViewModel.isArabic ? model.subCategorise[index].namen : model.subCategorise[index].name, + // model.subCategorise[index].name, + fontSize: 14, + fontWeight: FontWeight.w600, + maxLines: 2, ), ), ), - ), - Container( - width: MediaQuery.of(context) - .size - .width * - 0.17, - height: MediaQuery.of(context) - .size - .height * - 0.10, - child: Center( - child: Texts( - model.subCategorise[index].name, - fontSize: 14, - fontWeight: FontWeight.w600, - maxLines: 2, + ], + ), + onTap: () { + Navigator.push( + context, + FadePage( + page: FinalProductsPage( + id: model.subCategorise[index].id!, ), ), - ), - ], + ); + }, ), - onTap: () { - Navigator.push( - context, - FadePage( - page: FinalProductsPage( - id: model.subCategorise[index].id, - ), - ), - ); - }, - ), - ); - }), + ); + }), + ), ), ), - ), - Divider( - thickness: 1.0, - color: Colors.grey.shade400, - ), - Padding( - padding: EdgeInsets.symmetric(horizontal: 8.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - InkWell( - child: Row( - children: [ - Icon(Icons.wrap_text), - SizedBox( - width: 10.0, - ), - Texts( - 'Refine', - fontWeight: FontWeight.w600, - ), - ], - ), - onTap: () { - showModalBottomSheet( - isScrollControlled: true, - context: context, - builder: (BuildContext context) { - return DraggableScrollableSheet( - initialChildSize: 0.95, - maxChildSize: 0.95, - minChildSize: 0.9, - builder: (BuildContext context, - ScrollController scrollController) { - return SingleChildScrollView( - controller: scrollController, - child: Container( - color: Colors.white, - height: MediaQuery.of(context) - .size - .height * - 1.95, - child: Column( - children: [ - Padding( - padding: - EdgeInsets.all(8.0), - child: Row( + Divider( + thickness: 1.0, + color: Colors.grey.shade400, + ), + Padding( + padding: EdgeInsets.symmetric(horizontal: 8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + InkWell( + child: Row( + children: [ + Icon(Icons.wrap_text), + SizedBox( + width: 10.0, + ), + Texts( + TranslationBase.of(context).refine, +// 'Refine', + fontWeight: FontWeight.w600, + ), + ], + ), + onTap: () { + showModalBottomSheet( + isScrollControlled: true, + context: context, + builder: (BuildContext context) { + return DraggableScrollableSheet( + initialChildSize: 0.95, + maxChildSize: 0.95, + minChildSize: 0.9, + builder: (BuildContext context, ScrollController scrollController) { + return SingleChildScrollView( + controller: scrollController, + child: Container( + color: Colors.white, + height: MediaQuery.of(context).size.height * 1.95, + child: Column( + children: [ + Padding( + padding: EdgeInsets.all(8.0), + child: Row( + children: [ + Icon( + Icons.wrap_text, + ), + SizedBox( + width: 10.0, + ), + Texts( + TranslationBase.of(context).refine, +// 'Refine', + fontWeight: FontWeight.w600, + ), + SizedBox( + width: 250.0, + ), + InkWell( + child: Texts( + TranslationBase.of(context).closeIt, +// 'Close', + color: Colors.red, + fontWeight: FontWeight.w600, + fontSize: 15.0, + ), + onTap: () { + Navigator.pop(context); + }, + ), + ], + ), + ), + Divider( + thickness: 1.0, + color: Colors.black12, + ), + Column( children: [ - Icon( - Icons.wrap_text, - ), - SizedBox( - width: 10.0, + ExpansionTile( + title: Texts(TranslationBase.of(context).subGroup), + children: [ + ProcedureListWidget( + model: model, + masterList: model.subCategorise, + removeHistory: (item) { + setState(() { + entityList.remove(item); + }); + }, + addHistory: (history) { + setState(() { + entityList.add(history); + }); + }, + isEntityListSelected: (master) => isEntityListSelected(master), + ) + ], ), - Texts( - 'Refine', - fontWeight: - FontWeight.w600, + Divider( + thickness: 1.0, + color: Colors.black12, ), - SizedBox( - width: 250.0, + ExpansionTile( + title: Texts(TranslationBase.of(context).brands), + children: [ + ProcedureListWidget( + model: model, + masterList: model.brandsList, + removeHistory: (item) { + setState(() { + entityListBrands.remove(item); + }); + }, + addHistory: (history) { + setState(() { + entityListBrands.add(history); + }); + }, + isEntityListSelected: (master) => isEntityListSelectedBrands(master), + ) + ], ), - InkWell( - child: Texts( - 'Close', - color: Colors.red, - fontWeight: - FontWeight.w600, - fontSize: 15.0, - ), - onTap: () { - Navigator.pop( - context); - }, + Divider( + thickness: 1.0, + color: Colors.black12, ), - ], - ), - ), - Divider( - thickness: 1.0, - color: Colors.black12, - ), - Column( - children: [ - ExpansionTile( - title: - Texts('Categorise'), - children: [ - ProcedureListWidget( - model: model, - masterList: model - .subCategorise, - removeHistory: - (item) { - setState(() { - entityList - .remove( - item); - }); - }, - addHistory: - (history) { - setState(() { - entityList.add( - history); - }); - }, - addSelectedHistories: - () { - //TODO build your fun herr - // widget.addSelectedHistories(); - }, - isEntityListSelected: - (master) => - isEntityListSelected( - master), - ) - ], - ), - Divider( - thickness: 1.0, - color: Colors.black12, - ), - ExpansionTile( - title: Texts('Brands'), - children: [ - ProcedureListWidget( - model: model, - masterList: model - .brandsList, - removeHistory: - (item) { - setState(() { - entityListBrands - .remove( - item); - }); - }, - addHistory: - (history) { - setState(() { - entityListBrands - .add( - history); - }); - }, - addSelectedHistories: - () { - //TODO build your fun herr - // widget.addSelectedHistories(); - }, - isEntityListSelected: - (master) => - isEntityListSelectedBrands( - master), - ) - ], - ), - Divider( - thickness: 1.0, - color: Colors.black12, - ), - ExpansionTile( - title: Texts('Price'), - children: [ - Container( - color: Color( - 0xffEEEEEE), - child: Row( - mainAxisAlignment: - MainAxisAlignment - .spaceAround, - children: [ - Column( - mainAxisAlignment: - MainAxisAlignment - .start, - children: [ - Texts( - 'Min'), - Container( - color: Colors - .white, - width: - 200, - height: - 40, - child: - TextFormField( - decoration: - InputDecoration( - border: - OutlineInputBorder(), + ExpansionTile( + title: Texts(TranslationBase.of(context).price), + children: [ + Container( + color: Color(0xffEEEEEE), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Texts(TranslationBase.of(context).min), + Container( + color: Colors.white, + width: 200, + height: 40, + child: TextFormField( + decoration: InputDecoration( + border: OutlineInputBorder(), + ), + controller: minField, ), - controller: - minField, ), - ), - ], - ), - Column( - mainAxisAlignment: - MainAxisAlignment - .start, - children: [ - Texts( - 'Max'), - Container( - color: Colors - .white, - width: - 200, - height: - 40, - child: - TextFormField( - decoration: - InputDecoration( - border: - OutlineInputBorder(), + ], + ), + Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Texts(TranslationBase.of(context).max), + Container( + color: Colors.white, + width: 200, + height: 40, + child: TextFormField( + decoration: InputDecoration( + border: OutlineInputBorder(), + ), + controller: maxField, ), - controller: - maxField, ), - ), - ], + ], + ), + ], + ), + ) + ], + ), + Divider( + thickness: 1.0, + color: Colors.black12, + ), + SizedBox( + height: MediaQuery.of(context).size.height * 0.4, + ), + Padding( + padding: EdgeInsets.all(8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Expanded( + child: Container( + width: 100, + child: Button( + label: TranslationBase.of(context).reset, +// 'Reset', + backgroundColor: Colors.red, + ), ), - ], - ), - ) - ], - ), - Divider( - thickness: 1.0, - color: Colors.black12, - ), - SizedBox( - height: MediaQuery.of( - context) - .size - .height * - 0.4, - ), - Padding( - padding: - EdgeInsets.all(8.0), - child: Row( - mainAxisAlignment: - MainAxisAlignment - .spaceEvenly, - children: [ - Container( - width: 100, - child: Button( - label: 'Reset', - backgroundColor: - Colors.red, ), - ), - SizedBox( - width: 30, - ), - Container( - width: 200, - child: Button( - onTap: () { - String - categoriesId = - ""; - for (CategoriseParentModel category - in entityList) { - if (categoriesId == - "") { - categoriesId = - category - .id; - } else { - categoriesId = - "$categoriesId,${category.id}"; + SizedBox( + width: 30, + ), + Container( + width: 200, + child: Button( + onTap: () async { + String categoriesId = ""; + for (CategoriseParentModel category in entityList) { + if (categoriesId == "") { + categoriesId = category.id!; + } else { + categoriesId = "$categoriesId,${category.id}"; + } } - } - String - brandIds = - ""; - for (CategoriseParentModel brand - in entityListBrands) { - if (brandIds == - "") { - brandIds = - brand - .id; - } else { - brandIds = - "$brandIds,${brand.id}"; + String brandIds = ""; + + for (CategoriseParentModel brand in entityListBrands) { + if (brandIds == "") { + brandIds = brand.id!; + } else { + brandIds = "$brandIds,${brand.id}"; + } } - } + GifLoaderDialogUtils.showMyDialog(context); - model.getFilteredProducts( - min: minField - .text - .toString(), - max: maxField - .text - .toString(), - categoryId: - categoriesId, - brandId: - brandIds); - }, - label: 'Apply', - backgroundColor: - Colors - .green, + await model.getFilteredSubProducts( + min: minField.text.isEmpty ? "" : minField.text.toString(), + max: maxField.text.isEmpty ? "" : maxField.text.toString(), + categoryId: categoriesId, + brandId: brandIds.isEmpty ? "" : "&manufacturerids=" + brandIds); + GifLoaderDialogUtils.hideDialog(context); + Navigator.pop(context); + }, + label: TranslationBase.of(context).apply, +// 'Apply', + backgroundColor: Colors.green, + ), ), - ), - ], + ], + ), ), - ), - ], - ), - ], + ], + ), + ], + ), ), - ), - ); - }); - }, - ); - }, - ), - Row( - children: [ - Container( - height: 44.0, - child: VerticalDivider( - color: Colors.black45, - thickness: 1.0, - //width: 0.3, - // indent: 0.0, - ), - ), - Padding( - padding: EdgeInsets.all(8.0), - child: InkWell( - child: styleIcon, - onTap: () { - setState(() { - if (styleOne == true) { - styleOne = false; - styleTwo = true; - styleIcon = Icon( - Icons.auto_awesome_mosaic, - color: Colors.blue, - size: 29.0, - ); - } else { - styleOne = true; - styleTwo = false; - styleIcon = Icon( - Icons.widgets_sharp, - color: Colors.blue, - size: 29.0, - ); - } - }); + ); + }); }, + ); + }, + ), + Row( + children: [ + Container( + height: 44.0, + child: VerticalDivider( + color: Colors.black45, + thickness: 1.0, + //width: 0.3, + // indent: 0.0, + ), ), - ), - ], - ), - ], + Padding( + padding: EdgeInsets.all(8.0), + child: InkWell( + child: styleIcon, + onTap: () { + setState(() { + if (styleOne == true) { + styleOne = false; + styleTwo = true; + styleIcon = Icon( + Icons.auto_awesome_mosaic, + color: CustomColors.green, + size: 29.0, + ); + } else { + styleOne = true; + styleTwo = false; + styleIcon = Icon( + Icons.widgets_sharp, + color: CustomColors.green, + size: 29.0, + ); + } + }); + }, + ), + ), + ], + ), + ], + ), ), - ), - Divider( - thickness: 1.0, - color: Colors.grey.shade400, - ), - styleOne == true - ? Container( - height: model.subProducts.length * - MediaQuery.of(context).size.height * - 0.15, - child: GridView.builder( - physics: NeverScrollableScrollPhysics(), - gridDelegate: - SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 2, - crossAxisSpacing: 0.5, - mainAxisSpacing: 2.0, - childAspectRatio: 0.9, - ), - itemCount: model.subProducts.length, - itemBuilder: (BuildContext context, int index) { - return NetworkBaseView( - baseViewModel: model, - child: InkWell( - child: Card( - color: model.subProducts[index] - .discountName != - null - ? Color(0xffFFFF00) - : Colors.white, - elevation: 0, - shape: Border( - right: BorderSide( - color: Colors.grey.shade300, - width: 1, - ), - left: BorderSide( - color: Colors.grey.shade300, - width: 1, - ), - bottom: BorderSide( - color: Colors.grey.shade300, - width: 1, - ), - top: BorderSide( - color: Colors.grey.shade300, - width: 1, - ), - ), - margin: EdgeInsets.symmetric( - horizontal: 8, - vertical: 4, - ), - child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.only( - topLeft: Radius.circular(110.0), + Divider( + thickness: 1.0, + color: Colors.grey.shade400, + ), + model.subProducts.isNotEmpty + ? styleOne == true + ? Container( + height: model.subProducts.length * MediaQuery.of(context).size.height * 0.15, + child: GridView.builder( + physics: NeverScrollableScrollPhysics(), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + crossAxisSpacing: 0.5, + mainAxisSpacing: 2.0, + childAspectRatio: 0.9, + ), + itemCount: model.subProducts.length, + itemBuilder: (BuildContext context, int index) { + return InkWell( + child: Card( + color: model.subProducts[index].discountName != null ? Color(0xffFFFF00) : Colors.white, + elevation: 0, + shape: Border( + right: BorderSide( + color: Colors.grey.shade300, + width: 1, + ), + left: BorderSide( + color: Colors.grey.shade300, + width: 1, + ), + bottom: BorderSide( + color: Colors.grey.shade300, + width: 1, + ), + top: BorderSide( + color: Colors.grey.shade300, + width: 1, ), - color: Colors.white, ), - padding: EdgeInsets.symmetric( - horizontal: 0), - width: MediaQuery.of(context) - .size - .width / - 3, - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Stack( - children: [ - Container( - margin: - EdgeInsets.fromLTRB( - 0, 16, 0, 0), - alignment: - Alignment.center, - child: Image.network( - model - .subProducts[ - index] - .images - .isNotEmpty - ? model - .subProducts[ - 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.cover, - height: 80, - ), - ), - Container( - width: model - .subProducts[ - index] - .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: Texts( - model.subProducts[index] - .rxMessage != - null - ? model - .subProducts[ - index] - .rxMessage - : "", - color: Colors.white, - regular: true, - fontSize: 10, - fontWeight: - FontWeight.w400, - ), - ), - ], + margin: EdgeInsets.symmetric( + horizontal: 8, + vertical: 4, + ), + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(110.0), ), - Container( - margin: EdgeInsets.symmetric( - horizontal: 6, - vertical: 0, - ), - child: Column( - crossAxisAlignment: - CrossAxisAlignment - .start, + color: Colors.white, + ), + padding: EdgeInsets.symmetric(horizontal: 0), + width: MediaQuery.of(context).size.width / 3, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Stack( children: [ - Texts( - model.subProducts[index] - .name, - regular: true, - fontSize: 12, - fontWeight: - FontWeight.w400, - ), - Padding( - padding: - const EdgeInsets - .only( - top: 4, - bottom: 4), - child: Texts( - "SAR ${model.subProducts[index].price}", - bold: true, - fontSize: 14, + Container( + margin: EdgeInsets.fromLTRB(0, 16, 0, 0), + alignment: Alignment.center, + child: Image.network( + model.subProducts[index].images!.isNotEmpty + ? model.subProducts[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.cover, + height: 80, ), ), - Row( - children: [ - StarRating( - totalAverage: model - .subProducts[ - index] - .approvedRatingSum > - 0 - ? (model.subProducts[index].approvedRatingSum - .toDouble() / - model - .subProducts[index] - .approvedRatingSum - .toDouble()) - .toDouble() - : 0, - forceStars: true), - Texts( - "(${model.subProducts[index].approvedTotalReviews})", - regular: true, - fontSize: 10, - fontWeight: - FontWeight.w400, - ) - ], + Container( + width: model.subProducts[index].rxMessage != null ? MediaQuery.of(context).size.width / 3 : 0, + padding: EdgeInsets.all(4), + decoration: BoxDecoration( + color: Color(0xffb23838), + borderRadius: BorderRadius.only(topLeft: Radius.circular(6)), + ), + child: model.subProducts[index].rxMessage != null + ? Texts( + projectProvider.isArabic ? model.subProducts[index].rxMessagen : model.subProducts[index].rxMessage, + color: Colors.white, + regular: true, + fontSize: 10, + fontWeight: FontWeight.w400, + ) + : Texts(""), +// Texts( +// model.subProducts[index].rxMessage != null ? model.subProducts[index].rxMessage : "", +// color: Colors.white, +// regular: true, +// fontSize: 10, +// fontWeight: FontWeight.w400, +// ), ), ], ), - ), - ], - ), - ), - ), - onTap: () => { - Navigator.push( - context, - FadePage( - page: ProductDetailPage( - model.subProducts[index]), - )), - }, - )); - }, - ), - ) - : Container( - height: model.subProducts.length * - MediaQuery.of(context).size.height * - 0.122, - child: ListView.builder( - physics: NeverScrollableScrollPhysics(), - itemCount: model.subProducts.length, - itemBuilder: - (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, - ), - ), - ), - Container( - margin: - EdgeInsets.fromLTRB( - 0, 0, 0, 0), - alignment: - Alignment.center, - child: Image.network( - model - .subProducts[ - index] - .images - .isNotEmpty - ? model - .subProducts[ - 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.symmetric( + horizontal: 6, + vertical: 0, ), - ], - ), - Column( - children: [ - Container( - width: model - .subProducts[ - index] - .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: Texts( - model.subProducts[index] - .rxMessage != - null - ? model - .subProducts[ - index] - .rxMessage - : "", - color: Colors.white, - regular: true, - fontSize: 10, - fontWeight: - FontWeight.w400, - ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Texts( + projectViewModel.isArabic ? model.subProducts[index].namen : model.subProducts[index].name, +// model.subProducts[index].name, + regular: true, + fontSize: 12, + fontWeight: FontWeight.w400, + ), + Padding( + padding: const EdgeInsets.only(top: 4, bottom: 4), + child: Texts( + "SAR ${model.subProducts[index].price}", + bold: true, + fontSize: 14, + ), + ), + Row( + children: [ +// StarRating( +// totalAverage: model.subProducts[index].approvedRatingSum > 0 +// ? (model.subProducts[index].approvedRatingSum.toDouble() / model.subProducts[index].approvedRatingSum.toDouble()).toDouble() +// : 0, +// forceStars: true), + RatingBar( + initialRating: model.subProducts[index].approvedRatingSum!.toDouble(), + ratingWidget: RatingWidget( + full: Icon( + Icons.star, + color: CustomColors.accentColor, + ), + half: Icon( + Icons.star_half, + color: CustomColors.accentColor, + ), + empty: Icon( + Icons.star_border, + color: CustomColors.accentColor, + ), + ), + onRatingUpdate: (double value) {}, + unratedColor: Colors.grey[500], + updateOnDrag: false, + tapOnlyMode: false, + ), + Texts( + "(${model.subProducts[index].approvedTotalReviews})", + regular: true, + fontSize: 10, + fontWeight: FontWeight.w400, + ) + ], + ), + ], ), - ], - ), - ], - ), - Container( - height: 100.0, - margin: EdgeInsets.symmetric( - horizontal: 6, - vertical: 0, + ), + ], ), - child: Column( - mainAxisAlignment: - MainAxisAlignment - .spaceAround, - crossAxisAlignment: - CrossAxisAlignment.start, + ), + ), + onTap: () => { + Navigator.push( + context, + FadePage( + page: ProductDetailPage(model.subProducts[index]), + )), + }, + ); + }, + ), + ) + : Container( + height: model.subProducts.length * MediaQuery.of(context).size.height * 0.122, + child: ListView.builder( + physics: NeverScrollableScrollPhysics(), + itemCount: model.subProducts.length, + itemBuilder: (BuildContext context, int index) { + return InkWell( + child: Card( + child: Row( children: [ - SizedBox( - height: 4.0, + Stack( + children: [ + Column( + children: [ + Container( + decoration: BoxDecoration(), + child: Padding( + padding: EdgeInsets.only( + left: 9.0, + top: 8.0, + right: 10.0, + ), + ), + ), + Container( + margin: EdgeInsets.fromLTRB(0, 0, 0, 8), + alignment: Alignment.center, + child: (model.subProducts[index].images != null && model.subProducts[index].images!.length > 0) + ? Image.network( + model.subProducts[index].images![0].src!, + fit: BoxFit.cover, + height: 80, + width: 80, + ) + : Image.asset( + "assets/images/no_image.png", + fit: BoxFit.cover, + height: 80, + width: 80, + ), + ), + ], + ), + Column( + children: [ + Container( + width: model.subProducts[index].rxMessage != null ? MediaQuery.of(context).size.width / 3.70 : 0, + padding: EdgeInsets.all(4), + decoration: BoxDecoration( + color: Color(0xffb23838), + //borderRadius: BorderRadius.only(topLeft: Radius.circular(5)), + ), + child: model.subProducts[index].rxMessage != null + ? Texts( + projectProvider.isArabic ? model.subProducts[index].rxMessagen : model.subProducts[index].rxMessage, + color: Colors.white, + regular: true, + fontSize: 8, + fontWeight: FontWeight.w600, + ) + : Texts(""), + ), + ], + ), + ], ), Container( - width: - MediaQuery.of(context) - .size - .width * - 0.65, - child: Texts( - model.subProducts[index] - .name, - regular: true, - fontSize: 13.2, - fontWeight: - FontWeight.w500, - maxLines: 5, + height: 100.0, + margin: EdgeInsets.symmetric( + horizontal: 6, + vertical: 0, ), - ), - SizedBox( - height: 8.0, - ), - Padding( - padding: - const EdgeInsets.only( - top: 4, bottom: 4), - child: Texts( - "SAR ${model.subProducts[index].price}", - bold: true, - fontSize: 14, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceAround, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: 4.0, + ), + Container( + width: MediaQuery.of(context).size.width * 0.55, + child: Texts( + projectViewModel.isArabic ? model.subProducts[index].namen : model.subProducts[index].name, + regular: true, + fontSize: 13.2, + fontWeight: FontWeight.w500, + maxLines: 5, + ), + ), + SizedBox( + height: 8.0, + ), + Padding( + padding: const EdgeInsets.only(top: 4, bottom: 4), + child: Texts( + "SAR ${model.subProducts[index].price}", + bold: true, + fontSize: 14, + ), + ), + Row( + children: [ + RatingBar( + initialRating: model.subProducts[index].approvedRatingSum!.toDouble(), + ratingWidget: RatingWidget( + full: Icon( + Icons.star, + color: CustomColors.accentColor, + ), + half: Icon( + Icons.star_half, + color: CustomColors.accentColor, + ), + empty: Icon( + Icons.star_border, + color: CustomColors.accentColor, + ), + ), + onRatingUpdate: (double value) {}, + unratedColor: Colors.grey[500], + updateOnDrag: false, + tapOnlyMode: false, + ), + Texts( + "(${model.subProducts[index].approvedTotalReviews})", + regular: true, + fontSize: 10, + fontWeight: FontWeight.w400, + ) + ], + ), + ], ), ), - Row( - children: [ - StarRating( - totalAverage: model - .subProducts[ - index] - .approvedRatingSum > - 0 - ? (model - .subProducts[ - index] - .approvedRatingSum - .toDouble() / - model - .parentProducts[ - index] - .approvedRatingSum - .toDouble()) - .toDouble() - : 0, - forceStars: true), - Texts( - "(${model.subProducts[index].approvedTotalReviews})", - regular: true, - fontSize: 10, - fontWeight: - FontWeight.w400, - ) - ], - ), + widget.authenticatedUserObject.isLogin + ? Container( + child: IconButton( + icon: Icon( + Icons.shopping_cart, + size: 18, + color: CustomColors.green, + ), + onPressed: () async { + if (model.subProducts[index].isRx == false) { + GifLoaderDialogUtils.showMyDialog(context); + await addToCartFunction(1, model.subProducts[index].id); + GifLoaderDialogUtils.hideDialog(context); + utils.Utils.navigateToCartPage(); + } else { + AppToast.showErrorToast(message: TranslationBase.of(context).needPrescription); + } +// + }), + ) + : Container(), ], ), ), - ], + onTap: () => { + Navigator.push( + context, + FadePage( + page: ProductDetailPage(model.subProducts[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, +// ), +// ), +// ), +// Container( +// margin: EdgeInsets +// .fromLTRB( +// 0, 0, 0, 0), +// alignment: Alignment +// .center, +// child: model +// .subProducts[ +// index] +// .images +// .isNotEmpty +// ? Image.network( +// model +// .subProducts[ +// index] +// .images[ +// 0] +// .thumb, +// fit: BoxFit +// .contain, +// height: 70, +// ) +// : Text(TranslationBase.of( +// context) +// .noImage), +// ), +// ], +// ), +// Column( +// children: [ +// Container( +// width: model +// .subProducts[ +// index] +// .rxMessage != +// null +// ? MediaQuery.of( +// context) +// .size +// .width / +// 3.70 +// : 0, +// padding: +// EdgeInsets.all( +// 4), +// decoration: +// BoxDecoration( +// color: Color( +// 0xffb23838), +// // borderRadius: BorderRadius.only( +// // topLeft: Radius +// // .circular( +// // 6)), +// ), +// child: model +// .subProducts[ +// index] +// .rxMessage != +// null +// ? Texts( +// projectProvider +// .isArabic +// ? model +// .subProducts[ +// index] +// .rxMessagen +// : model +// .subProducts[index] +// .rxMessage, +// color: Colors +// .white, +// regular: +// true, +// fontSize: +// 10, +// fontWeight: +// FontWeight +// .w400, +// ) +// : Texts(""), +// // Texts( +// // model.subProducts[index].rxMessage != null ? model.subProducts[index].rxMessage : "", +// // color: Colors.white, +// // regular: true, +// // fontSize: 10, +// // fontWeight: FontWeight.w400, +// // ), +// ), +// ], +// ), +// ], +// ), +// Container( +// height: 130.0, +// margin: +// EdgeInsets.symmetric( +// horizontal: 0, +// 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( +// projectViewModel +// .isArabic +// ? model +// .subProducts[ +// index] +// .namen +// : model +// .subProducts[ +// index] +// .name, +// // model.subProducts[index].name, +// regular: true, +// fontSize: 13.2, +// fontWeight: +// FontWeight.w500, +// maxLines: 5, +// ), +// ), +// SizedBox( +// height: 8.0, +// ), +// Padding( +// padding: +// const EdgeInsets +// .only( +// top: 4, +// bottom: 4), +// child: Texts( +// "SAR ${model.subProducts[index].price}", +// bold: true, +// fontSize: 14, +// ), +// ), +// Row( +// children: [ +// // StarRating( +// // totalAverage: model.subProducts[index].approvedRatingSum > 0 +// // ? (model.subProducts[index].approvedRatingSum.toDouble() / model.subProducts[index].approvedRatingSum.toDouble()).toDouble() +// // : 0, +// // forceStars: true), +// RatingBar.readOnly( +// initialRating: model +// .subProducts[ +// index] +// .approvedRatingSum +// .toDouble(), +// size: 15.0, +// filledColor: +// Colors.yellow[ +// 700], +// emptyColor: Colors +// .grey[500], +// isHalfAllowed: +// true, +// halfFilledIcon: +// Icons +// .star_half, +// filledIcon: +// Icons.star, +// emptyIcon: +// Icons.star, +// ), +// Texts( +// "(${model.subProducts[index].approvedTotalReviews})", +// regular: true, +// fontSize: 10, +// fontWeight: +// FontWeight +// .w400, +// ) +// ], +// ), +// ], +// ), +// ), +// widget.authenticatedUserObject +// .isLogin +// ? Container( +// child: IconButton( +// icon: Icon( +// Icons +// .shopping_cart, +// size: 18, +// color: +// CustomColors +// .green, +// ), +// onPressed: +// () async { +// if (model +// .subProducts[ +// index] +// .isRx == false) { +// GifLoaderDialogUtils +// .showMyDialog( +// context); +// await addToCartFunction( +// 1, +// model +// .subProducts[ +// index] +// .id); +// GifLoaderDialogUtils +// .hideDialog( +// context); +// Utils +// .navigateToCartPage(); +// } else { +// AppToast.showErrorToast( +// message: TranslationBase.of( +// context) +// .needPrescription); +// } +// }), +// ) +// : Container(), +// ], +// ), +// ), +// onTap: () => { +// Navigator.push( +// context, +// FadePage( +// page: ProductDetailPage( +// model.subProducts[ +// index]), +// )), +// }, +// ); + }), + ) + : Padding( + padding: const EdgeInsets.all(12.0), + child: Container( + child: 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, + ), ), - ), - onTap: () => { - Navigator.push( - context, - FadePage( - page: ProductDetailPage( - model.subProducts[index]), - )), - }, - ); - }), - ) - ], + Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + TranslationBase.of(context).noData, + style: TextStyle(fontSize: 30), + ), + ) + ], + ), + ), + ), + ) + ], + ), ), ), ), @@ -1029,8 +1204,7 @@ class _SubCategorisePageState extends State { } bool isEntityListSelected(CategoriseParentModel masterKey) { - Iterable history = - entityList.where((element) => masterKey.id == element.id); + Iterable history = entityList.where((element) => masterKey.id == element.id); if (history.length > 0) { return true; } @@ -1038,11 +1212,15 @@ class _SubCategorisePageState extends State { } bool isEntityListSelectedBrands(CategoriseParentModel masterKey) { - Iterable history = - entityListBrands.where((element) => masterKey.id == element.id); + Iterable history = entityListBrands.where((element) => masterKey.id == element.id); if (history.length > 0) { return true; } return false; } + + addToCartFunction(quantity, itemID) async { + ProductDetailViewModel x = new ProductDetailViewModel(); + await x.addToCartData(quantity, itemID, context); + } } diff --git a/lib/pages/symptom-checker/info.dart b/lib/pages/symptom-checker/info.dart index 7906ba1a..41724809 100644 --- a/lib/pages/symptom-checker/info.dart +++ b/lib/pages/symptom-checker/info.dart @@ -1,12 +1,10 @@ -import 'package:diplomaticquarterapp/config/size_config.dart'; +import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; -import 'package:diplomaticquarterapp/widgets/card/rounded_container.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/text/app_texts_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:diplomaticquarterapp/routes.dart'; class SymptomInfo extends StatefulWidget { @override @@ -96,7 +94,7 @@ class _SymptomInfo extends State { value: checkValue, onChanged: (newValue) { setState(() { - this.checkValue = newValue; + this.checkValue = newValue!; }); }, controlAffinity: ListTileControlAffinity diff --git a/lib/pages/symptom-checker/select-gender.dart b/lib/pages/symptom-checker/select-gender.dart index 0b8be29d..c0ca1712 100644 --- a/lib/pages/symptom-checker/select-gender.dart +++ b/lib/pages/symptom-checker/select-gender.dart @@ -1,13 +1,11 @@ -import 'package:diplomaticquarterapp/config/size_config.dart'; +import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; -import 'package:diplomaticquarterapp/widgets/card/rounded_container.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/text/app_texts_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:diplomaticquarterapp/routes.dart'; -import 'package:flutter_xlider/flutter_xlider.dart'; +// import 'package:flutter_xlider/flutter_xlider.dart'; class SelectGender extends StatefulWidget { @override @@ -84,18 +82,18 @@ class _SelectGender extends State { SizedBox( height: 30, ), - FlutterSlider( - values: [slider], - max: 90, - min: 14, - onDragCompleted: (handlerIndex, lowerValue, upperValue) { - print(lowerValue); - print(upperValue); - setState(() { - slider = upperValue; - }); - }, - ), + // FlutterSlider( + // values: [slider], + // max: 90, + // min: 14, + // onDragCompleted: (handlerIndex, lowerValue, upperValue) { + // print(lowerValue); + // print(upperValue); + // setState(() { + // slider = upperValue; + // }); + // }, + // ), ], ), Expanded( diff --git a/lib/pages/vaccine/my_vaccines_item_screen.dart b/lib/pages/vaccine/my_vaccines_item_screen.dart index 33ef5975..2aa78aee 100644 --- a/lib/pages/vaccine/my_vaccines_item_screen.dart +++ b/lib/pages/vaccine/my_vaccines_item_screen.dart @@ -1,19 +1,15 @@ -import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/config/size_config.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/vaccine_view_model.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.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'; -import 'package:flutter/material.dart'; -import 'package:diplomaticquarterapp/config/size_config.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'; + import '../base/base_view.dart'; -import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:diplomaticquarterapp/core/viewModels/vaccine_view_model.dart'; -import 'package:diplomaticquarterapp/widgets/others/rounded_container.dart'; -import 'package:popup_box/popup_box.dart'; class MyVaccinesItemPage extends StatefulWidget { @override @@ -26,16 +22,16 @@ class _MyVaccinesItemPageState extends State { ProjectViewModel projectViewModel = Provider.of(context); return BaseView( onModelReady: (model) => model.getMyVaccinationItem(), - builder: (BuildContext context, VaccineViewModel model, Widget child) => + builder: (BuildContext context, VaccineViewModel model, Widget? child) => AppScaffold( isShowAppBar: true, appBarTitle: TranslationBase.of(context).myVaccinesAvailability, baseViewModel: model, body: Container( margin: EdgeInsets.only( - left: SizeConfig.screenWidth * 0.004, - right: SizeConfig.screenWidth * 0.004, - top: SizeConfig.screenWidth * 0.04, + left: SizeConfig.screenWidth! * 0.004, + right: SizeConfig.screenWidth! * 0.004, + top: SizeConfig.screenWidth! * 0.04, ), child: ListView.builder( itemCount: model.vaccinationItemList.length, @@ -64,7 +60,7 @@ class _MyVaccinesItemPageState extends State { child: Texts( model.vaccinationItemList[index].dESCRIPTION)), Icon(projectViewModel.isArabic - ? Icons.arrow_forward_ios + ? Icons.arrow_forward : Icons.arrow_back_ios) ], ), diff --git a/lib/pages/vaccine/my_vaccines_screen.dart b/lib/pages/vaccine/my_vaccines_screen.dart index fb723a1f..44d85cc5 100644 --- a/lib/pages/vaccine/my_vaccines_screen.dart +++ b/lib/pages/vaccine/my_vaccines_screen.dart @@ -1,20 +1,19 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/vaccine_view_model.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.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/transitions/fade_page.dart'; -import 'package:flutter/material.dart'; -import 'package:diplomaticquarterapp/config/size_config.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/medical/doctor_card.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/confirm_send_email_dialog.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_expandable_notifier.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'; -import '../base/base_view.dart'; -import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:diplomaticquarterapp/core/viewModels/vaccine_view_model.dart'; -import 'package:diplomaticquarterapp/widgets/others/rounded_container.dart'; -import 'package:popup_box/popup_box.dart'; -import 'my_vaccines_item_screen.dart'; +import '../base/base_view.dart'; //TODO fix by jammal we have a static data class MyVaccines extends StatefulWidget { @@ -28,193 +27,77 @@ class _MyVaccinesState extends State { ProjectViewModel projectViewModel = Provider.of(context); return BaseView( onModelReady: (model) => model.getVaccine(), - builder: (BuildContext context, VaccineViewModel model, Widget child) => - AppScaffold( + builder: (BuildContext context, VaccineViewModel model, Widget? child) => AppScaffold( isShowAppBar: true, - appBarTitle: TranslationBase.of(context).myVaccines, + showNewAppBar: true, + showNewAppBarTitle: true, baseViewModel: model, - body: Container( - margin: EdgeInsets.only( - left: SizeConfig.screenWidth * 0.004, - right: SizeConfig.screenWidth * 0.004, - top: SizeConfig.screenWidth * 0.04, - ), + appBarTitle: TranslationBase.of(context).myVaccines, + description: TranslationBase.of(context).infoVaccines, + imagesInfo: [ + ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-vacceines/en/0.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-vacceines/ar/0.png'), + ], + body: SingleChildScrollView( child: Column( children: [ - RoundedContainer( - backgroundColor: Colors.white, - child: ExpansionTile( - title: Container( - height: 65.0, - child: Text('2018'), + AppExpandableNotifier( + isExpand: true, + title: model.state == ViewState.Idle + ? model.vaccineList.isEmpty + ? "" + : DateUtil.convertStringToDate(model.vaccineList[0].vaccinationDate!).year.toString() + : "", + bodyWidget: Container( + child: ListView.separated( + physics: ScrollPhysics(), + scrollDirection: Axis.vertical, + shrinkWrap: true, + itemCount: model.vaccineList == null ? 0 : model.vaccineList.length, + padding: EdgeInsets.only(bottom: 14, top: 14, left: 21, right: 21), + separatorBuilder: (context, index) => SizedBox(height: 14), + itemBuilder: (BuildContext context, int index) { + return DoctorCard( + onTap: null, + isInOutPatient: true, + isShowInOutPatient: false, + name: TranslationBase.of(context).dr.toString() + " " + model.vaccineList[index].doctorName!, + billNo: "", + vaccineName: model.vaccineList[index].vaccineName!, + profileUrl: model.vaccineList[index].doctorImageURL, + subName: model.vaccineList[index].projectName, + isLiveCareAppointment: false, + date: DateUtil.convertStringToDate(model.vaccineList[index].vaccinationDate!), + isSortByClinic: true, + ); + }, ), - children: [ - Container( - child: ListView.builder( - scrollDirection: Axis.vertical, - shrinkWrap: true, - itemCount: model.vaccineList == null - ? 0 - : model.vaccineList.length, - itemBuilder: (BuildContext context, int index) { - return Column( - children: [ - RoundedContainer( - child: Column( - children: [ - Row( - children: [ - Expanded( - child: Column( - children: [ - Padding( - padding: EdgeInsets.symmetric( - horizontal: 20.0, - vertical: 20.0), - child: Image.network( - model.vaccineList[index] - .doctorImageURL, - height: SizeConfig - .imageSizeMultiplier * - 23, - width: SizeConfig - .imageSizeMultiplier * - 20, - fit: BoxFit.fill, - ), - ), - ], - ), - flex: 2, - ), - Expanded( - child: Container( - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Text( - model.vaccineList[index] - .doctorTitle + - model.vaccineList[index] - .doctorName, - style: TextStyle( - fontWeight: - FontWeight.w900, - fontSize: 16.6, - ), - ), - SizedBox(height: 7.0), - Text( - model.vaccineList[index] - .projectName, - style: TextStyle( - fontSize: 17.0, - letterSpacing: 0.5, - ), - ), - SizedBox(height: 7.0), - Text( - model.vaccineList[index] - .vaccineName, - style: TextStyle( - fontSize: 17.0, - ), - ), - SizedBox(height: 7.0), - Text( - 'Date Taken ' + - convertDateFormat(model - .vaccineList[index] - .invoiceDate), - style: TextStyle( - fontSize: 17.0), - ), - ], - ), - ), - flex: 5, - ), - ], - ), - ], - ), - ), - ], - ); - }), - ) - ], ), ), + SizedBox( + height: 40.0, + ) // SpaceBetweenTexts(space: 165.0), ], ), ), bottomSheet: Container( - color: Theme.of(context).scaffoldBackgroundColor, - padding: EdgeInsets.all(12), - height: MediaQuery.of(context).size.height * 0.25, - width: double.infinity, - child: Column( - children: [ - Divider( - height: 2, - thickness: 1, - ), - SizedBox( - height: 6, - ), - Container( - width: double.infinity, - // height: 80.0, - child: Button( - disabled: true, - label: TranslationBase.of(context).checkVaccineAvailability, - backgroundColor: Color(0xff9EA3A4), - onTap: () => Navigator.push( - context, FadePage(page: MyVaccinesItemPage())), - ), - ), - if (projectViewModel.havePrivilege(27)) - Container( - width: double.infinity, - // height: 80.0, - child: SecondaryButton( - label: TranslationBase.of(context).sendEmail, - color: Color(0xffF62426), - textColor: Colors.white, - disabled: model.vaccineList.length == 0, - loading: model.state == ViewState.BusyLocal, - onTap: () async { - model.sendEmail( - message: TranslationBase.of(context) - .emailSentSuccessfully); + color: Colors.white, + padding: EdgeInsets.only(top: 16, bottom: 16, right: 21, left: 21), + child: DefaultButton( + TranslationBase.of(context).sendEmail, + () { + showDialog( + context: context, + builder: (cxt) => ConfirmSendEmailDialog( + email: projectViewModel.user!.emailAddress!, + onTapSendEmail: () { + model.sendEmail(message: TranslationBase.of(context).emailSentSuccessfully); }, ), - ), - ], - ), - ), + ); + }, + )), ), ); } - - convertDateFormat(String Date) { - const start = "/Date("; - const end = "+0300)"; - - final startIndex = Date.indexOf(start); - final endIndex = Date.indexOf(end, startIndex + start.length); - - var date = new DateTime.fromMillisecondsSinceEpoch( - int.parse(Date.substring(startIndex + start.length, endIndex))); - String newDate = date.year.toString() + - "-" + - date.month.toString().padLeft(2, '0') + - "-" + - date.day.toString().padLeft(2, '0'); - - return newDate.toString(); - } } diff --git a/lib/pages/videocall-webrtc-rnd/js_wrapper/multistreammixer-wrapper.dart b/lib/pages/videocall-webrtc-rnd/js_wrapper/multistreammixer-wrapper.dart new file mode 100644 index 00000000..b21a345d --- /dev/null +++ b/lib/pages/videocall-webrtc-rnd/js_wrapper/multistreammixer-wrapper.dart @@ -0,0 +1,15 @@ +@JS() +library streammixer.js; +import 'package:js/js.dart'; + + +@JS('multiStreamsMixerFlutter') +external initMultiStreamsMixer(arrayOfMediaStreams); + +@JS("MultiStreamsMixer") +class MultiStreamsMixer { + external MultiStreamsMixer(arrayOfMediaStreams, elementClass); + + external getMixedStream(); + external start(); +} \ No newline at end of file diff --git a/lib/pages/videocall-webrtc-rnd/utils/blob-extension.dart b/lib/pages/videocall-webrtc-rnd/utils/blob-extension.dart new file mode 100644 index 00000000..7f20a6f5 --- /dev/null +++ b/lib/pages/videocall-webrtc-rnd/utils/blob-extension.dart @@ -0,0 +1,45 @@ +// import 'dart:async'; +// import 'dart:html' as html; +// +// import 'dart:typed_data'; +// +// extension xHtmlBlob on html.Blob{ +// +// /* File Reader --- */ +// Future _fileDataUrlReader()async{ +// html.FileReader reader = html.FileReader(); +// reader.readAsDataUrl(this); +// return reader; +// } +// +// Future _fileByteReader()async{ +// html.FileReader reader = html.FileReader(); +// reader.readAsArrayBuffer(this); +// return reader; +// } +// /* --- File Reader */ +// +// Future readDataUrl() async{ +// Completer completer = Completer(); +// _fileDataUrlReader().then((reader){ +// reader.onLoadEnd.listen((e) async { +// dynamic data = reader.result; +// completer.complete(data); +// }); +// }); +// final data = await completer.future; +// return data; +// } +// +// Future readBytes() async{ +// Completer completer = Completer(); +// _fileByteReader().then((reader){ +// reader.onLoadEnd.listen((e) async { +// dynamic data = reader.result; +// completer.complete(data); +// }); +// }); +// final data = await completer.future; +// return data; +// } +// } \ No newline at end of file diff --git a/lib/pages/videocall-webrtc-rnd/utils/device_info.dart b/lib/pages/videocall-webrtc-rnd/utils/device_info.dart new file mode 100644 index 00000000..668f2f12 --- /dev/null +++ b/lib/pages/videocall-webrtc-rnd/utils/device_info.dart @@ -0,0 +1,15 @@ +import 'dart:io'; + +class DeviceInfo { + static String get label { + return 'Flutter ' + + Platform.operatingSystem + + '(' + + Platform.localHostname + + ")"; + } + + static String get userAgent { + return 'flutter-webrtc/' + 'Web' + '-plugin 0.0.1'; + } +} diff --git a/lib/pages/videocall-webrtc-rnd/utils/device_info_web.dart b/lib/pages/videocall-webrtc-rnd/utils/device_info_web.dart new file mode 100644 index 00000000..34fad372 --- /dev/null +++ b/lib/pages/videocall-webrtc-rnd/utils/device_info_web.dart @@ -0,0 +1,11 @@ +// ignore: avoid_web_libraries_in_flutter + +class DeviceInfo { + static String get label { + return 'Flutter Web'; + } + + static String get userAgent { + return 'flutter-webrtc/web-plugin 0.0.1 (Mobile)'; + } +} diff --git a/lib/pages/videocall-webrtc-rnd/utils/turn.dart b/lib/pages/videocall-webrtc-rnd/utils/turn.dart new file mode 100644 index 00000000..f91fef80 --- /dev/null +++ b/lib/pages/videocall-webrtc-rnd/utils/turn.dart @@ -0,0 +1,19 @@ +import 'dart:convert'; +import 'dart:async'; +import 'dart:io'; + +Future getTurnCredential(String host) async { + HttpClient client = HttpClient(context: SecurityContext()); + client.badCertificateCallback = + (X509Certificate cert, String host, int port) { + print('getTurnCredential: Allow self-signed certificate => $host:$port. '); + return true; + }; + var url = '$host/api/turn?service=turn&username=flutter-webrtc'; + var request = await client.getUrl(Uri.parse(url)); + var response = await request.close(); + var responseBody = await response.transform(Utf8Decoder()).join(); + print('getTurnCredential:response => $responseBody.'); + Map data = JsonDecoder().convert(responseBody); + return data; + } diff --git a/lib/pages/videocall-webrtc-rnd/utils/turn_web.dart b/lib/pages/videocall-webrtc-rnd/utils/turn_web.dart new file mode 100644 index 00000000..bf2ea7ad --- /dev/null +++ b/lib/pages/videocall-webrtc-rnd/utils/turn_web.dart @@ -0,0 +1,13 @@ +import 'dart:convert'; +import 'package:http/http.dart' as http; + +Future getTurnCredential(String host, int port) async { + var url = 'https://$host:$port/api/turn?service=turn&username=flutter-webrtc'; + final res = await http.get(Uri.parse(url)); + if (res.statusCode == 200) { + var data = json.decode(res.body); + print('getTurnCredential:response => $data.'); + return data; + } + return {}; +} diff --git a/lib/pages/videocall-webrtc-rnd/utils/upload-recording.dart b/lib/pages/videocall-webrtc-rnd/utils/upload-recording.dart new file mode 100644 index 00000000..53eb2230 --- /dev/null +++ b/lib/pages/videocall-webrtc-rnd/utils/upload-recording.dart @@ -0,0 +1,97 @@ +// import 'dart:convert'; +// import 'dart:html' as html; +// +// import 'package:diplomaticquarterapp/pages/videocall-webrtc-rnd/utils/blob-extension.dart'; +// import 'package:flutter/cupertino.dart'; +// import 'package:http/http.dart' as http; +// +// // should run on port '65482' add to additional arguments --web-port=65482 +// class UploadRecording{ +// +// final url = "https://vcallapi.hmg.com/api/videocall/trackMeeting"; +// // final url = "https://10.20.200.186/api/videocall/trackMeeting"; +// upload(html.Blob blob, {@required Map params, @required Function completion, @required Function(double) onProgress}) async{ +// +// final bytes = await blob.readBytes(); +// final filename = "${DateTime.now().millisecondsSinceEpoch}.webm"; +// final file = http.MultipartFile.fromBytes('file', bytes ?? [], filename: filename); +// +// var request = http.MultipartRequest('POST', Uri.parse(url)); +// request.files.add(file); +// request.fields.addAll({'fileName':filename,...params}); +// +// print("Uploading video of '${blob.size}' bytes"); +// var response = await request.send().catchError((e){ +// print(e.toString()); +// completion(e.toString()); +// }); +// +// print(response.statusCode); +// if (response.statusCode == 200) { +// final bytes = await response.stream.toBytes(); +// final jsonString = utf8.decode(bytes); +// final json = jsonDecode(jsonString); +// if(json == null) +// completion('200: Invalid response format'); +// else +// completion(json); +// +// }else { +// print(response.reasonPhrase); +// completion(response.reasonPhrase); +// } +// } +// +// _upload(html.Blob blob, {@required Map params, @required Function completion, @required Function(double) onProgress}) async{ +// final blobBytes = await blob.readBytes(); +// +// Map body = {}; +// body.addAll(params); +// body['file'] = blobBytes ?? []; +// body['fileName'] = "${DateTime.now().millisecondsSinceEpoch}.webm"; +// +// final json = jsonEncode(body); +// +// var request = http.StreamedRequest('POST', Uri.parse(url)); +// +// var totalLength = json.length;// Total length (to calculate upload progress) +// var transferredLength = 0;// Length transferred (to calculate upload progress) +// var uploadProgress = 0.0; // Upload progress (from 0.0 to 1.0) +// +// Stream.value(json).transform(utf8.encoder).listen((chunk) { +// +// transferredLength += chunk.length; +// uploadProgress = transferredLength / totalLength; +// // print("Chunk: ${chunk.length}, transferred: $transferredLength, progress: $uploadProgress"); +// request.sink.add(chunk); +// onProgress(uploadProgress*100); +// +// }, onDone: () { +// print("Done. Total: $totalLength, transferred: $transferredLength, progress: $uploadProgress"); +// request.sink.close(); +// onProgress(uploadProgress*100); +// }); +// +// +// print("Uploading video of '${blob.size}' bytes"); +// var response = await request.send(); +// +// print(response.statusCode); +// if (response.statusCode == 200){ +// +// final bytes = await response.stream.toBytes(); +// final jsonString = utf8.decode(bytes); +// final json = jsonDecode(jsonString); +// if(json == null) +// completion('200: Invalid response format'); +// else +// completion(json); +// +// +// }else { +// print("${response.statusCode}: ${response.reasonPhrase}"); +// completion(response.reasonPhrase); +// } +// +// } +// } \ No newline at end of file diff --git a/lib/pages/videocall-webrtc-rnd/utils/websocket.dart b/lib/pages/videocall-webrtc-rnd/utils/websocket.dart new file mode 100644 index 00000000..acb4720d --- /dev/null +++ b/lib/pages/videocall-webrtc-rnd/utils/websocket.dart @@ -0,0 +1,75 @@ +import 'dart:io'; +import 'dart:math'; +import 'dart:convert'; +import 'dart:async'; + +class SimpleWebSocket { + String? _url; + late var _socket; + late Function() onOpen; + late Function(dynamic msg) onMessage; + late Function(int code, String reaso) onClose; + SimpleWebSocket(this._url); + + connect() async { + try { + //_socket = await WebSocket.connect(_url); + print('connecting to $_url'); + _socket = await _connectForSelfSignedCert(_url); + onOpen?.call(); + _socket.listen((data) { + onMessage?.call(data); + }, onDone: () { + onClose?.call(_socket.closeCode, _socket.closeReason); + }); + } catch (e) { + onClose?.call(500, e.toString()); + } + } + + send(data) { + if (_socket != null) { + _socket.add(data); + print('send: $data'); + } + } + + close() { + if (_socket != null) _socket.close(); + } + + Future _connectForSelfSignedCert(url) async { + try { + Random r = new Random(); + String key = base64.encode(List.generate(8, (_) => r.nextInt(255))); + HttpClient client = HttpClient(context: SecurityContext()); + client.badCertificateCallback = + (X509Certificate cert, String host, int port) { + print( + 'SimpleWebSocket: Allow self-signed certificate => $host:$port. '); + return true; + }; + + HttpClientRequest request = + await client.getUrl(Uri.parse(url)); // form the correct url here + request.headers.add('Connection', 'Upgrade'); + request.headers.add('Upgrade', 'websocket'); + request.headers.add( + 'Sec-WebSocket-Version', '13'); // insert the correct version here + request.headers.add('Sec-WebSocket-Key', key.toLowerCase()); + + HttpClientResponse response = await request.close(); + // ignore: close_sinks + Socket socket = await response.detachSocket(); + var webSocket = WebSocket.fromUpgradedSocket( + socket, + protocol: 'signaling', + serverSide: false, + ); + + return webSocket; + } catch (e) { + throw e; + } + } +} diff --git a/lib/pages/videocall-webrtc-rnd/utils/websocket_web.dart b/lib/pages/videocall-webrtc-rnd/utils/websocket_web.dart new file mode 100644 index 00000000..9b72f402 --- /dev/null +++ b/lib/pages/videocall-webrtc-rnd/utils/websocket_web.dart @@ -0,0 +1,48 @@ +// ignore: avoid_web_libraries_in_flutter +import 'dart:html'; + +class SimpleWebSocket { + late String _url; + late var _socket; + late Function() onOpen; + late Function(dynamic msg) onMessage; + late Function(int code, String reason) onClose; + + SimpleWebSocket(this._url) { + _url = _url.replaceAll('https:', 'wss:'); + } + + connect() async { + try { + _socket = WebSocket(_url); + _socket.onOpen.listen((e) { + onOpen?.call(); + }); + + _socket.onMessage.listen((e) { + onMessage?.call(e.data); + }); + + _socket.onClose.listen((e) { + onClose?.call(e.code, e.reason); + }); + } catch (e) { + onClose?.call(500, e.toString()); + } + } + + send(data) { + if (_socket != null && _socket.readyState == WebSocket.OPEN) { + _socket.send(data); + print('send: $data'); + } else { + print('WebSocket not connected, message $data not sent'); + } + } + + close() { + if (_socket != null) { + _socket.close(); + } + } +} diff --git a/lib/pages/videocall-webrtc-rnd/web_recorder.dart b/lib/pages/videocall-webrtc-rnd/web_recorder.dart new file mode 100644 index 00000000..99217d68 --- /dev/null +++ b/lib/pages/videocall-webrtc-rnd/web_recorder.dart @@ -0,0 +1,234 @@ +// +// import 'dart:async'; +// import 'dart:collection'; +// import 'dart:html' as html; +// import 'dart:io'; +// import 'dart:js' as js; +// import 'dart:typed_data'; +// import 'package:diplomaticquarterapp/pages/videocall-webrtc-rnd/js_wrapper/multistreammixer-wrapper.dart'; +// import 'package:diplomaticquarterapp/pages/videocall-webrtc-rnd/utils/blob-extension.dart'; +// import 'package:diplomaticquarterapp/pages/videocall-webrtc-rnd/utils/upload-recording.dart'; +// import 'package:flutter/cupertino.dart'; +// import 'package:flutter_webrtc/flutter_webrtc.dart'; +// +// final _recorder_options = { +// 'mimeType': 'video/webm;codecs=vp9,opus', +// 'bitsPerSecond': 128000, +// 'audioBitsPerSecond': 128000,// only for audio track +// 'videoBitsPerSecond': 128000// only for video track +// }; +// +// class WebRtcStreamRecorder{ +// html.MediaStream remoteStreamWeb; +// html.MediaStream localStreamWeb; +// +// html.MediaRecorder _local_recorder; +// html.MediaRecorder _mixed_recorder; +// html.MediaRecorder _remote_recorder; +// Duration chunkDuration; +// +// WebRtcStreamRecorder({@required MediaStream remoteStream, @required MediaStream localStream}){ +// remoteStreamWeb = (remoteStream as dynamic).jsStream; // MediaStreamWeb.jsStream +// localStreamWeb = (localStream as dynamic).jsStream; // MediaStreamWeb.jsStream +// } +// +// Function(html.Blob blob, bool isLast, html.MediaRecorder recorder) _blobChunkCallback; +// +// onBlobChunk(Duration chunkDuration,{@required Function(html.Blob blob, bool isLast, html.MediaRecorder recorder) onBlobChunk}){ +// _blobChunkCallback = onBlobChunk; +// this.chunkDuration = chunkDuration; +// } +// +// stop(){ +// _mixed_recorder?.stop(); +// _remote_recorder?.stop(); +// _local_recorder?.stop(); +// _sliceTimer?.cancel(); +// } +// +// WebRtcStreamRecorder start({bool withMixedStream = true}){ +// if(withMixedStream){ +// _recordMixedStream(); +// +// }else{ +// Future.wait([_startLocal(), _startRemote()]).then((value) async{ +// final localVideoData = await value[0].readBytes(); +// final remoteVideoData = await value[1].readBytes(); +// +// processAndSendClip(localVideoData, 'local-video'); +// processAndSendClip(remoteVideoData, 'remote-video'); +// print("\n\n\n"); +// print("------------------------------------------------------------------------------------------------------------------------"); +// print("Recordings Completed"); +// print("------------------------------------------------------------------------------------------------------------------------"); +// print(" Local: ${localVideoData == null ? 'not recorded' : 'recorded'}"); +// print("Remote: ${remoteVideoData == null ? 'not recorded' : 'recorded'}"); +// print("------------------------------------------------------------------------------------------------------------------------"); +// print("\n\n\n"); +// +// }); +// } +// return this; +// } +// +// _recordMixedStream(){ +// final mixer = initMultiStreamsMixer([remoteStreamWeb,localStreamWeb]); +// final jsMixedStream = mixer.getMixedStream(); +// _mixed_recorder = html.MediaRecorder(jsMixedStream, _recorder_options); +// _startRecording(_mixed_recorder).then((blob) async { +// final data = await blob?.readBytes(); +// // final url = await blob?.readDataUrl(); +// final params = { +// 'requesterId':'1', +// 'source':'ziktest4', +// 'target':'adeltest4', +// 'callStart':'2022-04-13 09:00', +// 'callEnd':'2022-04-13 10:00', +// 'archive':'1' +// }; +// +// print("Uploading called"); +// UploadRecording().upload(blob, params: params, completion: (response){ +// print("Response: $response"); +// }, onProgress: (progress){ +// print("Upload: ${progress.toInt()}/100"); +// }); +// +// // String file = await FileSaver.instance.saveFile("recorded", data!, "webm", mimeType: MimeType.WEBM).catchError((e){ +// // print(e); +// // }); +// // print(file); +// }); +// } +// +// Future _startRemote() async{ +// _remote_recorder = html.MediaRecorder(remoteStreamWeb, _recorder_options); +// return _startRecording(_remote_recorder); +// } +// +// Future _startLocal() async{ +// _local_recorder = html.MediaRecorder(localStreamWeb, _recorder_options); +// return _startRecording(_local_recorder); +// } +// +// processAndSendClip(Uint8List data, String filename) async{ +// if(data != null){ +// // String file = await FileSaver.instance.saveFile("$filename", data, "webm", mimeType: MimeType.OTHER).catchError((e){ +// // print(e); +// // }); +// // print(file); +// }else{ +// +// } +// } +// } +// +// Timer _sliceTimer; +// extension xWebRtcStreamRecorder on WebRtcStreamRecorder{ +// +// @override +// Future _startRecording(html.MediaRecorder recorder) async{ +// html.Blob _blob; +// bool isLast = false; +// if(recorder != null){ +// final completer = Completer(); +// recorder.addEventListener('dataavailable', (html.Event event) async{ +// _blob = js.JsObject.fromBrowserObject(event)['data']; +// isLast = recorder.state == 'inactive'; +// final data = await _blob?.readBytes(); +// print("dataavailable isLast:$isLast data:${data?.length}"); +// if(_blobChunkCallback != null) +// _blobChunkCallback(_blob, isLast, recorder); +// +// if(isLast) +// completer.complete(); +// }); +// recorder.start(); +// print("_startRecording Start"); +// _enableSliceChunks(recorder); +// +// await completer.future; +// } +// +// print("_startRecording Finish"); +// return _blob; +// } +// +// _enableSliceChunks(html.MediaRecorder recorder){ +// if(chunkDuration != null && recorder != null){ +// _sliceTimer = Timer.periodic(chunkDuration, (timer) { +// if(recorder.stream?.active == true){ +// recorder.requestData(); +// }else{ +// timer.cancel(); +// } +// }); +// } +// } +// } +// +// // class WebRecorder { +// // static bool isNotRecording = true; +// // static html.MediaRecorder? recorder; +// // +// // final Future Function() whenRecorderStart; // Function to call when recording starts +// // final Future Function() whenRecorderStop; // Function to call when recording finishs +// // final Future Function(dynamic) whenReceiveData; +// // +// // WebRecorder({ +// // required this.whenRecorderStart, +// // required this.whenRecorderStop, +// // required this.whenReceiveData +// // }); +// // +// // WebRecorder openRecorder({MediaStream? stream}){ +// // WebRecorder.isNotRecording = !WebRecorder.isNotRecording; +// // if(WebRecorder.isNotRecording) +// // stopRecoring().whenComplete(whenRecorderStop); +// // else +// // if(stream == null){ +// // html.window.navigator +// // .getUserMedia(audio: true) +// // .then((stream) { +// // recorder = html.MediaRecorder(stream); +// // recorder?.addEventListener('dataavailable', hundlerFunctionStream); +// // }) +// // .whenComplete((){ +// // startRecording().whenComplete(whenRecorderStart); +// // }) +// // .catchError((e)=> print); +// // }else{ +// // final htmlStream = html.MediaStream(stream.getTracks()); +// // recorder = html.MediaRecorder(htmlStream); +// // recorder?.addEventListener('dataavailable', hundlerFunctionStream); +// // } +// // +// // return this; +// // } +// // +// // Future startRecording(){ +// // WebRecorder.recorder?.start(); +// // return Future.value(true); +// // } +// // +// // Future stopRecoring() async{ +// // WebRecorder.recorder?.stop(); +// // return Future.value(true); +// // } +// // +// // hundlerFunctionStream(event) async{ +// // html.FileReader reader = html.FileReader(); +// // html.Blob blob = js.JsObject.fromBrowserObject(event)['data']; +// // reader.readAsArrayBuffer(blob); +// // reader.onLoadEnd.listen((e) async { +// // setData(reader.result); +// // }); +// // } +// // +// // setData(data) => whenReceiveData(data); +// // +// // dispose(){ +// // WebRecorder.recorder?.removeEventListener('dataavailable', hundlerFunctionStream); +// // WebRecorder.recorder = null; +// // } +// // } diff --git a/lib/pages/videocall-webrtc-rnd/webrtc/random_string.dart b/lib/pages/videocall-webrtc-rnd/webrtc/random_string.dart new file mode 100644 index 00000000..399fb972 --- /dev/null +++ b/lib/pages/videocall-webrtc-rnd/webrtc/random_string.dart @@ -0,0 +1,77 @@ +// Copyright (c) 2016, Damon Douglas. All rights reserved. Use of this source code +// is governed by a BSD-style license that can be found in the LICENSE file. + +/// Simple library for generating random ascii strings. +/// +/// More dartdocs go here. +/// +/// +/// A simple usage example: +/// +/// import 'package:random_string/random_string.dart' as random; +/// main() { +/// print(randomBetween(10,20)); // some integer between 10 and 20 +/// print(randomNumeric(4)); // sequence of 4 random numbers i.e. 3259 +/// print(randomString(10)); // random sequence of 10 characters i.e. e~f93(4l- +/// print(randomAlpha(5)); // random sequence of 5 alpha characters i.e. aRztC +/// print(randomAlphaNumeric(10)); // random sequence of 10 alpha numeric i.e. aRztC1y32B +/// } + +library random_string; + +import 'dart:math'; + +const ASCII_START = 33; +const ASCII_END = 126; +const NUMERIC_START = 48; +const NUMERIC_END = 57; +const LOWER_ALPHA_START = 97; +const LOWER_ALPHA_END = 122; +const UPPER_ALPHA_START = 65; +const UPPER_ALPHA_END = 90; + +/// Generates a random integer where [from] <= [to]. +int randomBetween(int from, int to) { + if (from > to) throw Exception('$from cannot be > $to'); + var rand = Random(); + return ((to - from) * rand.nextDouble()).toInt() + from; +} + +/// Generates a random string of [length] with characters +/// between ascii [from] to [to]. +/// Defaults to characters of ascii '!' to '~'. +String randomString(int length, {int from= ASCII_START, int to= ASCII_END}) { + return String.fromCharCodes( + List.generate(length, (index) => randomBetween(from, to))); +} + +/// Generates a random string of [length] with only numeric characters. +String randomNumeric(int length) => + randomString(length, from: NUMERIC_START, to: NUMERIC_END); +/* +/// Generates a random string of [length] with only alpha characters. +String randomAlpha(int length) { + var lowerAlphaLength = randomBetween(0, length); + var upperAlphaLength = length - lowerAlphaLength; + var lowerAlpha = randomString(lowerAlphaLength, + from: LOWER_ALPHA_START, to: LOWER_ALPHA_END); + var upperAlpha = randomString(upperAlphaLength, + from: UPPER_ALPHA_START, to: UPPER_ALPHA_END); + return randomMerge(lowerAlpha, upperAlpha); +} + +/// Generates a random string of [length] with alpha-numeric characters. +String randomAlphaNumeric(int length) { + var alphaLength = randomBetween(0, length); + var numericLength = length - alphaLength; + var alpha = randomAlpha(alphaLength); + var numeric = randomNumeric(numericLength); + return randomMerge(alpha, numeric); +} + +/// Merge [a] with [b] and scramble characters. +String randomMerge(String a, String b) { + var mergedCodeUnits = List.from("$a$b".codeUnits); + mergedCodeUnits.shuffle(); + return String.fromCharCodes(mergedCodeUnits); +}*/ diff --git a/lib/pages/videocall-webrtc-rnd/webrtc/settings.dart b/lib/pages/videocall-webrtc-rnd/webrtc/settings.dart new file mode 100644 index 00000000..fe9c9535 --- /dev/null +++ b/lib/pages/videocall-webrtc-rnd/webrtc/settings.dart @@ -0,0 +1,35 @@ +import 'package:flutter/material.dart'; +import 'dart:core'; + +class CallSettings extends StatefulWidget { + static String tag = 'call_settings'; + + @override + _CallSettingsState createState() => _CallSettingsState(); +} + +class _CallSettingsState extends State { + @override + initState() { + super.initState(); + } + + @override + deactivate() { + super.deactivate(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text('Settings'), + ), + body: OrientationBuilder( + builder: (context, orientation) { + return Center(child: Text("settings")); + }, + ), + ); + } +} diff --git a/lib/pages/videocall-webrtc-rnd/webrtc/signaling.dart b/lib/pages/videocall-webrtc-rnd/webrtc/signaling.dart new file mode 100644 index 00000000..853183a9 --- /dev/null +++ b/lib/pages/videocall-webrtc-rnd/webrtc/signaling.dart @@ -0,0 +1,509 @@ +// import 'dart:convert'; +// import 'dart:async'; +// import 'package:flutter/cupertino.dart'; +// import 'package:flutter_webrtc/flutter_webrtc.dart'; +// +// import '../utils/websocket.dart' if (dart.library.js) '../utils/websocket_web.dart'; +// import '../utils/turn.dart' if (dart.library.js) '../utils/turn_web.dart'; +// +// +// enum SignalingState { Open, Closed, Error } +// enum CallState { Calling, Ringing, Invite, Connected, Bye } +// +// +// const JsonEncoder _encoder = JsonEncoder(); +// const JsonDecoder _decoder = JsonDecoder(); +// +// class SessionOneToOne { +// late String id; +// late SocketUser local_user; +// late SocketUser remote_user; +// SessionOneToOne({required this.id, required this.local_user, required this.remote_user}); +// +// +// late RTCPeerConnection pc; +// late RTCDataChannel dc; +// List remoteCandidates = []; +// } +// +// class SocketUser{ +// String? id; +// String? name; +// String? userAgent; +// Map? moreInfo; +// +// SocketUser({required this.id, required this.name, required this.userAgent, required this.moreInfo}); +// +// SocketUser.from(dynamic json){ +// id = json['id']; +// name = json['name']; +// userAgent = json['user_agent']; +// moreInfo = json['more_info']; +// } +// +// Map toJson() => { +// "id": id, +// "name": name, +// "user_agent": userAgent, +// "more_info": moreInfo +// }; +// } +// +// class Signaling { +// var _host; +// var _turnCredential; +// +// SimpleWebSocket? _socket; +// SessionOneToOne? session; +// +// Signaling(this._host, {required this.session}); +// +// late MediaStream? localStream; +// late final List remoteStreams = []; +// +// late Function(SignalingState state) onSignalingStateChange; +// late Function(SessionOneToOne session, CallState state) onCallStateChange; +// late Function(MediaStream stream) onLocalStream; +// late Function(SessionOneToOne session, MediaStream stream) onAddRemoteStream; +// late Function(SessionOneToOne session, MediaStream stream) onRemoveRemoteStream; +// late Function(dynamic event) onPeersUpdate; +// late Function(dynamic event) onConnected; +// late Function(dynamic event) onRemoteConnected; +// late Function(SessionOneToOne session, RTCDataChannel dc, RTCDataChannelMessage data) onDataChannelMessage; +// late Function(SessionOneToOne session, RTCDataChannel dc) onDataChannel; +// +// String? get sdpSemantics => WebRTC.platformIsWindows ? 'plan-b' : 'unified-plan'; +// +// Map _iceServers = { +// 'iceServers': [ +// {'url': 'stun:stun.l.google.com:19302'}, +// /* +// * turn server configuration example. +// { +// 'url': 'turn:123.45.67.89:3478', +// 'username': 'change_to_real_user', +// 'credential': 'change_to_real_secret' +// }, +// */ +// ] +// }; +// +// final Map _config = { +// 'mandatory': {}, +// 'optional': [ +// {'DtlsSrtpKeyAgreement': true}, +// ] +// }; +// +// final Map _dcConstraints = { +// 'mandatory': { +// 'OfferToReceiveAudio': false, +// 'OfferToReceiveVideo': false, +// }, +// 'optional': [], +// }; +// +// +// close() async { +// await finishSessions(); +// _socket?.close(); +// } +// +// void switchCamera() { +// if (localStream != null) { +// Helper.switchCamera(localStream! .getVideoTracks()[0]); +// } +// } +// +// void muteMic() { +// if (localStream != null) { +// bool enabled = localStream!.getAudioTracks()[0].enabled; +// localStream!.getAudioTracks()[0].enabled = !enabled; +// } +// } +// +// +// callAccepted(SessionOneToOne session){ +// _send('call_accepted', { +// 'to': session.remote_user?.id, +// 'from': session.local_user.id, +// 'session_id': session.id, +// }); +// } +// +// void offer(String media, bool useScreen) async { +// if(session == null) +// return; +// +// if (media == 'data') { +// _createDataChannel(session!); +// } +// _createOffer(session!, media); +// onCallStateChange?.call(session!, CallState.Calling); +// } +// +// void bye(SessionOneToOne session) { +// _send('bye', { +// 'session_id': session.id, +// 'from': session.local_user.id, +// }); +// _closeSession(session); +// } +// +// void onMessage(message) async { +// Map mapData = message; +// var data = mapData['data']; +// +// switch (mapData['type']) { +// case 'call_accepted': +// { +// onRemoteConnected?.call(data); +// } +// break; +// +// case 'connected': +// { +// if (onConnected != null) { +// onConnected?.call(data); +// } +// } +// break; +// +// case 'offer': +// { +// +// var peerId = data['from']; +// var description = data['description']; +// var media = data['media']; +// +// await _initPeerConnection(session!, media: media, screenSharing: false); +// await session!.pc?.setRemoteDescription(RTCSessionDescription(description['sdp'], description['type'])); +// await _createAnswer(session!, media); +// +// if (session!.remoteCandidates!.isNotEmpty) { +// session!.remoteCandidates!.forEach((candidate) async { +// await session!.pc?.addCandidate(candidate); +// }); +// session!.remoteCandidates.clear(); +// } +// onCallStateChange?.call(session!, CallState.Calling); +// } +// break; +// case 'answer': +// { +// +// var description = data['description']; +// var sessionId = data['session_id']; +// session!.pc?.setRemoteDescription( +// RTCSessionDescription(description['sdp'], description['type'])); +// } +// break; +// case 'candidate': +// { +// +// var peerId = data['from']; +// var candidateMap = data['candidate']; +// var sessionId = data['session_id']; +// RTCIceCandidate candidate = RTCIceCandidate(candidateMap['candidate'], +// candidateMap['sdpMid'], candidateMap['sdpMLineIndex']); +// +// if (session != null) { +// if (session!.pc != null) { +// await session!.pc?.addCandidate(candidate); +// } else { +// session!.remoteCandidates.add(candidate); +// } +// } else { +// // _sessions[sessionId] = SessionOneToOne(pid: peerId, sid: sessionId) +// // ..remoteCandidates.add(candidate); +// } +// } +// break; +// case 'leave': +// { +// var peerId = data as String; +// _closeSessionById(peerId); +// } +// break; +// case 'bye': +// { +// +// var sessionId = data['session_id']; +// print('bye: ' + sessionId); +// if (session != null) { +// onCallStateChange?.call(session!, CallState.Bye); +// _closeSession(session!); +// } +// } +// break; +// case 'keepalive': +// { +// print('keepalive response!'); +// } +// break; +// default: +// break; +// } +// } +// +// Future connect() async { +// _socket = SimpleWebSocket('$_host/ws'); +// +// if (_turnCredential == null) { +// try { +// _turnCredential = await getTurnCredential(_host); +// /* +// { +// "username": "1584195784:mbzrxpgjys", +// "password": "isyl6FF6nqMTB9/ig5MrMRUXqZg", +// "ttl": 86400, +// "uris": ["turn:127.0.0.1:19302?transport=udp"] +// } +// */ +// _iceServers = { +// 'iceServers': [ +// { +// 'urls': _turnCredential['uris'][0], +// 'username': _turnCredential['username'], +// 'credential': _turnCredential['password'] +// }, +// ] +// }; +// } catch (e) {} +// } +// +// _socket?.onOpen = () { +// print('onOpen'); +// onSignalingStateChange?.call(SignalingState.Open); +// _send('connect', session!.local_user!.toJson()); +// }; +// +// _socket?.onMessage = (message) { +// print('Received data: ' + message); +// onMessage(_decoder.convert(message)); +// }; +// +// _socket?.onClose = (int code, String reason) { +// print('Closed by server [$code => $reason]!'); +// onSignalingStateChange?.call(SignalingState.Closed); +// }; +// +// await _socket?.connect(); +// } +// +// Future createStream(String media, bool userScreen) async { +// final Map mediaConstraints = { +// 'audio': userScreen ? false : true, +// 'video': userScreen +// ? true +// : { +// 'mandatory': { +// 'minWidth': '640', // Provide your own width, height and frame rate here +// 'minHeight': '480', +// 'minFrameRate': '30', +// }, +// 'facingMode': 'user', +// 'optional': [], +// } +// }; +// +// MediaStream stream = userScreen +// ? await navigator.mediaDevices.getDisplayMedia(mediaConstraints) +// : await navigator.mediaDevices.getUserMedia(mediaConstraints); +// onLocalStream?.call(stream); +// return stream; +// } +// +// Future _initPeerConnection(SessionOneToOne session, {required String media, required bool screenSharing}) async { +// +// if (media != 'data') +// localStream = await createStream(media, screenSharing); +// print(_iceServers); +// RTCPeerConnection pc = await createPeerConnection({ +// ..._iceServers, +// ...{'sdpSemantics': sdpSemantics} +// }, _config); +// if (media != 'data') { +// switch (sdpSemantics) { +// case 'plan-b': +// pc.onAddStream = (MediaStream stream) { +// onAddRemoteStream?.call(session, stream); +// remoteStreams.add(stream); +// }; +// await pc.addStream(localStream!); +// break; +// case 'unified-plan': +// // Unified-Plan +// pc.onTrack = (event) { +// if (event.track.kind == 'video') { +// onAddRemoteStream?.call(session, event.streams[0]); +// } +// }; +// localStream! .getTracks().forEach((track) { +// pc.addTrack(track, localStream!); +// }); +// break; +// } +// +// // Unified-Plan: Simuclast +// /* +// await pc.addTransceiver( +// track: _localStream.getAudioTracks()[0], +// init: RTCRtpTransceiverInit( +// direction: TransceiverDirection.SendOnly, streams: [_localStream]), +// ); +// +// await pc.addTransceiver( +// track: _localStream.getVideoTracks()[0], +// init: RTCRtpTransceiverInit( +// direction: TransceiverDirection.SendOnly, +// streams: [ +// _localStream +// ], +// sendEncodings: [ +// RTCRtpEncoding(rid: 'f', active: true), +// RTCRtpEncoding( +// rid: 'h', +// active: true, +// scaleResolutionDownBy: 2.0, +// maxBitrate: 150000, +// ), +// RTCRtpEncoding( +// rid: 'q', +// active: true, +// scaleResolutionDownBy: 4.0, +// maxBitrate: 100000, +// ), +// ]), +// );*/ +// /* +// var sender = pc.getSenders().find(s => s.track.kind == "video"); +// var parameters = sender.getParameters(); +// if(!parameters) +// parameters = {}; +// parameters.encodings = [ +// { rid: "h", active: true, maxBitrate: 900000 }, +// { rid: "m", active: true, maxBitrate: 300000, scaleResolutionDownBy: 2 }, +// { rid: "l", active: true, maxBitrate: 100000, scaleResolutionDownBy: 4 } +// ]; +// sender.setParameters(parameters); +// */ +// } +// pc.onIceCandidate = (candidate) async { +// if (candidate == null) { +// print('onIceCandidate: complete!'); +// return; +// } +// // This delay is needed to allow enough time to try an ICE candidate +// // before skipping to the next one. 1 second is just an heuristic value +// // and should be thoroughly tested in your own environment. +// await Future.delayed( +// const Duration(seconds: 1), +// () => _send('candidate', { +// 'to': session.remote_user?.id, +// 'from': session.local_user.id, +// 'candidate': { +// 'sdpMLineIndex': candidate.sdpMLineIndex, // sdpMlineIndex or sdpMLineIndex +// 'sdpMid': candidate.sdpMid, +// 'candidate': candidate.candidate, +// }, +// 'session_id': session.id, +// })); +// }; +// +// pc.onIceConnectionState = (state) {}; +// +// pc.onRemoveStream = (stream) { +// onRemoveRemoteStream?.call(session, stream); +// remoteStreams.removeWhere((it) { +// return (it.id == stream.id); +// }); +// }; +// +// pc.onDataChannel = (channel) { +// _addDataChannel(session, channel); +// }; +// +// session.pc = pc; +// return session; +// } +// +// void _addDataChannel(SessionOneToOne session, RTCDataChannel channel) { +// channel.onDataChannelState = (e) {}; +// channel.onMessage = (RTCDataChannelMessage data) { +// onDataChannelMessage?.call(session, channel, data); +// }; +// session.dc = channel; +// onDataChannel?.call(session, channel); +// } +// +// Future _createDataChannel(SessionOneToOne session, {label= 'fileTransfer'}) async { +// RTCDataChannelInit dataChannelDict = RTCDataChannelInit() +// ..maxRetransmits = 30; +// RTCDataChannel channel = +// await session.pc .createDataChannel(label, dataChannelDict); +// _addDataChannel(session, channel); +// } +// +// Future _createOffer(SessionOneToOne session, String media) async { +// try { +// RTCSessionDescription s = +// await session.pc .createOffer(media == 'data' ? _dcConstraints : {}); +// await session.pc .setLocalDescription(s); +// _send('offer', { +// 'to': session.remote_user?.id, +// 'from': session.local_user.id, +// 'description': {'sdp': s.sdp, 'type': s.type}, +// 'session_id': session.id, +// 'media': media, +// }); +// } catch (e) { +// print(e.toString()); +// } +// } +// +// Future _createAnswer(SessionOneToOne session, String media) async { +// try { +// RTCSessionDescription s = +// await session.pc .createAnswer(media == 'data' ? _dcConstraints : {}); +// await session.pc .setLocalDescription(s); +// _send('answer', { +// 'to': session.remote_user?.id, +// 'from': session.local_user.id, +// 'description': {'sdp': s.sdp, 'type': s.type}, +// 'session_id': session.id, +// }); +// } catch (e) { +// print(e.toString()); +// } +// } +// +// _send(event, data) { +// var request = Map(); +// request["type"] = event; +// request["data"] = data; +// _socket?.send(_encoder.convert(request)); +// } +// +// Future finishSessions() async { +// _closeSessionById(session!.id); +// } +// +// void _closeSessionById(String sessionId) { +// if (session != null && session!.id == sessionId) { +// _closeSession(session!); +// onCallStateChange?.call(session!, CallState.Bye); +// } +// } +// +// Future _closeSession(SessionOneToOne session) async { +// localStream?.getTracks()?.forEach((element) async { +// await element.stop(); +// }); +// await localStream?.dispose(); +// localStream = null; +// +// await session.pc?.close(); +// await session.dc?.close(); +// } +// } diff --git a/lib/pages/videocall-webrtc-rnd/webrtc/start_video_call.dart b/lib/pages/videocall-webrtc-rnd/webrtc/start_video_call.dart new file mode 100644 index 00000000..d17bffe3 --- /dev/null +++ b/lib/pages/videocall-webrtc-rnd/webrtc/start_video_call.dart @@ -0,0 +1,241 @@ +// import 'dart:async'; +// +// import 'package:diplomaticquarterapp/pages/conference/conference_button_bar.dart'; +// import 'package:diplomaticquarterapp/pages/conference/web_rtc/widgets/cam_view_widget.dart'; +// import 'package:diplomaticquarterapp/pages/videocall-webrtc-rnd/utils/device_info.dart'; +// import 'package:firebase_messaging/firebase_messaging.dart'; +// import 'package:flutter/material.dart'; +// import 'package:flutter/services.dart'; +// import 'dart:core'; +// import 'signaling.dart'; +// import 'package:flutter_webrtc/flutter_webrtc.dart'; +// +// class StartVideoCall extends StatefulWidget { +// static String tag = 'webrtc'; +// final String host; +// +// String caller; +// String receiver; +// bool iAmCaller; +// StartVideoCall({required this.caller, required this.receiver, this.iAmCaller = false, required this.host}); +// +// @override +// StartVideoCallState createState() => StartVideoCallState(receiverId: receiver, callerId: caller, iAmCaller: iAmCaller); +// } +// +// class StartVideoCallState extends State { +// late Signaling _signaling; +// late SessionOneToOne? _session; +// +// StartVideoCallState({required String callerId, required String receiverId, required bool iAmCaller}){ +// +// final self_role = iAmCaller ? "Caller" : "Receiver"; +// final self_id = iAmCaller ? callerId : receiverId; +// final self_user = SocketUser(id: self_id, name: "$self_role-$self_id", userAgent: DeviceInfo.userAgent, moreInfo: {}); +// +// final remote_role = !iAmCaller ? "Caller" : "Receiver"; +// final remote_id = !iAmCaller ? callerId : receiverId; +// final remote_user = SocketUser(id: remote_id, name: "$remote_role-$remote_id", userAgent: DeviceInfo.userAgent, moreInfo: {}); +// +// final session_id = "$callerId-$receiverId"; +// _session = SessionOneToOne(id: session_id, local_user: self_user, remote_user: remote_user); +// } +// +// bool showNoise = true; +// final StreamController _audioButton = StreamController.broadcast(); +// final StreamController _videoButton = StreamController.broadcast(); +// final StreamController _onButtonBarVisibleStreamController = StreamController.broadcast(); +// final StreamController _onButtonBarHeightStreamController = StreamController.broadcast(); +// +// final RTCVideoRenderer _localRenderer = RTCVideoRenderer(); +// final RTCVideoRenderer _remoteRenderer = RTCVideoRenderer(); +// +// MediaStream get localMediaStream => _signaling.localStream!; +// MediaStream get remoteMediaStream => _signaling.remoteStreams.first; +// +// @override +// initState() { +// super.initState(); +// initRenderers(); +// _connect(); +// } +// +// initRenderers() async { +// await _localRenderer.initialize(); +// await _remoteRenderer.initialize(); +// } +// +// @override +// deactivate() { +// super.deactivate(); +// _signaling?.close(); +// _localRenderer.dispose(); +// _remoteRenderer.dispose(); +// } +// +// @override +// Widget build(BuildContext context) { +// return Scaffold( +// // appBar: AppBar( +// // title: Text('P2P Call Sample' + (_session?.local_user != null ? ' [Your ID (${_session?.local_user?.id})] ' : '')), +// // actions: [ +// // IconButton( +// // icon: const Icon(Icons.settings), +// // onPressed: (){ +// // setState(() { +// // }); +// // }, +// // tooltip: 'setup', +// // ), +// // ], +// // ), +// body: videoCanvasWidgets(), +// ); +// } +// +// LayoutBuilder videoCanvasWidgets() { +// return LayoutBuilder( +// builder: (BuildContext context, BoxConstraints constraints) { +// return Stack( +// children: [ +// CamViewWidget( +// localRenderer: _localRenderer, +// remoteRenderer: _remoteRenderer, +// constraints: constraints, +// onButtonBarVisibleStreamController: _onButtonBarVisibleStreamController, +// onButtonBarHeightStreamController: _onButtonBarHeightStreamController, +// ), +// ConferenceButtonBar( +// audioEnabled: _audioButton.stream, +// videoEnabled: _videoButton.stream, +// onAudioEnabled: _onAudioEnable, +// onVideoEnabled: _onVideoEnabled, +// onSwitchCamera: _onSwitchCamera, +// onHangup: _onHangup, +// onPersonAdd: () {}, +// onPersonRemove: () {}, +// onHeight: _onHeightBar, +// onShow: _onShowBar, +// onHide: _onHideBar, +// ), +// ], +// ); +// }, +// ); +// } +// +// +// void _connect() async { +// if(_session == null) +// return; +// +// _signaling ??= Signaling(widget.host, session: _session!)..connect(); +// +// _signaling?.onSignalingStateChange = (SignalingState state) { +// switch (state) { +// case SignalingState.Closed: +// case SignalingState.Error: +// case SignalingState.Open: +// break; +// } +// }; +// +// _signaling?.onCallStateChange = (SessionOneToOne session, CallState state) { +// switch (state) { +// case CallState.Calling: +// setState(() {}); +// break; +// case CallState.Bye: +// setState(() { +// _localRenderer.srcObject = null; +// _remoteRenderer.srcObject = null; +// _session = null; +// }); +// break; +// case CallState.Invite: +// case CallState.Connected: +// case CallState.Ringing: +// } +// }; +// +// _signaling?.onConnected = ((event) { +// _signaling?.callAccepted(_session!); +// }); +// +// _signaling?.onRemoteConnected = ((event) { +// +// }); +// +// _signaling?.onLocalStream = ((stream) { +// _localRenderer.srcObject = stream; +// setState(() { +// }); +// }); +// +// _signaling?.onAddRemoteStream = ((_, stream) { +// _remoteRenderer.srcObject = stream; +// setState(() {}); +// }); +// +// _signaling?.onRemoveRemoteStream = ((_, stream) { +// setState(() { +// _remoteRenderer.srcObject = null; +// }); +// }); +// } +// +// _hangUp() async{ +// if (_session != null) { +// _signaling?.bye(_session!); +// } +// } +// +// _switchCamera() { +// _signaling?.switchCamera(); +// } +// +// _muteMic() { +// _signaling?.muteMic(); +// } +// +// Function? _onAudioEnable() { +// final audioTrack = localMediaStream.getAudioTracks()[0]; +// final mute = audioTrack.muted; +// Helper.setMicrophoneMute(!mute!, audioTrack); +// _audioButton.add(mute); +// } +// +// Function? _onVideoEnabled() { +// final videoTrack = localMediaStream.getVideoTracks()[0]; +// bool videoEnabled = videoTrack.enabled; +// localMediaStream.getVideoTracks()[0].enabled = !videoEnabled; +// _videoButton.add(!videoEnabled); +// } +// +// Function? _onSwitchCamera() { +// Helper.switchCamera(localMediaStream.getVideoTracks()[0]); +// } +// +// void _onShowBar() { +// setState(() { +// }); +// _onButtonBarVisibleStreamController.add(true); +// } +// +// void _onHeightBar(double height) { +// _onButtonBarHeightStreamController.add(height); +// } +// +// void _onHideBar() { +// setState(() { +// SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: [SystemUiOverlay.bottom]); +// }); +// _onButtonBarVisibleStreamController.add(false); +// } +// +// Future _onHangup() async { +// _signaling?.finishSessions(); +// print('onHangup'); +// Navigator.of(context).pop(); +// } +// } \ No newline at end of file diff --git a/lib/pages/webRTC/OpenTok/OpenTok.dart b/lib/pages/webRTC/OpenTok/OpenTok.dart new file mode 100644 index 00000000..2e21e8cf --- /dev/null +++ b/lib/pages/webRTC/OpenTok/OpenTok.dart @@ -0,0 +1,249 @@ +import 'dart:async'; + +import 'package:diplomaticquarterapp/pages/conference/conference_button_bar.dart'; +import 'package:diplomaticquarterapp/pages/conference/draggable_publisher.dart'; +import 'package:diplomaticquarterapp/services/livecare_services/livecare_provider.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; + + final StreamController _audioButton = StreamController.broadcast(); + final StreamController _videoButton = StreamController.broadcast(); + final StreamController _onButtonBarVisibleStreamController = StreamController.broadcast(); + final StreamController _onButtonBarHeightStreamController = StreamController.broadcast(); + + var audioMute = false; + var videoMute = false; + + 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: Stack( + fit: StackFit.expand, + 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(), + ConferenceButtonBar( + audioEnabled: _audioButton.stream, + videoEnabled: _videoButton.stream, + onAudioEnabled: _onAudioEnable, + onVideoEnabled: _onVideoEnabled, + onSwitchCamera: _onSwitchCamera, + onHangup: _onHangup, + onPersonAdd: () {}, + onPersonRemove: () {}, + onHeight: _onHeightBar, + onShow: _onShowBar, + onHide: _onHideBar, + ), + ], + ), + ); + } + + bool remoteVideoOnFull = true; + + List platformVideoViews() { + return [ + SizedBox(width: MediaQuery.of(context).size.width, height: MediaQuery.of(context).size.height, child: remoteVideoOnFull ? returnFlutterNewRemoteWidget() : returnFlutterNewLocalWidget()), + DraggablePublisher( + onButtonBarHeight:Stream.value(50.0), + onButtonBarVisible: Stream.value(true), + availableScreenSize: MediaQuery.of(context).size, + child: InkWell( + child: (remoteVideoOnFull ? returnFlutterNewLocalWidget() : returnFlutterNewRemoteWidget()), + 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 returnFlutterNewRemoteWidget() { + final Map args = {"someInit": "initData"}; + const StandardMessageCodec _decoder = StandardMessageCodec(); + if (defaultTargetPlatform == TargetPlatform.android) { + return AndroidView( + viewType: 'remote-video-container', + creationParams: args, + creationParamsCodec: _decoder); + } + return UiKitView( + viewType: 'remote-video-container', + creationParams: args, + creationParamsCodec: _decoder); + } + + Widget returnFlutterNewLocalWidget() { + final Map args = {"someInit": "initData"}; + const StandardMessageCodec _decoder = StandardMessageCodec(); + if (defaultTargetPlatform == TargetPlatform.android) { + return AndroidView( + viewType: 'local-video-container', + creationParams: args, + creationParamsCodec: _decoder); + } + return UiKitView( + viewType: 'local-video-container', + creationParams: args, + creationParamsCodec: _decoder); + } + + // 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(); + // }, + // ); + // } + + _onAudioEnable() async { + await openTokPlatform!.toggleAudio(); + _audioButton.add(!audioMute); + } + + _onVideoEnabled() async { + await openTokPlatform!.toggleVideo(); + _videoButton.add(!videoMute); + } + + _onSwitchCamera() async { + await openTokPlatform!.swapCamera(); + } + + Future _onHangup() async { + print('onHangup'); + await openTokPlatform!.hangupCall(); + endCallAPI(); + Navigator.of(context).pop(); + } + + void endCallAPI() { + LiveCareService service = new LiveCareService(); + service.endCallAPI(widget.sessionId, 2, context).then((res) {}).catchError((err) { + print(err); + }); + } + + void _onShowBar() { + setState(() {}); + _onButtonBarVisibleStreamController.add(true); + } + + void _onHeightBar(double height) { + _onButtonBarHeightStreamController.add(height); + } + + void _onHideBar() { + // setState(() { + // SystemChrome!.setEnabledSystemUIOverlays([SystemUiOverlay.bottom]); + // }); + _onButtonBarVisibleStreamController.add(false); + } +} diff --git a/lib/pages/webRTC/OpenTok/OpenTokPlatformBridge.dart b/lib/pages/webRTC/OpenTok/OpenTokPlatformBridge.dart new file mode 100644 index 00000000..8f7a2457 --- /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 { + try { + await _platformMethodChannel.invokeMethod('toggleAudio'); + } on PlatformException catch (e) {} + } + + Future toggleVideo() async { + try { + await _platformMethodChannel.invokeMethod('toggleVideo'); + } on PlatformException catch (e) {} + } + + Future hangupCall() async { + try { + await _platformMethodChannel.invokeMethod('hangupCall'); + } on PlatformException catch (e) {} + } +} diff --git a/lib/pages/webRTC/call_page.dart b/lib/pages/webRTC/call_page.dart new file mode 100644 index 00000000..b9f444d1 --- /dev/null +++ b/lib/pages/webRTC/call_page.dart @@ -0,0 +1,164 @@ +// import 'dart:io'; +// +// import 'package:diplomaticquarterapp/models/LiveCare/IncomingCallData.dart'; +// import 'package:diplomaticquarterapp/pages/livecare/incoming_call.dart'; +// import 'package:diplomaticquarterapp/pages/webRTC/signaling.dart'; +// import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +// import 'package:firebase_messaging/firebase_messaging.dart'; +// import 'package:flutter/material.dart'; +// import 'package:flutter_webrtc/flutter_webrtc.dart'; +// +// class CallPage extends StatefulWidget { +// @override +// _CallPageState createState() => _CallPageState(); +// } +// +// class _CallPageState extends State { +// Signaling signaling = Signaling(); +// RTCVideoRenderer _localRenderer = RTCVideoRenderer(); +// RTCVideoRenderer _remoteRenderer = RTCVideoRenderer(); +// String roomId; +// TextEditingController textEditingController = TextEditingController(text: ''); +// +// @override +// void initState() { +// _localRenderer.initialize(); +// _remoteRenderer.initialize(); +// +// // signaling.onRemoteStream = ((stream) { +// // _remoteRenderer.srcObject = stream; +// // setState(() {}); +// // }); +// +// fcmConfigure(); +// +// super.initState(); +// } +// +// @override +// void dispose() { +// _localRenderer.dispose(); +// _remoteRenderer.dispose(); +// super.dispose(); +// } +// +// @override +// Widget build(BuildContext context) { +// FirebaseMessaging.instance.getToken().then((value) { +// print('FCM_TOKEN: $value'); +// }); +// +// return AppScaffold( +// isShowAppBar: true, +// showNewAppBar: true, +// showNewAppBarTitle: true, +// isShowDecPage: false, +// appBarTitle: "WebRTC Calling", +// body: Column( +// children: [ +// SizedBox(height: 8), +// Wrap( +// children: [ +// SizedBox( +// width: 8, +// ), +// ElevatedButton( +// onPressed: () { +// dummyCall(); +// }, +// child: Text("Call"), +// ), +// SizedBox( +// width: 8, +// ), +// ElevatedButton( +// onPressed: () { +// signaling.hangUp(_localRenderer); +// }, +// child: Text("Hangup"), +// ) +// ], +// ), +// SizedBox(height: 8), +// Expanded( +// child: Padding( +// padding: const EdgeInsets.all(0.0), +// child: Stack( +// children: [ +// Positioned(top: 0.0, right: 0.0, left: 0.0, bottom: 0.0, child: RTCVideoView(_remoteRenderer)), +// Positioned( +// top: 20.0, +// right: 100.0, +// left: 20.0, +// bottom: 300.0, +// child: RTCVideoView(_localRenderer, mirror: true), +// ), +// ], +// ), +// ), +// ), +// Padding( +// padding: const EdgeInsets.all(8.0), +// child: Row( +// mainAxisAlignment: MainAxisAlignment.center, +// children: [ +// Text("Join the following Room: "), +// Flexible( +// child: TextFormField( +// controller: textEditingController, +// ), +// ) +// ], +// ), +// ), +// SizedBox(height: 8) +// ], +// ), +// ); +// } +// +// dummyCall() async { +// final json = { +// "callerID": "9920", +// "receiverID": "2001273", +// "msgID": "123", +// "notfID": "123", +// "notification_foreground": "true", +// "count": "1", +// "message": "Doctor is calling ", +// "AppointmentNo": "123", +// "title": "Rayyan Hospital", +// "ProjectID": "123", +// "NotificationType": "10", +// "background": "1", +// "doctorname": "Dr Sulaiman Al Habib", +// "clinicname": "ENT Clinic", +// "speciality": "Speciality", +// "appointmentdate": "Sun, 15th Dec, 2019", +// "appointmenttime": "09:00", +// "type": "video", +// "session_id": +// "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImN0eSI6InR3aWxpby1mcGE7dj0xIn0.eyJqdGkiOiJTS2I2NjYyOWMzN2ZhOTM3YjFjNDI2Zjg1MTgyNWFmN2M0LTE1OTg3NzQ1MDYiLCJpc3MiOiJTS2I2NjYyOWMzN2ZhOTM3YjFjNDI2Zjg1MTgyNWFmN2M0Iiwic3ViIjoiQUNhYWQ1YTNmOGM2NGZhNjczNTY3NTYxNTc0N2YyNmMyYiIsImV4cCI6MTU5ODc3ODEwNiwiZ3JhbnRzIjp7ImlkZW50aXR5IjoiSGFyb29uMSIsInZpZGVvIjp7InJvb20iOiJTbWFsbERhaWx5U3RhbmR1cCJ9fX0.7XUS5uMQQJfkrBZu9EjQ6STL6R7iXkso6BtO1HmrQKk", +// "identity": "Haroon1", +// "name": "SmallDailyStandup", +// "videoUrl": "video", +// "picture": "video", +// "is_call": "true" +// }; +// +// IncomingCallData incomingCallData = IncomingCallData.fromJson(json); +// final result = await Navigator.push(context, MaterialPageRoute(builder: (context) => IncomingCall(incomingCallData: incomingCallData))); +// } +// +// fcmConfigure() { +// FirebaseMessaging.onMessage.listen((RemoteMessage message) async { +// print(message.toString()); +// +// IncomingCallData incomingCallData; +// if (Platform.isAndroid) +// incomingCallData = IncomingCallData.fromJson(message.data['data']); +// else if (Platform.isIOS) incomingCallData = IncomingCallData.fromJson(message.data); +// if (incomingCallData != null) final result = await Navigator.push(context, MaterialPageRoute(builder: (context) => IncomingCall(incomingCallData: incomingCallData))); +// }); +// } +// } diff --git a/lib/pages/webRTC/call_page_bkp.dart b/lib/pages/webRTC/call_page_bkp.dart new file mode 100644 index 00000000..4a31feae --- /dev/null +++ b/lib/pages/webRTC/call_page_bkp.dart @@ -0,0 +1,147 @@ +// import 'package:diplomaticquarterapp/pages/webRTC/signaling_bkp.dart'; +// import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +// import 'package:flutter/material.dart'; +// import 'package:flutter_webrtc/flutter_webrtc.dart'; +// +// class CallPage extends StatefulWidget { +// @override +// _CallPageState createState() => _CallPageState(); +// } +// +// class _CallPageState extends State { +// Signaling signaling = Signaling(); +// RTCVideoRenderer _localRenderer = RTCVideoRenderer(); +// RTCVideoRenderer _remoteRenderer = RTCVideoRenderer(); +// String roomId; +// TextEditingController textEditingController = TextEditingController(text: ''); +// +// @override +// void initState() { +// _localRenderer.initialize(); +// _remoteRenderer.initialize(); +// +// signaling.onAddRemoteStream = ((stream) { +// _remoteRenderer.srcObject = stream; +// setState(() {}); +// }); +// +// super.initState(); +// } +// +// @override +// void dispose() { +// _localRenderer.dispose(); +// _remoteRenderer.dispose(); +// super.dispose(); +// } +// +// void _getUserMedia() async { +// final Map constraints = { +// 'audio': 'false', +// 'video': {'facingMode': 'user'}, +// }; +// +// MediaStream stream = await navigator.mediaDevices.getUserMedia(constraints); +// setState(() { +// _localRenderer.srcObject = stream; +// }); +// } +// +// void initializeRenderers() async { +// _localRenderer.initialize(); +// } +// +// @override +// Widget build(BuildContext context) { +// return AppScaffold( +// isShowAppBar: true, +// showNewAppBar: true, +// showNewAppBarTitle: true, +// isShowDecPage: false, +// appBarTitle: "WebRTC Calling", +// body: Column( +// children: [ +// SizedBox(height: 8), +// Wrap( +// children: [ +// ElevatedButton( +// onPressed: () { +// setState(() { +// signaling.openUserMedia(_localRenderer, _remoteRenderer); +// }); +// }, +// child: Text("Open camera & microphone"), +// ), +// SizedBox( +// width: 8, +// ), +// ElevatedButton( +// onPressed: () async { +// roomId = await signaling.createRoom(_remoteRenderer); +// textEditingController.text = roomId; +// setState(() {}); +// }, +// child: Text("Create room"), +// ), +// SizedBox( +// width: 8, +// ), +// ElevatedButton( +// onPressed: () { +// // Add roomId +// signaling.joinRoom( +// textEditingController.text, +// _remoteRenderer, +// ); +// }, +// child: Text("Join room"), +// ), +// SizedBox( +// width: 8, +// ), +// ElevatedButton( +// onPressed: () { +// signaling.hangUp(_localRenderer); +// }, +// child: Text("Hangup"), +// ) +// ], +// ), +// SizedBox(height: 8), +// Expanded( +// child: Padding( +// padding: const EdgeInsets.all(0.0), +// child: Stack( +// children: [ +// Positioned(top: 0.0, right: 0.0, left: 0.0, bottom: 0.0, child: RTCVideoView(_remoteRenderer)), +// Positioned( +// top: 20.0, +// right: 100.0, +// left: 20.0, +// bottom: 300.0, +// child: RTCVideoView(_localRenderer, mirror: true), +// ), +// ], +// ), +// ), +// ), +// Padding( +// padding: const EdgeInsets.all(8.0), +// child: Row( +// mainAxisAlignment: MainAxisAlignment.center, +// children: [ +// Text("Join the following Room: "), +// Flexible( +// child: TextFormField( +// controller: textEditingController, +// ), +// ) +// ], +// ), +// ), +// SizedBox(height: 8) +// ], +// ), +// ); +// } +// } diff --git a/lib/pages/webRTC/fcm/FCMSendNotification.dart b/lib/pages/webRTC/fcm/FCMSendNotification.dart new file mode 100644 index 00000000..08c4cca9 --- /dev/null +++ b/lib/pages/webRTC/fcm/FCMSendNotification.dart @@ -0,0 +1,86 @@ + +import 'dart:convert'; + +import 'package:diplomaticquarterapp/core/service/client/base_app_client.dart'; +import 'package:http/http.dart' as http; + +const _serverFCMToken = 'ya29.a0ARrdaM9U7fZtxF64ntg2Y1Nve-cd4rPazyGcWN69cQmOsddUqxAL1X8GUQ8V6sW2gWxM8ln1BIbmh0OrzQtCiTGrsmcL3jZlGXoQhZN51nX3O7F3g1AXCW_Zt_pjiworCJEGSRkl7QirxE7RFzlwBONsOuft'; +const doctorID = '12345'; + +class FCM{ + static Future sendCallNotifcationTo(String token, String patientID, String patientMobile) async{ + var headers = { + 'Authorization': 'Bearer $_serverFCMToken', + 'Content-Type': 'application/json' + }; + + final body = { + "message": { + "token": token, + "notification": { + "title": "Dr Sulaiman Al Habib", + "body": "Doctor is calling" + }, + "apns": { + "payload": { + "aps": { + "sound": "ring_30Sec.mp3", + "token": "466e0f16fecf1e32c51f812cccc84fcbc807f958b15eb55675a5fa971a775829", + "badge": 1 + } + }, + "headers": { + "apns-priority": "10", + "apns-expiration": "0", + "apns-collapse-id": "2561368006" + } + }, + "data": { + "callerID" : doctorID, + "receiverID" : patientID, + "receiverMobile" : patientMobile, + "msgID": "123", + "notfID": "123", + "notification_foreground": "true", + "count": "1", + "message": "Doctor is calling ", + "AppointmentNo": "123", + "title": "Rayyan Hospital", + "ProjectID": "123", + "NotificationType": "10", + "background": "1", + "doctorname": "Dr Sulaiman Al Habib", + "clinicname": "ENT Clinic", + "speciality": "Speciality", + "appointmentdate": "Sun, 15th Dec, 2019", + "appointmenttime": "09:00", + "type": "video", + "session_id": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImN0eSI6InR3aWxpby1mcGE7dj0xIn0.eyJqdGkiOiJTS2I2NjYyOWMzN2ZhOTM3YjFjNDI2Zjg1MTgyNWFmN2M0LTE1OTg3NzQ1MDYiLCJpc3MiOiJTS2I2NjYyOWMzN2ZhOTM3YjFjNDI2Zjg1MTgyNWFmN2M0Iiwic3ViIjoiQUNhYWQ1YTNmOGM2NGZhNjczNTY3NTYxNTc0N2YyNmMyYiIsImV4cCI6MTU5ODc3ODEwNiwiZ3JhbnRzIjp7ImlkZW50aXR5IjoiSGFyb29uMSIsInZpZGVvIjp7InJvb20iOiJTbWFsbERhaWx5U3RhbmR1cCJ9fX0.7XUS5uMQQJfkrBZu9EjQ6STL6R7iXkso6BtO1HmrQKk", + "identity": "Haroon1", + "name": "SmallDailyStandup", + "videoUrl": "video", + "picture": "video", + "is_call": "true" + } + } + }; + + bool success = false; + await BaseAppClient().simplePost('https://fcm.googleapis.com/v1/projects/api-project-815750722565/messages:send', body: body, headers: headers, onSuccess: (data, statusCode){ + success = true; + }, onFailure: (error, statusCode){ + success = false; + }); + + return success; + // final response = await http.post('https://fcm.googleapis.com/v1/projects/api-project-815750722565/messages:send', headers:he aders, body: body); + + + } +} + +String toB64(String data){ + var bytes = utf8.encode(data); + var base64Str = base64.encode(bytes); + return base64Str; +} \ No newline at end of file diff --git a/lib/pages/webRTC/signaling.dart b/lib/pages/webRTC/signaling.dart new file mode 100644 index 00000000..028de903 --- /dev/null +++ b/lib/pages/webRTC/signaling.dart @@ -0,0 +1,277 @@ +// import 'dart:convert'; +// +// import 'package:diplomaticquarterapp/uitl/SignalRUtil.dart'; +// import 'package:flutter/cupertino.dart'; +// import 'package:flutter_webrtc/flutter_webrtc.dart'; +// +// typedef void StreamStateCallback(MediaStream stream); +// typedef void RTCIceGatheringStateCallback(RTCIceGatheringState state); +// typedef void RTCPeerConnectionStateCallback(RTCPeerConnectionState state); +// typedef void RTCSignalingStateCallback(RTCSignalingState state); +// +// final Map constraints = { +// 'mandatory': {}, +// 'optional': [ +// {'DtlsSrtpKeyAgreement': true}, +// ] +// }; +// +// Map snapsis_ice_config = { +// 'iceServers': [ +// { "urls": 'stun:15.185.116.59:3478' }, +// { "urls": "turn:15.185.116.59:3479", "username": "admin", "credential": "admin" }, +// ], +// // 'sdpSemantics': 'unified-plan' +// }; +// Map twilio_ice_config = { +// "ice_servers": [ +// { +// "url": "stun:global.stun.twilio.com:3478?transport=udp", +// "urls": "stun:global.stun.twilio.com:3478?transport=udp" +// }, +// { +// "url": "turn:global.turn.twilio.com:3478?transport=udp", +// "username": "ce8042842b62c21bd20b176f80d6067fd3db81b1e9766312418ef5421d9ca2a2", +// "urls": "turn:global.turn.twilio.com:3478?transport=udp", +// "credential": "UzGOsiLwPZJ32cjafAebfDDpVrqeQjgpFHZEdau/8r4=" +// }, +// { +// "url": "turn:global.turn.twilio.com:3478?transport=tcp", +// "username": "ce8042842b62c21bd20b176f80d6067fd3db81b1e9766312418ef5421d9ca2a2", +// "urls": "turn:global.turn.twilio.com:3478?transport=tcp", +// "credential": "UzGOsiLwPZJ32cjafAebfDDpVrqeQjgpFHZEdau/8r4=" +// }, +// { +// "url": "turn:global.turn.twilio.com:443?transport=tcp", +// "username": "ce8042842b62c21bd20b176f80d6067fd3db81b1e9766312418ef5421d9ca2a2", +// "urls": "turn:global.turn.twilio.com:443?transport=tcp", +// "credential": "UzGOsiLwPZJ32cjafAebfDDpVrqeQjgpFHZEdau/8r4=" +// } +// ], +// // 'sdpSemantics': 'unified-plan' +// }; +// Map google_ice_config = { +// 'iceServers': [ +// { +// 'urls': [ +// 'stun:stun.l.google.com:19302', +// 'stun:stun1.l.google.com:19302', +// 'stun:stun2.l.google.com:19302', +// 'stun:stun3.l.google.com:19302' +// ] +// }, +// ], +// // 'sdpSemantics': 'unified-plan' +// }; +// Map aws_ice_config = { +// 'iceServers': [ +// {'url': "stun:ec2-15-185-116-59.me-south-1.compute.amazonaws.com:3478"}, +// {'url': "turn:ec2-15-185-116-59.me-south-1.compute.amazonaws.com:3479", 'credential': "admin", 'username': "admin"} +// ], +// // 'sdpSemantics': 'unified-plan' +// }; +// +// class Signaling { +// dispose() { +// if (peerConnection != null) { +// peerConnection.dispose(); +// peerConnection.getLocalStreams().forEach((e) => e.dispose()); +// peerConnection.getRemoteStreams().forEach((e) => e.dispose()); +// } +// signalR.closeConnection(); +// } +// +// init() async{ +// // Create Peer Connection +// peerConnection = await createPeerConnection(google_ice_config, constraints); +// registerPeerConnectionListeners(); +// } +// +// initializeSignalR(String userName) async { +// if (signalR != null) await signalR.closeConnection(); +// // https://vcallapi.hmg.com/webRTCHub?source=web&username=zohaib +// // signalR = SignalRUtil(hubName: "https://vcallapi.hmg.com/webRTCHub?source=mobile&username=$userName"); +// signalR = SignalRUtil(hubName: "http://35.193.237.29/webRTCHub?source=mobile&username=$userName"); +// final connected = await signalR.openConnection(); +// if (!connected) throw 'Failed to connect SignalR'; +// } +// +// Map configuration = { +// // 'iceServers': [ +// // { +// // 'urls': ['stun:stun1.l.google.com:19302', 'stun:stun2.l.google.com:19302'] +// // } +// // ] +// +// 'iceServers': [ +// // {'url': "stun:ec2-15-185-116-59.me-south-1.compute.amazonaws.com:3478"}, +// // {'url': "turn:ec2-15-185-116-59.me-south-1.compute.amazonaws.com:3479", 'credential': "admin", 'username': "admin"} +// // {'url': "stun:15.185.116.59:3478"}, +// // { +// // "url":"turn:15.185.116.59:3479", +// // "username": "admin", +// // "credential":"admin" +// // } +// { +// "url": "stun:global.stun.twilio.com:3478?transport=udp", +// "urls": "stun:global.stun.twilio.com:3478?transport=udp" +// }, +// { +// "url": "turn:global.turn.twilio.com:3478?transport=udp", +// "username": "f18fc347ba4aeeaa1b00f5199b1e900834b464962d434a4a89b4cdba02510047", +// "urls": "turn:global.turn.twilio.com:3478?transport=udp", +// "credential": "WX16BB+9nKm0f+Whf5EwpM8S/Yv+T2tlvQWLfdV7oqo=" +// } +// ] +// }; +// +// SignalRUtil signalR; +// +// RTCPeerConnection peerConnection; +// MediaStream localStream; +// MediaStream remoteStream; +// RTCDataChannel dataChannel; +// +// // Future call(String patientId, String mobile, {@required RTCVideoRenderer localVideo, @required RTCVideoRenderer remoteVideo}) async { +// // await initializeSignalR(patientId); +// // +// // // final isCallPlaced = await FCM.sendCallNotifcationTo(DOCTOR_TOKEN, patientId, mobile); +// // if(!isCallPlaced) +// // throw 'Failed to notify target for call'; +// // +// // return isCallPlaced; +// // } +// +// Future acceptCall(String caller, String receiver, {@required MediaStream localMediaStream, @required Function(MediaStream) onRemoteMediaStream, @required Function(RTCTrackEvent) onRemoteTrack}) async { +// await initializeSignalR(receiver); +// signalR.setContributors(caller: caller, receiver: receiver); +// await signalR.acceptCall(receiver, caller).catchError((e) => throw 'Failed to inform signalR that i accepted a call'); +// +// peerConnection.addStream(localMediaStream); +// +// // peerConnection?.onTrack = (track){ +// // onRemoteTrack(track); +// // }; +// peerConnection?.onAddStream = (MediaStream stream) { +// remoteStream = stream; +// onRemoteMediaStream?.call(stream); +// }; +// return true; +// } +// +// +// Future declineCall(String caller, String receiver) async { +// await initializeSignalR(receiver); +// signalR.setContributors(caller: caller, receiver: receiver); +// await signalR.declineCall(receiver, caller).catchError((e) => throw 'Failed to inform signalR that i accepted a call'); +// +// // peerConnection.addStream(localMediaStream); +// // +// // peerConnection?.onAddStream = (MediaStream stream) { +// // remoteStream = stream; +// // onRemoteMediaStream?.call(stream); +// // }; +// return true; +// } +// +// Future hangupCall(String caller, String receiver) async { +// await signalR.hangupCall(caller, receiver); +// dispose(); +// } +// +// answerOffer(String sdp) async { +// final offer = jsonDecode(sdp); +// final caller = offer['caller']; +// final receiver = offer['target']; +// final offerSdp = offer['sdp']; +// peerConnection.setRemoteDescription(rtcSessionDescriptionFrom(offerSdp)).then((value) { +// return peerConnection.createAnswer().catchError((e){ +// print(e); +// }); +// }).then((anwser) { +// return peerConnection.setLocalDescription(anwser).catchError((e){ +// print(e); +// }); +// }).then((value) { +// return peerConnection.getLocalDescription().catchError((e){ +// print(e); +// }); +// }).then((answer) { +// return signalR.answerOffer(answer, caller, receiver).catchError((e){ +// print(e); +// }); +// }).catchError((e) { +// print(e); +// }); +// } +// +// Future hangUp(RTCVideoRenderer localVideo) async {} +// +// Future createSdpAnswer(String toOfferSdp) async { +// final offerSdp = rtcSessionDescriptionFrom(jsonDecode(toOfferSdp)); +// peerConnection.setRemoteDescription(offerSdp).catchError((e){ +// print(e); +// }); +// +// final answer = await peerConnection.createAnswer().catchError((e){ +// print(e); +// }); +// var answerSdp = json.encode(answer); // Send SDP via Push or any channel +// return answerSdp; +// } +// +// Future createSdpOffer() async { +// final offer = await peerConnection.createOffer(); +// await peerConnection.setLocalDescription(offer).catchError((e){ +// print(e); +// }); +// final map = offer.toMap(); +// var offerSdp = json.encode(map); // Send SDP via Push or any channel +// return offerSdp; +// } +// +// addCandidate(String candidateJson) { +// peerConnection.addCandidate(rtcIceCandidateFrom(candidateJson)).catchError((e){ +// print(e); +// }); +// } +// +// void registerPeerConnectionListeners() { +// peerConnection.onRenegotiationNeeded = (){ +// print('Renegotiation Needed...'); +// }; +// +// peerConnection.onIceCandidate = (RTCIceCandidate candidate) { +// // print(json.encode(candidate.toMap())); +// signalR.addIceCandidate(json.encode(candidate.toMap())).catchError((e){ +// print(e); +// }); +// }; +// +// peerConnection?.onIceGatheringState = (RTCIceGatheringState state) { +// print('ICE gathering state changed: $state'); +// }; +// +// peerConnection?.onConnectionState = (RTCPeerConnectionState state) { +// print('Connection state change: $state'); +// }; +// +// peerConnection?.onSignalingState = (RTCSignalingState state) { +// print('Signaling state change: $state'); +// }; +// +// +// } +// } +// +// rtcSessionDescriptionFrom(Map sdp) { +// return RTCSessionDescription( +// sdp['sdp'], +// sdp['type'], +// ); +// } +// +// rtcIceCandidateFrom(String json) { +// final map = jsonDecode(json)['candidate']; +// return RTCIceCandidate(map['candidate'], map['sdpMid'], map['sdpMLineIndex']); +// } diff --git a/lib/pages/webRTC/signaling_bkp.dart b/lib/pages/webRTC/signaling_bkp.dart new file mode 100644 index 00000000..3b716ab6 --- /dev/null +++ b/lib/pages/webRTC/signaling_bkp.dart @@ -0,0 +1,242 @@ +// import 'dart:convert'; +// +// // import 'package:cloud_firestore/cloud_firestore.dart'; +// import 'package:flutter_webrtc/flutter_webrtc.dart'; +// +// typedef void StreamStateCallback(MediaStream stream); +// +// class Signaling { +// Map configuration = { +// 'iceServers': [ +// { +// 'urls': ['stun:stun1.l.google.com:19302', 'stun:stun2.l.google.com:19302'] +// } +// ] +// }; +// +// late RTCPeerConnection peerConnection; +// late MediaStream localStream; +// late MediaStream remoteStream; +// late String roomId; +// late String currentRoomText; +// late StreamStateCallback onAddRemoteStream; +// +// Future createRoom(RTCVideoRenderer remoteRenderer) async { +// // FirebaseFirestore db = FirebaseFirestore.instance; +// // DocumentReference roomRef = db.collection('rooms').doc(); +// +// print('Create PeerConnection with configuration: $configuration'); +// +// peerConnection = await createPeerConnection(configuration); +// +// registerPeerConnectionListeners(); +// +// localStream.getTracks().forEach((track) { +// peerConnection?.addTrack(track, localStream); +// }); +// +// // Code for collecting ICE candidates below +// // var callerCandidatesCollection = roomRef.collection('callerCandidates'); +// +// peerConnection?.onIceCandidate = (RTCIceCandidate candidate) { +// print('Got candidate: ${candidate.toMap()}'); +// // callerCandidatesCollection.add(candidate.toMap()); +// }; +// // Finish Code for collecting ICE candidate +// +// // Add code for creating a room +// RTCSessionDescription offer = await peerConnection.createOffer(); +// await peerConnection.setLocalDescription(offer); +// print('Created offer: $offer'); +// +// Map roomWithOffer = {'offer': offer.toMap()}; +// +// // await roomRef.set(roomWithOffer); +// // var roomId = roomRef.id; +// print('New room created with SDK offer. Room ID: $roomId'); +// currentRoomText = 'Current room is $roomId - You are the caller!'; +// // Created a Room +// +// peerConnection?.onTrack = (RTCTrackEvent event) { +// print('Got remote track: ${event.streams[0]}'); +// +// event.streams[0].getTracks().forEach((track) { +// print('Add a track to the remoteStream $track'); +// remoteStream?.addTrack(track); +// }); +// }; +// +// // Listening for remote session description below +// // roomRef.snapshots().listen((snapshot) async { +// // print('Got updated room: ${snapshot.data()}'); +// // +// // Map data = snapshot.data() as Map; +// // if (peerConnection?.getRemoteDescription() != null && data['answer'] != null) { +// // var answer = RTCSessionDescription( +// // data['answer']['sdp'], +// // data['answer']['type'], +// // ); +// // +// // print("Someone tried to connect"); +// // await peerConnection?.setRemoteDescription(answer); +// // } +// // }); +// // // Listening for remote session description above +// // +// // // Listen for remote Ice candidates below +// // roomRef.collection('calleeCandidates').snapshots().listen((snapshot) { +// // snapshot.docChanges.forEach((change) { +// // if (change.type == DocumentChangeType.added) { +// // Map data = change.doc.data() as Map; +// // print('Got new remote ICE candidate: ${jsonEncode(data)}'); +// // peerConnection.addCandidate( +// // RTCIceCandidate( +// // data['candidate'], +// // data['sdpMid'], +// // data['sdpMLineIndex'], +// // ), +// // ); +// // } +// // }); +// // }); +// // Listen for remote ICE candidates above +// +// return roomId; +// } +// +// Future joinRoom(String roomId, RTCVideoRenderer remoteVideo) async { +// // FirebaseFirestore db = FirebaseFirestore.instance; +// // DocumentReference roomRef = db.collection('rooms').doc('$roomId'); +// // var roomSnapshot = await roomRef.get(); +// // print('Got room ${roomSnapshot.exists}'); +// +// // if (roomSnapshot.exists) { +// // print('Create PeerConnection with configuration: $configuration'); +// // peerConnection = await createPeerConnection(configuration); +// // +// // registerPeerConnectionListeners(); +// // +// // localStream.getTracks().forEach((track) { +// // peerConnection?.addTrack(track, localStream); +// // }); +// // +// // // Code for collecting ICE candidates below +// // // var calleeCandidatesCollection = roomRef.collection('calleeCandidates'); +// // peerConnection.onIceCandidate = (RTCIceCandidate candidate) { +// // if (candidate == null) { +// // print('onIceCandidate: complete!'); +// // return; +// // } +// // print('onIceCandidate: ${candidate.toMap()}'); +// // // calleeCandidatesCollection.add(candidate.toMap()); +// // }; +// // // Code for collecting ICE candidate above +// // +// // peerConnection?.onTrack = (RTCTrackEvent event) { +// // print('Got remote track: ${event.streams[0]}'); +// // event.streams[0].getTracks().forEach((track) { +// // print('Add a track to the remoteStream: $track'); +// // remoteStream?.addTrack(track); +// // }); +// // }; +// // +// // // Code for creating SDP answer below +// // var data = roomSnapshot.data() as Map; +// // print('Got offer $data'); +// // var offer = data['offer']; +// // await peerConnection?.setRemoteDescription( +// // RTCSessionDescription(offer['sdp'], offer['type']), +// // ); +// // var answer = await peerConnection.createAnswer(); +// // print('Created Answer $answer'); +// // +// // await peerConnection.setLocalDescription(answer); +// // +// // Map roomWithAnswer = { +// // 'answer': {'type': answer.type, 'sdp': answer.sdp} +// // }; +// // +// // await roomRef.update(roomWithAnswer); +// // // Finished creating SDP answer +// // +// // // Listening for remote ICE candidates below +// // // roomRef.collection('callerCandidates').snapshots().listen((snapshot) { +// // // snapshot.docChanges.forEach((document) { +// // // var data = document.doc.data() as Map; +// // // print(data); +// // // print('Got new remote ICE candidate: $data'); +// // // peerConnection.addCandidate( +// // // RTCIceCandidate( +// // // data['candidate'], +// // // data['sdpMid'], +// // // data['sdpMLineIndex'], +// // // ), +// // // ); +// // // }); +// // // }); +// // } +// } +// +// Future openUserMedia( +// RTCVideoRenderer localVideo, +// RTCVideoRenderer remoteVideo, +// ) async { +// var stream = await navigator.mediaDevices.getUserMedia({'video': true, 'audio': false}); +// +// localVideo.srcObject = stream; +// localStream = stream; +// +// remoteVideo.srcObject = await createLocalMediaStream('key'); +// } +// +// Future hangUp(RTCVideoRenderer localVideo) async { +// List tracks = localVideo.srcObject!.getTracks(); +// tracks.forEach((track) { +// track.stop(); +// }); +// +// if (remoteStream != null) { +// remoteStream.getTracks().forEach((track) => track.stop()); +// } +// if (peerConnection != null) peerConnection.close(); +// +// if (roomId != null) { +// // var db = FirebaseFirestore.instance; +// // var roomRef = db.collection('rooms').doc(roomId); +// // var calleeCandidates = await roomRef.collection('calleeCandidates').get(); +// // calleeCandidates.docs.forEach((document) => document.reference.delete()); +// +// // var callerCandidates = await roomRef.collection('callerCandidates').get(); +// // callerCandidates.docs.forEach((document) => document.reference.delete()); +// +// // await roomRef.delete(); +// } +// +// localStream.dispose(); +// remoteStream?.dispose(); +// } +// +// void registerPeerConnectionListeners() { +// peerConnection?.onIceGatheringState = (RTCIceGatheringState state) { +// print('ICE gathering state changed: $state'); +// }; +// +// peerConnection?.onConnectionState = (RTCPeerConnectionState state) { +// print('Connection state change: $state'); +// }; +// +// peerConnection?.onSignalingState = (RTCSignalingState state) { +// print('Signaling state change: $state'); +// }; +// +// peerConnection?.onIceGatheringState = (RTCIceGatheringState state) { +// print('ICE connection state change: $state'); +// }; +// +// peerConnection?.onAddStream = (MediaStream stream) { +// print("Add remote stream"); +// onAddRemoteStream?.call(stream); +// remoteStream = stream; +// }; +// } +// } diff --git a/lib/routes.dart b/lib/routes.dart index 4f1f2364..c2ee5f51 100644 --- a/lib/routes.dart +++ b/lib/routes.dart @@ -1,27 +1,36 @@ +import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/health-weather/health-weather-indicator.dart'; import 'package:diplomaticquarterapp/pages/DrawerPages/family/add-family-member.dart'; import 'package:diplomaticquarterapp/pages/DrawerPages/family/add-family_type.dart'; import 'package:diplomaticquarterapp/pages/DrawerPages/family/my-family.dart'; import 'package:diplomaticquarterapp/pages/TestPage.dart'; import 'package:diplomaticquarterapp/pages/appUpdatePage/app_update_page.dart'; +import 'package:diplomaticquarterapp/pages/conference/zoom/call_screen.dart'; import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; +import 'package:diplomaticquarterapp/pages/livecare/incoming_call.dart'; import 'package:diplomaticquarterapp/pages/livecare/livecare_home.dart'; import 'package:diplomaticquarterapp/pages/login/confirm-login.dart'; import 'package:diplomaticquarterapp/pages/login/forgot-password.dart'; -import 'package:diplomaticquarterapp/pages/login/register-info.dart'; -import 'package:diplomaticquarterapp/pages/login/welcome.dart'; import 'package:diplomaticquarterapp/pages/login/login-type.dart'; import 'package:diplomaticquarterapp/pages/login/login.dart'; +import 'package:diplomaticquarterapp/pages/login/register-info.dart'; import 'package:diplomaticquarterapp/pages/login/register.dart'; +import 'package:diplomaticquarterapp/pages/login/welcome.dart'; import 'package:diplomaticquarterapp/pages/packages_offers/OfferAndPackagesCartPage.dart'; -import 'package:diplomaticquarterapp/pages/packages_offers/OfferAndPackagesPage.dart'; import 'package:diplomaticquarterapp/pages/packages_offers/PackageOrderCompletedPage.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/screens/cart-page/cart-order-page.dart'; 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/pages/webRTC/call_page.dart'; +import 'package:diplomaticquarterapp/pages/webRTC/call_page_bkp.dart'; import 'package:diplomaticquarterapp/splashPage.dart'; +import 'models/Appointments/DoctorListResponse.dart'; +import 'pages/BookAppointment/SearchResultsByRegion.dart'; + const String INIT_ROUTE = '/'; const String HOME = 'home'; const String SPLASH = '/'; @@ -45,9 +54,16 @@ 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 CART_ORDER_PAGE = 'cart-order-page'; +const String CALL_PAGE = 'CALL_PAGE'; +const String INCOMING_CALL_PAGE = 'INCOMING_CALL_PAGE'; const String HEALTH_WEATHER = 'health-weather'; const APP_UPDATE = 'app-update'; + +const ZOOM_CALL_PAGE = 'zoom_call_page'; + var routes = { SPLASH: (_) => SplashScreen(), HOME: (_) => LandingPage(), @@ -66,11 +82,21 @@ 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(), + APP_UPDATE: (_) => AppUpdatePage(appUpdateText: '',), SETTINGS: (_) => Settings(), + CART_ORDER_PAGE: (_) => CartOrderPage(), + // CALL_PAGE: (_) => CallPage(), + INCOMING_CALL_PAGE: (_) => IncomingCall(), + + ZOOM_CALL_PAGE: (_) => CallScreen(), + + OPENTOK_CALL_PAGE: (_) => OpenTokConnectCallPage( + apiKey: OPENTOK_API_KEY, + sessionId: '1_MX40NjIwOTk2Mn5-MTY0NzE3MzcwNjA0MH55RUJoZnd0ZGh2U3BPc01ENVZBelQvT1Z-fg', + token: 'T1==cGFydG5lcl9pZD00NjIwOTk2MiZzaWc9M2I4ODYxYTIzMGQ0ZDA3OTYyNDhkODIxNzI5ZjIzODM1NjY2YzExMzpzZXNzaW9uX2lkPTFfTVg0ME5qSXdPVGsyTW41LU1UWTBOekUzTXpjd05qQTBNSDU1UlVKb1puZDBaR2gyVTNCUGMwMUVOVlpCZWxRdlQxWi1mZyZjcmVhdGVfdGltZT0xNjQ3MTczNzA2Jm5vbmNlPTAuMjA3NDI0MzA1NzcwMzY4MiZyb2xlPW1vZGVyYXRvciZleHBpcmVfdGltZT0xNjQ3MjYwMTA2JmluaXRpYWxfbGF5b3V0X2NsYXNzX2xpc3Q9' + ), }; diff --git a/lib/services/appointment_services/GetDoctorsList.dart b/lib/services/appointment_services/GetDoctorsList.dart index 65fe2b04..7664f4ac 100644 --- a/lib/services/appointment_services/GetDoctorsList.dart +++ b/lib/services/appointment_services/GetDoctorsList.dart @@ -3,16 +3,24 @@ import 'dart:io'; import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DoctorProfile.dart'; import 'package:diplomaticquarterapp/models/Appointments/PatientShareResposne.dart'; +import 'package:diplomaticquarterapp/models/Appointments/doctor_pre_post_image.dart'; +import 'package:diplomaticquarterapp/models/Appointments/laser_body_parts.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/models/Request.dart'; +import 'package:diplomaticquarterapp/models/apple_pay_request.dart'; import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart'; import 'package:flutter/cupertino.dart'; +import 'mock_doctor_response.dart'; + class DoctorsListService extends BaseService { AppSharedPreferences sharedPref = AppSharedPreferences(); AppGlobal appGlobal = new AppGlobal(); @@ -20,68 +28,60 @@ class DoctorsListService extends BaseService { AuthenticatedUser authUser = new AuthenticatedUser(); AuthProvider authProvider = new AuthProvider(); - double lat; - double long; - String deviceToken; - String tokenID; + double? lat; + double? long; + String? deviceToken; + String? tokenID; + List selectedBodyPartList = []; - Future getDoctorsList( - int clinicID, int projectID, bool isNearest, BuildContext context, - {doctorId, doctorName}) async { + Future getDoctorsList(int clinicID, int projectID, bool isNearest, int languageID, BuildContext? context, {doctorId, doctorName, isContinueDentalPlan = false}) async { Map request; if (await this.sharedPref.getObject(USER_PROFILE) != null) { - var data = AuthenticatedUser.fromJson( - await this.sharedPref.getObject(USER_PROFILE)); + var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE)); authUser = data; } - if (await this.sharedPref.getDouble(USER_LAT) != null && - await this.sharedPref.getDouble(USER_LONG) != null) { + if (await this.sharedPref.getDouble(USER_LAT) != null && await this.sharedPref.getDouble(USER_LONG) != null) { lat = await this.sharedPref.getDouble(USER_LAT); long = await this.sharedPref.getDouble(USER_LONG); } - var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); - Request req = appGlobal.getPublicRequest(); + // 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": authUser.outSA, + // + // "IPAdress": "10.20.10.20", + // "VersionID": req.VersionID, + // "Channel": req.Channel, + // "generalid": 'Cs2020@2016\$2958', + "PatientOutSA": authProvider.isLogin ? authUser.outSA : 0, "TokenID": "", - "DeviceTypeID": req.DeviceTypeID, + // "DeviceTypeID": req.DeviceTypeID, "SessionID": "YckwoXhUmWBsnHKEKig", "ClinicID": clinicID, "ProjectID": projectID, "DoctorName": doctorName, //!= null ? doctorId : 0, - "ContinueDentalPlan": false, - "IsSearchAppointmnetByClinicID": true, + "ContinueDentalPlan": isContinueDentalPlan, + "IsSearchAppointmnetByClinicID": isContinueDentalPlan ? false : true, "PatientID": authUser.patientID != null ? authUser.patientID : 0, "gender": authUser.gender != null ? authUser.gender : 0, "age": authUser.age != null ? authUser.age : 0, + "DateofBirth": authUser.dateofBirth != null ? authUser.dateofBirth : null, "IsGetNearAppointment": false, - // "Latitude": 0, - // "Longitude": 0, - // "License": true, - "SearchForVoiceCommand": - doctorId != null && doctorId.length > 0 ? true : false, + "SearchForVoiceCommand": doctorId != null && doctorId.length > 0 ? true : false, "DoctorIDsList": doctorId, "Latitude": lat != null ? lat.toString() : 0, "Longitude": long != null ? long.toString() : 0, + "isDentalAllowedBackend": clinicID == 17 ? true : isContinueDentalPlan, "IsGetNearAppointment": isNearest, - if (isNearest) - "SelectedDate": DateUtil.convertDateToString(DateTime.now()), + "LanguageID": languageID, + if (isNearest) "SelectedDate": DateUtil.convertDateToString(DateTime.now()), "License": true }; dynamic localRes; - await baseAppClient.post(GET_DOCTORS_LIST_URL, - onSuccess: (response, statusCode) async { + await baseAppClient.post(GET_DOCTORS_LIST_URL, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { throw error; @@ -89,34 +89,29 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } - Future getDoctorsListByName(String docName, BuildContext context) async { + Future getDoctorsListByName(String docName, int languageID, BuildContext context) async { Map request; - double lat; - double long; + late double lat = 0.0; + late double long = 0.0; if (await this.sharedPref.getObject(USER_PROFILE) != null) { - var data = AuthenticatedUser.fromJson( - await this.sharedPref.getObject(USER_PROFILE)); + var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE)); authUser = data; } - if (await this.sharedPref.getDouble(USER_LAT) != null && - await this.sharedPref.getDouble(USER_LONG) != null) { + if (await this.sharedPref.getDouble(USER_LAT) != null && await this.sharedPref.getDouble(USER_LONG) != null) { lat = await this.sharedPref.getDouble(USER_LAT); long = await this.sharedPref.getDouble(USER_LONG); } - 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": authUser.outSA, + "PatientOutSA": authProvider.isLogin ? authUser.outSA : false, "TokenID": "", "DeviceTypeID": req.DeviceTypeID, "SessionID": null, @@ -125,16 +120,18 @@ class DoctorsListService extends BaseService { "ContinueDentalPlan": false, "IsSearchAppointmnetByClinicID": false, "DoctorName": docName, + "DateofBirth": authUser.dateofBirth != null ? authUser.dateofBirth : null, "PatientID": authUser.patientID != null ? authUser.patientID : 0, "gender": authUser.gender != null ? authUser.gender : 0, "age": authUser.age != null ? authUser.age : 0, "IsGetNearAppointment": false, - "Latitude": lat, - "Longitude": long, + "Latitude": lat == null ? 0.0 : lat, + "Longitude": long == null ? 0.0 : long, + "LanguageID": languageID, "License": true }; - dynamic localRes; + dynamic localRes = response; await baseAppClient.post(GET_DOCTORS_LIST_URL, onSuccess: (response, statusCode) async { @@ -145,19 +142,16 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } - Future getDoctorsProfile( - int docID, int clinicID, int projectID, context) async { + Future getDoctorsProfile(int docID, int clinicID, int projectID, int languageID, context) async { Map request; - 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": authUser.outSA, + "PatientOutSA": authUser.outSA ?? false, "TokenID": "", "DeviceTypeID": req.DeviceTypeID, "SessionID": null, @@ -167,13 +161,13 @@ class DoctorsListService extends BaseService { "License": true, "IsRegistered": true, "ProjectID": projectID, - "isDentalAllowedBackend": false + "isDentalAllowedBackend": false, + "LanguageID": languageID, }; dynamic localRes; - await baseAppClient.post(GET_DOCTOR_PROFILE, - onSuccess: (response, statusCode) async { + await baseAppClient.post(GET_DOCTOR_PROFILE, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { throw error; @@ -181,13 +175,11 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } - Future getDoctorsRating(int docID, context) async { + Future getDoctorsRating(int docID, int languageID, context) async { Map request; - 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, @@ -200,13 +192,13 @@ class DoctorsListService extends BaseService { "PatientID": 0, "License": true, "IsRegistered": true, + "LanguageID": languageID, "isDentalAllowedBackend": false }; dynamic localRes; - await baseAppClient.post(GET_DOCTOR_RATING_NOTES, - onSuccess: (response, statusCode) async { + await baseAppClient.post(GET_DOCTOR_RATING_NOTES, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { throw error; @@ -214,13 +206,31 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } - Future getDoctorsRatingDetails(int docID, context) async { + Future getDoctorPrePostImages(DoctorProfileList doctorProfile, context) async { + Map request; + request = {"PatientOutSA": authUser.outSA ?? 0, "isDentalAllowedBackend": false, "DoctorID": doctorProfile.doctorID, "ClinicID": doctorProfile.clinicID, "ProjectID": doctorProfile.projectID}; + + var images = DoctorPrePostImages(); + await baseAppClient.post(GET_DOCTOR_PRE_POST_IMAGES, onSuccess: (response, statusCode) async { + var list = response['DoctorPrePostImagesList']; + if (list is List && list.length > 0) { + list.forEach((j) { + var image = DoctorPrePostImageModel.fromJson(j); + if (image.imageType == 1) images.pre = image; + if (image.imageType == 2) images.post = image; + }); + } + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(images); + } + + Future getDoctorsRatingDetails(int docID, int languageID, context) async { Map request; - 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, @@ -233,13 +243,13 @@ class DoctorsListService extends BaseService { "PatientID": 0, "License": true, "IsRegistered": true, + "LanguageID": languageID, "isDentalAllowedBackend": false }; dynamic localRes; - await baseAppClient.post(GET_DOCTOR_RATING_DETAILS, - onSuccess: (response, statusCode) async { + await baseAppClient.post(GET_DOCTOR_RATING_DETAILS, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { throw error; @@ -247,11 +257,9 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } - Future getDoctorFreeSlots( - int docID, int clinicID, int projectID, BuildContext context) async { + Future getDoctorFreeSlots(int docID, int clinicID, int projectID, bool isContinueDentalPlan, BuildContext context, [ProjectViewModel? projectViewModel]) async { Map request; - var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + Request req = appGlobal.getPublicRequest(); request = { "DoctorID": docID, @@ -263,19 +271,29 @@ class DoctorsListService extends BaseService { "isReschadual": false, "VersionID": req.VersionID, "Channel": 3, - "LanguageID": languageID == 'ar' ? 1 : 2, "IPAdress": "10.20.10.20", "generalid": "Cs2020@2016\$2958", - "PatientOutSA": authUser.outSA, + "PatientOutSA": authProvider.isLogin ? authUser.outSA : 0, "SessionID": null, "isDentalAllowedBackend": false, - "DeviceTypeID": 1 + "LanguageID": 1, + "DeviceTypeID": 1, + "ContinueDentalPlan": isContinueDentalPlan, }; + if (clinicID == 253) { + List procedureID = projectViewModel!.selectedBodyPartList.map((element) => element.id.toString()).toList(); + request["GeneralProcedureList"] = procedureID; + if (procedureID.length == 1 && procedureID[0] == "1") { + request["ProcedureSlotDuration"] = 90; + } else { + request["ProcedureSlotDuration"] = projectViewModel.laserSelectionDuration; + } + } + dynamic localRes; - await baseAppClient.post(GET_DOCTOR_FREE_SLOTS, - onSuccess: (response, statusCode) async { + await baseAppClient.post(GET_DOCTOR_FREE_SLOTS, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { throw error; @@ -283,11 +301,9 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } - Future getDoctorScheduledFreeSlots(int docID, int clinicID, - int projectID, int serviceID, BuildContext context) async { + Future getDoctorScheduledFreeSlots(int docID, int clinicID, int projectID, int serviceID, BuildContext context) async { Map request; - var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + Request req = appGlobal.getPublicRequest(); request = { "DoctorID": docID, @@ -300,19 +316,18 @@ class DoctorsListService extends BaseService { "isReschadual": false, "VersionID": req.VersionID, "Channel": 3, - "LanguageID": languageID == 'ar' ? 1 : 2, "IPAdress": "10.20.10.20", "generalid": "Cs2020@2016\$2958", "PatientOutSA": authUser.outSA, "SessionID": null, "isDentalAllowedBackend": false, + "LanguageID": 1, "DeviceTypeID": 1 }; dynamic localRes; - await baseAppClient.post(GET_LIVECARE_SCHEDULE_DOCTOR_TIME_SLOTS, - onSuccess: (response, statusCode) async { + await baseAppClient.post(GET_LIVECARE_SCHEDULE_DOCTOR_TIME_SLOTS, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { throw error; @@ -320,18 +335,14 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } - Future insertAppointment(int docID, int clinicID, int projectID, - String selectedTime, String selectedDate, BuildContext context) async { + Future insertWalkInAppointment(int docID, int clinicID, int projectID, String selectedTime, String selectedDate, int initialSlotDuration, int languageID, BuildContext context) async { Map request; if (await this.sharedPref.getObject(USER_PROFILE) != null) { - var data = AuthenticatedUser.fromJson( - await this.sharedPref.getObject(USER_PROFILE)); + var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE)); authUser = data; } - var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { "IsForLiveCare": false, @@ -341,16 +352,17 @@ class DoctorsListService extends BaseService { "StartTime": selectedTime, "SelectedTime": selectedTime, "EndTime": selectedTime, - "InitialSlotDuration": 0, + "InitialSlotDuration": initialSlotDuration, "StrAppointmentDate": selectedDate, "IsVirtual": false, "DeviceType": Platform.isIOS ? 'iOS' : 'Android', "BookedBy": 102, "VisitType": 1, "VisitFor": 1, + "GenderID": authUser.gender, + "Age": authUser.age != null ? authUser.age : 0, "VersionID": req.VersionID, "Channel": req.Channel, - "LanguageID": languageID == 'ar' ? 1 : 2, "IPAdress": req.IPAdress, "generalid": req.generalid, "PatientOutSA": authUser.outSA, @@ -358,40 +370,101 @@ class DoctorsListService extends BaseService { "isDentalAllowedBackend": false, "DeviceTypeID": req.DeviceTypeID, "PatientID": authUser.patientID, - "TokenID": "@dm!n", "PatientTypeID": authUser.patientType, "PatientType": authUser.patientType }; dynamic localRes; + try { + await baseAppClient.post(INSERT_WALKIN_APPOINTMENT, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } catch (e) { + return Future.error(e); + } + } - await baseAppClient.post(INSERT_SPECIFIC_APPOINTMENT, - onSuccess: (response, statusCode) async { - localRes = response; - }, onFailure: (String error, int statusCode) { - throw error; - }, body: request); - return Future.value(localRes); + Future insertAppointment(int docID, int clinicID, int projectID, String selectedTime, String selectedDate, int initialSlotDuration, int languageID, BuildContext context, + [String? procedureID, num? testTypeEnum, num? testProcedureEnum, ProjectViewModel? projectViewModel, int? invoiceNumber, int? lineItemNo, String? invoiceNoVP]) async { + Map request; + + if (await this.sharedPref.getObject(USER_PROFILE) != null) { + var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE)); + authUser = data; + } + + Request req = appGlobal.getPublicRequest(); + request = { + "IsForLiveCare": false, + "ProjectID": projectID, + "ClinicID": clinicID, + "DoctorID": docID, + "StartTime": selectedTime, + "SelectedTime": selectedTime, + "EndTime": selectedTime, + "ProcedureID": procedureID, + "TestTypeEnum": testTypeEnum, + "TestProcedureEnum": testProcedureEnum, + "InitialSlotDuration": initialSlotDuration, + "StrAppointmentDate": selectedDate, + "IsVirtual": false, + "DeviceType": Platform.isIOS ? 'iOS' : 'Android', + "BookedBy": 102, + "VisitType": 1, + "VisitFor": 1, + "GenderID": authUser.gender, + "Age": authUser.age != null ? authUser.age : 0, + "VersionID": req.VersionID, + "Channel": req.Channel, + "IPAdress": req.IPAdress, + "generalid": req.generalid, + "PatientOutSA": authUser.outSA, + "SessionID": "YckwoXhUmWBsnHKEKig", + "isDentalAllowedBackend": false, + "DeviceTypeID": req.DeviceTypeID, + "PatientID": authUser.patientID, + "PatientTypeID": authUser.patientType, + "PatientType": authUser.patientType, + "InvoiceNo": invoiceNumber, + "InvoiceNo_VP": invoiceNoVP, + "LineItemNo": lineItemNo, + // "TokenID":"@dm!n" + }; + + if (clinicID == 253) { + List procedureID = projectViewModel!.selectedBodyPartList.map((element) => element.id.toString()).toList(); + request["GeneralProcedureList"] = procedureID; + if (procedureID.length == 1 && procedureID[0] == "1") { + request["InitialSlotDuration"] = 90; + } else { + request["InitialSlotDuration"] = projectViewModel.laserSelectionDuration; + } + } + + dynamic localRes; + try { + await baseAppClient.post(INSERT_SPECIFIC_APPOINTMENT, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } catch (e) { + return Future.error(e); + } } - Future insertLiveCareScheduleAppointment( - int docID, - int clinicID, - int projectID, - int serviceID, - String selectedTime, - String selectedDate, - BuildContext context) async { + Future insertLiveCareScheduleAppointment(int docID, int clinicID, int projectID, int serviceID, String selectedTime, String selectedDate, int languageID, BuildContext context) async { Map request; if (await this.sharedPref.getObject(USER_PROFILE) != null) { - var data = AuthenticatedUser.fromJson( - await this.sharedPref.getObject(USER_PROFILE)); + var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE)); authUser = data; } - var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { "IsForLiveCare": true, @@ -406,12 +479,14 @@ class DoctorsListService extends BaseService { "StrAppointmentDate": selectedDate, "IsVirtual": false, "DeviceType": Platform.isIOS ? 'iOS' : 'Android', + "DeviceToken": await sharedPref.getString(PUSH_TOKEN), "BookedBy": 102, "VisitType": 1, "VisitFor": 1, + "Age": authUser.age != null ? authUser.age : 0, + "GenderID": authUser.gender, "VersionID": req.VersionID, "Channel": req.Channel, - "LanguageID": languageID == 'ar' ? 1 : 2, "IPAdress": req.IPAdress, "generalid": req.generalid, "PatientOutSA": authUser.outSA, @@ -419,15 +494,13 @@ class DoctorsListService extends BaseService { "isDentalAllowedBackend": false, "DeviceTypeID": req.DeviceTypeID, "PatientID": authUser.patientID, - "TokenID": "@dm!n", "PatientTypeID": authUser.patientType, "PatientType": authUser.patientType }; dynamic localRes; - await baseAppClient.post(INSERT_LIVECARE_SCHEDULE_APPOINTMENT, - onSuccess: (response, statusCode) async { + await baseAppClient.post(INSERT_LIVECARE_SCHEDULE_APPOINTMENT, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { throw error; @@ -435,18 +508,14 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } - Future getPatientShare( - String appoID, int clinicID, int projectID, BuildContext context) async { + Future getPatientShare(String appoID, int clinicID, int projectID, int languageID, BuildContext context) async { Map request; if (await this.sharedPref.getObject(USER_PROFILE) != null) { - var data = AuthenticatedUser.fromJson( - await this.sharedPref.getObject(USER_PROFILE)); + var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE)); authUser = data; } - var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { @@ -456,7 +525,6 @@ class DoctorsListService extends BaseService { "IsActiveAppointment": true, "VersionID": req.VersionID, "Channel": req.Channel, - "LanguageID": languageID == 'ar' ? 1 : 2, "IPAdress": req.IPAdress, "generalid": req.generalid, "PatientOutSA": authUser.outSA, @@ -464,34 +532,68 @@ class DoctorsListService extends BaseService { "isDentalAllowedBackend": false, "DeviceTypeID": req.DeviceTypeID, "PatientID": authUser.patientID, - "TokenID": "@dm!n", "PatientTypeID": authUser.patientType, + "LanguageID": languageID, "PatientType": authUser.patientType }; dynamic localRes; - await baseAppClient.post(GET_PATIENT_SHARE, - onSuccess: (response, statusCode) async { - localRes = response['OnlineCheckInAppointments'][0]; + await baseAppClient.post(GET_PATIENT_SHARE, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } + + Future setOnlineCheckInForAppointment(String appoID, int projectID, int languageID, BuildContext context) async { + Map request; + + if (await this.sharedPref.getObject(USER_PROFILE) != null) { + var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE)); + authUser = data; + } + request = {"ProjectID": projectID, "AppointmentNo": appoID, "LanguageID": languageID}; + + dynamic localRes; + + await baseAppClient.post(SET_ONLINE_CHECKIN_FOR_APPOINTMENT, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } + + Future checkPatientHasDermaPackage(int patientID, int clinicID, int projectID, int doctorID, int languageID, BuildContext context) async { + Map request; + + if (await this.sharedPref.getObject(USER_PROFILE) != null) { + var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE)); + authUser = data; + } + request = {"PatientID": patientID, "ClinicID": clinicID, "ProjectID": projectID, "LanguageID": languageID}; + //request = { "PatientID":4768732, "ClinicID":1, "ProjectID": 15, "LanguageID": languageID, "TokenID":"@dm!n" }; + + dynamic localRes; + + await baseAppClient.post(CHECK_PATIENT_DERMA_PACKAGE, onSuccess: (response, statusCode) async { + localRes = response; }, onFailure: (String error, int statusCode) { throw error; }, body: request); return Future.value(localRes); } - Future getLiveCareAppointmentPatientShare( - String appoID, int clinicID, int projectID, BuildContext context) async { + Future getLiveCareAppointmentPatientShare(String appoID, int clinicID, int projectID, int languageID, BuildContext context) async { Map request; if (await this.sharedPref.getObject(USER_PROFILE) != null) { - var data = AuthenticatedUser.fromJson( - await this.sharedPref.getObject(USER_PROFILE)); + var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE)); authUser = data; } - var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { @@ -502,7 +604,6 @@ class DoctorsListService extends BaseService { "IsForLiveCare": true, "VersionID": req.VersionID, "Channel": req.Channel, - "LanguageID": languageID == 'ar' ? 1 : 2, "IPAdress": req.IPAdress, "generalid": req.generalid, "PatientOutSA": authUser.outSA, @@ -510,15 +611,14 @@ class DoctorsListService extends BaseService { "isDentalAllowedBackend": false, "DeviceTypeID": req.DeviceTypeID, "PatientID": authUser.patientID, - "TokenID": "@dm!n", "PatientTypeID": authUser.patientType, + "LanguageID": languageID, "PatientType": authUser.patientType }; dynamic localRes; - await baseAppClient.post(GET_PATIENT_SHARE_LIVECARE, - onSuccess: (response, statusCode) async { + await baseAppClient.post(GET_PATIENT_SHARE_LIVECARE, onSuccess: (response, statusCode) async { localRes = response['OnlineCheckInAppointments'][0]; }, onFailure: (String error, int statusCode) { throw error; @@ -526,41 +626,129 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } - Future getPatientAppointmentHistory( - bool isActiveAppointment, BuildContext context) async { + Future getOBGyneOrdersList(BuildContext context) async { + Map request; + + if (await this.sharedPref.getObject(USER_PROFILE) != null) { + var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE)); + authUser = data; + } + + Request req = appGlobal.getPublicRequest(); + + request = {"ProjectID": 15, "DeviceTypeID": req.DeviceTypeID, "PatientID": authUser.patientID, "PatientTypeID": authUser.patientType, "PatientType": authUser.patientType}; + + dynamic localRes; + + await baseAppClient.post(GET_OBGYNE_ORDERS_LIST, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } + + Future getOBGyneDoctorsList(int projectID, String setupID, int languageID, BuildContext context) async { + Map request; + + if (await this.sharedPref.getObject(USER_PROFILE) != null) { + var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE)); + authUser = data; + } + + Request req = appGlobal.getPublicRequest(); + + request = { + "ProjectID": projectID, + "SetupID": setupID, + "isDentalAllowedBackend": false, + "DeviceTypeID": req.DeviceTypeID, + "PatientID": authUser.patientID, + "PatientTypeID": authUser.patientType, + "LanguageID": languageID, + "PatientType": authUser.patientType + }; + + dynamic localRes; + + await baseAppClient.post(GET_OBGYNE_DOCTORS_LIST, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } + + Future getPatientAppointmentHistoryWithAppoNo(int appoNo, int languageID) async { + Map request; + request = {"IsActiveAppointment": true, "AppointmentNo": appoNo, "IsComingFromCOC": false, "LanguageID": languageID}; + dynamic localRes; + await baseAppClient.post(GET_PATIENT_APPOINTMENT_HISTORY, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + + return Future.value(localRes); + } + + Future getPatientShareForWalkInAppointment(int clinicID, int projectID, int doctorID) async { + Map request; + request = {"ProjectID": projectID, "ClinicID": clinicID, "DoctorID": doctorID}; + dynamic localRes; + await baseAppClient.post(GET_PATIENT_SHARE_FOR_WALKIN_APPOINTMENT, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + + return Future.value(localRes); + } + + Future canPayForWalkInAppointment(int clinicID, int projectID, int doctorID) async { + Map request; + request = {"ProjectID": projectID, "ClinicID": clinicID, "DoctorID": doctorID, "StartTime": "12:00", "EndTime": "12:00"}; + dynamic localRes; + await baseAppClient.post(CAN_PAY_FOR_FOR_WALKIN_APPOINTMENT, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + + return Future.value(localRes); + } + + Future getPatientAppointmentHistory(bool isActiveAppointment, int languageID, BuildContext context, {bool isForCOC = false, isForUpcomming = false, IsForArrived = false}) async { Map request; 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; } - var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { "IsActiveAppointment": isActiveAppointment, "VersionID": req.VersionID, "Channel": req.Channel, - "LanguageID": languageID == 'ar' ? 1 : 2, "IPAdress": req.IPAdress, "generalid": req.generalid, - "PatientOutSA": 0, "SessionID": "YckwoXhUmWBsnHKEKig", "isDentalAllowedBackend": false, "DeviceTypeID": req.DeviceTypeID, "PatientID": authUser.patientID, - "TokenID": "@dm!n", "PatientTypeID": authUser.patientType, - "PatientType": authUser.patientType + "IsComingFromCOC": isForCOC, + "PatientType": authUser.patientType, + "LanguageID": languageID, + "isForUpcomming": isForUpcomming, + "IsForArrived": IsForArrived }; dynamic localRes; - await baseAppClient.post(GET_PATIENT_APPOINTMENT_HISTORY, - onSuccess: (response, statusCode) async { + await baseAppClient.post(GET_PATIENT_APPOINTMENT_HISTORY, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { throw error; @@ -568,34 +756,28 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } - Future getPatientAppointmentCurfewHistory( - bool isActiveAppointment) async { + Future getPatientAppointmentCurfewHistory(bool isActiveAppointment) async { Map request; - var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + Request req = appGlobal.getPublicRequest(); request = { "IsActiveAppointment": isActiveAppointment, "VersionID": req.VersionID, "Channel": req.Channel, - "LanguageID": languageID == 'ar' ? 1 : 2, "IPAdress": req.IPAdress, "generalid": req.generalid, - "PatientOutSA": 0, "SessionID": "YckwoXhUmWBsnHKEKig", "isDentalAllowedBackend": false, "DeviceTypeID": req.DeviceTypeID, "PatientID": 1231755, - "TokenID": "@dm!n", "PatientTypeID": 1, "PatientType": 1 }; dynamic localRes; - await baseAppClient.post(GET_PATIENT_APPOINTMENT_CURFEW_HISTORY, - onSuccess: (response, statusCode) async { + await baseAppClient.post(GET_PATIENT_APPOINTMENT_CURFEW_HISTORY, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { throw error; @@ -603,18 +785,14 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } - Future confirmAppointment(int appoNo, int clinicID, int projectID, - bool isLiveCare, BuildContext context) async { + Future confirmAppointment(int appoNo, int clinicID, int projectID, bool isLiveCare, BuildContext context) async { 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; } - var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { @@ -625,23 +803,19 @@ class DoctorsListService extends BaseService { "ConfirmationBy": 102, "VersionID": req.VersionID, "Channel": req.Channel, - "LanguageID": languageID == 'ar' ? 1 : 2, "IPAdress": req.IPAdress, "generalid": req.generalid, - "PatientOutSA": 0, "SessionID": "YckwoXhUmWBsnHKEKig", "isDentalAllowedBackend": false, "DeviceTypeID": req.DeviceTypeID, "PatientID": authUser.patientID, - "TokenID": "@dm!n", "PatientTypeID": authUser.patientType, "PatientType": authUser.patientType }; dynamic localRes; - await baseAppClient.post(CONFIRM_APPOINTMENT, - onSuccess: (response, statusCode) async { + await baseAppClient.post(CONFIRM_APPOINTMENT, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { throw error; @@ -649,41 +823,38 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } - Future insertVIDARequest(int appoNo, int clinicID, int projectID, - int serviceID, int docID, BuildContext context) async { + Future insertVIDARequest(int appoNo, int clinicID, int projectID, int serviceID, int docID, String appoDate, String clientRequestID, int languageID, BuildContext context) async { Map request; if (await this.sharedPref.getObject(USER_PROFILE) != null) { - var data = AuthenticatedUser.fromJson( - await this.sharedPref.getObject(USER_PROFILE)); + var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE)); authUser = data; } deviceToken = await sharedPref.getString(PUSH_TOKEN); - if (await this.sharedPref.getDouble(USER_LAT) != null && - await this.sharedPref.getDouble(USER_LONG) != null) { + if (await this.sharedPref.getDouble(USER_LAT) != null && await this.sharedPref.getDouble(USER_LONG) != null) { lat = await this.sharedPref.getDouble(USER_LAT); long = await this.sharedPref.getDouble(USER_LONG); } - var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { "AppointmentNo": appoNo, + "AppointmentDate": appoDate, + "ClientRequestID": clientRequestID, "ClinicID": clinicID, "ProjectID": projectID, "ServiceID": serviceID, "AcceptedBy": docID, + "IsFlutter": true, "DeviceToken": deviceToken, "Latitude": lat, "Longitude": long, "DeviceType": req.DeviceType, "VersionID": req.VersionID, "Channel": req.Channel, - "LanguageID": languageID == 'ar' ? 1 : 2, "IPAdress": req.IPAdress, "generalid": req.generalid, "PatientOutSA": authUser.outSA, @@ -691,13 +862,15 @@ class DoctorsListService extends BaseService { "DeviceTypeID": req.DeviceTypeID, "PatientID": authUser.patientID, "PatientTypeID": authUser.patientType, - "PatientType": authUser.patientType + "PatientType": authUser.patientType, + "VoipToken": await sharedPref.getString(ONESIGNAL_APNS_TOKEN), + "LanguageID": languageID, + "IsVoip": Platform.isIOS ? true : false }; dynamic localRes; - await baseAppClient.post(INSERT_VIDA_REQUEST, - onSuccess: (response, statusCode) async { + await baseAppClient.post(INSERT_VIDA_REQUEST, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { throw error; @@ -705,34 +878,30 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } - Future cancelAppointment( - AppoitmentAllHistoryResultList appo, BuildContext context) async { + Future cancelAppointment(AppoitmentAllHistoryResultList appo, BuildContext context, {bool isReschedule = false}) async { 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; } - var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { "AppointmentID": appo.appointmentNo, "ClinicID": appo.clinicID, "ProjectID": appo.projectID, + "CancelToReschadual": isReschedule, "EndTime": appo.endTime, "StartTime": appo.startTime, "DoctorID": appo.doctorID, "IsForLiveCare": appo.isLiveCareAppointment, "OriginalClinicID": appo.originalClinicID, "OriginalProjectID": appo.originalProjectID, - "StrAppointmentDate": DateUtil.getDateFormatted(appo.appointmentDate), + "StrAppointmentDate": DateUtil.getDateFormatted(appo.appointmentDate!), "VersionID": req.VersionID, "Channel": req.Channel, - "LanguageID": languageID == 'ar' ? 1 : 2, "IPAdress": req.IPAdress, "generalid": req.generalid, "PatientOutSA": authUser.outSA, @@ -740,15 +909,14 @@ class DoctorsListService extends BaseService { "isDentalAllowedBackend": false, "DeviceTypeID": req.DeviceTypeID, "PatientID": authUser.patientID, - "TokenID": "@dm!n", "PatientTypeID": authUser.patientType, + // "LanguageID": 1, "PatientType": authUser.patientType }; dynamic localRes; - await baseAppClient.post(CANCEL_APPOINTMENT, - onSuccess: (response, statusCode) async { + await baseAppClient.post(CANCEL_APPOINTMENT, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { throw error; @@ -756,18 +924,14 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } - Future generateAppointmentQR( - PatientShareResponse patientShareResponse, BuildContext context) async { + Future generateAppointmentQR(PatientShareResponse patientShareResponse, BuildContext context) async { 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; } - var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { @@ -777,7 +941,6 @@ class DoctorsListService extends BaseService { "IsFollowup": patientShareResponse.isFollowup, "VersionID": req.VersionID, "Channel": req.Channel, - "LanguageID": languageID == 'ar' ? 1 : 2, "IPAdress": req.IPAdress, "generalid": req.generalid, "PatientOutSA": authUser.outSA, @@ -785,15 +948,14 @@ class DoctorsListService extends BaseService { "isDentalAllowedBackend": false, "DeviceTypeID": req.DeviceTypeID, "PatientID": authUser.patientID, - "TokenID": "@dm!n", "PatientTypeID": authUser.patientType, + "LanguageID": 1, "PatientType": authUser.patientType }; dynamic localRes; - await baseAppClient.post(GENERATE_QR_APPOINTMENT, - onSuccess: (response, statusCode) async { + await baseAppClient.post(GENERATE_QR_APPOINTMENT, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { throw error; @@ -801,25 +963,14 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } - Future sendAppointmentQREmail( - String to, - String appoDate, - String appoNo, - String docName, - String projName, - String QR, - String speciality, - BuildContext context) async { + Future sendAppointmentQREmail(String to, String appoDate, String appoNo, String docName, String projName, String QR, String speciality, BuildContext context) async { 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; } - var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { @@ -832,7 +983,6 @@ class DoctorsListService extends BaseService { "To": to, "VersionID": req.VersionID, "Channel": req.Channel, - "LanguageID": languageID == 'ar' ? 1 : 2, "IPAdress": req.IPAdress, "generalid": req.generalid, "PatientOutSA": authUser.outSA, @@ -840,15 +990,13 @@ class DoctorsListService extends BaseService { "isDentalAllowedBackend": false, "DeviceTypeID": req.DeviceTypeID, "PatientID": authUser.patientID, - "TokenID": "@dm!n", "PatientTypeID": authUser.patientType, "PatientType": authUser.patientType }; dynamic localRes; - await baseAppClient.post(EMAIL_QR_APPOINTMENT, - onSuccess: (response, statusCode) async { + await baseAppClient.post(EMAIL_QR_APPOINTMENT, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { throw error; @@ -856,22 +1004,19 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } - Future checkPaymentStatus( - String transactionID, BuildContext context) async { + Future checkPaymentStatus(String transactionID, bool isPharma, BuildContext context) async { 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; } - var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + Request req = appGlobal.getPublicRequest(); request = { "ClientRequestID": transactionID, + "IsPharmacy": isPharma, "VersionID": req.VersionID, "Channel": req.Channel, - "LanguageID": languageID == 'ar' ? 1 : 2, "IPAdress": req.IPAdress, "generalid": req.generalid, "PatientOutSA": authUser.outSA, @@ -879,13 +1024,12 @@ class DoctorsListService extends BaseService { "isDentalAllowedBackend": false, "DeviceTypeID": req.DeviceTypeID, "PatientID": authUser.patientID, - "TokenID": "@dm!n", "PatientTypeID": authUser.patientType, + "LanguageID": 1, "PatientType": authUser.patientType }; dynamic localRes; - await baseAppClient.post(CHECK_PAYMENT_STATUS, - onSuccess: (response, statusCode) async { + await baseAppClient.post(CHECK_PAYMENT_STATUS, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { throw error; @@ -893,27 +1037,33 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } - Future addAdvancedNumberRequest( - String advanceNumber, - String paymentReference, - dynamic appointmentID, - BuildContext context) async { + Future getTamaraPaymentStatus(String orderID) async { + hasError = false; + dynamic localRes; + await baseAppClient.get(GET_TAMARA_PAYMENT_STATUS + "$orderID", isRCService: false, isExternal: true, onSuccess: (dynamic response, int statusCode) { + localRes = response; + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }); + return Future.value(localRes); + } + + Future addAdvancedNumberRequest(String advanceNumber, String paymentReference, dynamic appointmentID, BuildContext context) async { 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; } - var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + Request req = appGlobal.getPublicRequest(); request = { "AdvanceNumber": advanceNumber, + "AdvanceNumber_VP": advanceNumber, "PaymentReferenceNumber": paymentReference, "AppointmentID": appointmentID, "VersionID": req.VersionID, "Channel": req.Channel, - "LanguageID": languageID == 'ar' ? 1 : 2, "IPAdress": req.IPAdress, "generalid": req.generalid, "PatientOutSA": authUser.outSA, @@ -921,30 +1071,26 @@ class DoctorsListService extends BaseService { "isDentalAllowedBackend": false, "DeviceTypeID": req.DeviceTypeID, "PatientID": authUser.patientID, - "TokenID": "@dm!n", "PatientTypeID": authUser.patientType, + "LanguageID": 1, "PatientType": authUser.patientType }; dynamic localRes; - await baseAppClient.post(ADD_ADVANCE_NUMBER_REQUEST, - onSuccess: (response, statusCode) async { + await baseAppClient.post(ADD_ADVANCE_NUMBER_REQUEST, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { throw error; - }, body: request); + }, body: request, isAllowAny: true); return Future.value(localRes); } - Future addVIDARequest(String advanceNumber, - String paymentReference, dynamic apptData, BuildContext context) async { + Future addVIDARequest(String advanceNumber, String paymentReference, dynamic apptData, BuildContext context) async { 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; } - var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + Request req = appGlobal.getPublicRequest(); request = { "AdvanceNumber": advanceNumber, @@ -954,13 +1100,11 @@ class DoctorsListService extends BaseService { "ServiceID": apptData.ServiceID, "ProjectID": apptData.ProjectID, "ClinicID": apptData.ClinicID, - "ClientRequestID": Utils.getAppointmentTransID( - apptData.ProjectID, apptData.ClinicID, apptData.AppointmentNo), + "ClientRequestID": Utils.getAppointmentTransID(apptData.ProjectID, apptData.ClinicID, apptData.AppointmentNo), "AppointmentDate": apptData.AppointmentDate, "DeviceType": Platform.isIOS ? "iOS" : "Android", "VersionID": req.VersionID, "Channel": req.Channel, - "LanguageID": languageID == 'ar' ? 1 : 2, "IPAdress": req.IPAdress, "generalid": req.generalid, "PatientOutSA": authUser.outSA, @@ -968,13 +1112,16 @@ class DoctorsListService extends BaseService { "isDentalAllowedBackend": false, "DeviceTypeID": req.DeviceTypeID, "PatientID": authUser.patientID, - "TokenID": "@dm!n", "PatientTypeID": authUser.patientType, - "PatientType": authUser.patientType + "PatientType": authUser.patientType, + "DeviceToken": await sharedPref.getString(PUSH_TOKEN), + "VoipToken": await sharedPref.getString(ONESIGNAL_APNS_TOKEN), + "LanguageID": 1, + "IsVoip": Platform.isIOS ? true : false }; // request.DeviceToken = this.cs.sharedService.getSharedData(AuthenticationService.DEVICE_TOKEN, false); - // request.Latitude = this.cs.sharedService.getSharedData('userLat', false); + // request.Latitude = this.cs.szharedService.getSharedData('userLat', false); // request.Longitude = this.cs.sharedService.getSharedData('userLong', false); // request.ServiceID = apptData.ServiceID; // request.ProjectID = apptData.ProjectID; @@ -984,8 +1131,36 @@ class DoctorsListService extends BaseService { // request.DeviceType = this.getDeviceType(); // request.VoipToken = this.platform.is('ios') ? this.cs.sharedService.getSharedData(AuthenticationService.APNS_TOKEN, false) : ""; dynamic localRes; - await baseAppClient.post(ADD_VIDA_REQUEST, - onSuccess: (response, statusCode) async { + await baseAppClient.post(ADD_VIDA_REQUEST, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } + + Future autoGenerateAncillaryOrdersInvoice(dynamic orderNo, int projectID, dynamic appointmentID, List selectedProcListAPI, int languageID, BuildContext context) async { + Map request; + if (await this.sharedPref.getObject(USER_PROFILE) != null) { + var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE)); + authUser = data; + } + + List procedureOrderIDs = []; + + selectedProcListAPI.forEach((element) { + procedureOrderIDs.add(element["ProcedureID"]); + }); + + request = { + "LanguageID": languageID, + "RequestAncillaryOrderInvoice": [ + {"MemberID": 102, "ProjectID": projectID, "AppointmentNo": appointmentID, "OrderNo": orderNo, "AncillaryOrderInvoiceProcList": selectedProcListAPI} + ], + "ProcedureOrderIds": procedureOrderIDs + }; + dynamic localRes; + await baseAppClient.post(GENERATE_ANCILLARY_ORDERS_INVOICE, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { throw error; @@ -993,15 +1168,13 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } - Future isAllowedToAskDoctor(int docID, BuildContext context) async { + Future isAllowedToAskDoctor(int docID, int languageID, BuildContext context) async { Map request; if (await this.sharedPref.getObject(USER_PROFILE) != null) { - var data = AuthenticatedUser.fromJson( - await this.sharedPref.getObject(USER_PROFILE)); + var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE)); authUser = data; } - var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + Request req = appGlobal.getPublicRequest(); request = { "IsForAskYourDoctor": true, @@ -1009,9 +1182,9 @@ class DoctorsListService extends BaseService { "Top": 25, "beforeDays": 15, "exludType": 4, + "LanguageID": languageID, "VersionID": req.VersionID, "Channel": req.Channel, - "LanguageID": languageID == 'ar' ? 1 : 2, "IPAdress": req.IPAdress, "generalid": req.generalid, "PatientOutSA": authUser.outSA, @@ -1019,14 +1192,12 @@ class DoctorsListService extends BaseService { "isDentalAllowedBackend": false, "DeviceTypeID": req.DeviceTypeID, "PatientID": authUser.patientID, - "TokenID": "@dm!n", "PatientTypeID": authUser.patientType, "PatientType": authUser.patientType }; dynamic localRes; - await baseAppClient.post(IS_ALLOW_ASK_DOCTOR, - onSuccess: (response, statusCode) async { + await baseAppClient.post(IS_ALLOW_ASK_DOCTOR, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { throw error; @@ -1034,20 +1205,17 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } - Future getCallRequestType(BuildContext context) async { + Future getCallRequestType(int languageID, BuildContext context) async { Map request; if (await this.sharedPref.getObject(USER_PROFILE) != null) { - var data = AuthenticatedUser.fromJson( - await this.sharedPref.getObject(USER_PROFILE)); + var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE)); authUser = data; } - var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + Request req = appGlobal.getPublicRequest(); request = { "VersionID": req.VersionID, "Channel": req.Channel, - "LanguageID": languageID == 'ar' ? 1 : 2, "IPAdress": req.IPAdress, "generalid": req.generalid, "PatientOutSA": authUser.outSA, @@ -1055,14 +1223,13 @@ class DoctorsListService extends BaseService { "isDentalAllowedBackend": false, "DeviceTypeID": req.DeviceTypeID, "PatientID": authUser.patientID, - "TokenID": "@dm!n", "PatientTypeID": authUser.patientType, + "LanguageID": languageID, "PatientType": authUser.patientType }; dynamic localRes; - await baseAppClient.post(GET_CALL_REQUEST_TYPE, - onSuccess: (response, statusCode) async { + await baseAppClient.post(GET_CALL_REQUEST_TYPE, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { throw error; @@ -1070,45 +1237,34 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } - Future sendAskDocCallRequest(AppoitmentAllHistoryResultList appo, - String requestType, BuildContext context) async { + Future sendAskDocCallRequest(AppoitmentAllHistoryResultList appo, String requestType, int languageID, BuildContext context) async { Map request; if (await this.sharedPref.getObject(USER_PROFILE) != null) { - var data = AuthenticatedUser.fromJson( - await this.sharedPref.getObject(USER_PROFILE)); + var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE)); authUser = data; } - var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + Request req = appGlobal.getPublicRequest(); request = { "ProjectID": appo.projectID, "SetupID": appo.setupID, "DoctorID": appo.doctorID, + "ClinicID": appo.clinicID, "RequestType": requestType, "RequestTypeID": requestType, "PatientMobileNumber": authUser.mobileNumber, "IsMessageSent": false, - "RequestDate": - DateUtil.getYearMonthDayHourMinSecDateFormatted(DateTime.now()) - .split(" ")[0], - "RequestTime": - DateUtil.getYearMonthDayHourMinSecDateFormatted(DateTime.now()) - .split(" ")[1], + "RequestDate": DateUtil.getYearMonthDayHourMinSecDateFormatted(DateTime.now()).split(" ")[0], + "RequestTime": DateUtil.getYearMonthDayHourMinSecDateFormatted(DateTime.now()).split(" ")[1], "Remarks": "", "Status": 1, "CreatedBy": 102, - "CreatedOn": - DateUtil.getYearMonthDayHourMinSecDateFormatted(DateTime.now()) - .split(" ")[0], + "CreatedOn": DateUtil.getYearMonthDayHourMinSecDateFormatted(DateTime.now()).split(" ")[0], "EditedBy": 102, - "EditedOn": - DateUtil.getYearMonthDayHourMinSecDateFormatted(DateTime.now()) - .split(" ")[0], + "EditedOn": DateUtil.getYearMonthDayHourMinSecDateFormatted(DateTime.now()).split(" ")[0], "VersionID": req.VersionID, "Channel": req.Channel, - "LanguageID": languageID == 'ar' ? 1 : 2, "IPAdress": req.IPAdress, "generalid": req.generalid, "PatientOutSA": authUser.outSA, @@ -1116,14 +1272,13 @@ class DoctorsListService extends BaseService { "isDentalAllowedBackend": false, "DeviceTypeID": req.DeviceTypeID, "PatientID": authUser.patientID, - "TokenID": "@dm!n", "PatientTypeID": authUser.patientType, + "LanguageID": languageID, "PatientType": authUser.patientType }; dynamic localRes; - await baseAppClient.post(SEND_CALL_REQUEST, - onSuccess: (response, statusCode) async { + await baseAppClient.post(SEND_CALL_REQUEST, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { throw error; @@ -1131,21 +1286,19 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } - Future getPatientRadOrders(String appoNo, BuildContext context) async { + Future getPatientRadOrders(String appoNo, int projectID, int languageID, BuildContext context) async { Map request; if (await this.sharedPref.getObject(USER_PROFILE) != null) { - var data = AuthenticatedUser.fromJson( - await this.sharedPref.getObject(USER_PROFILE)); + var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE)); authUser = data; } - var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + Request req = appGlobal.getPublicRequest(); request = { "AppointmentNo": appoNo, + "ProjectID": projectID, "VersionID": req.VersionID, "Channel": req.Channel, - "LanguageID": languageID == 'ar' ? 1 : 2, "IPAdress": req.IPAdress, "generalid": req.generalid, "PatientOutSA": authUser.outSA, @@ -1153,14 +1306,13 @@ class DoctorsListService extends BaseService { "isDentalAllowedBackend": false, "DeviceTypeID": req.DeviceTypeID, "PatientID": authUser.patientID, - "TokenID": "@dm!n", "PatientTypeID": authUser.patientType, + "LanguageID": languageID, "PatientType": authUser.patientType }; dynamic localRes; - await baseAppClient.post(GET_PATIENT_ORDERS, - onSuccess: (response, statusCode) async { + await baseAppClient.post(GET_PATIENT_ORDERS, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { throw error; @@ -1168,16 +1320,13 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } - Future getPatientLabOrdersByAppoNo(dynamic appoNo, dynamic projID, - dynamic clinicID, BuildContext context) async { + Future getPatientLabOrdersByAppoNo(dynamic appoNo, dynamic projID, dynamic clinicID, int languageID, BuildContext context) async { Map request; if (await this.sharedPref.getObject(USER_PROFILE) != null) { - var data = AuthenticatedUser.fromJson( - await this.sharedPref.getObject(USER_PROFILE)); + var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE)); authUser = data; } - var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + Request req = appGlobal.getPublicRequest(); request = { "AppointmentNo": appoNo, @@ -1185,7 +1334,6 @@ class DoctorsListService extends BaseService { "ClinicID": clinicID, "VersionID": req.VersionID, "Channel": req.Channel, - "LanguageID": languageID == 'ar' ? 1 : 2, "IPAdress": req.IPAdress, "generalid": req.generalid, "PatientOutSA": authUser.outSA, @@ -1193,14 +1341,13 @@ class DoctorsListService extends BaseService { "isDentalAllowedBackend": false, "DeviceTypeID": req.DeviceTypeID, "PatientID": authUser.patientID, - "TokenID": "@dm!n", "PatientTypeID": authUser.patientType, + "LanguageID": languageID, "PatientType": authUser.patientType }; dynamic localRes; - await baseAppClient.post(GET_PATIENT_LAB_ORDERS_BY_APPOINTMENT, - onSuccess: (response, statusCode) async { + await baseAppClient.post(GET_PATIENT_LAB_ORDERS_BY_APPOINTMENT, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { throw error; @@ -1208,16 +1355,13 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } - Future getPatientPrescriptionReports( - AppoitmentAllHistoryResultList appo, BuildContext context) async { + Future getPatientPrescriptionReports(AppoitmentAllHistoryResultList appo, int languageID, BuildContext context) async { Map request; if (await this.sharedPref.getObject(USER_PROFILE) != null) { - var data = AuthenticatedUser.fromJson( - await this.sharedPref.getObject(USER_PROFILE)); + var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE)); authUser = data; } - var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + Request req = appGlobal.getPublicRequest(); request = { "AppointmentNo": appo.appointmentNo, @@ -1227,7 +1371,6 @@ class DoctorsListService extends BaseService { "VersionID": req.VersionID, "SetupID": appo.setupID, "Channel": req.Channel, - "LanguageID": languageID == 'ar' ? 1 : 2, "IPAdress": req.IPAdress, "generalid": req.generalid, "PatientOutSA": authUser.outSA, @@ -1235,14 +1378,13 @@ class DoctorsListService extends BaseService { "isDentalAllowedBackend": false, "DeviceTypeID": req.DeviceTypeID, "PatientID": authUser.patientID, - "TokenID": "@dm!n", "PatientTypeID": authUser.patientType, + "LanguageID": languageID, "PatientType": authUser.patientType }; dynamic localRes; - await baseAppClient.post(GET_PRESCRIPTION_REPORT_ENH, - onSuccess: (response, statusCode) async { + await baseAppClient.post(GET_PRESCRIPTION_REPORT_ENH, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { throw error; @@ -1250,16 +1392,13 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } - Future sendPrescriptionEmail(String appoDate, String setupId, - dynamic prescriptionReportEnhList, BuildContext context) async { + Future sendPrescriptionEmail(String appoDate, String setupId, int languageID, dynamic prescriptionReportEnhList, bool isDownload, BuildContext context) async { 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; } - var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + Request req = appGlobal.getPublicRequest(); request = { "AppointmentDate": appoDate, @@ -1267,12 +1406,11 @@ class DoctorsListService extends BaseService { "ListPrescriptions": prescriptionReportEnhList, "PatientIditificationNum": authUser.patientIdentificationNo, "PatientMobileNumber": authUser.mobileNumber, - "PatientName": authUser.firstName + " " + authUser.lastName, + "PatientName": authUser.firstName! + " " + authUser.lastName!, "To": authUser.emailAddress, "SetupID": setupId, "VersionID": req.VersionID, "Channel": req.Channel, - "LanguageID": languageID == 'ar' ? 1 : 2, "IPAdress": req.IPAdress, "generalid": req.generalid, "PatientOutSA": authUser.outSA, @@ -1280,14 +1418,15 @@ class DoctorsListService extends BaseService { "isDentalAllowedBackend": false, "DeviceTypeID": req.DeviceTypeID, "PatientID": authUser.patientID, - "TokenID": "@dm!n", "PatientTypeID": authUser.patientType, - "PatientType": authUser.patientType + "LanguageID": authUser.patientType, + "PatientType": authUser.patientType, + "IsDownload": isDownload, + }; dynamic localRes; - await baseAppClient.post(SEND_PRESCRIPTION_EMAIL, - onSuccess: (response, statusCode) async { + await baseAppClient.post(SEND_PRESCRIPTION_EMAIL, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { throw error; @@ -1295,21 +1434,13 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } - Future createAdvancePayment( - AppoitmentAllHistoryResultList appo, - String projectID, - double payedAmount, - String paymentReference, - String paymentMethodName, - BuildContext context) async { + Future createAdvancePayment(AppoitmentAllHistoryResultList appo, String projectID, double payedAmount, String paymentReference, String paymentMethodName, BuildContext context) async { 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; } - var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + Request req = appGlobal.getPublicRequest(); request = { "ProjectID": projectID, @@ -1317,11 +1448,7 @@ class DoctorsListService extends BaseService { "AppointmentNo": appo != null ? appo.appointmentNo.toString() : "0", "PaymentMethodName": paymentMethodName, "PaymentAmount": payedAmount == 0 ? "0" : payedAmount.toString(), - "PaymentDate": payedAmount == 0 - ? "" - : "/Date(" + - DateTime.now().millisecondsSinceEpoch.toString() + - ")/", + "PaymentDate": payedAmount == 0 ? "" : "/Date(" + DateTime.now().millisecondsSinceEpoch.toString() + ")/", "PaymentReferenceNumber": payedAmount == 0 ? "" : paymentReference, "ProjectID": appo != null ? appo.projectID.toString() : projectID, "PatientID": authUser.patientID, @@ -1331,20 +1458,18 @@ class DoctorsListService extends BaseService { }, "VersionID": req.VersionID, "Channel": req.Channel, - "LanguageID": languageID == 'ar' ? 1 : 2, "IPAdress": req.IPAdress, "generalid": req.generalid, "PatientOutSA": authUser.outSA, "SessionID": "YckwoXhUmWBsnHKEKig", "isDentalAllowedBackend": false, "PatientID": authUser.patientID, - "TokenID": "@dm!n", "PatientTypeID": authUser.patientType, + "LanguageID": 1, "PatientType": authUser.patientType }; dynamic localRes; - await baseAppClient.post(CREATE_ADVANCE_PAYMENT, - onSuccess: (response, statusCode) async { + await baseAppClient.post(CREATE_ADVANCE_PAYMENT, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { throw error; @@ -1352,24 +1477,15 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } - Future HIS_createAdvancePayment( - AppoitmentAllHistoryResultList appo, - String projectID, - double payedAmount, - String paymentReference, - String paymentMethodName, - dynamic patientType, - String patientName, - dynamic patientID, - BuildContext context) async { + Future HIS_createAdvancePayment(AppoitmentAllHistoryResultList appo, String projectID, double payedAmount, String paymentReference, String paymentMethodName, dynamic patientType, + String patientName, dynamic patientID, BuildContext context, + {bool isAncillaryOrder = false, int clinicID = 0}) async { 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; } - var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + Request req = appGlobal.getPublicRequest(); request = { @@ -1381,26 +1497,66 @@ class DoctorsListService extends BaseService { "AccountID": patientID, "PaymentAmount": payedAmount, "NationalityID": null, - "DepositorName": authUser.firstName + " " + authUser.lastName, + "DepositorName": authUser.firstName! + " " + authUser.lastName!, "CreatedBy": 3, "PaymentMethodName": paymentMethodName, "PaymentReference": paymentReference, "PaymentMethod": paymentMethodName, "VersionID": req.VersionID, "Channel": req.Channel, - "LanguageID": languageID == 'ar' ? 1 : 2, + "LanguageID": 1, "IPAdress": req.IPAdress, "generalid": req.generalid, "PatientOutSA": authUser.outSA, "SessionID": "YckwoXhUmWBsnHKEKig", "isDentalAllowedBackend": false, - "TokenID": "@dm!n", "PatientTypeID": patientType, + "IsAncillaryOrder": isAncillaryOrder, + // "AncillaryProcedureList": ancillaryOrdersProcedureList, "PatientType": patientType }; dynamic localRes; - await baseAppClient.post(HIS_CREATE_ADVANCE_PAYMENT, - onSuccess: (response, statusCode) async { + await baseAppClient.post(HIS_CREATE_ADVANCE_PAYMENT, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } + + Future ER_createAdvancePayment(AppoitmentAllHistoryResultList appo, String projectID, double payedAmount, String paymentReference, String paymentMethodName, BuildContext context) async { + Map request; + if (await this.sharedPref.getObject(USER_PROFILE) != null) { + var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE)); + authUser = data; + } + + Request req = appGlobal.getPublicRequest(); + + request = { + // "VersionID": req.VersionID, + // "Channel": req.Channel, + // "IPAdress": req.IPAdress, + // "generalid": req.generalid, + // "PatientOutSA": authUser.outSA, + // "PatientTypeID": authUser.patientType, + "LanguageID": 1, + "ERAdvanceAmount": { + "ProjectId": projectID, + "PatientId": authUser.patientID, + "ClinicId": 10, + "DepositorName": authUser.firstName! + " " + authUser.lastName!, + "MemberId": authUser.patientID, + "NationalityID": authUser.nationalityID, + "PaymentAmount": payedAmount, + "PaymentDate": DateUtil.convertDateToString(DateTime.now()), + "PaymentMethodName": paymentMethodName, + "PaymentReferenceNumber": paymentReference, + "SourceType": 2 + } + }; + dynamic localRes; + await baseAppClient.post(ER_CREATE_ADVANCE_PAYMENT, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { throw error; @@ -1408,23 +1564,64 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } - Future getPatientHealthDataStats( - int medCategoryId, int medCategoryStsId, BuildContext context) async { + Future ER_InsertEROnlinePaymentDetails( + AppoitmentAllHistoryResultList appo, String projectID, double payedAmount, String paymentReference, String paymentMethodName, BuildContext context) async { 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; } - var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + + Request req = appGlobal.getPublicRequest(); + + request = { + "VersionID": req.VersionID, + "Channel": req.Channel, + "IPAdress": req.IPAdress, + "generalid": req.generalid, + "PatientOutSA": authUser.outSA, + "PatientTypeID": authUser.patientType, + "LanguageID": 1, + "EROnlineCheckinPaymentDetails": { + "CheckinDate": DateUtil.convertDateToString(DateTime.now()), + "ExpectedArrivalTime": DateUtil.convertDateToString(DateTime.now()), + "ProjectId": projectID, + "PatientId": authUser.patientID, + "ClinicId": 10, + "FormId": 15, + "DepositorName": authUser.firstName! + " " + authUser.lastName!, + "MemberId": authUser.patientID, + "NationalityID": authUser.nationalityID, + "PaymentAmount": payedAmount, + "PaymentDate": DateUtil.convertDateToString(DateTime.now()), + "PaymentMethodName": paymentMethodName, + "PaymentReferenceNumber": paymentReference, + "TriageScore": await sharedPref.getInt(ER_CHECKIN_RISK_SCORE) + } + }; + dynamic localRes; + await baseAppClient.post(ER_INSERT_ADVANCE_PAYMENT, onSuccess: (response, statusCode) async { + localRes = response; + sharedPref.remove(ER_CHECKIN_RISK_SCORE); + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } + + Future getPatientHealthDataStats(int medCategoryId, int medCategoryStsId, BuildContext context) async { + Map request; + if (await this.sharedPref.getObject(USER_PROFILE) != null) { + var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE)); + authUser = data; + } + Request req = appGlobal.getPublicRequest(); request = { "MedCategoryID": medCategoryId, "MedGetStsID": medCategoryStsId, "VersionID": req.VersionID, "Channel": req.Channel, - "LanguageID": languageID == 'ar' ? 1 : 2, "IPAdress": req.IPAdress, "generalid": req.generalid, "PatientOutSA": authUser.outSA, @@ -1432,17 +1629,373 @@ class DoctorsListService extends BaseService { "isDentalAllowedBackend": false, "DeviceTypeID": req.DeviceTypeID, "PatientID": authUser.patientID, - "TokenID": "@dm!n", "PatientTypeID": authUser.patientType, "PatientType": authUser.patientType }; dynamic localRes; - await baseAppClient.post(GET_PATIENT_HEALTH_STATS, - onSuccess: (response, statusCode) async { + await baseAppClient.post(GET_PATIENT_HEALTH_STATS, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } + + Future sendCheckinNfcRequest(int appointmentNo, String nfcCode, int projectId, int checkInBy, int clinicID, BuildContext context) async { + Map request; + + request = {"AppointmentNo": appointmentNo, "NFC_Code": nfcCode, "ProjectID": projectId, "ClinicID": clinicID, "CheckinBy": checkInBy}; + dynamic localRes; + await baseAppClient.post(SEND_CHECK_IN_NFC_REQUEST, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } + + Future checkScannedNFCAndQRCode(String nfcCode, int projectId) async { + Map request; + + request = {"NFC_Code": nfcCode, "ProjectID": projectId}; + dynamic localRes; + await baseAppClient.post(CHECK_SCANNED_NFC_QR_CODE, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } + + Future checkIfHasDentalPlan(int projectID, BuildContext context) async { + Map request; + + request = { + "ProjectID": projectID, + "LanguageID": 1, + }; + dynamic localRes; + await baseAppClient.post(HAS_DENTAL_PLAN, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } + + Future getTamaraPaymentDetails(BuildContext context) async { + dynamic localRes; + await baseAppClient.get(GET_TAMARA_PLAN, isExternal: true, onSuccess: (response, statusCode) async { + localRes = response[0]; + }, onFailure: (String error, int statusCode) { + throw error; + }); + return localRes; + } + + Future callPayfortApplePayAPI(ApplePayRequest applePayRequest, BuildContext context) async { + Map request; + + request = { + "currency": applePayRequest.currency, + "language": applePayRequest.language, + "customername": applePayRequest.customername, + "customer_email": applePayRequest.customerEmail, + "orderdescription": applePayRequest.orderdescription, + "live_serviceid": applePayRequest.liveServiceid, + "longitude": applePayRequest.longitude, + "latitude": applePayRequest.latitude, + "devicetoken": applePayRequest.devicetoken, + "clientrequestid": applePayRequest.clientrequestid, + "projectid": applePayRequest.projectid, + "serviceid": applePayRequest.serviceid, + "patientid": applePayRequest.patientid, + "Amount": applePayRequest.amount, + "apple_data": applePayRequest.appleData, + "apple_signature": applePayRequest.appleSignature, + "apple_header": { + "apple_applicationData": "76a9a9cb2d9811e8de56d8e7713601bfa6acda3d488b1cf03b9b115bc3ff12b4", + "apple_ephemeralPublicKey": applePayRequest.appleHeader!.appleEphemeralPublicKey!, + "apple_publicKeyHash": applePayRequest.appleHeader!.applePublicKeyHash!, + "apple_transactionId": applePayRequest.appleHeader!.appleTransactionId + }, + "apple_paymentMethod": { + "apple_displayName": applePayRequest.applePaymentMethod!.appleDisplayName, + "apple_network": applePayRequest.applePaymentMethod!.appleNetwork, + "apple_type": applePayRequest.applePaymentMethod!.appleType + } + }; + dynamic localRes; + await baseAppClient.post(MyInAppBrowser.APPLE_PAY_PAYFORT_URL, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request, isExternal: true); + return Future.value(localRes); + } + + Future getLaserBodyPartsList(int laserCategoryID, int projectID, int languageID) async { + Map request; + + request = { + "LaserCategoryID": laserCategoryID, + "ProjectID": projectID, + "LanguageID": languageID, + }; + dynamic localRes; + await baseAppClient.post(LASER_BODY_PARTS, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } + + Future insertCovidQuestionnaire(List qa, int projectID, int testTypeEnum, int languageID, int testProcedureEnum) async { + Map request; + + request = { + "ProjectID": projectID, + "LanguageID": languageID, + "IsForTravel": qa[0]['ans'].toString(), + "IsComingOutSA": qa[1]['ans'].toString(), + "IsFeverCurrently": qa[2]['ans'].toString(), + "IsFeverLast2Week": qa[3]['ans'].toString(), + "IsSorethroat": qa[4]['ans'].toString(), + "IsRunnyNose": qa[5]['ans'].toString(), + "IsCough": qa[6]['ans'].toString(), + "IsShortnessBreath": qa[7]['ans'].toString(), + "IsNausea": qa[8]['ans'].toString(), + "IsVomiting": qa[9]['ans'].toString(), + "IsHeadache": qa[10]['ans'].toString(), + "IsMusclePain": qa[11]['ans'].toString(), + "IsJoinPain": qa[12]['ans'].toString(), + "IsDiarrhea": qa[13]['ans'].toString(), + "TestTypeEnum": testTypeEnum, + "TestProcedureEnum": testProcedureEnum + }; + + dynamic localRes; + await baseAppClient.post(INSERT_COVID_QUESTIONNAIRE, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } + + Future updateCovidQuestionnaire(String appoNo, int projectID, int testTypeEnum, int testProcedureEnum) async { + Map request; + + request = {"AppointmentNo": appoNo, "ProjectID": projectID, "TestTypeEnum": testTypeEnum, "TestProcedureEnum": testProcedureEnum}; + + dynamic localRes; + await baseAppClient.post(UPDATE_COVID_QUESTIONNAIRE, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + + return Future.value(localRes); + } + + Future updateObGyneAppointment(int episodeID, int appointmentNo, int orderNo, String procedureId, int lineItemNo, int uniqueRowID, int languageID) async { + Map request; + + request = { + "EpisodeID": episodeID, + "LanguageID": languageID, + "AppointmentNo": appointmentNo, + "OrderNo": orderNo, + "ProcedureId": procedureId, + "ProcedureAppointmentNo": appointmentNo, + "LineItemNo": lineItemNo, + "UniqueRowID": uniqueRowID + }; + + dynamic localRes; + await baseAppClient.post(OBGYNE_PROCEDURE_UPDATE, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + + return Future.value(localRes); + } + + Future getRRTProcedures(int projectID, int languageID) async { + Map request; + + request = {"ProjectID": projectID, "LanguageID": languageID}; + + dynamic localRes; + await baseAppClient.post(GET_RRT_PROCEDURE_LIST, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + + return Future.value(localRes); + } + + Future updateTamaraRequestStatus(String responseMessage, String status, String clientRequestID, String tamaraOrderID, num selectedInstallments) async { + Map request = { + "Response_Message": responseMessage, + "ClientRequestID": clientRequestID, + "Status": status, + "FortID": tamaraOrderID, // Tamara order ID + "LanguageID": 1, + "Installments_Number": selectedInstallments + }; + + dynamic localRes; + await baseAppClient.post(UPDATE_TAMARA_STATUS, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request, isAllowAny: true); + + return Future.value(localRes); + } + + Future markAppointmentForTamara(int projectID, String appoNo) async { + Map request; + request = {"ProjectID": projectID, "AppointmentNo": appoNo, "LanguageID": 1}; + dynamic localRes; + await baseAppClient.post(MARK_APPOINTMENT_TAMARA_STATUS, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + + return Future.value(localRes); + } + + Future autoGenerateInvoiceTamara(int projectID, String appoNo, String mobileNo) async { + Map request; + request = {"ProjectID": projectID, "AppointmentNo": appoNo, "MobileNo": mobileNo, "UserID": 102, "LanguageID": 1}; + dynamic localRes; + await baseAppClient.post(AUTO_GENERATE_INVOICE_TAMARA, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + + return Future.value(localRes); + } + + Future autoGenerateInvoiceERClinic(int? projectID, int? paymentMethod, String? paymentReferenceNo, num? amount, String? cardType, String? cardNumber, String? orderID, String? rrn, bool isAdvanceAvailable) async { + Map request; + request = { + "ProjectID": projectID, + "ClinicID": "10", + // "PaymentMethod": paymentMethod, + "PaymentMethod": "VISA", + "PaymentReferenceNo": paymentReferenceNo, + "PaymentAmount": amount, + "CardType": cardType, + "CardNumber": cardNumber, + "OrderId": orderID, + "MemberID": 102, + "RRN": rrn, + "IsAdvanceAvailable": isAdvanceAvailable + }; + dynamic localRes; + await baseAppClient.post(AUTO_GENERATE_INVOICE_ER, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + + return Future.value(localRes); + } + + Future checkPatientNphiesEligibility(int projectID) async { + Map request; + request = {"ProjectID": projectID, "LanguageID": 1}; + dynamic localRes; + await baseAppClient.post(CHECK_PATIENT_NPHIES_ELIGIBILITY, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + + return Future.value(localRes); + } + + Future convertPatientToCash(int projectID) async { + Map request; + request = {"ProjectID": projectID, "LanguageID": 1}; + dynamic localRes; + await baseAppClient.post(CONVERT_PATIENT_TO_CASH, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { throw error; }, body: request); + + return Future.value(localRes); + } + + Future getAncillaryOrders() async { + Map body = Map(); + + hasError = false; + dynamic localRes; + await baseAppClient.post(GET_ANCILLARY_ORDERS, onSuccess: (dynamic response, int statusCode) { + localRes = response; + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + + return Future.value(localRes); + } + + Future getPayfortSDKTokenForPayment(String deviceID, String signatureValue, {bool isTest = true}) async { + Map request; + request = {"service_command": "SDK_TOKEN", "access_code": "BsM6He4FMBaZ86W64kjZ", "merchant_identifier": "ipxnRXXq", "language": "en", "device_id": deviceID, "signature": signatureValue}; + dynamic localRes; + await baseAppClient.post(isTest ? PAYFORT_TEST_URL : PAYFORT_PROD_URL, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request, isExternal: true, isAllowAny: true); + + return Future.value(localRes); + } + + Future logDoctorFreeSlots(int docID, int clinicID, int projectID, List selectedfreeSlots, dynamic appoNumber, BuildContext context, [ProjectViewModel? projectViewModel]) async { + Map requestFreeSlots; + Map request; + + Request req = appGlobal.getPublicRequest(); + requestFreeSlots = { + "DoctorID": docID, + "IsBookingForLiveCare": 0, + "ClinicID": clinicID, + "ProjectID": projectID, + "OriginalClinicID": clinicID, + "days": 0, + "isReschadual": false, + "VersionID": req.VersionID, + "Channel": 3, + "IPAdress": "10.20.10.20", + "generalid": "Cs2020@2016\$2958", + "PatientOutSA": authProvider.isLogin ? authUser.outSA : 0, + "SessionID": null, + "isDentalAllowedBackend": false, + "LanguageID": 1, + "DeviceTypeID": 1 + }; + + request = {"ClinicID": clinicID, "ProjectID": projectID, "AppointmentNo": appoNumber, "DoctorFreeSlotRequest": requestFreeSlots, "DoctorFreeSlotResponse": selectedfreeSlots, "Value1": docID}; + dynamic localRes; + await baseAppClient.post(INSERT_FREE_SLOTS_LOGS, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); } } diff --git a/lib/services/appointment_services/doctor_response_mapper.dart b/lib/services/appointment_services/doctor_response_mapper.dart new file mode 100644 index 00000000..6062fd5b --- /dev/null +++ b/lib/services/appointment_services/doctor_response_mapper.dart @@ -0,0 +1,211 @@ +import 'dart:math'; + +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; +import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; + +class DoctorMapper{ + static Future getMappedDoctor(List doctorList, + {bool isArabic = false}) async { + RegionList regionList = RegionList(); + AppSharedPreferences sharedPref = AppSharedPreferences(); + + for (var element in doctorList) { + String? region = element.getRegionName(isArabic); + if (region == null) continue; + + var regionDoctorList = regionList.registeredDoctorMap?.putIfAbsent(region, () => PatientDoctorAppointmentListByRegion()); + + List? targetList = element.isHMC == true + ? regionDoctorList?.hmcDoctorList + : regionDoctorList?.hmgDoctorList; + + var doctorByHospital = targetList + ?.where((clinic) => + clinic.filterName == + element.getProjectCompleteNameWithLocale(isArabic: isArabic)) + .toList() ?? + []; + + if (doctorByHospital.isNotEmpty) { + doctorByHospital.first.patientDoctorAppointmentList?.add(element); + } else { + var newAppointment = PatientDoctorAppointmentList( + filterName: + element.getProjectCompleteNameWithLocale(isArabic: isArabic), + distanceInKMs: element.projectDistanceInKiloMeters.toString(), + projectTopName: element.projectTopName, + projectBottomName: element.projectBottomName, + patientDoctorAppointment: element, + ); + if(element.projectDistanceInKiloMeters!= null ){ + if(regionDoctorList!.distance>element.projectDistanceInKiloMeters){ + regionDoctorList!.distance = element.projectDistanceInKiloMeters; + } + if (element.isHMC == true && + element.projectDistanceInKiloMeters < + regionDoctorList.hmcDistance) + regionDoctorList.hmcDistance = element.projectDistanceInKiloMeters; + else if (element.projectDistanceInKiloMeters < + regionDoctorList.hmgDistance) + regionDoctorList.hmgDistance = element.projectDistanceInKiloMeters; + }else + if (await sharedPref.getDouble(USER_LAT) != null && await sharedPref.getDouble(USER_LONG) != null && element.latitude != null && element.longitude != null) { + var lat = await sharedPref.getDouble(USER_LAT); + var long = await sharedPref.getDouble(USER_LONG); + + double distance = calculateDistance(lat, long, double.parse(element.latitude!), double.parse(element.longitude!)); + if(distance<0){ + distance *= -1; + } + if(regionDoctorList!.distance>distance){ + regionDoctorList!.distance = distance; + } + if (element.isHMC == true && + element.projectDistanceInKiloMeters < + regionDoctorList.hmcDistance) + regionDoctorList.hmcDistance = element.projectDistanceInKiloMeters; + else if (element.projectDistanceInKiloMeters < + regionDoctorList.hmgDistance) + regionDoctorList.hmgDistance = element.projectDistanceInKiloMeters; + print("the distance is $distance"); + } + targetList?.add(newAppointment); + } + + + + + regionDoctorList?.hmcSize = regionDoctorList.hmcDoctorList?.length ?? 0; + regionDoctorList?.hmgSize = regionDoctorList.hmgDoctorList?.length ?? 0; + + regionList.registeredDoctorMap?[region] = regionDoctorList; + } + + return regionList; + } + static double calculateDistance(double lat1, double lon1, double lat2, double lon2) { + var pi = 3.142; + const double R = 6371; + double dLat = (lat2 - lat1) * pi / 180; + double dLon = (lon2 - lon1) * pi / 180; + double a = sin(dLat / 2) * sin(dLat / 2) + + cos(lat1 * pi / 180) * cos(lat2 * pi / 180) * sin(dLon / 2) * sin(dLon / 2); + double c = 2 * atan2(sqrt(a), sqrt(1 - a)); + return R * c; + } + + static Future sortList(bool isGPSEnabled, RegionList unsorted, ) async { + if(isGPSEnabled){ + if(unsorted.registeredDoctorMap == null) return unsorted; + var sortedMap = Map.fromEntries( + unsorted.registeredDoctorMap!.entries.toList() + ..sort((a, b) => a.value!.distance.compareTo(b.value!.distance)), + ); + + unsorted.registeredDoctorMap = sortedMap; + return unsorted; + + } + + List? keys = unsorted.registeredDoctorMap?.keys.toList(); + keys?.sort(); + + if (keys == null) return unsorted; + Map sortedMap = {}; + for (var key in keys) { + sortedMap[key] = unsorted.registeredDoctorMap![key]!; + } + unsorted.registeredDoctorMap = sortedMap; + return unsorted; + } + + static Future getMappedHospitals( + List hospitalList, { + bool isArabic = false, + }) async { + final regionList = RegionList(); + final sharedPref = AppSharedPreferences(); + + for (final hospital in hospitalList) { + final region = hospital.getRegionName(isArabic); + if (region == null) continue; + + final regionData = regionList.registeredDoctorMap?.putIfAbsent( + region, + () => PatientDoctorAppointmentListByRegion(), + ); + + List? targetList = hospital.isHMC == true + ? regionData?.hmcDoctorList + : regionData?.hmgDoctorList; + + List existingEntry = targetList + ?.where( + (entry) => entry.filterName == hospital.getName(isArabic), + ) + .toList() ?? + []; + + if (existingEntry.isNotEmpty) { + existingEntry.first.hospitalList.add(hospital); + } else { + final newEntry = PatientDoctorAppointmentList( + filterName: hospital.name, + distanceInKMs: hospital.distanceInKilometers?.toString(), + projectTopName: hospital.name, + projectBottomName: hospital.name, + model: hospital); + + final distance = hospital.distanceInKilometers; + + if (distance != null) { + if (regionData!.distance > distance) { + regionData.distance = distance; + } + + if (hospital.isHMC == true && distance < regionData.hmcDistance) { + regionData.hmcDistance = distance; + } else if (distance < regionData.hmgDistance) { + regionData.hmgDistance = distance; + } + } else if (await sharedPref.getDouble(USER_LAT) != null && + await sharedPref.getDouble(USER_LONG) != null && + hospital.latitude != null && + hospital.longitude != null) { + final lat = await sharedPref.getDouble(USER_LAT); + final long = await sharedPref.getDouble(USER_LONG); + + double calculatedDistance = calculateDistance( + lat, + long, + double.parse(hospital.latitude!), + double.parse(hospital.longitude!), + ).abs(); + + if (regionData!.distance > calculatedDistance) { + regionData.distance = calculatedDistance; + } + + if (hospital.isHMC == true && + calculatedDistance < regionData.hmcDistance) { + regionData.hmcDistance = calculatedDistance; + } else if (calculatedDistance < regionData.hmgDistance) { + regionData.hmgDistance = calculatedDistance; + } + + print("Calculated distance: $calculatedDistance"); + } + + targetList?.add(newEntry); + } + + regionData?.hmcSize = regionData.hmcDoctorList?.length ?? 0; + regionData?.hmgSize = regionData.hmgDoctorList?.length ?? 0; + regionList.registeredDoctorMap?[region] = regionData; + } + + return regionList; + } +} \ No newline at end of file diff --git a/lib/services/appointment_services/mock_doctor_response.dart b/lib/services/appointment_services/mock_doctor_response.dart new file mode 100644 index 00000000..3f30ee30 --- /dev/null +++ b/lib/services/appointment_services/mock_doctor_response.dart @@ -0,0 +1,8029 @@ +var response = { + "Date": null, + "LanguageID": 0, + "ServiceName": 0, + "Time": null, + "AndroidLink": null, + "AuthenticationTokenID": null, + "Data": null, + "Dataw": false, + "DietType": 0, + "DietTypeID": 0, + "ErrorCode": null, + "ErrorEndUserMessage": null, + "ErrorEndUserMessageN": null, + "ErrorMessage": null, + "ErrorStatusCode": 0, + "ErrorType": 0, + "FoodCategory": 0, + "IOSLink": null, + "IsAuthenticated": true, + "MealOrderStatus": 0, + "MealType": 0, + "MessageStatus": 1, + "NumberOfResultRecords": 0, + "PatientBlodType": null, + "SuccessMsg": null, + "SuccessMsgN": null, + "VidaUpdatedResponse": null, + "AgeError": false, + "AllowedBooking": false, + "AncillaryOrderInvoiceList": null, + "AncillaryOrderList": null, + "AncillaryOrderListCount": 0, + "AncillaryOrderProcList": null, + "AppoimentAllHistoryResultList": null, + "AppoimentAllResultList": null, + "AppointmentActiveNumber": 0, + "AppointmentNo": null, + "AppointmentQR": null, + "AppointmentStats": null, + "AvgDoctorRatingList": null, + "BloodBank_Appointment_GetList": null, + "COVID19_AppointmentResponse": null, + "COVID19_FreeTimeSlots": null, + "COVID19_InvoiceResponse": null, + "COVID19_PatientShare": null, + "COVID19_TestProceduresList": null, + "ClinicCategoryList": null, + "ClinicInsertedID": 0, + "ClinicsHaveScheduleList": null, + "ContinueBookAppointment": false, + "DAPP_TemplateGetList": null, + "DecimalDoctorRate": 0, + "DentalProcedure": "", + "DentalProcedureName": "", + "DiseasesByClinicList": null, + "DoctorBasicScheduleList": null, + "DoctorByClinicIDList": null, + "DoctorByDiseaseList": null, + "DoctorCalenderList": null, + "DoctorImage_GenerateImageURLList": null, + "DoctorImage_ProjectFolderConfig_List": null, + "DoctorInformationAsHTML": null, + "DoctorInformationRAW": null, + "DoctorList": [ + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 5018, + "Name": "RUBEENA QUADRI", + "ProjectID": 12, + "ProjectName": "Olaya Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.86, + "DoctorAvailability": null, + "DoctorID": 5018, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/OALAY/5018.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.70441742217276", + "Longitude": "46.67674567554396", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/USA.png", + "NationalityID": "USA", + "NationalityName": "American", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 11444, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 1.2, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Olaya", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "91877 ", + "Speciality": [ + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري طب الباطنية " + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 14315, + "Name": "ALAA FARIZ ISMAIL ", + "ProjectID": 12, + "ProjectName": "Olaya Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.83, + "DoctorAvailability": null, + "DoctorID": 14315, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/OALAY/14315.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.70441742217276", + "Longitude": "46.67674567554396", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/JOR.png", + "NationalityID": "JOR", + "NationalityName": "Jordanian", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 8962, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 1.2, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Olaya", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "91877 ", + "Speciality": [ + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري طب الباطنية " + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 12565, + "Name": "SAMER YOUSEF ABUALRUB", + "ProjectID": 12, + "ProjectName": "Olaya Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.86, + "DoctorAvailability": null, + "DoctorID": 12565, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.70441742217276", + "Longitude": "46.67674567554396", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/JOR.png", + "NationalityID": "JOR", + "NationalityName": "Jordanian", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 4655, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 1.2, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Olaya", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "91877 ", + "Speciality": [ + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري طب الباطنية " + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 281722, + "Name": "MUSHIRA ENANI", + "ProjectID": 12, + "ProjectName": "Olaya Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.95, + "DoctorAvailability": null, + "DoctorID": 281722, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.70441742217276", + "Longitude": "46.67674567554396", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 1639, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 0.2, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Olaya", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "91877 ", + "Speciality": [ + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري طب الباطنية " + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 360282, + "Name": "MAHA IBRAHIM ALDESSOUGI", + "ProjectID": 12, + "ProjectName": "Olaya Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.86, + "DoctorAvailability": null, + "DoctorID": 360282, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.70441742217276", + "Longitude": "46.67674567554396", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SCT.png", + "NationalityID": "SCT", + "NationalityName": "Scottish", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 1102, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 0.1, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Olaya", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "91877 ", + "Speciality": [ + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري طب الباطنية " + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 12108, + "Name": "RITA NADER", + "ProjectID": 16, + "ProjectName": "Takhassusi Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.86, + "DoctorAvailability": null, + "DoctorID": 12108, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/TAKHSUSI/12108.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": true, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": true, + "Latitude": "24.719364", + "Longitude": "46.657567", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/LBN.png", + "NationalityID": "LBN", + "NationalityName": "Lebanese", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 27060, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 1.4, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Takhassusi", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "102000", + "Speciality": [ + "Specialist Internal Medicine" + ], + "SpecialityN": [ + "أخصائي أمراض باطنية" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 170987, + "Name": "SAADIA PARVEEN MALIK", + "ProjectID": 16, + "ProjectName": "Takhassusi Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.74, + "DoctorAvailability": null, + "DoctorID": 170987, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": true, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.719364", + "Longitude": "46.657567", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/GBR.png", + "NationalityID": "GBR", + "NationalityName": "British", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 18514, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 1.4, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Takhassusi", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "102000", + "Speciality": [ + "Consultant Internal Medicine", + "Rheumatology Consultant" + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n", + "استشاري علاج أمراض الروماتيزم" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 122495, + "Name": "FADI MOURAD ", + "ProjectID": 16, + "ProjectName": "Takhassusi Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.82, + "DoctorAvailability": null, + "DoctorID": 122495, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/TAKHSUSI/122495.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": true, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": true, + "Latitude": "24.719364", + "Longitude": "46.657567", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/ESP.png", + "NationalityID": "ESP", + "NationalityName": "Spanish", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 17013, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 1.4, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Takhassusi", + "QR": "data:image/png;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCABkAGQDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3+iiuf8XeLrPwdp1reXlnfXn2q7SzhhsYhJI0jBioClhnO0jjnJHFAHQUV5//AMLT/wCpC8c/+Cf/AOzq5pvxK03U9GbVE0nWYYItT/s26Wa2VWtGChnlm+bEcSA/MxPHcUAdpRXnafF/Tbq4u00vw14n1aC1uHt2u9NsVngdlPVXV8EEYI9iD3rpI/F1ncadp95Z2d9efaruOzmhtohJJYyMMsLhQ37vZwHzypI4oA6CiuPh+Jfhub+14vtOy+027ms/sDyRi5upI+0Me7L7j8q9CTxitDRvF1nqmnJeXlnfaH5l2LOGHWYhbSTSEAqEUsd2ckDHJKnjigDoKK5//hKv+oDrn/IV/sz/AI8//Jjr/wAe/wDt/pXPyfFiz/tHULOz8K+K9Q+wXclnNNY6cJY/MQ4YBg/0PODgjigD0CivP4/ixZ/2jp9neeFfFen/AG+7js4Zr7ThFH5jnCgsX+p4ycA8V6BQAUUUUAFef/FP/mSv+xrsf/Z69Arzv4xz6Da+FdPuPEEuswwRanG9vJpDIs6TBJCpy/AAG7kc5xQB5p/xcf8A4XJ/zNf9if8ACQf9PH2b7P8AaP8Avny9n4Y9q9D8BPDHo3xDe4spL6BfEepGS0jiErTrtXKBDwxYcY75xXCTa54Ph1HSLP8A4WF8QH/tKKGXzk1qEx2vmHG2Zs/Iy9WHOBWx9p0fw14e/wCJR4lvrP7L4g/te8/te+SO51a3VPna3248+OXaNhPDkHJoAnhv7Pw/p2r6d4Xu4IrHWYpp3tkkC3ui3kw2l5ljwLe2hAUMeWRvWsDSr+88HeDb3xR4Qu9V1y+j1CSz1eO7kNzZNIIxJNdxiPBKkquJXOdrHI5FXNH8P6lr/hXWPEml21ppM914jn1Jp9aRoFudMZBJ5UrKCXgYkFlzsODzxWf4YvIdM1m/8N6prGjTaXK8mvLB4auQy3cxYR/2eFb5ZEdQR5GMn5eaALkkdnruo6h4ts9Nsf8AkSpLya8sYB5dvqufMYhxnZcLkHk7wMHNYdz46m1m38O36Xkl9AtvbaNdadLKZb8XWMvfWse4jzcHakx+bccEV3cejWf9o6f4S8OJfaf9vu4/FGo2d8BFH9jc+XLaFEH+6PKYFcAgtXIa74dvPBHiHU5Z/C/2ixgu5df0u/0jTy/2eRXPlQXEhAC26hdzovI4INAHb+F7+z8OfY9XvLv4gP8A2lqCaLDZeIZAdskm1ll2HGF4I3Ak/eGK5DV/+Ek/4Q3xT/wi/wDav27/AITq73/2Z5nmeX5Zzny+dudvtnFZfhrxB4q8a3GkPcXFpfQL4thv5LSN5Zbu1XIywQkhLVQ2M9mOM13cPhrw3N4h1eL/AITHxX4bvrzVZm+wPqcdn9qkd/8AWwx4y8bH5VbqduO1AHMaR/wkn/CG+Fv+Eo/tX7d/wnVps/tPzPM8vyxjHmc7c7vbOa+h68n1DwXo+l+IdCivPE3jLXL6PULe5hsGv0ufJw523EsZUFYQQVZx03Y716xQAUUUUAFcv8QbXR77wbf2er3GlW/nxSRWc2puiRx3DRuEYM3RhknI5Aziuorg/irBpt1o2i29/FJNPLrECafGVVoHuiriMXAPJgJzvC/NjpQB4w+k6lcaNaW76f4Dtp9IuEe1jaFku9bWJcIUGM3EUx6EY3sOMVn+J7mbU7iw0u98MazDBEkepak0tgVu7SEErLFa54js0BOxWGA3U13keieBIfiHp/8AbnimdNb02KO8bbqEA021kjl5tIt43IqvnbFwQnfNEmn6PefEPUPEd54h1X7D5Uiw6Zc3qfadU/e71it4iMTWUoyqKD85yKALFhp9n4j+zaHq/iHXNLsU8PreWaWF6ILZtKGEQ3QYEG4wTvwNmAMHio7LwpoNrrOpWAGmw6pF4cln0fUYNi2iWoYCC7lkxuF0G+ZpU+XbyKjv/C+sX2nXNn9h1W38+VtU863idJI9GYEf2WjY4mGci3/1YPetfwF/Y994yOnXn+kX0Hh/7DDbDY8cenLIqrDdqeRdgkiRR8gHagCxNrtnpenaRdajqulXljdafD4euNe0y4El7DeMMsxuGICwgAvk/MGIbbWJqWreKtGuF8QJqGm+KvB8Cf2RdW9lNLfMbUEu8865Efn+UMM5O35hkYNZ958L9N1O41WyTxhpsMEWuzX91pdrqarBaWAOHYxbMRzoDtyflAwCa1/BVnqXgTWZvCj6PJrvg/Wna4tb6ytmulCzMsaCeT5Y9nlJubAP3gRkGgCh4fvPBN146g1R9YtPDs4t1u7VdHuYbS0e180Mlvd9zcE/6xAdu1Rg8VHZ/wBj/wDCQ+LfEPi/+3P+Xz+yNSn2fZvs+/fD9ilk/wCXj7zR7DjHI71p6h8O9B8JeKvEut28ejX0C6FdX8ekX6pK0U28uGWEKAIAF2A5yMkZrU8I6r4bvvh5dT65YT3HkRPq7aVqkMb+XGsSktZwueLYZKxnoORmgDjPCB02Tx1p1w+v+Lta1S4eOa1k0+8W4WCwaVSkN6fvKVb/AFqj5RkY619F184aY15qnjLRtc0Pwnrmh+ZqsESvp2nG2sptKMgcNMUzukORuOdhVR6V9H0AFFFFABXlfx4nhtfCug3FxLdwwRa7bvJJZsFnRQkpJjJ4DgdD64r1SuH+K1r9u8GtZ/aPDlv58vledr77I490bjdE3aYZyp7DdQB5B/a+jzeMvtmneBNV1Tf4axbw6hpCTyXVwZMreSqp+dW4DSjkkn1qxHbf2vqOnwa54a8V6XYp5d02qrY+RJptwDgxxTPkQ2EYJZV6qRntWxYeHrPS9Otv+EX+IelXnim609dIf7frQkjhjYDK2vlgOrCQLsHQAnjNa+geMtH8KadqnhfxbNrlxfQWkt1dya4yPHebQI3jtjIwMkblW2KR8w3Z70AeeXmteNtA8VarpfhvxFd+LYLuymEDWt7NftbQu+1XOwgJOoC8gYG8etSfD7W/GH/Cw7DUYPC3/PPRdUuU0+b/AJ6o0sszA/8AHx3Zm/EVuXsGg+J7fTfGHgiLWfDsA1OLSNTNgqWixWuDLLO3lZCgBky7HaNoyOAa1L+/1jwL9p1DTrux/wCPRp7e5uJH/s3Ubflld2XHm6nJtBJHDJQBp23w71LwxrPiLxWkdpqM+oXtybqxZWmWXTJG8x0SPaC1wSu0Akoc4NYCeK9evfHV3o1kZFgvdCey02y0feF0pnl2xPdoDiCWIELIVB2cACtfw+dS8Q+BYLjVNf1m5n1fXVmWTwveM7WCyxA+VKWyYooyTuXnbletYCfCrUvCXiq71nVNd1ldLvbh4VvdHu2F3Ervu867dkCiIKpaRsnDYNAFiDxFNpnxLit9Z8N+INWntfC40i8jjsTO12yzYecBjmSByD85655HNSeLvFVnY/Zde0PQZ7fW54k8PL4d1mzCeZZtucMlsh3FS4EYOdp5XbmuDvYtStfi5pthb+ObvUYNQuIrWPUbDVmmnS1knIEbSDgOB8xXlckGvV9Q03QdG8C+Jb2/bUm1Sye6t9P1TxMUN2ZkiJjNrKQG2bgWTbg7txFABrXifUpLjwB4bsNO1Kx1Rn07UtQgsIGiggtcmOSJlB3KitgFWG0ADJr1yvnzS9W8VazceCrhNQ8P3063Fil1Jo80suqC1yC4uzknysn94D8u8jNfQdABRRRQAV538X/D83ifRvD+lpbXc0Euu2wumtULNFCVkV3PBCgBupGBxmvRK8/+LEl5/Z3hqzs9SvtP+3+ILWzmmsZzFJ5bhwwDD8DzkZA4oA4TQ/hFNa+Krm48PwSQ6XE7afcSa8hW7Rg4LXVkUTaCF2+XIf4t3FdH5fg/w5p3m+KNN1XVN+t/2Ul/4nghnkXI4dZJMYtuGYH1LHHNch/a/hv/AITL/hF/+Ev+J327+0P7P8z+0o/L8zzPLznOdue+M47Vt6PqUNr4V1jS9bWTxFOfFs+jaU2tAXapNsCwtLuOQgOdxUZ+Y4HNAB8QIJrrRrO38ERWk3g+W9RNTj8KKWu3YqwlBEX7soYtnDfxbc8YrAstDmXRtSt7i61LVtLtbeWaSO/kM8GnWCqAYVBG2LVI16L91QT61saDpkPhLRvF4fxdpq+Ir1L1LXRdF1ICCKZ1GwRQYDicOuxQMkDAHNcfZ+IJtW8VaVZWtxd6dBp9lCde0u6cwtq91G+LhBECRPPKDtw+GfBDUAet+DdP8H32nQxeF/EM9v5+iC3ewtL2FJI9wXNzJHGOLkZVTJ2OBWWdYh0bRtb8KXGh/ErWYLh57eS+ntBcMVZfLJikJA2YG5eO+e9WND0PQdT8dXN/4futN0mC68ONZXGnWEiQX9pM0oLO0aDEboCqknkMAMcVT1/U/Eml+MtLi8F67Y655dpFo9zYXV3JcyQyCQ77qeOIjbjCK0h5BYjHIoA881zSdB8GW9tceD9P1nUdU1BFtRJfwpMthNICfLUxgNFfIyrheSuT7VqeKviT4ksfD2i2eo+CvtFjBaQRXE3ifSpH8y8VGDMrM2DkAkE/Mfmrk538VaN8S5X1my1JoLLWDrt5aWcUpgKpN89xGjYGzAIDnHGATXUeK/GMPifwqbjw/o3ifVoLXXf7XuJNXtRPaRKqMWgyjELEAy/Ieik880AZfwptf+Ej8ZLeaRcT6Xraah9uvIbd/Ism04SIXhRVyxbeQAh+TaOTkV9T15fpGjWfiPw94W1zwgmh6XfJd2lxq76YBBujCB5rYmMEnkr+7c44Gegr1CgAooooAK8/+LEd5/Z3hq8s9NvtQ+weILW8mhsYDLJ5aByxCj8BzgZI5r0CigD54/sjw3/wmX/CUf8ACIfE77d/aH9oeX/Zsfl+Z5nmYxjO3PbOcd62NKbxJD4evbzTvCe++1LxrJc28Ot6dIfssciArcMq8ptOAXGQPmr2+igDwCw0j+1PiHbaj4o8Ia5Z63a6qqJc6Bpvl6bNtlDCeVpAWbLliz90C96r/EfwRrF94yt5dO0ae31ufUFa3v8ASLV0so7dpH2y3EiruFyHIZ2HAXB619D0UAcPH4NvLHw9p8GmQ6Vb63PFHa61qyqUuZI2TE8kUyruMxcBlZ+CeTzXEXWhaxY+MoNR8OaVfW9jPt8M6jczW7peybpN0uoKyDByApE7dW6rXt9FAHmfjHSdNurjSfDNxp/i6aeW3htZNe0yFWZ4SWjMdzcEZKE/O64x0avPNf0zxJb+MtL0PwXoWuWeiWvlWNyl1aSR2V9IshR5pxENskbps3ORllB4xivo+igDxu50n4g6NceHbdNP8P2Oltrts91H4XhuImK5w5lGAvlbR8xPoua9koooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigD/9k=", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "102000", + "Speciality": [ + "Consultant Internal Medicine", + "Consultant Family Medicine", + "Specialist Internal Medicine" + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n", + "استشاري طب الأسرة\r\n", + "أخصائي أمراض باطنية" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 103068, + "Name": "HADI AHMED YOUNIS", + "ProjectID": 16, + "ProjectName": "Takhassusi Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.71, + "DoctorAvailability": null, + "DoctorID": 103068, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/TAKHSUSI/103068.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": true, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.719364", + "Longitude": "46.657567", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/LBN.png", + "NationalityID": "LBN", + "NationalityName": "Lebanese", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 16284, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 1.4, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Takhassusi", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "102000", + "Speciality": [ + "Rheumatology Consultant" + ], + "SpecialityN": [ + "استشاري علاج أمراض الروماتيزم" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 17024, + "Name": "LOAY ABDALRAZZAQ AL DHAHIR", + "ProjectID": 16, + "ProjectName": "Takhassusi Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.8, + "DoctorAvailability": null, + "DoctorID": 17024, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/TAKHSUSI/17024.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": true, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.719364", + "Longitude": "46.657567", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/GBR.png", + "NationalityID": "GBR", + "NationalityName": "British", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 15551, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 1.4, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Takhassusi", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "102000", + "Speciality": [ + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 13909, + "Name": "ABDEL HAMEED ABU MALLUH", + "ProjectID": 16, + "ProjectName": "Takhassusi Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.72, + "DoctorAvailability": null, + "DoctorID": 13909, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/TAKHSUSI/13909.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": true, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": true, + "Latitude": "24.719364", + "Longitude": "46.657567", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/JOR.png", + "NationalityID": "JOR", + "NationalityName": "Jordanian", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 14504, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 1.4, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Takhassusi", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "102000", + "Speciality": [ + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 187622, + "Name": "MUNEERAH SALEH ALHUTHAYFI", + "ProjectID": 16, + "ProjectName": "Takhassusi Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.79, + "DoctorAvailability": null, + "DoctorID": 187622, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": true, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.719364", + "Longitude": "46.657567", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/YEM.png", + "NationalityID": "YEM", + "NationalityName": "Yemeni                                     ", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 10017, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 1.4, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Takhassusi", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "102000", + "Speciality": [ + "Resident Internal Medicine" + ], + "SpecialityN": [ + "طبيب أمراض باطنية مقيم" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 258923, + "Name": "MOHAMMED AL SHEEF", + "ProjectID": 16, + "ProjectName": "Takhassusi Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.8, + "DoctorAvailability": null, + "DoctorID": 258923, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/TAKHSUSI/258923.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.719364", + "Longitude": "46.657567", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 6020, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 1.4, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Takhassusi", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "102000", + "Speciality": [ + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 160486, + "Name": "EBTISAM BAKHSH ", + "ProjectID": 16, + "ProjectName": "Takhassusi Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.84, + "DoctorAvailability": null, + "DoctorID": 160486, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.719364", + "Longitude": "46.657567", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 4904, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 1.4, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Takhassusi", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "102000", + "Speciality": [ + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 288442, + "Name": "SIRINE AHMED", + "ProjectID": 16, + "ProjectName": "Takhassusi Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.86, + "DoctorAvailability": null, + "DoctorID": 288442, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": true, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.719364", + "Longitude": "46.657567", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/LBN.png", + "NationalityID": "LBN", + "NationalityName": "Lebanese", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 4629, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 1.4, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Takhassusi", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "102000", + "Speciality": [ + "Specialist Internal Medicine" + ], + "SpecialityN": [ + "أخصائي أمراض باطنية" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 270663, + "Name": "NOOR FARIS ALHASSAN", + "ProjectID": 16, + "ProjectName": "Takhassusi Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.88, + "DoctorAvailability": null, + "DoctorID": 270663, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.719364", + "Longitude": "46.657567", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 3046, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 1.4, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Takhassusi", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "102000", + "Speciality": [ + "Rheumatology Consultant" + ], + "SpecialityN": [ + "استشاري علاج أمراض الروماتيزم" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 243527, + "Name": "MOHAMMED ABBAS AL SAEED", + "ProjectID": 16, + "ProjectName": "Takhassusi Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.85, + "DoctorAvailability": null, + "DoctorID": 243527, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.719364", + "Longitude": "46.657567", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 2765, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 1.4, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Takhassusi", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "102000", + "Speciality": [ + "Consultant Infectious Disease " + ], + "SpecialityN": [ + "\r\n\r\n\r\n\r\n\r\n\r\n\r\nاستشاري الأمراض المعدية" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 397230, + "Name": "AHMED KAMAL ADAM", + "ProjectID": 16, + "ProjectName": "Takhassusi Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.91, + "DoctorAvailability": null, + "DoctorID": 397230, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/TAKHSUSI/397230.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": true, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.719364", + "Longitude": "46.657567", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SDN.png", + "NationalityID": "SDN", + "NationalityName": "Sudanese", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 1966, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 1.4, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Takhassusi", + "QR": "data:image/png;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCABkAGQDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3+iiuf8XeLrPwdp1reXlnfXn2q7SzhhsYhJI0jBioClhnO0jjnJHFAHQUV5//AMLT/wCpC8c/+Cf/AOzqOf4x6Da+FZfEFxpmswwRamdLkt5IEWdJgm85UvgADjrnPagD0SiuPuviPo8Pg2DxRZ219qli+3zo9OjSeS1zH5jecA2E2jG7J4JHrUdn8StNutG0rVH0nWbSDVNTh021W6tlRnaVdySj5sGIj+IE9DgGgDtKK5f/AIWD4b/4TL/hF/7Rg+3eVv8AM8+Py/M8zy/Izuz52f4MZxWhdeJLOx8QwaReRz2/nxK8N7MoS2kkZ9qwK5PMxwSEAyRzQBsUVz+leKv7U8Q3ukf2Drln9l8z/Tbuz8u2m2uF/dvk7s5yOOQCa5+T4sWf9o6hZ2fhXxXqH2C7ks5prHThLH5iHDAMH+h5wcEcUAegUV5/H8WLP+0dPs7zwr4r0/7fdx2cM19pwij8xzhQWL/U8ZOAeK9AoAKKKKACvP8A4p/8yV/2Ndj/AOz16BXn/wAXP7H/AOEe0r+1/wC3P+QrD9j/ALE2faftGyTZt3fjjHOduKAPMP8Ai4//AAuT/ma/7E/4SD/p4+zfZ/tH/fPl7Pwx7VqHQ5tf0bW7e3utGhni+IU80ceryFYLlguBDgAlyxP3e4zRrl14V0DRra/uPiJ48mnldUk06DWomu7ZipJEsZwUKkbWHZuK3/CnhTTdf8Ci40YeIIZ4tY/tuzk1/arXN0IlKO5UEvAxIyR8x+bBoA5TxVo3/Cv9R0WKBPEb/wBpahBcapYaeM6TP5hbzbaKMBdzNs2rG2cpgGo3nm8a6zaX+ty6lo3h231hNC0rTtKY289rdK2YZJI2yiFUYqWX5gQABgV17xabJrNpb+JPHOjNBZXqavPG2rKZ4NTRsNAgfhbVRuwhw4PeuY8QalpumXE72S3c0Euutq2m2jBWu7vUyT5UqIDiTT3AADL85bgGgDQsvCkNr8XNSsPEA02GCLw5LPb6jBhZ0UTgLdyyOMC6A3M0o781p634u8Nzf8I3pmr2fitLHTdVtWs9cuIoxbXUkeVSV52bDxsMuWABI5FR6lBDJ4FXxAkWs614iuLjddW9kouGgmaIu9hOv31s1fhoCcjIzya5SbW/7d8PaRp0HhbxXqH2DxBDeapbPp/m21vsTbLaQqCdka5wsTYwDyaANTwJ4r16T4ua5cOfEGs+Hbi9uLK1ktd9xaQM06lHJzsVFTuOikYGDVPV/wDhJP8AhDfFP/CL/wBq/bv+E6u9/wDZnmeZ5flnOfL5252+2cV1fh+88E2usweG9L1jUtJnur1deaBbmGBUmZhH/Z7qvIIOAYMZ468VHrvhXR9C8Q6n/wAT7xzp/wBv83U/+JfeJFbXFw7n/R4uBvuGx8qckgDmgDmNI/4ST/hDfC3/AAlH9q/bv+E6tNn9p+Z5nl+WMY8znbnd7ZzX0PXzxoV/4b13xlpmnfa/idqF9YahFP8AZtQkjljt5EkC75V5KKpOGPBAJr6HoAKKKKACsfxRYWd94evPtlpPceRE88P2WMPcxyKjbXgz0mGTtI5BxWxXL+OPtn9nad/Z39q/bv7Qi+z/AGDPl+Zhtv2rbz9mzjfjnGKAPANb/wCEb1Txl4b1eDyLOxtdQtdM1Sy1jy472aRZC0txcIMhlIOHdjksCCK9T0zxrpujW/ijS9Gg1lp7Kyu9Zs21NFNoYUAVFttrA/Z8gbAABtzg15x4g0XUvDGszp4r8O2moz6hetqtld6VZNMst/Ix8uzkeQAtASrExLljkEGuv8KeGNB1m4Gt6zqPiDRtUt7fN5pF/OlvALVSruiwsC32HcSgBO3AIPSgDA0nw/D4t+JdjqnjC20axgbQo9fK6YgiglXzg2bnzAQSQzb+eQBz1qP4mx2fiPxDoMvh7Tdc0u+S7t9K0+/eAQaa0Yd/KeGRMk8lWUrxsGQOKjvLLQZPFWq276p4n1qe4SYWsfg64S4gg0xnwlu46qFPWMfIAUx1rDupPEnh/UYLOLUvtmiXW2zsZtWnkkj0WRjiMO3C293CgydvKAnAxQB2mralqXw+8C32ieGV1LWtUuHkuNb1eMNcQWkzRFLgCZCrJKrIr/OMgHJ61wfw41nWLHUbjXNRfxlcaJBK15cPpBd45LhSjsbgsdpUoDvyckY5xXoh1LXtG+GmtpcL4f1nS7iyntJLvwyHuJzdNDzcXTkhcbRl3+9kqe9cHYaJ/Zfw8tp4PFN9efartZ9U0nQNQ8zydOaIGV5YQBtkGNrFvkGVBoA2NKv/AA34W8ZXvj/V7vStXsdVlkns9PtJI7i9s5JZBMjyRtgRsgUqSGJViAM5zXUeI7/R/iN5eoT3fivwx5NoJ9LudTkSy017gZaJwx3ZkO/OV52KcdK5v4f+GPh9JrN5pd/qMdzPq9k509pJ7d1ghlZVjQ5GVvlOeFBAzxmtid9SjuJdLv7K0toNIc6bp7eK4mTR57WI7Y5Rnhrxhn5lAUxhsAUAV/AupTR6za6pYLpt94iXU00HUFsAZVnsNytJqDYO9nZ8ZnY7TkZGa+g68Q+HHir/AIqG4/4kPhX/AI+20z/imLP/AEn76f6Q3P8Ax6er+u3ivb6ACiiigArj/iH4uvPB2naPeWdn9s+1arDZzQrEZJGjYOWEShhmQ7QFzxk9K7CuL+I2uQ6Bb+HLi4tdNmgl122hkkv4wy2ykOTKpJAR1A4btzQBHrOu+G/Ffh59Oi1XSrfW54j9htr64jS5s7xkKx5XJaOZHbHy/Mpzjmsv4f2cMdxeaJrOj+IL7VFt3ivNX1u2EsE65VHhhmb5mgZsuqEcgsTXkms2v/CLfGR5by40qex8SSm5hv1fd9jt7i4O24ikOBHMgUsrjIXrzXpemW0MejeKH0bxP4uvtUXTLuOztNTvxK067RsurZF+ZkZsBJB1yQKANRfBtn4c/wCEn8UXkMGl7NPurWGPw8og22Y/eLJgqMXPB+YHbwvpXlH9n2d94h/sPwv4hsb+x1zSvtjp4nvRL5d5M+wlRGMC7AK44LDLcmtDxhrPiSx8Q+Dorp9cuLGDw/ZXmuWCGR/MjV2+0GaMnByBtbfwejGtjUPAXg/S/wCwvGmlHVYr7WdQt5dJtWMK20NxNmWFZUVQVhBADBGJA4GetAHT+HPh5Z2Pw8k0PSNb+0X0F2bi8RLsPbSXixBHtpgq5NuSBujI3Eda4TWBpsfjrR7e10DUtG1S3eCHXo7WzW30uewWUi4lIHzNAzfxP8pQDd0rU8UTePLH7ZpF5os9v58T6hDe+B7WdPMvG3KouHPVTglwBuPyHNcvYah48vvENtL4h8PX1vYz6Uugahf3FlOnl2bOPNneRzgSAFmLt8o6kUAdBJ4Rs/B2o6h4j0q88K3mt3V3JeaTplzKJI2s2O+E28SqGNwXUKmw7cEgHNXPCmm694ttw/xHaOx0ttd+12lpfl4p5brC7LdUmBU25VpAEHzEggd6jutP0f8AcXkXiHw5qF9YRLpVjDa3qS3P9nJzG8C4z/aOeFK4TJGBW3AkPi3wLEnje91Lw1BpmsAaZd3kos7uVY4v3TyPLkGUhnJK4yykjoaAMjwd43htfi5q3h+38GabDBFcTWUdxomlhZ0UTqgeZg2BEByxx128V7nXzp8KvE8OjfEvWtEt9Ok1mC4vZxHq8EAuLsq0yIHlmBA8jA3scfeOe9fRdABRRRQAVzfjW50210aF9U8MXfiKA3ChbS1sFu2RtrfOUbgADIz/ALQHeukrz/4sSXn9neGrOz1K+0/7f4gtbOaaxnMUnluHDAMPwPORkDigDkNZ0jWNF8Gvq8XhCx1++vdVL2Nlfaa91Jp+nPGWjgKYBi8sjGxSUUsQOtRvoepaz4FtLjS7q78K+Ip9TSBpNYkaxYKYs/ZLQqC/2feR5cX+ye4rL/tfw3/wmX/CL/8ACX/E77d/aH9n+Z/aUfl+Z5nl5znO3PfGcdqk1DUte0/4aeJUt1u9en07xRdWkd3fh7qeyhjhOLhXBzG6EZD8BSxPegDP8ReFPiDdeOtAsNZF3NBLZW+l3mo6J9oZXtTKQ/nSMMFyMs2fl+6SK6B9Nm0C4tLLw22s6tqlrqaWMGl+KCZ4LaFThb+KJAGSJWCqsw4ALDHNT6B4d161uPCPiC48SeLtR0vULezeS3gvnmZLqQhyZVI2i1C8McluaZ8QYf8Aj/8AFE+tX39t/a5NB0uPwrdf78kUVyD83mb/AL6qf7uBmgDX8ZeJPHn9ozeF9Ij0r7d/wjR1C8kiWfzPMy0bi2KnO7ONgIznqa840y51i+1HRp18S65cWMF3Ba+ItJ1a+d5I9pBuZHh6C0AO0tJ0OQ1bFrDeQ/Dyf7ZrWq6p42eVnh/sO6M+pWsZi+WC5z+9SFZc70HAcr3NV9G0az1TTkvPFqa5oetyY067h0sC2kmsyAXvbxZAWaMuWEkx+UlRkZBoALrwvefDnxlB40isdD1fRNV1VYrG1tYjcSJHLJ5sbQJhVEgRMKVYjJAGQc0aVr95D8Q7288f6Rrj+FtSu5IrCHW7Ym2tZJJQY2ZZjsTbHvBK5IG7HGa3PiYdB8MW/gW/t9fu7uDS7iwMenR3iSLLaxByLgRjAZyF2+Zwpzjise98a6D41uNN0uwg8QX0C+I4tZ1BtXRJYLW1yVkXhiEgUMOGG0AnJoA7P4T6FeWPiHxLqMWlaVb6JPqF19huVtylzJGzo0flNjabYoMrt4J6cV6xXD+B9V8SapqOo+fYaVZ+FrWWW10v7PDJHJNGpXypEySjQmM8MvBI44ruKACiiigArz/4sR3n9neGryz02+1D7B4gtbyaGxgMsnloHLEKPwHOBkjmvQKKAPnj+yPDf/CZf8JR/wAIh8Tvt39of2h5f9mx+X5nmeZjGM7c9s5x3q5Lc+KrX4aeK30vwxqRn17xHeBrS6sJfPS1nh++EXkEHAzyucjmve6KAPnzw14E8bazb6Q9h4h8T6LpdukNvqFpqd7NbzhlA8w2yBSvlbSAm7uCD0rU1Xwvea14hsrPwvY65YX2h3cdy82txGLTdQkhcg3DNGCZbiQlSX4LIG6V7fRQB4/4o+HGsWPg281Hw5c/Z/FM92+p6jc2rukkm6Nmlt4GRd5jMgUqjdTjJzXKDwVqUnirRE1mfx5cwavoUEV5dwOztBNK/wA8MrsuFgUZLIckZyc19F0UAeXyfDSz0vTtQs7y2/tzRI9KkWGa5jFzq0MgGFit2KhVjCAlFHIdj2NeQeEbLxJ4O8ZXV5Z+CNcvNEut9nNDfaVJJI1m0ilgVGFMhRQOflyTxivq+igDxP4f+LfFWn+KrzS7/wAKeIF8O3t6509pNOlDWSu6rGhydkcCIDwoO3txXtlFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAf/Z", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "102000", + "Speciality": [ + "Specialist Internal Medicine" + ], + "SpecialityN": [ + "أخصائي أمراض باطنية" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 252136, + "Name": "WALID AHMED ALKERIDY", + "ProjectID": 16, + "ProjectName": "Takhassusi Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.8, + "DoctorAvailability": null, + "DoctorID": 252136, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.719364", + "Longitude": "46.657567", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 1488, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 1.4, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Takhassusi", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "102000", + "Speciality": [ + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 397869, + "Name": "ABDULRAHMAN ALI AL OTAIBI ", + "ProjectID": 16, + "ProjectName": "Takhassusi Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.79, + "DoctorAvailability": null, + "DoctorID": 397869, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.719364", + "Longitude": "46.657567", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 1411, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 1.4, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Takhassusi", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "102000", + "Speciality": [ + "Specialist Internal Medicine" + ], + "SpecialityN": [ + "أخصائي أمراض باطنية" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 418918, + "Name": "MOHAMMED GHANNAM THALLAB ALHARBI", + "ProjectID": 16, + "ProjectName": "Takhassusi Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.77, + "DoctorAvailability": null, + "DoctorID": 418918, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/TAKHSUSI/418918.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": true, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.719364", + "Longitude": "46.657567", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 119, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 1.4, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Takhassusi", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "102000", + "Speciality": [ + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 190045, + "Name": "MAISA KANGER", + "ProjectID": 140, + "ProjectName": "Women-Health Hospital", + "ActualDoctorRate": 3, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 3, + "DoctorAvailability": null, + "DoctorID": 190045, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 3, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.722985232854427", + "Longitude": "46.65414917392709", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SYR.png", + "NationalityID": "SYR", + "NationalityName": "Syrian", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 748, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 2, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Women Health", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "012344", + "Speciality": [ + "Specialist Internal Medicine" + ], + "SpecialityN": [ + "أخصائي أمراض باطنية" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 350852, + "Name": "Ahmad Ramadan", + "ProjectID": 80, + "ProjectName": "AlNakheel Medical-Center", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.88, + "DoctorAvailability": null, + "DoctorID": 350852, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DC/350852.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.7403156", + "Longitude": "46.6352264", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/LBN.png", + "NationalityID": "LBN", + "NationalityName": "Lebanese", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 4609, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 4.7, + "ProjectNameBottom": "Medical Center", + "ProjectNameTop": "AlNakheel Digital City", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "012576", + "Speciality": [ + "Specialist Internal Medicine" + ], + "SpecialityN": [ + "أخصائي أمراض باطنية" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 413076, + "Name": "AYAT HAITHAM", + "ProjectID": 80, + "ProjectName": "AlNakheel Medical-Center", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.84, + "DoctorAvailability": null, + "DoctorID": 413076, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DC/413076.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.7403156", + "Longitude": "46.6352264", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/JOR.png", + "NationalityID": "JOR", + "NationalityName": "Jordanian", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 413, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 4.7, + "ProjectNameBottom": "Medical Center", + "ProjectNameTop": "AlNakheel Digital City", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "012576", + "Speciality": [ + "Specialist Internal Medicine" + ], + "SpecialityN": [ + "أخصائي أمراض باطنية" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 417022, + "Name": "MOHAMMED ALAHMARI", + "ProjectID": 80, + "ProjectName": "AlNakheel Medical-Center", + "ActualDoctorRate": 4, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.41, + "DoctorAvailability": null, + "DoctorID": 417022, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 4.5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.7403156", + "Longitude": "46.6352264", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 41, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 4.7, + "ProjectNameBottom": "Medical Center", + "ProjectNameTop": "AlNakheel Digital City", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "012576", + "Speciality": [ + "Specialist Internal Medicine" + ], + "SpecialityN": [ + "أخصائي أمراض باطنية" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Ms", + "ID": 1482, + "Name": "FOUZIA DRIDI BOUHEDJA", + "ProjectID": 70, + "ProjectName": "Diplomatic-Quarter Medical-Center", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.87, + "DoctorAvailability": null, + "DoctorID": 1482, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DQ/1482.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.674988", + "Longitude": "46.629421", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/DZA.png", + "NationalityID": "DZA", + "NationalityName": "Algerian", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 15290, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 5.3, + "ProjectNameBottom": "Medical Center", + "ProjectNameTop": "Diplomatic Quarter", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "011564", + "Speciality": [ + "Consultant Gastroentrologist", + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري الجهاز الهضمي", + "استشاري طب الباطنية\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 337922, + "Name": "ABDULRAHMAN KHOJAH", + "ProjectID": 70, + "ProjectName": "Diplomatic-Quarter Medical-Center", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.6, + "DoctorAvailability": null, + "DoctorID": 337922, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DQ/337922.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.674988", + "Longitude": "46.629421", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 6279, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 5.3, + "ProjectNameBottom": "Medical Center", + "ProjectNameTop": "Diplomatic Quarter", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "011564", + "Speciality": [ + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "", + "ID": 39819, + "Name": "MONA METAWEE MONA METAWEE", + "ProjectID": 154, + "ProjectName": "AlGhadeer Medical-Center", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.78, + "DoctorAvailability": null, + "DoctorID": 39819, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.7763844", + "Longitude": "46.6621208", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/EGY.png", + "NationalityID": "EGY", + "NationalityName": "EGYPT, ARAB REPUBLIC OF                              ", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 1109, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 7.5, + "ProjectNameBottom": "Medical Center", + "ProjectNameTop": "AlGhadeer", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "107", + "Speciality": [ + "Specialist Internal Medicine" + ], + "SpecialityN": [ + "أخصائي أمراض باطنية" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "", + "ID": 38271, + "Name": "ZAIN KHALILAH ZAIN KHALILAH", + "ProjectID": 154, + "ProjectName": "AlGhadeer Medical-Center", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.76, + "DoctorAvailability": null, + "DoctorID": 38271, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/AlGhadeer/38271.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.7763844", + "Longitude": "46.6621208", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/JOR.png", + "NationalityID": "JOR", + "NationalityName": "JORDAN, HASHEMITE KINGDOM OF                         ", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 796, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 7.5, + "ProjectNameBottom": "Medical Center", + "ProjectNameTop": "AlGhadeer", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "107", + "Speciality": [ + "Specialist Internal Medicine" + ], + "SpecialityN": [ + "أخصائي أمراض باطنية" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "", + "ID": 34030, + "Name": "ABDULLAH SAEED ALGHAMDI ABDULLAH SAEED ALGHAMDI", + "ProjectID": 154, + "ProjectName": "AlGhadeer Medical-Center", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.8, + "DoctorAvailability": null, + "DoctorID": 34030, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.7763844", + "Longitude": "46.6621208", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "SAUDI ARABIA, KINGDOM OF                             ", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 237, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 7.5, + "ProjectNameBottom": "Medical Center", + "ProjectNameTop": "AlGhadeer", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "107", + "Speciality": [ + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري طب الباطنية " + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "", + "ID": 50932, + "Name": "ZIYAD ALFARAJ ZIYAD ALFARAJ", + "ProjectID": 154, + "ProjectName": "AlGhadeer Medical-Center", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.8, + "DoctorAvailability": null, + "DoctorID": 50932, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.7763844", + "Longitude": "46.6621208", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "SAUDI ARABIA, KINGDOM OF                             ", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 230, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 7.5, + "ProjectNameBottom": "Medical Center", + "ProjectNameTop": "AlGhadeer", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "107", + "Speciality": [ + "Consultant Nephrologist" + ], + "SpecialityN": [ + "استشاري أمراض الكلى " + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 13180, + "Name": "SADIG MOHEMMED YAHYA MONAWAR", + "ProjectID": 15, + "ProjectName": "Arryan Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.9, + "DoctorAvailability": null, + "DoctorID": 13180, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/RAYAN/13180.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": true, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": true, + "Latitude": "24.722136", + "Longitude": "46.774303", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/USA.png", + "NationalityID": "USA", + "NationalityName": "American", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 17796, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 11.1, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Arryan", + "QR": "data:image/png;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCABkAGQDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3+iiuf8XeLrPwdp1reXlnfXn2q7SzhhsYhJI0jBioClhnO0jjnJHFAHQUV5//AMLT/wCpC8c/+Cf/AOzq5pvxK03U9GbVE0nWYYItT/s26Wa2VWtGChnlm+bEcSA/MxPHcUAdpRXB6b8VdN1nWWsNL0LxBfQLe/Ym1G1tFltA24DeZFcjZghs/wB0g4rUh8aedqOr2f8AwjPiNP7Niml857DEd15Zxthbd87N1UcZFAHUUVx918R9Hh06Ceztr7VL59vnaVp0aT3trkZbzoQ2U2nCtnoxA71oaN4us9U05Ly8s77Q/MuxZww6zELaSaQgFQiljuzkgY5JU8cUAdBRXP8A/CVf9QHXP+Qr/Zn/AB5/+THX/j3/ANv9K5+T4sWf9o6hZ2fhXxXqH2C7ks5prHThLH5iHDAMH+h5wcEcUAegUV5/H8WLP+0dPs7zwr4r0/7fdx2cM19pwij8xzhQWL/U8ZOAeK9AoAKKKKACvP8A4p/8yV/2Ndj/AOz16BXn/wAXP7H/AOEe0r+1/wC3P+QrD9j/ALE2faftGyTZt3fjjHOduKAPMP8Ai4//AAuT/ma/7E/4SD/p4+zfZ/tH/fPl7Pwx7V6H4CeGPRviG9xZSX0C+I9SMlpHEJWnXauUCHhiw4x3ziuQebQV1m00tPGPxKmnlt0uLpotTRl05S21xdd4jGfv5Hy960/Js/DXg3+0NI1rVbOxtfEv9oXlzq90I5NWjWPc4t2XAnWUKCgPDkHJoAkstS03w1b6lZeH1u7nS9XSW4uNL0gK+saZdSgBh5SELDFGqqvOWWQgc1gabeTWtw3itNY+Id34d0u4+z3VjNcl7tLqIiRzNH9wW4T5WyQ244OBXNyar4ksf7Q8UaHYQW/n63Jq6xtDImpSWbfvA0oQ82RwNxztL96sR+MvO07T59Mm32OpeII7rWtKVs3t1cSDM8cUKth7RhhVV8ktwaANhdG0fVP+En8W6GnxA0O+k0+61VbyYJbW02f3gRXQEspJBAzyFznisu58dTazb+Hb9LyS+gW3ttGutOllMt+LrGXvrWPcR5uDtSY/NuOCK6Tw5r/27UZPCWr6R4yt/P1s31nZpbbI49OYiNIZkY8WwyQyAbAOAax9d8O3ngjxDqcs/hf7RYwXcuv6Xf6Rp5f7PIrnyoLiQgBbdQu50XkcEGgDt/C9/Z+HPser3l38QH/tLUE0WGy8QyA7ZJNrLLsOMLwRuBJ+8MVyGr/8JJ/whvin/hF/7V+3f8J1d7/7M8zzPL8s5z5fO3O32zisvw14g8VeNbjSHuLi0voF8Ww38lpG8st3arkZYISQlqobGezHGa7uHw14bm8Q6vF/wmPivw3fXmqzN9gfU47P7VI7/wCthjxl42Pyq3U7cdqAOY0j/hJP+EN8Lf8ACUf2r9u/4Tq02f2n5nmeX5YxjzOdud3tnNfQ9eT6h4L0fS/EOhRXnibxlrl9HqFvcw2DX6XPk4c7biWMqCsIIKs46bsd69YoAKKKKACuH+Jv2P8As7QfP8/7d/bdv/ZezHl/bMP5XnZ58nP3tvzY6V3Fcn8QJ5rXRrO4t5fDEM8V6jxyeI2KwIwViDGRyJQeh9N1AHlnh66vPCn/AAnV54ot/CtvfT/2hKkN2hS5vJGwQsayYMlo5VgB1Y5rDvdDm8d6Nptvb3XiDSZ7p4po49ekMGjlmUgRWQAY5y/7tf8AnmG9K2LKCHxP4V1LWfEEUerapa+KJUt72BRPaRKqBlErvll08MzMwB4U5711fhy1+3adJZ6vcQW+iTymKzmun2SR6iwARtMZvlFsEJMBHzg5xxQBnx6V4b+Ff9nz65f6rr+t3unx6Q2lLNHdZjfkrFC4VvJ3xlVHI+bGMmrGqx+BNF+xeNNO02xt76fy9Kt7WWCBLbT7xsyq9yi4MUkZADkNuUcY71TsoNN1O41LSbCLUrufS72VNQ8T+JlWRrSGIhZBa3Q5jlQkSIGAAyzHFVLrwDZ2PiGDTrPxbpV/omuRLJNba5qQluZJJn2tdWyhdpmKABJDkkluooAsa/4os/GOnaXLpl99j1u11WKx1q/0mURyLZqD58ySKSwtA7Bg7/LkAkZqPUtW8VaNcL4gTUNN8VeD4E/si6t7KaW+Y2oJd551yI/P8oYZydvzDIwax0vfCujeOruwTStSsfDraY/hG61FbeKJTdebh5Xk4TOwbix+bjJXFb/gqz1LwJrM3hR9Hk13wfrTtcWt9ZWzXShZmWNBPJ8sezyk3NgH7wIyDQBQ8P3ngm68dQao+sWnh2cW63dquj3MNpaPa+aGS3u+5uCf9YgO3aoweKjs/wCx/wDhIfFviHxf/bn/AC+f2RqU+z7N9n374fsUsn/Lx95o9hxjkd609Q+Heg+EvFXiXW7ePRr6BdCur+PSL9UlaKbeXDLCFAEAC7Ac5GSM1qeEdV8N33w8up9csJ7jyIn1dtK1SGN/LjWJSWs4XPFsMlYz0HIzQBxnhA6bJ46064fX/F2tapcPHNayafeLcLBYNKpSG9P3lKt/rVHyjIx1r6Lr5w0xrzVPGWja5ofhPXND8zVYIlfTtONtZTaUZA4aYpndIcjcc7Cqj0r6PoAKKKKACuL+JQ1KTRtMt9L0DTdZnuNTihaPUrNriCBWVx5rBeVCnGW7An1rtKr3V/Z2PkfbLuC38+VYIfOkCeZI33UXPVjg4A5NAHgniLwdqXgTWdAvzrMdp4d1TU7dNY06O6ZLQTSsTOBHtVPs+xNuHydowcirCXs2n+Oru4stK8QX3h1bdzpsmq25l0uyuvNzFcRkfJHaogGJF+ZUJxxV/WtS1LQLfXn1tdG8W6Xd6xcRaVaKGv57a/cHyYXRiFRFUEFF+YF8DrVzwrpX9u+Htatft+uafrd/pU9r/YOrzeVbW+9FHmW9vgslurnYjc4AK9aAI9S8HQ6Noy+IE1nWbmfV7j7VdW9ldB9HM0ql3knXaD9jyMMxJPlkZzWB4O8MabrNvq3jzxBqN3PP4Z1OY28Olzq1oIbYLMqQBwT5WSwUBlG3HTrViDUNN8CXEWjHxVJq09rpgGsWWp6gs9gIVO2e3tkyp+0ZTakbjG0kHrUd/wCD9H13w9cz+APHH9n/AG/dqF/pVxqyRW1vbuhMgeGFTs25RSGyABgnpQBz/naPqnxD8/8AsXxzeaJdf8T7+yvsqSedcNLnzfJ5Vrcodu7qc4ziukTxXr1746u9GsjIsF7oT2Wm2Wj7wulM8u2J7tAcQSxAhZCoOzgAVc8BaVrEOnHQbO/sdUvn/dzeIrWZ547XTiFRrWC5AylwpxIsZGwAhu9ZafCrUvCXiq71nVNd1ldLvbh4VvdHu2F3Ervu867dkCiIKpaRsnDYNAFiDxFNpnxLit9Z8N+INWntfC40i8jjsTO12yzYecBjmSByD85655HNSeLvFVnY/Zde0PQZ7fW54k8PL4d1mzCeZZtucMlsh3FS4EYOdp5XbmuDvYtStfi5pthb+ObvUYNQuIrWPUbDVmmnS1knIEbSDgOB8xXlckGvV9Q03QdG8C+Jb2/bUm1Sye6t9P1TxMUN2ZkiJjNrKQG2bgWTbg7txFABrXifUpLjwB4bsNO1Kx1Rn07UtQgsIGiggtcmOSJlB3KitgFWG0ADJr1yvnzS9W8VazceCrhNQ8P3063Fil1Jo80suqC1yC4uzknysn94D8u8jNfQdABRRRQAV5/8WNGvNd07w1Z2aX3/ACMFq001iD5lvHhw0oYA7NuQdx4BxXoFef8AxYkvP7O8NWdnqV9p/wBv8QWtnNNYzmKTy3DhgGH4HnIyBxQByFz4CvLHw94gvPC51y4voLu5Dw+IiX8yRUyby0WNcm4JCiOXqfmrH0bX/GGhbJbPSJ/t39ngzX/jC2m+03Fxxus7SQEF1YgNHEeSd5o/tfw3/wAJl/wi/wDwl/xO+3f2h/Z/mf2lH5fmeZ5ec5ztz3xnHarkviCHQPhp4rTW7jUtWntfEd5pulXd04nntplh/cyh2IKFSCdy8gkkDmgDT1+w8CeK/D2l/wBq2kFvrc8sU+rf2HHAlzZyMh857ndlo4UdjvL8qduea4yDwd4V8MeKovD9/rPiAz684TT7jRLqLyJbCd9kYmYqCxJUlgoKkbcZrH0mCG6t7HWfDMXiebVJbiNNbvdUUNpbqQGuBO6fMYi21mDn7mSa6S2/4uN8ZPD/APZH2GD/AIRu0tvtnlfLbP8AZ7j5/s23dmM7xszjjrigDU02y034feOm8P6XqniC58O6vb/2W1xa3CutpqcsoTll2okqogPQuMjgit86xDo2ja34UuND+JWswXDz28l9PaC4Yqy+WTFISBswNy8d896j8NeEbO48ZeKrO8vL68+1Xd3eQzWMoksrGRpAFIYr+7v05PHKqRzRr+p+JNL8ZaXF4L12x1zy7SLR7mwuruS5khkEh33U8cRG3GEVpDyCxGORQB55rmk6D4Mt7a48H6frOo6pqCLaiS/hSZbCaQE+WpjAaK+RlXC8lcn2rU8VfEnxJY+HtFs9R8FfaLGC0giuJvE+lSP5l4qMGZWZsHIBIJ+Y/NXJzv4q0b4lyvrNlqTQWWsHXby0s4pTAVSb57iNGwNmAQHOOMAmuo8V+MYfE/hU3Hh/RvE+rQWuu/2vcSavaie0iVUYtBlGIWIBl+Q9FJ55oAy/hTa/8JH4yW80i4n0vW01D7deQ27+RZNpwkQvCirli28gBD8m0cnIr6nry/SNGs/Efh7wtrnhBND0u+S7tLjV30wCDdGEDzWxMYJPJX925xwM9BXqFABRRRQAV5/8WI7z+zvDV5Z6bfah9g8QWt5NDYwGWTy0DliFH4DnAyRzXoFFAHzx/ZHhv/hMv+Eo/wCEQ+J327+0P7Q8v+zY/L8zzPMxjGdue2c471cMWpSeBdbe48G6lcwav4tnlktJ9MZ7uC1li5miQ8LKo4V+VDHHNe90UAfNEfhfWNC/s/U/Dlj4y/4Rb+0I4tR0O+if7TcfxSsYEAR4WjCpljycg8V0njXwhNa3EPivw3pms6TBdaOtvBY+H7cwXaXTFpFNxGi4EQG1Xwd24KO1e50UAeb+F9G8Yf8ACvLOzlTStPvr+VGvpoRNFc/Z3iUSSs2M/bc8lmyMjmuYutC1ix8ZQaj4c0q+t7Gfb4Z1G5mt3S9k3SbpdQVkGDkBSJ26t1Wvb6KAPM/GOk6bdXGk+GbjT/F008tvDaya9pkKszwktGY7m4IyUJ+d1xjo1eea/pniS38ZaXofgvQtcs9EtfKsblLq0kjsr6RZCjzTiIbZI3TZucjLKDxjFfR9FAHjdzpPxB0a48O26af4fsdLbXbZ7qPwvDcRMVzhzKMBfK2j5ifRc17JRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAH/2Q==", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "010266", + "Speciality": [ + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 13325, + "Name": "ALI KHALED AL QAMMAZ", + "ProjectID": 15, + "ProjectName": "Arryan Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.84, + "DoctorAvailability": null, + "DoctorID": 13325, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/RAYAN/13325.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": true, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": true, + "Latitude": "24.722136", + "Longitude": "46.774303", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/JOR.png", + "NationalityID": "JOR", + "NationalityName": "Jordanian", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 16086, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 11.1, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Arryan", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "010266", + "Speciality": [ + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 14679, + "Name": "ABDEL RAHIM TAHA MOHAMMED", + "ProjectID": 15, + "ProjectName": "Arryan Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.82, + "DoctorAvailability": null, + "DoctorID": 14679, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/RAYAN/14679.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": true, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": true, + "Latitude": "24.722136", + "Longitude": "46.774303", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SDN.png", + "NationalityID": "SDN", + "NationalityName": "Sudanese", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 13224, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 11.1, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Arryan", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "010266", + "Speciality": [ + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 13342, + "Name": "HAITHAM MAMOUN ELFADIL MOHAMED", + "ProjectID": 15, + "ProjectName": "Arryan Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.9, + "DoctorAvailability": null, + "DoctorID": 13342, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/RAYAN/13342.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": true, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": true, + "Latitude": "24.722136", + "Longitude": "46.774303", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SDN.png", + "NationalityID": "SDN", + "NationalityName": "Sudanese", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 11384, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 11.1, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Arryan", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "010266", + "Speciality": [ + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 109549, + "Name": "NOURA HAMDAN ", + "ProjectID": 15, + "ProjectName": "Arryan Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.83, + "DoctorAvailability": null, + "DoctorID": 109549, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": true, + "Latitude": "24.722136", + "Longitude": "46.774303", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/LBN.png", + "NationalityID": "LBN", + "NationalityName": "Lebanese", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 4742, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 11.1, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Arryan", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "010266", + "Speciality": [ + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 109498, + "Name": "IBRAHIM MOTABI", + "ProjectID": 15, + "ProjectName": "Arryan Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.52, + "DoctorAvailability": null, + "DoctorID": 109498, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/RAYAN/109498.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": true, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.722136", + "Longitude": "46.774303", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 4316, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 11.1, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Arryan", + "QR": "data:image/png;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCABkAGQDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3+iiuf8XeLrPwdp1reXlnfXn2q7SzhhsYhJI0jBioClhnO0jjnJHFAHQUV5//AMLT/wCpC8c/+Cf/AOzrQ0r4j6Pqnh691f7NfWf2W7ksfsV3GkdzNcKgbyY03HdIc4C5ySCMUAdhRXnepfGPQdG0Zb/VNM1mxna48ldOuoEiuyu0nzRGzg+VkFd394EUab8Y9B1C4a3fTNZsZ2svttrHewJE16uQESAb8yO5PygfewcGgD0SiuT0P4iaDrOjXOqXEkmjQW961hIursluwmVQxXliM4PTOeDxxWXp/wAYPDeqajrtnZw30v8AY1pcXk0yrG0c0cJAYxMHO7OQVzgEdxQB6BRXlek/HzwrrOs2Ol2+n6ys97cR28bSQxBQzsFBOJCcZPoa1JPixZ/2jqFnZ+FfFeofYLuSzmmsdOEsfmIcMAwf6HnBwRxQB6BRXn8fxYs/7R0+zvPCvivT/t93HZwzX2nCKPzHOFBYv9Txk4B4r0CgAooooAK8/wDin/zJX/Y12P8A7PXoFed/GOfQbXwrp9x4gl1mGCLU43t5NIZFnSYJIVOX4AA3cjnOKAPNP+Lj/wDC5P8Ama/7E/4SD/p4+zfZ/tH/AHz5ez8Me1XNQTTZPCviVL+9u7GdvHt0NPu4JViWC62Hy3lc8rEpyWK/MMZFbejaRo+u7JbPx38QPsP9ni+mv21dPs1v03QyyAEJMoIZkPQc5rIutGs7zToPDmhpff8AIwLqq6n4sA+xapJjYEjlQfvvN4YDGXXcc0AYepaTr3hK3XWdU0+TxrqklvvW9uoX1LS4rAgtkOwDCUMpbOdoRye9bmjahZ67pyeI/Efh6+/tv7INO07TNBsh5lvZ4DxXsMTksm1yyrMp2g7QBmtvR0mutG1h729ux4d0G4nk1K0hlO57qBR5trCh+Q6eUyFjbDdjgV554c8e/bvGUlnaie38/UCdDmQbJI90gFvZzMG4shnLRJ0P3aAO7HhTTdf+JeiaNcDUodLi0KDW5LK52q1zdCbaXukIKvKynbIcbj0zVi21qHRrjxFYP8N47Gdri5srXUYtDEVgbXOEe6kyD5WRucj5doyBWh4gttN8MaNPqmqeJ44fGESNqqq1+qtKwUt9jTdiRrMyqcRZ59c1iXniKzvvD3hKKDxR9vvtc8QWdxqlh/aAl8uOZP3tt5YORbgnb5bZAzg5oA4fwFrd5D8QzpFn4W8Oapv1vz5r2108z/ZYzKqs8Dg/JCvBUkYGQe9dBq//AAkn/CG+Kf8AhF/7V+3f8J1d7/7M8zzPL8s5z5fO3O32zitjzvB/g7xD5H9i+K9D8zxBv/tX7LDbWzZfHkedxm0O3ds9Fz2rPhk8N33iHV5dI1L4j29jPqszXl/pk8aabHIz/PKZF4EYBDbjyEwTQBX0j/hJP+EN8Lf8JR/av27/AITq02f2n5nmeX5YxjzOdud3tnNfQ9eGeH7bwrr/AIqgR/E/jW7g0vU1Nrd6rfxSWFzdRONiRvyHdgcgDDFSSMV7nQAUUUUAFcP8Vrr7D4Na8+z+HLjyJfN8nX03xybY3O2Je8xxhR3G6u4rj/iX4Rs/GPg24s7y8+x/Zd15DM0ojjWRY3CmVipxGNxLY5wOtAHJ/DF4fiD4Fd7iytNGgt9YJktNEiFvBdqsSZSZDuDowfDDuAo7VgatqWpSeKr7wHoy2ljAzyXFnN4pDRNBNvMKDTypwqKMGHC5GGx6UT22peHvAsul3/ifwxo0Fvphv9Pbw5ftb3d/MsW2NpM4EqSAHJUZZguDxVPwvYXl99j8Q2dpqtxrcGnpPNqXjiMvpsca7XZ7eUfMGDkMhJwE3nrQBcT4f+NtQ8K3fh/RL6Sxga9d9VuNVmminvbrZsmMbKuJLVwQQWG5iDmrniHw7Z+HP+EF0yDwvsvtNu9PvNU1y008C2WOPKymScAEcjedwAxgk1P4j1zWL7UY7zSPiF4Nt/P0QWN5C+tOkcdwxJeaFVPDDICueQOorkPF0njC3+HlrZ2epareWN1qCWc01zPNJc31w0TBhbsOJLJxgpnliTxQBY8e6z4b0vxkLzQ3/wCEz1vUflWHUTHqNlDHJIxEUKoQyyBwAq8gK57muj1jVPCun2+j+H38I2mmeMNb0yB7W4tdNihWyupgUQls+ZGUlGcgFlwMZNQWdn4VutG0rS9L0eMeMNB0eHW2aytotz3UC7fs0+394XMuN0eA3TkGuf8AGt5puk6ND4rTWI9R8Yagi291Y3tyszaQ0itI5gj4kgeKUbVyTsyQeaAOv+JXgrxtr/gXTNLSfTbuDS7KK4umZ5pLu5uoonVwnykOGB4yAxY84rE+HH9sf8I9ceHvCH9h/wAX9r6b4n3/AGn7RsRJtsUf/Lv91RvGc7ge1XPAuta9J4VtdEuPEUdzPq9wkkmrz3rusEMqKhtYpicrfKfnWPBAznmuL8NaV4ksfiH4qg0O/gt/Plu9IXVtZmkTzJGlACpMg5uTgMB1PJxQB2mveFNS8JXHhC3Qaaul3viiyvbqOHcGiv3JDpCMBRbhV+UHLDua9zrxBvFFnqmo+GND1y+83+xtVtbFkhlDXs2qwnYZmDk7rQ5OXwHLdhXt9ABRRRQAVy/xB0D/AISPwbf2f9rz6Xsikl85LnyI2xG42zNg5h5yw9B7V1Fcn8QL3XrXRrO38P6VaajPqF6llcR3lu80CQyKwZ5AnIQHbknIwTxQB4Zo2t/YfGSf8Jp4W/tmx0nw+LO2+w6f9ojkt4pBsux5pwYyA/70YBBHAya1J59N8T3EujaNL8SrSfVLcvZ2UjLHYRQynahKLkragsFyAQFGBmtzxdYaxrWnWvm2ljoFjZbNLvvIje1vdQ2BvMtrHqJbeQH91G2NzLyOK5+1ks/C2oz3kWpa5p/2/Sm0Cxh8QziK9s5HOY59vHl2ibcb1yVYNgUAakGgaa1xFYaz4KkstL8LaYL281GPSljbUbq2OHQSMNssEi5bB2s2MkitvxH4us/Efw8ji8PWdjpd8mG0+w1qIQXLRiI+VLYxoxJkyVWJl4yCB0rEsoprrwLqXhnxB45kmnleW5t9eg1YtYOxiEa2ctw/JJO52iA+781bc3hGzm+HmkS+L7yxS+03yV0i/wDDkoFzdRxxfuYo5JFy8jHcwVMAnaR3oAxINS1LRtGi0S4XwxoPjDUdMFxJq94GtWNrIuwiSYkSfbPNG88FflJ6itfxaNB8FeBfDOs3ugeH9ZnuLi1h1K9azS4a6VomaWVHOC7sVLBmPOcnrWZf3Wjzajc+I9Xt4E/s3w01jZ6Z4vRBe3VxGS6TeU331bld4IJbeAK5vxb4r02Twr4Z0bSzJrWqXF7a6y1k224tIGZGX7CiKdyorYUQ44U4zzQBsT+MYdT+Gktxo2jeH9JguvFB0+zkktRAtorQ5S6JVsRzoCP3g6Y4HFR+EfFV5ffatB1zQYLjRIJXhbxFo1mX8u8XahvnuXO0MEJkM2Nw4bpW3rnhrTdA+Edtf3GialNPLerrsmnQWqtBbXRgJMcsZAKWqkbWX7wHGa4j4Oalr2s+OtQsrBdNXS71JLjUNLnDi0ELyxiQRRAld+0hV3ZG3g0AdAPDGmx+OtE8SX+o6bfaWupwabp8+gzrLPPdeb5kct6xG1nZcmRlO4krgV9B15H4t0nwro3jrwzbvp/iCxga9tXtY9Khii0s3XmsEMgwB5uByR82wDFeuUAFFFFABXH/ABHuryx8PW95p1vrlxfQXay28OkIX8yRUcqtwq8m3JADgcniuwrz/wCLEl5/Z3hqzs9SvtP+3+ILWzmmsZzFJ5bhwwDD8DzkZA4oA5/wjH4813wbdXl5ptj/AG3/AMJA95DD4kgn8u3j8tSpgU5ZNrkhccAbuc1TnudBkuJdE8YeGPEFzqmr3psDq93YI8EE0p2bbOaT5lgVtzxjBIBJweaxP7X8N/8ACZf8Iv8A8Jf8Tvt39of2f5n9pR+X5nmeXnOc7c98Zx2rb0e2huvCusJrfieQT6D4tnOlXetX42vNAg8lJXbkoTksFwepGKAPLLm1vPDn/CQaVp1xY6pYvqtzo9vo925nuVkPyrdRwrgCTACCQDOSRjmvSLz/AISTS/BvhL/hL/7Ks7G1ls/7I8jzI5IbxY/3P23zMBYQA3mbPmBHHesfT7DWIdR126ltPCuqWL/aNavte02N55LXJBkitbjolwo+dFboSGJ5ro9NPhXxb8NGuH1/UmgstY861k8W3kRWW6SEFIZDyDAQ3KjDH58UAQXnh+a60bVb3xXbx6tqlqk3iWy1S1Qz2DwquY7IyyDcYi25vKXjaQQ3NeX+FNSm0/WR4rt18IrPe6n9kjsb8ELZM7LILhYwcxxIRtD5O3kYrtNZk8eaX4Ne8s9S0PXNEj1U3E0OjTz3McMYjJa2dRhVtAgAMZ4AYdjWhdav4b0vwbBL408CWMX9s2iy21/4e0iNY4Y5o/kXzJSNtwMO2BkAbTzzQBr2vijWPB3nxeNL7SvEdjr8rS21hpMr3ly3n/cVI5SAbYhXUAZ5YDnJrM0PVNNtfFVzcX/hHxB4Zn1h20LT5LDTVsoEhmcGORiTkXAOcsuRhRgHFZbXXhv/AIQ3wxrmh2+uah9g8V2tsr6ikct75aR7xbwlP+WfTamQNxNWPFXiSz13UdF8L+X4y0++v/EsGoeZq6iKS3jctHi3OSUVSfkGCAQeaAOvsNA87Ubaz1fV9VTRNN1tZbObX7nF7dajGQEWJmG17ZkyVAw5bdjivWK8Qm0+8m+MmkaH4v8AEOyx020hvNIRL0j7VJHcbITMJBh7hhu3bACex617fQAUUUUAFef/ABYjvP7O8NXlnpt9qH2DxBa3k0NjAZZPLQOWIUfgOcDJHNegUUAfPH9keG/+Ey/4Sj/hEPid9u/tD+0PL/s2Py/M8zzMYxnbntnOO9XDp+van4F1u3t/Cshn17xbOY49X0991pDPFgXGAMxlCf8AWcgc9a97ooA8QtfBusaR8LJ9O8OQ3yX2m6q11qNtqKuI9S8uDbLHCqKDNbyEKFVsbhnNX/DmkaPcfDyTTtR8Ia5F/bOqlLi2fTUX7DcTRBWnhVh+7t05CuclfevYKKAPJ5NCvPCniHUNO0PSp7jRIPB8m22a3L215eK+0eaqALJM6KA38TD2rItfG2sX3g2fTvEfwtvri+g3f2dbQ+H3eyj2x7Ytyu2RglgdvRele30UAfNniLw18QbW30DxNb6JpsMEVxb3Ueg6Ja3CqkwBkEk1uBgOB8jNnP3VrpLprzxj4Ng1zxp4T1yz1u11VYrZ/D2nGO9WNY96NmXLCMOz8g43Be+a9vooA8f1fQtHvvGXgvUbzSvHNxfQWlj5NyLdHjj2yFl+1sRkSAkmTHQV7BRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAH//Z", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "010266", + "Speciality": [ + "Consultant Internal Medicine", + "Consultant Hematologist " + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n", + "استشاري امراض الدم" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 122546, + "Name": "NASHAAT AHMED SAKR ", + "ProjectID": 15, + "ProjectName": "Arryan Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.8, + "DoctorAvailability": null, + "DoctorID": 122546, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": true, + "Latitude": "24.722136", + "Longitude": "46.774303", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/EGY.png", + "NationalityID": "EGY", + "NationalityName": "Egyptians", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 3305, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 11.1, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Arryan", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "010266", + "Speciality": [ + "Specialist Internal Medicine " + ], + "SpecialityN": [ + "أخصائي أمراض باطنة" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 235959, + "Name": "MOHAMMAD SALEH ALSHABEBI", + "ProjectID": 15, + "ProjectName": "Arryan Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.75, + "DoctorAvailability": null, + "DoctorID": 235959, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": true, + "Latitude": "24.722136", + "Longitude": "46.774303", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/YEM.png", + "NationalityID": "YEM", + "NationalityName": "Yemeni                                     ", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 2823, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 11.1, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Arryan", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "010266", + "Speciality": [ + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 70907, + "Name": "MOQBIL ABDULLAH AL HODAITHY", + "ProjectID": 15, + "ProjectName": "Arryan Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.79, + "DoctorAvailability": null, + "DoctorID": 70907, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/RAYAN/70907.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": true, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.722136", + "Longitude": "46.774303", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 2479, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 11.1, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Arryan", + "QR": "data:image/png;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCABkAGQDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3+iiuf8XeLrPwdp1reXlnfXn2q7SzhhsYhJI0jBioClhnO0jjnJHFAHQUV5//AMLT/wCpC8c/+Cf/AOzq5pvxK03U9GbVE0nWYYItT/s26Wa2VWtGChnlm+bEcSA/MxPHcUAdpRXnafF/Tbq4u00vw14n1aC1uHt2u9NsVngdlPVXV8EEYI9iD3rY1L4gabo1utxqljqVjA2mf2gsl1CsSlsE/ZQWYD7RgH937HmgDrKK4PQ/i74V1/Rrm/t55IZ4nZI9OneJbu5YKCBFGHJcsTtUd24rc0bxdZ6ppyXl5Z32h+Zdizhh1mIW0k0hAKhFLHdnJAxySp44oA6Ciuf/AOEq/wCoDrn/ACFf7M/48/8AyY6/8e/+3+lc/J8WLP8AtHULOz8K+K9Q+wXclnNNY6cJY/MQ4YBg/wBDzg4I4oA9Aorz+P4sWf8AaOn2d54V8V6f9vu47OGa+04RR+Y5woLF/qeMnAPFegUAFFFFABXn/wAU/wDmSv8Asa7H/wBnr0CvP/i5/Y//AAj2lf2v/bn/ACFYfsf9ibPtP2jZJs27vxxjnO3FAHmH/Fx/+Fyf8zX/AGJ/wkH/AE8fZvs/2j/vny9n4Y9q9D8BPDHo3xDe4spL6BfEepGS0jiErTrtXKBDwxYcY75xXKTLo8Oo6RZ/8JZ8Tn/tKWG285NRQx2txIcfZ5m/gmXqyckCtf8Asr/hGvD3/Eov9cs/sviv7Vef2vN5dzq21Pnjt9oHn+btGxT98g5oArw39n4f07V9O8L3cEVjrMU072ySBb3RbyYbS8yx4FvbQgKGPLI3rWQ3hqz/ALR8MXmueMb7xPok13a2bQw6mL2P+1SckMrjb9n2ZB/jw3TBrLSLXrq4u00vwbrNpqmqeKHu2u77THSB7CU/8e9y6/MYi2C6crgE810+h+H4dGuLnw34gt5G1SyvW8Z28GgIDAVQiNYEVwGzuDAIAONvzUAamr+E/Df9neKfFGneH59IvtK0+7s7eN7KO3j8yIGRbuEKM7s42ygg4HQYrzy58dTazb+Hb9LyS+gW3ttGutOllMt+LrGXvrWPcR5uDtSY/NuOCK9HvdH17WdZ02ysNcjXS724i1vUNL1e7cX4hdiJLbygCv2faQvltkbsgmuE13w7eeCPEOpyz+F/tFjBdy6/pd/pGnl/s8iufKguJCAFt1C7nReRwQaAO38L39n4c+x6veXfxAf+0tQTRYbLxDIDtkk2ssuw4wvBG4En7wxXIav/AMJJ/wAIb4p/4Rf+1ft3/CdXe/8AszzPM8vyznPl87c7fbOKy/DXiDxV41uNIe4uLS+gXxbDfyWkbyy3dquRlghJCWqhsZ7McZru4fDXhubxDq8X/CY+K/Dd9earM32B9Tjs/tUjv/rYY8ZeNj8qt1O3HagDmNI/4ST/AIQ3wt/wlH9q/bv+E6tNn9p+Z5nl+WMY8znbnd7ZzX0PXk+oeC9H0vxDoUV54m8Za5fR6hb3MNg1+lz5OHO24ljKgrCCCrOOm7HevWKACiiigArzP406lDo2jeGNUuFkaCy8R2txIsYBYqiyMQMkDOB6ivTK5vxje6Da2+k2/iDSo9Rg1DU4bK3jkt0mVJpAwVyH4AA3cjJ56UAeKeI/Et5feIY9c0jwdrlv4WntBNeO+mFPLkZy738JU7BcCMjbMTkd+K3NJ1bQdft7Hw+NQ8Tw6pFcR67o9x4rmRVuZgAkEYbJZ4mY52oMn5sGsvWbXWLf4hvFZ3HiOz8LWspM1hqjvHbX22U7rOzjHySK8eFjiP3gCOlWJtfs9F8Q6Ref2RY29jPqsMXk+KrYJqWnxs+d1suQIrSMDCHor7qAC60jxJqnjKCKXx3faH5l2sV9YXmryW0k0hk/eNYR4O63OdsRbklSD0rf/tOz8OeIftk+u2OqeKX/AOKZ0uGC7E+2MvmKS9UkOJPMGJGXjnhcmqfivQ9e8d3B1m3uvDF3pel3vnR3ugSO+qGGIswhRwGXzdr7guQN5U8Vwk2gaP4c1HSPEf8Aa8+qa2/iWGX+zEuUnvVtyd+2aLAYXO8bWGcbjjqaAOs1x/iDrNxbXus2Vpo0FvrC6beappEVxb3YtVJLy+a2R9lwS24/LuAJHFWNS1bxVo1wviBNQ03xV4PgT+yLq3sppb5jagl3nnXIj8/yhhnJ2/MMjBrs7/V/B+u/aZ9R8X/2f9v0ptPuNKuNShi+z78li8LE7LhclSTnGMYrk/BVnqXgTWZvCj6PJrvg/Wna4tb6ytmulCzMsaCeT5Y9nlJubAP3gRkGgCh4fvPBN146g1R9YtPDs4t1u7VdHuYbS0e180Mlvd9zcE/6xAdu1Rg8VHZ/2P8A8JD4t8Q+L/7c/wCXz+yNSn2fZvs+/fD9ilk/5ePvNHsOMcjvWnqHw70Hwl4q8S63bx6NfQLoV1fx6RfqkrRTby4ZYQoAgAXYDnIyRmtTwjqvhu++Hl1PrlhPceRE+rtpWqQxv5caxKS1nC54thkrGeg5GaAOM8IHTZPHWnXD6/4u1rVLh45rWTT7xbhYLBpVKQ3p+8pVv9ao+UZGOtfRdfOGmNeap4y0bXND8J65ofmarBEr6dpxtrKbSjIHDTFM7pDkbjnYVUelfR9ABRRRQAV538W54bW38H3FxLHDBF4osnkkkYKqKA5JJPAAHevRK4/4j6Vo+qeHrf8Ate/sbP7LdrdWf9oTJHbTXCo+yOXcDujOTuUckA4oA8w0/wAcaxD4y13SNT0v+1LF7u41TRb2+t3njtcyBYLkuzYS0UZPmIOASQeap+Lxr0nhXUdZTQLTWYLh5Ibq91Cze4ngZkZnlsn6LYqPmiYngkk9a0PCnhSa6uB4g8QDxBNPLrH9l29vpGWsHsCVdflcZNiTuHB27ccVtw63rGl+IdX8L6d4W1y80S686C3k1PT3ktobhn8tUBUhVsAgHAGQCe1AGh4X0Cz/AOENs4tD1f8As/W7/wAKIFsIbkRR+Y8a4vGjQbvM34Uy8nAx1rnPDGh6DHcX9x48utN0bxFbpJpkUjSJbtOqkEaihlG9p2fficdcdMg1l/2n9h+Kf2zxRrulWH9h6JlIfDF35Ucnkz5FmyyHljhgYuMgL0rf8XWFn8QPENr/AGHaQPrepeGknX+2YwbaCzkdsOmzcy3Ku4weVAz3oA5C18G+G7HxDPqF5D4j8YY1BrqG50NY9QtpI9+5Y7livMxwS6jgh19a3E8V69e+OrvRrIyLBe6E9lptlo+8LpTPLtie7QHEEsQIWQqDs4AFa+k+HdB0DwrY+D7DxJrM2qS6nG+oDw5fI09tMUEUhkwAyW6sBksMg7c+lYCfCrUvCXiq71nVNd1ldLvbh4VvdHu2F3Ervu867dkCiIKpaRsnDYNAFiDxFNpnxLit9Z8N+INWntfC40i8jjsTO12yzYecBjmSByD85655HNSeLvFVnY/Zde0PQZ7fW54k8PL4d1mzCeZZtucMlsh3FS4EYOdp5XbmuDvYtStfi5pthb+ObvUYNQuIrWPUbDVmmnS1knIEbSDgOB8xXlckGvV9Q03QdG8C+Jb2/bUm1Sye6t9P1TxMUN2ZkiJjNrKQG2bgWTbg7txFABrXifUpLjwB4bsNO1Kx1Rn07UtQgsIGiggtcmOSJlB3KitgFWG0ADJr1yvnzS9W8VazceCrhNQ8P3063Fil1Jo80suqC1yC4uzknysn94D8u8jNfQdABRRRQAV538X/AA/N4n0bw/paW13NBLrtsLprVCzRQlZFdzwQoAbqRgcZr0SvP/ixJef2d4as7PUr7T/t/iC1s5prGcxSeW4cMAw/A85GQOKAOMvdN8baN4603Sw2stpdlZRW+jtpJmNoWSUrAb/gLjaP3uwD5cYrftrybwxo3iLxXqmsazDqkSXNutjrFyVsJboL5mbSNsM0RZSsfO4rkVxn9r+G/wDhMv8AhF/+Ev8Aid9u/tD+z/M/tKPy/M8zy85znbnvjOO1aC39nD8PPE+keI7ufVN/iW60XTr3VpBP9lkMW2KV3f7ir8xLKMjJIHNAGPNoWj+MfD2keRpV9Fres+IIb7VN9ui3K28yfvZocAsLQO3ys2RnqSa6Dwr4H1jwt8Q9ag1fVL7+xP8AhH54LPVvtD/6Hb+aoRPOZQsciIpbA4XqOKr2HgHxJqmo23n+LdKs7618NLa6X/YGpSRyTRqR5UkuVJaEk/My8EhcVv63oGsWOo+G7zxDq+q3GiQafa2OoQ2Fy7xyXCkmWa6VxtNsUDB3bkjGRigDzS9nhbx1pthby6zpOqXWpxafHqNgwgXUdMaUgXTSD5pZ5G+YyfcbAOOK9HOsQ6No2t+FLjQ/iVrMFw89vJfT2guGKsvlkxSEgbMDcvHfPesT+xtY8V/FPzdOTw5caJBp/wBjt7/Tw7x2dus/yiKRQVjvURgy44UYOMVr6/qfiTS/GWlxeC9dsdc8u0i0e5sLq7kuZIZBId91PHERtxhFaQ8gsRjkUAeea5pOg+DLe2uPB+n6zqOqagi2okv4UmWwmkBPlqYwGivkZVwvJXJ9q1PFXxJ8SWPh7RbPUfBX2ixgtIIribxPpUj+ZeKjBmVmbByASCfmPzVyc7+KtG+Jcr6zZak0FlrB128tLOKUwFUm+e4jRsDZgEBzjjAJrqPFfjGHxP4VNx4f0bxPq0Frrv8Aa9xJq9qJ7SJVRi0GUYhYgGX5D0UnnmgDL+FNr/wkfjJbzSLifS9bTUPt15Dbv5Fk2nCRC8KKuWLbyAEPybRycivqevL9I0az8R+HvC2ueEE0PS75Lu0uNXfTAIN0YQPNbExgk8lf3bnHAz0FeoUAFFFFABXn/wAWI7z+zvDV5Z6bfah9g8QWt5NDYwGWTy0DliFH4DnAyRzXoFFAHzx/ZHhv/hMv+Eo/4RD4nfbv7Q/tDy/7Nj8vzPM8zGMZ257ZzjvW3ocWpSaNcvceDZLmDV/HDSyWmr6YztBayqMzbDwpUcb+VGSOa9sooA8bns9e1n4uSp4f0e70bS7fRzo1xd3ds9uohWf5ms3TK79pUxk8cE44rkPHT+NtQt7rS7ey8atPZXD6bG0EUxtL2wQMollxzJO5PzNgKy9q+k6KAPM/CHgrUtA+GmnaXok8lpPqjx3Gqteu0c9sssKrMINqgpKpA27gcEHOa5y60LWLHxlBqPhzSr63sZ9vhnUbma3dL2TdJul1BWQYOQFInbq3Va9vooA8z8Y6Tpt1caT4ZuNP8XTTy28NrJr2mQqzPCS0ZjubgjJQn53XGOjV55r+meJLfxlpeh+C9C1yz0S18qxuUurSSOyvpFkKPNOIhtkjdNm5yMsoPGMV9H0UAeN3Ok/EHRrjw7bpp/h+x0ttdtnuo/C8NxExXOHMowF8raPmJ9FzXslFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAf/Z", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "010266", + "Speciality": [ + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 136339, + "Name": "AZZAM ALOTAIBI", + "ProjectID": 15, + "ProjectName": "Arryan Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.7, + "DoctorAvailability": null, + "DoctorID": 136339, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/RAYAN/136339.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": true, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.722136", + "Longitude": "46.774303", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 1245, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 11.1, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Arryan", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "010266", + "Speciality": [ + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 208675, + "Name": "ABDULLAH BUKHARI", + "ProjectID": 15, + "ProjectName": "Arryan Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.88, + "DoctorAvailability": null, + "DoctorID": 208675, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/RAYAN/208675.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": true, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.722136", + "Longitude": "46.774303", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 1185, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 11.1, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Arryan", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "010266", + "Speciality": [ + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 15774, + "Name": "RAYAN SALAHELDIN HUSSEIN", + "ProjectID": 15, + "ProjectName": "Arryan Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.79, + "DoctorAvailability": null, + "DoctorID": 15774, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/RAYAN/15774.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": true, + "Latitude": "24.722136", + "Longitude": "46.774303", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SDN.png", + "NationalityID": "SDN", + "NationalityName": "Sudanese", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 778, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 11.1, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Arryan", + "QR": "data:image/png;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCABkAGQDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3+iiuf8XeLrPwdp1reXlnfXn2q7SzhhsYhJI0jBioClhnO0jjnJHFAHQUV5//AMLT/wCpC8c/+Cf/AOzrQ0r4j6Pqnh691f7NfWf2W7ksfsV3GkdzNcKgbyY03HdIc4C5ySCMUAdhRXBv8WdBtbe0fVLTUtJnur1LRbTUo0gnRWH/AB8MjPkQA5Bf1BGOKkh+LXg+bTtXvP7UgT+zZZovJe4hEl15YzuhXf8AOrdFPGTQB3FFZ9hrNnfeHrbXN/2exntFvN9wQnlxsgfLnOBgHnnA9a4/T/jB4b1TUdds7OG+l/sa0uLyaZVjaOaOEgMYmDndnIK5wCO4oA9AoryvSfj54V1nWbHS7fT9ZWe9uI7eNpIYgoZ2CgnEhOMn0NaknxYs/wC0dQs7Pwr4r1D7BdyWc01jpwlj8xDhgGD/AEPODgjigD0CivP4/ixZ/wBo6fZ3nhXxXp/2+7js4Zr7ThFH5jnCgsX+p4ycA8V6BQAUUUUAFef/ABT/AOZK/wCxrsf/AGevQK8/+Ln9j/8ACPaV/a/9uf8AIVh+x/2Js+0/aNkmzbu/HGOc7cUAeYf8XH/4XJ/zNf8AYn/CQf8ATx9m+z/aP++fL2fhj2q5qCabJ4V8Spf3t3Yzt49uhp93BKsSwXWw+W8rnlYlOSxX5hjIrb0bSNH13xCmh2fjv4gfbv7PF9Mjaun+j/OEaGUAEpMpI3IRx61kazo1nb6c/hyzS+s/sviA6rNqfjUCOyvpFBRkEoH7zfw2CMsoc5oAy30nUvCVxaaz4k0+78azyIjz3rQtqVhFphO5ijuAROCrMCTsCvnvWP4OvdN8T+KtW8P2+leGLTS9UvZpo7jU7dY7uKGV1QRWzDKrKFbKLggMD1r0/wAFWU3i23mt01SRvDtlesLqOG4JWW6QKHt4Ryh00o3yxnDHvxXnGpaTqWjeKlt7LT/D9jO3jPfpsd1C0V2V3kREAAH7HkDlf4gcUAdJqHhq80L4p6F4Ss/GN9/Yn2S3uJrPWdTPl3EfnmNrZEACvuQACMjBGR0rbttah0a48RWD/DeOxna4ubK11GLQxFYG1zhHupMg+VkbnI+XaMgVgfEDTde8JeFbPxJ4gbTb7xEvihLu3njLyrFDsaRbcM4DiIOrHYDgZ9a1LzxFZ33h7wlFB4o+332ueILO41Sw/tAS+XHMn7228sHItwTt8tsgZwc0AcP4C1u8h+IZ0iz8LeHNU3635817a6eZ/ssZlVWeBwfkhXgqSMDIPeug1f8A4ST/AIQ3xT/wi/8Aav27/hOrvf8A2Z5nmeX5Zzny+dudvtnFbHneD/B3iHyP7F8V6H5niDf/AGr9lhtrZsvjyPO4zaHbu2ei57VnwyeG77xDq8ukal8R7exn1WZry/0yeNNNjkZ/nlMi8CMAhtx5CYJoAr6R/wAJJ/whvhb/AISj+1ft3/CdWmz+0/M8zy/LGMeZztzu9s5r6Hrwzw/beFdf8VQI/ifxrdwaXqam1u9Vv4pLC5uonGxI35DuwOQBhipJGK9zoAKKKKACvP8A4uWt5N4e0q8064sUvtN1WG+t4btyPtUkaSFYY1Xl5GOAEGCeea9Arn/F2oWel6da3l54evtc8u7RoYbGyFzJDIAxWUKSNuMEbhyCw9aAPGLC6/4TfxlbXnhC3n0DxtZRLLq8Nwn2WyuNkgMyuseZWZpWUEPjKrzyBUnjHwxNrNvpL6zqPidZ73xRDpt5aXc5FoGcNvls0YE+VkkRsc/LkEVqeFdfs9F8Q61Z6dpH2/xTrl3PfW80FsJf7PjmdQsN6ykPF5cgBkQZC56k1y+s6/4w0v4hvFZ6RquuX0cRuZrDVLaa5tobgSndcWcYIKwggLG55AYjvQB0Fzdf8KW8G+IPDk9vqr/2lLcy6XqdomY4vMj2RLJKdm2YeXuIUHAwRWX4a03Uo7jSL3xu0l9AtvDr2mapGWlu55sgxaeJZRhiw3t5C8ljkHrWxoaTfF63ubrxBex23iLSLhhb+HzKUtGaIAq9xbvucgvI0bkY+UbeDVfUraHU9ZXwG/ie0hnit/7VtZob8Ktpq4YwpZwnrHAhOViC+YOx7UAX/iBoem2ujWfia/uvF2oz6hepNp+g3kizQJdSK0kcUluRkIDlCqktglRRrGqeFdPt9H8Pv4RtNM8Ya3pkD2txa6bFCtldTAohLZ8yMpKM5ALLgYyazPFWleMPB3w80X+17/8AtzW4/FcF1Z/vprndiJtkfzAMcup+Uf3uOTWX41vNN0nRofFaaxHqPjDUEW3urG9uVmbSGkVpHMEfEkDxSjauSdmSDzQB1/xK8FeNtf8AAumaWk+m3cGl2UVxdMzzSXdzdRROrhPlIcMDxkBix5xWJ8OP7Y/4R648PeEP7D/i/tfTfE+/7T9o2Ik22KP/AJd/uqN4zncD2q54F1rXpPCtrolx4ijuZ9XuEkk1ee9d1ghlRUNrFMTlb5T86x4IGc81xfhrSvElj8Q/FUGh38Fv58t3pC6trM0ieZI0oAVJkHNycBgOp5OKAO017wpqXhK48IW6DTV0u98UWV7dRw7g0V+5IdIRgKLcKvyg5YdzXudeIN4os9U1HwxoeuX3m/2NqtrYskMoa9m1WE7DMwcndaHJy+A5bsK9voAKKKKACuP+I+v+JPDnh63vPC+kf2pfPdrE8P2aSfbGUcltsZBHIUZ6c+9dhXP+MtfvPDnh6a807SL7VL58xW8NpbGfbIUYq0iqQRHkAEjnketAHgnh/wAQQ3XjqBLW4tPDs4vV1XXrvVXFpO83mj7RZxuDkwE8iJ+cqSx4rv7LXJrrxVqVh4PtZJvEUry3o1HxNGWgewLgbLWSM7zAX2sg+7jcc5xXnnhHxLZ6X4yurP4ieDrGL+2bt7wTX2mBZIZJpFGS0xG23GHPcg55PNdZZalNJ461LRPD6x2OltZS3Fxq+rAxTwWHmhGFhMh2rbqu14sjaCCaAKd/NrF59pg1HRf+EY1uHVWe41XR7V7L+1LcZDQW8zfNNcSvlkQ8PtB6ijX28N6pp2l6ZF4T8V6Hrcl3FFY65dadHbSTXhBWNp5+WbLnexUbiVJHIrf+I+p+G5vD1v4cn12+S+03Sl1zS9T+1xj7VJGjpF+9Jy8jH5vlAJ6g1kaFp+sWPg3TNc8f+IYLjRIJYtfsH+2u97JcLGHjgzMNpUoH+RTkt0OM0ASalqEOn6MvghPFWm33iJU+23Wq+INQEsFlNtMTpby53xzo43ICuVBYk54q/wCLRoPgrwL4Z1m90Dw/rM9xcWsOpXrWaXDXStEzSyo5wXdipYMx5zk9a848QeDpo9Zn8bvrPhhYL121210rUroieeF2MqRtFtwxYfKVDEE5APetDxb4r02Twr4Z0bSzJrWqXF7a6y1k224tIGZGX7CiKdyorYUQ44U4zzQBsT+MYdT+Gktxo2jeH9JguvFB0+zkktRAtorQ5S6JVsRzoCP3g6Y4HFR+EfFV5ffatB1zQYLjRIJXhbxFo1mX8u8XahvnuXO0MEJkM2Nw4bpW3rnhrTdA+Edtf3GialNPLerrsmnQWqtBbXRgJMcsZAKWqkbWX7wHGa4j4Oalr2s+OtQsrBdNXS71JLjUNLnDi0ELyxiQRRAld+0hV3ZG3g0AdAPDGmx+OtE8SX+o6bfaWupwabp8+gzrLPPdeb5kct6xG1nZcmRlO4krgV9B15H4t0nwro3jrwzbvp/iCxga9tXtY9Khii0s3XmsEMgwB5uByR82wDFeuUAFFFFABXH/ABHuryx8PW95p1vrlxfQXay28OkIX8yRUcqtwq8m3JADgcniuwrz/wCLEl5/Z3hqzs9SvtP+3+ILWzmmsZzFJ5bhwwDD8DzkZA4oA4TxbLr2s2/hm48SeBpL7VFvbXUJ5NK0l5VFhhi1rIXy3m7i2Yz8vI5qS60bWNU8i80NINDsZNQWFYfFge2uZs8iwjVAQ1kQQBD3Kt6Vn/2v4b/4TL/hF/8AhL/id9u/tD+z/M/tKPy/M8zy85znbnvjOO1alsYY/AviK41vX7uefwz4ouZtKk1K8DNPNbRZhiYtywY5yq7SecYoAn1zwdpugXFtf3Gs+GJvEUtuqSad4mulawtoSSSLWMqHRFcbUHQLuHWuMv8Axd4k8OeHrmLV7Pwrqli+qs1nYX8Uk+2ModktrGzAC0wCqMOOSB1rt/Dk1n/Z0mo+P9Fg1e+1WI6tYXL2ouI/LlAaOwhabnzs7ysK5GDwTk1keLptY1fTrXytF8DPY6ldpoNjutXN7pvmBvLil6iGSMH5lXO1ugoA4fX5vEkP9l/bNF0rVN8UXiSHybWSf7LZnO22bP3LZecxj5Rn73NU/CmpTafrI8V26+EVnvdT+yR2N+CFsmdlkFwsYOY4kI2h8nbyMV6B4n1yGy0aw8Ppax6V4i8PWUYurjVYxBBqtrbqUe3jbO+eKVxkRkBXAOcEVJdav4b0vwbBL408CWMX9s2iy21/4e0iNY4Y5o/kXzJSNtwMO2BkAbTzzQBr2vijWPB3nxeNL7SvEdjr8rS21hpMr3ly3n/cVI5SAbYhXUAZ5YDnJrM0PVNNtfFVzcX/AIR8QeGZ9YdtC0+Sw01bKBIZnBjkYk5FwDnLLkYUYBxWW114b/4Q3wxrmh2+uah9g8V2tsr6ikct75aR7xbwlP8Aln02pkDcTVjxV4ks9d1HRfC/l+MtPvr/AMSwah5mrqIpLeNy0eLc5JRVJ+QYIBB5oA6+w0DztRtrPV9X1VNE03W1ls5tfucXt1qMZARYmYbXtmTJUDDlt2OK9YrxCbT7yb4yaRofi/xDssdNtIbzSES9I+1SR3GyEzCQYe4Ybt2wAnsete30AFFFFABXn/xYjvP7O8NXlnpt9qH2DxBa3k0NjAZZPLQOWIUfgOcDJHNegUUAfPH9keG/+Ey/4Sj/AIRD4nfbv7Q/tDy/7Nj8vzPM8zGMZ257ZzjvVwxalJ4F1t7jwbqVzBq/i2eWS0n0xnu4LWWLmaJDwsqjhX5UMcc173RQB8ueJ9U+IOs6NYeH7LwjrNtpekXEb6bcLptwl2FiUpEXYErv2kElQPmHGK3LD4cePP8AhDbb+0bmD7D/AGgviG4+zvP/AGt5nljcqblx52M4B53/AMVfQ9FAHz5o/hDXrXxVrGqa3pl34igPhye70pdat3u2Rt4aG3l3LgTgZ3Ip/iODzWpa+NtYvvBs+neI/hbfXF9Bu/s62h8Pu9lHtj2xbldsjBLA7ei9K9vooA+bPEXhr4g2tvoHia30TTYYIri3uo9B0S1uFVJgDIJJrcDAcD5GbOfurXSXTXnjHwbBrnjTwnrlnrdrqqxWz+HtOMd6sax70bMuWEYdn5BxuC9817fRQB4/q+haPfeMvBeo3mleObi+gtLHybkW6PHHtkLL9rYjIkBJMmOgr2CiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAP/Z", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "010266", + "Speciality": [ + "Specialist Internal Medicine " + ], + "SpecialityN": [ + "أخصائي أمراض باطنة" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 406994, + "Name": "ASHRAF AHMED", + "ProjectID": 15, + "ProjectName": "Arryan Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.75, + "DoctorAvailability": null, + "DoctorID": 406994, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.722136", + "Longitude": "46.774303", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/GBR.png", + "NationalityID": "GBR", + "NationalityName": "British", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 759, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 11.1, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Arryan", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "010266", + "Speciality": [ + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 325966, + "Name": "ABDULLAH SULAIMAN ALSALEH", + "ProjectID": 15, + "ProjectName": "Arryan Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.77, + "DoctorAvailability": null, + "DoctorID": 325966, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/RAYAN/325966.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": true, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.722136", + "Longitude": "46.774303", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 676, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 11.1, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Arryan", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "010266", + "Speciality": [ + "Consultant Hematologist " + ], + "SpecialityN": [ + "استشاري امراض الدم" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 288462, + "Name": "ABDULRAHMAN ABDULLAH AL RAIZAH", + "ProjectID": 15, + "ProjectName": "Arryan Hospital", + "ActualDoctorRate": 4, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.47, + "DoctorAvailability": null, + "DoctorID": 288462, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/RAYAN/288462.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 4.5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": true, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.722136", + "Longitude": "46.774303", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 2746, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 11.1, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Arryan", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "010266", + "Speciality": [ + "Consultant Hematologist " + ], + "SpecialityN": [ + "استشاري امراض الدم" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 70343, + "Name": "ZAKI ALSHAMMASI", + "ProjectID": 15, + "ProjectName": "Arryan Hospital", + "ActualDoctorRate": 4, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.04, + "DoctorAvailability": null, + "DoctorID": 70343, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/RAYAN/70343.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 4.5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": true, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.722136", + "Longitude": "46.774303", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 2481, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 11.1, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Arryan", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "010266", + "Speciality": [ + "Consultant Internal Medicine", + "Miscellaneous" + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n", + "متنوع\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 304264, + "Name": "TALAL MOHAMMED ALI OREIBI", + "ProjectID": 130, + "ProjectName": "Sahafa Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.72, + "DoctorAvailability": null, + "DoctorID": 304264, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/Sahafa/304264.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": true, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.8113774", + "Longitude": "46.6239813", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 10732, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 12.2, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Sahafa", + "QR": "data:image/png;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCABkAGQDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3+iiuf8XeLrPwdp1reXlnfXn2q7SzhhsYhJI0jBioClhnO0jjnJHFAHQUV5//AMLT/wCpC8c/+Cf/AOzq5pvxK03U9GbVE0nWYYItT/s26Wa2VWtGChnlm+bEcSA/MxPHcUAdpRXnafF/Tbq4u00vw14n1aC1uHt2u9NsVngdlPVXV8EEYI9iD3rU8I/EOz8Y6jdWdnomuWf2Xes019aCONZFKhoiwY4kG4HaecA0AdhRXDyfFLR7fxDqGh3mn6rZ31rFJLClzCkf27a+xVtwXzIznOwAfNg1saN4us9U05Ly8s77Q/MuxZww6zELaSaQgFQiljuzkgY5JU8cUAdBRXP/APCVf9QHXP8AkK/2Z/x5/wDkx1/49/8Ab/Sufk+LFn/aOoWdn4V8V6h9gu5LOaax04Sx+YhwwDB/oecHBHFAHoFFefx/Fiz/ALR0+zvPCvivT/t93HZwzX2nCKPzHOFBYv8AU8ZOAeK9AoAKKKKACvP/AIp/8yV/2Ndj/wCz16BXB/FmDTZPCtrcapF4gaCyvUulk0JVM8DIjnzGLcKijOW4wdtAHln/ABcf/hcn/M1/2J/wkH/Tx9m+z/aP++fL2fhj2r0PwE8MejfEN7iykvoF8R6kZLSOIStOu1coEPDFhxjvnFcZHe+G7jUdPs7Pxv8AEe8+1Wkd5NNbarHJHYxscMbhh/q9nBfPCgjmtfybPw14N/tDSNa1WzsbXxL/AGheXOr3Qjk1aNY9zi3ZcCdZQoKA8OQcmgCSy1LTfDVvqVl4fW7udL1dJbi40vSAr6xpl1KAGHlIQsMUaqq85ZZCBzVAeMYbq30Sw8M6N4n06DT9dgfW9RubUQq6xjFwbqRGwXI2tIXx0yax/DD6ldazf6pZWUlpPqmsSX+mrFEyX7rKwaJrrHJ00nG8qT8w4Jru7rStH8OadBp2q39899qWqrq+rW2nTIY18wbZmmVgCLDIIYvnjGTQBwHjew1jxHqOrXWh2l8ljpvna0uvapG4kbyyxEVncJkG3wQ8a8c5bNU7nx1NrNv4dv0vJL6Bbe20a606WUy34usZe+tY9xHm4O1Jj8244IrqHn1KS4tPD+ly3etaXceKEuWuNKZriwg0xjs+xyMvyqFXBMWNgUj1rD13w7eeCPEOpyz+F/tFjBdy6/pd/pGnl/s8iufKguJCAFt1C7nReRwQaAO38L39n4c+x6veXfxAf+0tQTRYbLxDIDtkk2ssuw4wvBG4En7wxXIav/wkn/CG+Kf+EX/tX7d/wnV3v/szzPM8vyznPl87c7fbOKy/DXiDxV41uNIe4uLS+gXxbDfyWkbyy3dquRlghJCWqhsZ7McZru4fDXhubxDq8X/CY+K/Dd9earM32B9Tjs/tUjv/AK2GPGXjY/KrdTtx2oA5jSP+Ek/4Q3wt/wAJR/av27/hOrTZ/afmeZ5fljGPM5253e2c19D15PqHgvR9L8Q6FFeeJvGWuX0eoW9zDYNfpc+ThztuJYyoKwggqzjpux3r1igAooooAK5/xla3l94ems4Lixt7GfMWqTXblPLs2RhK0bDgSAHILfKOc10Fcf8AEvxdZ+DvBtxeXln9s+1brOGFohJG0jRuVEqlhmM7SGxzg9KAOH8XfDiz0jw9a+KPBdzAn9m6en2mNnAttSs40aR/NESjzmkwm7JCsPwrlNPTTfFus+GrK4vdZsZ2uLXUpNL16VYtLlh3AGKyiOSQS22NehQMM1YuZ/G2jeFfDt/qktpc+HdX1i2uV07TWmecwypn7GsbYTyNgKiLkZIHIqxe6b4Vk1nTdbDeJ7HxE2pxW+j6Rq5iiWBtxeA+Tjetmr/J8h4wQOaANTxHqdnD8ZI7PSNd0PS7FPD4028me7EH2WMXBDxwspwlwowVU8DHI4q/deGrPQtRgvND8Y2Or63qtotmsPizUxcR3FnKcgRqgDPucADqpBbgk15xczXml6d4g1HxDovhy8sbrxLc6fqFzFamS9hkYbpTbM+AqgBihbkMeRXpem+FNNk8Kt4w1sSNBZaF5OlG12meCwRBLDMdwwt4oz8ykKDjHrQBiXV1rGqeIYPBemW8Hgyx06JdS1q6tUfTvO8t/KnkgdchoSCCrOozsBJ4xUmpat4q0a4XxAmoab4q8HwJ/ZF1b2U0t8xtQS7zzrkR+f5Qwzk7fmGRg1nv4S0210a08SeK/Fficwa9cJYWU8WoruSwnXzI1umkGAANxcKSvoDWv4Ks9S8CazN4UfR5Nd8H607XFrfWVs10oWZljQTyfLHs8pNzYB+8CMg0AUPD954JuvHUGqPrFp4dnFut3aro9zDaWj2vmhkt7vubgn/WIDt2qMHio7P+x/8AhIfFviHxf/bn/L5/ZGpT7Ps32ffvh+xSyf8ALx95o9hxjkd609Q+Heg+EvFXiXW7ePRr6BdCur+PSL9UlaKbeXDLCFAEAC7Ac5GSM1qeEdV8N33w8up9csJ7jyIn1dtK1SGN/LjWJSWs4XPFsMlYz0HIzQBxnhA6bJ46064fX/F2tapcPHNayafeLcLBYNKpSG9P3lKt/rVHyjIx1r6Lr5w0xrzVPGWja5ofhPXND8zVYIlfTtONtZTaUZA4aYpndIcjcc7Cqj0r6PoAKKKKACuH+K32P/hDW/tH+yvsPm/6R9vx5nl+W+77Lu4+04zszxnNdxXD/Fb7H/whrf2j/ZX2Hzf9I+348zy/Lfd9l3cfacZ2Z4zmgDl7bwr/AG78PPD/APwg+vf2h9g1W21OL+27zzfs+yLi3bygdm3KZQYxluelcp4g+GvirxPrM/iRNWk06fT3YXU+sXMsKxTRsZHe0baStqC2YySCMHNU9KhvNC0698L2utT6fY3+nyeJNDktLoxXtxI4EdvbSEYDswHMaAksBtatSDxPNH4Vi8N3GnfEO+8RKg1KSC8gMqzts8sxSKTvazZ+CuOcnnNAFy1/4RvxH4en06z8/VNbeJtGmtofLntmvCm1tWZRliu8gG5PzYPTJrPtvh58R/Dmo+H4tR1ufVNEfULazuLC0u7ieNbcn5hJGyhRDsBU54wQMYNH2r/hHNR+2ajb6V4b1u80TzbiHT0+xxrpznLLErYYajvBCg/JhR3FakHi/XtGt4vFY1OPWdLuLIaNo9jaXD3E5umHmQNeR7gvn7RtkKHdkgAc0AW/F3hfWPC3iG11OzsZ/E/haaVIptDuYnvfseXZma3gACRqkahEJPy7iOhrMTxXr1746u9GsjIsF7oT2Wm2Wj7wulM8u2J7tAcQSxAhZCoOzgAVHHD8R9X07T/N1rfY6l4gje+/sa6uDe6b5g/eQP1EMcYPKNna2M1Gnwq1Lwl4qu9Z1TXdZXS724eFb3R7thdxK77vOu3ZAoiCqWkbJw2DQBYg8RTaZ8S4rfWfDfiDVp7XwuNIvI47Eztdss2HnAY5kgcg/OeueRzUni7xVZ2P2XXtD0Ge31ueJPDy+HdZswnmWbbnDJbIdxUuBGDnaeV25rg72LUrX4uabYW/jm71GDULiK1j1Gw1Zpp0tZJyBG0g4DgfMV5XJBr1fUNN0HRvAviW9v21JtUsnurfT9U8TFDdmZIiYzaykBtm4Fk24O7cRQAa14n1KS48AeG7DTtSsdUZ9O1LUILCBooILXJjkiZQdyorYBVhtAAya9cr580vVvFWs3Hgq4TUPD99OtxYpdSaPNLLqgtcguLs5J8rJ/eA/LvIzX0HQAUUUUAFed/F/wAPzeJ9G8P6WltdzQS67bC6a1Qs0UJWRXc8EKAG6kYHGa9Erz/4sSXn9neGrOz1K+0/7f4gtbOaaxnMUnluHDAMPwPORkDigDyz4laLNdXGmJ4b8O+NRqmgpFpsF21kfIeGAvtlR0G4uW2kMMDHOBXQeH7LUtG0aDxgmqXdj4iZF0u6Pjy4aKArtEr+R0fG8fLk9A+Rnmsv+1/Df/CZf8Iv/wAJf8Tvt39of2f5n9pR+X5nmeXnOc7c98Zx2rUttS0218C+ItL8VrrPiKA+KLnRrJmC3d2jeVtjZPMOA4G7BUfebgc0AF74dh8T6zptwfEnhHVoLW4i1fWJJ74TzxKrEzwRHBC2YDfKj9CeTzU+h+FJtA8VXNxbi0m0uW9bW45J8to9tYFwQ8RACpeKo+U/dEfeuAnfQdZ8VS6X4fsvEGjQW+hHTbhkiS3YTK+1pb7ZkeRgr5rEZ46cV0nw4k1jw5qNxF4o1KfVNEeJtOSw89541tyUxe+XJhRZbAy+d0wcYwaAOjn8QabqHjqXS/D9xd6DPqKGO4a7dbW0vYZJdrXVnsOZLpyV8uQghlU+lWDrEOjaNrfhS40P4lazBcPPbyX09oLhirL5ZMUhIGzA3Lx3z3rM1X4beG/FfiGyvPC/jX7RfQXccrwxarG/2OzVyStssakx7CyhB91av6/qfiTS/GWlxeC9dsdc8u0i0e5sLq7kuZIZBId91PHERtxhFaQ8gsRjkUAeea5pOg+DLe2uPB+n6zqOqagi2okv4UmWwmkBPlqYwGivkZVwvJXJ9q1PFXxJ8SWPh7RbPUfBX2ixgtIIribxPpUj+ZeKjBmVmbByASCfmPzVyc7+KtG+Jcr6zZak0FlrB128tLOKUwFUm+e4jRsDZgEBzjjAJrqPFfjGHxP4VNx4f0bxPq0Frrv9r3Emr2ontIlVGLQZRiFiAZfkPRSeeaAMv4U2v/CR+MlvNIuJ9L1tNQ+3XkNu/kWTacJELwoq5YtvIAQ/JtHJyK+p68v0jRrPxH4e8La54QTQ9Lvku7S41d9MAg3RhA81sTGCTyV/duccDPQV6hQAUUUUAFef/FiO8/s7w1eWem32ofYPEFreTQ2MBlk8tA5YhR+A5wMkc16BRQB88f2R4b/4TL/hKP8AhEPid9u/tD+0PL/s2Py/M8zzMYxnbntnOO9aEN54k0vwbq+r6d4LnvL668YTX1vZanpckkkMbR7lmCLgqwIA3A4BJGa93ooA+dPDGn+NvFvjq/uL3wraaDBqOmSWWpSNp81qssMkoMroSCDcEMcFsg7eRxXV/wDCrrOx8Q/Y9O1DxXcX0GlZt5tQmD6bJGr4WzlZUyYyQC0Q4KZr2CigDyvwxouvXWjX6J4d8P8Ah3VBqcmm3V3Y2T2jPYbRvltnxuLluUY/L8oJHFYl1oWsWPjKDUfDmlX1vYz7fDOo3M1u6Xsm6TdLqCsgwcgKRO3Vuq17fRQB5n4x0nTbq40nwzcaf4umnlt4bWTXtMhVmeElozHc3BGShPzuuMdGrzzX9M8SW/jLS9D8F6Frlnolr5VjcpdWkkdlfSLIUeacRDbJG6bNzkZZQeMYr6PooA8budJ+IOjXHh23TT/D9jpba7bPdR+F4biJiucOZRgL5W0fMT6LmvZKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//2Q==", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "013311", + "Speciality": [ + "Consultant Internal Medicine", + "Consultant Infectious Disease " + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n", + "\r\n\r\n\r\n\r\n\r\n\r\n\r\nاستشاري الأمراض المعدية" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 367887, + "Name": "KHOLOUD HAMEED MOHAMMED ALMAABDI", + "ProjectID": 130, + "ProjectName": "Sahafa Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.87, + "DoctorAvailability": null, + "DoctorID": 367887, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.8113774", + "Longitude": "46.6239813", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 2038, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 12.2, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Sahafa", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "013311", + "Speciality": [ + "Rheumatology Consultant" + ], + "SpecialityN": [ + "استشاري علاج أمراض الروماتيزم" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 397434, + "Name": "MOHAMAD IMAD HOURY", + "ProjectID": 130, + "ProjectName": "Sahafa Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.68, + "DoctorAvailability": null, + "DoctorID": 397434, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/Sahafa/397434.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.8113774", + "Longitude": "46.6239813", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/LBN.png", + "NationalityID": "LBN", + "NationalityName": "Lebanese", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 1238, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 12.2, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Sahafa", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "013311", + "Speciality": [ + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 396083, + "Name": "MOHAMED ABDALGAWAD", + "ProjectID": 130, + "ProjectName": "Sahafa Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.82, + "DoctorAvailability": null, + "DoctorID": 396083, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": true, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.8113774", + "Longitude": "46.6239813", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SWE.png", + "NationalityID": "SWE", + "NationalityName": "Swedish", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 1143, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 12.2, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Sahafa", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "013311", + "Speciality": [ + "Consultant Internal Medicine", + "Consultant Nephrologist" + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n", + "استشاري أمراض الكلى\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 397826, + "Name": "NOUR ABDULLAH LAFY AL SHAMAILEH", + "ProjectID": 130, + "ProjectName": "Sahafa Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.66, + "DoctorAvailability": null, + "DoctorID": 397826, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": true, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.8113774", + "Longitude": "46.6239813", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/JOR.png", + "NationalityID": "JOR", + "NationalityName": "Jordanian", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 1114, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 12.2, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Sahafa", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "013311", + "Speciality": [ + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 405270, + "Name": "SHAHAD ABDULRAHMAN H ALSHEHRI", + "ProjectID": 130, + "ProjectName": "Sahafa Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.91, + "DoctorAvailability": null, + "DoctorID": 405270, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.8113774", + "Longitude": "46.6239813", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 669, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 12.2, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Sahafa", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "013311", + "Speciality": [ + "Consultant Internal Medicine", + "Consultant Infectious Disease " + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n", + "\r\n\r\n\r\n\r\n\r\n\r\n\r\nاستشاري الأمراض المعدية" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 142614, + "Name": "LUTFI ABDULLATIF MESFER ALSYALI", + "ProjectID": 130, + "ProjectName": "Sahafa Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.77, + "DoctorAvailability": null, + "DoctorID": 142614, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": true, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.8113774", + "Longitude": "46.6239813", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 604, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 12.2, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Sahafa", + "QR": "data:image/png;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCABkAGQDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3+iiuf8XeLrPwdp1reXlnfXn2q7SzhhsYhJI0jBioClhnO0jjnJHFAHQUV5//AMLT/wCpC8c/+Cf/AOzqOf4x6Da+FZfEFxpmswwRamdLkt5IEWdJgm85UvgADjrnPagD0SiuTf4gabJ4VtPEGl2OpazBcOiNb6VCtxPAzJvxIqthSowCM8Ej1rm/+F46P/0LHiv/AI+/sP8Ax4J/x8f88f8AWf6z/Z6+1AHqFFcvo3j3R9U2RXgn0O+klEUNhrIS2uZs42skZYllJJUEdSpHatC68SWdj4hg0i8jnt/PiV4b2ZQltJIz7VgVyeZjgkIBkjmgDYorn9K8Vf2p4hvdI/sHXLP7L5n+m3dn5dtNtcL+7fJ3ZzkccgE1z8nxYs/7R1Czs/CvivUPsF3JZzTWOnCWPzEOGAYP9Dzg4I4oA9Aorz+P4sWf9o6fZ3nhXxXp/wBvu47OGa+04RR+Y5woLF/qeMnAPFegUAFFFFABXn/xT/5kr/sa7H/2evQK4f4o2FnfeHrH7ZaeI7jyNQjnh/4R6MPcxyKj7X56KMnkcg7aAPKP+Lj/APC5P+Zr/sT/AISD/p4+zfZ/tH/fPl7Pwx7VqHQ5tf0bW7e3utGhni+IU80ceryFYLlguBDgAlyxP3e4zW3qvhX+y/D1lq/9vfFW8+1eX/oVpeeZcw7kLfvEwNuMYPPBIFR6boegx+BWuHutZ0We313+1LWTxbIlu09+sQKeYcZaJj1x8xw+DxQBia3pX/CufEPhvyL/AFzT/t+q2t1qn2ebytFTe582NMBcY2cK2f3Y5rHuYfDf9neIPFGr614j+w/8JhcpZx6JdR+X5mPMSdQ3G7GcODnG3FdI+oaDrPiq08P+JPFWm32lqieIJ7htQSWAX+/Y1ojOSv2faWIiI3YPWjVtH8Kx299ZaNrnh++0tbiTW7PS47uKWefU8EJbCJRta3ZcL5Y+ck4BoAj8I3Wj674hutMvLfVfsP8AYj6lDrniRE/tK3+dVWSCc5CQqCXVgOH3HNa+t+LvDc3/AAjemavZ+K0sdN1W1az1y4ijFtdSR5VJXnZsPGwy5YAEjkVzGq2HiTS/BtlP9kgvPFN1qEd5/ZVpHJJJDpTRk/ZJIeHW2Eg2mL7gJAzmq82t/wBu+HtI06Dwt4r1D7B4ghvNUtn0/wA22t9ibZbSFQTsjXOFibGAeTQBqeBPFevSfFzXLhz4g1nw7cXtxZWslrvuLSBmnUo5Odioqdx0UjAwap6v/wAJJ/whvin/AIRf+1ft3/CdXe/+zPM8zy/LOc+Xztzt9s4rq/D954JtdZg8N6XrGpaTPdXq680C3MMCpMzCP+z3VeQQcAwYzx14qPXfCuj6F4h1P/ifeOdP+3+bqf8AxL7xIra4uHc/6PFwN9w2PlTkkAc0AcxpH/CSf8Ib4W/4Sj+1ft3/AAnVps/tPzPM8vyxjHmc7c7vbOa+h6+eNCv/AA3rvjLTNO+1/E7UL6w1CKf7NqEkcsdvIkgXfKvJRVJwx4IBNfQ9ABRRRQAVh+K01KTRilhe2ljAz41C7nlaJoLXa3mPE44WVRgqW+UYya3K4f4tX95Y/DzUvsd3pVv58UsE39oyFPMjaJ9yQ46zHA2g8HmgDD+H/inTY9ZvNLt/Fsd9pa3D28ba3qSy3891uVQYcHa1uy/d43Fi1Z/iDwVNr9xPraT+J7uDS9da4utI1hy8FzDES7i0h2kOGB2R5IBBIOK5CDQ4dA+GkWs+H7rwjNBLZCa4vdTkDX9tfmHc0Ns6ABHUBWRSdwbJrLbxv/YX/CMXkus/ED7d5treX0Oo3X+jXFv1kMK7gXViMLu4Izk0AWNA0LR2+KeqadeaV9vsdctJfJttOt0lk0fzpwq+cpGLeSEZDYzsJHWpPiV8NdB8CW+mP4b1bUpvEUt7EILRrlGnCkPtdERVfO9FAI78da7OO10fVPjJp+uWdxPodjJ4aj1yZ7Z0tvOzcb2+0EZDKQRvyedo54rc+IHhjQdQuLPx4NRkbVLK3Q6PDHOhgvZkLTQIBjdIXY4wjAsOnrQBz88GvXXgWU+IItS07xFp+hHULfWtMV4WeGOL5bW5nf5zKX3O8YwOAc5rzT4cazrFjqNxrmov4yuNEgla8uH0gu8clwpR2NwWO0qUB35OSMc4ruNduvinovw81O81G3sb+x1zzZbiHZdS3OnxzREsu1sCKOMAjByFJ71x9hon9l/Dy2ng8U3159qu1n1TSdA1DzPJ05ogZXlhAG2QY2sW+QZUGgDY0q/8N+FvGV74/wBXu9K1ex1WWSez0+0kjuL2zklkEyPJG2BGyBSpIYlWIAznNdR4jv8AR/iN5eoT3fivwx5NoJ9LudTkSy017gZaJwx3ZkO/OV52KcdK5v4f+GPh9JrN5pd/qMdzPq9k509pJ7d1ghlZVjQ5GVvlOeFBAzxmtid9SjuJdLv7K0toNIc6bp7eK4mTR57WI7Y5Rnhrxhn5lAUxhsAUAV/AupTR6za6pYLpt94iXU00HUFsAZVnsNytJqDYO9nZ8ZnY7TkZGa+g68Q+HHir/iobj/iQ+Ff+PttM/wCKYs/9J++n+kNz/wAenq/rt4r2+gAooooAK5fxx9j/ALO07+0f+Ec+w/2hF9o/t/Hl+Xht3lbuPOxnbnjG6uorj/iPoHhvxH4et7PxRq/9l2KXaypN9pjg3SBHAXdICDwWOOvHtQBj6nN4Em+Hms/bNFg0vRElnSHNrBB9qkER2z2mfldmTPluOTj0FcR4X+HGj+I9Rs/FF5c64nhbTbRPJj8Qugkbyysi8FShtPLJ6Ec7u1a/i77H4c+yzxeR4k0Sz8NJDY6U2LzbIm4x30sPCiHYNrTLz82Bwa881jVtejt9H1bS9Q1JYL14EbwxezOFnZwWxBaqcNYsMRqMnPK0Ae3z2egx+KpdUt9H1K+gXwuYo1s7ZJbCe137hDHjhpWHRM7SpFeYawnirxP460d7K90bTtL094JNNtJpZYbSKaOU+VazIMqt4FYBo1wQowKj8I3PjCHUbqfXPEtj4bsbzfatpWqX01nJa27lSZLOF+E2jKxt0BUjtWx4u0qz+Ffh618UaHfz6/8AbdQSRY9ZmF1bGR0aQXSBAv7792MSZJwx9aANNNW8Vafo13oyah4f8S+ItT110urJZpbyCytZF2uHTO+OJHG0ggqobB5NcxrA02Px1o9va6BqWjapbvBDr0drZrb6XPYLKRcSkD5mgZv4n+UoBu6VX8O6br2s2+v3tu0az3tlca9HqnhwuJxdOARp8koBOMncYOWztOap2GoePL7xDbS+IfD19b2M+lLoGoX9xZTp5dmzjzZ3kc4EgBZi7fKOpFAHQSeEbPwdqOoeI9KvPCt5rd1dyXmk6ZcyiSNrNjvhNvEqhjcF1CpsO3BIBzVzwppuveLbcP8AEdo7HS2137XaWl+XinlusLst1SYFTblWkAQfMSCB3qO60/R/3F5F4h8OahfWES6VYw2t6ktz/ZycxvAuM/2jnhSuEyRgVtwJD4t8CxJ43vdS8NQaZrAGmXd5KLO7lWOL908jy5BlIZySuMspI6GgDI8HeN4bX4uat4ft/BmmwwRXE1lHcaJpYWdFE6oHmYNgRAcscddvFe5186fCrxPDo3xL1rRLfTpNZguL2cR6vBALi7KtMiB5ZgQPIwN7HH3jnvX0XQAUUUUAFc341udNtdGhfVPDF34igNwoW0tbBbtkba3zlG4AAyM/7QHeukrz/wCLEl5/Z3hqzs9SvtP+3+ILWzmmsZzFJ5bhwwDD8DzkZA4oA5/SvC954j+23mnWN9pdinmG3h1uIwXLSDBWzZVBB0zBAMQ5yG9KxNDs4dG+JdzqniDR9SaCy0xordb62BgN+kwZYdN34GzAbyUBDYzVP+1/Df8AwmX/AAi//CX/ABO+3f2h/Z/mf2lH5fmeZ5ec5ztz3xnHatCH/hJLjwbq+kad5+uX0fjCbTLe91PzLmSxjEe1bgOvMbIcHeBhSxOOaAOX8Xa3/wAJH4ytdX1zwtriX2m3aTtZNp+I20aORmLyo5JMmSQxyI8cVX1XT9Y1fUbLU9O8Q6VqmiPqEd5b6HLevPHptuSWU3MCgrDDGhCPg4UHGcGjVbDx5qnjKyg8Q2mq2djaxR6LqGrWkc8cc1mshEsskz5DKQWYs3ykAEius1z4f6bpmjW1wL6S0n1R10LR5NBmWOC7hlUmCS9O3Mhcj94yZBAXANAHocP2P/hVmr/8Iv8A2V9u/s+bf/wjmPL+2eRz5fl87s7cfxY214xplzrF9qOjTr4l1y4sYLuC18RaTq187yR7SDcyPD0FoAdpaTochq3NcTXtG+Glt4b8P3umt4istTUXEHhGVzOYUhMbPOqYffvChiQBnZ3qno2jWeqacl54tTXND1uTGnXcOlgW0k1mQC97eLICzRlywkmPykqMjINABdeF7z4c+MoPGkVjoer6JquqrFY2trEbiRI5ZPNjaBMKokCJhSrEZIAyDmjStfvIfiHe3nj/AEjXH8LaldyRWEOt2xNtaySSgxsyzHYm2PeCVyQN2OM1ufEw6D4Yt/At/b6/d3cGl3FgY9OjvEkWW1iDkXAjGAzkLt8zhTnHFY97410HxrcabpdhB4gvoF8RxazqDauiSwWtrkrIvDEJAoYcMNoBOTQB2fwn0K8sfEPiXUYtK0q30SfULr7DcrblLmSNnRo/KbG02xQZXbwT04r1iuH8D6r4k1TUdR8+w0qz8LWsstrpf2eGSOSaNSvlSJklGhMZ4ZeCRxxXcUAFFFFABXn/AMWI7z+zvDV5Z6bfah9g8QWt5NDYwGWTy0DliFH4DnAyRzXoFFAHzx/ZHhv/AITL/hKP+EQ+J327+0P7Q8v+zY/L8zzPMxjGdue2c471v6BqHjDS/D2qXmh+Hp4r7WfGErLDq1lMvk28yAiV1QgqoIALcgc9a9oooA4PQ/B2vWviq5v9Z1mTUdL1DTGS806e6eaBLqRwXEUbLtEAXKqDlsHBrl/F+k+KtZuNRv8Aw3p8dtpekWUmnwadqEMqMJoixW6so0BXftKrFIMHgjAr2SigDwC1+HHjCx+Fk+o2dz9n8Uz3banNcwvMl7JbtBua3Zgu8yGQAlDwW75qmPBWpSeKtETWZ/HlzBq+hQRXl3A7O0E0r/PDK7LhYFGSyHJGcnNfRdFAHl8nw0s9L07ULO8tv7c0SPSpFhmuYxc6tDIBhYrdioVYwgJRRyHY9jXkHhGy8SeDvGV1eWfgjXLzRLrfZzQ32lSSSNZtIpYFRhTIUUDn5ck8Yr6vooA8T+H/AIt8Vaf4qvNLv/CniBfDt7eudPaTTpQ1kruqxocnZHAiA8KDt7cV7ZRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAH//Z", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "013311", + "Speciality": [ + "Rheumatology Consultant" + ], + "SpecialityN": [ + "استشاري علاج أمراض الروماتيزم" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 394223, + "Name": "FAISAL WALEED GHALIB SHAHWAN", + "ProjectID": 130, + "ProjectName": "Sahafa Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.67, + "DoctorAvailability": null, + "DoctorID": 394223, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/Sahafa/394223.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.8113774", + "Longitude": "46.6239813", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 502, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 12.2, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Sahafa", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "013311", + "Speciality": [ + "Consultant Nephrologist" + ], + "SpecialityN": [ + "استشاري أمراض الكلى\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 405264, + "Name": "ABDULELLAH AL MOHAYA", + "ProjectID": 130, + "ProjectName": "Sahafa Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.8, + "DoctorAvailability": null, + "DoctorID": 405264, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/Sahafa/405264.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.8113774", + "Longitude": "46.6239813", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 360, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 12.2, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Sahafa", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "013311", + "Speciality": [ + "Consultant Infectious Disease " + ], + "SpecialityN": [ + "\r\n\r\n\r\n\r\n\r\n\r\n\r\nاستشاري الأمراض المعدية" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 408789, + "Name": "LINA ABDULRAHMAN A ALANSARI", + "ProjectID": 130, + "ProjectName": "Sahafa Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.82, + "DoctorAvailability": null, + "DoctorID": 408789, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.8113774", + "Longitude": "46.6239813", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 175, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 12.2, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Sahafa", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "013311", + "Speciality": [ + "Consultant Infectious Disease " + ], + "SpecialityN": [ + "\r\n\r\n\r\n\r\n\r\n\r\n\r\nاستشاري الأمراض المعدية" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 406923, + "Name": "AREEJ GHAZI A MATAR", + "ProjectID": 130, + "ProjectName": "Sahafa Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.84, + "DoctorAvailability": null, + "DoctorID": 406923, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.8113774", + "Longitude": "46.6239813", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 75, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 12.2, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Sahafa", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "013311", + "Speciality": [ + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 418305, + "Name": "YAZEED ALHINDI ", + "ProjectID": 130, + "ProjectName": "Sahafa Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.85, + "DoctorAvailability": null, + "DoctorID": 418305, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.8113774", + "Longitude": "46.6239813", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/DEU.png", + "NationalityID": "DEU", + "NationalityName": "German", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 75, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 12.2, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Sahafa", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "013311", + "Speciality": [ + "Consultant Nephrologist" + ], + "SpecialityN": [ + "استشاري أمراض الكلى\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 418866, + "Name": "RASHED ALRASHED", + "ProjectID": 130, + "ProjectName": "Sahafa Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.92, + "DoctorAvailability": null, + "DoctorID": 418866, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/Sahafa/418866.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.8113774", + "Longitude": "46.6239813", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 61, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 12.2, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Sahafa", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "013311", + "Speciality": [ + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 408805, + "Name": "FATIMAH SAAD ABDULLAH ALSHAHRANI", + "ProjectID": 130, + "ProjectName": "Sahafa Hospital", + "ActualDoctorRate": 4, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.42, + "DoctorAvailability": null, + "DoctorID": 408805, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 4.5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.8113774", + "Longitude": "46.6239813", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 71, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 12.2, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Sahafa", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "013311", + "Speciality": [ + "Consultant Internal Medicine", + "Consultant Infectious Disease " + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n", + "\r\n\r\n\r\n\r\n\r\n\r\n\r\nاستشاري الأمراض المعدية" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 149425, + "Name": "EMAD ALI", + "ProjectID": 17, + "ProjectName": "Suwaidi Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.85, + "DoctorAvailability": null, + "DoctorID": 149425, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/SUWAIDI/149425.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": true, + "Latitude": "24.567525", + "Longitude": " 46.641019", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/JOR.png", + "NationalityID": "JOR", + "NationalityName": "Jordanian", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 11103, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 15.9, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Suwaidi", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "010266", + "Speciality": [ + "Consultant Nephrologist" + ], + "SpecialityN": [ + "استشاري أمراض الكلى" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 143723, + "Name": "MOHAMMED GAFFAR", + "ProjectID": 17, + "ProjectName": "Suwaidi Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.87, + "DoctorAvailability": null, + "DoctorID": 143723, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/SUWAIDI/143723.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": true, + "Latitude": "24.567525", + "Longitude": " 46.641019", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/IRL.png", + "NationalityID": "IRL", + "NationalityName": "Irish", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 9643, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 15.9, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Suwaidi", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "010266", + "Speciality": [ + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 6760, + "Name": "AHMAD TAHA AL IRANI", + "ProjectID": 17, + "ProjectName": "Suwaidi Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.65, + "DoctorAvailability": null, + "DoctorID": 6760, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/SUWAIDI/6760.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.567525", + "Longitude": " 46.641019", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/JOR.png", + "NationalityID": "JOR", + "NationalityName": "Jordanian", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 8158, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 15.9, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Suwaidi", + "QR": "data:image/png;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCABkAGQDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3+iiuf8XeLrPwdp1reXlnfXn2q7SzhhsYhJI0jBioClhnO0jjnJHFAHQUV5//AMLT/wCpC8c/+Cf/AOzrQ0r4j6Pqnh691f7NfWf2W7ksfsV3GkdzNcKgbyY03HdIc4C5ySCMUAdhRXDx/FLR/wDiXxXmn6rp99f6hHYw2F9CkVz8/wB2Yxl8+TnK7xnkEYrsPt9n/aP9nfa4Pt3lef8AZvMHmeXnbv29dueM9M0AWKK5NPiBpses3dhqljqWjQW7ui6jqsK29pOytjEcjNhiwywHdQT2rL0/4weG9U1HXbOzhvpf7GtLi8mmVY2jmjhIDGJg53ZyCucAjuKAPQKK8r0n4+eFdZ1mx0u30/WVnvbiO3jaSGIKGdgoJxITjJ9DWpJ8WLP+0dQs7Pwr4r1D7BdyWc01jpwlj8xDhgGD/Q84OCOKAPQKK8/j+LFn/aOn2d54V8V6f9vu47OGa+04RR+Y5woLF/qeMnAPFegUAFFFFABXn/xT/wCZK/7Gux/9nr0CuH+KNhZ33h6x+2WniO48jUI54f8AhHow9zHIqPtfnooyeRyDtoA8o/4uP/wuT/ma/wCxP+Eg/wCnj7N9n+0f98+Xs/DHtVzUE02Twr4lS/vbuxnbx7dDT7uCVYlguth8t5XPKxKclivzDGRWvpthoOp6y2lp8QfHkM8Wmf2ldNNrKKtooYK8U3eOVCfmUjjuaoT+H4dQ0aXRPD9vqTQWWsHX7jV/FaA2F6qLsYiZBiRHBV+QNy7jmgDn72DXvAlxpus38Uni3xFdvEmn3s6vf2AhcloxE52v9o3oWUKcbXyOTWp4c12zs/GUn/CUarqs/inxJEbFP7MuA0elx3EgxCfMO+GaKTd8vIQY4Jrb8P6t4V1m3gsNU1DUraDSNYXUF1GWaJNLF1EAPstrIxI8jBLJHw2wZyK4C81iHTPHWqpdaHJNPLrE2s6Dd2toGnu5jL/o6lycyWrkZwnJOCpoA9v1jwJoOv6zo9lqniHUrufS7eCVdLmvUkW5WJiPOmiZSXLElWfjOccVy9trUOjXHiKwf4bx2M7XFzZWuoxaGIrA2ucI91JkHysjc5Hy7RkCsjUtWm8JeFV8QeK9QkXxhe3v9oWVvZTETxQuheO1nWQiQWolVg0akgHGDmrl54is77w94Sig8Ufb77XPEFncapYf2gJfLjmT97beWDkW4J2+W2QM4OaAOH8Ba3eQ/EM6RZ+FvDmqb9b8+a9tdPM/2WMyqrPA4PyQrwVJGBkHvXQav/wkn/CG+Kf+EX/tX7d/wnV3v/szzPM8vyznPl87c7fbOK2PO8H+DvEPkf2L4r0PzPEG/wDtX7LDbWzZfHkedxm0O3ds9Fz2rPhk8N33iHV5dI1L4j29jPqszXl/pk8aabHIz/PKZF4EYBDbjyEwTQBX0j/hJP8AhDfC3/CUf2r9u/4Tq02f2n5nmeX5YxjzOdud3tnNfQ9eGeH7bwrr/iqBH8T+NbuDS9TU2t3qt/FJYXN1E42JG/Id2ByAMMVJIxXudABRRRQAVx/xH0DxJ4j8PW9n4X1f+y75LtZXm+0yQbowjgrujBJ5KnHTj2rsK4/4j6rrGl+Hrf8Asiwvrz7Vdra3n9nwvJcw27I++SLaRtkGBtY8AkZoA8c034a683ipn0TVo4dUiTGq2mu3Lq2osHHnOqKu6WzkbABb73zA1X1x/FWjeKrZzZeLm8O2TqdYtBFKbAqjnz0t04T7LsGED4+Xg8VsJo+vL4qu73wprl3NBL4ceK91TxLduzacxfMkJljGIp4xtbY33fmJqTVYdY1T4eWXhfSNa1y81u61WNLyS7unk863aIxvPGVyzWBcjDkYOTnmgCn470mbRvCuh3/hvT7S58O6vrFvq8GnXUJec3UqMVgEaAJ5GwKuwZbJIyRWh4fvZpLeDxAmlaM0FlerBdW+uW5N/BdIA72mnL0VFHEMRIYNuzVf4oaPNa+BfCr6Xrl3d6ppdxaaM1ppt2ZIEuoon+ZUUbhOGwAeGwQMCsPSv+Ew0vw9e6R/xI7z7V5mp/bbvzpLmHUWQL9njfjbfjGQmN4JJzQBc+IA1K68dWfiDxNoF3NBLZINEt7SzZleYys9vb3ivwXI3CSNDnpiun1jVPCun2+j+H38I2mmeMNb0yB7W4tdNihWyupgUQls+ZGUlGcgFlwMZNc5o3xD8eappyWd5omhy/2NhYZtZtJ2kmvIQAsSMWO67OSQowxOelR+NbzTdJ0aHxWmsR6j4w1BFt7qxvblZm0hpFaRzBHxJA8Uo2rknZkg80Adf8SvBXjbX/AumaWk+m3cGl2UVxdMzzSXdzdRROrhPlIcMDxkBix5xWJ8OP7Y/wCEeuPD3hD+w/4v7X03xPv+0/aNiJNtij/5d/uqN4zncD2q54F1rXpPCtrolx4ijuZ9XuEkk1ee9d1ghlRUNrFMTlb5T86x4IGc81xfhrSvElj8Q/FUGh38Fv58t3pC6trM0ieZI0oAVJkHNycBgOp5OKAO017wpqXhK48IW6DTV0u98UWV7dRw7g0V+5IdIRgKLcKvyg5YdzXudeIN4os9U1HwxoeuX3m/2NqtrYskMoa9m1WE7DMwcndaHJy+A5bsK9voAKKKKACuH+KOn6xqnh6xs9D8QwaHfSahGqzTXr23nZRwIlZASzEkEL32+1dxXnfxfg1KTRvD9xpcUbT2Wu2100kysYIFRZD5kxXlYlONzcYFAHnlrp+saF4en8OS+IdK+3f222o32p3V6/8AZtx8mySynlwC8zEbmhYcpkk109ho15N4ettc0hL5L7TdVW4vHAI+1WcaB3ttPKjL2jHHlRkhT3rM1KDUvEvgVbjVIvCOjT2/ij7Usl0rW9hqarET5gLZMwkLH5v4lB9Kk8OazeTeIZND364ljptodf2WRI+1SRuE8izGcPYMP9WmATxzQBb1bxB8PvDXhW+e4uLu5n1fU5L+S0je3e/0y6lQ5YISDC8ZXGeWVjjJrM1XWfB/iP4WWUunPqul7Nbjt7e/lMMEjaiIDtubmRScryGeQfPkZ7VzfjrxnDrNxdJ4f+HVosF672Fxd3+iAXYv3LblV0YjzcFSActuycV0Gi+FNN0a30Hw/wCJBJY+HWt7fxBPcaltiU6ngI1ozOAmzYGJiI38HnFAGH4Vh8Sf8IbrUH9teDfsP9tzp/a2r3UnmfbPLUefbzdN2PmR/vZya7PxaNB8FeBfDOs3ugeH9ZnuLi1h1K9azS4a6VomaWVHOC7sVLBmPOcnrXKeMrXwJ4c8680641zVLF7s31vDaPBPoq3h3FYZFXAHAAKD5vLI55qn4t8V6bJ4V8M6NpZk1rVLi9tdZaybbcWkDMjL9hRFO5UVsKIccKcZ5oA2J/GMOp/DSW40bRvD+kwXXig6fZySWogW0VocpdEq2I50BH7wdMcDio/CPiq8vvtWg65oMFxokErwt4i0azL+XeLtQ3z3LnaGCEyGbG4cN0rb1zw1pugfCO2v7jRNSmnlvV12TToLVWgtrowEmOWMgFLVSNrL94DjNcR8HNS17WfHWoWVgumrpd6klxqGlzhxaCF5YxIIogSu/aQq7sjbwaAOgHhjTY/HWieJL/UdNvtLXU4NN0+fQZ1lnnuvN8yOW9YjazsuTIyncSVwK+g68j8W6T4V0bx14Zt30/xBYwNe2r2selQxRaWbrzWCGQYA83A5I+bYBivXKACiiigAri/ic80fhVHt7LWb6dbgGO00yIyrO2x8JcoOWt2PDjvkCu0rz/4sSXn9neGrOz1K+0/7f4gtbOaaxnMUnluHDAMPwPORkDigDziRvGGu+HtQ1PxH4Tn+w/2fJo+naHY6dN/o9xs3RXQgfIRVBZPMU5HAArDi1jXvDFx4URND8TwwRXFml1d3to63crA/PZQPkBrchcrCerZJrc/tfw3/AMJl/wAIv/wl/wATvt39of2f5n9pR+X5nmeXnOc7c98Zx2rY0+HzvBuu/wBp61fXt94e8V3D6L9uuvMkuriCMeRAd3L7jn5EwSScYoAj1bxXoOgW994mvzps2qS3Eh0/QbTYy20xBkjuLy3JDJdKwKSSKcjhRWvZa5N8RPAupWHiC10aaeXTJb231GCMtYWLGIBUlkcsY7hC7MwH3V5zXMeJ/CGm3WjWCXumXdpqmqXEevaldy26oztKp83T7Vyu4zlslIGz0ySaNN8V6DH4FbRnMejT2+u/YrWy+S3adViCo+ppnLRMflmIHOMAcUAbdr4cs/h/8PJ/tknhzVNEfT21CH+0WE/n6qYvlEOQqtCyIdoHznJ5wa8k8KalNp+sjxXbr4RWe91P7JHY34IWyZ2WQXCxg5jiQjaHydvIxXqms/Fjw3/whr2d54V/tD7BmzhmXTo5dJ+2JGQoiYv/AKvqVxhth6Vn3Wr+G9L8GwS+NPAljF/bNosttf8Ah7SI1jhjmj+RfMlI23Aw7YGQBtPPNAGva+KNY8HefF40vtK8R2OvytLbWGkyveXLef8AcVI5SAbYhXUAZ5YDnJrM0PVNNtfFVzcX/hHxB4Zn1h20LT5LDTVsoEhmcGORiTkXAOcsuRhRgHFZbXXhv/hDfDGuaHb65qH2DxXa2yvqKRy3vlpHvFvCU/5Z9NqZA3E1Y8VeJLPXdR0Xwv5fjLT76/8AEsGoeZq6iKS3jctHi3OSUVSfkGCAQeaAOvsNA87Ubaz1fV9VTRNN1tZbObX7nF7dajGQEWJmG17ZkyVAw5bdjivWK8Qm0+8m+MmkaH4v8Q7LHTbSG80hEvSPtUkdxshMwkGHuGG7dsAJ7HrXt9ABRRRQAV5/8WI7z+zvDV5Z6bfah9g8QWt5NDYwGWTy0DliFH4DnAyRzXoFFAHzx/ZHhv8A4TL/AISj/hEPid9u/tD+0PL/ALNj8vzPM8zGMZ257ZzjvWxpVtrFx4evf+Kavov7Z8aySf6XYutzY28yD/So/wDnnInaTkKc9a9vooA4/WfDmsX2nPpEUljcWMGlFLG9vmd72PUVBWOcvjAwDneo3hskVwc/hbQfCWjS6JrPhLxB4l1TU7c3F5q9npqXjRTSLscRzMAwIZS4yCRuBPWvbKKAPCNK8Ef8I5qN7Fp2jarqmiP4ak1W3sNbtfPjXUSRtRo1UKJtgCkD58FhnBqxa+NtYvvBs+neI/hbfXF9Bu/s62h8Pu9lHtj2xbldsjBLA7ei9K9vooA+bPEXhr4g2tvoHia30TTYYIri3uo9B0S1uFVJgDIJJrcDAcD5GbOfurXSXTXnjHwbBrnjTwnrlnrdrqqxWz+HtOMd6sax70bMuWEYdn5BxuC9817fRQB4/q+haPfeMvBeo3mleObi+gtLHybkW6PHHtkLL9rYjIkBJMmOgr2CiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAP/2Q==", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "010266", + "Speciality": [ + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 147460, + "Name": "SHADI NIZAR AL RAWWASH", + "ProjectID": 17, + "ProjectName": "Suwaidi Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.62, + "DoctorAvailability": null, + "DoctorID": 147460, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/SUWAIDI/147460.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": true, + "Latitude": "24.567525", + "Longitude": " 46.641019", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/JOR.png", + "NationalityID": "JOR", + "NationalityName": "Jordanian", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 6492, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 15.9, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Suwaidi", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "010266", + "Speciality": [ + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 155561, + "Name": "NAGWA MUKHTAR", + "ProjectID": 17, + "ProjectName": "Suwaidi Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.64, + "DoctorAvailability": null, + "DoctorID": 155561, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": true, + "Latitude": "24.567525", + "Longitude": " 46.641019", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SDN.png", + "NationalityID": "SDN", + "NationalityName": "Sudanese", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 6149, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 15.9, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Suwaidi", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "010266", + "Speciality": [ + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 118631, + "Name": "MOHAMMED SAAD AL SULAIMAN", + "ProjectID": 17, + "ProjectName": "Suwaidi Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.74, + "DoctorAvailability": null, + "DoctorID": 118631, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/SUWAIDI/118631.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.567525", + "Longitude": " 46.641019", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 2326, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 15.9, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Suwaidi", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "010266", + "Speciality": [ + "Consultant Infectious Disease" + ], + "SpecialityN": [ + "استشاري الأمراض المعدية" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 334762, + "Name": "ABDULRAHMAN ABDULAZIZ ALMASOUD", + "ProjectID": 17, + "ProjectName": "Suwaidi Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.56, + "DoctorAvailability": null, + "DoctorID": 334762, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/SUWAIDI/334762.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.567525", + "Longitude": " 46.641019", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 1429, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 15.9, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Suwaidi", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "010266", + "Speciality": [ + "Consultant Internal Medicine and Hematology" + ], + "SpecialityN": [ + "استشاري الباطنية وأمراض الدم" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 325423, + "Name": "TARIQ SALEH AL KHUWAITIR", + "ProjectID": 17, + "ProjectName": "Suwaidi Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.66, + "DoctorAvailability": null, + "DoctorID": 325423, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.567525", + "Longitude": " 46.641019", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 933, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 15.9, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Suwaidi", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "010266", + "Speciality": [ + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 419326, + "Name": "THAHABA SAAD ALMALKI", + "ProjectID": 17, + "ProjectName": "Suwaidi Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.87, + "DoctorAvailability": null, + "DoctorID": 419326, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.567525", + "Longitude": " 46.641019", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 312, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 15.9, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Suwaidi", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "010266", + "Speciality": [ + "Consultant Internal Medicine / Allergy and Immunology" + ], + "SpecialityN": [ + "استشاري الطب الباطني / أمراض الحساسية والمناعة" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 191285, + "Name": "ABDULRAHMAN ALI KHORMI", + "ProjectID": 17, + "ProjectName": "Suwaidi Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.59, + "DoctorAvailability": null, + "DoctorID": 191285, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.567525", + "Longitude": " 46.641019", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 293, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 15.9, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Suwaidi", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "010266", + "Speciality": [ + "Consultant Rheumatologist", + "Specialist Internal Medicine " + ], + "SpecialityN": [ + "استشاري أمراض الروماتيزم", + "أخصائي أمراض باطنة" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 412659, + "Name": "BASHAYR MARZOUQ ALOTAIBI", + "ProjectID": 17, + "ProjectName": "Suwaidi Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.86, + "DoctorAvailability": null, + "DoctorID": 412659, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/SUWAIDI/412659.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.567525", + "Longitude": " 46.641019", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 137, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 15.9, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Suwaidi", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "010266", + "Speciality": [ + "Consultant Internal Medicine", + "Consultant Pulmonology" + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n", + "استشاري علاج الأمراض الصدرية\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 408368, + "Name": "BASEN ABDRABALAMEER ALALI", + "ProjectID": 17, + "ProjectName": "Suwaidi Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.71, + "DoctorAvailability": null, + "DoctorID": 408368, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/SUWAIDI/408368.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.567525", + "Longitude": " 46.641019", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 94, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 15.9, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Suwaidi", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "010266", + "Speciality": [ + "Consultant Nephrologist" + ], + "SpecialityN": [ + "استشاري أمراض الكلى" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 134050, + "Name": "SANAA TAHIR ", + "ProjectID": 17, + "ProjectName": "Suwaidi Hospital", + "ActualDoctorRate": 4, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.33, + "DoctorAvailability": null, + "DoctorID": 134050, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 4.5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": true, + "Latitude": "24.567525", + "Longitude": " 46.641019", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/GBR.png", + "NationalityID": "GBR", + "NationalityName": "British", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 10094, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 15.9, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Suwaidi", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "010266", + "Speciality": [ + "Nephrologist Consultant" + ], + "SpecialityN": [ + "استشاري أمراض الكلى" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "", + "ID": 33249, + "Name": "SARA FAKHREDINE", + "ProjectID": 152, + "ProjectName": "AlNarjis Medical-Center", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.9, + "DoctorAvailability": null, + "DoctorID": 33249, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.869826060310395", + "Longitude": "46.64015390240179", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/LBN.png", + "NationalityID": "LBN", + "NationalityName": "LEBANON, LEBANESE REPUBLIC                           ", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 1073, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 18.1, + "ProjectNameBottom": "Medical Center", + "ProjectNameTop": "AlNarjis", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "107", + "Speciality": [ + "Specialist Internal Medicine" + ], + "SpecialityN": [ + "أخصائي أمراض باطنية" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "", + "ID": 41011, + "Name": "AMJAD ABU MUHANNA", + "ProjectID": 152, + "ProjectName": "AlNarjis Medical-Center", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.66, + "DoctorAvailability": null, + "DoctorID": 41011, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.869826060310395", + "Longitude": "46.64015390240179", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/JOR.png", + "NationalityID": "JOR", + "NationalityName": "JORDAN, HASHEMITE KINGDOM OF                         ", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 790, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 18.1, + "ProjectNameBottom": "Medical Center", + "ProjectNameTop": "AlNarjis", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "107", + "Speciality": [ + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري طب الباطنية " + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "", + "ID": 39693, + "Name": "AHMED ALGHAMDI", + "ProjectID": 152, + "ProjectName": "AlNarjis Medical-Center", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.66, + "DoctorAvailability": null, + "DoctorID": 39693, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.869826060310395", + "Longitude": "46.64015390240179", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "SAUDI ARABIA, KINGDOM OF                             ", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 781, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 18.1, + "ProjectNameBottom": "Medical Center", + "ProjectNameTop": "AlNarjis", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "107", + "Speciality": [ + "Senior Specialist Pulmonology" + ], + "SpecialityN": [ + "أخصائي أول أمراض الرئة" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "", + "ID": 48479, + "Name": "EBTEHAL ELHASSAN", + "ProjectID": 152, + "ProjectName": "AlNarjis Medical-Center", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.9, + "DoctorAvailability": null, + "DoctorID": 48479, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.869826060310395", + "Longitude": "46.64015390240179", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SDN.png", + "NationalityID": "SDN", + "NationalityName": "SUDAN, DEMOCRATIC REPUBLIC OF THE                    ", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 494, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 18.1, + "ProjectNameBottom": "Medical Center", + "ProjectNameTop": "AlNarjis", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "107", + "Speciality": [ + "Specialist Internal Medicine" + ], + "SpecialityN": [ + "أخصائي أمراض باطنية" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "", + "ID": 48851, + "Name": "FARIS ALSALEH", + "ProjectID": 152, + "ProjectName": "AlNarjis Medical-Center", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.67, + "DoctorAvailability": null, + "DoctorID": 48851, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.869826060310395", + "Longitude": "46.64015390240179", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "SAUDI ARABIA, KINGDOM OF                             ", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 82, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 18.1, + "ProjectNameBottom": "Medical Center", + "ProjectNameTop": "AlNarjis", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "107", + "Speciality": [ + "Specialist Internal Medicine" + ], + "SpecialityN": [ + "أخصائي أمراض باطنية" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "", + "ID": 51271, + "Name": "DHAFER ALSHEHRI", + "ProjectID": 152, + "ProjectName": "AlNarjis Medical-Center", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 5, + "DoctorAvailability": null, + "DoctorID": 51271, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.869826060310395", + "Longitude": "46.64015390240179", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "SAUDI ARABIA, KINGDOM OF                             ", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 60, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 18.1, + "ProjectNameBottom": "Medical Center", + "ProjectNameTop": "AlNarjis", + "QR": "data:image/png;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCABkAGQDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3+iiuf8XeLrPwdp1reXlnfXn2q7SzhhsYhJI0jBioClhnO0jjnJHFAHQUV5//AMLT/wCpC8c/+Cf/AOzrY8OePdH8R6dJeYn0vZqB03ydTCQSNcAA+WF3HLc429cg8cUAdRRWHqXivTdPt1uEMl9At79iupLLbKtk2CXec5xGiAfMT93IyK5v/hbmj/8ACQ/2R/Y+uf8APT7b9mT7N9n37ftW/f8A8e/fzMYxzQB6BRXH3/xL8N2P2mX7T9osYLRrj7fbyRvbSSLn/Rkk3YNwQNwj6kc0XXxH0ex06DUby2vrexn0pdThuZo0SOTcNy26sWwbggEhB1HegDsKKw/D/i/QfE9vA+l6naTTy263DWi3CNPEpA4dFYlSCwB9DxXNyfFiz/tHULOz8K+K9Q+wXclnNNY6cJY/MQ4YBg/0PODgjigD0CivP4/ixZ/2jp9neeFfFen/AG+7js4Zr7ThFH5jnCgsX+p4ycA8V6BQAUUUUAFef/FP/mSv+xrsf/Z69Arh/ijYWd94esftlp4juPI1COeH/hHow9zHIqPtfnooyeRyDtoA8o/4uP8A8Lk/5mv+xP8AhIP+nj7N9n+0f98+Xs/DHtW5FqU2jeFfGWqW6+H2nsvGd7cRrrYJUsibgIcEHz8j5eR/FVOwks77xDbaH/aXxjt76fa2y4nCeXGzhPNcdRGCeWxgVX12bw3oWnan4X/sXxlqF9YahLr3mahaxyx3EiAx+bKeC9sxHzNgEgnmgDp/C/iXxJ/aNnZ654OsZ9E8SWiXjTaHpkjR+ZcFQTcs52/cyX6nG3kirGu+Jf8AhHNR1PQ5/B0Gqa2+nyrpaaRpnnxrpxJSKK4BIYLvHzqo2YIxyawPBC+MNd/smKz8WeHPsP8AaEOsTWFjqM32m3t/l3WojGQkKghfLPAOBmqZvNej1nW/ElxrGm22l6R4onSSee5dL+eGJvMNlEx+VomXlYcgFh2oAj0q48nTr3Q9R+HPiN9E1KKS8uEi0TMlrqMgCMbYN8qQqmdmQXB74rl7DUPEnhzxDbRav4e1zVPCz3a2dnYa/ZST7Yy42CKNiEFx5YKrjjlgBg13H/CRaxfad5uneKILfz9b/tu3v9Q1B0so7dh8unSyKeJhkM0A4C5Oax/DniTWNd8QyQeKI77UNEsPEB1BNV0xXltre4RwADNISqWioWbHBAIOcUAR2fgrXtA+Jela3pc8dpBqmpw3DaRZO6XdtYSzb8TwqoCRKAEbkqGAHNXNX/4ST/hDfFP/AAi/9q/bv+E6u9/9meZ5nl+Wc58vnbnb7ZxXV6kkLW6+JNLvdShni8R+Y0+oShZ9RtQDJ9lsmXmWCQ4MUedrHNZ95o+g2us6q6a5480me60ybxTdWlrdpAqKzfOhTGRKDxg+gBbigDE0j/hJP+EN8Lf8JR/av27/AITq02f2n5nmeX5YxjzOdud3tnNfQ9eJ+GtM8K+J/FWkW9v4u8XatPa28Ouxx3mpRTwRMrgCOQAErKC3K9gTzzXtlABRRRQAVh+K9Hh1nRilxrmpaLBbv9oku7C7FuwVVbIZyCNmDk/QHtW5XD/FG/s7Hw9Y/bLue38/UI4IcSBLaSRkfal3nrbHB8wDkigDzCNdH/4SHT9c8OeLPEeoX1hrcdjqL32opL/xLkffLMSnP2bO352ITk5FamreJ9Nk1m+0Sw07WbmfV7iQahq+pwK6waRKxSR7aYHK26nDoWBjGSTmsOGw0fQvh5q+o+KLS+0/7f4gmgS58ORpF9ot3i3BI2kxvtGwxA5BwtU4PAmpeLbiJ/B/iHUrGBtMFuLTxHetFdy2uesaRqQbUhlA/hLBh6UAdBpPhiHRvFVja+CNRtG8O2Tx6rqfiCScFiqOBLZm4iATZsCSeU2P7xOMVJZ/8IJqmo+Lf+RjvLG6lvP9f5EllNeMf+XLqGuSD+7/AIipqN/Ck3hK3tPBF6PEC+Hb23S91LVdKyFiunHlSpJKQEFqEUsQylhwSccVfs9Y8E+GNZ0pH0PxBDpcTw2Nrd3VpCulyzBvkvg+QrSlVz5w5KZIFAGJa6N4P1Tw9P8ADuJPEeh30krarYnxCIbbzrgp5EadCWUk9FXJ2tg8Yrf0LxL9h07TPBeg+Dp7jyNQi0rX7r+zN9lJtAiuX3oeWOAcyLyvLDtWJ41TXvHfiqG1sr3wjDBFcLJpviC1ldWLB2EVqbgbh5+HEnlr7MK7Owv/AOy/s3heC7sbz7VaLZ6pJoEnmalDqLYjlu5SMbYxj5pWG8OVyKAPEPiD/wAJhpfiG/8AP/tyz0S11WT+y9/nR20O138ryc4VcIPl29AOOK2NK0q81Twbe6vq9/4yvPFN1FJa2dlaTGSSazaMMkkiMC7WxkJBYHaSQBzXST+BNe1C3le/8Q3bT2Xig2+n2niu9c2l7Cg/dkIVzI7kkfLgMu4CrE76l4SuJdb8P2WpX3jBXOm3GkXcTSwRWud7S2cKYkFqJVVI2J2gEjGaAM/4bwaba3Gl29hFqUM8V7EmoRwKq6ol0CgkEoHI00HG4N82/rX0XXzhoVrZ33iHTPEeg3GuW/imfxBFFr+mbwnlxs4e5byk+cW4kIXMhwOjc19H0AFFFFABXm/xmj/4p7Q7yXTZ9QsbDW4Ly+hhg83/AEdEkMhZem3HB3YHPJr0ivL/AI63/wBh8G6b5t3fW9jPqsUF99hk2SSW7Ry+Yg7HIHRuCcZoA5CbxdZ/FTxDpGh6RZ2Nh4W0PydVvE1OIRYjhfY6AKzJ5flyDggDg5IFST6xDo3iqW9t9D8XN4dsnN3HqlnaAsVR8i3jlBCf2bsG4Jx2PStPSvDnhvS/hZe6j4QkgvLG6ikfV7m7aOS9hs2gDTQRtGAFmACkI/yhic9qj8OzzXXgXX9G0aXUptLl0K4ezstbYtqjsYgqGFF+U2pXCqQPv7gKAMSHWdY8R6dq8Wrv4jfRNS1Ca8s7DTC51ZreQfITGxKmy2Erxkb8AHFY/iWTw3peo+FdKs9S8V655d3aXE2j308dzHDGCVa2MIxtuBgJ5ZGAGI71Y0a/s77w8mkaZd+I7DW9DiF5rV7cyCK5js4UCz2lu6/MFDkFInAUEEkg11HhzWfhZN5njTfsvtNtDb/ZdTNqLm6kjxL9pCZy9wx48zcCTke9AGff/wBj+Fvh5c6vP/0NbanpdlYbP9DuPKLRW90hx5ezbh0U5XgA1l/DXxvqWjeKtTuNU8GXdzPq6S6osmm6Wz3ZWV0PylmB+z5Bx1+Yjk1sat8QPCup6NfeH7+x0Yz688l1p9xaQxeRaNOpSOS8YtmO4QkmRlBwMYzUdhHZ2Ph620z+zfiPcX0G1f7c0eAP5kaoF8q3n6m0JG9Fxg8GgDP0+Sz8Y6jrt54j1LxzZ/ZdVuLjToVnEcayKQYraJXzi7G5gsa84HFal747hj8Vaalx4e8XW0GkaZFcSXZsgmqTrE5yLhy2GtWHL9MuM8VTtY/tnn3mp6b4j0i+0qVrzRYbqD7PbapcRcwGdW5mvZTkNswXAOCMVJPrGm6zby6XrOh/ENfEV6hu7xrO0UTiFxte3j3Ev9j3k4QgjOM80AY+k6loOs/Eux1TwQvi5dUvdYjuNTWQIIBavMGlB8oltm4p94lcde1fTdfNmn3ug3Xjrw1b+CNK8T6dqmn3FrZanGbdIVe1jlAle4EXzFy2zeWwvHI6V9J0AFFFFABXB/FDSZtZt/CtumnyX0C+I7R7qNYTKohw4cuMEbMHknjnmu8rz/4sSXn9neGrOz1K+0/7f4gtbOaaxnMUnluHDAMPwPORkDigDP8AHvhez0LThqeh2Ouf88l0PQ4h9iuJMMwa5gQDfG2AjnOSu0Vxmm3sOn3DXD6V410zxFrdl/YlrJe24hsLKaYgokB+/HEjj5QMlVBwCaj/ALX8N/8ACZf8Iv8A8Jf8Tvt39of2f5n9pR+X5nmeXnOc7c98Zx2rY0aSz/s5LPxHqWuah9g+IAs9OmacSyeYgAiErP8A8s/vFtuDk8CgC3Z/CbXtMuNKS1u9NmgluIbvXru6kdru7Yn/AEi3DhMSW7gZ2P1bJY1zkmmeD7z4h6hF4j0KfSL7SpZJdOsLG0ht7bVLeKX90ojcZmmlO5cLgOAAMYrYhk8eTeIdXi/tLZY6b4gm1X7A8841K6s43+5DH0e3YfKo4Uvxmq//AAg9n4x8Zf8ACUavqniPQ7GSXyLOPV7gW16t4ZPMRLcMpAhAY7ADu3KcdKAOb8a+FNN0/wAKw27jRtM1TW/Ea3trHNthnsrCZGCJMMbo0Rh8wGVUjgmu78BfEf7D4NOnXlt/bN9pN3/ZkNt4ej+0SSW8UaqtxtLZMZII3jAJK8DNUPjjpWj/APCPeHdI+32P9t/a7a1+26hMn2n7PskXzJXxu8vfyzYxnJ61z+jR3ng7Tks/Dmm/bPtWLfUZoIDJqzRsAJbmxZMZtDtUxSNxvPNAHH6n4ovNd8ZazFqd94r/AOPueXRbCGU+Zb3nmHyFaNidm3JUhPmB4FegaZ40vNC8ZaNrmueGfFf/ACL8Ghs81gfMuLzzA52l2G/dg453E9q5vxFrHhWPWdA8SWGh+J7afSNTt7fUJ7y0iRZ2iYySGRgctdMcE7iM4OcVsax8QNN1m30e40ux8XX0C+LYNQaS9hWVQ2CfssBViM4I2x+55oA7OPwv/wAJT4h0/wAaeHLHVfDF9DqEcWo2t9F9i+2W4fzZWKICZGcsoyzYbaQema9Yryew0DWPEeo23iPSNX8ZaXs1tZbzTNfuXgja3BDusUSg5XkKoJxgMD0r1igAooooAK8/+LEd5/Z3hq8s9NvtQ+weILW8mhsYDLJ5aByxCj8BzgZI5r0CigD54/sjw3/wmX/CUf8ACIfE77d/aH9oeX/Zsfl+Z5nmYxjO3PbOcd6L+28Sf8Ibc6vp3hrVft3/AAnTavb2VxYyeZ5flllZ0XnbnAJBxnjNfQ9FAHj9hYaxqnh628UQWmuWet2uqreapHfxvHczW6oJJbS1AyzW5c/JExwSDk5o0bwjeeMfGSeI7y88V2eiWt2LyHTNZlMci3iyB1KRFSotwjFRg7sgjOK9gooA8M+LPhCbU7i10TS9M1nUdU1DU0u21e6tzNBaQyF0+ziZV3RxIxD7MEAEnNT3tz4q8JaNpuiXHhiS+1RbeKwk1fQLCWVotM2lCqTHDC4DLvAxsGVOK9sooA+bJ9F17ULeXS/D/h3WW0uyuD4iuG8V2Tme9ukG1oRsG2QOpX5SAzHd81df4a0XXtZ1nSNbsPDum6NpdukMeoaRqdk9uoulYPJdW0IBXftIRJGO7gg9K9kooA8f8VarrGqfEPRf7IsPHNn9l1WC1vP3Lx6bNbrK2+T5Sd2cj5jwUHNewUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQB/9k=", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "107", + "Speciality": [ + "Specialist Internal Medicine" + ], + "SpecialityN": [ + "أخصائي أمراض باطنية" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "", + "ID": 42971, + "Name": "SAIF ALSAIF", + "ProjectID": 152, + "ProjectName": "AlNarjis Medical-Center", + "ActualDoctorRate": 4, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.47, + "DoctorAvailability": null, + "DoctorID": 42971, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 4.5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "24.869826060310395", + "Longitude": "46.64015390240179", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "SAUDI ARABIA, KINGDOM OF                             ", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 279, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 18.1, + "ProjectNameBottom": "Medical Center", + "ProjectNameTop": "AlNarjis", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "107", + "Speciality": [ + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري طب الباطنية " + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 13769, + "Name": "MUATH ABDULAZIZ ALSHAIKH", + "ProjectID": 21, + "ProjectName": "Qassim Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.84, + "DoctorAvailability": null, + "DoctorID": 13769, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/QASSIM/13769.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": true, + "Latitude": "26.360724", + "Longitude": "43.945774", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/YEM.png", + "NationalityID": "YEM", + "NationalityName": "Yemeni                                     ", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 8303, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 329.2, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Qassim", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "051431", + "Speciality": [ + "Resident Internal Medicine" + ], + "SpecialityN": [ + "طبيب أمراض باطنية مقيم" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 7716, + "Name": "GAAFAR ABU EL-HASSAN", + "ProjectID": 21, + "ProjectName": "Qassim Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.82, + "DoctorAvailability": null, + "DoctorID": 7716, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/QASSIM/7716.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": true, + "Latitude": "26.360724", + "Longitude": "43.945774", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SDN.png", + "NationalityID": "SDN", + "NationalityName": "Sudanese", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 4561, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 329.2, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Qassim", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "051431", + "Speciality": [ + "Consultant Pulmonology" + ], + "SpecialityN": [ + "استشاري علاج الأمراض الصدرية\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 4778, + "Name": "MOHAMMAD OBEIDAT", + "ProjectID": 21, + "ProjectName": "Qassim Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.81, + "DoctorAvailability": null, + "DoctorID": 4778, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/QASSIM/4778.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "26.360724", + "Longitude": "43.945774", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/JOR.png", + "NationalityID": "JOR", + "NationalityName": "Jordanian", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 4156, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 329.2, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Qassim", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "051431", + "Speciality": [ + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 299710, + "Name": "HUDA MOHAMED MAHMOD SALIH", + "ProjectID": 21, + "ProjectName": "Qassim Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.9, + "DoctorAvailability": null, + "DoctorID": 299710, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": true, + "Latitude": "26.360724", + "Longitude": "43.945774", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SDN.png", + "NationalityID": "SDN", + "NationalityName": "Sudanese", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 4061, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 329.2, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Qassim", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "051431", + "Speciality": [ + "Specialist Internal Medicine" + ], + "SpecialityN": [ + "أخصائي باطنية" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 364042, + "Name": "HUSSEIN TALEB", + "ProjectID": 21, + "ProjectName": "Qassim Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.66, + "DoctorAvailability": null, + "DoctorID": 364042, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "26.360724", + "Longitude": "43.945774", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/LBN.png", + "NationalityID": "LBN", + "NationalityName": "Lebanese", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 631, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 329.2, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Qassim", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "051431", + "Speciality": [ + "Specialist Internal Medicine" + ], + "SpecialityN": [ + "أخصائي باطنية" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "", + "ID": 35257, + "Name": "SALMA GAFAR SALMA GAFAR", + "ProjectID": 156, + "ProjectName": "Buraydah Medical-Center", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.75, + "DoctorAvailability": null, + "DoctorID": 35257, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "26.4119376", + "Longitude": "43.9164603", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SDN.png", + "NationalityID": "SDN", + "NationalityName": "SUDAN, DEMOCRATIC REPUBLIC OF THE                    ", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 733, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 334.8, + "ProjectNameBottom": "Medical Center", + "ProjectNameTop": "Buraydah", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "107", + "Speciality": [ + "Specialist Internal Medicine" + ], + "SpecialityN": [ + "أخصائي أمراض باطنية" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "", + "ID": 51912, + "Name": "MUATH ALHARBI MUATH ALHARBI", + "ProjectID": 156, + "ProjectName": "Buraydah Medical-Center", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.96, + "DoctorAvailability": null, + "DoctorID": 51912, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "26.4119376", + "Longitude": "43.9164603", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "SAUDI ARABIA, KINGDOM OF                             ", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 56, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 334.8, + "ProjectNameBottom": "Medical Center", + "ProjectNameTop": "Buraydah", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "107", + "Speciality": [ + "Consultant Internal Medicine,Rheumatology Consultant" + ], + "SpecialityN": [ + "استشاري طب الباطنية ,استشاري علاج أمراض الروماتيزم" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "", + "ID": 47992, + "Name": "SAMI ALOMARI SAMI ALOMARI", + "ProjectID": 156, + "ProjectName": "Buraydah Medical-Center", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.75, + "DoctorAvailability": null, + "DoctorID": 47992, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "26.4119376", + "Longitude": "43.9164603", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "SAUDI ARABIA, KINGDOM OF                             ", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 20, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 334.8, + "ProjectNameBottom": "Medical Center", + "ProjectNameTop": "Buraydah", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "107", + "Speciality": [ + "Rheumatology Consultant" + ], + "SpecialityN": [ + "استشاري علاج أمراض الروماتيزم" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "", + "ID": 59275, + "Name": "OMAR AHMED OMAR AHMED ABDULRAHMAN ALSAQAB", + "ProjectID": 156, + "ProjectName": "Buraydah Medical-Center", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.75, + "DoctorAvailability": null, + "DoctorID": 59275, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "26.4119376", + "Longitude": "43.9164603", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "SAUDI ARABIA, KINGDOM OF                             ", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 4, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 334.8, + "ProjectNameBottom": "Medical Center", + "ProjectNameTop": "Buraydah", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "107", + "Speciality": [ + "Specialist Internal Medicine" + ], + "SpecialityN": [ + "أخصائي أمراض باطنية" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "", + "ID": 31066, + "Name": "AHMAD MIHDAWI AHMAD MIHDAWI", + "ProjectID": 156, + "ProjectName": "Buraydah Medical-Center", + "ActualDoctorRate": 4, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.49, + "DoctorAvailability": null, + "DoctorID": 31066, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 4.5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "26.4119376", + "Longitude": "43.9164603", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/JOR.png", + "NationalityID": "JOR", + "NationalityName": "JORDAN, HASHEMITE KINGDOM OF                         ", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 1107, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 334.8, + "ProjectNameBottom": "Medical Center", + "ProjectNameTop": "Buraydah", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "107", + "Speciality": [ + "Specialist Internal Medicine" + ], + "SpecialityN": [ + "أخصائي أمراض باطنية" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 312542, + "Name": "DONIA NASSERDDINE", + "ProjectID": 60, + "ProjectName": "Khobar Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.83, + "DoctorAvailability": null, + "DoctorID": 312542, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": true, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "26.3107804", + "Longitude": "50.2108347", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/LBN.png", + "NationalityID": "LBN", + "NationalityName": "Lebanese", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 7053, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 398.2, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Khobar", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "034423", + "Speciality": [ + "Consultant Internal Medicine", + "Consultant Infectious Disease " + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n", + "\r\n\r\n\r\n\r\n\r\n\r\n\r\nاستشاري الأمراض المعدية" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 310666, + "Name": "HASSAN ALMARZOOQ", + "ProjectID": 60, + "ProjectName": "Khobar Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.81, + "DoctorAvailability": null, + "DoctorID": 310666, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": true, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "26.3107804", + "Longitude": "50.2108347", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 4784, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 398.2, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Khobar", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "034423", + "Speciality": [ + "Consultant Internal Medicine", + "Rheumatology Consultant" + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n", + "استشاري علاج أمراض الروماتيزم" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 304263, + "Name": "ABDULRAHMAN ALBDULQADER", + "ProjectID": 60, + "ProjectName": "Khobar Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.82, + "DoctorAvailability": null, + "DoctorID": 304263, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/KHOBAR/304263.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": true, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "26.3107804", + "Longitude": "50.2108347", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 3928, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 398.2, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Khobar", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "034423", + "Speciality": [ + "Consultant Gastroentrologist", + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري الجهاز الهضمي", + "استشاري طب الباطنية\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 270523, + "Name": "DOAA HELMI ", + "ProjectID": 60, + "ProjectName": "Khobar Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.7, + "DoctorAvailability": null, + "DoctorID": 270523, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/KHOBAR/270523.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "26.3107804", + "Longitude": "50.2108347", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/EGY.png", + "NationalityID": "EGY", + "NationalityName": "Egyptians", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 3921, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 398.2, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Khobar", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "034423", + "Speciality": [ + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 302950, + "Name": "TURKI ABDULLAH AL SALAMH", + "ProjectID": 60, + "ProjectName": "Khobar Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.74, + "DoctorAvailability": null, + "DoctorID": 302950, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": true, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "26.3107804", + "Longitude": "50.2108347", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 2305, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 398.2, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Khobar", + "QR": "data:image/png;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCABkAGQDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3+iiuf8XeLrPwdp1reXlnfXn2q7SzhhsYhJI0jBioClhnO0jjnJHFAHQUV5//AMLT/wCpC8c/+Cf/AOzrY8OePdH8R6dJeYn0vZqB03ydTCQSNcAA+WF3HLc429cg8cUAdRRWPdeJLOHyPscc+qb9QXT5v7OUT/ZZD94zYPyKvG4nkZHHNc/rPxS0fS/EL6HZ6fquuX0cRlmTRoUufJw5RlcBwVYEDII43D1oA7iivO5/jHoNr4Vl8QXGmazDBFqZ0uS3kgRZ0mCbzlS+AAOOuc9q1Lr4j6PY6dBqN5bX1vYz6Uupw3M0aJHJuG5bdWLYNwQCQg6jvQB2FFYfh/xfoPie3gfS9TtJp5bdbhrRbhGniUgcOisSpBYA+h4rm5PixZ/2jqFnZ+FfFeofYLuSzmmsdOEsfmIcMAwf6HnBwRxQB6BRXn8fxYs/7R0+zvPCvivT/t93HZwzX2nCKPzHOFBYv9Txk4B4r0CgAooooAK8/wDin/zJX/Y12P8A7PXoFed/GOfQbXwrp9x4gl1mGCLU43t5NIZFnSYJIVOX4AA3cjnOKAPNP+Lj/wDC5P8Ama/7E/4SD/p4+zfZ/tH/AHz5ez8Me1bkWpTaN4V8Zapbr4faey8Z3txGutglSyJuAhwQfPyPl5H8VYdh4i8N332aX/hKPirb2M92tn9vuNQjS2jkbHDyZwMA7j3A5xVjWZvDekeHn0iLRfGWqb9bOoWN7fWsc9tqV4UKxgvx50MmM4UbmBJB5oA29J8d+KtGuLFL/wAPaNBB4mt47jT7vTLKVYDf3JHli5csBnAJfbubGCM1U8OareeDtRk/tGw0qLxTrPjA2txvhKyNZzEbpIdxDmEyKdrHK59TWfpmp/aP7G0PXNd0qzvrXW4PETJNd+XbWNuuENioc5jmQ5xDjCgferUvdc8E3XjrTbC/tfE82qS67Fe6fqM8cLK6mUiNIpCdxsy2WUL9QaAJ5Rpslv4rt00DUtZ8O3GsXkN1HDZrcX8GpsMPLCPuLAqfdY/OGPPBrzyw1DxJ4c8Q20Wr+Htc1Tws92tnZ2Gv2Uk+2MuNgijYhBceWCq445YAYNdp4g1CbRvHU/h/wp4q0axga9bxBe3GpagYlN15pSS0ZoyBswFJiYbuDk1l+HPEmsa74hkg8UR32oaJYeIDqCarpivLbW9wjgAGaQlUtFQs2OCAQc4oAjs/BWvaB8S9K1vS547SDVNThuG0iyd0u7awlm34nhVQEiUAI3JUMAOauav/AMJJ/wAIb4p/4Rf+1ft3/CdXe/8AszzPM8vyznPl87c7fbOK6vUkha3XxJpd7qUM8XiPzGn1CULPqNqAZPstky8ywSHBijztY5rPvNH0G11nVXTXPHmkz3WmTeKbq0tbtIFRWb50KYyJQeMH0ALcUAYmkf8ACSf8Ib4W/wCEo/tX7d/wnVps/tPzPM8vyxjHmc7c7vbOa+h68T8NaZ4V8T+KtIt7fxd4u1ae1t4ddjjvNSingiZXAEcgAJWUFuV7AnnmvbKACiiigAri/iVZ6bdaNpj6po+s6tBa6nFcLaaVbLOzsqvxIjcGIjIP1A712lc/4u8Sf8I5p1r5Ue++1K7TT7HcuY1uJA3lmXkER5HzFcnHQUAeUar4d8YQ6jZanp3hfw4+ialLHb2+hy6fMY7XzCWW5uYFG1JlTCPICcDjpVjU/DmsX3g3Wftkl9YWOh+fqEOWeKSPUYYztFpkYFgAT5YGHBHUVPqviL7DqNlocHiie41uDUI9b1RItQ3xybSUl062AO4sXHyQMOR1OawPEfirxJ/aMfkaD4y/4Rb+0Bqeqf2nZyeZ5eT5tuMHZ9m8v+BuM5ycUASaTovhWP4aWPiTWfDvie+nXU47+8nksopZ528kSOxZhlrNjk5J5J5NYfjS18N3Go+Htc0O48V3n2q7tir2rxyR2MbFnFnAU/1dwnG2LOFBFaFr8XP+Ej1GfTrzR75PC2m7rqG20O2xI1vGdqx3Klyht/LJDqMDO3tXQRzedqOn+L9D0Wx0vwsnloujapa+RJdXAPmCezgT5HuGjwkb5ySCOgzQBbni8K6z4Vl0u38HXa+Ir1DYxtqmmRC/DOm0X0+Mv5W8/NNg/NnjNR6F4l+w6dpngvQfB09x5GoRaVr91/Zm+yk2gRXL70PLHAOZF5Xlh2rA8R3N5cadH/Z3iWCLxTrPiUR2+y+K3tjZzA7bWbb88apJjdGMqreprt7C/wD7L+zeF4LuxvPtVotnqkmgSeZqUOotiOW7lIxtjGPmlYbw5XIoA8Q+IP8AwmGl+Ib/AM/+3LPRLXVZP7L3+dHbQ7XfyvJzhVwg+Xb0A44rY0rSrzVPBt7q+r3/AIyvPFN1FJa2dlaTGSSazaMMkkiMC7WxkJBYHaSQBzXST+BNe1C3le/8Q3bT2Xig2+n2niu9c2l7Cg/dkIVzI7kkfLgMu4CrE76l4SuJdb8P2WpX3jBXOm3GkXcTSwRWud7S2cKYkFqJVVI2J2gEjGaAM/4bwaba3Gl29hFqUM8V7EmoRwKq6ol0CgkEoHI00HG4N82/rX0XXzhoVrZ33iHTPEeg3GuW/imfxBFFr+mbwnlxs4e5byk+cW4kIXMhwOjc19H0AFFFFABXP+LtGvNd061s7NLH/j7RpprkHzLePDBpbdgDsuFyCjHgHNdBXH/EOHWJtO0f+w9asdLvk1WF1+3XTwR3WA+IDs5fccfJ3APpQB4okHhXT/HV3YaJF4gvtUW9e21XUdVWKVbKHzcTXkci/NHKjAMJW4XJJrtzrkNr4V1vwzb2vjXUYNQSeGPXtXjE1oiyJ5Ym+0A4FuB8+7B+Ulq4z4rfY7fTm1eDz9D8UyS/2Zqllb4to76Mh2luEQfPJC8nAdjhguCMitDwbJo82nQxajqXxAT+zdEGq3FhdzoLK6t4wu5I42+/C3KgHAK5GaALHwdsP7C8PeLNQ1G00PUNEsPtkFxc28fm3NxsSNmRGbCvbsgJAOMk+lc3P4717xDrMuqW/h67bwfZIbSNbOycrYQo24XEeGMcV1HEeHyAvHGK7DxPrGm3VxYeG9L0PWbTw7qmjx6y0Hhe0VLt2lJj2yqp2GIpgMMH5gvJFa7poPhjwraa3ol7aQ6XFbpYarpGpSoqyqE3zK0K4VtQKqEIY88gigDnLW68N+FtOn1zQ7ex8T+daNqSvdJHe6tZ3hG8STlMeXbptG5s7ldjzzWX8NfG+paN4q1O41TwZd3M+rpLqiyabpbPdlZXQ/KWYH7PkHHX5iOTW5f6rZ3Hg25/4Rew8GxX2sytav8AYIQsljpU0ZzJdeWcxsh2725RTjrVewjs7Hw9baZ/ZvxHuL6Dav8AbmjwB/MjVAvlW8/U2hI3ouMHg0AZ+nyWfjHUddvPEepeObP7LqtxcadCs4jjWRSDFbRK+cXY3MFjXnA4rUvfHcMfirTUuPD3i62g0jTIriS7NkE1SdYnORcOWw1qw5fplxniqdrH9s8+81PTfEekX2lSteaLDdQfZ7bVLiLmAzq3M17KchtmC4BwRipJ9Y03WbeXS9Z0P4hr4ivUN3eNZ2iicQuNr28e4l/se8nCEEZxnmgDH0nUtB1n4l2OqeCF8XLql7rEdxqayBBALV5g0oPlEts3FPvErjr2r6br5s0+90G68deGrfwRpXifTtU0+4tbLU4zbpCr2scoEr3Ai+YuW2by2F45HSvpOgAooooAK4f4k2F5ff8ACI/Y7Se48jxLZzzeTGX8uNd+52x0UZGSeBXcV5/8WJLz+zvDVnZ6lfaf9v8AEFrZzTWM5ik8tw4YBh+B5yMgcUAcn41+Hepanbwpqkcmoz6h4tUrd2qtNPaaZIG+Quy5jRCSccoCQaqa/o39heHtLs9DTVft3/CSxaMs3iEf8fFvsIEG5AC9kxAOzofm4rP/ALX8N/8ACZf8Iv8A8Jf8Tvt39of2f5n9pR+X5nmeXnOc7c98Zx2q4mrabo3hW7uPFeoeINTg0Txw6WUizLNOWhTMYcyEDZgNkLjk8YoA3/E97r2n29hcaJpWjX0C28eiarJ4dt3lv7JsEzJAV4jRABsDfdYrkVxF7o/w+k1nTfDdxrnjW5n1e4iuJIDd27rBdSsYyLhSMrOp4fgsM961NA8VfYdO1TUbzQfHNvYz+IJfEMNzp1nsjkt2AZVmYnBjIBLAcEY+ao72y0HX9Z03xvb6p4fh1SLU4r2PSrC4RZ7m1DGUI0Qyz3zMdpG7aTgZ70AWPiVZeFdG8K6Z4f8ACmqaNY6o17Fpd7cRXEUU5h2Okn2po8Ns3BS+4YyORW34C+I/2HwadOvLb+2b7Sbv+zIbbw9H9okkt4o1VbjaWyYyQRvGASV4GawPi5oX9u/2V/ZGlaHp/wBv8m+vPNt/K1K33+ZvmudoOy3XI3sc4ccms/Ro7zwdpyWfhzTftn2rFvqM0EBk1Zo2AEtzYsmM2h2qYpG43nmgDj9T8UXmu+MtZi1O+8V/8fc8ui2EMp8y3vPMPkK0bE7NuSpCfMDwK9A0zxpeaF4y0bXNc8M+K/8AkX4NDZ5rA+ZcXnmBztLsN+7BxzuJ7VzfiLWPCses6B4ksND8T20+kanb2+oT3lpEiztExkkMjA5a6Y4J3EZwc4rY1j4gabrNvo9xpdj4uvoF8Wwag0l7CsqhsE/ZYCrEZwRtj9zzQB2cfhf/AISnxDp/jTw5Y6r4YvodQji1G1vovsX2y3D+bKxRATIzllGWbDbSD0zXrFeT2Ggax4j1G28R6Rq/jLS9mtrLeaZr9y8EbW4Id1iiUHK8hVBOMBgelesUAFFFFABXn/xYjvP7O8NXlnpt9qH2DxBa3k0NjAZZPLQOWIUfgOcDJHNegUUAfPH9keG/+Ey/4Sj/AIRD4nfbv7Q/tDy/7Nj8vzPM8zGMZ257ZzjvUeraLqWs+Bb57jw74gWC98cSX8lpHZMLsWrxHLBCCM4OM8ru4zX0XRQBx/hzULOb4eSRf8I9riWOm2hs/sGp2QFzdRxxDgR5w+4fL2BORivLPiN4W02TWfDmqeH/AAl4nsZ2S2uLhdI01Ylgh3OzD5BlbpTt6nAwK+g6KAPmSez8Vazo0uiW+j+Ll1S91gxR6vqltKGGmOuwQzzDLbNx3smCnU1197c+KvCWjabolx4YkvtUW3isJNX0CwllaLTNpQqkxwwuAy7wMbBlTivbKKAPmyfRde1C3l0vw/4d1ltLsrg+IrhvFdk5nvbpBtaEbBtkDqV+UgMx3fNXX+GtF17WdZ0jW7Dw7pujaXbpDHqGkanZPbqLpWDyXVtCAV37SESRju4IPSvZKKAPH/FWq6xqnxD0X+yLDxzZ/ZdVgtbz9y8emzW6ytvk+UndnI+Y8FBzXsFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAf/Z", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "034423", + "Speciality": [ + "Consultant Gastroentrologist", + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري الجهاز الهضمي", + "استشاري طب الباطنية\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 349962, + "Name": "AISHA ALOSAIL", + "ProjectID": 60, + "ProjectName": "Khobar Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.84, + "DoctorAvailability": null, + "DoctorID": 349962, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": true, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "26.3107804", + "Longitude": "50.2108347", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 2169, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 398.2, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Khobar", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "034423", + "Speciality": [ + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 296487, + "Name": "KHALED ALDERAAN", + "ProjectID": 60, + "ProjectName": "Khobar Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.77, + "DoctorAvailability": null, + "DoctorID": 296487, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "26.3107804", + "Longitude": "50.2108347", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 1740, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 398.2, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Khobar", + "QR": "data:image/png;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCABkAGQDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3+iiuf8XeLrPwdp1reXlnfXn2q7SzhhsYhJI0jBioClhnO0jjnJHFAHQUV5//AMLT/wCpC8c/+Cf/AOzq5pvxK03U9GbVE0nWYYItT/s26Wa2VWtGChnlm+bEcSA/MxPHcUAdpRXm8nxm0f8A4mEtn4f8R6hY2EskU1/Y2aS23yfeYSB8bcYbJxwQa0PCPxS0fxj9qls9P1WzsbWJ5Zr++hSO2Xbt3KZA5AYBg2D2BNAHcUV53ZfGjwrqGs6lpdv9raeySUxsPKK3rIwUJb4fMjuT8gwN1dJo3i6z1TTkvLyzvtD8y7FnDDrMQtpJpCAVCKWO7OSBjklTxxQB0FFc/wD8JV/1Adc/5Cv9mf8AHn/5Mdf+Pf8A2/0rn5PixZ/2jqFnZ+FfFeofYLuSzmmsdOEsfmIcMAwf6HnBwRxQB6BRXn8fxYs/7R0+zvPCvivT/t93HZwzX2nCKPzHOFBYv9Txk4B4r0CgAooooAK8/wDin/zJX/Y12P8A7PXoFef/ABc/sf8A4R7Sv7X/ALc/5CsP2P8AsTZ9p+0bJNm3d+OMc524oA8w/wCLj/8AC5P+Zr/sT/hIP+nj7N9n+0f98+Xs/DHtXofgJ4Y9G+Ib3FlJfQL4j1IyWkcQladdq5QIeGLDjHfOK5SNdHuPEOn6HZ+LPideX11FHLMltqKSfYdz7GW4A5jZDjeCPlyK00sofD2jXdvomqazbT6Rrr63qseq3AS7v7WJcTPGFwZYpCBgthWYHJFAEcP2Oz07V/D3hfyJ7HxJFNv01MNe6XeXA2Hzoo+IbaIbVbgsjcc1Q0b/AIRvwp8PE06X/hI7jyPEosb62sfLf7ZeLEFkhC8eZbPtxtb5m4yKseGrDzvBvirxxFaX2l3yard61YytH5El1biMSxxSnq9ux5ZVbBI4PGa5vSfFeg6/b2NvYG7h1SLXY/E+oR3exVuZgAJLezAJZ3ZiPLRuTzlqAJLnUPDcPh7xBL4X8Pf2XfJd3Nw9/wCIrKOD7LIE5trSSM5S4U7Wjj6jDHtVO58dTazb+Hb9LyS+gW3ttGutOllMt+LrGXvrWPcR5uDtSY/NuOCK6i91L4fSazpvhu4XWbmfV9di1uSAi3dYLqVjGba4UnKhTw8eCwz1NYeu+HbzwR4h1OWfwv8AaLGC7l1/S7/SNPL/AGeRXPlQXEhAC26hdzovI4INAHb+F7+z8OfY9XvLv4gP/aWoJosNl4hkB2ySbWWXYcYXgjcCT94YrkNX/wCEk/4Q3xT/AMIv/av27/hOrvf/AGZ5nmeX5Zzny+dudvtnFZfhrxB4q8a3GkPcXFpfQL4thv5LSN5Zbu1XIywQkhLVQ2M9mOM13cPhrw3N4h1eL/hMfFfhu+vNVmb7A+px2f2qR3/1sMeMvGx+VW6nbjtQBzGkf8JJ/wAIb4W/4Sj+1ft3/CdWmz+0/M8zy/LGMeZztzu9s5r6HryfUPBej6X4h0KK88TeMtcvo9Qt7mGwa/S58nDnbcSxlQVhBBVnHTdjvXrFABRRRQAVwfxZg02Twra3GqReIGgsr1LpZNCVTPAyI58xi3CoozluMHbXeV5f8ef7Y/4V4v8AZH27/j7H2z7Jv/49/Kl3+Zt/5Z9M546ZoA4x7ObTLi08SWWj+J5tUlskuNNn0O2LQXcJPmRDUWHzSTuwBm2nBG3FY+uDXrq4tvEFhoHjybxFK6jULe/s3aweEkvJbqo+cwF8ARscbc55r0v4fX/9qeHrCfTru+s9btfD8dnb6Tqcnl2021EK3YhXLNGXIXzR1AIxms/WYdYm8Gv5uta5pd8niAvfeZdPBJdYjPmQad3eNj/qUbqRz0oAxPD9tDa6zBZePPE+paTPdW66rFpa34g0tLVmAFm8UvIIO9TEPl2DGeDVPxxoHg++8ZadeeHtX0q38+KKx0+HQLmFJI9RaRjFNKqDiEZUM6/ODtwKr/ZbO+/0PUbj+2b7Sbv/AISK4m1BxcXMelRcNYys3IuASS0JwgJPzDNcv4Xj0f8A4XJZ3mp6bqun2N/qCXmiwwwJF9+4UwFlbjycZB2Z6cGgDrL0abdeKtN8M6zoGpadPp9vFPea9YWaw3b3UbmN7trhuTak5cykBtwDGtjUtW8VaNcL4gTUNN8VeD4E/si6t7KaW+Y2oJd551yI/P8AKGGcnb8wyMGqfijQLPVPGV5LLq/ivQ/Mu3tr6/1y5FtZTWZkbzLe2kwd2c7kRvlKqxPStPwVZ6l4E1mbwo+jya74P1p2uLW+srZrpQszLGgnk+WPZ5SbmwD94EZBoAoeH7zwTdeOoNUfWLTw7OLdbu1XR7mG0tHtfNDJb3fc3BP+sQHbtUYPFR2f9j/8JD4t8Q+L/wC3P+Xz+yNSn2fZvs+/fD9ilk/5ePvNHsOMcjvWnqHw70Hwl4q8S63bx6NfQLoV1fx6RfqkrRTby4ZYQoAgAXYDnIyRmtTwjqvhu++Hl1PrlhPceRE+rtpWqQxv5caxKS1nC54thkrGeg5GaAOM8IHTZPHWnXD6/wCLta1S4eOa1k0+8W4WCwaVSkN6fvKVb/WqPlGRjrX0XXzhpjXmqeMtG1zQ/CeuaH5mqwRK+nacbaym0oyBw0xTO6Q5G452FVHpX0fQAUUUUAFcH8WZ9Nj8K2tvqkviBYL29S1WPQmUTzs6OPLYNwyMM5XnJ213lcf8R9K0fVPD1v8A2vf31n9lu1urP+z5kjuZrhUfZHFuB3SHJ2qOSQMUAcWNH03RvCuiap4f1y7aey1OD7Qt/dqb8wom5tLXYAd+QuLYkDdmqGpWUOs3C+Jk1TxPbT6Rqf8Abd1oPiC4CMLWImR3t7fk4ydiEkLwykiuH1hIfAms6O+qXviCaeXWINfW0mlDKLUseZkbaftmUIb+Htmu/geGS4i8eWFl4guYNXvRpuoQ+I4g8EGmSnzpJYwOFgUYAZmKAFsg9aANC2vfCuoW/iLxvpelSWOqNoVyW0rUreKJb2HHm/aGiX5pEdiFMm7DYI965SwuvB/xU1G2vPs/iOw1vQ9EWXydHSGKMeSQdtuvzNu3yYQccAdDXT/8gv4h/wBr6v8A2HeaJdaV/ZlnZaR+88nTml3JcXCNhVtwgIdwdgyABiuY8UQ+G5viHef8IlrUGl7PDTvaf8I9dRwfarwStsg/d/fZvl+QfMcLjoKANTwxZzXXiq/fVNH8a6t4dtdHkuFtPFFsZ2e6VxxEjfIXKZC/xcsOhqunivXr3x1d6NZGRYL3QnstNstH3hdKZ5dsT3aA4gliBCyFQdnAArL8L+KPHlnqNn4Llvv7X/tXZLfXUMs9xe6XHKVikVnz+5ki6kMpCMcnOcVcT4Val4S8VXes6prusrpd7cPCt7o92wu4ld93nXbsgURBVLSNk4bBoAsQeIptM+JcVvrPhvxBq09r4XGkXkcdiZ2u2WbDzgMcyQOQfnPXPI5qTxd4qs7H7Lr2h6DPb63PEnh5fDus2YTzLNtzhktkO4qXAjBztPK7c1wd7FqVr8XNNsLfxzd6jBqFxFax6jYas006Wsk5AjaQcBwPmK8rkg16vqGm6Do3gXxLe37ak2qWT3Vvp+qeJihuzMkRMZtZSA2zcCybcHduIoANa8T6lJceAPDdhp2pWOqM+nalqEFhA0UEFrkxyRMoO5UVsAqw2gAZNeuV8+aXq3irWbjwVcJqHh++nW4sUupNHmll1QWuQXF2ck+Vk/vAfl3kZr6DoAKKKKACvP8A4saNea7p3hqzs0vv+RgtWmmsQfMt48OGlDAHZtyDuPAOK9Arz/4sSXn9neGrOz1K+0/7f4gtbOaaxnMUnluHDAMPwPORkDigDk9N+HepeM/HTap4rjkGl6C/9m2SzK3n36wSho5ZvMUrKjqzbmUjcegFZmp3V5pfjLWdDit/FcWiazaT6HYpqKFbKG8mkKR+SOFW3CD5doLBc4BFV/7X8N/8Jl/wi/8Awl/xO+3f2h/Z/mf2lH5fmeZ5ec5ztz3xnHatjT9Zs9L8G67Z+I31zXPL8V3GladMpFzewyCMCJ4mcjbIMMVK8hm4HNAGfqvgLxJ4c+HllZ6ib7VL59VjtribRDJPcrpRiIa3VmUER5BIQ/Jkr61y+q/Diz0vxlZf2Rc6rZ2NrokfiG8+1uI72GNZDvWPaoCzAAYB4DA5auwv9V8eaXqNz59h4jvLG68NNa6X9ghnkkhkYnypLrJAW5AHzsvIJGKt/DXR9B8T2+pve654gm8RS6ZLo2pWmq3aNPEpCea0aEF1QOxALdDkEZoAg8KeBJtGtx4kt/EMcE/ia4+zxz396VnNhchZAVYKD9uyMjllznrWudYh0bRtb8KXGh/ErWYLh57eS+ntBcMVZfLJikJA2YG5eO+e9Z+m/BbXpNZa31vxbqTeHbJ9+lR2uouZ4GRgISQybFKpnlcYOMcVc1/U/Eml+MtLi8F67Y655dpFo9zYXV3JcyQyCQ77qeOIjbjCK0h5BYjHIoA881zSdB8GW9tceD9P1nUdU1BFtRJfwpMthNICfLUxgNFfIyrheSuT7VqeKviT4ksfD2i2eo+CvtFjBaQRXE3ifSpH8y8VGDMrM2DkAkE/Mfmrk538VaN8S5X1my1JoLLWDrt5aWcUpgKpN89xGjYGzAIDnHGATXUeK/GMPifwqbjw/o3ifVoLXXf7XuJNXtRPaRKqMWgyjELEAy/Ieik880AZfwptf+Ej8ZLeaRcT6Xraah9uvIbd/Ism04SIXhRVyxbeQAh+TaOTkV9T15fpGjWfiPw94W1zwgmh6XfJd2lxq76YBBujCB5rYmMEnkr+7c44Gegr1CgAooooAK8/+LEd5/Z3hq8s9NvtQ+weILW8mhsYDLJ5aByxCj8BzgZI5r0CigD54/sjw3/wmX/CUf8ACIfE77d/aH9oeX/Zsfl+Z5nmYxjO3PbOcd62NKttYuPD17/xTV9F/bPjWST/AEuxdbmxt5kH+lR/885E7SchTnrXt9FAHl/j7StY0L/hF9X0i/8AFeofYLu0tbyytJnl+0W6bmeSRFA3yNgAsSAcgGsDX/C/iTVPinpeueC7H+w/M0qK+uXuopLaOaQzl3hnMQO6Q5TchOSFPPAr2+igDj/7A8SQ+HvscGr777UrvzdUmnuZD9ljkTEq2TAZTaeYw2QO9cBdaFrFj4yg1Hw5pV9b2M+3wzqNzNbul7Juk3S6grIMHICkTt1bqte30UAeZ+MdJ026uNJ8M3Gn+Lpp5beG1k17TIVZnhJaMx3NwRkoT87rjHRq881/TPElv4y0vQ/Beha5Z6Ja+VY3KXVpJHZX0iyFHmnEQ2yRumzc5GWUHjGK+j6KAPG7nSfiDo1x4dt00/w/Y6W2u2z3UfheG4iYrnDmUYC+VtHzE+i5r2SiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAP/Z", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "034423", + "Speciality": [ + "Rheumatology Consultant" + ], + "SpecialityN": [ + "استشاري علاج أمراض الروماتيزم" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 340682, + "Name": "IBRAHIM ALZAHRANI", + "ProjectID": 60, + "ProjectName": "Khobar Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.7, + "DoctorAvailability": null, + "DoctorID": 340682, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/KHOBAR/340682.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": true, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "26.3107804", + "Longitude": "50.2108347", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 1385, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 398.2, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Khobar", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "034423", + "Speciality": [ + "Consultant Gastroentrologist", + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري الجهاز الهضمي", + "استشاري طب الباطنية\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 291086, + "Name": "METEB ALBUGAMI", + "ProjectID": 60, + "ProjectName": "Khobar Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.54, + "DoctorAvailability": null, + "DoctorID": 291086, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/KHOBAR/291086.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": true, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "26.3107804", + "Longitude": "50.2108347", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 907, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 398.2, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Khobar", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "034423", + "Speciality": [ + "Consultant Nephrologist" + ], + "SpecialityN": [ + "استشاري أمراض الكلى\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 401986, + "Name": "ALI AL SAEED", + "ProjectID": 60, + "ProjectName": "Khobar Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.85, + "DoctorAvailability": null, + "DoctorID": 401986, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/KHOBAR/401986.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "26.3107804", + "Longitude": "50.2108347", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 577, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 398.2, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Khobar", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "034423", + "Speciality": [ + "Consultant Internal Medicine", + "Consultant Infectious Disease " + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n", + "\r\n\r\n\r\n\r\n\r\n\r\n\r\nاستشاري الأمراض المعدية" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 388826, + "Name": "SALEEM SALAH SALEEM KASHAN", + "ProjectID": 60, + "ProjectName": "Khobar Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.86, + "DoctorAvailability": null, + "DoctorID": 388826, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "26.3107804", + "Longitude": "50.2108347", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 424, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 398.2, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Khobar", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "034423", + "Speciality": [ + "Consultant Internal Medicine", + "Rheumatology Consultant" + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n", + "استشاري علاج أمراض الروماتيزم" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 408163, + "Name": "SALMA ALBAHRANI", + "ProjectID": 60, + "ProjectName": "Khobar Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.84, + "DoctorAvailability": null, + "DoctorID": 408163, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/KHOBAR/408163.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "26.3107804", + "Longitude": "50.2108347", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 83, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 398.2, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Khobar", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "034423", + "Speciality": [ + "Consultant Infectious Disease " + ], + "SpecialityN": [ + "\r\n\r\n\r\n\r\n\r\n\r\n\r\nاستشاري الأمراض المعدية" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 419308, + "Name": "YASMEEN ABU ALSAUD", + "ProjectID": 60, + "ProjectName": "Khobar Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.79, + "DoctorAvailability": null, + "DoctorID": 419308, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/KHOBAR/419308.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "26.3107804", + "Longitude": "50.2108347", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 14, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 398.2, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Khobar", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "034423", + "Speciality": [ + "Consultant Internal Medicine", + "Consultant Medical Oncologist " + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n", + "استشاري طب الاورام" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 392828, + "Name": "ABRAR FAIZ KHOJAH ", + "ProjectID": 120, + "ProjectName": "Jeddah-Fayha Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.73, + "DoctorAvailability": null, + "DoctorID": 392828, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/AlFayha/392828.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": true, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "21.50907430916284", + "Longitude": "39.21568919999999", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 1430, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 841.4, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Jeddah Fayha", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "023623", + "Speciality": [ + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 398094, + "Name": "MOHAMED ANWAR HASAN", + "ProjectID": 120, + "ProjectName": "Jeddah-Fayha Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.9, + "DoctorAvailability": null, + "DoctorID": 398094, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": true, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "21.50907430916284", + "Longitude": "39.21568919999999", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 1110, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 841.4, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Jeddah Fayha", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "023623", + "Speciality": [ + "Consultant Nephrologist" + ], + "SpecialityN": [ + "استشاري أمراض الكلى\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 400158, + "Name": "MANAL HAMDAN", + "ProjectID": 120, + "ProjectName": "Jeddah-Fayha Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.74, + "DoctorAvailability": null, + "DoctorID": 400158, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/AlFayha/400158.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "21.50907430916284", + "Longitude": "39.21568919999999", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/LBN.png", + "NationalityID": "LBN", + "NationalityName": "Lebanese", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 816, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 841.4, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Jeddah Fayha", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "023623", + "Speciality": [ + "Consultant Internal Medicine", + "Consultant Infectious Disease " + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n", + "\r\n\r\n\r\n\r\n\r\n\r\n\r\nاستشاري الأمراض المعدية" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 399412, + "Name": "OLA TARABZUNI", + "ProjectID": 120, + "ProjectName": "Jeddah-Fayha Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.56, + "DoctorAvailability": null, + "DoctorID": 399412, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/AlFayha/399412.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "21.50907430916284", + "Longitude": "39.21568919999999", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 344, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 841.4, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Jeddah Fayha", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "023623", + "Speciality": [ + "Consultant Nephrologist" + ], + "SpecialityN": [ + "استشاري أمراض الكلى\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 419317, + "Name": "SHIMA AZIZ", + "ProjectID": 120, + "ProjectName": "Jeddah-Fayha Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.88, + "DoctorAvailability": null, + "DoctorID": 419317, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "21.50907430916284", + "Longitude": "39.21568919999999", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 300, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 841.4, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Jeddah Fayha", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "023623", + "Speciality": [ + "Consultant Endocrinologist" + ], + "SpecialityN": [ + "استشاري علاج أمراض الغدد\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 399426, + "Name": "EMAN MANSORY", + "ProjectID": 120, + "ProjectName": "Jeddah-Fayha Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.97, + "DoctorAvailability": null, + "DoctorID": 399426, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "21.50907430916284", + "Longitude": "39.21568919999999", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 213, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 841.4, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Jeddah Fayha", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "023623", + "Speciality": [ + "Cons.Hematopathologist / Transfusion Medicine" + ], + "SpecialityN": [ + "استشاري أمراض الدم / نقل الدم\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 404463, + "Name": "FAYEZ ALHARTHY", + "ProjectID": 120, + "ProjectName": "Jeddah-Fayha Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.85, + "DoctorAvailability": null, + "DoctorID": 404463, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "21.50907430916284", + "Longitude": "39.21568919999999", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 184, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 841.4, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Jeddah Fayha", + "QR": "data:image/png;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCABkAGQDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3+iiuf8XeLrPwdp1reXlnfXn2q7SzhhsYhJI0jBioClhnO0jjnJHFAHQUV5//AMLT/wCpC8c/+Cf/AOzq5pvxK03U9GbVE0nWYYItT/s26Wa2VWtGChnlm+bEcSA/MxPHcUAdpRXm8nxm0f8A4mEtn4f8R6hY2EskU1/Y2aS23yfeYSB8bcYbJxwQa2Lr4j6PD4Ng8UWdtfapYvt86PTo0nktcx+Y3nANhNoxuyeCR60AdhRXnem/GPQdQuGt30zWbGdrL7bax3sCRNerkBEgG/MjuT8oH3sHBrpNG8XWeqacl5eWd9ofmXYs4YdZiFtJNIQCoRSx3ZyQMckqeOKAOgorn/8AhKv+oDrn/IV/sz/jz/8AJjr/AMe/+3+lc/J8WLP+0dQs7Pwr4r1D7BdyWc01jpwlj8xDhgGD/Q84OCOKAPQKK8/j+LFn/aOn2d54V8V6f9vu47OGa+04RR+Y5woLF/qeMnAPFegUAFFFFABXn/xT/wCZK/7Gux/9nr0CvP8A4uf2P/wj2lf2v/bn/IVh+x/2Js+0/aNkmzbu/HGOc7cUAeYf8XH/AOFyf8zX/Yn/AAkH/Tx9m+z/AGj/AL58vZ+GPavQ/ATwx6N8Q3uLKS+gXxHqRktI4hK067VygQ8MWHGO+cVz97o8On3Gmpca58WVgvbeK4kuzdgQWSuTkXDkYjKAZfrtHNWILKHRPCsVx4f1TWYYIvFAvbiTU7gLPrKhMslsUwLgTALsB++c80AVzPpuk6NrejeH5bQ6Xr1vO9xZFl+16RdTrtY3CJhYLWJQquSCyNxzWx4U0OFvhoLe4utNu4NLuPOkj8IyB11FYoVBinBGJXkH3l43ZTpWBo+izXWjaxqj+HdZtNU1TxRObVXsijPDKoZEvONxsy3+sAJHHGaktY7z4c6dPZ65puuf8hVtfabwnAfsSR4wYJGfbiMbCSnTbt5oAn1PTP7d/tnxpFoU+kWOleGp7GxtdRtPs9zb3EWZY5oUwQiqDhXVgQQQAMZrjLnx1NrNv4dv0vJL6Bbe20a606WUy34usZe+tY9xHm4O1Jj8244Iru9G1Oz8Y+Mk0Oz12+vNEurQeIpka7EkiyNIEaxlAJUW4RhuhIzk/exXIa74dvPBHiHU5Z/C/wBosYLuXX9Lv9I08v8AZ5Fc+VBcSEALbqF3Oi8jgg0Adv4Xv7Pw59j1e8u/iA/9pagmiw2XiGQHbJJtZZdhxheCNwJP3hiuQ1f/AIST/hDfFP8Awi/9q/bv+E6u9/8AZnmeZ5flnOfL5252+2cVl+GvEHirxrcaQ9xcWl9Avi2G/ktI3llu7VcjLBCSEtVDYz2Y4zXdw+GvDc3iHV4v+Ex8V+G7681WZvsD6nHZ/apHf/Wwx4y8bH5VbqduO1AHMaR/wkn/AAhvhb/hKP7V+3f8J1abP7T8zzPL8sYx5nO3O72zmvoevJ9Q8F6PpfiHQorzxN4y1y+j1C3uYbBr9LnycOdtxLGVBWEEFWcdN2O9esUAFFFFABXm/wAZo9Y/4R7Q7zQ9Nn1C+sNbgvFhhgeX7iSEFlTnbnAPTr1r0iuD+Luua9oHgWa48P2sk08rtDcSRxuzW0JikLSgoQUKkL8x4FAHGeONP8SeI/7O1O68Q/2XYp4fivNc0O3vZILloxua4KQEEHg7BvOMjDHissaPNrPhXREt9cu9F8H2+pwXEd34muzb34ZU4Fq4Bj8ryjlP9oMegqnN4ovNa8PaRZ/btDuPFMFpDdeckpf+0LNUx/Z8zZLy3Ekhy0H3W+tc/qt1Z33iGy0rxRb+ObexntI5U0eJAnl3jOVC20MnAtwCyIMbh0oA2IZ/sPjLV7PV/ijqtxokGnzX1nNpmv75JNsmEhLN8pmKAnYOpxg4o8VanrHiPTtFs9O13VX/ALSlg023mgu3Nk1vIGCx3rKTm95BkUZG3tWxo3h2z8LeDUvLPwvY+J/O8QBZoW08Xt7Z2ZjBaKVQB5dwm0BlPyqze9R6b4O0HxtcMPCms6zos9vrv2q90W9ukt2tVUjzJIII1JR1LKis3TBB6UAdn4R8G6P4I0660GWG+t76fSnur7xEqokdvuCpJHFc7QV2lfMVWHA+Y1zmpat4q0a4XxAmoab4q8HwJ/ZF1b2U0t8xtQS7zzrkR+f5Qwzk7fmGRg1Jf6v4P8LeIbnwvqPi/wAV6v8A2raNp9xJcalDcW1n5rmNi5Yjy5E2nJIO0Hoc0/wVZ6l4E1mbwo+jya74P1p2uLW+srZrpQszLGgnk+WPZ5SbmwD94EZBoAoeH7zwTdeOoNUfWLTw7OLdbu1XR7mG0tHtfNDJb3fc3BP+sQHbtUYPFR2f9j/8JD4t8Q+L/wC3P+Xz+yNSn2fZvs+/fD9ilk/5ePvNHsOMcjvWnqHw70Hwl4q8S63bx6NfQLoV1fx6RfqkrRTby4ZYQoAgAXYDnIyRmtTwjqvhu++Hl1PrlhPceRE+rtpWqQxv5caxKS1nC54thkrGeg5GaAOM8IHTZPHWnXD6/wCLta1S4eOa1k0+8W4WCwaVSkN6fvKVb/WqPlGRjrX0XXzhpjXmqeMtG1zQ/CeuaH5mqwRK+nacbaym0oyBw0xTO6Q5G452FVHpX0fQAUUUUAFU9Sn02O3W31SW0WC9f7Ksd0yhZ2cEeWA3DFhn5ec81crn/GX9j/8ACPTf2v7/AGPytn2n7RsbZ9m3f8vHXZjnPSgDzPQ9J03wZ4qubi/0/wAMajpeoeI2tdPksIVmu7C6kcGONiQFiRFU5VcsrEYq5qfg37dqOs+KLOHXLi+gu57WaPWF3yR26kyNJpgC5EgJHksTgHNc5qYhutZ8L3FhoHjXToNP1O0n1CTVLMQ2jrGxMl3ORwZyMbpWx8oOa17z4gTaNrOq2D2Pi658O6u8yWuopCXnN1K2EFnJuCeRsG6MDLZORkUAeaeHP+E8/wCEyk/4Rf8A4SP7D/bZ3/bfP8vzPMGftnl8bsbfM74zXYeI9VvNC8ZR6vBYQaffX8Q0LVLKyhMV7cSPIWlvLNAQXViMRysSSwAIqnqWuQx+Klt0tfiHo2l2+j+fdR2UYt7ueZXIe7nGdrBl+9KeSwGeldB8RoIbXwr4c8YaNFd6jqmoWVtpFmb9RNOiyI8qTrt+YXQbGHBPJOB3oAn034d6Dr9u3ivVI5LufS3ytjp6o89ysQEmy9jZSXvGJKyjIySBxVBPFevXvjq70ayMiwXuhPZabZaPvC6Uzy7Ynu0BxBLECFkKg7OABWnoXi7ydR0zwXBZzv8A2lokTapdaRFm9tdRkIilluHDfIy9XZlLhsE+lYifCrUvCXiq71nVNd1ldLvbh4VvdHu2F3Ervu867dkCiIKpaRsnDYNAFiDxFNpnxLit9Z8N+INWntfC40i8jjsTO12yzYecBjmSByD85655HNSeLvFVnY/Zde0PQZ7fW54k8PL4d1mzCeZZtucMlsh3FS4EYOdp5XbmuDvYtStfi5pthb+ObvUYNQuIrWPUbDVmmnS1knIEbSDgOB8xXlckGvV9Q03QdG8C+Jb2/bUm1Sye6t9P1TxMUN2ZkiJjNrKQG2bgWTbg7txFABrXifUpLjwB4bsNO1Kx1Rn07UtQgsIGiggtcmOSJlB3KitgFWG0ADJr1yvnzS9W8VazceCrhNQ8P3063Fil1Jo80suqC1yC4uzknysn94D8u8jNfQdABRRRQAV5/wDFjRrzXdO8NWdml9/yMFq001iD5lvHhw0oYA7NuQdx4BxXoFef/FiS8/s7w1Z2epX2n/b/ABBa2c01jOYpPLcOGAYfgecjIHFAHCXum6lH4q03S7BviVfQLrEVvqDauWlsJ7XeVkPAwyMMfeG0qTmuj126/wCEc8G6neadbwJ/Zutyy28Pi1MRr5cZKrYKuMLwBEBjjfXIf2v4b/4TL/hF/wDhL/id9u/tD+z/ADP7Sj8vzPM8vOc52574zjtWgviSz8OfDzxP/wAJHHP4k+x+JbrT9O/tZRebZEi/dF95GF4bJXn5jgc0AZ+t+MPEninUfDeoweB9V+w+Vavqlzb6TJ5l5HktLAjBiJLZw2QjcMetY/xD8UWdxqOjxXl9fWf2W7hlhsNGlEcdjZqX2q8ZP7u/TlSB8qgAV0F0tnceDYNT0PxZ4rvNburRZV0Pw9qIkjsZGj3BfIT5o7dHwmM5UFR1qPTR4J1nRmv73QNZvvES2X9jalp1rZwy3Ym2gy3xjOX37yV85udxAIzQBy+kpqXhL4l2KW97JJB4wt4xHdySsbuK1u5hhy4wBcALnPzKG55r086xDo2ja34UuND+JWswXDz28l9PaC4Yqy+WTFISBswNy8d8964DxRpsOs+KvBL27alo0Fu9jokdpfkW+qBVdsXKoARswcCT++CMcV3ev6n4k0vxlpcXgvXbHXPLtItHubC6u5LmSGQSHfdTxxEbcYRWkPILEY5FAHnmuaToPgy3trjwfp+s6jqmoItqJL+FJlsJpAT5amMBor5GVcLyVyfatTxV8SfElj4e0Wz1HwV9osYLSCK4m8T6VI/mXiowZlZmwcgEgn5j81cnO/irRviXK+s2WpNBZawddvLSzilMBVJvnuI0bA2YBAc44wCa6jxX4xh8T+FTceH9G8T6tBa67/a9xJq9qJ7SJVRi0GUYhYgGX5D0UnnmgDL+FNr/AMJH4yW80i4n0vW01D7deQ27+RZNpwkQvCirli28gBD8m0cnIr6nry/SNGs/Efh7wtrnhBND0u+S7tLjV30wCDdGEDzWxMYJPJX925xwM9BXqFABRRRQAV5/8WI7z+zvDV5Z6bfah9g8QWt5NDYwGWTy0DliFH4DnAyRzXoFFAHzx/ZHhv8A4TL/AISj/hEPid9u/tD+0PL/ALNj8vzPM8zGMZ257ZzjvVw6fr2p+Bdbt7fwrIZ9e8WzmOPV9PfdaQzxYFxgDMZQn/Wcgc9a97ooA8bi0WbwJ4q8KJonh27m1SWys9N1W7tbItYCEv8AvpS6hW8/cgO5uNuCRXSan4Xs/wDhMtZl0OxvtP1u/wDD88S38MQisvMeQ4ZpEG77RvwxPJ2jPWvQKKAPN4/hxeQ+HtPgluYNU1t5Y/t2rao5nubWMpiT7HNt3Iyv80e7gEknk1zF1oWsWPjKDUfDmlX1vYz7fDOo3M1u6Xsm6TdLqCsgwcgKRO3Vuq17fRQB5n4x0nTbq40nwzcaf4umnlt4bWTXtMhVmeElozHc3BGShPzuuMdGrzzX9M8SW/jLS9D8F6Frlnolr5VjcpdWkkdlfSLIUeacRDbJG6bNzkZZQeMYr6PooA8budJ+IOjXHh23TT/D9jpba7bPdR+F4biJiucOZRgL5W0fMT6LmvZKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//2Q==", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "023623", + "Speciality": [ + "Rheumatology Consultant" + ], + "SpecialityN": [ + "استشاري علاج أمراض الروماتيزم" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 402223, + "Name": "SULTAN ALTOURI", + "ProjectID": 120, + "ProjectName": "Jeddah-Fayha Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.84, + "DoctorAvailability": null, + "DoctorID": 402223, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "21.50907430916284", + "Longitude": "39.21568919999999", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 135, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 841.4, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Jeddah Fayha", + "QR": "data:image/png;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCABkAGQDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3+iiuf8XeLrPwdp1reXlnfXn2q7SzhhsYhJI0jBioClhnO0jjnJHFAHQUV5//AMLT/wCpC8c/+Cf/AOzrQ0r4j6Pqnh691f7NfWf2W7ksfsV3GkdzNcKgbyY03HdIc4C5ySCMUAdhRXDx/FLR/wDiXxXmn6rp99f6hHYw2F9CkVz8/wB2Yxl8+TnK7xnkEYqxdfEfR4fGUHheztr7VL59vnSadGk8drmTy284hsptON2RwCPWgDsKK5NPiBpses3dhqljqWjQW7ui6jqsK29pOytjEcjNhiwywHdQT2rL0/4weG9U1HXbOzhvpf7GtLi8mmVY2jmjhIDGJg53ZyCucAjuKAPQKK8r0n4+eFdZ1mx0u30/WVnvbiO3jaSGIKGdgoJxITjJ9DWpJ8WLP+0dQs7Pwr4r1D7BdyWc01jpwlj8xDhgGD/Q84OCOKAPQKK8/j+LFn/aOn2d54V8V6f9vu47OGa+04RR+Y5woLF/qeMnAPFegUAFFFFABXn/AMU/+ZK/7Gux/wDZ69Arh/ijYWd94esftlp4juPI1COeH/hHow9zHIqPtfnooyeRyDtoA8o/4uP/AMLk/wCZr/sT/hIP+nj7N9n+0f8AfPl7Pwx7Vc1BNNk8K+JUv727sZ28e3Q0+7glWJYLrYfLeVzysSnJYr8wxkVr6bYaDqestpafEHx5DPFpn9pXTTayiraKGCvFN3jlQn5lI47msjUtN01tGXRNLa7hgi13+2W1fxiVWw1FgpTakyjEokGHAx8y7zmgCnbWt54I8Q+H9V8UXH9v317d20SaxdubrTbezd9waOaTBW4Uqzg5KhGJ71T8SzzN4q1fxAJZNJnunm0/R7fw4xgu9RZnLwXUi9ZYJDwZEPzMFwOK6S11nwfqnh6ez1x9VlsdG1BtRaYmFtNmuIUwbK0ZyQ0JBJjh4JTuK03tvh9qejWmqWXifTYdUiuE1XTV1K/t1a0YLuis2x80dujEZiU8c4NAFDT/AA7qWv6z4aHxH8SabDBFZWr2mim+ZZ7mYMNhuIJgQ7sDIjkck8DvV+21qHRrjxFYP8N47Gdri5srXUYtDEVgbXOEe6kyD5WRucj5doyBXnmn+KP7U8Q67L4jvtKlvtGluNY06/WXd51xC48q1ikcktbElmWNcE9QRXcXniKzvvD3hKKDxR9vvtc8QWdxqlh/aAl8uOZP3tt5YORbgnb5bZAzg5oA4fwFrd5D8QzpFn4W8Oapv1vz5r2108z/AGWMyqrPA4PyQrwVJGBkHvXQav8A8JJ/whvin/hF/wC1ft3/AAnV3v8A7M8zzPL8s5z5fO3O32zitjzvB/g7xD5H9i+K9D8zxBv/ALV+yw21s2Xx5HncZtDt3bPRc9qz4ZPDd94h1eXSNS+I9vYz6rM15f6ZPGmmxyM/zymReBGAQ248hME0AV9I/wCEk/4Q3wt/wlH9q/bv+E6tNn9p+Z5nl+WMY8znbnd7ZzX0PXhnh+28K6/4qgR/E/jW7g0vU1Nrd6rfxSWFzdRONiRvyHdgcgDDFSSMV7nQAUUUUAFcn8RLaG68KyI/ieTw7OHJtbtb8WivNsfYjv1KE8kDn5cjpXWVw/xWutHh8GtZ6vbwP/aUv2GzmuEQx2txJG4SZ2b7iryS4yQOgoA8k8O6HqXw71nX9Z8QXWm6jBqHhy4mt72SRprS+mkYMsRdwokdwjNtBJZTmgaxNrNvoml3+h6yul3txBd6e1/aEWg1Nxtjt1ySv9n7ScIoL7c4qPUP+Ek8R+HtC8L65/ZSaJpuoW8LSWPmC5azjQxm+BfKm22E/vsBc47V18fhWz8R+HtP8L6Hr2qp/Zutx3yyapeAXLWcaeWJrMoDmHkeW2Auc80Ac5o8Gmx2+seD/FcVpouqW+sT67ZC6VbfS52UCKOMeZ8zQM275VHKA4PGK6uw+FOj/wCjajqK6H/Yny61cXNuE/4+OGaJGZNv2DZkhTz74rzTx1Z6lqHiq6TxNo/iBoLK3fRtEu4LZi17Mjt9naV34kLgsWKYLdQK6z+3f7U+Hn/CD6vqv2PW7XSvOs4tIuPL87bF5SWNwGJZrguSHhC84GOeKAMv4geH9Njt7PxXo1t4fvp111LCzsdERZbSeHDSIs0ajLTscKwBwVKgCun1jVPCun2+j+H38I2mmeMNb0yB7W4tdNihWyupgUQls+ZGUlGcgFlwMZNZFzZ69a/CPw6+l6Ppt3qml67bXDWmj2zuyNFB0u0X5hOGwJOnUDis/wAa3mm6To0PitNYj1HxhqCLb3Vje3KzNpDSK0jmCPiSB4pRtXJOzJB5oA6/4leCvG2v+BdM0tJ9Nu4NLsori6Znmku7m6iidXCfKQ4YHjIDFjzisT4cf2x/wj1x4e8If2H/ABf2vpviff8AaftGxEm2xR/8u/3VG8ZzuB7Vc8C61r0nhW10S48RR3M+r3CSSavPeu6wQyoqG1imJyt8p+dY8EDOea4vw1pXiSx+IfiqDQ7+C38+W70hdW1maRPMkaUAKkyDm5OAwHU8nFAHaa94U1LwlceELdBpq6Xe+KLK9uo4dwaK/ckOkIwFFuFX5QcsO5r3OvEG8UWeqaj4Y0PXL7zf7G1W1sWSGUNezarCdhmYOTutDk5fAct2Fe30AFFFFABXH/Euw+3eDbjzbSxuLGDdPffaY98kdusb+Y9v2FwAfkLcA5zXYVyfxAgmutGs7e3i1KaeW9RI47RS0DsVYAXgHJtSf9YPTFAHnHhoal4zt9IsLfQLvToNPuIRHqN5ZtCt/okYAFvJIMiV3DbjHxG2Cakv9fs9F8Q3PhzSNI1y3vp7torzU7+2Cf2fpTOUdrWVSDFbxkBkJGxeSaj1KfUvCWjLfpL4nWe91P8AsK607cwgiV1JeTTI+CACu2FjnA4IostDh1+31K3uLrxPDBFZSzSR38gXxDcqAAYVBBD2bA8L3lzQBXg0ya68VReCPE3i6SbS5XGu6JqsepFrt2L+VbxiVxtJK7m2ov3uQe1WE8PzNcXd7rdv4f0KDRdTcaVql8htbvUbqE5he5lYYlikGWcrhmZSRjFc/BrE3w+1mLS9W0OPWZ7iyF34ca8tDcX9ozNttbeTcVKBShykY4Ynb1rp/EUGm6no2geH/GEXi4z69e2+oG4jVfItLqdSn2UNJzGiEsfLwWA7nmgDU1lf7U8PPLZ+LPDmh2MkRlmv9G1H7N52slDuV5BkNCQQxB/eHaD2qn4tGg+CvAvhnWb3QPD+sz3Fxaw6letZpcNdK0TNLKjnBd2KlgzHnOT1rAvPB0Pw10bVQ+s+H76dbia6tdF126EsElrt+SRYNqk3RKbAw+XBYCsfxb4r02Twr4Z0bSzJrWqXF7a6y1k224tIGZGX7CiKdyorYUQ44U4zzQBsT+MYdT+Gktxo2jeH9JguvFB0+zkktRAtorQ5S6JVsRzoCP3g6Y4HFR+EfFV5ffatB1zQYLjRIJXhbxFo1mX8u8XahvnuXO0MEJkM2Nw4bpW3rnhrTdA+Edtf3GialNPLerrsmnQWqtBbXRgJMcsZAKWqkbWX7wHGa4j4Oalr2s+OtQsrBdNXS71JLjUNLnDi0ELyxiQRRAld+0hV3ZG3g0AdAPDGmx+OtE8SX+o6bfaWupwabp8+gzrLPPdeb5kct6xG1nZcmRlO4krgV9B15H4t0nwro3jrwzbvp/iCxga9tXtY9Khii0s3XmsEMgwB5uByR82wDFeuUAFFFFABXH/Ee6vLHw9b3mnW+uXF9BdrLbw6QhfzJFRyq3CrybckAOByeK7CvP8A4sSXn9neGrOz1K+0/wC3+ILWzmmsZzFJ5bhwwDD8DzkZA4oAr2thefEDw9Pq95aarpetpp7WcNlqMZgtoLwJuW7hQ7mVldyFlB3AAjGRWHo9lqWjaNrB1TVI7GdrKfS11rxBcNFdm/2j/j3nbB+x5BdP4twY4rnP7X8N/wDCZf8ACL/8Jf8AE77d/aH9n+Z/aUfl+Z5nl5znO3PfGcdq1LbR9N1/wL4i0vxXrms3cGl+KLmKyZrtZLu5aKLbHCnmAh3YFsIoGWPGKAOT8I6zZ6XqN1qviN77XNbju30rTtYviLnSYZAVaJzM5DLhwz5U5CMSBk13fjHxBNH4V0l/E1xpt94iXU4b/RLTw45lWdtjfZ2kRzvaJn3AlOuVAOa5zRvC/wDxTyaHZ2M+oWNhrY8RTI0Xm/6OiBGsZQBj7bjG6EgDn71XJ4JvHdxLb6tFo3hKe0cp4cjkU2GqFkOLUENuPkZc8R/xp8vSgDq4bDR7j4eav4o1G0sdc1uO0mvLiPU40ufsNwIvMa0Ab5o40fP7onK7jzk14Z4U1KbT9ZHiu3Xwis97qf2SOxvwQtkzssguFjBzHEhG0Pk7eRivW7/VfEngXwbc6RqNh4c+3eU11cXtxDJ9i1GPyyrRu7EGW9kKklSMMvNZF1q/hvS/BsEvjTwJYxf2zaLLbX/h7SI1jhjmj+RfMlI23Aw7YGQBtPPNAGva+KNY8HefF40vtK8R2OvytLbWGkyveXLef9xUjlIBtiFdQBnlgOcmszQ9U0218VXNxf8AhHxB4Zn1h20LT5LDTVsoEhmcGORiTkXAOcsuRhRgHFZbXXhv/hDfDGuaHb65qH2DxXa2yvqKRy3vlpHvFvCU/wCWfTamQNxNWPFXiSz13UdF8L+X4y0++v8AxLBqHmauoikt43LR4tzklFUn5BggEHmgDr7DQPO1G2s9X1fVU0TTdbWWzm1+5xe3WoxkBFiZhte2ZMlQMOW3Y4r1ivEJtPvJvjJpGh+L/EOyx020hvNIRL0j7VJHcbITMJBh7hhu3bACex617fQAUUUUAFef/FiO8/s7w1eWem32ofYPEFreTQ2MBlk8tA5YhR+A5wMkc16BRQB88f2R4b/4TL/hKP8AhEPid9u/tD+0PL/s2Py/M8zzMYxnbntnOO9aELaxD4N1e8/4RPVX/tLxhNc+S+nOb21t5I8/aIV/gmXor8gNXu9FAHi+v+EdY0v4eaXZ+C7zxHFfazrcV5czXUrrcw+dEQ5naJQVUEIWznBzyeK2NM8BeJNU1HRpfGh0OX+xvIltr/TjI17NJCRsWaSVTujOXZgMEtg8c16hRQB5HrVn4quvHWvPrej2mraXa6FcXGlWi20s9o8yynyQ6N8puCuQdvO04HWsy18baxfeDZ9O8R/C2+uL6Dd/Z1tD4fd7KPbHti3K7ZGCWB29F6V7fRQB82eIvDXxBtbfQPE1vommwwRXFvdR6DolrcKqTAGQSTW4GA4HyM2c/dWukumvPGPg2DXPGnhPXLPW7XVVitn8PacY71Y1j3o2ZcsIw7PyDjcF75r2+igDx/V9C0e+8ZeC9RvNK8c3F9BaWPk3It0eOPbIWX7WxGRICSZMdBXsFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAf/9k=", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "023623", + "Speciality": [ + "Cons.Hematopathologist / Transfusion Medicine" + ], + "SpecialityN": [ + "استشاري أمراض الدم / نقل الدم\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 415760, + "Name": "SAUD ABAALKHAIL", + "ProjectID": 120, + "ProjectName": "Jeddah-Fayha Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.86, + "DoctorAvailability": null, + "DoctorID": 415760, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "21.50907430916284", + "Longitude": "39.21568919999999", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 70, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 841.4, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Jeddah Fayha", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "023623", + "Speciality": [ + "Consultant Internal Medicine", + "Rheumatology Consultant" + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n", + "استشاري علاج أمراض الروماتيزم" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية", + "DoctorTitle": "Dr.", + "ID": 420966, + "Name": "TURKI ALSHUAIBI", + "ProjectID": 120, + "ProjectName": "Jeddah-Fayha Hospital", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.75, + "DoctorAvailability": null, + "DoctorID": 420966, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/AlFayha/420966.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "21.50907430916284", + "Longitude": "39.21568919999999", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SAU.png", + "NationalityID": "SAU", + "NationalityName": "Saudi", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 16, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 841.4, + "ProjectNameBottom": "Hospital", + "ProjectNameTop": "Jeddah Fayha", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "023623", + "Speciality": [ + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 197867, + "Name": "ALINE ABI KHALIL ELIAS LATTOUF", + "ProjectID": 3, + "ProjectName": "Dubai Sheikh Zayed Road Center", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.94, + "DoctorAvailability": null, + "DoctorID": 197867, + "DoctorImageURL": "https://hmgwebservices.com/Images/SZR/197867.gif", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": true, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "25.154501", + "Longitude": "55.226000", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/LBN.png", + "NationalityID": "LBN", + "NationalityName": "Lebanese", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 6272, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 865.2, + "ProjectNameBottom": "Sheikh Zayed Road Center", + "ProjectNameTop": "Dubai", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "505005", + "Speciality": [ + "Consultant Family Medicine" + ], + "SpecialityN": [ + "استشاري طب الأسرة\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 226098, + "Name": "SALINA MULHAM IBRAHIM NAJJAR", + "ProjectID": 3, + "ProjectName": "Dubai Sheikh Zayed Road Center", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.97, + "DoctorAvailability": null, + "DoctorID": 226098, + "DoctorImageURL": "https://hmgwebservices.com/Images/SZR/226098.gif", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "25.154501", + "Longitude": "55.226000", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/JOR.png", + "NationalityID": "JOR", + "NationalityName": "Jordanian", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 5500, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 865.2, + "ProjectNameBottom": "Sheikh Zayed Road Center", + "ProjectNameTop": "Dubai", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "505005", + "Speciality": [ + "Specialist Internal Medicine" + ], + "SpecialityN": [ + "أخصائي أمراض باطنية" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 290602, + "Name": "FATEMEH AGHANASIRI", + "ProjectID": 3, + "ProjectName": "Dubai Sheikh Zayed Road Center", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.94, + "DoctorAvailability": null, + "DoctorID": 290602, + "DoctorImageURL": "https://hmgwebservices.com/Images/SZR/290602.gif", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "25.154501", + "Longitude": "55.226000", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/CAN.png", + "NationalityID": "CAN", + "NationalityName": "Canadian", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 1252, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 865.2, + "ProjectNameBottom": "Sheikh Zayed Road Center", + "ProjectNameTop": "Dubai", + "QR": "data:image/png;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCABkAGQDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3+iiuf8XeLrPwdp1reXlnfXn2q7SzhhsYhJI0jBioClhnO0jjnJHFAHQUV5//AMLT/wCpC8c/+Cf/AOzrQ0r4j6Pqnh691f7NfWf2W7ksfsV3GkdzNcKgbyY03HdIc4C5ySCMUAdhRXBv8WdBtbe0fVLTUtJnur1LRbTUo0gnRWH/AB8MjPkQA5Bf1BGOK7CDVtNuriK3t9QtJp5bcXUcccyszwk4EgAOShP8XSgC5RXF658TtB0DWbawuI7uaCW4W1k1GAI1pbTFiDHLIXAR1A3MvULzVPT/AIweG9U1HXbOzhvpf7GtLi8mmVY2jmjhIDGJg53ZyCucAjuKAPQKK8r0n4+eFdZ1mx0u30/WVnvbiO3jaSGIKGdgoJxITjJ9DWpJ8WLP+0dQs7Pwr4r1D7BdyWc01jpwlj8xDhgGD/Q84OCOKAPQKK8/j+LFn/aOn2d54V8V6f8Ab7uOzhmvtOEUfmOcKCxf6njJwDxXoFABRRRQAV5/8U/+ZK/7Gux/9nr0CvP/AIuf2P8A8I9pX9r/ANuf8hWH7H/Ymz7T9o2SbNu78cY5ztxQB5h/xcf/AIXJ/wAzX/Yn/CQf9PH2b7P9o/758vZ+GParmoJpsnhXxKl/e3djO3j26Gn3cEqxLBdbD5byueViU5LFfmGMit+DQdNk1mLS7jxt8Q7GdtHGsyNeaqsSwQ7tpWTIyrqeoxgYPNZE/h+HUNGl0Tw/b6k0FlrB1+41fxWgNheqi7GImQYkRwVfkDcu45oA5+9gm8CXGm6z4wik8Wz3bxIb2dTf2AsHJbETybT9oyjMozt2vnuaw7XxJ4kh+Ic/9lRz2X/CQxNp+k/2iskf2Wznl/cmHafkVeNpTKjBwDXUWvijw3qmoz6Hrl95uiaNu1hkMsbRzXkJ2G1tA5KtaFCfLjwGI7gVl6lqmpSaMus2XhHWWnstd/tfTb2601jBBpiKWigDg5WJThtikIBkg0AbGppqUdx4X8N6ze+Cr6BfEdoLyDTJWlu55smN3uVbhiwyHJGSxGa6e21qHRrjxFYP8N47Gdri5srXUYtDEVgbXOEe6kyD5WRucj5doyBXCa//AMU54N0vxRef2G/inUvEEXiGGOHmRbeSMyKrA4cR+YDkAkZ/izXYXniKzvvD3hKKDxR9vvtc8QWdxqlh/aAl8uOZP3tt5YORbgnb5bZAzg5oA4fwFrd5D8QzpFn4W8Oapv1vz5r2108z/ZYzKqs8Dg/JCvBUkYGQe9dBq/8Awkn/AAhvin/hF/7V+3f8J1d7/wCzPM8zy/LOc+Xztzt9s4rY87wf4O8Q+R/YvivQ/M8Qb/7V+yw21s2Xx5HncZtDt3bPRc9qz4ZPDd94h1eXSNS+I9vYz6rM15f6ZPGmmxyM/wA8pkXgRgENuPITBNAFfSP+Ek/4Q3wt/wAJR/av27/hOrTZ/afmeZ5fljGPM5253e2c19D14Z4ftvCuv+KoEfxP41u4NL1NTa3eq38Ulhc3UTjYkb8h3YHIAwxUkjFe50AFFFFABXF/EbXIdAt/DlxcWumzQS67bQySX8YZbZSHJlUkgI6gcN25rtK8r+PEEN14V0G3uIruaCXXbdJI7NQ07qUlBEYPBcjoPXFAEmlX+j6p8Q73UdXu7G8+1Wkml2dzaSJJps1u0oZLaRmzuuzkkxjgoRgUf8Sf/kXv+Kr/AORg/wCQb8n/AB7/AHP9V/0DP4emO1c5pOueCfBlvY+D9GtbvUdU1C4jvbMapHDMthfyARIk+0honRlG4AFlycHtWPqyalo3iq+8V3F74gbVLK3kEljHKxYzI5kLiM4b+ydw25yD2oAufEv4faxNp1x5WneBtLsUu2ex+wwPBe3WA/lwD5cPIw/gXqwGOlGjeJP7F05PA8seua/Y3vh8PfRWK/ar3T7hwIpIAMgRRxgY2MpKswz1xUmh6Zr3jDRrm/t/F2jaj4i1B2uo9On1J5oNLhkUESRRgF4biN22q3IQHHWsO1v7zWvP8IWd3pWgeNrLUGgm1mGQ2v8AaEafu2RpxmWWaSUhyCAG256jFABpWoeD4dRvYtO8PeMvEmt2enyWdvYa3ZQ3kdrsI2ho1O5FV8KcdAzDGTXV6xqnhXT7fR/D7+EbTTPGGt6ZA9rcWumxQrZXUwKIS2fMjKSjOQCy4GMmmXWheMPhXp0GoeHNKsdfvr3b/aNzNbzXV6bhxul2sgU/Z8xqRuydzc9a5vxreabpOjQ+K01iPUfGGoItvdWN7crM2kNIrSOYI+JIHilG1ck7MkHmgDr/AIleCvG2v+BdM0tJ9Nu4NLsori6Znmku7m6iidXCfKQ4YHjIDFjzisT4cf2x/wAI9ceHvCH9h/xf2vpviff9p+0bESbbFH/y7/dUbxnO4HtVzwLrWvSeFbXRLjxFHcz6vcJJJq8967rBDKiobWKYnK3yn51jwQM55ri/DWleJLH4h+KoNDv4Lfz5bvSF1bWZpE8yRpQAqTIObk4DAdTycUAdpr3hTUvCVx4Qt0Gmrpd74osr26jh3Bor9yQ6QjAUW4VflByw7mvc68QbxRZ6pqPhjQ9cvvN/sbVbWxZIZQ17NqsJ2GZg5O60OTl8By3YV7fQAUUUUAFef/FzVf7L8PaV/oH2z7VqsNr+6h8y5h3JJ+8tuRtuBj5G7E16BXF/Ep9NtdG0zVNUstZu4NL1OK/VdKiV2Roldt0m7gRAZycjqORQBwmheDdH0v4h6Z/ZEN9ea3dWkWr3n/CTqknk27Sjey7VDLdhwME8DLZOanv9KvNU8ZXPkX8FnY2uoNdap/b8xjvZrNZD5scWAQ2nEH5Vb5SwbNZniC8h+KFvP4r8B6xqWneItPt2t5bFrkQzzWsYMhKRxbnYl3RRkhSRjripNE1Wz/4Q3xJpGo2HiP8A4Sn/AIRq6uri91+EeZ5flhWjidjv8nzMlVIxncetAF+//wCEb+HOo3P9neRPY+JIm+z/ANj+W2rJJcE7fs+3aBbAINmMnfjrXAaBqH9l+IdU8Oan4enivtZllbRdT1ay26lDcTOEgleViCqggsWQEh8kZrY8OeHPGFx8PJNR06Twrrnl2he3uXaa51KxxEGWCFlH7uROCqD7rt710ep6xqWn6N4X8SHQ9G16DTre0t9YnktGutUspo1Mk5LZxGUAz85BV2560AdRrk/irQPCttYXEsc0Eujrp8mowNK09tflCDdSyHAS3UDc0n3gecVz/i0aD4K8C+GdZvdA8P6zPcXFrDqV61mlw10rRM0sqOcF3YqWDMec5PWsjVrrTbq4vvE1v8RJJtLl0yTUI9BvNaVme6JMgtZLcfKYCvyGPO7qua5/xb4r02Twr4Z0bSzJrWqXF7a6y1k224tIGZGX7CiKdyorYUQ44U4zzQBsT+MYdT+Gktxo2jeH9JguvFB0+zkktRAtorQ5S6JVsRzoCP3g6Y4HFR+EfFV5ffatB1zQYLjRIJXhbxFo1mX8u8XahvnuXO0MEJkM2Nw4bpW3rnhrTdA+Edtf3GialNPLerrsmnQWqtBbXRgJMcsZAKWqkbWX7wHGa4j4Oalr2s+OtQsrBdNXS71JLjUNLnDi0ELyxiQRRAld+0hV3ZG3g0AdAPDGmx+OtE8SX+o6bfaWupwabp8+gzrLPPdeb5kct6xG1nZcmRlO4krgV9B15H4t0nwro3jrwzbvp/iCxga9tXtY9Khii0s3XmsEMgwB5uByR82wDFeuUAFFFFABXF/E55o/CqPb2Ws3063AMdppkRlWdtj4S5QctbseHHfIFdpXn/xYkvP7O8NWdnqV9p/2/wAQWtnNNYzmKTy3DhgGH4HnIyBxQBxmseEJrq40fVNE0zWfDuqDR4LvVV0W3NpA8OS01vFtXcbotjajHGFGTxRZ+IodGuNKsE8N+J7mfV9Th0661HxjYh2NrKcPAkmQcZG4Icry5INZf9r+G/8AhMv+EX/4S/4nfbv7Q/s/zP7Sj8vzPM8vOc52574zjtVyW2huvhp4rTW/E+pCfQfEd4dKu7q/HnvNBD+5QO3JJOThcHOSMUAbdzJ4bm/4SDU/C+pX2i33hj7Sz6HaTx21tdSW3zGWSCPl42O1C2VJCgcYriL/AFn7D4NudD1d9VGt+K5W1+zTQD+7k+1RlEglDHcVLg7kAbI24JNdJ4EGpah4F1zWfEmgabY6W2j3EM97a2bRaper5Ss0pd/lkDqWbcT8zgGuLj1/R/8AiXy6VpHiPULGwljOk399bJLc/wBop/qbMyKcfZsYbykw+SSKAJNYimtfAujong3TbvVNLuILu6u9P0wvAkMUR3296/3hOG5lQ4GCCcVz/hTUptP1keK7dfCKz3up/ZI7G/BC2TOyyC4WMHMcSEbQ+Tt5GK97h+x+DvhZq+r6j5EV9rMU2p3FlqeFja8mg3NbhGwSpKkbCS2MjJriLrV/Del+DYJfGngSxi/tm0WW2v8Aw9pEaxwxzR/IvmSkbbgYdsDIA2nnmgDXtfFGseDvPi8aX2leI7HX5WltrDSZXvLlvP8AuKkcpANsQrqAM8sBzk1maHqmm2viq5uL/wAI+IPDM+sO2hafJYaatlAkMzgxyMSci4BzllyMKMA4rLa68N/8Ib4Y1zQ7fXNQ+weK7W2V9RSOW98tI94t4Sn/ACz6bUyBuJqx4q8SWeu6jovhfy/GWn31/wCJYNQ8zV1EUlvG5aPFuckoqk/IMEAg80AdfYaB52o21nq+r6qmiabray2c2v3OL261GMgIsTMNr2zJkqBhy27HFesV4hNp95N8ZNI0Pxf4h2WOm2kN5pCJekfapI7jZCZhIMPcMN27YAT2PWvb6ACiiigArz/4sR3n9neGryz02+1D7B4gtbyaGxgMsnloHLEKPwHOBkjmvQKKAPnj+yPDf/CZf8JR/wAIh8Tvt39of2h5f9mx+X5nmeZjGM7c9s5x3q4YtSk8C629x4N1K5g1fxbPLJaT6Yz3cFrLFzNEh4WVRwr8qGOOa97ooA8f8R+B9Y/4U3Hp3hfVNc7Xj22p3D/afs/2cqbQLGv+6PK6ZzzWZ4Fi8bR+FbV7jwb4fttL0i4SWS0n0yZL+dokXM0SH5WnZeFfjLDHFe50UAeN3mk6lJ4q1W/fT9Z1rS7jw5Nq9rp2uwtcQQX7PlIFjxtV1X5Qg+YAsAeaqWvjbWL7wbPp3iP4W31xfQbv7OtofD7vZR7Y9sW5XbIwSwO3ovSvb6KAPmzxF4a+INrb6B4mt9E02GCK4t7qPQdEtbhVSYAyCSa3AwHA+Rmzn7q10l0154x8Gwa5408J65Z63a6qsVs/h7TjHerGse9GzLlhGHZ+QcbgvfNe30UAeP6voWj33jLwXqN5pXjm4voLSx8m5Fujxx7ZCy/a2IyJASTJjoK9goooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigD/9k=", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "505005", + "Speciality": [ + "General Practitioner" + ], + "SpecialityN": [ + "طبيب عام" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 294042, + "Name": "TAMAMA ALMUTAIR", + "ProjectID": 3, + "ProjectName": "Dubai Sheikh Zayed Road Center", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.89, + "DoctorAvailability": null, + "DoctorID": 294042, + "DoctorImageURL": "https://hmgwebservices.com/Images/SZR/294042.gif", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "25.154501", + "Longitude": "55.226000", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/NLD.png", + "NationalityID": "NLD", + "NationalityName": "Dutch (Netherlands)", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 1101, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 865.2, + "ProjectNameBottom": "Sheikh Zayed Road Center", + "ProjectNameTop": "Dubai", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "505005", + "Speciality": [ + "Consultant Family Medicine" + ], + "SpecialityN": [ + "استشاري طب الأسرة\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 392403, + "Name": "OMAR IBRAHIM", + "ProjectID": 3, + "ProjectName": "Dubai Sheikh Zayed Road Center", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.94, + "DoctorAvailability": null, + "DoctorID": 392403, + "DoctorImageURL": "https://hmgwebservices.com/Images/SZR/392403.gif", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "25.154501", + "Longitude": "55.226000", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/LBN.png", + "NationalityID": "LBN", + "NationalityName": "Lebanese", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 866, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 865.2, + "ProjectNameBottom": "Sheikh Zayed Road Center", + "ProjectNameTop": "Dubai", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "505005", + "Speciality": [ + "General Practitioner" + ], + "SpecialityN": [ + "طبيب عام" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 398856, + "Name": "MOHAMMED NORAIN", + "ProjectID": 3, + "ProjectName": "Dubai Sheikh Zayed Road Center", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.84, + "DoctorAvailability": null, + "DoctorID": 398856, + "DoctorImageURL": "https://hmgwebservices.com/Images/SZR/398856.gif", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "25.154501", + "Longitude": "55.226000", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SDN.png", + "NationalityID": "SDN", + "NationalityName": "Sudanese", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 40, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 865.2, + "ProjectNameBottom": "Sheikh Zayed Road Center", + "ProjectNameTop": "Dubai", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "505005", + "Speciality": [ + "Specialist Family Medicine" + ], + "SpecialityN": [ + "اخصائي طب الاسرة " + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 417558, + "Name": "DIALA AREF MEHANNA", + "ProjectID": 3, + "ProjectName": "Dubai Sheikh Zayed Road Center", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.85, + "DoctorAvailability": null, + "DoctorID": 417558, + "DoctorImageURL": "https://hmgwebservices.com/Images/SZR/417558.gif", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "25.154501", + "Longitude": "55.226000", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/LBN.png", + "NationalityID": "LBN", + "NationalityName": "Lebanese", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 39, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 865.2, + "ProjectNameBottom": "Sheikh Zayed Road Center", + "ProjectNameTop": "Dubai", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "505005", + "Speciality": [ + "Specialist Family Medicine", + "Specialist Internal Medicine", + "Specialist Internal Medicine" + ], + "SpecialityN": [ + "اخصائي طب الاسرة ", + "أخصائي أمراض باطنية", + "أخصائي أمراض باطنية" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 400703, + "Name": "SHAHAD ALNAQBI", + "ProjectID": 3, + "ProjectName": "Dubai Sheikh Zayed Road Center", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 5, + "DoctorAvailability": null, + "DoctorID": 400703, + "DoctorImageURL": "https://hmgwebservices.com/Images/SZR/400703.gif", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "25.154501", + "Longitude": "55.226000", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/ARE.png", + "NationalityID": "ARE", + "NationalityName": "Emirati", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 5, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 865.2, + "ProjectNameBottom": "Sheikh Zayed Road Center", + "ProjectNameTop": "Dubai", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "505005", + "Speciality": [ + "Consultant Family Medicine" + ], + "SpecialityN": [ + "استشاري طب الأسرة\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 417926, + "Name": "RAVI TEJA TANGIRALA", + "ProjectID": 3, + "ProjectName": "Dubai Sheikh Zayed Road Center", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 5, + "DoctorAvailability": null, + "DoctorID": 417926, + "DoctorImageURL": "https://hmgwebservices.com/Images/SZR/417926.gif", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "25.154501", + "Longitude": "55.226000", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/IND.png", + "NationalityID": "IND", + "NationalityName": "Indian", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 3, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 865.2, + "ProjectNameBottom": "Sheikh Zayed Road Center", + "ProjectNameTop": "Dubai", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "505005", + "Speciality": [ + "General Practitioner" + ], + "SpecialityN": [ + "طبيب عام" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 172036, + "Name": "ABEER ELMOHANDES", + "ProjectID": 2, + "ProjectName": "Dubai Hospital Medical City", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.77, + "DoctorAvailability": null, + "DoctorID": 172036, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/172036.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": true, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "25.231273", + "Longitude": "55.320942", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/USA.png", + "NationalityID": "USA", + "NationalityName": "American", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 7351, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 875, + "ProjectNameBottom": "Hospital Medical City", + "ProjectNameTop": "Dubai", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "505005", + "Speciality": [ + "Consultant Family Medicine" + ], + "SpecialityN": [ + "استشاري طب الأسرة\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 120423, + "Name": "FIRAS ALI AL RUBAIY", + "ProjectID": 2, + "ProjectName": "Dubai Hospital Medical City", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.81, + "DoctorAvailability": null, + "DoctorID": 120423, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/120423.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "25.231273", + "Longitude": "55.320942", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/SWE.png", + "NationalityID": "SWE", + "NationalityName": "Swedish", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 6409, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 875, + "ProjectNameBottom": "Hospital Medical City", + "ProjectNameTop": "Dubai", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "505005", + "Speciality": [ + "Consultant Family Medicine" + ], + "SpecialityN": [ + "استشاري طب الأسرة\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 10008, + "Name": "FIRAS BASSAM AMAWI", + "ProjectID": 2, + "ProjectName": "Dubai Hospital Medical City", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.66, + "DoctorAvailability": null, + "DoctorID": 10008, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/10008.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": true, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "25.231273", + "Longitude": "55.320942", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/USA.png", + "NationalityID": "USA", + "NationalityName": "American", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 5429, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 875, + "ProjectNameBottom": "Hospital Medical City", + "ProjectNameTop": "Dubai", + "QR": "data:image/png;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCABkAGQDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3+iiuf8XeLrPwdp1reXlnfXn2q7SzhhsYhJI0jBioClhnO0jjnJHFAHQUV5//AMLT/wCpC8c/+Cf/AOzqOf4x6Da+FZfEFxpmswwRamdLkt5IEWdJgm85UvgADjrnPagD0SiuTf4gabJ4VtPEGl2OpazBcOiNb6VCtxPAzJvxIqthSowCM8Ej1q5H4us/7R0+zvLO+0/7faR3EM19EIo/Mc4W2LFv+PjqfLGTgGgDoKK5+18ZaPfeMp/C9nN9ovoLRrqaSFkeOPbJ5bRsQ2RICRlSOBVi68SWdj4hg0i8jnt/PiV4b2ZQltJIz7VgVyeZjgkIBkjmgDYorn9K8Vf2p4hvdI/sHXLP7L5n+m3dn5dtNtcL+7fJ3ZzkccgE1z8nxYs/7R1Czs/CvivUPsF3JZzTWOnCWPzEOGAYP9Dzg4I4oA9Aorz+P4sWf9o6fZ3nhXxXp/2+7js4Zr7ThFH5jnCgsX+p4ycA8V6BQAUUUUAFef8AxT/5kr/sa7H/ANnr0CvP/i5/Y/8Awj2lf2v/AG5/yFYfsf8AYmz7T9o2SbNu78cY5ztxQB5h/wAXH/4XJ/zNf9if8JB/08fZvs/2j/vny9n4Y9q1Doc2v6Nrdvb3WjQzxfEKeaOPV5CsFywXAhwAS5Yn7vcZq/4n0zTfCXhWw8Qap4u+JSwXrxotuupKJ4mdC+HVgACApBGTg1Jo2leG5vh4moxX+q6Xs1savY3PimaOD7VeCINGzNj54W6kr8xw2DxQBka/o158OdR0u80xPFf/AB9xarrUOkg/2SkeSZ0RVC4xsAAfjZjJqnPPr3xQ8VS3GrS6l4d0sW5fw5JIz2kE11vzakltytKVc8x/MQvy9K3NQ137dqOheF9M1W+1++vdVt9T1qSxuPtVlHbuTHPbgqci3BI+RwQFYZPNU9WTUtPuL6yF7aa9Bp2sSalo+l6JK11d2U0ZIgimi6R2qAbWVMFWZQDzQBj+GNMh0bxVf+GfEni7TbGdkk1CfXtK1IRXZm3iNrWS4cA4yGcxkZ3ANmuz1vxd4bm/4RvTNXs/FaWOm6ratZ65cRRi2upI8qkrzs2HjYZcsACRyKkn+G+m3XgWXxBcaTJN4ilc+IJLeS2Vme6MW82hUrvMBfjys7vfNcZNrf8Abvh7SNOg8LeK9Q+weIIbzVLZ9P8ANtrfYm2W0hUE7I1zhYmxgHk0AangTxXr0nxc1y4c+INZ8O3F7cWVrJa77i0gZp1KOTnYqKncdFIwMGqer/8ACSf8Ib4p/wCEX/tX7d/wnV3v/szzPM8vyznPl87c7fbOK6vw/eeCbXWYPDel6xqWkz3V6uvNAtzDAqTMwj/s91XkEHAMGM8deKj13wro+heIdT/4n3jnT/t/m6n/AMS+8SK2uLh3P+jxcDfcNj5U5JAHNAHMaR/wkn/CG+Fv+Eo/tX7d/wAJ1abP7T8zzPL8sYx5nO3O72zmvoevnjQr/wAN674y0zTvtfxO1C+sNQin+zahJHLHbyJIF3yryUVScMeCATX0PQAUUUUAFcP8UfDl54j8PWP2OSdP7N1CPUJvsrEXLRxo+4QYBzNyNoOBnHNdxXB/FnVtN0bwra3Gqah4gsYGvURZNCmWKctsc4YsQNmAcj1C0AcnrOv6x/wjz6HeaRpWoX1hp51yFNetnl/4lyIUXzgTn7bnO7ACctzXnnjFIdZ8C6TdW974gXVL29hEfh+7lAgCvExD2duMt5G4+XGeeMrXceBNSm0zRtc8SeK1jm8OypcRWU+ugtql3CVWSOFWkOySJ0DEIpwX3Y4qnqvirR9L8PWWr+HtB+2a3darH/Z9l4is0kuYbdkLRfZEQhltw4UR7TgEsBzQBjt4C1j4c/8ACMeNNMOq/YfKtZdatYS/2lP+Ws6siqoEICAEO3Xg+tbkGm6l4SuIvHmjNaSap4w1gW9nDeFjBFa3Z85DIFAYShlAOGZQM4z1qvB4lh+KHjqLRtZ1vWfDsA0cWt5ZR3QtFmv/ADdrxhGLBgQ5XaRuO3B6Vnz2UNrrMo0bVPE+tweHLgw2eiyXAuZ0v7dvkmMC8CzAwm4YbLYGM0AdP4v1abT/AArqNgmoeLr7VFeTULrUdCmMtpZXWxg9q0md0cCMNxjPzKpUk15p8ONZ1ix1G41zUX8ZXGiQSteXD6QXeOS4Uo7G4LHaVKA78nJGOcV1C2viT+zvE+h65cf2f9v0q68XsmnPJFJ5jjYbeYP/AMs+u6PBOQPmrn7DRP7L+HltPB4pvrz7VdrPqmk6BqHmeTpzRAyvLCANsgxtYt8gyoNAGxpV/wCG/C3jK98f6vd6Vq9jqssk9np9pJHcXtnJLIJkeSNsCNkClSQxKsQBnOa6jxHf6P8AEby9Qnu/FfhjybQT6Xc6nIllpr3Ay0ThjuzId+crzsU46Vzfw/8ADHw+k1m80u/1GO5n1eyc6e0k9u6wQysqxocjK3ynPCggZ4zWxO+pR3Eul39laW0GkOdN09vFcTJo89rEdscozw14wz8ygKYw2AKAK/gXUpo9ZtdUsF02+8RLqaaDqC2AMqz2G5Wk1BsHezs+MzsdpyMjNfQdeIfDjxV/xUNx/wASHwr/AMfbaZ/xTFn/AKT99P8ASG5/49PV/XbxXt9ABRRRQAVy/wAQbXR77wbf2er3GlW/nxSRWc2puiRx3DRuEYM3RhknI5Aziuorm/HUGg3XhW6t/EEUc0EqOlvGFRp3mKMFFuH4M5G7YBzmgDh/AusQ6ho1r4U8b6HaNBZOlvpl9PaA2F6qKscRiklOJJXBdl2gbl5HeuYvYIbr4uab4ft4o9Og0/U4tQjuNeUQzusc5QWtkw4NuRzHHgchuaj1u/8AEn9o+G/C8934c0ix0qK11rS5NYkkt5PLiJjiiuCePOx99VAGQcEYrs9HfTbrRtY1R7KPVvGFqk9/arqESzs7KoZGsv8AlobMy/6og9zg5NAHAfE7SYbXx0lxcafdw6pFcDUZJPDkIVU0wSuTPISNwug3V/ufd5qnarZ6p4ynli8WWOh+Z4faWxv7PURbSTSGT92t/JzuuDndKF5JUEdK2L/xp9u8ZXN54h8M+I7fz/B7WOoQ29hskj3SEyzIrtxCMsA7dD1FcP408L3n9o+HpYrGx0/RL+0torG/ERij8ty3ltdyY2/aNnzSFcjAyOKAPX9GuvEmqacmmWdv4V1zW47QW02uMklzZTWYAVreWcZZrguQ7IRtKtnqa5TWBpsfjrR7e10DUtG1S3eCHXo7WzW30uewWUi4lIHzNAzfxP8AKUA3dK1LWT/hDvh5P4c8F6lBeX11E1xc6mZ/MtmuGi2PbWksWCbklUaOMjODn0rl7DUPHl94htpfEPh6+t7GfSl0DUL+4sp08uzZx5s7yOcCQAsxdvlHUigDoJPCNn4O1HUPEelXnhW81u6u5LzSdMuZRJG1mx3wm3iVQxuC6hU2HbgkA5q54U03XvFtuH+I7R2Oltrv2u0tL8vFPLdYXZbqkwKm3KtIAg+YkEDvUd1p+j/uLyLxD4c1C+sIl0qxhtb1Jbn+zk5jeBcZ/tHPClcJkjArbgSHxb4FiTxve6l4ag0zWANMu7yUWd3KscX7p5HlyDKQzklcZZSR0NAGR4O8bw2vxc1bw/b+DNNhgiuJrKO40TSws6KJ1QPMwbAiA5Y467eK9zr50+FXieHRviXrWiW+nSazBcXs4j1eCAXF2VaZEDyzAgeRgb2OPvHPevougAooooAK5/xdqFnpenWt5eeHr7XPLu0aGGxshcyQyAMVlCkjbjBG4cgsPWugrz/4sSXn9neGrOz1K+0/7f4gtbOaaxnMUnluHDAMPwPORkDigDD8QaLD4n8dT6pqnh3UptLl8GMVVrINPFMZS2xNwKrcBWOBnINYHh+CaPWYLCyi8QaLBb26tpuo+JVNvPPdKwEVgZBw1qww3kL8xIYjpVP+1/Df/CZf8Iv/AMJf8Tvt39of2f5n9pR+X5nmeXnOc7c98Zx2rUstS17T/CupJbrHr0+neM5bSO718PdLZQxoMXDuDmMIRkvwF3Me9AEnhXwr/aniHWtX8ca9fWet2t3P5tl9s8u2m05XVj8koLNaFy45OwgY65qv4u/4SSHxDazxf8IbqmiPEkNjpLeZPbWtmXYx30sP3UVU+Vpl+UA4HBrz/wCy+MPEfxT+x6jcaq/9pS+VcTae8xjbTpJ8M0TNnNtySpOUxivSPFWgWdj4h0W807V/tFjBaQeFbeGC5D+ZeK7FYr1VGDbkACRR8x/u0AY8n2zRfh5qGnaH/wAI5r+t3utyXy22g5uv7PjeLaJoVTDRNG4AVuQu5ecmsfTLnWL7UdGnXxLrlxYwXcFr4i0nVr53kj2kG5keHoLQA7S0nQ5DVJeeFPG2jazqvh/Sxo1jqjW83iBrjRfOinMO7Z9kiZQG2bgCsWMZA5q5o2jWeqacl54tTXND1uTGnXcOlgW0k1mQC97eLICzRlywkmPykqMjINABdeF7z4c+MoPGkVjoer6JquqrFY2trEbiRI5ZPNjaBMKokCJhSrEZIAyDmjStfvIfiHe3nj/SNcfwtqV3JFYQ63bE21rJJKDGzLMdibY94JXJA3Y4zW58TDoPhi38C39vr93dwaXcWBj06O8SRZbWIORcCMYDOQu3zOFOccVj3vjXQfGtxpul2EHiC+gXxHFrOoNq6JLBa2uSsi8MQkChhww2gE5NAHZ/CfQryx8Q+JdRi0rSrfRJ9QuvsNytuUuZI2dGj8psbTbFBldvBPTivWK4fwPqviTVNR1Hz7DSrPwtayy2ul/Z4ZI5Jo1K+VImSUaExnhl4JHHFdxQAUUUUAFef/FiO8/s7w1eWem32ofYPEFreTQ2MBlk8tA5YhR+A5wMkc16BRQB88f2R4b/AOEy/wCEo/4RD4nfbv7Q/tDy/wCzY/L8zzPMxjGdue2c471t6Pc+KrXwrrD6X4YkM+veLZw1prVhLtS1nQfPKi8hAcBjyvUc17ZRQB82WWk6la6zqVx4g0/4hw6pFcS2tvJ4XhZbRLUMCscJcbhEG3bVHy7dtd3f+Dbz+zrnV9Ohn+w/8I00lvZXCn7b/auCy3Toq4+04wDIDv3cV6xRQB4vqvhzx5qnwsstR8yCz8U2sUb/AGm0aeO9ms1gLeRI2C7TGQ5KfdLAd65weCtSk8VaImsz+PLmDV9CgivLuB2doJpX+eGV2XCwKMlkOSM5Oa+i6KAPL5PhpZ6Xp2oWd5bf25okelSLDNcxi51aGQDCxW7FQqxhASijkOx7GvIPCNl4k8HeMrq8s/BGuXmiXW+zmhvtKkkkazaRSwKjCmQooHPy5J4xX1fRQB4n8P8Axb4q0/xVeaXf+FPEC+Hb29c6e0mnShrJXdVjQ5OyOBEB4UHb24r2yiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAP/9k=", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "505005", + "Speciality": [ + "Consultant Family Medicine" + ], + "SpecialityN": [ + "استشاري طب الأسرة\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 205158, + "Name": "MAZEN NABA", + "ProjectID": 2, + "ProjectName": "Dubai Hospital Medical City", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.91, + "DoctorAvailability": null, + "DoctorID": 205158, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/205158.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "25.231273", + "Longitude": "55.320942", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/LBN.png", + "NationalityID": "LBN", + "NationalityName": "Lebanese", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 4644, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 875, + "ProjectNameBottom": "Hospital Medical City", + "ProjectNameTop": "Dubai", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "505005", + "Speciality": [ + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Mr.", + "ID": 311562, + "Name": "REEM ABDULLAH ALI MUSTAFA", + "ProjectID": 2, + "ProjectName": "Dubai Hospital Medical City", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.86, + "DoctorAvailability": null, + "DoctorID": 311562, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/311562.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "25.231273", + "Longitude": "55.320942", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/JOR.png", + "NationalityID": "JOR", + "NationalityName": "Jordanian", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 2069, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 875, + "ProjectNameBottom": "Hospital Medical City", + "ProjectNameTop": "Dubai", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "505005", + "Speciality": [ + "Consultant Internal Medicine" + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 157312, + "Name": "KARIM CHADDA", + "ProjectID": 2, + "ProjectName": "Dubai Hospital Medical City", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 5, + "DoctorAvailability": null, + "DoctorID": 157312, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/157312.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": true, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "25.231273", + "Longitude": "55.320942", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/FRA.png", + "NationalityID": "FRA", + "NationalityName": "French", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 1728, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 875, + "ProjectNameBottom": "Hospital Medical City", + "ProjectNameTop": "Dubai", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "505005", + "Speciality": [ + "Consultant Internal Medicine", + "Miscellaneous " + ], + "SpecialityN": [ + "استشاري طب الباطنية\r\n", + "متنوع\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 339102, + "Name": "WASAN SULAIMAN", + "ProjectID": 2, + "ProjectName": "Dubai Hospital Medical City", + "ActualDoctorRate": 5, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.85, + "DoctorAvailability": null, + "DoctorID": 339102, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/339102.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 5, + "Gender": 2, + "GenderDescription": "Female", + "IsActive": true, + "IsAllowWaitList": true, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "25.231273", + "Longitude": "55.320942", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/CAN.png", + "NationalityID": "CAN", + "NationalityName": "Canadian", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 904, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 875, + "ProjectNameBottom": "Hospital Medical City", + "ProjectNameTop": "Dubai", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "505005", + "Speciality": [ + "Consultant Family Medicine" + ], + "SpecialityN": [ + "استشاري طب الأسرة\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + }, + { + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "ClinicNameN": "الباطنية\r\n", + "DoctorTitle": "Dr.", + "ID": 395684, + "Name": "MESHAEL ALRUM", + "ProjectID": 2, + "ProjectName": "Dubai Hospital Medical City", + "ActualDoctorRate": 4, + "ClinicRoomNo": 0, + "Date": null, + "DayName": null, + "DecimalDoctorRate": 4.12, + "DoctorAvailability": null, + "DoctorID": 395684, + "DoctorImageURL": "https://hmgwebservices.com/Images/MobileImages/DUBAI/395684.png", + "DoctorMobileNumber": "", + "DoctorProfile": null, + "DoctorProfileInfo": null, + "DoctorRate": 0, + "DoctorStarsRate": 4.5, + "Gender": 1, + "GenderDescription": "Male", + "IsActive": true, + "IsAllowWaitList": false, + "IsAppointmentAllowed": true, + "IsDoctorAllowVedioCall": false, + "IsDoctorDummy": false, + "IsDoctorHasPrePostImages": false, + "IsLiveCare": false, + "Latitude": "25.231273", + "Longitude": "55.320942", + "NationalityFlagURL": "https://hmgwebservices.com/Images/flag/ARE.png", + "NationalityID": "ARE", + "NationalityName": "Emirati", + "NearestFreeSlot": null, + "NoOfFreeSlotsAvailable": 0, + "NoOfPatientsRate": 28, + "OriginalClinicID": null, + "PersonRate": 0, + "ProjectDistanceInKiloMeters": 875, + "ProjectNameBottom": "Hospital Medical City", + "ProjectNameTop": "Dubai", + "QR": "data:image/png;base64,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", + "QRString": null, + "RateNumber": 0, + "ServiceID": null, + "SetupID": "505005", + "Speciality": [ + "Consultant Family Medicine" + ], + "SpecialityN": [ + "استشاري طب الأسرة\r\n" + ], + "TransactionType": 0, + "WorkingHours": null, + "vida3Id": null + } + ], + "DoctorPrePostImagesList": null, + "DoctorProfileList": null, + "DoctorRate": 0, + "DoctorRatingDetailsList": null, + "DoctorScheduleAvailabilty": null, + "DoctorScheduleMapping_Insert": 0, + "DoctorSchedulesByClinicList": null, + "Doctorscheduleslot_Insert": 0, + "Doctorscheduleslot_SelectList": null, + "DrIncludeExclude": 0, + "ERAppointmentFeesObject": null, + "ER_AdvancePaymentResponse": null, + "ER_OnlinePaymentDetailsResponse": null, + "ER_PatientShare": null, + "ER_TriageQuestionsList": null, + "ErrCode": null, + "ErrorSearchMsg": null, + "FormID": 0, + "FreeSlots_NearestWithDoctorsNameList": null, + "FreeTimeSlots": null, + "GenderError": false, + "GetDoctorFreeSlots_Nearest_OnSlotSelecionList": null, + "GetDoctorMobileNo": null, + "GetPatientInfoByPatientIDList": null, + "GetPatientMedicalStatus": null, + "GetQuestionsRating_PAList": null, + "HIS_GetAllAppoimentHistoryList": null, + "HIS_GetDoctorOffDaysList": null, + "HIS_ObgyneUltrasoundDoctorsList": null, + "HIS_ProcedureTemplateDetailsList": null, + "HIS_ProcedureTemplateList": null, + "HIS_Waiting_CheckDoctorAvailableForWaitingAppointment_List": null, + "His_ObGyneProcedureGet_Response": null, + "His_PRM_GetApprovalRemarkList": null, + "HoursDiff": 0, + "ISDentalplan": false, + "ISMobileAppDentalAllow": false, + "InitialSlotDuration": 0, + "IsAllowToBookWaitingAppointment": false, + "IsAllowVClinic": false, + "IsAllowWaitList": false, + "IsAppointmentAllowed": false, + "IsCash": false, + "IsClinicEnabledForICDCodes": false, + "IsDoctorExist": false, + "IsDrBlocked": false, + "IsEligible": false, + "IsInsertOrUpdate": 0, + "IsInsured": false, + "IsLastAppoitmentRatedList": null, + "IsShowInsuranceUpdateModule": false, + "IsSlotAvailable": 0, + "LC_GetClinicScheduleList": null, + "ListHoursDiff": null, + "ListReqTypes": null, + "List_AllClinicRate": null, + "List_AllDoctorRate": null, + "List_AllProjectRate": null, + "List_COVID19_DoctorsByClinicAndProject": null, + "List_COVID19_ProjectDriveThroughTestingCenter": null, + "List_CalculationTable": null, + "List_DDAdmin_Members": null, + "List_DentalChiefComplain": [], + "List_DentalDDDetails": null, + "List_DentalDoctorChiefComplaintMapping": null, + "List_DentalPediatricDoctor": null, + "List_DoctorAll": null, + "List_DoctorByIPAddressCheckIn": null, + "List_DoctorByProjectClinicAr": null, + "List_DoctorByProjectClinicEn": null, + "List_DoctorCases": null, + "List_DoctorClinics": null, + "List_DoctorDetailsList": null, + "List_DoctorDetailsListAr": null, + "List_DoctorLanguages": null, + "List_DoctorMappinsgs": null, + "List_DoctorPatientVitalSign": null, + "List_DoctorProcedureMapping": null, + "List_DoctorProfileImage": null, + "List_DoctorProject": null, + "List_DoctorQualifications": null, + "List_DoctorSlotFirstVisit": null, + "List_DoctorSpeciality": null, + "List_DoctorSpecializations": null, + "List_DoctorWorkingHoursTable": null, + "List_DoctorblacklistModel": null, + "List_Doctorinfo": null, + "List_English": null, + "List_GetAllCancelAppointmentReasons": null, + "List_GetAllClinicsRoomNo": null, + "List_GetAllDoctorsOnProject": null, + "List_GetAllDoctorsbyProject": null, + "List_GetAppForCancel": null, + "List_GetClinicsInfobyProject": null, + "List_GetClinicsbyProject": null, + "List_GetDoctorsbyProject": null, + "List_GetIPAddressForDD": null, + "List_GetIPAddressForDentalDD": null, + "List_GetInfoForDentalClinicsDD": null, + "List_GetLoginDetails": null, + "List_GetPatientCancelAppointment": null, + "List_HISDoctorProject": null, + "List_HIS_GetContactLensPerscription": null, + "List_HIS_GetGlassPerscription": null, + "List_HmgPartTimeDoctor": null, + "List_InvoiceDetails": null, + "List_IsPatientHasOnGoingEstimation": [], + "List_LaserDoctors": null, + "List_LaserProcedures": null, + "List_MedicalReportByAppointment": null, + "List_NonAdminProjectMapping": null, + "List_PatientER_AdminServiceModel": null, + "List_PatientER_DoctorBlackListModel": null, + "List_PhysioDoctors": null, + "List_ProjectERPMapping": null, + "List_RecordByIPAddress": null, + "List_RecordByIPAddressNew": null, + "List_RecordByIPAddressNewCheckIn": null, + "List_RecordByIPAddressNewForDubai": null, + "List_RescahdualOnlineModel": null, + "Message": null, + "NotesDoctorRatingForCOC_List": null, + "NotesDoctorRatingList": null, + "OnlineCheckInAppointments": null, + "OnlineCheckInAppointmentsWalkInModel": null, + "OnlineCheckinBeforeHour": 0, + "PRM_AdmissionInfoList": null, + "PRM_DentalEstimationDetailList": null, + "PRM_DentalEstimationList": null, + "PRM_DoctorsForRadiologyList": null, + "PRM_GET_ERToOPDRequestStatusList": null, + "PRM_GetDoctorRatingList": null, + "PRM_GetProceureAndPackagesList": null, + "PRM_HIS_AppointmentqueuegetList": null, + "PRM_HIS_CheckDoctorIsFullyBookedList": null, + "PRM_HIS_GetDentalEstimationPlan_List": null, + "PRM_HIS_GetDischargeInfo_List": null, + "PRM_HIS_GetUpcomingConfirmedAppoimentList": null, + "PRM_HIS_QueueERToOP_List": null, + "PRM_HIS_QueueERToOP_WithOutER_List": null, + "PRM_QueueERreferralHistory_getList": null, + "PRM_QueueOPDreferralHistory_getList": null, + "PRM_SpecialClinicalCareMapping_List": null, + "PatientDoctorAppointmentResultExit": false, + "PatientDoctorAppointmentResultList": null, + "PatientER_DoctorFreeSlots": null, + "PatientER_GetAllClinics_List": null, + "PatientER_GetDoctorClincByServiceID_List": null, + "PatientER_GetServiceList": null, + "PatientER_Logininsert": 0, + "PatientER_PrescriptionLogin": null, + "PatientER_SelectAdmin": null, + "PatientER_SelectRole2": null, + "PatientER_UpdateLiveCareStatus": 0, + "PatientER_insert": 0, + "PatientInformationList": null, + "PatientNumber": 0, + "PaymentModes": null, + "Physio_IsPatientHasApproval": false, + "PhysiotherapyError": 0, + "ProcedureNeedeTime": 0, + "ReturnValue": null, + "RiskScore": 0, + "RowCount": 0, + "SameClinicApptList": null, + "SearchDoctorsByTime_IsVoiceCommandList": null, + "SlotDuration": 0, + "StatusCode": 0, + "Tamara_IntegrationLogsInsert_Response": 0, + "Tamara_IntegrationLogsUpdate_Response": 0, + "TransactionNo": null, + "UserDentalPlanMessage": null, + "WaitingAppointmentNoPerDay": 0, + "age": 0, + "erpDoctorDetails": null, + "isNphiesMatchedWithVida": false, + "isWithinFollowUpPeriod": false, + "returnValue": 0 +}; + + + + +var region = ['UAE Region','Eastern Region','Central Region','Western Region',]; \ No newline at end of file diff --git a/lib/services/authentication/auth_provider.dart b/lib/services/authentication/auth_provider.dart index bd2006f8..4a8a896c 100644 --- a/lib/services/authentication/auth_provider.dart +++ b/lib/services/authentication/auth_provider.dart @@ -1,9 +1,15 @@ +import 'dart:io'; + import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/service/AuthenticatedUserObject.dart'; import 'package:diplomaticquarterapp/core/service/client/base_app_client.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/main.dart'; +import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/models/Authentication/check_activation_code_request.dart'; +import 'package:diplomaticquarterapp/models/Authentication/check_activation_code_request_register.dart'; import 'package:diplomaticquarterapp/models/Authentication/check_activation_code_response.dart'; import 'package:diplomaticquarterapp/models/Authentication/check_paitent_authentication_req.dart'; import 'package:diplomaticquarterapp/models/Authentication/check_user_status_req.dart'; @@ -13,57 +19,58 @@ import 'package:diplomaticquarterapp/models/Authentication/register_user_requet. import 'package:diplomaticquarterapp/models/Authentication/registered_authenticated_user_req.dart'; import 'package:diplomaticquarterapp/models/Authentication/select_device_imei_res.dart'; import 'package:diplomaticquarterapp/models/Request.dart'; +import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:flutter/cupertino.dart'; +import 'package:intl/intl.dart'; +import 'package:provider/provider.dart'; import '../../locator.dart'; // SharedPreferences sharedPref = new SharedPreferences(); enum APP_STATUS { LOADING, UNAUTHENTICATED, AUTHENTICATED } -AppSharedPreferences sharedPref = new AppSharedPreferences(); -AppGlobal appGlobal = new AppGlobal(); +AppSharedPreferences sharedPref = AppSharedPreferences(); +AppGlobal appGlobal = AppGlobal(); -const String INSERT_DEVICE_IMEI = - 'Services/Patients.svc/REST/Patient_INSERTDeviceIMEI'; -const String SELECT_DEVICE_IMEI = - 'Services/Patients.svc/REST/Patient_SELECTDeviceIMEIbyIMEI'; -const String CHECK_PATIENT_AUTH = - 'Services/Authentication.svc/REST/CheckPatientAuthentication'; +const String INSERT_DEVICE_IMEI = 'Services/Patients.svc/REST/Patient_INSERTDeviceIMEI'; +const String SELECT_DEVICE_IMEI = 'Services/Patients.svc/REST/Patient_SELECTDeviceIMEIbyIMEI'; +const String CHECK_PATIENT_AUTH = 'Services/Authentication.svc/REST/CheckPatientAuthentication'; const GET_MOBILE_INFO = 'Services/Authentication.svc/REST/GetMobileLoginInfo'; -const SEND_ACTIVATION_CODE = - 'Services/Authentication.svc/REST/SendActivationCodebyOTPNotificationType'; -const CHECK_ACTIVATION_CODE = - 'Services/Authentication.svc/REST/CheckActivationCode'; -const FORGOT_PASSWORD = - 'Services/Authentication.svc/REST/CheckActivationCodeForSendFileNo'; -const CHECK_PATIENT_FOR_REGISTRATION = - "Services/Authentication.svc/REST/CheckPatientForRegisteration"; +const SEND_ACTIVATION_CODE = 'Services/Authentication.svc/REST/SendActivationCodebyOTPNotificationType'; + +const SEND_ACTIVATION_CODE_REGISTER = 'Services/Authentication.svc/REST/SendActivationCodebyOTPNotificationTypeForRegistration'; +const CHECK_ACTIVATION_CODE = 'Services/Authentication.svc/REST/CheckActivationCode'; +const CHECK_ACTIVATION_CODE_REGISTER = 'Services/Authentication.svc/REST/CheckActivationCodeForRegistration'; + +const FORGOT_PASSWORD = 'Services/Authentication.svc/REST/CheckActivationCodeForSendFileNo'; +const CHECK_PATIENT_FOR_REGISTRATION = "Services/Authentication.svc/REST/CheckPatientForRegisteration"; const CHECK_USER_STATUS = "Services/NHIC.svc/REST/GetPatientInfo"; const REGISTER_USER = 'Services/Authentication.svc/REST/PatientRegistration'; -const LOGGED_IN_USER_URL = - 'Services/MobileNotifications.svc/REST/Insert_PatientMobileDeviceInfo'; +const LOGGED_IN_USER_URL = 'Services/MobileNotifications.svc/REST/Insert_PatientMobileDeviceInfo'; -const FORGOT_PATIENT_ID = - 'Services/Authentication.svc/REST/SendPatientIDSMSByMobileNumber'; +const FORGOT_PATIENT_ID = 'Services/Authentication.svc/REST/SendPatientIDSMSByMobileNumber'; const DASHBOARD = 'Services/Patients.svc/REST/PatientDashboard'; const PROFILE_SETTING = 'Services/Patients.svc/REST/GetPateintInfoForUpdate'; const SAVE_SETTING = 'Services/Patients.svc/REST/UpdatePateintInfo'; +const DEACTIVATE_ACCOUNT = 'Services/Patients.svc/REST/PatientAppleActivation_InsertUpdate'; + class AuthProvider with ChangeNotifier { bool isLogin = false; bool isLoading = true; dynamic authenticatedUser; - AuthenticatedUserObject authenticatedUserObject = - locator(); + AuthenticatedUserObject authenticatedUserObject = locator(); + var languageID; AuthProvider() { getUserAuthentication(); } void getUserAuthentication() async { - Map profile = await sharedPref.getObject(USER_PROFILE); + Map profile = await sharedPref.getObject(USER_PROFILE) ?? Map(); + languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); if (profile != null) { isLoading = false; isLogin = true; @@ -110,19 +117,18 @@ class AuthProvider with ChangeNotifier { var lastLogin = lstLogin; //await sharedPref.getInt( // LAST_LOGIN); //this.cs.sharedService.getStorage(AuthenticationService.LAST_LOGIN); //this.cs.sharedService.getSharedData(AuthenticationService.LAST_LOGIN, false); - var request = - AuthenticatedUser.fromJson(await sharedPref.getObject(USER_PROFILE)); + var request = AuthenticatedUser.fromJson(await sharedPref.getObject(USER_PROFILE)); var newRequest = INSERTDeviceIMEIRequest(); var imei = await sharedPref.getString(PUSH_TOKEN); // if (!request.) { newRequest.iMEI = imei; //imei!=null ? imei : ''; - newRequest.firstName = request.firstName + " " + request.lastName; - newRequest.firstNameN = request.firstNameN + " " + request.lastNameN; + newRequest.firstName = request.firstName ?? "" + " " + request.lastName! ?? ""; + newRequest.firstNameN = request.firstNameN ?? "" + " " + request.lastNameN! ?? ""; newRequest.lastNameN = request.lastNameN ?? ""; newRequest.outSA = request.outSA == 1 ? true : false; newRequest.biometricEnabled = false; - newRequest.preferredLanguage = int.parse(request.preferredLanguage) ?? 1; + newRequest.preferredLanguage = int.parse(request.preferredLanguage!) ?? 1; newRequest.logInTypeID = lastLogin ?? 1; newRequest.patientID = request.patientID; newRequest.mobileNo = request.mobileNumber; @@ -133,8 +139,7 @@ class AuthProvider with ChangeNotifier { newRequest.tokenID = await sharedPref.getString(TOKEN); // } - await new BaseAppClient().post(INSERT_DEVICE_IMEI, - onSuccess: (dynamic response, int statusCode) { + await new BaseAppClient().post(INSERT_DEVICE_IMEI, onSuccess: (dynamic response, int statusCode) { localRes = response; }, onFailure: (String error, int statusCode) { throw error; @@ -146,36 +151,52 @@ class AuthProvider with ChangeNotifier { } } - Future selectDeviceImei(imei) async { + Future selectDeviceImei(imei, {int languageID = 1}) async { + SelectDeviceIMEIRES? selectDeviceIMEIRES; try { - dynamic localRes; + // SelectDeviceIMEIRES? localRes; + print(imei); Map request = {}; request['IMEI'] = imei; - await new BaseAppClient().post(SELECT_DEVICE_IMEI, - onSuccess: (dynamic response, int statusCode) { - localRes = SelectDeviceIMEIRES.fromJson( - response['Patient_SELECTDeviceIMEIbyIMEIList'][0]); + request['LanguageID'] = languageID; + + await BaseAppClient().post(SELECT_DEVICE_IMEI, onSuccess: (dynamic response, int statusCode) async { + // localRes = Map(); + print("Here response: ${response['Patient_SELECTDeviceIMEIbyIMEIList'][0]}"); + if (response['Patient_SELECTDeviceIMEIbyIMEIList'][0] != null) { + selectDeviceIMEIRES = SelectDeviceIMEIRES.fromJson(response['Patient_SELECTDeviceIMEIbyIMEIList'][0]); + sharedPref.setObject(IMEI_USER_DATA, selectDeviceIMEIRES); + } else { + print("ELSE TRIGERRED!!!!!!!!!"); + selectDeviceIMEIRES = null; + } + // await new BaseAppClient().post(SELECT_DEVICE_IMEI, + // onSuccess: (dynamic response, int statusCode) { + // localRes = SelectDeviceIMEIRES.fromJson( + // response['Patient_SELECTDeviceIMEIbyIMEIList'][0]); + // }, onFailure: (String error, int statusCode) { + // throw error; + // }, body: request); }, onFailure: (String error, int statusCode) { - throw error; + print("in the failure with : $error and $statusCode"); }, body: request); - return Future.value(localRes); } catch (error) { - return Future.value(null); + print("in the error"); + // return Future.error(error); } + return Future.value(selectDeviceIMEIRES); } - Future checkPatientAuthentication( - CheckPatientAuthenticationReq request) async { + Future checkPatientAuthentication(CheckPatientAuthenticationReq request) async { request.versionID = VERSION_ID; request.channel = CHANNEL; request.iPAdress = IP_ADDRESS; request.generalid = GENERAL_ID; - request.languageID = LANGUAGE_ID; - request.patientOutSA = request.zipCode == '966' ? 0 : 1; + request.languageID = (languageID == 'ar' ? 1 : 2); + request.patientOutSA = (request.zipCode == '966' || request.zipCode == '+966') ? 0 : 1; try { dynamic localRes; - await new BaseAppClient().post(CHECK_PATIENT_AUTH, - onSuccess: (dynamic response, int statusCode) { + await new BaseAppClient().post(CHECK_PATIENT_AUTH, onSuccess: (dynamic response, int statusCode) { localRes = response; }, onFailure: (String error, int statusCode) { throw error; @@ -192,14 +213,14 @@ class AuthProvider with ChangeNotifier { request.channel = CHANNEL; request.iPAdress = IP_ADDRESS; request.generalid = GENERAL_ID; - request.languageID = LANGUAGE_ID; - request.deviceTypeID = DeviceTypeID; + request.languageID = (languageID == 'ar' ? 1 : 2); + request.deviceTypeID = Platform.isIOS ? 1 : 2; request.patientOutSA = request.zipCode == '966' ? 0 : 1; request.isDentalAllowedBackend = false; - + // request.patientTypeID = request.patientType; + // request.patientType = request.patientType; dynamic localRes; - await new BaseAppClient().post(GET_MOBILE_INFO, - onSuccess: (dynamic response, int statusCode) { + await new BaseAppClient().post(GET_MOBILE_INFO, onSuccess: (dynamic response, int statusCode) { localRes = response; }, onFailure: (String error, int statusCode) { throw error; @@ -212,14 +233,34 @@ class AuthProvider with ChangeNotifier { request.channel = CHANNEL; request.iPAdress = IP_ADDRESS; request.generalid = GENERAL_ID; - request.languageID = LANGUAGE_ID; - request.deviceTypeID = DeviceTypeID; + // request.languageID = (languageID == 'ar' ? 1 : 2); + request.languageID = 2; + request.deviceTypeID = Platform.isIOS ? 1 : 2; + request.patientOutSA = request.zipCode == '966' ? 0 : 1; + request.isDentalAllowedBackend = false; + + dynamic localRes; + await new BaseAppClient().post(SEND_ACTIVATION_CODE, onSuccess: (dynamic response, int statusCode) { + localRes = response; + authenticatedUser = CheckActivationCode.fromJson(localRes); + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request.toJson()); + return Future.value(localRes); + } + + Future sendActivationCodeRegister(request) async { + request.versionID = VERSION_ID; + request.channel = CHANNEL; + request.iPAdress = IP_ADDRESS; + request.generalid = GENERAL_ID; + request.languageID = (languageID == 'ar' ? 1 : 2); + request.deviceTypeID = Platform.isIOS ? 1 : 2; request.patientOutSA = request.zipCode == '966' ? 0 : 1; request.isDentalAllowedBackend = false; dynamic localRes; - await new BaseAppClient().post(SEND_ACTIVATION_CODE, - onSuccess: (dynamic response, int statusCode) { + await new BaseAppClient().post(SEND_ACTIVATION_CODE_REGISTER, onSuccess: (dynamic response, int statusCode) { localRes = response; authenticatedUser = CheckActivationCode.fromJson(localRes); }, onFailure: (String error, int statusCode) { @@ -230,32 +271,62 @@ class AuthProvider with ChangeNotifier { Future checkActivationCode(request, [value]) async { var neRequest = CheckActivationCodeReq.fromJson(request); + neRequest.activationCode = value ?? "0000"; neRequest.isSilentLogin = value != null ? false : true; neRequest.versionID = VERSION_ID; neRequest.channel = CHANNEL; neRequest.iPAdress = IP_ADDRESS; neRequest.generalid = GENERAL_ID; - // neRequest.languageID = LANGUAGE_ID; - neRequest.deviceTypeID = DeviceTypeID; + neRequest.deviceTypeID = Platform.isIOS ? 1 : 2; neRequest.patientOutSA = neRequest.zipCode == '966' ? 0 : 1; neRequest.projectOutSA = neRequest.zipCode == '966' ? false : true; neRequest.isDentalAllowedBackend = false; - neRequest.deviceToken = null; - neRequest.forRegisteration = - neRequest.isRegister != null ? neRequest.isRegister : false; + // neRequest.deviceToken = null; + neRequest.forRegisteration = neRequest.isRegister != null ? neRequest.isRegister : false; neRequest.isRegister = false; dynamic localRes; try { - await new BaseAppClient().post(CHECK_ACTIVATION_CODE, - onSuccess: (dynamic response, int statusCode) { + await new BaseAppClient().post(CHECK_ACTIVATION_CODE, onSuccess: (dynamic response, int statusCode) { localRes = response; //CheckActivationCode.fromJson(); }, onFailure: (String error, int statusCode) { localRes = error; return Future.value(error); // throw error; }, body: neRequest.toJson()); - sharedPref.setString(BLOOD_TYPE, localRes['PatientBloodType']); + return Future.value(localRes); + } catch (error) { + throw localRes; + } + } + + Future checkActivationCodeRegister(request, [value]) async { + var neRequest = CheckActivationCodeRegisterReq.fromJson(request); + + neRequest.activationCode = value ?? "0000"; + neRequest.isSilentLogin = value != null ? false : true; + neRequest.versionID = VERSION_ID; + neRequest.channel = CHANNEL; + neRequest.iPAdress = IP_ADDRESS; + neRequest.generalid = GENERAL_ID; + // request.languageID = (languageID == 'ar' ? 1 : 2); + neRequest.deviceTypeID = Platform.isIOS ? 1 : 2; + neRequest.patientOutSA = neRequest.zipCode == '966' ? 0 : 1; + neRequest.projectOutSA = neRequest.zipCode == '966' ? false : true; + neRequest.isDentalAllowedBackend = false; + // neRequest.deviceToken = null; + neRequest.forRegisteration = neRequest.isRegister != null ? neRequest.isRegister : false; + neRequest.isRegister = false; + dynamic localRes; + try { + await new BaseAppClient().post(CHECK_ACTIVATION_CODE_REGISTER, onSuccess: (dynamic response, int statusCode) { + localRes = response; //CheckActivationCode.fromJson(); + }, onFailure: (String error, int statusCode) { + localRes = error; + return Future.value(error); + // throw error; + }, body: neRequest.toJson()); + // sharedPref.setString(BLOOD_TYPE, localRes['PatientBloodType']); return Future.value(localRes); } catch (error) { throw localRes; @@ -268,20 +339,18 @@ class AuthProvider with ChangeNotifier { return authenticatedUser; } - Future checkPatientForRegisteration( - CheckPatientForRegistration request) async { + Future checkPatientForRegisteration(CheckPatientForRegistration request, int languageID) async { request.versionID = VERSION_ID; request.channel = CHANNEL; request.iPAdress = IP_ADDRESS; request.generalid = GENERAL_ID; - request.deviceTypeID = DeviceTypeID; - request.languageID = LANGUAGE_ID; + request.languageID = languageID; + request.deviceTypeID = Platform.isIOS ? 1 : 2; request.isRegister = false; // request.tokenID = ''; dynamic localRes; try { - await new BaseAppClient().post(CHECK_PATIENT_FOR_REGISTRATION, - onSuccess: (dynamic response, int statusCode) { + await new BaseAppClient().post(CHECK_PATIENT_FOR_REGISTRATION, onSuccess: (dynamic response, int statusCode) { localRes = response; }, onFailure: (String error, int statusCode) { localRes = error; @@ -298,14 +367,13 @@ class AuthProvider with ChangeNotifier { request.channel = CHANNEL; request.iPAdress = IP_ADDRESS; request.generalid = GENERAL_ID; - request.deviceTypeID = DeviceTypeID; - request.languageID = LANGUAGE_ID; + request.languageID = (languageID == 'ar' ? 1 : 2); + request.deviceTypeID = Platform.isIOS ? 1 : 2; // request.tokenID = ''; dynamic localRes; try { - await new BaseAppClient().post(CHECK_USER_STATUS, - onSuccess: (dynamic response, int statusCode) { + await new BaseAppClient().post(CHECK_USER_STATUS, onSuccess: (dynamic response, int statusCode) { localRes = response; }, onFailure: (String error, int statusCode) { localRes = error; @@ -322,14 +390,1303 @@ class AuthProvider with ChangeNotifier { request['Channel'] = CHANNEL; request['IPAdress'] = IP_ADDRESS; request['Generalid'] = GENERAL_ID; - request['DeviceTypeID'] = DeviceTypeID; - request['LanguageID'] = LANGUAGE_ID; + request['DeviceTypeID'] = Platform.isIOS ? 1 : 2; + request['LanguageID'] = (languageID == 'ar' ? 1 : 2); + request['LogInTokenID'] = await sharedPref.getString(LOGIN_TOKEN_ID); + var nhic = await sharedPref.getObject(NHIC_DATA); var requestN = RegisterUserRequest.fromJson(request); - // request.tokenID = ''; + requestN.patientOutSA = requestN.patientobject!.patientOutSA!; + final DateFormat dateFormat = DateFormat('MM/dd/yyyy'); + final DateFormat dateFormat2 = DateFormat('dd/MM/yyyy'); + if (nhic != null) { + requestN.dob = nhic['IsHijri'] ? nhic['DateOfBirth'] : dateFormat2.format(dateFormat.parse(nhic['DateOfBirth'])); + requestN.isHijri = nhic['IsHijri'] ? 1 : 0; + requestN.healthId = requestN.patientobject!.eHealthIDField!; + } + + requestN.zipCode = requestN.patientOutSA == 1 ? '971' : '966'; + + await sharedPref.remove(USER_PROFILE); + dynamic localRes; try { - await new BaseAppClient().post(REGISTER_USER, - onSuccess: (dynamic response, int statusCode) { + // localRes = { + // "Date": null, + // "LanguageID": 0, + // "ServiceName": 0, + // "Time": null, + // "AndroidLink": null, + // "AuthenticationTokenID": "d+TXwG6BFkSjRuFPvTdSwA==", + // "Data": null, + // "Dataw": false, + // "DietType": 0, + // "DietTypeID": 0, + // "ErrorCode": null, + // "ErrorEndUserMessage": "Patient verified Successfully", + // "ErrorEndUserMessageN": null, + // "ErrorMessage": null, + // "ErrorStatusCode": 0, + // "ErrorType": 0, + // "FoodCategory": 0, + // "IOSLink": null, + // "IsAuthenticated": true, + // "MealOrderStatus": 0, + // "MealType": 0, + // "MessageStatus": 1, + // "NumberOfResultRecords": 0, + // "PatientBlodType": null, + // "SuccessMsg": null, + // "SuccessMsgN": null, + // "VidaUpdatedResponse": null, + // "DoctorInformation_List": null, + // "GetAllPendingRecordsList": null, + // "GetAllSharedRecordsByStatusList": null, + // "GetResponseFileList": null, + // "IsHMGPatient": false, + // "IsLoginSuccessfully": false, + // "IsNeedUpdateIdintificationNo": false, + // "IsPatientAuthorized": false, + // "IsVidaPlus": false, + // "KioskSendSMS": false, + // "List": [ + // { + // "SetupID": "010266", + // "PatientType": 1, + // "PatientID": 5318335, + // "FirstName": "SYED TAHA", + // "MiddleName": "ALAM", + // "LastName": "ALAM", + // "FirstNameN": "سيد طه", + // "MiddleNameN": "علام", + // "LastNameN": "علام", + // "RelationshipID": 0, + // "Gender": 1, + // "DateofBirth": "/Date(839106000000+0300)/", + // "DateofBirthN": null, + // "NationalityID": "PAK", + // "PhoneResi": " ", + // "PhoneOffice": " ", + // "MobileNumber": "0560960398", + // "FaxNumber": " ", + // "EmailAddress": "testtaha@gmail.com", + // "BloodGroup": null, + // "RHFactor": null, + // "IsEmailAlertRequired": false, + // "IsSMSAlertRequired": true, + // "PreferredLanguage": "1", + // "IsPrivilegedMember": false, + // "MemberID": null, + // "ExpiryDate": null, + // "IsHmgEmployee": null, + // "EmployeeID": null, + // "EmergencyContactName": "", + // "EmergencyContactNo": "", + // "PatientPayType": 0, + // "DHCCPatientRefID": null, + // "IsPatientDummy": false, + // "Status": 2, + // "IsStatusCleared": null, + // "PatientIdentificationType": 2, + // "PatientIdentificationNo": "2579628724", + // "ProjectID": 15, + // "InfoSourceID": 0, + // "Address": "", + // "Age": 28, + // "AgeDesc": "28 Yr", + // "AreaID": 0, + // "CRSVerificationStatus": 2, + // "CRSVerificationStatusDesc": "verified", + // "CRSVerificationStatusDescN": "تم التوثيق", + // "CreatedBy": 0, + // "GenderDescription": "Male", + // "HealthIDFromNHICViaVida": "2bcc1b1a-96b7-4f33-86e2-fa955d0e3764", + // "IR": null, + // "ISOCityID": null, + // "ISOCountryID": null, + // "IsVerfiedFromNHIC": true, + // "ListPrivilege": [ + // { + // "ID": 1, + // "ServiceName": "Notifications", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 2, + // "ServiceName": "Family Files", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 3, + // "ServiceName": "Settings", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 4, + // "ServiceName": "My Profile", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 5, + // "ServiceName": "My Appointment", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 6, + // "ServiceName": "My Doctors", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 7, + // "ServiceName": "Radiology", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 8, + // "ServiceName": "Radiology Email", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 9, + // "ServiceName": "Radiology View Image", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 10, + // "ServiceName": "Lab Results", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 11, + // "ServiceName": "Lab Results Email", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 12, + // "ServiceName": "Precriptions", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 13, + // "ServiceName": "Precriptions Email", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 14, + // "ServiceName": "Eye Measurments", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 15, + // "ServiceName": "Eye Measurments Email", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 16, + // "ServiceName": "Sick Leaves", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 17, + // "ServiceName": "Sick Leaves Email", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 18, + // "ServiceName": "Approvals", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 19, + // "ServiceName": "Monthly Reports", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 20, + // "ServiceName": "Request Medical Report", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 21, + // "ServiceName": "Request Medical Report Email", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 22, + // "ServiceName": "Insurance Cards", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 23, + // "ServiceName": "Allergies", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 24, + // "ServiceName": "My Trackers", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 25, + // "ServiceName": "Vital Signs", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 26, + // "ServiceName": "My Vaccines", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 27, + // "ServiceName": "My Vaccines Email", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 28, + // "ServiceName": "Ask Doctors", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 29, + // "ServiceName": "Live Chat", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 30, + // "ServiceName": "Health Data", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 31, + // "ServiceName": "Online Check-in", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 32, + // "ServiceName": "Connect to internet", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 33, + // "ServiceName": "Advance Payment", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 34, + // "ServiceName": "Book Appointment", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 35, + // "ServiceName": "Child Vaccines", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 36, + // "ServiceName": "Blood Donation", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 38, + // "ServiceName": "H2O", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 40, + // "ServiceName": "ChatBot", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 41, + // "ServiceName": "Parking", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 42, + // "ServiceName": "SymptomChecker", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 47, + // "ServiceName": "AdvanceBalance", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 48, + // "ServiceName": "ActiveMedications", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 49, + // "ServiceName": "VaccineAvailability", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 51, + // "ServiceName": "UpcomingAppointment", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 52, + // "ServiceName": "PushNotificationCount", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 53, + // "ServiceName": "ActiveMedicationCount", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 54, + // "ServiceName": "LabOrderUnreadCount", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 55, + // "ServiceName": "RadOrderUnreadCount", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 56, + // "ServiceName": "MedicalReportUnreadCount", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 57, + // "ServiceName": "ERWaittingTimeShowing", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 58, + // "ServiceName": "OnlinePayment", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 59, + // "ServiceName": "RadiologyDisplayImage", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 60, + // "ServiceName": "EmergencyConsultation", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 61, + // "ServiceName": "PatientQueueCall", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 62, + // "ServiceName": "OnlinePrescriptionOrder", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 63, + // "ServiceName": "Transportations", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 64, + // "ServiceName": "HomeHealthCareService", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 65, + // "ServiceName": "Al-HabibPharmacyOnline", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 66, + // "ServiceName": "Al-HabibOffers", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 67, + // "ServiceName": "ComprehensiveMedicalCheckup", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 68, + // "ServiceName": "RRT", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 72, + // "ServiceName": "CancelLiveCareRequest", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 74, + // "ServiceName": "Exacart", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 76, + // "ServiceName": "Covid19-CarThrow", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 77, + // "ServiceName": "VoiceBot", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 78, + // "ServiceName": "LiveCareBookOnDoctorSchedule", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 79, + // "ServiceName": "CheckIn_QR", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 80, + // "ServiceName": "CheckIn_NFC", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 81, + // "ServiceName": "ED", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 82, + // "ServiceName": "Packages_&_Offers", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 83, + // "ServiceName": "Lakum_Points", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 84, + // "ServiceName": "QR_Reader", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 85, + // "ServiceName": "AncillaryOrders", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 86, + // "ServiceName": "Payment-MADA", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 87, + // "ServiceName": "Payment-VISA", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 88, + // "ServiceName": "Payment-MasterCard", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 89, + // "ServiceName": "Payment-ApplePay", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 90, + // "ServiceName": "Payment-Tamara", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 91, + // "ServiceName": "Payment-Installment", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 92, + // "ServiceName": "ED-Checkin", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 93, + // "ServiceName": "NetworkDebug", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 94, + // "ServiceName": "TamaraAncillary", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 95, + // "ServiceName": "Verif-Face", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 96, + // "ServiceName": "Verif-Finger", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 97, + // "ServiceName": "Verif-SMS", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 98, + // "ServiceName": "Verif-WhatsApp", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 99, + // "ServiceName": "PharmacyLivecare", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 100, + // "ServiceName": "ePharmacy", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 102, + // "ServiceName": "CheckIn_Geofence", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 103, + // "ServiceName": "Payment-ApplePay-Web", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 104, + // "ServiceName": "Livecare_Zoom", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 105, + // "ServiceName": "Dental Virtual Tour", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 106, + // "ServiceName": "Dental Medical Instructions", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 107, + // "ServiceName": "Navigation Service", + // "Previlege": false, + // "Region": null + // } + // ], + // "Marital": null, + // "OutSA": 0, + // "POBox": "", + // "ReceiveHealthSummaryReport": false, + // "SourceType": 0, + // "StrDateofBirth": null, + // "TempAddress": "", + // "ZipCode": "", + // "eHealthIDField": null, + // "patientPayType": null, + // "patientType": null, + // "status": null + // } + // ], + // "List_AskHabibMobileLoginInfo": null, + // "List_AskHabibPatientFile": null, + // "List_FamilyRelationships": null, + // "List_MergeFiles": null, + // "List_MobileLoginInfo": null, + // "List_PatientCount": null, + // "LogInTokenID": null, + // "MohemmPrivilege_List": null, + // "PateintID": 5318335, + // "PatientBloodType": "", + // "PatientER_AdminDriverFileList": null, + // "PatientER_AdminFile": null, + // "PatientER_DriverFile": null, + // "PatientER_DriverFileList": null, + // "PatientHasFile": false, + // "PatientMergedIDs": null, + // "PatientOutSA": false, + // "PatientShareRequestID": 0, + // "PatientType": 0, + // "ProjectIDOut": 0, + // "ReturnMessage": null, + // "SMSLoginRequired": false, + // "ServicePrivilege_List": [ + // { + // "ID": 1, + // "ServiceName": "Notifications", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 2, + // "ServiceName": "Family Files", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 3, + // "ServiceName": "Settings", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 4, + // "ServiceName": "My Profile", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 5, + // "ServiceName": "My Appointment", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 6, + // "ServiceName": "My Doctors", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 7, + // "ServiceName": "Radiology", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 8, + // "ServiceName": "Radiology Email", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 9, + // "ServiceName": "Radiology View Image", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 10, + // "ServiceName": "Lab Results", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 11, + // "ServiceName": "Lab Results Email", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 12, + // "ServiceName": "Precriptions", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 13, + // "ServiceName": "Precriptions Email", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 14, + // "ServiceName": "Eye Measurments", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 15, + // "ServiceName": "Eye Measurments Email", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 16, + // "ServiceName": "Sick Leaves", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 17, + // "ServiceName": "Sick Leaves Email", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 18, + // "ServiceName": "Approvals", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 19, + // "ServiceName": "Monthly Reports", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 20, + // "ServiceName": "Request Medical Report", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 21, + // "ServiceName": "Request Medical Report Email", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 22, + // "ServiceName": "Insurance Cards", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 23, + // "ServiceName": "Allergies", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 24, + // "ServiceName": "My Trackers", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 25, + // "ServiceName": "Vital Signs", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 26, + // "ServiceName": "My Vaccines", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 27, + // "ServiceName": "My Vaccines Email", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 28, + // "ServiceName": "Ask Doctors", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 29, + // "ServiceName": "Live Chat", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 30, + // "ServiceName": "Health Data", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 31, + // "ServiceName": "Online Check-in", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 32, + // "ServiceName": "Connect to internet", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 33, + // "ServiceName": "Advance Payment", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 34, + // "ServiceName": "Book Appointment", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 35, + // "ServiceName": "Child Vaccines", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 36, + // "ServiceName": "Blood Donation", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 38, + // "ServiceName": "H2O", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 40, + // "ServiceName": "ChatBot", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 41, + // "ServiceName": "Parking", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 42, + // "ServiceName": "SymptomChecker", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 47, + // "ServiceName": "AdvanceBalance", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 48, + // "ServiceName": "ActiveMedications", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 49, + // "ServiceName": "VaccineAvailability", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 51, + // "ServiceName": "UpcomingAppointment", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 52, + // "ServiceName": "PushNotificationCount", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 53, + // "ServiceName": "ActiveMedicationCount", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 54, + // "ServiceName": "LabOrderUnreadCount", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 55, + // "ServiceName": "RadOrderUnreadCount", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 56, + // "ServiceName": "MedicalReportUnreadCount", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 57, + // "ServiceName": "ERWaittingTimeShowing", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 58, + // "ServiceName": "OnlinePayment", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 59, + // "ServiceName": "RadiologyDisplayImage", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 60, + // "ServiceName": "EmergencyConsultation", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 61, + // "ServiceName": "PatientQueueCall", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 62, + // "ServiceName": "OnlinePrescriptionOrder", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 63, + // "ServiceName": "Transportations", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 64, + // "ServiceName": "HomeHealthCareService", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 65, + // "ServiceName": "Al-HabibPharmacyOnline", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 66, + // "ServiceName": "Al-HabibOffers", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 67, + // "ServiceName": "ComprehensiveMedicalCheckup", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 68, + // "ServiceName": "RRT", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 72, + // "ServiceName": "CancelLiveCareRequest", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 74, + // "ServiceName": "Exacart", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 76, + // "ServiceName": "Covid19-CarThrow", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 77, + // "ServiceName": "VoiceBot", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 78, + // "ServiceName": "LiveCareBookOnDoctorSchedule", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 79, + // "ServiceName": "CheckIn_QR", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 80, + // "ServiceName": "CheckIn_NFC", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 81, + // "ServiceName": "ED", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 82, + // "ServiceName": "Packages_&_Offers", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 83, + // "ServiceName": "Lakum_Points", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 84, + // "ServiceName": "QR_Reader", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 85, + // "ServiceName": "AncillaryOrders", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 86, + // "ServiceName": "Payment-MADA", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 87, + // "ServiceName": "Payment-VISA", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 88, + // "ServiceName": "Payment-MasterCard", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 89, + // "ServiceName": "Payment-ApplePay", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 90, + // "ServiceName": "Payment-Tamara", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 91, + // "ServiceName": "Payment-Installment", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 92, + // "ServiceName": "ED-Checkin", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 93, + // "ServiceName": "NetworkDebug", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 94, + // "ServiceName": "TamaraAncillary", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 95, + // "ServiceName": "Verif-Face", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 96, + // "ServiceName": "Verif-Finger", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 97, + // "ServiceName": "Verif-SMS", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 98, + // "ServiceName": "Verif-WhatsApp", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 99, + // "ServiceName": "PharmacyLivecare", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 100, + // "ServiceName": "ePharmacy", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 102, + // "ServiceName": "CheckIn_Geofence", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 103, + // "ServiceName": "Payment-ApplePay-Web", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 104, + // "ServiceName": "Livecare_Zoom", + // "Previlege": false, + // "Region": null + // }, + // { + // "ID": 105, + // "ServiceName": "Dental Virtual Tour", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 106, + // "ServiceName": "Dental Medical Instructions", + // "Previlege": true, + // "Region": null + // }, + // { + // "ID": 107, + // "ServiceName": "Navigation Service", + // "Previlege": false, + // "Region": null + // } + // ], + // "SharePatientName": null, + // "UserAccountIsActivated": false, + // "VerificationCode": null, + // "email": null, + // "errorList": null, + // "hasFile": false, + // "isActiveCode": false, + // "isMerged": false, + // "isNeedUserAgreement": false, + // "isSMSSent": false, + // "memberList": null, + // "message": "Patient Registered Successfully", + // "statusCode": 1 + // }; + await new BaseAppClient().post(REGISTER_USER, onSuccess: (dynamic response, int statusCode) { localRes = response; }, onFailure: (String error, int statusCode) { localRes = error; @@ -341,30 +1698,26 @@ class AuthProvider with ChangeNotifier { } } - Future registeredAuthenticatedUser( - AuthenticatedUser user, deviceToken, lat, long) async { + Future registeredAuthenticatedUser(AuthenticatedUser user, deviceToken, lat, long) async { var request = new RegisteredAuthenticatedUserRequest(); request.deviceToken = deviceToken; - request.voipToken = - ""; //this.cs.sharedService.getSharedData(AuthenticationService.APNS_TOKEN, false); - request.deviceType = DeviceTypeID.toString(); - request.patientMobileNumber = '0' + user.mobileNumber; + request.voipToken = ""; //this.cs.sharedService.getSharedData(AuthenticationService.APNS_TOKEN, false); + request.deviceType = Platform.isIOS ? "1" : "2"; + request.patientMobileNumber = user.mobileNumber![0] == '0' ? user.mobileNumber : '0' + user.mobileNumber!; request.nationalID = user.patientIdentificationNo; request.gender = user.gender; request.patientID = user.patientID; request.patientOutSA = user.outSA; - request.loginType = await sharedPref.getInt(LAST_LOGIN) != null - ? await sharedPref.getInt(LAST_LOGIN) - : 1; + request.loginType = await sharedPref.getInt(LAST_LOGIN) != null ? await sharedPref.getInt(LAST_LOGIN) : 1; request.mACAddress = '00:00:00:00:00:00'; request.latitude = lat; request.longitude = long; - request.languageID = int.parse(user.preferredLanguage); - request.patientTypeID = 2; + request.languageID = int.parse(user.preferredLanguage!); + request.patientTypeID = user.patientType; + request.patientType = user.patientType; dynamic localRes; try { - await new BaseAppClient().post(LOGGED_IN_USER_URL, - onSuccess: (dynamic response, int statusCode) { + await new BaseAppClient().post(LOGGED_IN_USER_URL, onSuccess: (dynamic response, int statusCode) { localRes = response; }, onFailure: (String error, int statusCode) { localRes = error; @@ -376,32 +1729,21 @@ class AuthProvider with ChangeNotifier { } } - Future sendPatientIDSMS(mobileNo, context) async { + Future sendPatientIDSMS(mobileNo, zipCode, context) async { Map request; - // 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, - // "PatientID": 0, - // "TokenID": "", + "PatientOutSA": zipCode == '966' ? 0 : 1, "PatientMobileNumber": mobileNo, "SearchType": 2, - // "ZipCode": "966", - // "PatientIdentificationID": "", + "ZipCode": zipCode, "DeviceTypeID": req.DeviceTypeID, - // "SessionID": null }; dynamic localRes; - await new BaseAppClient().post(FORGOT_PATIENT_ID, - onSuccess: (response, statusCode) async { + await new BaseAppClient().post(FORGOT_PATIENT_ID, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { throw error; @@ -410,20 +1752,16 @@ class AuthProvider with ChangeNotifier { } Future forgotPasswordActivation(request, [value]) async { - // var neRequest = CheckActivationCodeReq.fromJson(request); - // neRequest.activationCode = value ?? "0000"; - // neRequest.isSilentLogin = value != null ? false : true; request['VersionID'] = VERSION_ID; request['Channel'] = CHANNEL; request['IPAdress'] = IP_ADDRESS; request['generalid'] = GENERAL_ID; - request['LanguageID'] = LANGUAGE_ID; - request['DeviceTypeID'] = DeviceTypeID; + request['DeviceTypeID'] = Platform.isIOS ? 1 : 2; + request['LanguageID'] = (languageID == 'ar' ? 1 : 2); dynamic localRes; try { - await new BaseAppClient().post(FORGOT_PASSWORD, - onSuccess: (dynamic response, int statusCode) { + await new BaseAppClient().post(FORGOT_PASSWORD, onSuccess: (dynamic response, int statusCode) { localRes = response; //CheckActivationCode.fromJson(); }, onFailure: (String error, int statusCode) { localRes = error; @@ -437,20 +1775,66 @@ class AuthProvider with ChangeNotifier { } } + Future checkIfUserAgreed() async { + Map request; + request = {"Region": 1, "SessionID": SESSION_ID}; + dynamic localRes; + try { + await new BaseAppClient().post(CHECK_USAGE_AGREEMENT, onSuccess: (dynamic response, int statusCode) { + localRes = response; + }, onFailure: (String error, int statusCode) { + localRes = error; + return Future.value(error); + // throw error; + }, body: request); + return Future.value(localRes); + } catch (error) { + throw error; + } + } + + Future getUserAgreementContent() async { + Map request; + request = {"Region": 1}; + dynamic localRes; + try { + await new BaseAppClient().post(GET_USAGE_AGREEMENT, onSuccess: (dynamic response, int statusCode) { + localRes = response; + }, onFailure: (String error, int statusCode) { + localRes = error; + return Future.value(error); + // throw error; + }, body: request); + return Future.value(localRes); + } catch (error) { + throw error; + } + } + + Future addUserAgreementContent() async { + Map request; + request = {"Region": 1}; + dynamic localRes; + try { + await new BaseAppClient().post(ADD_USAGE_AGREEMENT, onSuccess: (dynamic response, int statusCode) { + localRes = response; + }, onFailure: (String error, int statusCode) { + localRes = error; + return Future.value(error); + // throw error; + }, body: request); + return Future.value(localRes); + } catch (error) { + throw error; + } + } + Future getDashboard() async { Map request = {}; - request['VersionID'] = VERSION_ID; - request['Channel'] = CHANNEL; - request['IPAdress'] = IP_ADDRESS; - request['generalid'] = GENERAL_ID; - request['LanguageID'] = LANGUAGE_ID; - request['DeviceTypeID'] = DeviceTypeID; - request["PatientTypeID"] = 1; - request["PatientType"] = 1; + dynamic localRes; try { - await new BaseAppClient().post(DASHBOARD, - onSuccess: (dynamic response, int statusCode) { + await new BaseAppClient().post(DASHBOARD, onSuccess: (dynamic response, int statusCode) { localRes = response; //CheckActivationCode.fromJson(); }, onFailure: (String error, int statusCode) { localRes = error; @@ -467,36 +1851,90 @@ class AuthProvider with ChangeNotifier { getSettings() async { dynamic localRes; try { - await new BaseAppClient().post(PROFILE_SETTING, - onSuccess: (dynamic response, int statusCode) { - localRes = response; //CheckActivationCode.fromJson(); + await new BaseAppClient().post(PROFILE_SETTING, onSuccess: (dynamic response, int statusCode) { + localRes = response; }, onFailure: (String error, int statusCode) { localRes = error; return Future.value(error); - // throw error; }, body: {}); return Future.value(localRes); } catch (error) { throw error; - //return Future.value(error); } } Future saveSettings(request) async { dynamic localRes; try { - await new BaseAppClient().post(SAVE_SETTING, - onSuccess: (dynamic response, int statusCode) { - localRes = response; //CheckActivationCode.fromJson(); + await new BaseAppClient().post(SAVE_SETTING, onSuccess: (dynamic response, int statusCode) { + localRes = response; }, onFailure: (String error, int statusCode) { localRes = error; return Future.value(error); - // throw error; }, body: request); return Future.value(localRes); } catch (error) { throw error; - //return Future.value(error); } } + + Future deactivateAccount(request, bool isLogin) async { + dynamic localRes; + try { + await new BaseAppClient().post(DEACTIVATE_ACCOUNT, onSuccess: (dynamic response, int statusCode) { + localRes = response; + }, onFailure: (String error, int statusCode) { + localRes = error; + return Future.value(error); + }, body: request); + if (!isLogin) logout(); + return Future.value(localRes); + } catch (error) { + throw error; + } + } + + Future activateAccount(request) async { + dynamic localRes; + try { + await new BaseAppClient().post(DEACTIVATE_ACCOUNT, onSuccess: (dynamic response, int statusCode) { + localRes = response; + }, onFailure: (String error, int statusCode) { + localRes = error; + return Future.value(error); + }, body: request); + logout(); + return Future.value(localRes); + } catch (error) { + throw error; + } + } + + Future getPatientOccupationList() async { + Map request = {"ProjectOutSA": false}; + + dynamic localRes; + try { + await new BaseAppClient().post(GET_PATIENT_OCCUPATION_LIST, onSuccess: (dynamic response, int statusCode) { + localRes = response; + }, onFailure: (String error, int statusCode) { + localRes = error; + return Future.value(error); + }, body: request); + // logout(); + return Future.value(localRes); + } catch (error) { + throw error; + } + } + + logout() async { + await sharedPref.remove(LOGIN_TOKEN_ID); + await sharedPref.remove(PHARMACY_CUSTOMER_ID); + await authenticatedUserObject.getUser(); + Provider.of(AppGlobal.context, listen: false).isLogin = false; + var model = Provider.of(AppGlobal.context, listen: false); + model.setState(0, 0, false, null); + Navigator.of(AppGlobal.context).pushReplacementNamed(HOME); + } } diff --git a/lib/services/clinic_services/get_clinic_service.dart b/lib/services/clinic_services/get_clinic_service.dart index 99345030..4737756c 100644 --- a/lib/services/clinic_services/get_clinic_service.dart +++ b/lib/services/clinic_services/get_clinic_service.dart @@ -7,6 +7,9 @@ import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart' import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:flutter/material.dart'; +import '../../models/InPatientServices/get_admission_info_response_model.dart'; +import '../../uitl/date_uitl.dart'; + class ClinicListService extends BaseService { AppSharedPreferences sharedPref = AppSharedPreferences(); AppGlobal appGlobal = new AppGlobal(); @@ -14,29 +17,29 @@ class ClinicListService extends BaseService { AuthenticatedUser authUser = new AuthenticatedUser(); AuthProvider authProvider = new AuthProvider(); - double lat; - double long; + double? lat; + double? long; Future getClinicsList(context) async { - Map request; - 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": null - }; + Map request = {}; + + dynamic localRes; + + await baseAppClient.post(GET_CLINICS_LIST_URL, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + sharedPref.setObject(CLINICS_LIST, localRes); + return Future.value(localRes); + } + + Future getClinicByHospital({required String projectID}) async { + Map request = {"ProjectID": projectID}; dynamic localRes; - await baseAppClient.post(GET_CLINICS_LIST_URL, - onSuccess: (response, statusCode) async { + await baseAppClient.post(GET_CLINICS_LIST_WRT_HOSPITAL_URL, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { throw error; @@ -45,55 +48,28 @@ class ClinicListService extends BaseService { } Future getActiveAppointmentNo(context) async { - Map request; - 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": "", - "IsActiveAppointment": true, - "DeviceTypeID": req.DeviceTypeID, - "PatientType": user.patientType, - "PatientTypeID": user.patientType, - "SessionID": null - }; + Map request = {}; + + request = {"IsActiveAppointment": true, "LanguageID": 1}; dynamic localRes; - await baseAppClient.post(GET_ACTIVE_APPOINTMENTS_LIST_URL, - onSuccess: (response, statusCode) async { - localRes = response; - }, onFailure: (String error, int statusCode) { - throw error; - }, body: request); + await baseAppClient.post(GET_ACTIVE_APPOINTMENTS_LIST_URL, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); return Future.value(localRes); } - Future getProjectsList(context) async { - Map request; - 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": null - }; + Future getProjectsList(int languageID, context) async { + Map request = {}; + + // request = {"LanguageID": languageID}; dynamic localRes; - await baseAppClient.post(GET_PROJECTS_LIST, - onSuccess: (response, statusCode) async { + await baseAppClient.post(GET_PROJECTS_LIST, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { throw error; @@ -101,15 +77,12 @@ class ClinicListService extends BaseService { return Future.value(localRes); } - Future getChiefComplaintsList( - int clinicID, int projectID, BuildContext context, - {doctorId}) async { + Future getChiefComplaintsList(int patientID, int clinicID, int projectID, int languageID, bool isContinueDentalPlan, BuildContext context, {doctorId}) async { //Utils.showProgressDialog(context); 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; } @@ -121,24 +94,23 @@ class ClinicListService extends BaseService { "SelectedDate": "", "SelectedTime": "", "License": true, - "VersionID": 5.6, - "Channel": 3, - "LanguageID": languageID == 'ar' ? 1 : 2, + // "VersionID": 5.6, + // "Channel": 3, + "LanguageID": languageID, "IPAdress": "10.20.10.20", "generalid": "Cs2020@2016\$2958", - "PatientOutSA": 0, "SessionID": null, "isDentalAllowedBackend": true, "DeviceTypeID": 1, - "PatientID": 1, - "ContinueDentalPlan": true, - "IsSearchAppointmnetByClinicID": false + "PatientID": patientID, + "ContinueDentalPlan": isContinueDentalPlan, + "IsSearchAppointmnetByClinicID": false, + "DateofBirth": authUser.dateofBirth }; dynamic localRes; - await baseAppClient.post(GET_DOCTORS_LIST_URL, - onSuccess: (response, statusCode) async { + await baseAppClient.post(GET_DOCTORS_LIST_URL, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { throw error; @@ -146,19 +118,15 @@ class ClinicListService extends BaseService { return Future.value(localRes); } - Future getChiefComplaintDoctorList( - int chiefComplaintID, int projectID, BuildContext context, - {doctorId}) async { + Future getChiefComplaintDoctorList(int chiefComplaintID, int projectID, int languageID, BuildContext context, {doctorId}) async { 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; } - if (await this.sharedPref.getDouble(USER_LAT) != null && - await this.sharedPref.getDouble(USER_LONG) != null) { + if (await this.sharedPref.getDouble(USER_LAT) != null && await this.sharedPref.getDouble(USER_LONG) != null) { lat = await this.sharedPref.getDouble(USER_LAT); long = await this.sharedPref.getDouble(USER_LONG); } @@ -168,28 +136,428 @@ class ClinicListService extends BaseService { request = { "ChiefComplaintID": chiefComplaintID, "ProjectID": projectID, - "VersionID": 5.6, - "Channel": 3, - "LanguageID": languageID == 'ar' ? 1 : 2, - "IPAdress": req.IPAdress, - "generalid": req.generalid, - "PatientOutSA": 0, + // "VersionID": 5.6, + // "Channel": 3, + "LanguageID": languageID, + // "IPAdress": req.IPAdress, + // "generalid": req.generalid, "SessionID": null, "isDentalAllowedBackend": true, - "Latitude": lat.toString(), - "Longitude": long.toString(), + "Latitude": lat != null ? lat.toString() : "0.0", + "Longitude": long != null ? long.toString() : "0.0", "DeviceTypeID": req.DeviceTypeID, - "IsPublicRequest" : true + "IsPublicRequest": true }; dynamic localRes; - await baseAppClient.post(GET_DENTAL_DOCTORS_LIST_URL, - onSuccess: (response, statusCode) async { + await baseAppClient.post(GET_DENTAL_DOCTORS_LIST_URL, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { throw error; }, body: request); return Future.value(localRes); } + + Future getCountries() async { + Map request = {}; + dynamic localRes; + await baseAppClient.post(GET_NATIONALITY, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } + + Future getInPatientAdvancePaymentHistory(int projectID, int admissionNo, int admissionReqNo, context) async { + Map request; + request = {"ProjectID": projectID, "AdmissionNo": admissionNo, "AdmissionReqNo": admissionReqNo}; + + dynamic localRes; + + await baseAppClient.post(GET_INPATIENT_PAID_ADVANCE_PAYMENT, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request, isAllowAny: true); + return Future.value(localRes); + } + + Future getInPatientPaymentLink(int paymentRequestID, int projectID, int admissionNo, int orderID, String name, String email, num amount, String nationalID, int clinicID, context) async { + Map request; + // request = {"ProjectID": projectID, "AdmissionReqNo": admissionReqNo, "AdmissionNo": admissionNo}; + + request = { + "ProjectID": projectID, + "PaymentRequestId": paymentRequestID, + "ClientOrderID": orderID, + "OrderDescription": "InPatient Advance Payment", + "CustomerName": name, + "CustomerEmail": email, + "Amount": amount, + "IsPaid": 0, + "AppointmentID": admissionNo.toString(), + "PaymentOption": "0", + "PaymentReferenceNumber": admissionNo, + "SourceType": "1", + "NationalID": nationalID, + "ClinicID": clinicID, + "createdBy": 102 + }; + + dynamic localRes; + + await baseAppClient.post(GET_INPATIENT_ADVANCE_PAYMENT_LINK, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request, isAllowAny: true); + return Future.value(localRes); + } + + Future submitBirthNotification(num motherMRN, int projectID, String fatherNameAR, String fatherNameEN, String babyNameAR, String babyNameEN, String contactNum, String idImage, context) async { + Map request; + request = { + "ProjectID": projectID, + "mothermrn": motherMRN, + "fatherName": fatherNameEN, + "fatherNameAr": fatherNameAR, + "babyName": babyNameEN, + "babyNameAr": babyNameEN, + "contactNumber": contactNum, + "iDImage": idImage, + }; + + dynamic localRes; + + await baseAppClient.post(SAVE_BIRTH_NOTIFICATION, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request, isAllowAny: true); + return Future.value(localRes); + } + + Future insertInPatientOrder( + GetAdmissionInfoResponseModel getAdmissionInfoResponseModel, int typeID, String patientName, String patientNameAR, String patientMobileNo, String comments, context) async { + Map request; + request = { + "ProjectID": getAdmissionInfoResponseModel.projectID, + "TypeID": typeID, + "RoomNo": getAdmissionInfoResponseModel.roomID, + "GenderId": 2, + "AdmissionNo": getAdmissionInfoResponseModel.admissionNo, + "prescriptionNo": 250420, + "patientName": patientName, + "patientNameN": patientNameAR, + "PatientMobileNumber": patientMobileNo, + "comments": comments + }; + + dynamic localRes; + + await baseAppClient.post(INSERT_INPATIENT_ORDER, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request, isAllowAny: true); + return Future.value(localRes); + } + + Future getGeneralInstructions(int projectID, int languageID, context) async { + Map request; + request = {"ProjectID": projectID, "LanguageID": languageID}; + + dynamic localRes; + + await baseAppClient.post(GET_GENERAL_INSTRUCTIONS, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request, isAllowAny: true); + return Future.value(localRes); + } + + Future getMedicalInstructions(int projectID, int languageID, context) async { + Map request; + request = {"ProjectID": projectID, "LanguageID": languageID}; + + dynamic localRes; + + await baseAppClient.post(GET_MEDICAL_INSTRUCTIONS, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request, isAllowAny: true); + return Future.value(localRes); + } + + Future getInPatientAdvancePaymentRequests(int projectID, int admissionNo, int admissionReqNo, int languageID, context) async { + Map request; + request = {"ProjectID": projectID, "AdmissionReqNo": admissionReqNo, "AdmissionNo": admissionNo, "LanguageID": languageID}; + + dynamic localRes; + + await baseAppClient.post(GET_INPATIENT_ADVANCE_PAYMENT_REQUESTS, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request, isAllowAny: true); + return Future.value(localRes); + } + + Future getBirthNotification(num motherMRN, int projectID, int languageID, context) async { + Map request; + request = {"mothermrn": motherMRN, "LanguageID": languageID, "ProjectID": projectID}; + + dynamic localRes; + + await baseAppClient.post(GET_BIRTH_NOTIFICATION, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request, isAllowAny: true); + return Future.value(localRes); + } + + Future getAdmittedPatientDetails(int patientID, int projectID, int admissionNo, int buildingID, int floorID, int nursingStationID, context) async { + Map request; + request = {"ProjectID": projectID, "PatientID": patientID, "AdmissionNo": admissionNo, "BuildingID": buildingID, "FloorID": floorID, "NursingStationID": nursingStationID}; + + dynamic localRes; + + await baseAppClient.post(GET_ADMITTED_PATIENTS, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request, isAllowAny: true); + return Future.value(localRes); + } + + Future getCurrentWeekIDAndDay(BuildContext context) async { + dynamic localRes; + await baseAppClient.get(GET_CURRENT_WEEKID_WEEKDAY, isExternal: false, isRCService: false, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }); + return localRes; + } + + Future getMealsOfScheduleID(int projectID, int admissionNo, int dietType, int weekID, int weekDay, context) async { + Map request; + request = { + "ProjectID": projectID, + "AdmissionNo": admissionNo, + "BuildingID": 0, + "FloorID": 0, + "NursingStationID": 0, + "DietType": dietType, + "WeekID": weekID, + "WeekDay": weekDay, + }; + + dynamic localRes; + + await baseAppClient.post(GET_MEALS_OF_SCHEDULE_ID, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request, isAllowAny: true); + return Future.value(localRes); + } + + Future getDefaultItemsOfScheduleID(int projectID, int scheduleID, context) async { + Map request; + request = { + "ProjectID": projectID, + "MealScheduleID": scheduleID, + }; + + dynamic localRes; + + await baseAppClient.post(GET_MEAL_ITEMS_OF_SCHEDULE_ID, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request, isAllowAny: true); + return Future.value(localRes); + } + + Future placeMealPlanOrder(int projectID, int scheduleID, String itemIDList, int patientID, int admissionNo, bool isCompanion, bool isFasting, context) async { + Map request; + request = { + "ProjectID": projectID, + "ItemIDList": itemIDList, + "IsActive": true, + "OrderDate": DateUtil.getISODateFormat(DateTime.now()).replaceAll("T", " "), + "PatientID": patientID, + "AdmissionNo": admissionNo, + "IsCompanion": isCompanion, + "IsFasting": isFasting, + "CreatedBy": patientID, + "EditedBy": patientID, + "MealScheduleID": scheduleID, + "MealStatus": 1, + "ItemStatus": 0, + "ConfirmedBy": patientID, + "Remarks": "", + "IsVIP": false, + "IsFixedRemarks": false + }; + + dynamic localRes; + + await baseAppClient.post(PLACE_MEAL_PLAN_ORDER, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request, isAllowAny: true); + return Future.value(localRes); + } + + Future checkIfInPatientAPI(context) async { + Map request; + request = { + "IsActiveAppointment": false, + }; + + dynamic localRes; + + await baseAppClient.post(CHECK_IF_PATIENT_ADMITTED, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request, isAllowAny: true); + return Future.value(localRes); + } + + Future getWeCareURL(int projectID) async { + Map request = {"ProjectID": projectID}; + dynamic localRes; + await baseAppClient.post(GET_WE_CARE_TOUR_URL, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } + + Future getDentalInstructions() async { + Map request = {}; + dynamic localRes; + await baseAppClient.post(GET_DENTAL_INSTRUCTIONS, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } + + Future getEROnlineCheckInPaymentDetails(int projectID, int clinicID) async { + Map request = {"ProjectID": projectID, "ClinicID": clinicID}; + dynamic localRes; + await baseAppClient.post(GET_ER_ONLINE_PAYMENT_DETAILS, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } + + Future checkIfPatientHasArrived(int projectID, int clinicID) async { + Map request = {"ProjectID": projectID, "ClinicID": clinicID}; + dynamic localRes; + await baseAppClient.post(CHECK_IF_PATIENT_ARRIVED_ER_ONLINE_CHECKIN, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request, isAllowAny: true); + return Future.value(localRes); + } + + Future checkPatientERAdvanceBalance(int clinicID) async { + Map request = {"ClinicID": clinicID}; + dynamic localRes; + await baseAppClient.post(CHECK_PATIENT_ER_ADVANCE_BALANCE, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request, isAllowAny: true); + return Future.value(localRes); + } + + Future getProjectIDFromNFC(String nfcID) async { + Map request = {"nFC_Code": nfcID}; + dynamic localRes; + await baseAppClient.post(GET_PROJECT_FROM_NFC, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request, isAllowAny: true); + return Future.value(localRes); + } + + Future getDischargeMedicationOrder(GetAdmissionInfoResponseModel getAdmissionInfoResponseModel) async { + Map request; + request = { + "ProjectID": getAdmissionInfoResponseModel.projectID, + "ClinicID": getAdmissionInfoResponseModel.clinicID, + "DoctorID": getAdmissionInfoResponseModel.doctorID, + "AdmissionNo": getAdmissionInfoResponseModel.admissionNo + }; + + // request = { + // "ProjectID": 12, + // "VersionID": 10.8, + // "Channel": 3, + // "LanguageID": 2, + // "IPAdress": "10.20.10.20", + // "generalid": "Cs2020@2016\$2958", + // "DeviceTypeID": 2, + // "PatientType": 1, + // "PatientTypeID": 1, + // "TokenID": "@dm!n", + // "PatientID": 869588, + // "PatientOutSA": 0, + // "SessionID": "rVuK3nzN4UKN0SW95un0jQ==", + // "ClinicID": 2, + // "DoctorID": "7600", + // "AdmissionNo": 2011001258 + // }; + + dynamic localRes; + + await baseAppClient.post(INPATIENT_DISCHARGE_MEDICATIONS, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request, isAllowAny: true); + return Future.value(localRes); + } + + Future insertForGeneralAdmissionConsent(int patientID, int admissionReqNo, int clinicID, int projectID, int status, context) async { + Map request; + request = { + "AdmissionRequestNo": admissionReqNo, + "ClinicID": clinicID, + "CreatedBy": 102, + "PatientID": patientID, + "ProjectID": projectID, + "status": status, + "searchKey": "", + "pageIndex": 0, + "pageSize": 0, + }; + + dynamic localRes; + + await baseAppClient.post(INSERT_GENERAL_ADMISSION_CONSENT, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request, isAllowAny: true); + return Future.value(localRes); + } } diff --git a/lib/services/covid-drivethru/covid-drivethru.dart b/lib/services/covid-drivethru/covid-drivethru.dart index 3943a8b3..b4241bcc 100644 --- a/lib/services/covid-drivethru/covid-drivethru.dart +++ b/lib/services/covid-drivethru/covid-drivethru.dart @@ -18,31 +18,38 @@ class CovidDriveThruService 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; } - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); - Request req = appGlobal.getPublicRequest(); + request = {}; + + dynamic localRes; + + await baseAppClient.post(GET_COVID_DRIVETHRU_PROJECT_LIST, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } + + Future getCovidTestProceduresList(BuildContext context, num testTypeEnum, num testProcedureEnum, int projectID) async { + Map request; + + if (await this.sharedPref.getObject(USER_PROFILE) != null) { + var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE)); + authUser = data; + } request = { - "LanguageID": languageID == 'ar' ? 1 : 2, - "IPAdress": "10.20.10.20", - "VersionID": req.VersionID, - "Channel": req.Channel, - "generalid": 'Cs2020@2016\$2958', - "PatientOutSA": authUser.outSA, - "TokenID": "", - "DeviceTypeID": req.DeviceTypeID, - "SessionID": "YckwoXhUmWBsnHKEKig", - "PatientID": authUser.patientID != null ? authUser.patientID : 0, - "License": true + "ProjectID": projectID, + "TestTypeEnum": testTypeEnum, + "TestProcedureEnum": testProcedureEnum }; dynamic localRes; - await baseAppClient.post(GET_COVID_DRIVETHRU_PROJECT_LIST, - onSuccess: (response, statusCode) async { + await baseAppClient.post(GET_COVID_DRIVETHRU_PROCEDURES_LIST, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { throw error; @@ -50,77 +57,52 @@ class CovidDriveThruService extends BaseService { return Future.value(localRes); } - Future getCovidPaymentInformation(BuildContext context, int projectID) async { + Future getCovidPaymentInformation(BuildContext context, int projectID, String procedureID, num testTypeEnum, num testProcedureEnum) async { 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; } - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); - Request req = appGlobal.getPublicRequest(); request = { - "LanguageID": languageID == 'ar' ? 1 : 2, - "IPAdress": "10.20.10.20", "ProjectID": projectID, - "VersionID": req.VersionID, - "Channel": req.Channel, - "generalid": 'Cs2020@2016\$2958', - "PatientOutSA": authUser.outSA, - "TokenID": "", - "DeviceTypeID": req.DeviceTypeID, - "SessionID": "YckwoXhUmWBsnHKEKig", - "PatientID": authUser.patientID != null ? authUser.patientID : 0, - "License": true + "ProcedureId": procedureID, + "TestTypeEnum": testTypeEnum, + "TestProcedureEnum": testProcedureEnum }; dynamic localRes; - await baseAppClient.post(GET_COVID_DRIVETHRU_PAYMENT_INFO, - onSuccess: (response, statusCode) async { - localRes = response; - }, onFailure: (String error, int statusCode) { - throw error; - }, body: request); + await baseAppClient.post(GET_COVID_DRIVETHRU_PAYMENT_INFO, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); return Future.value(localRes); } - Future getCovidFreeSlots(BuildContext context, int projectID) async { + Future getCovidFreeSlots(BuildContext context, int projectID, num testTypeEnum, num testProcedureEnum) async { 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; } - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); - Request req = appGlobal.getPublicRequest(); request = { - "LanguageID": languageID == 'ar' ? 1 : 2, - "IPAdress": "10.20.10.20", "ProjectID": projectID, - "VersionID": req.VersionID, - "Channel": req.Channel, - "generalid": 'Cs2020@2016\$2958', - "PatientOutSA": authUser.outSA, - "TokenID": "", - "DeviceTypeID": req.DeviceTypeID, - "SessionID": "YckwoXhUmWBsnHKEKig", - "PatientID": authUser.patientID != null ? authUser.patientID : 0, - "License": true + "TestTypeEnum": testTypeEnum, + "TestProcedureEnum": testProcedureEnum }; dynamic localRes; - await baseAppClient.post(GET_COVID_DRIVETHRU_FREE_SLOTS, - onSuccess: (response, statusCode) async { - localRes = response; - }, onFailure: (String error, int statusCode) { - throw error; - }, body: request); + await baseAppClient.post(GET_COVID_DRIVETHRU_FREE_SLOTS, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); return Future.value(localRes); } } diff --git a/lib/services/family_files/family_files_provider.dart b/lib/services/family_files/family_files_provider.dart index 7a2dec81..123cc4d1 100644 --- a/lib/services/family_files/family_files_provider.dart +++ b/lib/services/family_files/family_files_provider.dart @@ -1,61 +1,53 @@ +import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/family-file/add_family_file_request.dart'; import 'package:diplomaticquarterapp/core/model/family-file/insert_share_file_request.dart'; import 'package:diplomaticquarterapp/core/service/client/base_app_client.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; -import 'package:diplomaticquarterapp/models/Authentication/check_activation_code_response.dart'; import 'package:diplomaticquarterapp/models/Authentication/send_activation_request.dart'; import 'package:diplomaticquarterapp/models/FamilyFiles/GetAllSharedRecordByStatusResponse.dart'; import 'package:diplomaticquarterapp/models/FamilyFiles/GetAllSharedRecordsByStatusReq.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:flutter/cupertino.dart'; +import 'package:provider/provider.dart'; // SharedPreferences sharedPref = new SharedPreferences(); enum APP_STATUS { LOADING, UNAUTHENTICATED, AUTHENTICATED } + AppSharedPreferences sharedPref = new AppSharedPreferences(); -const String GET_SHARED_RECORD_BY_STATUS = - 'Services/Authentication.svc/REST/GetAllSharedRecordsByStatus'; -const String ADD_FAMILY_FILES = - 'Services/Patients.svc/REST/ShareFamilyFileService'; -const String SEND_FAMILY_FILE_ACTIVATION = - 'Services/Authentication.svc/REST/SendActivationCodeForFamilyFile'; -const String INSERT_PATIENT_FILE = - 'Services/Authentication.svc/REST/Insert_SharePatientFile'; -const String CHECK_ACTIVATION_CODE = - 'Services/Authentication.svc/REST/CheckActivationCodeForFamilyFile'; - -const String UPDATE_FILE_STATUS = - 'Services/Authentication.svc/REST/Update_FileStatus'; -const String REMOVE_FILE_STATUS = - 'Services/Authentication.svc/REST/ActiveDeactive_PatientFile'; - -const String ACTIVATION_CODE_URL = - "Services/Authentication.svc/REST/CheckActivationCode"; -const String SENT_REQUEST_URL = - 'Services/Authentication.svc/REST/GetAllSharedRecordsByStatus'; -const String RECEVIED_REQUEST_URL = - 'Services/Authentication.svc/REST/GetAllPendingRecordsByResponseId'; -const ACCEPT_REJECT_FAMILY = - 'Services/Authentication.svc/REST/Update_FileStatus'; -const DEACTIVATE_FAMILY = - 'Services/Authentication.svc/REST/DeactivateRequestByRensponse'; +const String GET_SHARED_RECORD_BY_STATUS = 'Services/Authentication.svc/REST/GetAllSharedRecordsByStatus'; +const String ADD_FAMILY_FILES = 'Services/Patients.svc/REST/ShareFamilyFileService'; +const String SEND_FAMILY_FILE_ACTIVATION = 'Services/Authentication.svc/REST/SendActivationCodeForFamilyFile'; +const String INSERT_PATIENT_FILE = 'Services/Authentication.svc/REST/Insert_SharePatientFile'; +const String CHECK_ACTIVATION_CODE = 'Services/Authentication.svc/REST/CheckActivationCodeForFamilyFile'; + +const String UPDATE_FILE_STATUS = 'Services/Authentication.svc/REST/Update_FileStatus'; +const String REMOVE_FILE_STATUS = 'Services/Authentication.svc/REST/ActiveDeactive_PatientFile'; + +const String ACTIVATION_CODE_URL = "Services/Authentication.svc/REST/CheckActivationCode"; +const String SENT_REQUEST_URL = 'Services/Authentication.svc/REST/GetAllSharedRecordsByStatus'; +const String RECEVIED_REQUEST_URL = 'Services/Authentication.svc/REST/GetAllPendingRecordsByResponseId'; +const ACCEPT_REJECT_FAMILY = 'Services/Authentication.svc/REST/Update_FileStatus'; +const DEACTIVATE_FAMILY = 'Services/Authentication.svc/REST/DeactivateRequestByRensponse'; class FamilyFilesProvider with ChangeNotifier { bool isLogin = false; bool isLoading = true; dynamic authenticatedUser; - GetAllSharedRecordsByStatusResponse allSharedRecordsByStatusResponse; - Future getSharedRecordByStatus() async { + GetAllSharedRecordsByStatusResponse allSharedRecordsByStatusResponse = GetAllSharedRecordsByStatusResponse(); + + Future getSharedRecordByStatus(int languageID) async { + dynamic localRes; try { - dynamic localRes; var request = GetAllSharedRecordsByStatusReq(); - var result = await sharedPref.getObject(MAIN_USER); - request.status = 0; - request.patientID = result["PatientID"]; - await new BaseAppClient().post(GET_SHARED_RECORD_BY_STATUS, - onSuccess: (dynamic response, int statusCode) { + // var request = {"LanguageID": languageID}; + // var result = await sharedPref.getObject(MAIN_USER); + // request.status = 0; + // request.patientID = result["PatientID"]; + await new BaseAppClient().post(GET_SHARED_RECORD_BY_STATUS, onSuccess: (dynamic response, int statusCode) { localRes = response; }, onFailure: (String error, int statusCode) { AppToast.showErrorToast(message: error); @@ -63,35 +55,31 @@ class FamilyFilesProvider with ChangeNotifier { }, body: request.toJson()); sharedPref.setObject(FAMILY_FILE, localRes); - return Future.value( - GetAllSharedRecordsByStatusResponse.fromJson(localRes)); + return Future.value(GetAllSharedRecordsByStatusResponse.fromJson(localRes)); } catch (error) { - print(error); + print("-------" + error.toString()); throw error; } } - Future getUserViewRequest( - responseID) async { + Future getUserViewRequest(responseID, int languageID) async { try { dynamic localRes; Map request = {}; request['ResponseID'] = responseID; - await new BaseAppClient().post(RECEVIED_REQUEST_URL, - onSuccess: (dynamic response, int statusCode) { + await new BaseAppClient().post(RECEVIED_REQUEST_URL, onSuccess: (dynamic response, int statusCode) { localRes = response; }, onFailure: (String error, int statusCode) { return Future.error(error); }, body: request); if (localRes != null) { // sharedPref.setObject(FAMILY_FILE, localRes); - allSharedRecordsByStatusResponse = - GetAllSharedRecordsByStatusResponse.fromJson(localRes); + allSharedRecordsByStatusResponse = GetAllSharedRecordsByStatusResponse.fromJson(localRes); return Future.value(allSharedRecordsByStatusResponse); } else return Future.error("No Data"); } catch (error) { - print(error); + print("errorerror:$error"); return Future.error(error); } } @@ -101,8 +89,7 @@ class FamilyFilesProvider with ChangeNotifier { dynamic localRes; Map request = {}; request['Status'] = 0; - await new BaseAppClient().post(SENT_REQUEST_URL, - onSuccess: (dynamic response, int statusCode) { + await new BaseAppClient().post(SENT_REQUEST_URL, onSuccess: (dynamic response, int statusCode) { localRes = response; }, onFailure: (String error, int statusCode) { return Future.value(error); @@ -110,8 +97,7 @@ class FamilyFilesProvider with ChangeNotifier { //throw error; }, body: request); //sharedPref.setObject(FAMILY_FILE, localRes); - return Future.value( - GetAllSharedRecordsByStatusResponse.fromJson(localRes)); + return Future.value(GetAllSharedRecordsByStatusResponse.fromJson(localRes)); } catch (error) { print(error); throw error; @@ -123,8 +109,7 @@ class FamilyFilesProvider with ChangeNotifier { dynamic localRes; // var request = GetAllSharedRecordsByStatusReq(); //request.status = 0; - await new BaseAppClient().post(ADD_FAMILY_FILES, - onSuccess: (dynamic response, int statusCode) { + await new BaseAppClient().post(ADD_FAMILY_FILES, onSuccess: (dynamic response, int statusCode) { localRes = response; }, onFailure: (String error, int statusCode) { AppToast.showErrorToast(message: error); @@ -144,8 +129,7 @@ class FamilyFilesProvider with ChangeNotifier { dynamic localRes; // var request = GetAllSharedRecordsByStatusReq(); //request.status = 0; - await new BaseAppClient().post(INSERT_PATIENT_FILE, - onSuccess: (dynamic response, int statusCode) { + await new BaseAppClient().post(INSERT_PATIENT_FILE, onSuccess: (dynamic response, int statusCode) { localRes = response; }, onFailure: (String error, int statusCode) { throw error; @@ -158,8 +142,7 @@ class FamilyFilesProvider with ChangeNotifier { } } - Future sendActivationCode( - cellNumber, zipCode, patientIdentificationID) async { + Future sendActivationCode(cellNumber, zipCode, patientIdentificationID, responseID, bool isExcluded) async { try { dynamic localRes; var request = SendActivationRequest(); @@ -170,8 +153,11 @@ class FamilyFilesProvider with ChangeNotifier { request.loginType = request.searchType = 1; request.oTPSendType = 1; request.isRegister = false; - await new BaseAppClient().post(SEND_FAMILY_FILE_ACTIVATION, - onSuccess: (dynamic response, int statusCode) { + request.responseID = responseID; + request.status = 2; + request.familyRegionID = zipCode == '966' ? 1 : 2; + request.isPatientExcluded = isExcluded; + await new BaseAppClient().post(SEND_FAMILY_FILE_ACTIVATION, onSuccess: (dynamic response, int statusCode) { localRes = response; }, onFailure: (String error, int statusCode) { AppToast.showErrorToast(message: error); @@ -186,8 +172,7 @@ class FamilyFilesProvider with ChangeNotifier { } //TODO - Future checkActivationCode( - loginTokenID, activationCode, indentification, mobileNo) async { + Future checkActivationCode(loginTokenID, activationCode, indentification, mobileNo, requestID, responseID) async { try { dynamic localRes; Map request = {}; @@ -196,9 +181,12 @@ class FamilyFilesProvider with ChangeNotifier { request['PatientIdentificationID'] = indentification; request['LogInTokenID'] = loginTokenID; request['activationCode'] = activationCode; + request['PatientShareRequestID'] = requestID; + request['ResponseID'] = responseID; + request['Status'] = 3; + // this.authService.authenticateRequest(request); - await new BaseAppClient().post(CHECK_ACTIVATION_CODE, - onSuccess: (dynamic response, int statusCode) { + await new BaseAppClient().post(CHECK_ACTIVATION_CODE, onSuccess: (dynamic response, int statusCode) { localRes = response; }, onFailure: (String error, int statusCode) { AppToast.showErrorToast(message: error); @@ -218,8 +206,7 @@ class FamilyFilesProvider with ChangeNotifier { Map request = {}; request['ID'] = id; request['Status'] = stauts; - await new BaseAppClient().post(UPDATE_FILE_STATUS, - onSuccess: (dynamic response, int statusCode) { + await new BaseAppClient().post(UPDATE_FILE_STATUS, onSuccess: (dynamic response, int statusCode) { localRes = response; }, onFailure: (String error, int statusCode) { AppToast.showErrorToast(message: error); @@ -237,8 +224,7 @@ class FamilyFilesProvider with ChangeNotifier { try { dynamic localRes; - await new BaseAppClient().post(REMOVE_FILE_STATUS, - onSuccess: (dynamic response, int statusCode) { + await new BaseAppClient().post(REMOVE_FILE_STATUS, onSuccess: (dynamic response, int statusCode) { localRes = response; }, onFailure: (String error, int statusCode) { AppToast.showErrorToast(message: error); @@ -252,56 +238,65 @@ class FamilyFilesProvider with ChangeNotifier { } } - Future silentLoggin(GetAllSharedRecordsByStatusList switchUser, - {onSuccess, mainUser}) async { + Future silentLoggin(GetAllSharedRecordsByStatusList? switchUser, int languageID, {onSuccess, mainUser}) async { Map request = {}; if (mainUser == true) { - var currentUser = - AuthenticatedUser.fromJson(await sharedPref.getObject(MAIN_USER)); - //const request = new SwitchUserRequest(); - request['LogInTokenID'] = ''; - request['PatientOutSA'] = currentUser.outSA; //? 1 : 0; - request['PatientMobileNumber'] = - currentUser.mobileNumber; //['MobileNumber']; + var currentUser = AuthenticatedUser.fromJson(await sharedPref.getObject(MAIN_USER) ?? ""); + + request['PatientOutSA'] = currentUser.outSA; //currentUser.outSA; //? 1 : 0; + request['LoginType'] = await sharedPref.getInt(LAST_LOGIN) ?? 1; + request['MobileNo'] = currentUser.mobileNumber![0].toString() == "0" ? currentUser.mobileNumber.toString() : '0' + currentUser.mobileNumber.toString(); + request['PatientMobileNumber'] = currentUser.mobileNumber; //['MobileNumber']; request['SearchType'] = 2; - request['SuperUser'] = currentUser.patientID; //currentUser.PatientID; + // request['SuperUser'] = currentUser.patientID; //currentUser.PatientID; request['PatientIdentificationID'] = ''; request['IsSilentLogin'] = true; + request['DeviceToken'] = await sharedPref.getString(PUSH_TOKEN ?? ""); request['PatientID'] = currentUser.patientID; //['PatientID']; request['ZipCode'] = currentUser.outSA == 1 ? "971" : "966"; request['activationCode'] = '0000'; request['isRegister'] = false; + request['LanguageID'] = languageID; } else { - var currentUser = - AuthenticatedUser.fromJson(await sharedPref.getObject(USER_PROFILE)); + var currentUser = AuthenticatedUser.fromJson(await sharedPref.getObject(USER_PROFILE)); //const request = new SwitchUserRequest(); - request['LogInTokenID'] = ''; - request['PatientOutSA'] = currentUser.outSA; //? 1 : 0; - request['PatientMobileNumber'] = - switchUser.mobileNumber; //['MobileNumber']; + // request['LogInTokenID'] = ''; + // request['PatientOutSA'] = currentUser.outSA; //? 1 : 0; + request['PatientOutSA'] = switchUser!.familyRegionID != null + ? switchUser!.familyRegionID == 1 + ? 0 + : 1 + : currentUser.outSA; //currentUser.outSA; //? 1 : 0; + request['PatientMobileNumber'] = switchUser!.mobileNumber; //['MobileNumber']; request['SearchType'] = 2; - request['SuperUser'] = switchUser.patientID; //currentUser.PatientID; + request['SuperUser'] = switchUser!.patientID; //currentUser.PatientID; request['PatientIdentificationID'] = ''; request['IsSilentLogin'] = true; - request['PatientID'] = switchUser.responseID; //['PatientID']; - request['ZipCode'] = currentUser.outSA == 1 ? "971" : "966"; + request['PatientID'] = switchUser!.responseID; //['PatientID']; + request['ZipCode'] = switchUser.familyRegionID != null + ? switchUser.familyRegionID == 1 + ? "966" + : "971" + : "966"; + // request['ZipCode'] = currentUser.outSA == 1 ? "971" : "966"; request['activationCode'] = '0000'; request['isRegister'] = false; + request['LanguageID'] = languageID; } try { dynamic localRes; - await new BaseAppClient().post(ACTIVATION_CODE_URL, - onSuccess: (dynamic response, int statusCode) { + await BaseAppClient().post(ACTIVATION_CODE_URL, onSuccess: (dynamic response, int statusCode) { localRes = response; }, onFailure: (String error, int statusCode) { AppToast.showErrorToast(message: error); throw error; }, body: request); - sharedPref.setString(BLOOD_TYPE, localRes['PatientBloodType']); + sharedPref.setString(BLOOD_TYPE, localRes['PatientBloodType'] ?? ""); return Future.value(localRes); - } catch (error) { + } + catch (error) { print(error); throw error; } @@ -311,8 +306,7 @@ class FamilyFilesProvider with ChangeNotifier { try { dynamic localRes; - await new BaseAppClient().post(ACCEPT_REJECT_FAMILY, - onSuccess: (dynamic response, int statusCode) { + await new BaseAppClient().post(ACCEPT_REJECT_FAMILY, onSuccess: (dynamic response, int statusCode) { localRes = response; }, onFailure: (String error, int statusCode) { AppToast.showErrorToast(message: error); @@ -330,8 +324,7 @@ class FamilyFilesProvider with ChangeNotifier { try { dynamic localRes; - await new BaseAppClient().post(DEACTIVATE_FAMILY, - onSuccess: (dynamic response, int statusCode) { + await new BaseAppClient().post(DEACTIVATE_FAMILY, onSuccess: (dynamic response, int statusCode) { localRes = response; }, onFailure: (String error, int statusCode) { AppToast.showErrorToast(message: error); diff --git a/lib/services/livecare_services/livecare_provider.dart b/lib/services/livecare_services/livecare_provider.dart index 285fa0bf..43547056 100644 --- a/lib/services/livecare_services/livecare_provider.dart +++ b/lib/services/livecare_services/livecare_provider.dart @@ -4,7 +4,8 @@ import 'package:diplomaticquarterapp/config/config.dart'; 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/LiveCare/ApplePayInsertRequest.dart'; +import 'package:diplomaticquarterapp/models/tamara_request_model.dart'; import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:flutter/material.dart'; @@ -16,36 +17,24 @@ class LiveCareService extends BaseService { AuthenticatedUser authUser = new AuthenticatedUser(); AuthProvider authProvider = new AuthProvider(); - Future getLivecareClinics(BuildContext context) async { + Future getLivecareClinics(int languageID, BuildContext context) async { Map request; if (await this.sharedPref.getObject(USER_PROFILE) != null) { - var data = AuthenticatedUser.fromJson( - await this.sharedPref.getObject(USER_PROFILE)); + var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE)); 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 + "Gender": authUser.gender != null ? authUser.gender : 0, + "LanguageID": languageID }; dynamic localRes; - await baseAppClient.post(GET_LIVECARE_CLINICS, - onSuccess: (response, statusCode) async { + await baseAppClient.post(GET_LIVECARE_CLINICS, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { throw error; @@ -57,127 +46,98 @@ class LiveCareService 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; } - 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 - }; + request = {"Age": authUser.age != null ? authUser.age : 0, "PatientID": authUser.patientID != null ? authUser.patientID : 0, "Gender": authUser.gender != null ? authUser.gender : 0}; dynamic localRes; - await baseAppClient.post(GET_LIVECARE_SCHEDULE_CLINICS, - onSuccess: (response, statusCode) async { - localRes = response; - }, onFailure: (String error, int statusCode) { - throw error; - }, body: request); + await baseAppClient.post(GET_LIVECARE_SCHEDULE_CLINICS, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); return Future.value(localRes); } - Future getLiveCareScheduledDoctorList(BuildContext context, int serviceID) async { + Future getLiveCareScheduledDoctorList(BuildContext context, int serviceID, int languageID) async { 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; } - 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 + "Gender": authUser.gender != null ? authUser.gender : 0, + "LanguageID": languageID }; dynamic localRes; - await baseAppClient.post(GET_LIVECARE_SCHEDULE_CLINIC_DOCTOR_LIST, - onSuccess: (response, statusCode) async { - localRes = response; - }, onFailure: (String error, int statusCode) { - throw error; - }, body: request); + await baseAppClient.post(GET_LIVECARE_SCHEDULE_CLINIC_DOCTOR_LIST, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); return Future.value(localRes); } Future getLivecareHistory(BuildContext context) async { Map request; + 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; + } + + dynamic localRes; + + await baseAppClient.post(GET_LIVECARE_HISTORY, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } + + Future getPatientInfoByQR(String clientID, BuildContext context) async { + if (await this.sharedPref.getObject(USER_PROFILE) != null) { + var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE)); authUser = data; } var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); -// Request req = appGlobal.getPublicRequest(); - request = { - "LanguageID": languageID == 'ar' ? 1 : 2, - "TokenID": "", - "SessionID": "YckwoXhUmWBsnHKEKig" - }; + Map request; + request = {"clientid": clientID, "patientid": authUser.patientID, "isOutKsa": authUser.outSA == 1 ? true : false, "appLang": languageID == 'ar' ? "1" : "2"}; dynamic localRes; - await baseAppClient.post(GET_LIVECARE_HISTORY, - onSuccess: (response, statusCode) async { + await baseAppClient.post("https://vcallapi.hmg.com/api/PharmaLiveCare/getPatientInfoByQR", onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { throw error; - }, body: request); + }, body: request, isExternal: true); return Future.value(localRes); } - Future getLivecareClinicTiming( - int serviceID, BuildContext context) async { + Future getLivecareClinicTiming(int serviceID, int languageID, BuildContext context) async { Map request; if (await this.sharedPref.getObject(USER_PROFILE) != null) { - var data = AuthenticatedUser.fromJson( - await this.sharedPref.getObject(USER_PROFILE)); + var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE)); 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", + "LanguageID": languageID, "Age": authUser.age != null ? authUser.age : 0, "PatientID": authUser.patientID != null ? authUser.patientID : 0, "Gender": authUser.gender != null ? authUser.gender : 0 @@ -185,8 +145,7 @@ class LiveCareService extends BaseService { dynamic localRes; - await baseAppClient.post(GET_LIVECARE_CLINIC_TIMING, - onSuccess: (response, statusCode) async { + await baseAppClient.post(GET_LIVECARE_CLINIC_TIMING, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { throw error; @@ -194,39 +153,27 @@ class LiveCareService extends BaseService { return Future.value(localRes); } - Future getERAppointmentFees(int serviceID, BuildContext context) async { + Future getERAppointmentFees(int serviceID, bool isPharmaLiveCare, int languageID, BuildContext context) async { Map request; if (await this.sharedPref.getObject(USER_PROFILE) != null) { - var data = AuthenticatedUser.fromJson( - await this.sharedPref.getObject(USER_PROFILE)); + var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE)); 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, + "IsPharmacy": isPharmaLiveCare, "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, + "ProjectID": 12, "PatientID": authUser.patientID != null ? authUser.patientID : 0, - "Gender": authUser.gender != null ? authUser.gender : 0 + "Age": authUser.age != null ? authUser.age : 0, + "Gender": authUser.gender != null ? authUser.gender : 0, + "LanguageID": languageID }; dynamic localRes; - await baseAppClient.post(GET_ER_APPOINTMENT_FEES, - onSuccess: (response, statusCode) async { + await baseAppClient.post(GET_ER_APPOINTMENT_FEES, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { throw error; @@ -234,39 +181,27 @@ class LiveCareService extends BaseService { return Future.value(localRes); } - Future getERAppointmentTime(int serviceID, BuildContext context) async { + Future getERAppointmentTime(int serviceID, bool isPharmaLiveCare, int languageID, BuildContext context) async { Map request; if (await this.sharedPref.getObject(USER_PROFILE) != null) { - var data = AuthenticatedUser.fromJson( - await this.sharedPref.getObject(USER_PROFILE)); + var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE)); 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, + "IsPharmacy": isPharmaLiveCare, "ServiceID": serviceID, - "ProjectID": 15, - "DeviceTypeID": req.DeviceTypeID, - "PatientType": authUser.patientType != null ? authUser.patientType : 0, - "PatientTypeID": authUser.patientType != null ? authUser.patientType : 0, - "SessionID": "YckwoXhUmWBsnHKEKig", + "ProjectID": 12, "Age": authUser.age != null ? authUser.age : 0, "PatientID": authUser.patientID != null ? authUser.patientID : 0, - "Gender": authUser.gender != null ? authUser.gender : 0 + "Gender": authUser.gender != null ? authUser.gender : 0, + "LanguageID": languageID }; dynamic localRes; - await baseAppClient.post(GET_ER_APPOINTMENT_TIME, - onSuccess: (response, statusCode) async { + await baseAppClient.post(GET_ER_APPOINTMENT_TIME, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { throw error; @@ -274,50 +209,44 @@ class LiveCareService extends BaseService { return Future.value(localRes); } - Future addNewCallForPatientER( - int serviceID, String clientRequestID, BuildContext context) async { + Future addNewCallForPatientER(int serviceID, String clientRequestID, int callTypeID, int languageID, bool isPharma, BuildContext context) async { Map request; - String deviceToken; + String? deviceToken; + + // String voipToken = Platform.isIOS ? (await AppSharedPreferences().getString(ONESIGNAL_APNS_TOKEN)) : ""; + String voipToken = Platform.isIOS ? (await AppSharedPreferences().getString(APNS_TOKEN)) : ""; getDeviceToken().then((value) { print(value); deviceToken = value; }); 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; } - 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, + "IsPharmacy": isPharma, "ErServiceID": serviceID, "ClientRequestID": clientRequestID, - "DeviceToken": deviceToken, - "VoipToken": "", - "Latitude": "24.708488", - "Longitude": "46.665925", + "DeviceToken": deviceToken!, + "VoipToken": voipToken, + "IsFlutter": true, + "Latitude": await this.sharedPref.getDouble(USER_LAT), + "Longitude": await this.sharedPref.getDouble(USER_LONG), "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 + "Gender": authUser.gender != null ? authUser.gender : 0, + "LanguageID": languageID, + "IsVoip": Platform.isIOS ? true : false, + "CallTypeID": callTypeID }; dynamic localRes; - await baseAppClient.post(ADD_NEW_CALL_FOR_PATIENT_ER, - onSuccess: (response, statusCode) async { + await baseAppClient.post(ADD_NEW_CALL_FOR_PATIENT_ER, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { throw error; @@ -334,16 +263,44 @@ class LiveCareService 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; } request = {"VCID": vc_id}; dynamic localRes; - await baseAppClient.post(CANCEL_LIVECARE_REQUEST, - onSuccess: (response, statusCode) async { + await baseAppClient.post(CANCEL_LIVECARE_REQUEST, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } + + Future applePayInsertRequest(ApplePayInsertRequest applePayInsertRequest, BuildContext context) async { + if (await this.sharedPref.getObject(USER_PROFILE) != null) { + var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE)); + authUser = data; + } + dynamic localRes; + await baseAppClient.post(APPLE_PAY_INSERT_REQUEST, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: applePayInsertRequest.toJson()); + return Future.value(localRes); + } + + Future sendLiveCareInvoiceEmail(String appoNo, int projectID, String emailAddress, int languageID, BuildContext context) async { + Map request; + if (await this.sharedPref.getObject(USER_PROFILE) != null) { + var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE)); + authUser = data; + } + request = {"To": emailAddress, "ProjectID": projectID, "AppointmentNo": appoNo, "LanguageID": languageID}; + dynamic localRes; + await baseAppClient.post(SEND_LIVECARE_INVOICE_EMAIL, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { throw error; @@ -351,25 +308,57 @@ class LiveCareService extends BaseService { return Future.value(localRes); } - Future sendLiveCareInvoiceEmail(String appoNo, int projectID, - String emailAddress, BuildContext context) async { + Future endCallAPI(String sessionID, int sessionStatus, BuildContext context) async { 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; } - request = { - "To": emailAddress, - "ProjectID": projectID, - "AppointmentNo": appoNo - }; + request = {"Open_SessionID": sessionID, "SessionStatus": sessionStatus, "SessionEndedBy": "Patient"}; + + dynamic localRes; + + await baseAppClient.post(CHANGE_PATIENT_ER_SESSION, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } + + Future tamaraInsertRequest(TamaraRequestModel tamaraInsertRequest, BuildContext context) async { + dynamic localRes; + await baseAppClient.post(TAMARA_REQUEST_INSERT, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: tamaraInsertRequest.toJson()); + return Future.value(localRes); + } + + Future getOneSignalVOIPToken(String voipToken, BuildContext context) async { + Map request; + // request = {"app_id": "b87a754b-9a2a-437c-960b-39a079c57586", "identifier": voipToken, "device_type": 0}; + request = {"app_id": "b87a754b-9a2a-437c-960b-39a079c57586", "identifier": voipToken, "device_type": 0, "test_type": 1}; + + dynamic localRes; + + await baseAppClient.post(GET_ONESIGNAL_VOIP_TOKEN, isExternal: true, isAllowAny: true, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } + + Future cancelPharmaLiveCareRequest(String pharmaClientRequestID, BuildContext context) async { + Map request; + request = {"clientid": pharmaClientRequestID, "status": "Cancel"}; dynamic localRes; - await baseAppClient.post(SEND_LIVECARE_INVOICE_EMAIL, - onSuccess: (response, statusCode) async { + await baseAppClient.post(CANCEL_PHARMA_LIVECARE_REQUEST, isExternal: true, isAllowAny: true, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { throw error; diff --git a/lib/services/my_invoice_service/my_invoice_services.dart b/lib/services/my_invoice_service/my_invoice_services.dart new file mode 100644 index 00000000..2245eeef --- /dev/null +++ b/lib/services/my_invoice_service/my_invoice_services.dart @@ -0,0 +1,112 @@ +import 'package:diplomaticquarterapp/config/config.dart'; +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/services/authentication/auth_provider.dart'; +import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; + +class MyInvoicesService extends BaseService { + AppSharedPreferences sharedPref = AppSharedPreferences(); + AppGlobal appGlobal = new AppGlobal(); + + AuthenticatedUser authUser = new AuthenticatedUser(); + AuthProvider authProvider = new AuthProvider(); + + Future getAllDentalAppointments(int projectID, context) async { + Map request; + + Request req = appGlobal.getPublicRequest(); + request = { + "IPAdress": "10.20.10.20", + "VersionID": req.VersionID, + "Channel": req.Channel, + "generalid": 'Cs2020@2016\$2958', + "PatientOutSA": authUser.outSA, + "DeviceTypeID": req.DeviceTypeID, + "SessionID": null, + "PatientID": authUser.patientID, + "License": true, + "IsRegistered": true, + "ProjectID": projectID, + "PatientTypeID": authUser.patientIdentificationType, + "PatientType": authUser.patientType, + "isDentalAllowedBackend": false + }; + + dynamic localRes; + + await baseAppClient.post(GET_ALL_APPOINTMENTS_FOR_DENTAL_CLINIC, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } + + Future getDentalAppointmentInvoice(int projectID, int appoNo, int invoiceNo, context) async { + Map request; + + Request req = appGlobal.getPublicRequest(); + request = { + "IPAdress": "10.20.10.20", + "VersionID": req.VersionID, + "Channel": req.Channel, + "generalid": 'Cs2020@2016\$2958', + "PatientOutSA": authUser.outSA, + "DeviceTypeID": req.DeviceTypeID, + "SessionID": null, + "PatientID": authUser.patientID, + "License": true, + "AppointmentNo": appoNo, + "InvoiceNo": invoiceNo, + "IsRegistered": true, + "ProjectID": projectID, + "PatientTypeID": authUser.patientIdentificationType, + "PatientType": authUser.patientType, + "isDentalAllowedBackend": false + }; + + dynamic localRes; + + await baseAppClient.post(GET_DENTAL_APPOINTMENT_INVOICE, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } + + Future sendDentalAppointmentInvoiceEmail(int projectID, int appoNo, context) async { + Map request; + + Request req = appGlobal.getPublicRequest(); + request = { + "IPAdress": "10.20.10.20", + "VersionID": req.VersionID, + "Channel": req.Channel, + "generalid": 'Cs2020@2016\$2958', + "PatientOutSA": authUser.outSA, + "DeviceTypeID": req.DeviceTypeID, + "SessionID": null, + "PatientID": authUser.patientID, + "License": true, + "AppointmentNo": appoNo, + "To": authProvider.authenticatedUserObject.user!.emailAddress, + "IsRegistered": true, + "ProjectID": projectID, + "PatientTypeID": authUser.patientIdentificationType, + "PatientType": authUser.patientType, + "isDentalAllowedBackend": false + }; + + dynamic localRes; + + await baseAppClient.post(SEND_DENTAL_APPOINTMENT_INVOICE_EMAIL, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } +} diff --git a/lib/services/payfort_services/payfort_project_details_resp_model.dart b/lib/services/payfort_services/payfort_project_details_resp_model.dart new file mode 100644 index 00000000..b4d9eae2 --- /dev/null +++ b/lib/services/payfort_services/payfort_project_details_resp_model.dart @@ -0,0 +1,37 @@ +class PayfortProjectDetailsRespModel { + String? accessCode; + int? integrationId; + String? merchantIdentifier; + int? projectID; + String? projectName; + int? servID; + String? shaRequest; + String? shaResponse; + String? signature; + + PayfortProjectDetailsRespModel({this.accessCode, this.integrationId, this.merchantIdentifier, this.projectID, this.projectName, this.servID, this.shaRequest, this.shaResponse, this.signature}); + + PayfortProjectDetailsRespModel.fromJson(Map json) { + accessCode = json['AccessCode']; + integrationId = json['Integration_Id']; + merchantIdentifier = json['MerchantIdentifier']; + projectID = json['ProjectID']; + projectName = json['ProjectName']; + servID = json['ServID']; + shaRequest = json['Sha_Request']; + shaResponse = json['Sha_Response']; + } + + Map toJson() { + final Map data = new Map(); + data['AccessCode'] = this.accessCode; + data['Integration_Id'] = this.integrationId; + data['MerchantIdentifier'] = this.merchantIdentifier; + data['ProjectID'] = this.projectID; + data['ProjectName'] = this.projectName; + data['ServID'] = this.servID; + data['Sha_Request'] = this.shaRequest; + data['Sha_Response'] = this.shaResponse; + return data; + } +} diff --git a/lib/services/payfort_services/payfort_service.dart b/lib/services/payfort_services/payfort_service.dart new file mode 100644 index 00000000..9b2c4597 --- /dev/null +++ b/lib/services/payfort_services/payfort_service.dart @@ -0,0 +1,196 @@ +import 'dart:convert'; + +import 'package:amazon_payfort/amazon_payfort.dart'; +import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/core/service/base_service.dart'; +import 'package:diplomaticquarterapp/services/payfort_services/payfort_project_details_resp_model.dart'; +import 'package:diplomaticquarterapp/services/payfort_services/sdk_token_response_model.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:http/http.dart'; +import 'package:network_info_plus/network_info_plus.dart'; + +class PayfortService extends BaseService { + final AmazonPayfort _payfort = AmazonPayfort.instance; + + final NetworkInfo _info = NetworkInfo(); + + Future initPayfortSDK() async { + await AmazonPayfort.initialize( + PayFortOptions(environment: payFortEnvironment), + ); + } + + Future getPayfortConfigurations({int? serviceId, int? projectId, int integrationId = 2, int? languageID}) async { + Map body = {"Integration_Id": integrationId, "ServID": serviceId, "ProjectID": projectId, "LanguageID": languageID}; + + PayfortProjectDetailsRespModel payfortProjectDetailsRespModel = PayfortProjectDetailsRespModel(); + await baseAppClient.post( + getPayFortProjectDetails, + onSuccess: (response, statusCode) async { + payfortProjectDetailsRespModel = PayfortProjectDetailsRespModel.fromJson(response.isNotEmpty ? response.first : response); + }, + onFailure: (String error, int statusCode) { + Utils.showErrorToast(error); + return null; + }, + body: body, + isAllowAny: true, + ); + return payfortProjectDetailsRespModel; + } + + Future addPayfortApplePayResponse(num patientID, {PayFortResult? result}) async { + Map body = { + "Fort_id": result!.fortId, + "CommandType": result!.command, + "Amount": (num.parse(result.amount!) / 100), + "Payment_Option": result.paymentOption, + "Customer_IP": result.customerIp, + "ECI": result.eci, + "Response_Message": result.responseMessage, + "Card_Number": result.cardNumber, + "Status": result.status, + "Merchant_Ref": result.merchantReference, + "Pat_Token": result.tokenName, + "IsRefund": false, + "RemmeberMe": false, + // "Reconciliation_Reference": result.reconciliationReference, + "LanguageID": 1, + "PatientID": patientID + }; + + await baseAppClient.post( + addPayFortApplePayResponse, + onSuccess: (response, statusCode) async { + // payfortProjectDetailsRespModel = PayfortProjectDetailsRespModel.fromJson(response.isNotEmpty ? response.first : response); + }, + onFailure: (String error, int statusCode) { + Utils.showErrorToast(error); + return null; + }, + body: body, + isAllowAny: true, + ); + } + + Future? generateSdkSignatureFromAPI(SdkTokenRequest request) async { + var response = await post( + Uri.parse(payFortEnvironment.paymentApi), + headers: {'Content-Type': 'application/json'}, + body: jsonEncode(request.asRequest()), + ); + if (response.statusCode == 200) { + var decodedResponse = jsonDecode(response.body); + return SdkTokenResponse.fromMap(decodedResponse); + } + return null; + } + + Future _generateSdkResponse({ + String? applePayAccessCode, + String? merchantIdentifier, + String? applePayShaType, + String? applePayShaRequestPhrase, + }) async { + try { + String? deviceId = await _payfort.getDeviceId(); + + /// Step 2: Generate the Signature + SdkTokenRequest tokenRequest = SdkTokenRequest( + accessCode: applePayAccessCode!, + deviceId: deviceId ?? '', + merchantIdentifier: merchantIdentifier!, + ); + + String? signature = await _payfort.generateSignature( + shaType: applePayShaType!, + concatenatedString: tokenRequest.toConcatenatedString(applePayShaRequestPhrase!), + ); + + tokenRequest = tokenRequest.copyWith(signature: signature); + + /// Step 3: Generate the SDK Token + return await generateSdkSignatureFromAPI(tokenRequest); + } catch (e) { + print("Error here: ${e.toString()}"); + } + return null; + } + + Future getPayfortSignature( + String applePayAccessCode, + String merchantIdentifier, + String applePayShaRequestPhrase, + ) async { + String? deviceId = await _payfort.getDeviceId(); + SdkTokenRequest tokenRequest = SdkTokenRequest( + accessCode: applePayAccessCode, + deviceId: deviceId ?? '', + merchantIdentifier: merchantIdentifier, + ); + + String? signature = await _payfort.generateSignature( + shaType: "SHA-256", + concatenatedString: tokenRequest.toConcatenatedString(applePayShaRequestPhrase), + ); + + return signature!; + } + + Future paymentWithApplePay({ + SucceededCallback? onSucceeded, + FailedCallback? onFailed, + String? customerName, + String? customerEmail, + String? orderDescription, + num? orderAmount, + String? merchantIdentifier, + String? applePayAccessCode, + String? applePayShaRequestPhrase, + String? merchantReference, + String currency = "SAR", + String applePayShaType = "SHA-256", + String countryIsoCode = "SA", + }) async { + try { + SdkTokenResponse? sdkTokenResponse = await _generateSdkResponse( + applePayAccessCode: applePayAccessCode, + merchantIdentifier: merchantIdentifier, + applePayShaType: applePayShaType, + applePayShaRequestPhrase: applePayShaRequestPhrase, + ); + + if (sdkTokenResponse != null && sdkTokenResponse.sdkToken == null) { + onFailed!((sdkTokenResponse.responseMessage ?? '') as PayFortFailureResult); + return; + } + + /// Step 4: Processing Payment [Don't multiply with 100] + /// Amount value send always round ex. [100] not [100.00, 100.21] + FortRequest request = FortRequest( + command: FortCommand.purchase, + amount: orderAmount!, + customerName: customerName!, + customerEmail: customerEmail!, + // orderDescription: orderDescription!, + orderDescription: "Dr. Sulaiman Al Habib Hospital", + sdkToken: sdkTokenResponse?.sdkToken ?? '', + merchantReference: merchantReference!, + currency: currency, + customerIp: (await _info.getWifiIP() ?? ''), + language: 'en'); + + _payfort.callPayFortForApplePay( + request: request, + countryIsoCode: countryIsoCode, + applePayMerchantId: applePayMerchantId, + callback: ApplePayResultCallback( + onSucceeded: onSucceeded!, + onFailed: onFailed!, + ), + ); + } catch (e) { + onFailed!(e.toString() as PayFortFailureResult); + } + } +} diff --git a/lib/services/payfort_services/payfort_view_model.dart b/lib/services/payfort_services/payfort_view_model.dart new file mode 100644 index 00000000..2ba62fc2 --- /dev/null +++ b/lib/services/payfort_services/payfort_view_model.dart @@ -0,0 +1,87 @@ +import 'package:amazon_payfort/amazon_payfort.dart'; +import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/core/enum/PayfortEnums.dart'; +import 'package:diplomaticquarterapp/locator.dart'; +import 'package:diplomaticquarterapp/services/payfort_services/payfort_project_details_resp_model.dart'; +import 'package:diplomaticquarterapp/services/payfort_services/payfort_service.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:flutter/cupertino.dart'; + +class PayfortViewModel extends ChangeNotifier { + PayfortService _payfortService = locator(); + + Future initPayfort() async { + await _payfortService.initPayfortSDK(); + } + + Future getProjectDetailsForPayfort({int? serviceId, int? projectId, int? languageID}) async { + PayfortProjectDetailsRespModel payfortProjectDetailsRespModel = PayfortProjectDetailsRespModel(); + try { + payfortProjectDetailsRespModel = await _payfortService.getPayfortConfigurations(serviceId: serviceId, projectId: projectId, languageID: languageID); + + String signature = + await _payfortService.getPayfortSignature(payfortProjectDetailsRespModel.accessCode!, payfortProjectDetailsRespModel.merchantIdentifier!, payfortProjectDetailsRespModel.shaRequest!); + payfortProjectDetailsRespModel.signature = signature; + + return payfortProjectDetailsRespModel; + } on Exception catch (e, s) { + print(s); + return null; + } + } + + Future addPayfortApplePayResponse(num patientID, {PayFortResult? result}) async { + try { + await _payfortService.addPayfortApplePayResponse(patientID, result: result); + } on Exception catch (e, s) { + print(s); + return null; + } + } + + Future initiateApplePayWithPayfort({ + String? customerName, + String? customerEmail, + String? orderDescription, + String? merchantReference, + num? orderAmount, + PayfortProjectDetailsRespModel? payfortProjectDetailsRespModel, + SucceededCallback? onSuccess, + FailedCallback? onFailed, + ServiceTypeEnum? serviceTypeEnum, + int? projectId, + String? currency, + }) async { + // GifLoaderDialogUtils.showMyDialog(AppGlobal.context); + // PayfortProjectDetailsRespModel payfortProjectDetailsRespModel = await getProjectDetailsForPayfort(projectId: projectId, serviceId: serviceTypeEnum.getIdFromServiceEnum()); + // + // if (payfortProjectDetailsRespModel == null) { + // GifLoaderDialogUtils.hideDialog(AppGlobal.context); + // return; + // } + + try { + await _payfortService.paymentWithApplePay( + onSucceeded: onSuccess, + onFailed: onFailed, + customerName: customerName, + customerEmail: customerEmail, + orderDescription: orderDescription, + orderAmount: orderAmount, + merchantReference: merchantReference, + merchantIdentifier: payfortProjectDetailsRespModel!.merchantIdentifier ?? "", + applePayAccessCode: payfortProjectDetailsRespModel!.accessCode ?? "", + applePayShaRequestPhrase: payfortProjectDetailsRespModel.shaRequest ?? "", + currency: currency!, + ); + GifLoaderDialogUtils.hideDialog(AppGlobal.context); + } catch (e) { + // Utils.showErrorToast(e.toString()); + AppToast.showErrorToast(message: e.toString(), localContext: AppGlobal.context); + GifLoaderDialogUtils.hideDialog(AppGlobal.context); + throw e; + } + } +} diff --git a/lib/services/payfort_services/sdk_token_response_model.dart b/lib/services/payfort_services/sdk_token_response_model.dart new file mode 100644 index 00000000..a0f48a4f --- /dev/null +++ b/lib/services/payfort_services/sdk_token_response_model.dart @@ -0,0 +1,55 @@ +class SdkTokenResponse { + SdkTokenResponse({ + this.responseCode, + this.deviceId, + this.responseMessage, + this.serviceCommand, + this.sdkToken, + this.signature, + this.merchantIdentifier, + this.accessCode, + this.language, + this.status, + }); + + String? responseCode; + String? deviceId; + String? responseMessage; + String? serviceCommand; + String? sdkToken; + String? signature; + String? merchantIdentifier; + String? accessCode; + String? language; + String? status; + + factory SdkTokenResponse.fromMap(Map data) { + return SdkTokenResponse( + responseCode: data['response_code'], + deviceId: data['device_id'], + responseMessage: data['response_message'], + serviceCommand: data['service_command'], + sdkToken: data['sdk_token'], + signature: data['signature'], + merchantIdentifier: data['merchant_identifier'], + accessCode: data['access_code'], + language: data['language'], + status: data['status'], + ); + } + + Map toMap() { + return { + 'response_code': responseCode, + 'device_id': deviceId, + 'response_message': responseMessage, + 'service_command': serviceCommand, + 'sdk_token': sdkToken, + 'signature': signature, + 'merchant_identifier': merchantIdentifier, + 'access_code': accessCode, + 'language': language, + 'status': status, + }; + } +} diff --git a/lib/services/permission/permission_service.dart b/lib/services/permission/permission_service.dart index ea408ce2..cc73c303 100644 --- a/lib/services/permission/permission_service.dart +++ b/lib/services/permission/permission_service.dart @@ -1,18 +1,14 @@ import 'package:diplomaticquarterapp/config/config.dart'; -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/services/authentication/auth_provider.dart'; -import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:localstorage/localstorage.dart'; import 'package:permission_handler/permission_handler.dart'; -import 'package:vibration/vibration.dart'; +// import 'package:vibration/vibration.dart'; +import 'package:geolocator/geolocator.dart' as geo; + class PermissionService extends BaseService { final LocalStorage storage = new LocalStorage("permission"); - + geo.LocationPermission? locationPermission; AppGlobal appGlobal = new AppGlobal(); setVibrationPermission(flag) async { @@ -20,23 +16,24 @@ class PermissionService extends BaseService { } isVibrationEnabled() { - return (storage.getItem('isVibration') ==null) || (storage.getItem('isVibration')) ==false ? false :true; + return (storage.getItem('isVibration') == null) || + (storage.getItem('isVibration')) == false + ? false + : true; } - vibrate(callback, context) async{ - if (callback == null) - return null; - if(isVibrationEnabled() ==true){ - if (await Vibration.hasVibrator()) { - Vibration.vibrate(duration: 100); - callback(); - } - }else{ + vibrate(callback, context) async { + if (callback == null) return null; + if (isVibrationEnabled() == true) { + // if (await Vibration.hasVibrator() !=null) { + // Vibration.vibrate(duration: 100); + // callback(); + // } + } else { callback(); } } - setTheme(flag) async { storage.setItem('isTheme', flag); } @@ -44,23 +41,52 @@ class PermissionService extends BaseService { isThemeEnabled() { return storage.getItem('isTheme'); } - cameraPermission() async{ - Map statuses = await [ - Permission.camera, - ].request(); - } - isCameraEnabled() async{ - print(await Permission.camera.status); - return await Permission.camera.status == PermissionStatus.granted ? true : false; + + cameraPermission() async { + Map statuses = await [ + Permission.camera, + ].request(); + } + + static isCameraEnabled() async { + return await Permission.camera.isGranted; + } + + static isExternalStorageEnabled() async { + return await Permission.storage.isGranted; + } + + static isHealthDataPermissionEnabled() async { + return await Permission.sensors.isGranted; } - setCameraLocationPermission(context) async{ + + static isMicrophonePermissionEnabled() async { + return await Permission.microphone.isGranted; + } + + static isCalendarPermissionEnabled() async { + return await Permission.calendarFullAccess.isGranted; + } + + setCameraLocationPermission(context) async { Navigator.pop(context); openAppSettings(); } - isLocationEnabled() async{ - return await Permission.location.status == PermissionStatus.granted ? true : false; + + static isLocationEnabled() async { + var permission = await geo.Geolocator.checkPermission(); + if (permission == geo.LocationPermission.denied) { + return false; + } else { + return true; + } } - openSettings() async{ + + openSettings() async { openAppSettings(); } + + openAccessbility() { + // OpenSettings.openAppSetting(); + } } diff --git a/lib/services/pharmacy_services/brands_service.dart b/lib/services/pharmacy_services/brands_service.dart index 32024f2f..cf348a46 100644 --- a/lib/services/pharmacy_services/brands_service.dart +++ b/lib/services/pharmacy_services/brands_service.dart @@ -8,13 +8,13 @@ class BrandsService extends BaseService { AppSharedPreferences sharedPref = AppSharedPreferences(); bool isLogin = false; - List _brandsList = List(); + List _brandsList =[]; List get brandsList => _brandsList; - List _topBrandsList = List(); + List _topBrandsList =[]; List get topBrandsList => _topBrandsList; - List _searchList = List(); + List _searchList =[]; List get searchList => _searchList; clearSearchList() { @@ -49,8 +49,8 @@ class BrandsService extends BaseService { }); } - Future searchProducts({String productName}) async { - RegExp exp = new RegExp(productName.toUpperCase()); + Future searchProducts({String? productName}) async { + RegExp exp = new RegExp(productName!.toUpperCase()); hasError = false; _searchList.clear(); await baseAppClient.getPharmacy( diff --git a/lib/services/pharmacy_services/cancelOrder_service.dart b/lib/services/pharmacy_services/cancelOrder_service.dart index 3804b19b..0500a45b 100644 --- a/lib/services/pharmacy_services/cancelOrder_service.dart +++ b/lib/services/pharmacy_services/cancelOrder_service.dart @@ -1,8 +1,6 @@ import 'package:diplomaticquarterapp/config/config.dart'; -import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/order_detail.dart'; -import 'package:diplomaticquarterapp/core/model/pharmacies/order_model.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; @@ -17,7 +15,7 @@ class CancelOrderService extends BaseService{ AuthenticatedUser authUser = new AuthenticatedUser(); AuthProvider authProvider = new AuthProvider(); - List _cancelOrderList = List(); + List _cancelOrderList =[]; List get cancelOrderList => _cancelOrderList; String url =""; diff --git a/lib/services/pharmacy_services/orderDetails_service.dart b/lib/services/pharmacy_services/orderDetails_service.dart index 4178c50a..f1f99e5b 100644 --- a/lib/services/pharmacy_services/orderDetails_service.dart +++ b/lib/services/pharmacy_services/orderDetails_service.dart @@ -3,7 +3,6 @@ import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/order_detail.dart'; -import 'package:diplomaticquarterapp/core/model/pharmacies/order_model.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; @@ -17,13 +16,14 @@ class OrderDetailsService extends BaseService{ AuthenticatedUser authUser = new AuthenticatedUser(); AuthProvider authProvider = new AuthProvider(); - List _orderList = List(); + List _orderList =[]; List get orderList => _orderList; - Future getOrderDetails(OrderId) async { + Future getOrderDetails(OrderId, orderGUID) async { + var customerGUID = await sharedPref.getObject(PHARMACY_CUSTOMER_GUID); hasError = false; - await baseAppClient.getPharmacy(GET_ORDER_DETAILS+OrderId, + await baseAppClient.getPharmacy(GET_ORDER_DETAILS+OrderId + "/$orderGUID", onSuccess: (dynamic response, int statusCode) { _orderList.clear(); response['orders'].forEach((item) { @@ -58,7 +58,7 @@ class OrderDetailsService extends BaseService{ reviewBody["store_id"] = 2; reviewBody["title"] = ""; body['review'] = reviewBody; - await baseAppClient.post("$PHARMACY_MAKE_REVIEW", + await baseAppClient.postPharmacy("$PHARMACY_MAKE_REVIEW", onSuccess: (response, statusCode) async { /* "success": { diff --git a/lib/services/pharmacy_services/order_service.dart b/lib/services/pharmacy_services/order_service.dart index 3f1ece78..9a2a15c7 100644 --- a/lib/services/pharmacy_services/order_service.dart +++ b/lib/services/pharmacy_services/order_service.dart @@ -1,46 +1,42 @@ import 'package:diplomaticquarterapp/config/config.dart'; -import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/orders_model.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; -import 'package:flutter/material.dart'; -import 'package:diplomaticquarterapp/core/model/pharmacies/orders_model.dart'; - -class OrderService extends BaseService{ +class OrderService extends BaseService { AppSharedPreferences sharedPref = AppSharedPreferences(); AppGlobal appGlobal = new AppGlobal(); AuthenticatedUser authUser = new AuthenticatedUser(); AuthProvider authProvider = new AuthProvider(); - List _orderList = List(); + List _orderList =[]; + List get orderList => _orderList; - String url =""; + String url = ""; - Future getOrder(customerId, pageId) async { + Future getOrder(customerId, customerGUID, pageId) async { hasError = false; // url =GET_ORDER+"customer=1,fields=id,order_total,order_status,order_statusn,order_status_id,created_on_utc&page=1&limit=200&customer_id=1367368"; - // url =GET_ORDER+"customer=1,fields=id,order_total,order_status,order_statusn,order_status_id,created_on_utc&page=$pageId&limit=200&customer_id=$customerId"; - url =GET_ORDER+"customer=1&fields=id,order_total,order_status,order_statusn,order_status_id,created_on_utc,product_count,can_cancel,can_refund&page=$pageId&limit=200&customer_id=$customerId"; + // url =GET_ORDER+"customer=1,fields=id,order_total,order_status,order_statusn,order_status_id,created_on_utc&page=$pageId&limit=200&customer_id=$customerId"; + url = GET_ORDER + "customer=1&fields=id,order_total,order_status,order_statusn,order_status_id,created_on_utc,product_count,can_cancel,can_refund,order_guid&page=$pageId&limit=200&customer_id=$customerId&CustomerguId=$customerGUID"; print(url); - await baseAppClient.getPharmacy(url, - onSuccess: (dynamic response, int statusCode) { - _orderList.clear(); + await baseAppClient.getPharmacy(url, onSuccess: (dynamic response, int statusCode) { + _orderList.clear(); - response['orders'].forEach((item) { - _orderList.add(Orders.fromJson(item)); - }); - print(_orderList.length); - print(response); - }, onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }); + response['orders'].forEach((item) { + _orderList.add(Orders.fromJson(item)); + }); + print(_orderList.length); + print(response); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }); } - // Future getProductReview(orderId) async { // print("step 1"); // hasError = false; @@ -61,7 +57,6 @@ class OrderService extends BaseService{ // }); // } - // Future getOrder(BuildContext context ) async { // // if (await this.sharedPref.getObject(USER_PROFILE) != null) { @@ -82,4 +77,4 @@ class OrderService extends BaseService{ // }); // return Future.value(localRes); // } -} \ No newline at end of file +} diff --git a/lib/services/pharmacy_services/pharmacyAddress_service.dart b/lib/services/pharmacy_services/pharmacyAddress_service.dart index 592359ca..562468c9 100644 --- a/lib/services/pharmacy_services/pharmacyAddress_service.dart +++ b/lib/services/pharmacy_services/pharmacyAddress_service.dart @@ -1,56 +1,63 @@ +import 'dart:async'; + import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; 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/core/service/base_service.dart'; import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; class PharmacyAddressService extends BaseService { - List addresses = List(); - CountryData country; + List addresses =[]; + CountryData? country; int selectedAddressIndex = 0; - Future getAddresses() async { + Future> getAddresses() async { var customerId = await sharedPref.getString(PHARMACY_CUSTOMER_ID); + var customerGUID = await sharedPref.getObject(PHARMACY_CUSTOMER_GUID); Map queryParams = {'fields': 'addresses'}; hasError = false; - Addresses selectedAddress; + Addresses? selectedAddress; try { - await baseAppClient.getPharmacy("$GET_CUSTOMERS_ADDRESSES$customerId", - onSuccess: (dynamic response, int statusCode) async { + var completer = Completer(); + + await baseAppClient.getPharmacy("$GET_CUSTOMERS_ADDRESSES$customerId/$customerGUID", onSuccess: (dynamic response, int statusCode) async { addresses.clear(); - var savedAddress = - await sharedPref.getObject(PHARMACY_SELECTED_ADDRESS); + var savedAddress = await sharedPref.getObject(PHARMACY_SELECTED_ADDRESS); if (savedAddress != null) { selectedAddress = Addresses.fromJson(savedAddress); } int index = 0; response['customers'][0]['addresses'].forEach((item) { - Addresses address = Addresses.fromJson(item); - if (selectedAddress != null && selectedAddress.id == item["id"]) { + AddressInfo address = AddressInfo.fromJson(item); + if (selectedAddress! != null && selectedAddress!.id == item["id"]) { selectedAddressIndex = index; } addresses.add(address); index++; }); + completer.complete(); }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; }, queryParams: queryParams); + + await completer.future; } catch (error) { throw error; } + + return addresses; } Future getCountries(String countryName) async { hasError = false; try { - await baseAppClient.getPharmacy("$PHARMACY_GET_COUNTRY", - onSuccess: (dynamic response, int statusCode) { + await baseAppClient.getPharmacy("$PHARMACY_GET_COUNTRY", onSuccess: (dynamic response, int statusCode) { // countries.clear(); response['countries'].forEach((item) { - if (CountryData.fromJson(item).name == countryName || - CountryData.fromJson(item).namen == countryName) { + if (CountryData.fromJson(item).name == countryName || CountryData.fromJson(item).namen == countryName) { country = CountryData.fromJson(item); } // countries.add(CountryData.fromJson(item)); @@ -64,19 +71,22 @@ class PharmacyAddressService extends BaseService { } } - Future addCustomerAddress(Addresses address) async { - makeCustomerAddress(address, ADD_CUSTOMER_ADDRESS); + Future addCustomerAddress(AddressInfo address) async { + await makeCustomerAddress(address, ADD_CUSTOMER_ADDRESS); + // if(!hasError) { + // selectedAddressIndex = addresses.length + 1; + // } } - Future editCustomerAddress(Addresses address) async { + Future editCustomerAddress(AddressInfo address) async { makeCustomerAddress(address, EDIT_CUSTOMER_ADDRESS); } - Future deleteCustomerAddress(Addresses address) async { + Future deleteCustomerAddress(AddressInfo address) async { makeCustomerAddress(address, DELETE_CUSTOMER_ADDRESS); } - Future makeCustomerAddress(Addresses address, String url) async { + Future makeCustomerAddress(AddressInfo address, String url) async { var customerId = await sharedPref.getString(PHARMACY_CUSTOMER_ID); hasError = false; super.error = ""; @@ -89,14 +99,15 @@ class PharmacyAddressService extends BaseService { Map body = Map(); body["customer"] = customerObject; - await baseAppClient.post("$url", onSuccess: (response, statusCode) async { - addresses.clear(); - response['customers'][0]['addresses'].forEach((item) { - addresses.add(Addresses.fromJson(item)); - }); + await baseAppClient.postPharmacy("$url", onSuccess: (response, statusCode) async { + // addresses.clear(); + // response['customers'][0]['addresses'].forEach((item) { + // addresses.add(AddressInfo.fromJson(item)); + // }); + // getAddresses(); }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; - }, body: body); + },isAllowAny: true, body: body); } } diff --git a/lib/services/pharmacy_services/product_detail_service.dart b/lib/services/pharmacy_services/product_detail_service.dart index f85faf2c..3d01d018 100644 --- a/lib/services/pharmacy_services/product_detail_service.dart +++ b/lib/services/pharmacy_services/product_detail_service.dart @@ -1,86 +1,112 @@ import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; import 'package:diplomaticquarterapp/models/pharmacy/Wishlist.dart'; -import 'package:diplomaticquarterapp/models/pharmacy/addToCartModel.dart'; import 'package:diplomaticquarterapp/models/pharmacy/locationModel.dart'; import 'package:diplomaticquarterapp/models/pharmacy/productDetailModel.dart'; -import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; -import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/models/pharmacy/specification.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; class ProductDetailService extends BaseService { bool isLogin = false; - List _productDetailList = List(); + num? _stockQuantity; + + num? get stockQuantity => _stockQuantity; + + String? _stockAvailability; + String? _stockAvailabilityn; + + String? get stockAvailability => _stockAvailability; + String? get stockAvailabilityn => _stockAvailabilityn; + + bool? _isStockAvailable; + + bool? get isStockAvailable => _isStockAvailable; + + List _productDetailList =[]; + List get productDetailList => _productDetailList; - List _productLocationList = List(); + List _productLocationList =[]; + List get productLocationList => _productLocationList; - List _addToCartModel = List(); + List _addToCartModel =[]; + List get addToCartModel => _addToCartModel; - List _wishListProducts = List(); - List get wishListProducts => _wishListProducts; + List _wishListProducts =[]; - List _productSpecification = List(); - List get productSpecification => _productSpecification; + List get wishListProducts => _wishListProducts; + List _productSpecification =[]; + List get productSpecification => _productSpecification; Future getProductReviews(productID) async { hasError = false; - await baseAppClient.getPharmacy(GET_PRODUCT_DETAIL+productID+"?fields=reviews", + await baseAppClient.getPharmacy( + GET_PRODUCT_DETAIL + + productID + + "?fields=reviews,stock_quantity,stock_availability,stock_availabilityn,IsStockAvailable", onSuccess: (dynamic response, int statusCode) { - _productDetailList.clear(); - response['products'].forEach((item) { - _productDetailList.add(ProductDetail.fromJson(item)); - print(response); - }); - }, onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }); + _productDetailList.clear(); + response['products'].forEach((item) { + _productDetailList.add(ProductDetail.fromJson(item)); + print(response); + }); + _stockQuantity = response['products'][0]['stock_quantity']; + _stockAvailability = response['products'][0]['stock_availability']; + _stockAvailabilityn = response['products'][0]['stock_availabilityn']; + + _isStockAvailable = response['products'][0]['IsStockAvailable']; + // _isStockAvailable = _stockAvailability == "In stock" ? true : false; + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }); } - Future getProductAvailabiltyDetail() async { + Future getProductAvailabiltyDetail(String productSKU) async { hasError = false; Map request; request = { - "Channel": 3, - "DeviceTypeID": 2, - "IPAdress": "10.20.10.20", - "LanguageID": 2, - "PatientOutSA": 0, - "SKU": "6720020025", - "SessionID": null, - "VersionID": 5.6, - "generalid": "Cs2020@2016\$2958", - "isDentalAllowedBackend": false + // "Channel": 3, + // "DeviceTypeID": 2, + // "IPAdress": "10.20.10.20", + // "LanguageID": 2, + // "PatientOutSA": 0, + "SKU": productSKU, + // "SessionID": null, + // "VersionID": 5.6, + // "generalid": "Cs2020@2016\$2958", + // "isDentalAllowedBackend": false }; await baseAppClient.post(GET_LOCATION, onSuccess: (dynamic response, int statusCode) { - _productLocationList.clear(); - response['PharmList'].forEach((item) { - _productLocationList.add(LocationModel.fromJson(item)); - print(_productLocationList); - print(response); - }); - }, onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }, body: request); + _productLocationList.clear(); + response['PharmList'].forEach((item) { + _productLocationList.add(LocationModel.fromJson(item)); + print(_productLocationList); + print(response); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: request); } - Future addToCart(quantity, itemID) async { + Future addToCart(quantity, itemID, context) async { var customerId = await sharedPref.getString(PHARMACY_CUSTOMER_ID); hasError = false; Map request; request = { - "shopping_cart_item": - { + "shopping_cart_item": { "quantity": quantity, "shopping_cart_type": "1", "product_id": itemID, @@ -88,96 +114,137 @@ class ProductDetailService extends BaseService { "language_id": 1 } }; + dynamic localRes; + await baseAppClient.pharmacyPost(GET_SHOPPING_CART, isExternal: false, onSuccess: (dynamic response, int statusCode) { - _addToCartModel.clear(); - response['shopping_carts'].forEach((item) { - _addToCartModel.add(Wishlist.fromJson(item)); - }); - AppToast.showSuccessToast(message: 'You have added a product to the cart'); - }, onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - AppToast.showErrorToast(message: 'something went wrong please try again'); - }, body: request); + _addToCartModel.clear(); + response['shopping_carts'].forEach((item) { + _addToCartModel.add(Wishlist.fromJson(item)); + }); + AppToast.showSuccessToast( + message: TranslationBase.of(context).addToCartMsg + // 'You have added a product to the cart' + ); + localRes = response; + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + AppToast.showErrorToast( + message: error ?? Utils.generateContactAdminMessage()); + }, body: request); + + return Future.value(localRes); } Future notifyMe(customerId, itemID) async { hasError = false; - await baseAppClient.getPharmacy(SUBSCRIBE_PRODUCT + "SinceId=$customerId&ProductId=$itemID", onSuccess: (dynamic response, int statusCode) { - AppToast.showSuccessToast(message: 'You will be notified when product available'); + await baseAppClient.getPharmacy( + SUBSCRIBE_PRODUCT + "SinceId=$customerId&ProductId=$itemID", + onSuccess: (dynamic response, int statusCode) { + AppToast.showSuccessToast( + message: TranslationBase.of(AppGlobal.context).notifyMeMsg + // TranslationBase.of(context).notifyMeMsg + //'You will be notified when product available' + ); }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; - AppToast.showErrorToast(message: 'something went wrong please try again'); + AppToast.showErrorToast( + message: error ?? Utils.generateContactAdminMessage()); }); } - Future addToWishlist(itemID) async { + Future addToWishlist(itemID, context) async { var customerId = await sharedPref.getString(PHARMACY_CUSTOMER_ID); hasError = false; Map request; request = { - "shopping_cart_item": {"quantity": 1, "shopping_cart_type": "Wishlist", "product_id": itemID, "customer_id": customerId, "language_id": 1} + "shopping_cart_item": { + "quantity": 1, + "shopping_cart_type": "Wishlist", + "product_id": itemID, + "customer_id": customerId, + "language_id": 1 + } }; await baseAppClient.pharmacyPost(GET_SHOPPING_CART, onSuccess: (dynamic response, int statusCode) { - _wishListProducts.clear(); - response['shopping_carts'].forEach((item) { - _wishListProducts.add(Wishlist.fromJson(item)); - AppToast.showSuccessToast(message: 'You have added a product to the Wishlist'); - }); - }, onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - AppToast.showErrorToast(message: 'something went wrong please try again'); - }, body: request); + _wishListProducts.clear(); + response['shopping_carts'].forEach((item) { + _wishListProducts.add(Wishlist.fromJson(item)); + }); + AppToast.showSuccessToast( + message: TranslationBase.of(context).addToWishlistMsg + // 'You have added a product to the Wishlist' + ); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + AppToast.showErrorToast( + message: error ?? Utils.generateContactAdminMessage()); + }, body: request); } Future getWishlistItems() async { var customerId = await sharedPref.getString(PHARMACY_CUSTOMER_ID); + var custGUID = await sharedPref.getObject(PHARMACY_CUSTOMER_GUID); hasError = false; - await baseAppClient.getPharmacy(GET_WISHLIST+customerId+"?shopping_cart_type=2", + await baseAppClient.getPharmacy( + GET_WISHLIST + customerId + "/$custGUID" + "?shopping_cart_type=2", onSuccess: (dynamic response, int statusCode) { - _wishListProducts.clear(); - response['shopping_carts'].forEach((item) { - _wishListProducts.add(Wishlist.fromJson(item)); - }); - }, onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }); + _wishListProducts.clear(); + response['shopping_carts'].forEach((item) { + _wishListProducts.add(Wishlist.fromJson(item)); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }); } - Future delteItemFromWishlist(itemID) async { + + Future deleteItemFromWishlist(itemID, context) async { var customerId = await sharedPref.getString(PHARMACY_CUSTOMER_ID); + var custGUID = await sharedPref.getObject(PHARMACY_CUSTOMER_GUID); hasError = false; - await baseAppClient.getPharmacy(DELETE_WISHLIST+customerId+"+&product_id="+itemID+"&cart_type=Wishlist", + await baseAppClient.getPharmacy( + DELETE_WISHLIST + + customerId + + "/$custGUID" + + "+&product_id=" + + itemID + + "&cart_type=Wishlist", onSuccess: (dynamic response, int statusCode) { - _wishListProducts.clear(); - response['shopping_carts'].forEach((item) { - _wishListProducts.add(Wishlist.fromJson(item)); - }); - }, onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }); + _wishListProducts.clear(); + response['shopping_carts'].forEach((item) { + _wishListProducts.add(Wishlist.fromJson(item)); + }); + AppToast.showSuccessToast( + message: TranslationBase.of(context).removeFromWishlistMsg + // 'You have removed a product from the Wishlist' + ); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + AppToast.showErrorToast( + message: error ?? Utils.generateContactAdminMessage()); + }); } Future productSpecificationData(itemID) async { hasError = false; - await baseAppClient.getPharmacy(GET_SPECIFICATION+itemID, + await baseAppClient.getPharmacy(GET_SPECIFICATION + itemID, onSuccess: (dynamic response, int statusCode) { - _productSpecification.clear(); - response['specification'].forEach((item) { - _productSpecification.add(SpecificationModel.fromJson(item)); - print(_productSpecification); - }); - }, onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }); + _productSpecification.clear(); + response['specification'].forEach((item) { + _productSpecification.add(SpecificationModel.fromJson(item)); + print(_productSpecification); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }); } - } diff --git a/lib/services/pharmacy_services/recommendedProduct_service.dart b/lib/services/pharmacy_services/recommendedProduct_service.dart index ad7222f8..4b45b6d8 100644 --- a/lib/services/pharmacy_services/recommendedProduct_service.dart +++ b/lib/services/pharmacy_services/recommendedProduct_service.dart @@ -15,24 +15,26 @@ class RecommendedProductService extends BaseService{ AuthenticatedUser authUser = new AuthenticatedUser(); AuthProvider authProvider = new AuthProvider(); - List _recommendedProductList = List(); - List get recommendedList => _recommendedProductList; - String url =""; +// List> _recommendedProductList =[]; +// List> get recommendedList => _recommendedProductList; + + List _recommendedProductList =[]; + List get recommendedList => _recommendedProductList; Future getRecommendedProducts(productId) async { + var customerId = await sharedPref.getString(PHARMACY_CUSTOMER_ID); hasError = false; - url =GET_RECOMMENDED_PRODUCT+productId; - await baseAppClient.getPharmacy(url, + + await baseAppClient.getPharmacy(GET_RECOMMENDED_PRODUCT+"$productId/$customerId", onSuccess: (dynamic response, int statusCode) { _recommendedProductList.clear(); response['products'].forEach((item) { - _recommendedProductList.add(Products.fromJson(item)); - print("----------------------------------"); - print("Test data"); - print(_recommendedProductList[0]); - print(item['name']); - print(response); +// _recommendedProductList.add(item); + _recommendedProductList.add(RecommendedProductModel.fromJson(item)); + }); + //print(item['name']); + print(response); }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; diff --git a/lib/services/pharmacy_services/review_service.dart b/lib/services/pharmacy_services/review_service.dart index 44839955..43d5b8d5 100644 --- a/lib/services/pharmacy_services/review_service.dart +++ b/lib/services/pharmacy_services/review_service.dart @@ -1,10 +1,10 @@ import 'package:diplomaticquarterapp/config/config.dart'; +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/pharmacy/reviewModel.dart'; import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; -import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; class ReviewService extends BaseService { @@ -14,7 +14,7 @@ class ReviewService extends BaseService { AuthProvider authProvider = new AuthProvider(); bool isLogin = false; - List _reviewList = List(); + List _reviewList =[]; List get reviewList => _reviewList; diff --git a/lib/services/pharmacy_services/wishList_service.dart b/lib/services/pharmacy_services/wishList_service.dart index 5404a2bd..64db972b 100644 --- a/lib/services/pharmacy_services/wishList_service.dart +++ b/lib/services/pharmacy_services/wishList_service.dart @@ -1,18 +1,14 @@ import 'package:diplomaticquarterapp/config/config.dart'; 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/pharmacy/Wishlist.dart'; -import 'package:diplomaticquarterapp/models/pharmacy/products.dart'; -import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; -import 'package:flutter/material.dart'; - class WishListService extends BaseService { AppSharedPreferences sharedPref = AppSharedPreferences(); bool isLogin = false; - List _wishListProducts = List(); + List _wishListProducts =[]; + List get wishListProducts => _wishListProducts; // Future getWishlist() async { @@ -55,18 +51,18 @@ class WishListService extends BaseService { // } Future getWishlist() async { - var customerId = await sharedPref.getString(PHARMACY_CUSTOMER_ID); + //TODO we need to check why the customer id comes null + String customerId = await sharedPref.getString(PHARMACY_CUSTOMER_ID) ?? "0"; + var customerGUID = await sharedPref.getObject(PHARMACY_CUSTOMER_GUID); hasError = false; - await baseAppClient.getPharmacy(GET_WISHLIST+customerId+"?shopping_cart_type=2", - onSuccess: (dynamic response, int statusCode) { - _wishListProducts.clear(); - response['shopping_carts'].forEach((item) { - _wishListProducts.add(Wishlist.fromJson(item)); - }); - }, onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }); + await baseAppClient.getPharmacy(GET_WISHLIST + customerId + "/$customerGUID/" + "?shopping_cart_type=2", onSuccess: (dynamic response, int statusCode) { + _wishListProducts.clear(); + response['shopping_carts'].forEach((item) { + _wishListProducts.add(Wishlist.fromJson(item)); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }); } - } diff --git a/lib/services/pharmacy_services/writeReview_service.dart b/lib/services/pharmacy_services/writeReview_service.dart index 573095eb..97495e99 100644 --- a/lib/services/pharmacy_services/writeReview_service.dart +++ b/lib/services/pharmacy_services/writeReview_service.dart @@ -1,12 +1,10 @@ import 'package:diplomaticquarterapp/config/config.dart'; -import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/order_model.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; -import 'package:flutter/material.dart'; class writeReviewService extends BaseService{ @@ -20,7 +18,7 @@ class writeReviewService extends BaseService{ AuthProvider authProvider = new AuthProvider(); List get writeReview => writeReview; - List _writeReviewList = List(); + List _writeReviewList =[]; List get orderList => _writeReviewList; diff --git a/lib/services/smartwatch_integration/SmartWatchIntegrationService.dart b/lib/services/smartwatch_integration/SmartWatchIntegrationService.dart index 3bfe62e3..6c316f7f 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,16 +19,13 @@ 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; } - 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, @@ -42,13 +40,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/lib/splashPage.dart b/lib/splashPage.dart index ef5db7f5..3d9b2927 100644 --- a/lib/splashPage.dart +++ b/lib/splashPage.dart @@ -1,23 +1,32 @@ import 'dart:async'; +import 'dart:convert'; +import 'dart:io'; + +import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/SearchResultsByRegion.dart'; import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; +import 'package:diplomaticquarterapp/theme/theme_notifier.dart'; +import 'package:diplomaticquarterapp/theme/theme_value.dart'; +import 'package:diplomaticquarterapp/uitl/LocalNotification.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; +import 'package:diplomaticquarterapp/uitl/push-notification-handler.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +import 'package:firebase_crashlytics/firebase_crashlytics.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:flutter_zoom_videosdk/native/zoom_videosdk.dart'; import 'package:provider/provider.dart'; -import 'config/shared_pref_kay.dart'; -import 'config/size_config.dart'; import 'core/service/AuthenticatedUserObject.dart'; import 'core/service/privilege_service.dart'; import 'core/viewModels/project_view_model.dart'; import 'locator.dart'; -import 'models/Authentication/authenticated_user.dart'; -import 'widgets/transitions/slide_up_page.dart'; AppSharedPreferences sharedPref = new AppSharedPreferences(); -AuthenticatedUserObject authenticatedUserObject = - locator(); +AuthenticatedUserObject authenticatedUserObject = locator(); class SplashScreen extends StatefulWidget { @override @@ -26,38 +35,113 @@ class SplashScreen extends StatefulWidget { class _SplashScreenState extends State { PrivilegeService _privilegeService = locator(); + @override void initState() { + AppGlobal.context = context; super.initState(); + print("Splash init called............."); Timer( Duration(seconds: 1, milliseconds: 500), - () { - loadPrivilege().then((value) { - Navigator.of(context).pushReplacement( - MaterialPageRoute( - builder: (BuildContext context) => LandingPage(), - ), - ); + () async { + await loadPrivilege().then((value) { + LocalNotification.init(onNotificationClick: (payload) {}); + // LocalNotification.getInstance().showNow(title: "Payload", subtitle: "Subtitle", payload: "Payload"); + if (!_privilegeService.hasError) { + Navigator.of(context).pushReplacement( + MaterialPageRoute( + builder: (BuildContext context) => LandingPage(), + ), + ); + } else {} }); }, ); + + var zoom = ZoomVideoSdk(); + InitConfig initConfig = InitConfig( + domain: "zoom.us", + enableLog: true, + ); + zoom.initSdk(initConfig); + + // AppSharedPreferences().getAll().then((value) { + // debugPrint("ALL SHARED PREFERENCES!!!!!"); + // debugPrint(jsonEncode(value)); + // }); } /// load the Privilege from service Future loadPrivilege() async { await _privilegeService.getPrivilege(); - Provider.of(context, listen: false) - .setPrivilegeModelList(privilege: _privilegeService.privilegeModelList); + ProjectViewModel projectProvider = Provider.of(context, listen: false); + projectProvider.setPrivilegeModelList(privilege: _privilegeService.privilegeModelList); + projectProvider.setVidaPlusProjectList(_privilegeService.vidaPlusProjectListModel); + projectProvider.setHMCProjectList(_privilegeService.hMCProjectListModel); + projectProvider.setProjectsDetailList(_privilegeService.projectDetailListModel); + double lat = await AppSharedPreferences().getDouble(USER_LAT) ?? 0.0; + double long = await AppSharedPreferences().getDouble(USER_LONG) ?? 0.0; + AppSharedPreferences().clear(); // Clearing Shared Preferences On App Launch + await AppSharedPreferences().setDouble(USER_LAT, lat); + await AppSharedPreferences().setDouble(USER_LONG, long); + AppSharedPreferences().setString(APP_LANGUAGE, projectProvider.isArabic ? "ar" : "en"); + var themeNotifier = Provider.of(context, listen: false); + themeNotifier.setTheme(defaultTheme(fontName: projectProvider.isArabic ? 'Cairo' : 'Poppins')); + PushNotificationHandler().init(context); // Asyncronously + AppSharedPreferences().getAll().then((value) { + // debugPrint("ALL SHARED PREFERENCES!!!!!"); + // debugPrint(jsonEncode(value)); + }); + // if (!kDebugMode) await FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled(true); + // PushNotificationHandler(context).init(); // Asyncronously } @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: Colors.white, - body: Image.asset( - 'assets/images/powerd-by.jpg', - fit: BoxFit.fitWidth, - width: MediaQuery.of(context).size.width, + backgroundColor: Color(0xffF8F8F8), + body: Stack( + alignment: Alignment.center, + children: [ + Padding( + padding: EdgeInsets.symmetric(horizontal: 53), + child: Image.asset( + 'assets/images/new/hmg_logo.png', + fit: BoxFit.fitWidth, + width: MediaQuery.of(context).size.width, + ), + ), + Align( + alignment: Alignment.bottomCenter, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + TranslationBase.of(context).poweredBy, + style: TextStyle(fontSize: 14, fontWeight: FontWeight.w400, color: Color(0xff333C45), letterSpacing: -0.56, height: 16 / 14), + ), + SizedBox( + height: 5, + ), + SvgPicture.asset( + 'assets/images/new/cloud_logo.svg', + width: 40, + height: 40, + ), + SizedBox( + height: 7, + ), + // Text( + // "Version 1.1.0", + // style: TextStyle(fontSize: 10, fontWeight: FontWeight.w400, color: Color(0xff3989898), letterSpacing: 0, height: 12 / 10), + // ), + SizedBox( + height: 18, + ) + ], + ), + ) + ], ), ); } diff --git a/lib/theme/colors.dart b/lib/theme/colors.dart index 893449f1..a9d4e437 100644 --- a/lib/theme/colors.dart +++ b/lib/theme/colors.dart @@ -5,7 +5,24 @@ class CustomColors { static const Color purple = Color(0xFF6002EE); static const Color deepPurple = Color(0xFF3900B1); static const Color grey = Color(0xFF848484); + static const Color textColor = Color(0xFF575757); + static const Color grey2 = Color(0xFFA5A5A5); static const Color darkGrey = Color(0xFF222222); static const Color black = Color(0xFF141414); static const Color white = Color(0xFFFFFFFF); + static const Color accentColor = Color(0xFFD02127); + static const Color lightGreyColor = Color(0xFFE2E2E2); + static const Color devider = Color(0xFFE5E5E5); + static const Color darkGreyColor = Color(0xFFC9C9C9); + static const Color textDarkColor = Color(0xFF2E303A); + static const Color pharmacyGreyColor = Color(0xFFDBDBDB); + static const Color backgroudGreyColor = Color(0xFFEFEFEF); + static const Color appBackgroudGreyColor = Color(0xFFF7F7F7); + static const Color appBackgroudGrey2Color = Color(0xFFF8F8F8); + static const Color green = Color(0xFF359846); + static const Color orange = Color(0xFFCC9B14); + static const Color darkOrange = Color(0xFFE16F17); + + static const Color femaleColor = Color(0xFF359846); + static const Color maleColor = Color(0xFFCC9B14); } diff --git a/lib/theme/theme_notifier.dart b/lib/theme/theme_notifier.dart index e61c73a6..9ad15f33 100644 --- a/lib/theme/theme_notifier.dart +++ b/lib/theme/theme_notifier.dart @@ -1,8 +1,4 @@ -import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; -import 'package:diplomaticquarterapp/theme/theme_value.dart'; import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:diplomaticquarterapp/config/config.dart'; class ThemeNotifier with ChangeNotifier { ThemeData _themeData; diff --git a/lib/theme/theme_value.dart b/lib/theme/theme_value.dart index 65d6f81d..4fd06d9c 100644 --- a/lib/theme/theme_value.dart +++ b/lib/theme/theme_value.dart @@ -1,22 +1,22 @@ -import 'dart:ui'; + import 'package:diplomaticquarterapp/Constants.dart'; -import 'package:diplomaticquarterapp/config/config.dart'; import 'package:flutter/material.dart'; -import 'package:hexcolor/hexcolor.dart'; -import 'package:provider/provider.dart'; +import 'package:flutter/services.dart'; /// ---- Default Theme ---- /// //final projectProvider = Provider.of(AppGlobal.context); -final bluePrimary = Color(0xFF3F51B5); +final bluePrimary = Color(0xFF00000); final blueAccent = Color(0xFFFF9800); final blueBackground = Color(0xFFFFFFFF); + defaultTheme({fontName}) { return ThemeData( - fontFamily: fontName, //projectProvider.isArabic ? 'Cairo' : 'WorkSans', - - primarySwatch: Colors.blue, + fontFamily: fontName, + useMaterial3: false, + //projectProvider.isArabic ? 'Cairo' : 'WorkSans', + primarySwatch: Colors.red, visualDensity: VisualDensity.adaptivePlatformDensity, brightness: Brightness.light, pageTransitionsTheme: const PageTransitionsTheme( @@ -27,45 +27,41 @@ defaultTheme({fontName}) { ), hintColor: Colors.grey[400], disabledColor: Colors.grey[300], - errorColor: Color.fromRGBO(235, 80, 60, 1.0), - scaffoldBackgroundColor: Color(0xffE9E9E9), // Colors.grey[100], - textSelectionColor: Color.fromRGBO(80, 100, 253, 0.5), - textSelectionHandleColor: Colors.grey, + // errorColor: Color.fromRGBO(235, 80, 60, 1.0), + scaffoldBackgroundColor: Color(0xffF8F8F8), canvasColor: Colors.white, - backgroundColor: Color.fromRGBO(255, 255, 255, 1), - highlightColor: Colors.grey[100].withOpacity(0.4), + // backgroundColor: Color.fromRGBO(255, 255, 255, 1), + highlightColor: Colors.grey[100]!.withOpacity(0.4), splashColor: Colors.transparent, primaryColor: Color(0xff515A5D), - buttonColor: Colors.black, - toggleableActiveColor: secondaryColor, + // toggleableActiveColor: secondaryColor, indicatorColor: secondaryColor, - bottomSheetTheme: - BottomSheetThemeData(backgroundColor: HexColor('#E0E0E0')), - cursorColor: Colors.grey, - primaryTextTheme: TextTheme(bodyText2: TextStyle(color: Colors.white)), + bottomSheetTheme: BottomSheetThemeData(backgroundColor: Color(0xFFE0E0E0)), + // primaryTextTheme: TextTheme(bodyText2: TextStyle(color: Colors.white)), iconTheme: IconThemeData(), textTheme: TextTheme( - bodyText1: TextStyle(color: Colors.black), - headline1: TextStyle(color: Colors.white), - headline2: TextStyle(color: Colors.white)), + // bodyText1: TextStyle(color: Colors.black, letterSpacing: 0.6), + // headline1: TextStyle(color: Colors.white, letterSpacing: 0.6), + // headline2: TextStyle(color: Colors.white, letterSpacing: 0.6), + ), floatingActionButtonTheme: FloatingActionButtonThemeData(highlightElevation: 2, disabledElevation: 0, elevation: 2), appBarTheme: AppBarTheme( color: Color(0xff515A5D), - brightness: Brightness.light, elevation: 0.0, actionsIconTheme: IconThemeData( color: Colors.grey[800], - ), - ), + ), systemOverlayStyle: SystemUiOverlayStyle.dark, + ), textSelectionTheme: TextSelectionThemeData(cursorColor: Colors.grey, selectionColor: Color.fromRGBO(80, 100, 253, 0.5), selectionHandleColor: Colors.grey,), ); } invertThemes({fontName}) { return ThemeData( - fontFamily: fontName, //projectProvider.isArabic ? 'Cairo' : 'WorkSans', - primarySwatch: Colors.blue, - + fontFamily: fontName, + //projectProvider.isArabic ? 'Cairo' : 'WorkSans', + primarySwatch: Colors.red, + useMaterial3: false, visualDensity: VisualDensity.adaptivePlatformDensity, brightness: Brightness.dark, pageTransitionsTheme: const PageTransitionsTheme( @@ -75,43 +71,35 @@ invertThemes({fontName}) { }, ), hintColor: Colors.grey[400], - textTheme: TextTheme( - bodyText1: TextStyle(color: Colors.white), - headline1: TextStyle(color: Colors.white), - headline2: TextStyle(color: Colors.white)), + // textTheme: TextTheme(bodyText1: TextStyle(color: Colors.white), headline1: TextStyle(color: Colors.white), headline2: TextStyle(color: Colors.white)), disabledColor: Colors.grey[800], - errorColor: Color.fromRGBO(235, 80, 60, 1.0), - scaffoldBackgroundColor: Color(0xff000000), // Colors.grey[100], - textSelectionColor: Color.fromRGBO(80, 100, 253, 0.5), - textSelectionHandleColor: Colors.grey, + // errorColor: Color.fromRGBO(235, 80, 60, 1.0), + scaffoldBackgroundColor: Color(0xff000000), canvasColor: Colors.black, - backgroundColor: Color.fromRGBO(255, 255, 255, 1), - highlightColor: Colors.grey[100].withOpacity(0.4), + // backgroundColor: Color.fromRGBO(255, 255, 255, 1), + highlightColor: Colors.grey[100]!.withOpacity(0.4), splashColor: Colors.transparent, primaryColor: Color(0xff515A5D), - buttonColor: Colors.black, - toggleableActiveColor: secondaryColor, + // toggleableActiveColor: secondaryColor, indicatorColor: secondaryColor, - bottomSheetTheme: - BottomSheetThemeData(backgroundColor: HexColor('#E0E0E0')), - cursorColor: Colors.black, + bottomSheetTheme: BottomSheetThemeData(backgroundColor: Color(0xFFE0E0E0)), iconTheme: IconThemeData(), appBarTheme: AppBarTheme( color: Color(0xff000000), - brightness: Brightness.dark, elevation: 0.0, actionsIconTheme: IconThemeData( color: Colors.grey[800], - ), - ), + ), systemOverlayStyle: SystemUiOverlayStyle.light, + ), textSelectionTheme: TextSelectionThemeData(cursorColor: Colors.black, selectionColor: Color.fromRGBO(80, 100, 253, 0.5), selectionHandleColor: Colors.grey,), ); } bwThemes({fontName}) { return ThemeData( - fontFamily: fontName, //projectProvider.isArabic ? 'Cairo' : 'WorkSans', - primarySwatch: Colors.blue, - + fontFamily: fontName, + //projectProvider.isArabic ? 'Cairo' : 'WorkSans', + primarySwatch: Colors.red, + useMaterial3: false, visualDensity: VisualDensity.adaptivePlatformDensity, brightness: Brightness.dark, unselectedWidgetColor: Colors.red, @@ -125,49 +113,45 @@ bwThemes({fontName}) { hintColor: Colors.grey[400], textTheme: TextTheme( - bodyText1: TextStyle(color: Colors.red[900]), - headline1: TextStyle(color: Colors.red[900]), - headline2: TextStyle(color: Colors.white), - bodyText2: TextStyle(color: Colors.red[900]), - subtitle1: TextStyle(color: Colors.red[900]), + // bodyText1: TextStyle(color: Colors.red[900]), + // headline1: TextStyle(color: Colors.red[900]), + // headline2: TextStyle(color: Colors.white), + // bodyText2: TextStyle(color: Colors.red[900]), + // subtitle1: TextStyle(color: Colors.red[900]), ), tabBarTheme: TabBarTheme(labelColor: Colors.red[900]), disabledColor: Colors.grey[800], - errorColor: Color.fromRGBO(235, 80, 60, 1.0), - scaffoldBackgroundColor: Color(0xffffffe4), // Colors.grey[100], - textSelectionColor: Color.fromRGBO(80, 100, 253, 0.5), - textSelectionHandleColor: Colors.grey, + // errorColor: Color.fromRGBO(235, 80, 60, 1.0), + scaffoldBackgroundColor: Color(0xffffffe4), canvasColor: Colors.black, - backgroundColor: Color(0xffffffe4), - highlightColor: Colors.grey[100].withOpacity(0.4), + // backgroundColor: Color(0xffffffe4), + highlightColor: Colors.grey[100]!.withOpacity(0.4), splashColor: Colors.transparent, primaryColor: Color(0xfffffff4), - toggleableActiveColor: secondaryColor, + // toggleableActiveColor: secondaryColor, indicatorColor: secondaryColor, - bottomSheetTheme: - BottomSheetThemeData(backgroundColor: HexColor('#E0E0E0')), - cursorColor: Colors.black, + bottomSheetTheme: BottomSheetThemeData(backgroundColor: Color(0xFFE0E0E0)), iconTheme: IconThemeData(), appBarTheme: AppBarTheme( color: Color(0xffffffe4), - brightness: Brightness.dark, elevation: 0.0, actionsIconTheme: IconThemeData( color: Colors.grey[800], - ), - ), + ), systemOverlayStyle: SystemUiOverlayStyle.light, + ), textSelectionTheme: TextSelectionThemeData(cursorColor: Colors.black, selectionColor: Color.fromRGBO(80, 100, 253, 0.5), selectionHandleColor: Colors.grey,), ); } dimTheme({fontName}) { return ThemeData( - fontFamily: fontName, //projectProvider.isArabic ? 'Cairo' : 'WorkSans', - primarySwatch: Colors.blue, + fontFamily: fontName, + //projectProvider.isArabic ? 'Cairo' : 'WorkSans', + primarySwatch: Colors.red, visualDensity: VisualDensity.adaptivePlatformDensity, brightness: Brightness.dark, - + useMaterial3: false, pageTransitionsTheme: const PageTransitionsTheme( builders: { TargetPlatform.android: ZoomPageTransitionsBuilder(), @@ -176,25 +160,21 @@ dimTheme({fontName}) { ), hintColor: Colors.grey[400], disabledColor: Colors.grey[300], - errorColor: Color.fromRGBO(235, 80, 60, 1.0), + // errorColor: Color.fromRGBO(235, 80, 60, 1.0), scaffoldBackgroundColor: Color(0xffEEEEEE), - textSelectionColor: Color.fromRGBO(80, 100, 253, 0.5), - textSelectionHandleColor: Colors.grey, canvasColor: Colors.white, - backgroundColor: Color.fromRGBO(255, 255, 255, 1), - highlightColor: Colors.grey[100].withOpacity(0.4), + // backgroundColor: Color.fromRGBO(255, 255, 255, 1), + highlightColor: Colors.grey[100]!.withOpacity(0.4), splashColor: Colors.transparent, primaryColor: Color(0xff40ACC9), bottomSheetTheme: BottomSheetThemeData(backgroundColor: Color(0xffE0E0E0)), - cursorColor: Colors.grey, iconTheme: IconThemeData(), appBarTheme: AppBarTheme( color: Color(0xff40ACC9), - brightness: Brightness.dark, elevation: 10.0, actionsIconTheme: IconThemeData( color: Color(0xff40ACC9), - ), - ), + ), systemOverlayStyle: SystemUiOverlayStyle.light, + ), textSelectionTheme: TextSelectionThemeData(cursorColor: Colors.grey, selectionColor: Color.fromRGBO(80, 100, 253, 0.5), selectionHandleColor: Colors.grey,), ); } diff --git a/lib/uitl/CalendarUtils.dart b/lib/uitl/CalendarUtils.dart index 546d9b2d..f7fdda41 100644 --- a/lib/uitl/CalendarUtils.dart +++ b/lib/uitl/CalendarUtils.dart @@ -1,51 +1,91 @@ import 'dart:async'; +import 'dart:convert'; +import 'dart:io'; import 'dart:ui'; import 'package:device_calendar/device_calendar.dart'; +import 'package:manage_calendar_events/manage_calendar_events.dart' as ios; +import 'package:timezone/data/latest.dart' as tzl; final DeviceCalendarPlugin deviceCalendarPlugin = DeviceCalendarPlugin(); +final ios.CalendarPlugin _myPlugin = ios.CalendarPlugin(); class CalendarUtils { - static Completer _completer; + static Completer? _completer; - Calendar get writableCalendars => calendars?.firstWhere((c) => !c.isReadOnly); - List calendars; + dynamic get writableCalendars => calendars.firstWhere((c) => !c.isReadOnly!); + dynamic calendars; CalendarUtils._(this.calendars); + // static Future getInstance() async { + // if (_completer == null) { + // _completer = Completer(); + // print(_completer!.isCompleted); + // try { + // final dynamic calendarsResult; + // if (Platform.isIOS) { + // calendarsResult = await _myPlugin.getCalendars(); + // if (!_completer!.isCompleted) { + // _completer?.complete(CalendarUtils._(await calendarsResult!)); + // } + // } else { + // calendarsResult = await deviceCalendarPlugin.retrieveCalendars(); + // if (!_completer!.isCompleted) { + // _completer?.complete(CalendarUtils._(await calendarsResult.data!)); + // } + // } + // } on Exception catch (e) { + // if (!_completer!.isCompleted) { + // _completer!.completeError(e); + // } + // } + // } + // return _completer!.future; + // } + static Future getInstance() async { - if (_completer == null) { - _completer = Completer(); - try { - final calendarsResult = await deviceCalendarPlugin.retrieveCalendars(); - _completer.complete(CalendarUtils._(calendarsResult?.data)); - } on Exception catch (e) { - _completer.completeError(e); - final Future sharedPrefsFuture = _completer.future; - _completer = null; - return sharedPrefsFuture; + tzl.initializeTimeZones(); + if (_completer != null) { + return _completer!.future; + } + _completer = Completer(); + try { + final dynamic calendarsResult; + if (Platform.isIOS) { + calendarsResult = await _myPlugin.getCalendars(); + _completer!.complete(CalendarUtils._(calendarsResult)); + } else { + calendarsResult = await deviceCalendarPlugin.retrieveCalendars(); + _completer!.complete(CalendarUtils._(calendarsResult.data)); } + } catch (e) { + _completer!.completeError(e); } - return _completer.future; + + return _completer!.future; } - Future createOrUpdateEvents( - {List scheduleList, - String title, - String description, - List scheduleDateTime, - List daysOfWeek}) async { - List events = List(); - scheduleDateTime.forEach((element) { + Future createOrUpdateEvents({List? scheduleList, String? title, String? description, List? scheduleDateTime, List? daysOfWeek}) async { + tzl.initializeTimeZones(); + List events = []; + Location _currentLocation; + if (DateTime.now().timeZoneName == "+04") + _currentLocation = getLocation('Asia/Dubai'); + else + _currentLocation = getLocation('Asia/Riyadh'); + + scheduleDateTime!.forEach((element) { RecurrenceRule recurrenceRule = RecurrenceRule( RecurrenceFrequency.Daily, daysOfWeek: daysOfWeek, endDate: element, ); - Event event = Event(writableCalendars.id, + //added byAamir Tz Time + Event event = Event(writableCalendars!.id, recurrenceRule: recurrenceRule, - start: element, - end: element.add(Duration(minutes: 30)), + start: TZDateTime.from(element, _currentLocation), + end: TZDateTime.from(element.add(Duration(minutes: 30)), _currentLocation), title: title, description: description); events.add(event); @@ -54,26 +94,81 @@ class CalendarUtils { events.forEach((element) { deviceCalendarPlugin.createOrUpdateEvent(element); }); + } + + Future createOrUpdateEvent({required String title, required String description, DateTime? scheduleDateTime, String? eventId}) async { + RecurrenceRule recurrenceRule = RecurrenceRule( + RecurrenceFrequency.Daily, + // daysOfWeek: daysOfWeek, + endDate: scheduleDateTime, + ); + + Location _currentLocation; + if (DateTime.now().timeZoneName == "+04") + _currentLocation = getLocation('Asia/Dubai'); + else + _currentLocation = getLocation('Asia/Riyadh'); + + TZDateTime scheduleDateTimeUTZ = TZDateTime.from(scheduleDateTime!, _currentLocation); + + print("writableCalendars-name: " + writableCalendars.name); + print("writableCalendars-Id: " + writableCalendars.id); + print("writableCalendarsToString: " + writableCalendars.toString()); + print("writableCalendarsToString: " + writableCalendars!.id!); + Event event = Event( + writableCalendars!.id, + start: scheduleDateTimeUTZ, + end: scheduleDateTimeUTZ.add(Duration(minutes: 30)), + title: title, + description: description, + ); + + ios.CalendarEvent iosCalEvent = + ios.CalendarEvent(eventId: eventId, startDate: scheduleDateTimeUTZ, endDate: scheduleDateTimeUTZ.add(Duration(minutes: 30)), title: title, description: description, isAllDay: false); + + if(Platform.isAndroid) { + Result result = await deviceCalendarPlugin.hasPermissions(); + print(result); + await deviceCalendarPlugin.createOrUpdateEvent(event).catchError((e) { + print("catchError " + e.toString()); + }).whenComplete(() { + print("whenComplete Calender ID " + eventId!); + }); + } else { + // Result result = await deviceCalendarPlugin.hasPermissions(); + // print(result); + await _myPlugin.createEvent(calendarId: writableCalendars.id!, event: iosCalEvent).catchError((e) { + print("catchError " + e.toString()); + }).whenComplete(() { + print("whenComplete Calender ID iOS " + eventId!); + }); + } + + + + } deleteEvent(Calendar _calendar, Event _event) async { - await deviceCalendarPlugin.deleteEvent(_calendar.id, _event.eventId); + if (Platform.isIOS) { + await _myPlugin.deleteEvent(calendarId: _calendar.id!, eventId: _event.eventId!); + } else { + await deviceCalendarPlugin.deleteEvent(_calendar.id, _event.eventId); + } } Future retrieveEvents( String calendarId, RetrieveEventsParams retrieveEventsParams, ) async { - return await deviceCalendarPlugin.retrieveEvents( - calendarId, retrieveEventsParams); + return await deviceCalendarPlugin.retrieveEvents(calendarId, retrieveEventsParams); } Future createCalendar( String calendarName, { - Color calendarColor, - String localAccountName, + Color? calendarColor, + String? localAccountName, }) async { - return await deviceCalendarPlugin.createCalendar(calendarName, - calendarColor: calendarColor, localAccountName: localAccountName); + return await deviceCalendarPlugin.createCalendar(calendarName, calendarColor: calendarColor, localAccountName: localAccountName); } } diff --git a/lib/uitl/DeepLinkHandler.dart b/lib/uitl/DeepLinkHandler.dart new file mode 100644 index 00000000..9f46242b --- /dev/null +++ b/lib/uitl/DeepLinkHandler.dart @@ -0,0 +1,100 @@ +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; +import 'package:diplomaticquarterapp/uitl/penguin_method_channel.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +import 'package:flutter/material.dart'; +import 'package:permission_handler/permission_handler.dart'; +import 'package:provider/provider.dart'; + +import '../pages/BookAppointment/Search.dart'; +import 'app-permissions.dart'; + +enum DeepLinkNavigation { + APPOINTMENT("/appointment", false), + LIVE_CARE("/livecare", true), + NAVIGATE("/navigate", false); + + final String name; + final bool isLoginRequired; + + const DeepLinkNavigation(this.name, this.isLoginRequired); +} + +class DeepLinkHandler { + final projectID = "projectID"; + final clinicId = "clinicId"; + + DeepLinkNavigation? navigationType; + Uri? uri; + + DeepLinkHandler._(); + + static final DeepLinkHandler _instance = DeepLinkHandler._(); + + static DeepLinkHandler get instance => _instance; + + void handleDeepLinkAndNavigation( + NavigatorState? currentState, Uri uri, BuildContext context) async { + var url = uri.toString().replaceFirst( + "https://hmg.com/Pages/PageNotFoundError.aspx?requestUrl=", ""); + + uri = Uri.parse(url); + this.uri = uri; + print( + "the uri contains ${uri.path.toLowerCase() == DeepLinkNavigation.NAVIGATE.name}"); + print("the uri.path ${uri.path}"); + if (uri.path.toLowerCase() == DeepLinkNavigation.NAVIGATE.name) { + await Future.delayed(Duration(seconds: 1)); + navigationType = DeepLinkNavigation.NAVIGATE; + var queryParam = uri.queryParameters; + print("the query params are $queryParam"); + initPenguinSDK( + queryParam[projectID] ?? "", queryParam[clinicId] ?? "", context); + removeDeepLinkData(); + return; + } + if (uri.path.toLowerCase() == DeepLinkNavigation.APPOINTMENT.name) { + navigationType = DeepLinkNavigation.NAVIGATE; + currentState?.push(FadePage(page: Search())); + removeDeepLinkData(); + return; + } + if (uri.path.toLowerCase() == DeepLinkNavigation.LIVE_CARE.name) { + var viewModel = Provider.of(context); + if (viewModel.isLogin) { + currentState?.push(FadePage(page: Search())); + removeDeepLinkData(); + return; + } else {} + } + } + + void removeDeepLinkData() { + navigationType = null; + uri = null; + } + + initPenguinSDK( + String projectId, String clinicID, BuildContext context) async { + AppSharedPreferences sharedPref = AppSharedPreferences(); + NavigationClinicDetails data = NavigationClinicDetails(); + data.clinicId = clinicID; + + data.projectId = projectId; + final bool permited = await AppPermission.askPenguinPermissions(); + if (!permited) { + Map statuses = await [ + Permission.location, + Permission.bluetooth, + Permission.bluetoothConnect, + Permission.bluetoothScan, + Permission.activityRecognition, + ].request().whenComplete(() async { + final currentLanguage = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + PenguinMethodChannel() + .launch("penguin", currentLanguage, "null", details: data); + }); + } + } +} diff --git a/lib/uitl/HMGNetworkConnectivity.dart b/lib/uitl/HMGNetworkConnectivity.dart index c4044573..9ef3ce67 100644 --- a/lib/uitl/HMGNetworkConnectivity.dart +++ b/lib/uitl/HMGNetworkConnectivity.dart @@ -2,129 +2,147 @@ import 'dart:developer'; import 'dart:io'; import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/service/client/base_app_client.dart'; -import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/locator.dart'; +import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/uitl/PlatformBridge.dart'; +import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/alert_dialog.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:wifi/wifi.dart'; +// import 'package:wifi/wifi.dart'; import 'gif_loader_dialog_utils.dart'; class HMGNetworkConnectivity { + final _platformBridge = PlatformBridge.shared(); final BuildContext context; - final Function callBack; + late Function callBack; - final String SSID = "HMG-MobileApp"; + final String GUEST_SSID = "HMG-MobileApp"; + final String PATIENT_SSID = "GUEST-POC"; - HMGNetworkConnectivity(this.context, this.callBack); + HMGNetworkConnectivity(this.context); + + late AuthenticatedUser userData; + + start() { + // getUserData().then((value) { + // userData = value; + // checkAndConnectIfNoInternet(); + // }); + } void checkAndConnectIfNoInternet() async { + // getMyWifiCredentials((username, password){ + // print(""); + // }); + // + // return; + String pingUrl = "$BASE_URL$PING_SERVICE"; // pingUrl = "https://captive.apple.com"; - String ssid = await Wifi.ssid.catchError((error) { - log(error.toString()); - }); - - bool alreadyConnected = ssid == SSID; - - BaseAppClient().simpleGet(pingUrl, onSuccess: (dynamic response, int statusCode) { - log("Having internet with status code: $statusCode"); - }, onFailure: (String error, int statusCode) { - if (alreadyConnected) - showFailDailog(TranslationBase.of(context).failedToAccessHmgServices); - else { - confirmFromUser(); + // String ssid = await Wifi.ssid.catchError((error) { + // log(error.toString()); + // }); + + // bool alreadyConnected = ssid == GUEST_SSID; + + // BaseAppClient().simpleGet(pingUrl, onSuccess: (dynamic response, int statusCode) { + // log("Having internet with status code: $statusCode"); + // }, onFailure: (String error, int statusCode) { + // if (alreadyConnected) + // showFailDailog(TranslationBase.of(context).failedToAccessHmgServices); + // else { + // confirmFromUser(connectForLocalAccess); + // } + // }); + // } + + void confirmFromUser(VoidCallback confirmCallback) { + TranslationBase translator = TranslationBase.of(context); + + void doIt() { + ConfirmDialog( + context: context, + confirmMessage: translator.wantToConnectWithHmgNetwork, + okText: translator.yes, + okFunction: () { + // ConfirmDialog.closeAlertDialog(context); + confirmCallback(); + }, + cancelText: translator.no, + cancelFunction: () { + ConfirmDialog.closeAlertDialog(context); + }).showAlertDialog(context); } - }); - } - void confirmFromUser() { - TranslationBase translator = TranslationBase.of(context); + // if (Platform.isAndroid) + // Wifi.list(GUEST_SSID).then((value) { + // if (!value.indexWhere((element) => element.ssid == GUEST_SSID).isNegative) doIt(); + // }); + // else + // doIt(); + } - void doIt() { - ConfirmDialog( + void showFailDailog(String message) { + TranslationBase translator = TranslationBase.of(context); + AlertDialogBox( context: context, - confirmMessage: translator.wantToConnectWithHmgNetwork, - okText: translator.yes, + okText: translator.ok, + confirmMessage: message, okFunction: () { - ConfirmDialog.closeAlertDialog(context); - callBack(); - }, - cancelText: translator.no, - cancelFunction: () { - ConfirmDialog.closeAlertDialog(context); + AlertDialogBox.closeAlertDialog(context); }).showAlertDialog(context); } - if (Platform.isAndroid) - Wifi.list(SSID).then((value) { - if (!value.indexWhere((element) => element.ssid == SSID).isNegative) doIt(); + Future getUserData() async { + var userData = AuthenticatedUser.fromJson( + await AppSharedPreferences().getObject(MAIN_USER)); + return userData; + } + + connectForLocalAccess() { + String patientID = userData.patientID.toString(); + GifLoaderDialogUtils.showMyDialog(context); + _platformBridge.connectHMGGuestWifi(GUEST_SSID).then((value) async { + if (value == 0) { + GifLoaderDialogUtils.hideDialog(context); + } else { + // getPatientWifiCredentials(patientID, (username, password) async { + // final result = await _platformBridge.connectHMGInternetWifi(PATIENT_SSID, username, password).catchError((err) => print(err.toString())); + // GifLoaderDialogUtils.hideDialog(context); + // if (result == 1) { + // // Success + // } + // }); + } }); - else - doIt(); - } + } + // + // getPatientWifiCredentials(String patientID, Function(String username, String password) successCallback) { + // final body = {"PatientID": patientID}; + // locator().post(WIFI_CREDENTIALS, body: body, onSuccess: (dynamic response, int statusCode) { + // print(response); + // var data = response["Hmg_SMS_Get_By_ProjectID_And_PatientIDList"]; + // if (data is List && data.first != null) { + // final username = data.first['UserName']; + // final password = data.first['Password']; + // if (username != null && password != null && username.isNotEmpty && password.isNotEmpty) { + // successCallback(username, password); + // } + // } + // }, onFailure: (String error, int statusCode) { + // print(error); + // }, bypassConnectionCheck: true); + // } + // - void showFailDailog(String message) { - TranslationBase translator = TranslationBase.of(context); - AlertDialogBox( - context: context, - okText: translator.ok, - confirmMessage: message, - okFunction: () { - AlertDialogBox.closeAlertDialog(context); - }).showAlertDialog(context); - } - // void next() { - // if (Platform.isIOS) { - // confirmFromUser_iOS(); - // } else if (Platform.isAndroid) { - // confirmFromUser(); - // } - // } - - // void confirmFromUser_iOS() { - // String message = "You don't have internet access, Do you want to connect with HMG Network to use App.\n\nMake sure you are in HMG Network range"; - // ConfirmDialog( - // context: context, - // confirmMessage: message, - // okText: "Yes", - // okFunction: () { - // ConfirmDialog.closeAlertDialog(context); - // callBack(); - // }, - // cancelText: "No", - // cancelFunction: () { - // ConfirmDialog.closeAlertDialog(context); - // }).showAlertDialog(context); - // } - - // void connect_Android() { - // // enable the Wifi if its off - // PlatformBridge() - // .enableWifiIfNot() - // .then((value) => { - // if (value == true) - // { - // callBack() - // // Wifi.list(SSID) - // // .then((value1) => { - // // if (value1.length > 0) {callBack()} else {log("No HMG network in range")} - // // }) - // // .catchError((e) { - // // log(e); - // // }) - // } - // }) - // .catchError((error) { - // showFailDailog(error); - // }); - // } + } + ///Commeneted code need to reimplement } diff --git a/lib/uitl/HMG_Geofence.dart b/lib/uitl/HMG_Geofence.dart index 54c789ba..9f1075bc 100644 --- a/lib/uitl/HMG_Geofence.dart +++ b/lib/uitl/HMG_Geofence.dart @@ -18,7 +18,7 @@ // import 'package:geofencing/geofencing.dart'; // // class HMG_Geofencing { -// var _testTrigger = false; +// var _testTrigger = true; // static var _isolatePortName = "hmg_geofencing_send_port"; // // List _zones; @@ -27,7 +27,7 @@ // final AndroidGeofencingSettings androidSettings = AndroidGeofencingSettings(initialTrigger: [GeofenceEvent.enter, GeofenceEvent.exit, GeofenceEvent.dwell], loiteringDelay: 1000 * 60); // // final BuildContext context; -// final List triggers = List(); +// final List triggers =[]; // // HMG_Geofencing(this.context) { // triggers.add(GeofenceEvent.enter); @@ -50,7 +50,7 @@ // await Future.delayed(Duration(seconds: 2)); // _registerIsolatePort(); // _registerGeofences().then((value) { -// debugPrint(value.toString()); +// print(value.toString()); // if(_testTrigger) { // var events = [GeofenceEvent.enter,GeofenceEvent.exit]; // events.shuffle(); @@ -61,7 +61,7 @@ // } // // void _saveZones() { -// var list = List(); +// var list =[]; // _zones.forEach((element) { // list.add(element.toJson()); // }); @@ -91,9 +91,9 @@ // break; // } // await Future.delayed(Duration(milliseconds: 100)); -// debugPrint("Geofence: ${zone.description} registered"); +// print("Geofence: ${zone.description} registered"); // } else { -// debugPrint("Geofence: ${zone.description} registered"); +// print("Geofence: ${zone.description} registered"); // } // } // } diff --git a/lib/uitl/LocalNotification.dart b/lib/uitl/LocalNotification.dart index e0367ba3..aba01f85 100644 --- a/lib/uitl/LocalNotification.dart +++ b/lib/uitl/LocalNotification.dart @@ -1,24 +1,24 @@ import 'dart:math'; import 'dart:typed_data'; -import 'dart:ui'; -import 'package:flutter/cupertino.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); class LocalNotification { - Function(String payload) _onNotificationClick; - static LocalNotification _instance; - static LocalNotification getInstance(){ + Function(String payload)? _onNotificationClick; + static LocalNotification? _instance; + + static LocalNotification? getInstance() { return _instance; } - static init({Function(String payload) onNotificationClick}){ - if(_instance == null){ + + static init({required Function(String payload) onNotificationClick}) { + if (_instance == null) { _instance = LocalNotification(); - _instance._onNotificationClick = onNotificationClick; - _instance._initialize(); - }else{ + _instance?._onNotificationClick = onNotificationClick; + _instance?._initialize(); + } else { // assert(false,(){ // //TODO fix it // "LocalNotification Already Initialized"; @@ -26,19 +26,66 @@ class LocalNotification { } } - _initialize(){ - var initializationSettingsAndroid = new AndroidInitializationSettings('app_icon'); - var initializationSettingsIOS = IOSInitializationSettings(onDidReceiveLocalNotification: null); - var initializationSettings = InitializationSettings(initializationSettingsAndroid, initializationSettingsIOS); - flutterLocalNotificationsPlugin.initialize(initializationSettings, onSelectNotification: _onNotificationClick); + _initialize() async { + try { + var initializationSettingsAndroid = new AndroidInitializationSettings('app_icon'); + var initializationSettingsIOS = DarwinInitializationSettings(); + var initializationSettings = InitializationSettings(android: initializationSettingsAndroid, iOS: initializationSettingsIOS); + await flutterLocalNotificationsPlugin.initialize( + initializationSettings, + onDidReceiveNotificationResponse: (NotificationResponse notificationResponse) { + switch (notificationResponse.notificationResponseType) { + case NotificationResponseType.selectedNotification: + // selectNotificationStream.add(notificationResponse.payload); + break; + case NotificationResponseType.selectedNotificationAction: + // if (notificationResponse.actionId == navigationActionId) { + // selectNotificationStream.add(notificationResponse.payload); + // } + break; + } + }, + // onDidReceiveBackgroundNotificationResponse: notificationTapBackground, + ); + } catch (ex) { + print(ex.toString()); + } + // flutterLocalNotificationsPlugin.initialize(initializationSettings, onDidReceiveNotificationResponse: (NotificationResponse notificationResponse) + // { + // switch (notificationResponse.notificationResponseType) { + // case NotificationResponseType.selectedNotification: + // // selectNotificationStream.add(notificationResponse.payload); + // break; + // case NotificationResponseType.selectedNotificationAction: + // // if (notificationResponse.actionId == navigationActionId) { + // // selectNotificationStream.add(notificationResponse.payload); + // } + // // break; + // },} + // + // , + // + // ); } + // void notificationTapBackground(NotificationResponse notificationResponse) { + // // ignore: avoid_print + // print('notification(${notificationResponse.id}) action tapped: ' + // '${notificationResponse.actionId} with' + // ' payload: ${notificationResponse.payload}'); + // if (notificationResponse.input?.isNotEmpty ?? false) { + // // ignore: avoid_print + // print('notification action tapped with input: ${notificationResponse.input}'); + // } + // } + var _random = new Random(); - _randomNumber({int from = 100000}){ + + _randomNumber({int from = 100000}) { return _random.nextInt(from); } - _vibrationPattern(){ + _vibrationPattern() { var vibrationPattern = Int64List(4); vibrationPattern[0] = 0; vibrationPattern[1] = 1000; @@ -48,16 +95,30 @@ class LocalNotification { return vibrationPattern; } - Future showNow({@required String title, @required String subtitle, String payload}) { + Future? showNow({required String title, required String subtitle, required String payload}) { Future.delayed(Duration(seconds: 1)).then((result) async { - var androidPlatformChannelSpecifics = AndroidNotificationDetails('com.hmg.local_notification', 'HMG', 'HMG', importance: Importance.Max, priority: Priority.High, ticker: 'ticker', vibrationPattern: _vibrationPattern()); - var iOSPlatformChannelSpecifics = IOSNotificationDetails(); - var platformChannelSpecifics = NotificationDetails(androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics); - await flutterLocalNotificationsPlugin.show(_randomNumber(), title, subtitle, platformChannelSpecifics, payload: payload); + var androidPlatformChannelSpecifics = AndroidNotificationDetails( + 'com.hmg.local_notification', + 'HMG', + channelDescription: 'HMG', + importance: Importance.max, + priority: Priority.high, + ticker: 'ticker', + vibrationPattern: _vibrationPattern(), + ongoing: true, + autoCancel: false, + usesChronometer: true, + when: DateTime.now().millisecondsSinceEpoch - 120 * 1000, + ); + var iOSPlatformChannelSpecifics = DarwinNotificationDetails(); + var platformChannelSpecifics = NotificationDetails(android: androidPlatformChannelSpecifics, iOS: iOSPlatformChannelSpecifics); + await flutterLocalNotificationsPlugin.show(25613, title, subtitle, platformChannelSpecifics, payload: payload).catchError((err) { + print(err); + }); }); } - Future scheduleNotification({@required DateTime scheduledNotificationDateTime, @required String title, @required String description}) async { + Future scheduleNotification({required DateTime scheduledNotificationDateTime, required String title, required String description}) async { ///vibrationPattern var vibrationPattern = Int64List(4); vibrationPattern[0] = 0; @@ -65,32 +126,31 @@ class LocalNotification { vibrationPattern[2] = 5000; vibrationPattern[3] = 2000; - var androidPlatformChannelSpecifics = AndroidNotificationDetails('active-prescriptions', 'ActivePrescriptions', 'ActivePrescriptionsDescription', - // icon: 'secondary_icon', - sound: RawResourceAndroidNotificationSound('slow_spring_board'), - - ///change it to be as ionic - // largeIcon: DrawableResourceAndroidBitmap('sample_large_icon'),///change it to be as ionic - vibrationPattern: vibrationPattern, - enableLights: true, - color: const Color.fromARGB(255, 255, 0, 0), - ledColor: const Color.fromARGB(255, 255, 0, 0), - ledOnMs: 1000, - ledOffMs: 500); - var iOSPlatformChannelSpecifics = IOSNotificationDetails(sound: 'slow_spring_board.aiff'); - - ///change it to be as ionic - // var platformChannelSpecifics = NotificationDetails( - // androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics); - // await flutterLocalNotificationsPlugin.schedule(0, title, description, - // scheduledNotificationDateTime, platformChannelSpecifics); + // var androidPlatformChannelSpecifics = AndroidNotificationDetails('active-prescriptions', 'ActivePrescriptions', + // channelDescription: 'ActivePrescriptionsDescription', + // // icon: 'secondary_icon', + // sound: RawResourceAndroidNotificationSound('slow_spring_board'), + // + // ///change it to be as ionic + // // largeIcon: DrawableResourceAndroidBitmap('sample_large_icon'),///change it to be as ionic + // vibrationPattern: vibrationPattern, + // enableLights: true, + // color: const Color.fromARGB(255, 255, 0, 0), + // ledColor: const Color.fromARGB(255, 255, 0, 0), + // ledOnMs: 1000, + // ledOffMs: 500); + // var iOSPlatformChannelSpecifics = DarwinNotificationDetails(sound: 'slow_spring_board.aiff'); + + // /change it to be as ionic + // var platformChannelSpecifics = NotificationDetails(android: androidPlatformChannelSpecifics, iOS: iOSPlatformChannelSpecifics); + // await flutterLocalNotificationsPlugin.schedule(0, title, description, scheduledNotificationDateTime, platformChannelSpecifics); } ///Repeat notification every day at approximately 10:00:00 am Future showDailyAtTime() async { - var time = Time(10, 0, 0); - var androidPlatformChannelSpecifics = AndroidNotificationDetails('repeatDailyAtTime channel id', 'repeatDailyAtTime channel name', 'repeatDailyAtTime description'); - var iOSPlatformChannelSpecifics = IOSNotificationDetails(); + // var time = Time(10, 0, 0); + // var androidPlatformChannelSpecifics = AndroidNotificationDetails('repeatDailyAtTime channel id', 'repeatDailyAtTime channel name', channelDescription: 'repeatDailyAtTime description'); + // var iOSPlatformChannelSpecifics = DarwinNotificationDetails(); // var platformChannelSpecifics = NotificationDetails( // androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics); // await flutterLocalNotificationsPlugin.showDailyAtTime( @@ -103,9 +163,9 @@ class LocalNotification { ///Repeat notification weekly on Monday at approximately 10:00:00 am Future showWeeklyAtDayAndTime() async { - var time = Time(10, 0, 0); - var androidPlatformChannelSpecifics = AndroidNotificationDetails('show weekly channel id', 'show weekly channel name', 'show weekly description'); - var iOSPlatformChannelSpecifics = IOSNotificationDetails(); + // var time = Time(10, 0, 0); + // var androidPlatformChannelSpecifics = AndroidNotificationDetails('show weekly channel id', 'show weekly channel name', channelDescription: 'show weekly description'); + // var iOSPlatformChannelSpecifics = DarwinNotificationDetails(); // var platformChannelSpecifics = NotificationDetails( // androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics); // await flutterLocalNotificationsPlugin.showWeeklyAtDayAndTime( diff --git a/lib/uitl/PlatformBridge.dart b/lib/uitl/PlatformBridge.dart index 3ad91cdd..4dfc13a2 100644 --- a/lib/uitl/PlatformBridge.dart +++ b/lib/uitl/PlatformBridge.dart @@ -1,17 +1,14 @@ -import 'dart:developer'; - import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/localized_values.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/service/client/base_app_client.dart'; -import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/services.dart'; class PlatformBridge { static const platform = const MethodChannel("HMG-Platform-Bridge"); - static PlatformBridge _shared; - static BuildContext _context; + static late PlatformBridge _shared; + static late BuildContext _context; // // Singleton // static final PlatformBridge _singleton = PlatformBridge._internal(); @@ -57,10 +54,10 @@ class PlatformBridge { //--------------------------------- // Incoming below //--------------------------------- - static Future localizedValue(String forKey) async { + static Future localizedValue(String forKey) async { String currentLanguage = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); - Object localized = platformLocalizedValues[forKey][currentLanguage]; - return (localized != null || (localized is String)) ? localized : forKey; + dynamic localized = platformLocalizedValues[forKey][currentLanguage]; + return (localized! != null || (localized! is String)) ? localized! : forKey!; } static Future getGeoZones() async { @@ -91,29 +88,29 @@ class PlatformBridge { static const show_loading_method = "loading"; static const register_Hmg_Geofences = "registerHmgGeofences"; static const un_register_Hmg_Geofences = "unRegisterHmgGeofences"; + static const IS_DRAW_OVER_APPS_PERMISSION_ALLOWED = "isDrawOverAppsPermissionAllowed"; + static const ASK_DRAW_OVER_APPS_PERMISSION = "askDrawOverAppsPermission"; + static const GET_INTENT = "getIntent"; - Future connectHMGInternetWifi(String patientId) { - print("Invoking platform method: $hmg_internet_wifi_connect_method"); + Future connectHMGInternetWifi(String ssid, username, password) { try { - return platform.invokeMethod(hmg_internet_wifi_connect_method, [patientId]); + return platform!.invokeMethod(hmg_internet_wifi_connect_method!, [ssid!, username!,password!]); } on PlatformException catch (e) { print(e); return Future.error(e); } } - Future connectHMGGuestWifi() { - print("Invoking platform method: $hmg_guest_wifi_connect_method"); + Future connectHMGGuestWifi(String ssid) { try { - return platform.invokeMethod(hmg_guest_wifi_connect_method); + return platform.invokeMethod(hmg_guest_wifi_connect_method, ssid); } on PlatformException catch (e) { print(e); return Future.error(e); } } - Future isHMGNetworkAvailable(String ssid) { - print("Invoking platform method: $is_hmg_network_available_method"); + Future isHMGNetworkAvailable(String ssid) { try { return platform.invokeMethod(is_hmg_network_available_method, ssid); } on PlatformException catch (e) { @@ -123,7 +120,6 @@ class PlatformBridge { } Future enableWifiIfNot() async { - print("Invoking platform method: $enable_wifi_if_not"); try { return platform.invokeMethod(enable_wifi_if_not); } on PlatformException catch (e) { @@ -133,7 +129,6 @@ class PlatformBridge { } void showLoading(String message, bool show) async { - print("Invoking platform method: $show_loading_method"); try { var result = await platform.invokeMethod(show_loading_method, [message, show]); } on PlatformException catch (e) { @@ -149,4 +144,19 @@ class PlatformBridge { void unRegisterHmgGeofences() async { var result = await platform.invokeMethod(un_register_Hmg_Geofences); } + + Future isDrawOverAppsPermissionAllowed() async { + var result = await platform.invokeMethod(IS_DRAW_OVER_APPS_PERMISSION_ALLOWED); + return result as bool; + } + + Future askDrawOverAppsPermission() async { + var result = await platform.invokeMethod(ASK_DRAW_OVER_APPS_PERMISSION); + return result as bool; + } + + Future getIntentData() async { + var result = await platform.invokeMethod(GET_INTENT); + return result as bool; + } } diff --git a/lib/uitl/SignalRUtil.dart b/lib/uitl/SignalRUtil.dart new file mode 100644 index 00000000..de90981f --- /dev/null +++ b/lib/uitl/SignalRUtil.dart @@ -0,0 +1,173 @@ +// import 'dart:convert'; +// import 'dart:io'; +// +// import 'package:flutter/cupertino.dart'; +// import 'package:flutter_webrtc/flutter_webrtc.dart'; +// import 'package:http/io_client.dart'; +// import 'package:signalr_core/signalr_core.dart'; +// +// class SignalRUtil { +// String hubName; +// +// String sourceUser; +// String destinationUser; +// setContributors({@required String caller, @required String receiver}){ +// this.sourceUser = caller; +// this.destinationUser = receiver; +// } +// +// Function(bool) onConnected; +// SignalRUtil({@required this.hubName}); +// +// +// HubConnection connectionHub; +// +// closeConnection() async{ +// if(connectionHub != null) { +// connectionHub.off('OnIncomingCallAsync'); +// connectionHub.off('OnCallDeclinedAsync'); +// connectionHub.off('OnCallAcceptedAsync'); +// connectionHub.off('nHangUpAsync'); +// connectionHub.off('OnIceCandidateAsync'); +// connectionHub.off('OnOfferAsync'); +// await connectionHub.stop(); +// } +// } +// +// Future openConnection() async { +// connectionHub = HubConnectionBuilder() +// .withUrl( +// hubName, +// HttpConnectionOptions( +// logMessageContent: true, +// client: IOClient(HttpClient()..badCertificateCallback = (x, y, z) => true), +// logging: (level, message) => print(message), +// )).build(); +// +// await connectionHub.start(); +// await Future.delayed(Duration(seconds: 1)); +// +// connectionHub.on('ReceiveMessage', (message) { +// handleIncomingMessage(message); +// }); +// +// return getConnectionState(); +// } +// +// void handleIncomingMessage(List message) { +// print(message.toString()); +// } +// +// void sendMessage(List args) async { +// await connectionHub.invoke('SendMessage', args: args); //['Bob', 'Says hi!'] +// } +// +// listen({Function(CallUser) onAcceptCall, Function(CallUser) onHangupCall, Function(String, CallUser) onDeclineCall, Function(String, CallUser) onOffer, Function(String) onCandidate}){ +// +// connectionHub.on('OnIncomingCallAsync', (arguments) { +// print('OnIncomingCallAsync: ${arguments.toString()}'); +// }); +// +// connectionHub.on('OnCallDeclinedAsync', (arguments) { +// print('OnCallDeclinedAsync: ${arguments.toString()}'); +// onDeclineCall(arguments.first, CallUser.from(arguments.last)); +// }); +// +// connectionHub.on('OnCallAcceptedAsync', (arguments) { +// print('OnCallAcceptedAsync: ${arguments.toString()}'); +// }); +// +// connectionHub.on('OnHangUpAsync', (arguments) { +// print('nHangUpAsync: ${arguments.toString()}'); +// onHangupCall(CallUser.from(arguments.first)); +// }); +// +// connectionHub.on('OnIceCandidateAsync', (arguments) { +// print('OnIceCandidateAsync: ${arguments.toString()}'); +// onCandidate(arguments.first); +// }); +// +// connectionHub.on('OnOfferAsync', (arguments) { +// print('OnOfferAsync: ${arguments.toString()}'); +// onOffer(arguments.first, CallUser.from(arguments.last)); +// }); +// +// } +// +// // CallUserAsync(string currentUserId, string targerUserId) +// Future callUser(String from, to) async{ +// return await connectionHub.invoke('CallUserAsync', args: [from, to]); +// } +// +// // CallDeclinedAsync(string currentUserId, string targerUserId) +// Future declineCall(String from, to) async{ +// return await connectionHub.invoke('CallDeclinedAsync', args: [from, to]); +// } +// +// // AnswerCallAsync(string currentUserId, string targetUserId) +// Future answerCall(String from, to) async{ +// return await connectionHub.invoke('AnswerCallAsync', args: [from, to]); +// } +// +// // IceCandidateAsync(string targetUserId, string candidate) +// Future addIceCandidate(String candidate) async{ +// final target = destinationUser; +// return await connectionHub.invoke('IceCandidateAsync', args: [target, candidate]); +// } +// +// // OfferAsync(string targetUserId,string currentUserId, string targetOffer) +// Future offer(String from, to, offer) async{ +// return await connectionHub.invoke('OfferAsync', args: [from, to, offer]); +// } +// +// // AnswerOfferAsync(string targetUserId, string CallerOffer) +// Future answerOffer(RTCSessionDescription answerSdp, caller, receiver) async{ +// final payload = { +// 'target': receiver, +// 'caller': caller, +// 'sdp': answerSdp.toMap(), +// }; +// return await connectionHub.invoke('AnswerOfferAsync', args: [caller, jsonEncode(payload)]); +// } +// +// // HangUpAsync(string currentUserId, string targetUserId) +// Future hangupCall(String from, to) async{ +// return await connectionHub.invoke('HangUpAsync', args: [from, to]); +// } +// +// // CallAccepted(string currentUserId,string targetUserId) +// Future acceptCall(String from, to) async{ +// // return await connectionHub.send(methodName: 'CallAccepted', args: [from, to]); +// return await connectionHub.invoke("CallAccepted", args: [ from, to]); +// } +// +// +// bool getConnectionState() { +// if (connectionHub.state == HubConnectionState.connected) return true; +// if (connectionHub.state == HubConnectionState.disconnected) return false; +// return false; +// } +// } +// +// +// class CallUser{ +// String Id; +// String UserName; +// String Email; +// String Phone; +// String Title; +// dynamic UserStatus; +// String Image; +// int UnreadMessageCount = 0; +// +// CallUser.from(Map map){ +// Id = map['Id']; +// UserName = map['UserName']; +// Email = map['Email']; +// Phone = map['Phone']; +// Title = map['Title']; +// UserStatus = map['UserStatus']; +// Image = map['Image']; +// UnreadMessageCount = map['UnreadMessageCount']; +// } +// } \ No newline at end of file diff --git a/lib/uitl/app-permissions.dart b/lib/uitl/app-permissions.dart new file mode 100644 index 00000000..94697e4f --- /dev/null +++ b/lib/uitl/app-permissions.dart @@ -0,0 +1,59 @@ +import 'dart:io'; + +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:permission_handler/permission_handler.dart'; + +import 'PlatformBridge.dart'; + +class AppPermission { + static Future askVideoCallPermission(BuildContext context) async { + if (!(await Permission.camera.request().isGranted) || !(await Permission.microphone.request().isGranted)) { + return false; + } + // if (Platform.isAndroid && !(await PlatformBridge.shared().isDrawOverAppsPermissionAllowed())) { + // await _drawOverAppsMessageDialog(context); + // return false; + // } + return true; + } + +// + + // Manifest.permission.INTERNET, + // Manifest.permission.ACCESS_FINE_LOCATION, + // Manifest.permission.ACCESS_COARSE_LOCATION, + // Manifest.permission.ACCESS_NETWORK_STATE, + // Manifest.permission.BLUETOOTH, + // Manifest.permission.BLUETOOTH_ADMIN, + // Manifest.permission.BLUETOOTH_SCAN, + // Manifest.permission.BLUETOOTH_CONNECT, + // Manifest.permission.HIGH_SAMPLING_RATE_SENSORS, + // Manifest.permission.ACTIVITY_RECOGNITION + + static Future askPenguinPermissions() async { + if (!(await Permission.location.request().isGranted) || + !(await Permission.bluetooth.request().isGranted) || + !(await Permission.bluetoothScan.request().isGranted) || + !(await Permission.bluetoothConnect.request().isGranted) || + !(await Permission.activityRecognition.request().isGranted)) { + return false; + } + return true; + } + + static Future _drawOverAppsMessageDialog(BuildContext context) async { + ConfirmDialog dialog = new ConfirmDialog( + context: context, + confirmMessage: TranslationBase.of(context).drawOverAppsPermission, + okText: TranslationBase.of(context).confirm, + cancelText: TranslationBase.of(context).cancel_nocaps, + okFunction: () async { + await PlatformBridge.shared().askDrawOverAppsPermission(); + Navigator.pop(context); + }, + cancelFunction: () => {}); + dialog.showAlertDialog(context); + } +} diff --git a/lib/uitl/app_shared_preferences.dart b/lib/uitl/app_shared_preferences.dart index 3ea323df..4ecd1b91 100644 --- a/lib/uitl/app_shared_preferences.dart +++ b/lib/uitl/app_shared_preferences.dart @@ -4,88 +4,124 @@ import 'package:shared_preferences/shared_preferences.dart'; class AppSharedPreferences { Future _prefs = SharedPreferences.getInstance(); + late Map _allData; + + // To Test Saved Data + Future> getAll() async { + final prefs = (await _prefs); + _allData = {}; + prefs.getKeys().forEach((key) { + _allData![key] = prefs.get(key); + }); + return _allData!; + } /// Save String [key] the key for save value [value] the value we need to save it setString(String key, String value) async { - final SharedPreferences prefs = await _prefs; - return prefs.setString(key, value); + if (value != null) { + final SharedPreferences prefs = await _prefs; + return prefs.setString(key, value); + } } /// Save List of String [key] the key for save value [value] the value we need to save it setStringList(String key, List value) async { - final SharedPreferences prefs = await _prefs; - return prefs.setStringList(key, value); + if (value != null) { + final SharedPreferences prefs = await _prefs; + return prefs.setStringList(key, value); + } } /// Save Double [key] the key for save value [value] the value we need to save it setDouble(String key, double value) async { - final SharedPreferences prefs = await _prefs; - return prefs.setDouble(key, value); + if (value != null) { + final SharedPreferences prefs = await _prefs; + return prefs.setDouble(key, value); + } } /// Save Bool [key] the key for save value [value] the value we need to save it setBool(String key, bool value) async { - final SharedPreferences prefs = await _prefs; - return prefs.setBool(key, value); + if (value != null) { + final SharedPreferences prefs = await _prefs; + return prefs.setBool(key, value); + } } /// Save int [key] the key for save value [value] the value we need to save it setInt(String key, int value) async { - final SharedPreferences prefs = await _prefs; - return prefs.setInt(key, value); + if (value != null) { + final SharedPreferences prefs = await _prefs; + return prefs.setInt(key, value); + } } /// save Object [key] the key for save value [value] the value we need to save it setObject(String key, value) async { - final SharedPreferences prefs = await _prefs; - return prefs.setString(key, json.encode(value)); + if (value != null) { + final SharedPreferences prefs = await _prefs; + return await prefs.setString(key, json.encode(value)); + } } /// Get String [key] the key was saved - getString(String key) async { + Future getString(String key) async { final SharedPreferences prefs = await _prefs; + await prefs.reload(); return prefs.getString(key); } /// Get String [key] the key was saved getStringWithDefaultValue(String key, String defaultVal) async { final SharedPreferences prefs = await _prefs; - String value = prefs.getString(key); - return value == null ? defaultVal : value; + await prefs.reload(); + String value = prefs.getString(key).toString(); + return (value == null) || (value == "null") ? defaultVal : value; + // return value == null ? defaultVal : value; } /// Get List of String [key] the key was saved getStringList(String key) async { final SharedPreferences prefs = await _prefs; + await prefs.reload(); return prefs.getStringList(key); } /// Get Double [key] the key was saved getDouble(String key) async { final SharedPreferences prefs = await _prefs; + await prefs.reload(); return prefs.getDouble(key); } /// Get Bool [key] the key was saved getBool(String key) async { final SharedPreferences prefs = await _prefs; + await prefs.reload(); return prefs.getBool(key); } /// Get Int [key] the key was saved getInt(String key) async { final SharedPreferences prefs = await _prefs; + await prefs.reload(); return prefs.getInt(key); } /// Get Object [key] the key was saved - getObject(String key) async { - final SharedPreferences prefs = await _prefs; - var string = prefs.getString(key); - if (string == null) { - return null; + Future getObject(String key) async { + try { + final SharedPreferences prefs = await _prefs; + await prefs.reload(); + var string = prefs.getString(key); + if (string == null) { + return null; + } + return json.decode(string); + } catch (ex) { + print(ex); + print(ex.toString()); } - return json.decode(string); } /// clear all saved values in shared preferences @@ -97,6 +133,8 @@ class AppSharedPreferences { /// remove value based on [key] the key was saved remove(String key) async { final SharedPreferences prefs = await _prefs; - prefs.remove(key); + prefs.remove(key).then((value) { + print(value); + }); } } diff --git a/lib/uitl/app_toast.dart b/lib/uitl/app_toast.dart index 5c917009..bbeebe5d 100644 --- a/lib/uitl/app_toast.dart +++ b/lib/uitl/app_toast.dart @@ -1,116 +1,91 @@ +import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_flexible_toast/flutter_flexible_toast.dart'; +import 'package:fluttertoast/fluttertoast.dart'; class AppToast { - - /// show long toast message - /// [message] to show for user - /// [timeInSeconds] how many second the toast will appear to the user - /// [toastLength] the time we show the message but should be Toast.LENGTH_SHORT , Toast.LENGTH_LONG - /// [toastGravity] the position of the toast in the screen - /// [backgroundColor] the background color of the toast - /// [textColor] the text color of the toast - /// [icon] the icon you want include in the toast - /// [radius] the radius of the toast - /// [elevation] an overlay color will be applied to indicate elevation. - /// [imageSize] image size inside the toast static void showToast({ - @required String message, - Toast toastLength, - int timeInSeconds, - double fontSize, - ToastGravity toastGravity, - Color backgroundColor, - Color textColor, - ICON icon, - int radius, - int elevation, - int imageSize, + required String message, + Toast? toastLength, + int? timeInSeconds, + double? fontSize, + ToastGravity? toastGravity, + Color? backgroundColor, + Color? textColor, + int? radius, + int? elevation, + int? imageSize, }) { - FlutterFlexibleToast.showToast( - message: message, - toastLength: toastLength, - timeInSeconds: timeInSeconds, - fontSize: fontSize, - toastGravity: toastGravity, - backgroundColor: backgroundColor, - textColor: textColor, - icon: icon, - radius: radius, - elevation: elevation, - imageSize: imageSize); + Fluttertoast.showToast( + msg: message, toastLength: toastLength, gravity: toastGravity, timeInSecForIosWeb: timeInSeconds!, backgroundColor: backgroundColor, textColor: textColor, fontSize: fontSize); } - /// show Success toast message - /// [message] to show for user - /// [timeInSeconds] how many second the toast will appear to the user - /// [toastLength] the time we show the message but should be Toast.LENGTH_SHORT , Toast.LENGTH_LONG - /// [toastGravity] the position of the toast in the screen - /// [textColor] the text color of the toast - /// [radius] the radius of the toast - /// [elevation] an overlay color will be applied to indicate elevation. - /// [imageSize] image size inside the toast static void showSuccessToast({ - @required String message, + required String message, Toast toastLength = Toast.LENGTH_LONG, - int timeInSeconds, + int timeInSeconds = 2, double fontSize = 16, ToastGravity toastGravity = ToastGravity.TOP, Color textColor = Colors.white, - int radius, - int elevation, + int? radius, + int? elevation, int imageSize = 32, }) { - FlutterFlexibleToast.showToast( - message: message, - toastLength: toastLength, - timeInSeconds: timeInSeconds=2, - fontSize: fontSize, - toastGravity: toastGravity, - backgroundColor: Colors.green, - textColor: textColor, - icon: ICON.SUCCESS, - radius: radius, - elevation: elevation, - imageSize: imageSize); + Fluttertoast.showToast( + msg: message, toastLength: toastLength, gravity: toastGravity, timeInSecForIosWeb: timeInSeconds ?? 0, backgroundColor: Colors.green, textColor: textColor, fontSize: fontSize); } - /// show Error toast message - /// [message] to show for user - /// [timeInSeconds] how many second the toast will appear to the user - /// [toastLength] the time we show the message but should be Toast.LENGTH_SHORT , Toast.LENGTH_LONG - /// [toastGravity] the position of the toast in the screen - /// [textColor] the text color of the toast - /// [radius] the radius of the toast - /// [elevation] an overlay color will be applied to indicate elevation. - /// [imageSize] image size inside the toast - static void showErrorToast({ - @required String message, - Toast toastLength = Toast.LENGTH_LONG, - int timeInSeconds=2, - double fontSize = 16, - ToastGravity toastGravity = ToastGravity.TOP, - Color textColor = Colors.white, - int radius, - int elevation, - int imageSize = 32, - }) { - FlutterFlexibleToast.showToast( - message: message, - toastLength: toastLength, - timeInSeconds: timeInSeconds, - fontSize: fontSize, - toastGravity: toastGravity, - backgroundColor: Colors.red, - textColor: textColor, - icon: ICON.CLOSE, - radius: radius, - elevation: elevation, - imageSize: imageSize); + static void showErrorToast( + {required String message, + Toast toastLength = Toast.LENGTH_LONG, + int timeInSeconds = 2, + double fontSize = 16, + ToastGravity toastGravity = ToastGravity.TOP, + Color textColor = Colors.white, + int radius = 15, + int? elevation, + int imageSize = 32, + BuildContext? localContext}) { + FToast fToast = FToast(); + fToast.init(localContext != null ? localContext : AppGlobal.context); + Widget toast = Container( + padding: EdgeInsets.all(8), + alignment: Alignment.topCenter, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(radius.toDouble()), + color: Colors.red, + ), + child: Wrap( + children: [ + Text( + message, + style: TextStyle(color: textColor, fontSize: fontSize), + softWrap: true, + overflow: TextOverflow.clip, + ), + ], + ), + ); + fToast.showToast( + child: toast, + gravity: ToastGravity.TOP, + toastDuration: Duration(seconds: timeInSeconds), + positionedToastBuilder: (context, child) { + return Positioned(top: 50, left: 10, right: 10, child: child); + }); + // Fluttertoast.showToast(msg: message, toastLength: toastLength, gravity: toastGravity, timeInSecForIosWeb: timeInSeconds, backgroundColor: Colors.red, textColor: textColor, fontSize: fontSize); } - /// cancel toast void cancelToast() { - FlutterFlexibleToast.cancel(); + Fluttertoast.cancel(); + } + + void backWithEmpty() { + AppToast.showErrorToast(message: TranslationBase.of(AppGlobal.context).empty); + Navigator.of(AppGlobal.context).pop(); + } + + void back() { + Navigator.of(AppGlobal.context).pop(); } } diff --git a/lib/uitl/cupertino_picker.dart b/lib/uitl/cupertino_picker.dart index d40d4b39..3dbbcea7 100644 --- a/lib/uitl/cupertino_picker.dart +++ b/lib/uitl/cupertino_picker.dart @@ -22,20 +22,20 @@ class CupertinoPickerUtils { /// [backgroundColor] background color showCupertinoPicker( - {BuildContext context, - List items, - String decKey, - Function onSelectFun, + {BuildContext? context, + List? items, + String? decKey, + Function? onSelectFun, bool isDismissible = false, double itemExtent = 25, bool looping = true, Color backgroundColor = const Color(0xfff7f7f7)}) { showModalBottomSheet( isDismissible: isDismissible, - context: context, + context: context!, builder: (BuildContext builder) { return Container( - height: SizeConfig.realScreenHeight * 0.4, + height: SizeConfig.realScreenHeight! * 0.4, color: backgroundColor, child: Column( mainAxisAlignment: MainAxisAlignment.end, @@ -60,22 +60,22 @@ class CupertinoPickerUtils { ), onPressed: () { Navigator.pop(context); - onSelectFun(cupertinoPickerIndex); + onSelectFun!(cupertinoPickerIndex); }, ), ], ), ), Container( - height: SizeConfig.realScreenHeight * 0.3, + height: SizeConfig.realScreenHeight! * 0.3, color: backgroundColor, child: buildPickerItems( context: context, - decKey: decKey, + decKey: decKey!, itemExtent: itemExtent, - items: items, + items: items!, looping: looping, - onSelectFun: onSelectFun)) + onSelectFun: onSelectFun!)) ], ), ); @@ -89,24 +89,24 @@ class CupertinoPickerUtils { /// [onSelectFun] the call function on select event /// [decKey] the key we show for user buildPickerItems( - {BuildContext context, - List items, - String decKey, - Function onSelectFun, - double itemExtent, - bool looping}) { + {BuildContext? context, + List? items, + String? decKey, + Function? onSelectFun, + double? itemExtent, + bool? looping}) { return CupertinoPicker( magnification: 1.5, scrollController: FixedExtentScrollController(initialItem: cupertinoPickerIndex), - children: items.map((item) { + children: items!.map((item) { return Text( '${item["$decKey"]}', - style: TextStyle(fontSize: SizeConfig.textMultiplier * 2), + style: TextStyle(fontSize: SizeConfig.textMultiplier! * 2), ); }).toList(), - itemExtent: itemExtent, - looping: looping, + itemExtent: itemExtent!, + looping: looping!, onSelectedItemChanged: (int index) { cupertinoPickerIndex = index; }, diff --git a/lib/uitl/date_uitl.dart b/lib/uitl/date_uitl.dart index 9f959885..2d4c5b5c 100644 --- a/lib/uitl/date_uitl.dart +++ b/lib/uitl/date_uitl.dart @@ -1,15 +1,55 @@ import 'package:device_calendar/device_calendar.dart'; +import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; class DateUtil { /// convert String To Date function /// [date] String we want to convert - static DateTime convertStringToDate(String date) { // /Date(1585774800000+0300)/ + static DateTime convertStringToDate(String? date) { if (date != null) { const start = "/Date("; const end = "+0300)"; final startIndex = date.indexOf(start); final endIndex = date.indexOf(end, startIndex + start.length); + return DateTime.fromMillisecondsSinceEpoch(int.parse( + date.substring(startIndex + start.length, endIndex), + )); + } else + return DateTime.now(); + } + + static DateTime convertStringToDateSaudiTimezone(String date, int projectId) { + if (date != null) { + const start = "/Date("; + const end = "+0300)"; + final startIndex = date.indexOf(start); + final endIndex = date.indexOf(end, startIndex + start.length); + // if (projectId == 2 || projectId == 3) { + // return DateTime.fromMillisecondsSinceEpoch( + // int.parse( + // date.substring(startIndex + start.length, endIndex), + // ), + // isUtc: true) + // .add(Duration(hours: 4)); + // } else { + return DateTime.fromMillisecondsSinceEpoch( + int.parse( + date.substring(startIndex + start.length, endIndex), + ), + isUtc: true) + .add(Duration(hours: 3)); + // } + } else + return DateTime.now(); + } + + static DateTime convertStringToDateNoTimeZone(String date) { + // /Date(1585774800000+0300)/ + if (date != null) { + const start = "/Date("; + const end = ")"; + final startIndex = date.indexOf(start); + final endIndex = date.indexOf(end, startIndex + start.length); return DateTime.fromMillisecondsSinceEpoch( int.parse( date.substring(startIndex + start.length, endIndex), @@ -19,13 +59,12 @@ class DateUtil { return DateTime.now(); } - static DateTime convertStringToDateTime(String date) { + static DateTime convertStringToDateTime(String? date) { if (date != null) { try { var dateT = date.split('/'); var year = dateT[2].substring(0, 4); - var dateP = - DateTime(int.parse(year), int.parse(dateT[1]), int.parse(dateT[0])); + var dateP = DateTime(int.parse(year), int.parse(dateT[1]), int.parse(dateT[0])); return dateP; } catch (e) { print(e); @@ -38,7 +77,7 @@ class DateUtil { static String convertDateToString(DateTime date) { const start = "/Date("; - const end = "+0300)"; + const end = "+0300)/"; int milliseconds = date.millisecondsSinceEpoch; return start + "$milliseconds" + end; @@ -52,6 +91,25 @@ class DateUtil { return start + "$milliseconds" + end; } + static String convertTime(String timeStr) { + TimeOfDay time = TimeOfDay(hour: int.parse(timeStr.split(":")[0]), minute: int.parse(timeStr.split(":")[1])); // 24-hour format time + + int hour = time.hourOfPeriod; // get hour in 12-hour format + String meridiem = time.period == DayPeriod.am ? "AM" : "PM"; // get AM/PM + + String convertedTime = '$hour:${time.minute == 0 ? "00" : time.minute} $meridiem'; // create the new time string + + return convertedTime; + } + + static String formatDateToDate(DateTime date, bool isArabic) { + return DateFormat('dd MMM yyy', isArabic ? "ar_SA" : "en_US").format(date); + } + + static String formatDateToTime(DateTime date) { + return DateFormat('hh:mm a').format(date); + } + static String yearMonthDay(DateTime dateTime) { String dateFormat = '${dateTime.year}-${dateTime.month}-${dateTime.day}'; return dateFormat; @@ -62,16 +120,19 @@ class DateUtil { return dateFormat; } + static String convertDateMSToJsonDate(utc) { + var dt = new DateTime.fromMicrosecondsSinceEpoch(utc); + + return "/Date(" + (dt.millisecondsSinceEpoch * 1000).toString() + '+0300' + ")/"; + } + /// check Date /// [dateString] String we want to convert static String checkDate(DateTime checkedTime) { DateTime currentTime = DateTime.now(); - if ((currentTime.year == checkedTime.year) && - (currentTime.month == checkedTime.month) && - (currentTime.day == checkedTime.day)) { + if ((currentTime.year == checkedTime.year) && (currentTime.month == checkedTime.month) && (currentTime.day == checkedTime.day)) { return "Today"; - } else if ((currentTime.year == checkedTime.year) && - (currentTime.month == checkedTime.month)) { + } else if ((currentTime.year == checkedTime.year) && (currentTime.month == checkedTime.month)) { if ((currentTime.day - checkedTime.day) == 1) { return "YESTERDAY"; } else if ((currentTime.day - checkedTime.day) == -1) { @@ -89,13 +150,12 @@ class DateUtil { static String getDateFormatted(String date) { DateTime dateObj = DateUtil.convertStringToDate(date); - return DateUtil.getWeekDay(dateObj.weekday) + - ", " + - dateObj.day.toString() + - " " + - DateUtil.getMonth(dateObj.month) + - " " + - dateObj.year.toString(); + return DateUtil.getWeekDay(dateObj.weekday) + ", " + dateObj.day.toString() + " " + DateUtil.getMonth(dateObj.month) + " " + dateObj.year.toString(); + } + + static String getISODateFormat(DateTime dateTime) { + // 2020-04-30T00:00:00.000 + return dateTime.toIso8601String(); } /// get month by @@ -190,7 +250,7 @@ class DateUtil { } static getMonthDateTime(String month, yearName) { - DateTime date; + DateTime? date; try { date = DateTime(int.parse(yearName), getMonthByName(month)); } catch (e) { @@ -241,69 +301,76 @@ class DateUtil { } } + static getWeekDayEnglish(int weekDay) { + switch (weekDay) { + case 1: + return "Monday"; + case 2: + return "Tuesday"; + case 3: + return "Wednesday"; + case 4: + return "Thursday"; + case 5: + return "Friday"; + case 6: + return "Saturday "; + case 7: + return "Sunday"; + } + } + /// get data formatted like Apr 26,2020 /// [dateTime] convert DateTime to data formatted static String getMonthDayYearDateFormatted(DateTime dateTime) { if (dateTime != null) - return getMonth(dateTime.month) + - " " + - dateTime.day.toString() + - ", " + - dateTime.year.toString(); + return getMonth(dateTime.month) + " " + dateTime.day.toString() + ", " + dateTime.year.toString(); else return ""; } + /// get data formatted like Apr 26,2020 /// [dateTime] convert DateTime to data formatted Arabic static String getMonthDayYearDateFormattedAr(DateTime dateTime) { if (dateTime != null) - return getMonthArabic(dateTime.month) + - " " + - dateTime.day.toString() + - ", " + - dateTime.year.toString(); + return getMonthArabic(dateTime.month) + " " + dateTime.day.toString() + ", " + dateTime.year.toString(); else return ""; } /// get data formatted like Thursday, Apr 26,2020 /// [dateTime] convert DateTime to date formatted - static String getWeekDayMonthDayYearDateFormatted( - DateTime dateTime, String lang) { + static String getWeekDayMonthDayYearDateFormatted(DateTime dateTime, String lang) { if (dateTime != null) return lang == 'en' - ? getDay(dateTime.weekday.getDayOfWeekEnumValue) + - ", " + - getMonth(dateTime.month) + - " " + - dateTime.day.toString() + - " " + - dateTime.year.toString() - : getWeekDayArabic(dateTime.weekday) + - ", " + - dateTime.day.toString() + - " " + - getMonthArabic(dateTime.month) + - " " + - dateTime.year.toString(); + ? getWeekDayEnglish(dateTime.weekday) + ", " + getMonth(dateTime.month) + " " + dateTime.day.toString() + " " + dateTime.year.toString() + : getWeekDayArabic(dateTime.weekday) + ", " + dateTime.day.toString() + " " + getMonthArabic(dateTime.month) + " " + dateTime.year.toString(); else return ""; } - static String getMonthDayYearLangDateFormatted( - DateTime dateTime, String lang) { + static String getMonthDayYearLangDateFormatted(DateTime dateTime, String lang) { if (dateTime != null) return lang == 'en' - ? getMonth(dateTime.month) + - " " + - dateTime.day.toString() + - " " + - dateTime.year.toString() - : dateTime.day.toString() + - " " + - getMonthArabic(dateTime.month) + - " " + - dateTime.year.toString(); + ? getMonth(dateTime.month) + " " + dateTime.day.toString() + " " + dateTime.year.toString() + : dateTime.day.toString() + " " + getMonthArabic(dateTime.month) + " " + dateTime.year.toString(); + else + return ""; + } + + /// get data formatted like 26/4/2020 + static String getDayMonthYearLangDateFormatted(DateTime dateTime, String lang) { + if (dateTime != null) + return lang == 'en' + ? dateTime.day.toString() + " " + getMonth(dateTime.month) + " " + dateTime.year.toString() + : dateTime.day.toString() + " " + getMonthArabic(dateTime.month) + " " + dateTime.year.toString(); + else + return ""; + } + + static String getMonthYearLangDateFormatted(DateTime dateTime, String lang) { + if (dateTime != null) + return lang == 'en' ? getMonth(dateTime.month) + " " + dateTime.year.toString() : getMonthArabic(dateTime.month) + " " + dateTime.year.toString(); else return ""; } @@ -312,28 +379,39 @@ class DateUtil { /// [dateTime] convert DateTime to data formatted static String getDayMonthYearDateFormatted(DateTime dateTime) { if (dateTime != null) - return dateTime.day.toString() + - "/" + - dateTime.month.toString() + - "/" + - dateTime.year.toString(); + return dateTime.day.toString() + "/" + dateTime.month.toString() + "/" + dateTime.year.toString(); + else + 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) { + if (dateTime != null) + return DateFormat('dd/MM/yyyy', isArabic ? "ar_SA" : "en_US").format(dateTime); else return ""; } + /// get data formatted like 10:30 according to lang + static String formatDateToTimeLang(DateTime date, bool isArabic) { + return DateFormat('HH:mm', isArabic ? "ar_SA" : "en_US").format(date); + } + /// get data formatted like 26/4/2020 10:30 /// [dateTime] convert DateTime to data formatted static String getDayMonthYearHourMinuteDateFormatted(DateTime dateTime) { if (dateTime != null) - return dateTime.day.toString() + - "/" + - dateTime.month.toString() + - "/" + - dateTime.year.toString() + - " " + - dateTime.hour.toString() + - ":" + - dateTime.minute.toString(); + return dateTime.day.toString() + "/" + dateTime.month.toString() + "/" + dateTime.year.toString() + " " + DateFormat('HH:mm').format(dateTime); else return ""; } @@ -357,18 +435,12 @@ class DateUtil { return ""; } - static String getFormattedDate(DateTime dateTime, String formattedString){ - return DateFormat(formattedString) - .format(dateTime); + static String getFormattedDate(DateTime dateTime, String formattedString) { + return DateFormat(formattedString).format(dateTime); } static convertISODateToJsonDate(String isoDate) { - return "/Date(" + - DateFormat('mm-dd-yyy') - .parse(isoDate) - .millisecondsSinceEpoch - .toString() + - ")/"; + return "/Date(" + DateFormat('mm-dd-yyy').parse(isoDate).millisecondsSinceEpoch.toString() + ")/"; } static String getDay(DayOfWeek dayOfWeek) { @@ -393,7 +465,6 @@ class DateUtil { break; case DayOfWeek.Sunday: return "Sunday"; - break; } return ""; diff --git a/lib/uitl/gif_loader_dialog_utils.dart b/lib/uitl/gif_loader_dialog_utils.dart index 785a6c6c..59fed780 100644 --- a/lib/uitl/gif_loader_dialog_utils.dart +++ b/lib/uitl/gif_loader_dialog_utils.dart @@ -3,15 +3,45 @@ import 'package:flutter/material.dart'; import '../widgets/Loader/gif_loader_container.dart'; class GifLoaderDialogUtils { - static showMyDialog(BuildContext context) { - showDialog(context: context, child: GifLoaderContainer()); + static bool _isLoadingVisible = false; + + static bool get isLoading => _isLoadingVisible; + + static showMyDialog(BuildContext context, {bool barrierDismissible = true}) { + // showDialog(context: context, builder: (cxt) => GifLoaderContainer()); + WidgetsBinding.instance.addPostFrameCallback((_) { + _isLoadingVisible = true; + showDialog( + barrierDismissible: barrierDismissible, + context: context, + barrierColor: Colors.black.withOpacity(0.5), + useRootNavigator: false, + builder: (BuildContext context) => GifLoaderContainer( + barrierDismissible: barrierDismissible, + ), + ).then((value) { + _isLoadingVisible = false; + }); + }); } static hideDialog(BuildContext context) { - try{ - Navigator.of(context).pop(); - }catch(error){ - Future.delayed(Duration(milliseconds: 250)).then((value) => Navigator.of(context).pop()); + try { + + if (_isLoadingVisible) { + _isLoadingVisible = false; + Navigator.of(context).pop(); + } + _isLoadingVisible = false; + // Navigator.of(context, rootNavigator: true).canPop(); + } catch (error) { + //Future.delayed(Duration(milliseconds: 250)).then((value) => Navigator.of(context, rootNavigator: true).canPop()); + // Future.delayed(Duration(milliseconds: 250)).then((value) => Navigator.of(context, rootNavigator: true).canPop()); + if (_isLoadingVisible) { + _isLoadingVisible = false; + Navigator.of(context).pop(); + } + _isLoadingVisible = false; } } -} +} \ No newline at end of file diff --git a/lib/uitl/laser_body_parts_data.dart b/lib/uitl/laser_body_parts_data.dart new file mode 100644 index 00000000..366201a0 --- /dev/null +++ b/lib/uitl/laser_body_parts_data.dart @@ -0,0 +1,136 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_svg/svg.dart'; + +class LaserBodyParts { + static final LaserBodyParts _instance = LaserBodyParts._internal(); + + LaserBodyParts._internal(); + + factory LaserBodyParts() => _instance; + + static Widget image(String assetUri) { + return new SvgPicture.asset(assetUri, fit: BoxFit.cover, width: 88, height: 88); + } + + static Widget imagePng(String assetUri) { + return Image.asset(assetUri, fit: BoxFit.cover, width: 88, height: 88); + } + + Map maleBodyMap = { + "1": imagePng("assets/images/new/body_parts/male/full_body_male.png"), + "40": imagePng("assets/images/new/body_parts/male/upper_arm.png"), + "41": imagePng("assets/images/new/body_parts/male/lower_arm.png"), + "42": imagePng("assets/images/new/body_parts/male/chest.png"), + "43": imagePng("assets/images/new/body_parts/male/chest_line.png"), + "44": imagePng("assets/images/new/body_parts/male/shoulders.png"), + "45": imagePng("assets/images/new/body_parts/male/back.png"), + "46": imagePng("assets/images/new/body_parts/male/abdomin.png"), + "47": imagePng("assets/images/new/body_parts/male/upper_legs.png"), + "48": imagePng("assets/images/new/body_parts/male/lower_legs.png"), + "49": imagePng("assets/images/new/body_parts/male/axilla.png") + }; + + Map maleFaceMap = { + "62": image("assets/images/new/body_parts/male/hydra_facial.svg"), + "5": image("assets/images/new/body_parts/male/upper_lips.svg"), + "6": image("assets/images/new/body_parts/male/chin.svg"), + "7": image("assets/images/new/body_parts/male/cheek.svg"), + "8": image("assets/images/new/body_parts/male/side_burn.svg"), + "9": image("assets/images/new/body_parts/male/ears.svg"), + "10": image("assets/images/new/body_parts/male/full_neck.svg"), + "11": image("assets/images/new/body_parts/male/half_neck.svg"), + "12": image("assets/images/new/body_parts/male/eyebrows.svg") + }; + + Map maleBodyRetouchMap = { + "50": imagePng("assets/images/new/body_parts/male/full_body_male.png"), + "51": imagePng("assets/images/new/body_parts/male/upper_arm.png"), + "52": imagePng("assets/images/new/body_parts/male/lower_arm.png"), + "53": imagePng("assets/images/new/body_parts/male/chest.png"), + "54": imagePng("assets/images/new/body_parts/male/shoulders.png"), + "55": imagePng("assets/images/new/body_parts/male/back.png"), + "56": imagePng("assets/images/new/body_parts/male/abdomin.png"), + "57": imagePng("assets/images/new/body_parts/male/full_legs.png"), + "58": imagePng("assets/images/new/body_parts/male/upper_legs.png"), + "59": imagePng("assets/images/new/body_parts/male/lower_legs.png"), + "60": imagePng("assets/images/new/body_parts/male/bikini.png"), + "61": imagePng("assets/images/new/body_parts/male/bikini_line.png") + }; + + Map femaleBodyMap = { + "1": imagePng("assets/images/new/body_parts/female/full_body_female.png"), + "40": imagePng("assets/images/new/body_parts/female/upper_arm.png"), + "41": imagePng("assets/images/new/body_parts/female/lower_arm.png"), + "42": imagePng("assets/images/new/body_parts/female/chest.png"), + "43": imagePng("assets/images/new/body_parts/female/chest_line.png"), + "44": imagePng("assets/images/new/body_parts/female/shoulders.png"), + "45": imagePng("assets/images/new/body_parts/female/back.png"), + "46": imagePng("assets/images/new/body_parts/female/abdomin.png"), + "47": imagePng("assets/images/new/body_parts/female/upper_legs.png"), + "48": imagePng("assets/images/new/body_parts/female/lower_leg.png"), + "49": imagePng("assets/images/new/body_parts/female/axilla.png") + }; + + Map femaleFaceMap = { + "62": image("assets/images/new/body_parts/female/hydra_facial.svg"), + "5": image("assets/images/new/body_parts/female/upper_lips.svg"), + "6": image("assets/images/new/body_parts/female/chin.svg"), + "7": image("assets/images/new/body_parts/female/cheeks.svg"), + "8": image("assets/images/new/body_parts/female/side_burn.svg"), + "9": image("assets/images/new/body_parts/female/ears.svg"), + "10": image("assets/images/new/body_parts/female/full_neck.svg"), + "11": image("assets/images/new/body_parts/female/half_neck.svg"), + "12": image("assets/images/new/body_parts/female/eyebrows.svg") + }; + + Map femaleBodyBikiniMap = { + "34": imagePng("assets/images/new/body_parts/female/bikini.png"), + "36": imagePng("assets/images/new/body_parts/female/bikini_line.png"), + "38": imagePng("assets/images/new/body_parts/female/buttocks.png"), + "39": imagePng("assets/images/new/body_parts/female/anal.png") + }; + + Map femaleBodyRetouchMap = { + "50": imagePng("assets/images/new/body_parts/female/full_body_female.png"), + "51": imagePng("assets/images/new/body_parts/female/upper_arm.png"), + "52": imagePng("assets/images/new/body_parts/female/lower_arm.png"), + "53": imagePng("assets/images/new/body_parts/female/chest.png"), + "54": imagePng("assets/images/new/body_parts/female/shoulders.png"), + "55": imagePng("assets/images/new/body_parts/female/back.png"), + "56": imagePng("assets/images/new/body_parts/female/abdomin.png"), + "57": imagePng("assets/images/new/body_parts/female/full_legs.png"), + "58": imagePng("assets/images/new/body_parts/female/upper_legs.png"), + "59": imagePng("assets/images/new/body_parts/female/lower_leg.png"), + "60": imagePng("assets/images/new/body_parts/female/bikini.png"), + "61": imagePng("assets/images/new/body_parts/female/bikini_line.png") + }; + + Widget? getCategoryImage(bool isMale, int category, String mappingCode) { + if (isMale) { + if (category == 1) { + return maleBodyMap![mappingCode]!; + } + if (category == 2) { + return maleFaceMap![mappingCode]!; + } + if (category == 11) { + return maleBodyRetouchMap![mappingCode]!; + } + } else { + if (category == 1) { + return femaleBodyMap![mappingCode]!; + } + if (category == 2) { + return femaleFaceMap![mappingCode]!; + } + if (category == 10) { + return femaleBodyBikiniMap![mappingCode]!; + } + if (category == 11) { + return femaleBodyRetouchMap![mappingCode]!; + } + } + return null; + } +} diff --git a/lib/uitl/location_util.dart b/lib/uitl/location_util.dart index e2edb2a1..6c170710 100644 --- a/lib/uitl/location_util.dart +++ b/lib/uitl/location_util.dart @@ -1,61 +1,77 @@ import 'dart:io'; -import 'package:connectivity/connectivity.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; import 'package:flutter/cupertino.dart'; -import 'package:flutter_hms_gms_availability/flutter_hms_gms_availability.dart'; import 'package:geolocator/geolocator.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; -import 'package:huawei_location/permission/permission_handler.dart'; -import 'package:huawei_location/location/fused_location_provider_client.dart'; -import 'package:huawei_location/location/location_request.dart'; -import 'package:huawei_location/location/location_settings_request.dart'; -import 'package:huawei_location/location/location_callback.dart'; -import 'package:huawei_location/location/location.dart'; -import 'package:huawei_location/location/location_settings_states.dart'; -import 'package:huawei_location/location/location_availability.dart'; +import 'package:huawei_location/huawei_location.dart'; import 'package:permission_handler/permission_handler.dart'; +import 'package:provider/provider.dart'; class LocationUtils { - AppSharedPreferences sharedPref = new AppSharedPreferences(); bool isShowConfirmDialog; + bool isShowLocationTimeoutDialog; BuildContext context; + bool isHuawei; + final GeolocatorPlatform _geolocatorPlatform = GeolocatorPlatform.instance; - LocationUtils({@required this.isShowConfirmDialog, @required this.context}); + LocationUtils({required this.isShowConfirmDialog, required this.context, this.isHuawei = false, this.isShowLocationTimeoutDialog = true}); - void getCurrentLocation({Function(LatLng) callBack}) async { - print("current location"); - if(Platform.isAndroid && (await FlutterHmsGmsAvailability.isHmsAvailable)) { - _getHMSCurrentLocation(callBack); - }else{ - Geolocator.isLocationServiceEnabled().then((value) { + void getCurrentLocation({Function(LatLng)? callBack}) async { + if (Platform.isAndroid && isHuawei) { + _getHMSCurrentLocation(callBack!); + } else { + Geolocator.isLocationServiceEnabled().then((value) async { if (value) { - Geolocator.checkPermission().then((permission) { - if (permission == LocationPermission.always || - permission == LocationPermission.whileInUse) { - Geolocator.getLastKnownPosition() - .then((value){ - setLocation(value); - if(callBack != null) - callBack(LatLng(value.latitude, value.longitude)); + await Geolocator.checkPermission().then((permission) async { + if (permission == LocationPermission.always || permission == LocationPermission.whileInUse) { + Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.medium, timeLimit: Duration(seconds: 5)).then((value) { + setLocation(value); + if (callBack != null) callBack(LatLng(value.latitude, value.longitude)); + }).catchError((err) { + print(err); + if (isShowConfirmDialog && isShowLocationTimeoutDialog) { + showLocationTimeOutDialog(failureCallBack: () { + Geolocator.openAppSettings(); + }); + } }); } - if (permission == LocationPermission.denied || - permission == LocationPermission.deniedForever) { - setZeroLocation(); - if (isShowConfirmDialog) showErrorLocationDialog(false); + if (permission == LocationPermission.denied || permission == LocationPermission.deniedForever) { + if (Platform.isAndroid) { + Utils.showPermissionConsentDialog(context, TranslationBase.of(context).locationPermissionDialog, () async { + final hasPermission = await _handlePermission(); + if (hasPermission) { + Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.medium, timeLimit: Duration(seconds: 10)).then((value) { + setLocation(value); + if (callBack != null) callBack(LatLng(value.latitude, value.longitude)); + }); + } else { + if (isShowConfirmDialog) showErrorLocationDialog(false, failureCallBack: () {}); + } + }); + } else { + if (await Permission.location.request().isGranted) { + getCurrentLocation(callBack: callBack); + } else { + setZeroLocation(); + if (isShowConfirmDialog) showErrorLocationDialog(false, failureCallBack: () {}); + } + } } }).catchError((err) { print(err); }); } else { - if (isShowConfirmDialog) showErrorLocationDialog(false); + if (isShowConfirmDialog) showErrorLocationDialog(false, failureCallBack: () {}); } }).catchError((err) { print(err); @@ -63,12 +79,61 @@ class LocationUtils { } } - LocationCallback _locationCallback; - _getHMSCurrentLocation(Function(LatLng) callBack) async{ - PermissionHandler permissionHandler = PermissionHandler(); + Future checkIfGPSIsEnabled() async { + if (Platform.isAndroid && isHuawei) { + FusedLocationProviderClient locationService = + FusedLocationProviderClient(); + LocationRequest locationRequest = LocationRequest(); + locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY; + locationRequest.interval = 1000; + List locationRequestList = [ + locationRequest + ]; + LocationSettingsRequest locationSettingsRequest = + LocationSettingsRequest(requests: locationRequestList); + bool success = false; + locationService + .checkLocationSettings(locationSettingsRequest) + .then((settings) { + success = true; + }); + return success; + } + return await Geolocator.isLocationServiceEnabled(); + } + + Future _handlePermission() async { + bool serviceEnabled; + LocationPermission permission; + + serviceEnabled = await _geolocatorPlatform.isLocationServiceEnabled(); + if (!serviceEnabled) { + return false; + } + + permission = await _geolocatorPlatform.checkPermission(); + if (permission == LocationPermission.denied) { + permission = await _geolocatorPlatform.requestPermission(); + if (permission == LocationPermission.denied) { + return false; + } + } + + if (permission == LocationPermission.deniedForever) { + return false; + } + return true; + } + + late LocationCallback _locationCallback; + + _getHMSCurrentLocation(Function(LatLng) callBack) async { + PermissionStatus permissionHandler = await Permission.location.request(); + + // print(statuses[Permission.location]); int _locationUpdateCbId = 0; - doIt(){ + doIt() { FusedLocationProviderClient locationService = FusedLocationProviderClient(); LocationRequest locationRequest = LocationRequest(); locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY; @@ -76,64 +141,105 @@ class LocationUtils { List locationRequestList = [locationRequest]; LocationSettingsRequest locationSettingsRequest = LocationSettingsRequest(requests: locationRequestList); - locationService.checkLocationSettings(locationSettingsRequest).then((settings) async{ - - _locationUpdateCbId = await locationService.requestLocationUpdatesCb(locationRequest, LocationCallback(onLocationResult: (locationResult){ - Location location = locationResult.lastLocation; - locationService.removeLocationUpdatesCb(_locationUpdateCbId); - callBack(LatLng(location.latitude, location.longitude)); - setLocation(Position(latitude: location.latitude, longitude: location.longitude, altitude: location.altitude)); - }, onLocationAvailability: (locationAvailability){ - debugPrint("onLocationAvailability: $locationAvailability"); - })); - - }).catchError((error){ - - if(error.code == "LOCATION_SETTINGS_NOT_AVAILABLE"){ + locationService.checkLocationSettings(locationSettingsRequest).then((settings) async { + _locationUpdateCbId = await locationService.requestLocationUpdatesCb( + locationRequest, + LocationCallback(onLocationResult: (locationResult) { + Location location = locationResult.lastLocation!; + locationService.removeLocationUpdatesCb(_locationUpdateCbId); + callBack(LatLng(location.latitude!, location.longitude!)); + setLocation( + Position( + latitude: location.latitude!, + longitude: location.longitude!, + altitude: location.altitude!, + timestamp: DateTime.now(), + accuracy: 1.0, + heading: 0.0, + speed: 0.0, + speedAccuracy: 1, + altitudeAccuracy: 0.0, + headingAccuracy: 0.0, + // altitudeAccuracy: 0.0, + // headingAccuracy: 0.0, + // altitudeAccuracy: 0, + // headingAccuracy: 0, + // Added by Aamir + ), + ); + }, onLocationAvailability: (locationAvailability) { + print("onLocationAvailability: $locationAvailability"); + })); + }).catchError((error) { + if (error.code == "LOCATION_SETTINGS_NOT_AVAILABLE") { // Location service not enabled. } - }); - } - - if(await permissionHandler.hasLocationPermission()){ + if (await permissionHandler.isGranted) { doIt(); - }else{ + } else { bool has = await requestPermissions(); - if(has) + if (has) doIt(); - else if(isShowConfirmDialog) - showErrorLocationDialog(false); - + else if (isShowConfirmDialog) showErrorLocationDialog(false); } } - showErrorLocationDialog(bool isPermissionError) { + showLocationTimeOutDialog({Function()? failureCallBack}) { + ConfirmDialog dialog = new ConfirmDialog( + context: context, + confirmMessage: TranslationBase.of(context).locationTimeoutError, + okText: TranslationBase.of(context).ok, + cancelText: TranslationBase.of(context).cancel_nocaps, + okFunction: () { + ConfirmDialog.closeAlertDialog(context); + Navigator.of(context).canPop(); + if (failureCallBack != null) { + failureCallBack(); + } + }, + cancelFunction: () { + if (failureCallBack != null) { + failureCallBack(); + } + }); + return dialog.showAlertDialog(context); + } + + showErrorLocationDialog(bool isPermissionError, {Function()? failureCallBack}) { + setLocation(null); ConfirmDialog dialog = new ConfirmDialog( context: context, confirmMessage: TranslationBase.of(context).locationDialogMessage, okText: TranslationBase.of(context).confirm, cancelText: TranslationBase.of(context).cancel_nocaps, - okFunction: () => { - ConfirmDialog.closeAlertDialog(context), - if (isPermissionError) - Geolocator.openAppSettings() - else - Geolocator.openLocationSettings() - }, - cancelFunction: () => {}); + okFunction: () { + ConfirmDialog.closeAlertDialog(context); + if (isPermissionError) + Geolocator.openAppSettings(); + else + Geolocator.openLocationSettings(); + Navigator.of(context).canPop(); + if (failureCallBack != null) { + failureCallBack(); + } + }, + cancelFunction: () { + if (failureCallBack != null) { + failureCallBack(); + } + }); return dialog.showAlertDialog(context); } - void setLocation(Position position) { - this - .sharedPref - .setDouble(USER_LAT, position != null ? position.latitude : 0.0); - this - .sharedPref - .setDouble(USER_LONG, position != null ? position.longitude : 0.0); + void setLocation(Position? position) { + this.sharedPref.setDouble(USER_LAT, position?.latitude ?? 0.0); + this.sharedPref.setDouble(USER_LONG, position?.longitude ?? 0.0); + ProjectViewModel projectViewModel = Provider.of(context, listen: false); + projectViewModel.setLatitudeLongitude( + position?.latitude ?? 0.0, position?.longitude ?? 0.0); } void setZeroLocation() { @@ -141,11 +247,10 @@ class LocationUtils { this.sharedPref.setDouble(USER_LONG, 0.0); } - Future requestPermissions() async { var result = await [ Permission.location, ].request(); - return (result[Permission.location].isGranted || result[Permission.locationAlways].isGranted); + return (result[Permission.location]!.isGranted || result[Permission.locationAlways]!.isGranted); } } diff --git a/lib/uitl/navigation_service.dart b/lib/uitl/navigation_service.dart index d4cd426b..c48f8a79 100644 --- a/lib/uitl/navigation_service.dart +++ b/lib/uitl/navigation_service.dart @@ -1,10 +1,30 @@ +import 'package:diplomaticquarterapp/locator.dart'; import 'package:flutter/material.dart'; +MaterialPageRoute _pageRoute(Widget page) => MaterialPageRoute(builder: (BuildContext context) => page); + class NavigationService { final GlobalKey navigatorKey = new GlobalKey(); - Future navigateTo(String routeName) { - return navigatorKey.currentState.pushNamed(routeName); + + static Future navigateTo(String routeName) { + final key = locator().navigatorKey; + return key.currentState!.pushNamed(routeName); + } + + static Future navigateToPage(Widget page) { + final key = locator().navigatorKey; + final pageRoute = MaterialPageRoute(builder: (context) => page); + return Navigator.push(key.currentContext!, pageRoute); } } + +class Navigate{ + static to({required Widget page}){ + final context = locator().navigatorKey.currentContext; + Navigator.of(context!).push(_pageRoute(page)); + } +} + +BuildContext? get currentContext => locator().navigatorKey.currentContext; diff --git a/lib/uitl/penguin_method_channel.dart b/lib/uitl/penguin_method_channel.dart new file mode 100644 index 00000000..50a642a7 --- /dev/null +++ b/lib/uitl/penguin_method_channel.dart @@ -0,0 +1,105 @@ +import 'package:flutter/services.dart'; + +class PenguinMethodChannel { + static const MethodChannel _channel = MethodChannel('launch_penguin_ui'); + + Future loadGif() async { + return await rootBundle.load("assets/images/progress-loading-red-crop-1.gif").then((data) => data.buffer.asUint8List()); + } + + Future launch(String storyboardName, String languageCode, String username, {NavigationClinicDetails? details}) async { + Uint8List image = await loadGif(); + try { + await _channel.invokeMethod('launchPenguin', { + "storyboardName": storyboardName, + "baseURL": "https://prod.hmg.nav.penguinin.com", + // "dataURL": "https://hmg.nav.penguinin.com", + // "positionURL": "https://hmg.nav.penguinin.com", + // "dataURL": "https://hmg-v33.local.penguinin.com", + // "positionURL": "https://hmg-v33.local.penguinin.com", + "dataURL": "https://prod.hmg.nav.penguinin.com", + "positionURL": "https://prod.hmg.nav.penguinin.com", + "dataServiceName": "api", + "positionServiceName": "pe", + "clientID": "HMG", + // "username": "Haroon", + "username": username, + "isSimulationModeEnabled": false, + "isShowUserName": false, + "isUpdateUserLocationSmoothly": true, + "isEnableReportIssue": true, + "languageCode": languageCode, + "clientKey": "UGVuZ3VpbklOX1Blbk5hdl9QSUY=", + "mapBoxKey": "sk.eyJ1IjoicndhaWQiLCJhIjoiY2x6NWo0bTMzMWZodzJrcGZpemYzc3Z4dSJ9.uSSZuwNSGCcCdPAiORECmg", + "clinicID": details?.clinicId ?? "", + // "clinicID": "108", // 46 ,49, 133 + "patientID": details?.patientId ?? "", + "projectID": details?.projectId ?? "", + "loaderImage": image, + }); + } on PlatformException catch (e) { + print("Failed to launch PenguinIn: '${e.message}'."); + } + } + + void setMethodCallHandler(){ + _channel.setMethodCallHandler((MethodCall call) async { + try { + + print(call.method); + + switch (call.method) { + + case PenguinMethodNames.onPenNavInitializationError: + _handleInitializationError(call.arguments); // Handle onPenNavInitializationError errors. + break; + case PenguinMethodNames.onPenNavUIDismiss: + //todo handle pen dismissable + // _handlePenNavUIDismiss(); // Handle UI dismissal event. + break; + case PenguinMethodNames.onReportIssue: + // Handle the report issue event. + _handleInitializationError(call.arguments); + break; + default: + _handleUnknownMethod(call.method); // Handle unknown method calls. + } + } catch (e) { + print("Error handling method call '${call.method}': $e"); + // Optionally, log this error to an external service + } + }); + } + static void _handleUnknownMethod(String method) { + print("Unknown method: $method"); + // Optionally, handle this unknown method case, such as reporting or ignoring it + } + + + static void _handleInitializationError(Map error) { + final type = error['type'] as String?; + final description = error['description'] as String?; + print("Initialization Error: ${type ?? 'Unknown Type'}, ${description ?? 'No Description'}"); + + } + +} +// Define constants for method names +class PenguinMethodNames { + static const String showPenguinUI = 'showPenguinUI'; + static const String openSharedLocation = 'openSharedLocation'; + + // ---- Handler Method + static const String onPenNavSuccess = 'onPenNavSuccess'; // Tested Android,iOS + static const String onPenNavInitializationError = 'onPenNavInitializationError'; // Tested Android,iOS + static const String onPenNavUIDismiss = 'onPenNavUIDismiss'; //Tested Android,iOS + static const String onReportIssue = 'onReportIssue'; // Tested Android,iOS + static const String onLocationOffCampus = 'onLocationOffCampus'; // Tested iOS,Android + static const String navigateToPOI = 'navigateToPOI'; // Tested Android,iOS +} + +class NavigationClinicDetails { + String? clinicId; + String? patientId; + String? projectId; +} diff --git a/lib/uitl/push-notification-handler.dart b/lib/uitl/push-notification-handler.dart new file mode 100644 index 00000000..c6ae36d3 --- /dev/null +++ b/lib/uitl/push-notification-handler.dart @@ -0,0 +1,467 @@ +import 'dart:async'; +import 'dart:convert'; +import 'dart:io'; + +import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/model/notifications/get_notifications_response_model.dart'; +import 'package:diplomaticquarterapp/locator.dart'; +import 'package:diplomaticquarterapp/models/LiveCare/IncomingCallData.dart'; +import 'package:diplomaticquarterapp/pages/DrawerPages/notifications/notification_details_page.dart'; +import 'package:diplomaticquarterapp/pages/conference/zoom/call_screen.dart'; +import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; +import 'package:diplomaticquarterapp/pages/livecare/incoming_call.dart'; +import 'package:diplomaticquarterapp/pages/webRTC/OpenTok/OpenTok.dart'; +import 'package:diplomaticquarterapp/uitl/LocalNotification.dart'; +import 'package:diplomaticquarterapp/uitl/app-permissions.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/penguin_method_channel.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:firebase_messaging/firebase_messaging.dart'; +import 'package:firebase_messaging/firebase_messaging.dart' as fir; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +// import 'package:flutter_ios_voip_kit/call_state_type.dart'; +// import 'package:flutter_ios_voip_kit/flutter_ios_voip_kit.dart'; +import 'package:flutter_local_notifications/flutter_local_notifications.dart'; +import 'package:get_it/get_it.dart'; +import 'package:huawei_hmsavailability/huawei_hmsavailability.dart'; +import 'package:huawei_push/huawei_push.dart' as h_push; +import 'package:permission_handler/permission_handler.dart'; + +import 'app_shared_preferences.dart'; +import 'navigation_service.dart'; + +// |--> Push Notification Background +@pragma('vm:entry-point') +Future backgroundMessageHandler(dynamic message) async { + print("Firebase backgroundMessageHandler!!!"); + fir.RemoteMessage message_; + if (message is h_push.RemoteMessage) { + // if huawei remote message convert it to Firebase Remote Message + message_ = toFirebaseRemoteMessage(message); + h_push.Push.localNotification({h_push.HMSLocalNotificationAttr.TITLE: 'Background Message', h_push.HMSLocalNotificationAttr.MESSAGE: "By: BackgroundMessageHandler"}); + } + + if (message.data != null && (message.data['is_call'] == 'true' || message.data['is_call'] == true)) { + // showCallkitIncoming(message); + _incomingCall(message.data); + return; + } else { + GetNotificationsResponseModel notification = new GetNotificationsResponseModel(); + + notification.createdOn = DateUtil.convertDateToString(DateTime.now()); + notification.messageTypeData = message.data['picture']; + notification.message = message.data['message']; + await NavigationService.navigateToPage(NotificationsDetailsPage( + notification: notification, + )); + } +} + +// Push Notification Background <--| + +RemoteMessage toFirebaseRemoteMessage(h_push.RemoteMessage message) { + final payload_data = jsonDecode(message.data!); + final fire_message = RemoteMessage( + from: message.from, + collapseKey: message.collapseKey, + data: payload_data['data'], + messageId: message.messageId, + sentTime: DateTime.fromMillisecondsSinceEpoch(message.sentTime! * 1000), + ttl: message.ttl, + category: null, + messageType: message.type, + notification: RemoteNotification( + title: message.notification!.title!, + titleLocArgs: (message.notification!.titleLocalizationArgs! ?? []).map((e) => e.toString()).toList(), + titleLocKey: message.notification!.titleLocalizationKey!, + body: message.notification!.body!, + bodyLocArgs: (message.notification!.bodyLocalizationArgs ?? []).map((e) => e.toString()).toList(), + bodyLocKey: message.notification!.bodyLocalizationKey, + android: AndroidNotification( + channelId: message.notification!.channelId, + clickAction: message.notification!.clickAction, + color: message.notification!.color, + count: null, + imageUrl: message.notification!.imageUrl!.path, + link: message.notification!.link!.path, + smallIcon: message.notification!.icon, + sound: message.notification!.sound, + ticker: message.notification!.ticker, + tag: message.notification!.tag, + ), + )); + return fire_message; +} + +// callPage(String sessionID, String token, String isWebrtc, String callerIdString) async { +callPage(String sessionID, String token) async { + // if (isWebrtc == "true"){ + // String caller = callerIdString.split("*")[3]; + // String receiver = callerIdString.split("*")[4]; + // String host = callerIdString.split("*")[5]; + // return StartVideoCall(caller: caller, receiver: receiver, iAmCaller: false, host: host); + // }else{ + await NavigationService.navigateToPage(OpenTokConnectCallPage(apiKey: OPENTOK_API_KEY, sessionId: sessionID, token: token)); + // } +} + +// Future showCallkitIncoming(Map message) async { +// // if (message['type'] == 'ReservationCallStart') { +// var params = CallKitParams( +// id: DateTime.now().millisecondsSinceEpoch.toString(), +// nameCaller: 'Dr Sulaiman Al Habib', +// appName: 'Dr Sulaiman Al Habib', +// avatar: 'https://play-lh.googleusercontent.com/FBNNpxb7m6eM6wtW7MV1Ffp6OXOGLI38q47zcvP29OCYA1yhYH5mZzl5itZi0TgOyZpG', +// handle: 'LiveCare Call', +// type: 1, +// duration: 60000, +// textAccept: 'Accept', +// textDecline: 'Decline', +// textMissedCall: 'Missed call', +// textCallback: 'Call back', +// extra: { +// // 'reservationID': message['id'], +// 'userId': '1a2b3c4d' +// }, +// headers: {'apiKey': 'Abc@123!', 'platform': 'flutter'}, +// android: AndroidParams( +// isCustomNotification: true, +// isShowLogo: false, +// isShowCallback: false, +// ringtonePath: 'system_ringtone_default', +// backgroundColor: '#424242FF', +// // 'backgroundUrl': 'https://i.pravatar.cc/500', +// actionColor: '#4CAF50', +// incomingCallNotificationChannelName: "Incoming Call", +// missedCallNotificationChannelName: "Missed Call", +// ), +// ios: IOSParams( +// iconName: 'CallKitLogo', +// handleType: '', +// supportsVideo: true, +// maximumCallGroups: 2, +// maximumCallsPerCallGroup: 1, +// audioSessionMode: 'default', +// audioSessionActive: true, +// audioSessionPreferredSampleRate: 44100.0, +// audioSessionPreferredIOBufferDuration: 0.005, +// supportsDTMF: true, +// supportsHolding: true, +// supportsGrouping: false, +// supportsUngrouping: false, +// ringtonePath: 'system_ringtone_default')); +// await FlutterCallkitIncoming.showCallkitIncoming(params); +// // } else if (message['type'] == 'ReservationCallFinished') { +// // await FlutterCallkitIncoming.endAllCalls(); +// // } +// } + +_incomingCall(Map data) async { + LandingPage.incomingCallData = IncomingCallData.fromJson(data); + if (LandingPage.isOpenCallPage == false) { + LandingPage.isOpenCallPage = true; + final bool permited = await AppPermission.askVideoCallPermission(currentContext!); + if (permited) + await NavigationService.navigateToPage( + IncomingCall(incomingCallData: LandingPage.incomingCallData), + ); + + LandingPage.isOpenCallPage = false; + } + await Future.delayed(Duration(milliseconds: 500)); + await AppSharedPreferences().remove('call_data'); +} + +class PushNotificationHandler { + late BuildContext context; + static final PushNotificationHandler _instance = PushNotificationHandler._internal(); + + late HmsApiAvailability hmsApiAvailability; + + // final voIPKit = FlutterIOSVoIPKit.instance; + + late Timer timeOutTimer; + bool isTalking = false; + + var data = { + "AppointmentNo": "2016059247", + "ProjectID": "15", + "NotificationType": "10", + "background": "0", + "doctorname": "Call from postman", + "clinicname": "LIVECARE FAMILY MEDICINE AND GP", + "speciality": "General Practioner", + "appointmentdate": "2022-01-19", + "appointmenttime": "12:10", + "PatientName": "Testing", + "session_id": "1_MX40NjIwOTk2Mn5-MTY1NDE2NDQxMjc2Mn5xc3NCZkNIejJOdzgzTkg2TmlXblhQdnl-fg", + "token": + "T1==cGFydG5lcl9pZD00NjIwOTk2MiZzaWc9MTliNTA3NDAxYmU0MjI5OGY5NTcxZTdhNzQyMTcyZjRjMjBhNjljZTpzZXNzaW9uX2lkPTFfTVg0ME5qSXdPVGsyTW41LU1UWTFOREUyTkRReE1qYzJNbjV4YzNOQ1prTkllakpPZHpnelRrZzJUbWxYYmxoUWRubC1mZyZjcmVhdGVfdGltZT0xNjU0MTY0NDEzJm5vbmNlPTAuNjM3ODkzNDk4NDQ2NTIxOSZyb2xlPW1vZGVyYXRvciZleHBpcmVfdGltZT0xNjU0MjUwODEzJmluaXRpYWxfbGF5b3V0X2NsYXNzX2xpc3Q9", + "DoctorImageURL": "https://image.shutterstock.com/image-vector/sample-stamp-square-grunge-sign-260nw-1474408826.jpg", + "callerID": "9920", + "PatientID": "1231755", + "is_call": "true" + }; + + PushNotificationHandler._internal(); + + factory PushNotificationHandler() => _instance; + + static PushNotificationHandler getInstance() => _instance; + + // void _timeOut({ + // int seconds = 30, + // }) async { + // timeOutTimer = Timer(Duration(seconds: seconds), () async { + // print('🎈 example: timeOut'); + // final incomingCallerName = await voIPKit.getIncomingCallerName(); + // voIPKit.unansweredIncomingCall( + // skipLocalNotification: false, + // missedCallTitle: '📞 Missed call', + // missedCallBody: 'There was a call from $incomingCallerName', + // ); + // }); + // } + + init(BuildContext context) async { + this.context = context; + + if (Platform.isIOS) { + // voIPKit.getVoIPToken().then((value) { + // print("APNS VOIP KIT TOKEN: $value"); + // AppSharedPreferences().setString(APNS_TOKEN, value!); + // }); + // + // voIPKit.onDidUpdatePushToken = (String token) { + // print('🎈 example: onDidUpdatePushToken: $token'); + // }; + // + // voIPKit.onDidReceiveIncomingPush = ( + // Map payload, + // ) async { + // print('🎈 example: onDidReceiveIncomingPush $payload'); + // _timeOut(); + // }; + // + // voIPKit.onDidRejectIncomingCall = ( + // String uuid, + // String callerId, + // ) async { + // try { + // print('🎈 example: onDidRejectIncomingCall $uuid - $callerId'); + // timeOutTimer.cancel(); + // } catch (err) {} + // }; + // + // voIPKit.onDidAcceptIncomingCall = ( + // String uuid, + // String callerId, + // ) async { + // print('🎈 example: onDidAcceptIncomingCall $uuid - $callerId'); + // await voIPKit.acceptIncomingCall(callerState: CallStateType.calling); + // await voIPKit.callConnected(); + // await Future.delayed(Duration(seconds: 1)); + // + // Navigator.pushNamed( + // locator().navigatorKey.currentContext!, + // "zoom_call_page", + // arguments: CallArguments("hoover-dam", "123", "Patient", "40", "1", false), + // ); + // + // await voIPKit.endCall(); + // + // // Navigator.pushNamed(navigatorKey.currentContext!, VIDEO_CALL_SCREEN, + // // arguments: VideoArgus( + // // reservationId: int.parse(callerId), token: null, isVideo: true)); + // + // timeOutTimer.cancel(); + // }; + } + + if (Platform.isAndroid) { + try { + if (!(await Utils.isGoogleServicesAvailable())) { + h_push.Push.enableLogger(); + final result = await h_push.Push.setAutoInitEnabled(true); + + h_push.Push.onNotificationOpenedApp.listen((message) { + newMessage(toFirebaseRemoteMessage(message)); + }, onError: (e) => print(e.toString())); + + h_push.Push.onMessageReceivedStream.listen((message) { + newMessage(toFirebaseRemoteMessage(message)); + }, onError: (e) => print(e.toString())); + + h_push.Push.getTokenStream.listen((token) { + onToken(token); + }, onError: (e) => print(e.toString())); + h_push.Push.getToken(''); + + h_push.Push.registerBackgroundMessageHandler(backgroundMessageHandler); + } else { + final fcmToken = await FirebaseMessaging.instance.getToken(); + if (fcmToken != null) onToken(fcmToken); + } + } catch (ex) { + print("Notification Exception: " + ex.toString()); + } + } + + if (Platform.isIOS) { + await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions( + alert: true, // Required to display a heads up notification + badge: true, + sound: true, + ); + final permission = await FirebaseMessaging.instance.requestPermission(); + if (permission.authorizationStatus == AuthorizationStatus.denied) return; + } else {} + + try { + FirebaseMessaging.instance.getInitialMessage().then((RemoteMessage? message) async { + if (message != null) { + if (Platform.isIOS) + await Future.delayed(Duration(milliseconds: 3000)).then((value) { + if (message != null) newMessage(message); + }); + else if (message != null) newMessage(message); + } + }); + } catch (ex) {} + + FirebaseMessaging.onMessage.listen((RemoteMessage message) async { + print("Firebase onMessage!!!"); + if (Platform.isIOS) + await Future.delayed(Duration(milliseconds: 3000)).then((value) { + newMessage(message); + }); + else + newMessage(message); + }); + + FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) async { + print("Firebase onMessageOpenedApp!!!"); + if (Platform.isIOS) + await Future.delayed(Duration(milliseconds: 3000)).then((value) { + newMessage(message); + }); + else + newMessage(message); + }); + + FirebaseMessaging.onBackgroundMessage(backgroundMessageHandler); + + FirebaseMessaging.instance.getToken(vapidKey: 'BHRJG8sIzcysWxPw3B6xQjz_85nUuCfU6EAmpH18kyUTmB2cj35IdFwCyWSab80SA1v6oBSWVh-p6PcHPw_y00Y').then((String? token) { + print("Push Notification getToken: " + token!); + onToken(token!); + }).catchError((err) { + print(err); + }); + + FirebaseMessaging.instance.onTokenRefresh.listen((fcm_token) { + print("Push Notification onTokenRefresh: " + fcm_token); + onToken(fcm_token); + }); + + // FirebaseMessaging.instance.getToken(vapidKey: 'BHRJG8sIzcysWxPw3B6xQjz_85nUuCfU6EAmpH18kyUTmB2cj35IdFwCyWSab80SA1v6oBSWVh-p6PcHPw_y00Y').then((String? token) { + // print("Push Notification getToken: " + token!); + // onToken(token!); + // }); + // FirebaseMessaging.instance.getToken(vapidKey: 'BHRJG8sIzcysWxPw3B6xQjz_85nUuCfU6EAmpH18kyUTmB2cj35IdFwCyWSab80SA1v6oBSWVh-p6PcHPw_y00Y').then((String? token) { + // print("Push Notification getToken: " + token!); + // onToken(token!); + // }); + + // if (Platform.isIOS) { + // FirebaseMessaging.instance.getAPNSToken().then((value) { + // print("Push APNS getToken: " + value!); + // }); + // } + + FirebaseMessaging.onBackgroundMessage(backgroundMessageHandler); + } + + newMessage(RemoteMessage remoteMessage) async { + print("Remote Message: " + remoteMessage.data.toString()); + if (remoteMessage.data.isEmpty) { + return; + } + debugPrint('the value of the remote message is ${remoteMessage.data}'); + if (remoteMessage.data['is_call'] == 'true' || remoteMessage.data['is_call'] == true) { + _incomingCall(remoteMessage.data); + // showCallkitIncoming(remoteMessage.data); + } + else if (remoteMessage.data['is_navigation'] == 'true' || remoteMessage.data['is_navigation'] == true) { + NavigationClinicDetails data = NavigationClinicDetails(); + data.clinicId = remoteMessage.data['clinic_Id']; + data.patientId = remoteMessage.data['patient_Id']; + data.projectId = remoteMessage.data['project_Id']; + initPenguinSDK(data); + } else { + GetNotificationsResponseModel notification = new GetNotificationsResponseModel(); + + notification.createdOn = DateUtil.convertDateToString(DateTime.now()); + notification.messageTypeData = remoteMessage.data['picture']; + notification.message = remoteMessage.data['message']; + notification.notificationType = remoteMessage.data["NotificationType"].toString(); + if (remoteMessage.data["NotificationType"] == "2") { + notification.videoURL = remoteMessage.data["VideoUrl"]; + } + + await NavigationService.navigateToPage(NotificationsDetailsPage( + notification: notification, + )); + } + } + + initPenguinSDK(NavigationClinicDetails data) async { + final bool permited = await AppPermission.askPenguinPermissions(); + if (!permited) { + Map statuses = await [ + Permission.location, + Permission.bluetooth, + Permission.bluetoothConnect, + Permission.bluetoothScan, + Permission.activityRecognition, + ].request().whenComplete(() { + PenguinMethodChannel().launch("penguin", "en", "1231755", details: data); + }); + } + } + + onToken(String token) async { + // print("Push Notification Token: " + token); + await AppSharedPreferences().setString(PUSH_TOKEN, token); + DEVICE_TOKEN = token; + } + + onResume() async { + var call_data = await AppSharedPreferences().getObject('call_data'); + if (call_data != null) { + _incomingCall(call_data); + } + } + + Future requestPermissions() async { + try { + if (Platform.isIOS) { + await flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation()?.requestPermissions(alert: true, badge: true, sound: true); + } else if (Platform.isAndroid) { + Map statuses = await [ + Permission.notification, + // Permission.camera, + // Permission.audio, + // Permission.microphone, + ].request(); + print("=-=-=-=-=-=-=-=-=-=-"); + print(statuses[Permission.location]); + } + } catch (_) { + debugPrint(_.toString()); + } + } +} diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index 0e0058f9..1f1438a8 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -1,7 +1,6 @@ import 'dart:async'; import 'package:diplomaticquarterapp/config/localized_values.dart'; -import 'package:diplomaticquarterapp/pages/symptom-checker/select-gender.dart'; import 'package:flutter/foundation.dart' show SynchronousFuture; import 'package:flutter/material.dart'; @@ -11,15 +10,16 @@ class TranslationBase { final Locale locale; static TranslationBase of(BuildContext context) { - return Localizations.of(context, TranslationBase); + return Localizations.of(context, TranslationBase)!; } String by(String key) { return localizedValues[key][locale.languageCode]; } - String get dashboardScreenToolbarTitle => - localizedValues['dashboardScreenToolbarTitle'][locale.languageCode]; + String get dashboardScreenToolbarTitle => localizedValues['dashboardScreenToolbarTitle'][locale.languageCode]; + + String get bloodType1 => localizedValues['bloodType'][locale.languageCode]; String get settings => localizedValues['settings'][locale.languageCode]; @@ -49,65 +49,95 @@ class TranslationBase { String get clinic => localizedValues['clinic'][locale.languageCode]; + String get byClinic => localizedValues['by-clinic'][locale.languageCode]; + + String get byHospital => localizedValues['by-hospital'][locale.languageCode]; + String get name => localizedValues['name'][locale.languageCode]; String get doctor => localizedValues['doctor'][locale.languageCode]; String get clinicName => localizedValues['clinicName'][locale.languageCode]; + String get hospitalName => localizedValues['hospitalName'][locale.languageCode]; + String get doctorName => localizedValues['doctorName'][locale.languageCode]; + String get NoClinicFound => localizedValues['NoClinicFound'][locale.languageCode]; + String get nearestAppo => localizedValues['nearestAppo'][locale.languageCode]; - String get searchByDocText => - localizedValues['searchByDocText'][locale.languageCode]; + String get searchByDocText => localizedValues['searchByDocText'][locale.languageCode]; - String get enterDocName => - localizedValues['enterDocName'][locale.languageCode]; + String get enterDocName => localizedValues['enterDocName'][locale.languageCode]; String get search => localizedValues['search'][locale.languageCode]; + String get noResultFound => localizedValues['noResultFound'][locale.languageCode]; + + String get noSearchResultFound => localizedValues['noSearchResultFound'][locale.languageCode]; + + String get pleaseEnterProductName => localizedValues['pleaseEnterProductName'][locale.languageCode]; + String get bookNow => localizedValues['bookNow'][locale.languageCode]; + String get reviewAppointment => localizedValues['reviewAppointment'][locale.languageCode]; + String get docInfo => localizedValues['docInfo'][locale.languageCode]; String get appoInfo => localizedValues['appoInfo'][locale.languageCode]; - String get availableAppo => - localizedValues['availableAppo'][locale.languageCode]; + String get availableAppo => localizedValues['availableAppo'][locale.languageCode]; String get gender => localizedValues['gender'][locale.languageCode]; + String get pleaseSelectGender => localizedValues['please_select_gender'][locale.languageCode]; + String get nationality => localizedValues['nationality'][locale.languageCode]; - String get docQualifications => - localizedValues['docQualifications'][locale.languageCode]; + String get docQualifications => localizedValues['docQualifications'][locale.languageCode]; - String get confirmAppoHeading => - localizedValues['confirmAppoHeading'][locale.languageCode]; + String get confirmAppoHeading => localizedValues['confirmAppoHeading'][locale.languageCode]; String get patientInfo => localizedValues['patientInfo'][locale.languageCode]; String get bookSuccess => localizedValues['bookSuccess'][locale.languageCode]; - String get patientShare => - localizedValues['patientShare'][locale.languageCode]; + String get patientShare => localizedValues['patientShare'][locale.languageCode]; + + String get neverWait => localizedValues['neverWait'][locale.languageCode]; + + String get patientShareWithTax => localizedValues['patientShareWithTax'][locale.languageCode]; - String get patientShareWithTax => - localizedValues['patientShareWithTax'][locale.languageCode]; + String get reminderTitle => localizedValues['reminderTitle'][locale.languageCode]; String get confirmAppo => localizedValues['confirmAppo'][locale.languageCode]; + String get appointmentCalendar => localizedValues['appointmentCalendar'][locale.languageCode]; + + String get appointmentReminder => localizedValues['appointmentReminder'][locale.languageCode]; + + String get prescriptionReminder => localizedValues['prescriptionReminder'][locale.languageCode]; + + String get pleaseSelectFromBelowOptions => localizedValues['please_select_from_below_options'][locale.languageCode]; + + String get appointmentSuccess => localizedValues['appointmentSuccess'][locale.languageCode]; + String get confirm => localizedValues['confirm'][locale.languageCode]; - String get confirmLiveCare => - localizedValues['confirmLiveCare'][locale.languageCode]; + String get pressAgain => localizedValues['pressAgain'][locale.languageCode]; + + String get laserMaxLimitReach => localizedValues['laserMaxLimitReach'][locale.languageCode]; + + String get confirmLiveCare => localizedValues['confirmLiveCare'][locale.languageCode]; + + String get doctorFilter => localizedValues['doctorFilter'][locale.languageCode]; - String get waitingForDoctor => - localizedValues['waitingForDoctor'][locale.languageCode]; + String get waitingForDoctor => localizedValues['waitingForDoctor'][locale.languageCode]; - String get confirmLater => - localizedValues['confirmLater'][locale.languageCode]; + String get waitingTime => localizedValues['waitingTime'][locale.languageCode]; + + String get confirmLater => localizedValues['confirmLater'][locale.languageCode]; String get todoList => localizedValues['todoList'][locale.languageCode]; @@ -123,47 +153,51 @@ class TranslationBase { String get login => localizedValues['login'][locale.languageCode]; - String get loginregister => - localizedValues['loginregister'][locale.languageCode]; + String get loginregister => localizedValues['loginregister'][locale.languageCode]; String get poweredBy => localizedValues['poweredBy'][locale.languageCode]; String get welcome => localizedValues['welcome'][locale.languageCode]; - String get welcomeText => - localizedValues['welcome_text'][locale.languageCode]; + String get welcomeTo => localizedValues['welcome-to'][locale.languageCode]; + + String get drSulaimanText => localizedValues['dr-sulaiman-text'][locale.languageCode]; + + String get patientApp => localizedValues['patient-app'][locale.languageCode]; + + String get welcomeText => localizedValues['welcome_text'][locale.languageCode]; - String get welcomeText2 => - localizedValues['welcome_text2'][locale.languageCode]; + String get welcomeText2 => localizedValues['welcome_text2'][locale.languageCode]; String get yes => localizedValues['yes'][locale.languageCode]; String get no => localizedValues['no'][locale.languageCode]; - String get logintypeRadio => - localizedValues['logintyperadio'][locale.languageCode]; - String get registerInfoFamily => - localizedValues['register-info-family'][locale.languageCode]; + String get logintypeRadio => localizedValues['logintyperadio'][locale.languageCode]; + + String get registerInfoFamily => localizedValues['register-info-family'][locale.languageCode]; String get registerNow => localizedValues['registernow'][locale.languageCode]; String get nationalID => localizedValues['nationalID'][locale.languageCode]; + String get medicalFileNumber => localizedValues['medical-file-number'][locale.languageCode]; + + String get nationalIdNumber => localizedValues['national-id-number'][locale.languageCode]; + String get idNo => localizedValues['national-id'][locale.languageCode]; String get fileNo => localizedValues['fileNo'][locale.languageCode]; + String get fileno => localizedValues['fileno'][locale.languageCode]; - String get forgotPassword => - localizedValues['forgotFileNo'][locale.languageCode]; - String get forgotFileNoTitle => - localizedValues['forgotFileNoTitle'][locale.languageCode]; + String get forgotPassword => localizedValues['forgotFileNo'][locale.languageCode]; - String get enterNationalId => - localizedValues['enter-national-id'][locale.languageCode]; + String get forgotFileNoTitle => localizedValues['forgotFileNoTitle'][locale.languageCode]; - String get profileInfo => - localizedValues['profile-info'][locale.languageCode]; + String get enterNationalId => localizedValues['enter-national-id'][locale.languageCode]; + + String get profileInfo => localizedValues['profile-info'][locale.languageCode]; String get submit => localizedValues['submit'][locale.languageCode]; @@ -173,78 +207,65 @@ class TranslationBase { String get hijriDate => localizedValues['hijri-date'][locale.languageCode]; - String get gregorianDate => - localizedValues['gregorian-date'][locale.languageCode]; + String get gregorianDate => localizedValues['gregorian-date'][locale.languageCode]; - String get verifyLoginWith => - localizedValues['verify-login-with'][locale.languageCode]; + String get verifyLoginWith => localizedValues['verify-login-with'][locale.languageCode]; String get register => localizedValues['register-user'][locale.languageCode]; - String get verifyFingerprint => - localizedValues['verify-with-fingerprint'][locale.languageCode]; + String get verifyFingerprint => localizedValues['verify-with-fingerprint'][locale.languageCode]; + + String get verifyFaceID => localizedValues['verify-with-faceid'][locale.languageCode]; - String get verifyFaceID => - localizedValues['verify-with-faceid'][locale.languageCode]; + String get verifySMS => localizedValues['verify-with-sms'][locale.languageCode]; - String get verifySMS => - localizedValues['verify-with-sms'][locale.languageCode]; + String get verifyWhatsApp => localizedValues['verify-with-whatsapp'][locale.languageCode]; - String get verifyWhatsApp => - localizedValues['verify-with-whatsapp'][locale.languageCode]; + String get verifyThrough => localizedValues['verify-through'][locale.languageCode]; String get lastLoginAt => localizedValues['last-login'][locale.languageCode]; - String get lastLoginWith => - localizedValues['last-login-with'][locale.languageCode]; + String get pleaseVerify => localizedValues['please-verify'][locale.languageCode]; - String get verifyFingerprint2 => - localizedValues['verify-fingerprint'][locale.languageCode]; + String get lastLoginWith => localizedValues['last-login-with'][locale.languageCode]; - String get searchMedicine => - localizedValues['searchMedicine'][locale.languageCode]; + String get verifyFingerprint2 => localizedValues['verify-fingerprint'][locale.languageCode]; - String get searchMedicineHere => - localizedValues['searchMedicineHere'][locale.languageCode]; + String get searchMedicine => localizedValues['searchMedicine'][locale.languageCode]; - String get pendingPayment => - localizedValues['pendingPayment'][locale.languageCode]; + String get searchMedicineHere => localizedValues['searchMedicineHere'][locale.languageCode]; + + String get pendingPayment => localizedValues['pendingPayment'][locale.languageCode]; String get payNow => localizedValues['payNow'][locale.languageCode]; + String get dailyWater => localizedValues['dailyWater'][locale.languageCode]; + String get viewQR => localizedValues['viewQR'][locale.languageCode]; String get instruction => localizedValues['instruction'][locale.languageCode]; String get livecare => localizedValues['livecare'][locale.languageCode]; - String get upcomingNoAction => - localizedValues['upcoming-noAction'][locale.languageCode]; + String get upcomingNoAction => localizedValues['upcoming-noAction'][locale.languageCode]; - String get upcomingConfirm => - localizedValues['upcoming-confirm'][locale.languageCode]; + String get upcomingConfirm => localizedValues['upcoming-confirm'][locale.languageCode]; - String get upcomingPaymentPending => - localizedValues['upcoming-payment-pending'][locale.languageCode]; - String get upcomingConfirmMore => - localizedValues['book-success-confirm-more-24-1-2'][locale.languageCode]; + String get upcomingPaymentPending => localizedValues['upcoming-payment-pending'][locale.languageCode]; - String get upcomingPaymentNow => - localizedValues['upcoming-payment-now'][locale.languageCode]; + String get upcomingConfirmMore => localizedValues['book-success-confirm-more-24-1-2'][locale.languageCode]; + + String get upcomingPaymentNow => localizedValues['upcoming-payment-now'][locale.languageCode]; String get upcomingQR => localizedValues['upcoming-QR'][locale.languageCode]; - String get upcomingVirtual => - localizedValues['upcoming-virtual'][locale.languageCode]; + String get upcomingVirtual => localizedValues['upcoming-virtual'][locale.languageCode]; - String get upcomingLivecare => - localizedValues['upcoming-livecare'][locale.languageCode]; + String get upcomingLivecare => localizedValues['upcoming-livecare'][locale.languageCode]; - String get liveCareAppo => - localizedValues['livecareAppo'][locale.languageCode]; + String get liveCareAppo => localizedValues['livecareAppo'][locale.languageCode]; - String get upcomingDetails => - localizedValues['upcoming-details'][locale.languageCode]; + String get upcomingDetails => localizedValues['upcoming-details'][locale.languageCode]; String get reschedule => localizedValues['reschedule'][locale.languageCode]; @@ -260,99 +281,178 @@ class TranslationBase { String get online => localizedValues['online'][locale.languageCode]; + String get viewMedicalFile => localizedValues['viewMedicalFile'][locale.languageCode]; + + String get viewAllServices => localizedValues['viewAllServices'][locale.languageCode]; + + String get medicalFile => localizedValues['medicalFile'][locale.languageCode]; + + String get verified => localizedValues['verified'][locale.languageCode]; + + String get onlineConsulting => localizedValues['onlineConsulting'][locale.languageCode]; + + String get checkup => localizedValues['checkup'][locale.languageCode]; + + String get comprehensive => localizedValues['comprehensive'][locale.languageCode]; + + String get hhcHome => localizedValues['hhcHome'][locale.languageCode]; + + String get refferal => localizedValues['refferal'][locale.languageCode]; + + String get healthCare => localizedValues['healthCare'][locale.languageCode]; + + String get emergency => localizedValues['emergency'][locale.languageCode]; + + String get cantSeeProfile => localizedValues['cantSeeProfile'][locale.languageCode]; + + String get loginRegisterNow => localizedValues['loginRegisterNow'][locale.languageCode]; + + String get HMGPharmacy => localizedValues['HMGPharmacy'][locale.languageCode]; + + String get ecommerceSolution => localizedValues['ecommerceSolution'][locale.languageCode]; + + String get services2 => localizedValues['services2'][locale.languageCode]; + String get payment => localizedValues['payment'][locale.languageCode]; - String get cancel_nocaps => - localizedValues['cancel-nocaps'][locale.languageCode]; + String get cancel_nocaps => localizedValues['cancel-nocaps'][locale.languageCode]; - String get cancelAppoMsg => - localizedValues['cancelAppoMsg'][locale.languageCode]; + String get cancelAppoMsg => localizedValues['cancelAppoMsg'][locale.languageCode]; - String get pharmaciesList => - localizedValues['pharmaciesList'][locale.languageCode]; + String get pharmaciesList => localizedValues['pharmaciesList'][locale.languageCode]; String get description => localizedValues['description'][locale.languageCode]; + String get howToUse => localizedValues['howToUse'][locale.languageCode]; String get price => localizedValues['price'][locale.languageCode]; - String get youCanFindItIn => - localizedValues['youCanFindItIn'][locale.languageCode]; + String get youCanFindItIn => localizedValues['youCanFindItIn'][locale.languageCode]; - String get pleaseEnterMedicineName => - localizedValues['pleaseEnterMedicineName'][locale.languageCode]; + String get pleaseEnterMedicineName => localizedValues['pleaseEnterMedicineName'][locale.languageCode]; - String get verificationMessage => - localizedValues['verification_message'][locale.languageCode]; + String get verificationMessage => localizedValues['verification_message'][locale.languageCode]; - String get validationMessage => - localizedValues['validation_message'][locale.languageCode]; + String get validationMessage => localizedValues['validation_message'][locale.languageCode]; - String get arabicChange => - localizedValues['arabic-change'][locale.languageCode]; + String get arabicChange => localizedValues['arabic-change'][locale.languageCode]; - String get notification => - localizedValues['notification'][locale.languageCode]; + String get notification => localizedValues['notification'][locale.languageCode]; String get appsetting => localizedValues['app-settings'][locale.languageCode]; + String get parkingDescription => localizedValues['parkingDescription'][locale.languageCode]; + + String get checkinOptions => localizedValues['checkinOption'][locale.languageCode]; + + String get wayHeading => localizedValues['RRT-way-heading'][locale.languageCode]; + + String get feedbackType => localizedValues["feedback-type"][locale.languageCode]; + + String get allow => localizedValues["allow"][locale.languageCode]; + + String get reject => localizedValues["reject"][locale.languageCode]; + + String get enterReferralRequesterName => localizedValues["enterReferralRequesterName"][locale.languageCode]; + + String get somethingWentWrong => localizedValues["somethingWentWrong"][locale.languageCode]; + + String get enterIdentificationNumber => localizedValues["enterIdentificationNumber"][locale.languageCode]; + + String get accountActivationDesc => localizedValues["accountActivationDesc"][locale.languageCode]; + + String get pointsToTransfer => localizedValues["pointsToTransfer"][locale.languageCode]; + + String get enterBeneficiaryAccountNo => localizedValues["enterBeneficiaryAccountNo"][locale.languageCode]; + + String get confirmPrescription => localizedValues["confirm-prescription"][locale.languageCode]; + + String get youAlreadyHaveOrder => localizedValues["you-already-have-order"][locale.languageCode]; + + String get orderOverview => localizedValues["order-overview"][locale.languageCode]; + + String get RapidResponseTeam => localizedValues['Rapid-Response-Team'][locale.languageCode]; + + String get RRTDDetails => localizedValues['RRTDDetails'][locale.languageCode]; + + String get ApproximateServiceFee => localizedValues['ApproximateServiceFee'][locale.languageCode]; + + String get AmountBeforeTax => localizedValues['AmountBeforeTax'][locale.languageCode]; + + String get TaxAmount => localizedValues['TaxAmount'][locale.languageCode]; + + String get TotalAmountPayable => localizedValues['TotalAmountPayable'][locale.languageCode]; + + String get iAcceptTermsConditions => localizedValues['iAcceptTermsConditions'][locale.languageCode]; + + String get YouCanPayByTheFollowingOptions => localizedValues['YouCanPayByTheFollowingOptions'][locale.languageCode]; + + String get rrtService => localizedValues['rrtService'][locale.languageCode]; + String get rateApp => localizedValues['rate-app'][locale.languageCode]; - String get setReminder => - localizedValues['set-reminder'][locale.languageCode]; + + String get setReminder => localizedValues['set-reminder'][locale.languageCode]; + String get before => localizedValues['before'][locale.languageCode]; + String get minute => localizedValues['minute'][locale.languageCode]; + String get hour => localizedValues['hour'][locale.languageCode]; - String get reminderSuccess => - localizedValues['reminderSuccess'][locale.languageCode]; - String get patientShareToDo => - localizedValues['patientShareToDo'][locale.languageCode]; - String get patientTaxToDo => - localizedValues['patientTaxToDo'][locale.languageCode]; - String get patientShareTotalToDo => - localizedValues['patientShareTotalToDo'][locale.languageCode]; - String get paymentMethod => - localizedValues['paymentMethod'][locale.languageCode]; - String get moreVerification => - localizedValues['more-verify'][locale.languageCode]; + String get reminderSuccess => localizedValues['reminderSuccess'][locale.languageCode]; + + String get patientShareToDo => localizedValues['patientShareToDo'][locale.languageCode]; + + String get patientTaxToDo => localizedValues['patientTaxToDo'][locale.languageCode]; - String get welcomeBack => - localizedValues['welcome-back'][locale.languageCode]; + String get patientShareTotalToDo => localizedValues['patientShareTotalToDo'][locale.languageCode]; - String get accountInfo => - localizedValues['account-info'][locale.languageCode]; + String get paymentMethod => localizedValues['paymentMethod'][locale.languageCode]; - String get useAnotherAccount => - localizedValues['another-acc'][locale.languageCode]; + String get moreVerification => localizedValues['more-verify'][locale.languageCode]; + + String get welcomeBack => localizedValues['welcome-back'][locale.languageCode]; + + String get accountInfo => localizedValues['account-info'][locale.languageCode]; + + String get useAnotherAccount => localizedValues['another-acc'][locale.languageCode]; String get next => localizedValues['next'][locale.languageCode]; - String get noNeedToWaitInLine => - localizedValues['noNeedToWaitInLine'][locale.languageCode]; - String get useQRAppoAttend => - localizedValues['useQRAppoAttend'][locale.languageCode]; - String get passQRAppoAttend => - localizedValues['passQRAppoAttend'][locale.languageCode]; - String get sitWaitingQR => - localizedValues['sitWaitingQR'][locale.languageCode]; - String get attendRegisterCode => - localizedValues['attendRegisterCode'][locale.languageCode]; - String get scanQRHospital => - localizedValues['scanQRHospital'][locale.languageCode]; + String get noNeedToWaitInLine => localizedValues['noNeedToWaitInLine'][locale.languageCode]; + + String get useQRAppoAttend => localizedValues['useQRAppoAttend'][locale.languageCode]; + + String get passQRAppoAttend => localizedValues['passQRAppoAttend'][locale.languageCode]; + + String get sitWaitingQR => localizedValues['sitWaitingQR'][locale.languageCode]; + + String get attendRegisterCode => localizedValues['attendRegisterCode'][locale.languageCode]; + + String get scanQRHospital => localizedValues['scanQRHospital'][locale.languageCode]; + String get sendEmail => localizedValues['sendEmail'][locale.languageCode]; + String get close => localizedValues['close'][locale.languageCode]; + + String get closeIt => localizedValues['closeIt'][locale.languageCode]; + String get booked => localizedValues['booked'][locale.languageCode]; + String get confirmed => localizedValues['confirmed'][locale.languageCode]; + String get arrived => localizedValues['arrived'][locale.languageCode]; - String get payNowBookSuccess => - localizedValues['payNowBookSuccess'][locale.languageCode]; - String get payNowBookSuccesstext1 => - localizedValues['payNowBookSuccesstext1'][locale.languageCode]; - String get payNowBookSuccesstext2 => - localizedValues['payNowBookSuccesstext2'][locale.languageCode]; + + String get payNowBookSuccess => localizedValues['payNowBookSuccess'][locale.languageCode]; + + String get payNowBookSuccesstext1 => localizedValues['payNowBookSuccesstext1'][locale.languageCode]; + + String get payNowBookSuccesstext2 => localizedValues['payNowBookSuccesstext2'][locale.languageCode]; + String get payLater => localizedValues['payLater'][locale.languageCode]; - String get askDocNotAllowed => - localizedValues['askDocNotAllowed'][locale.languageCode]; + + String get askDocNotAllowed => localizedValues['askDocNotAllowed'][locale.languageCode]; + String get firstName => localizedValues['first-name'][locale.languageCode]; String get middleName => localizedValues['middle-name'][locale.languageCode]; @@ -363,15 +463,13 @@ class TranslationBase { String get female => localizedValues['female'][locale.languageCode]; - String get prefferedLanguage => - localizedValues['preferred-language'][locale.languageCode]; + String get prefferedLanguage => localizedValues['preferred-language'][locale.languageCode]; String get english => localizedValues['english'][locale.languageCode]; String get arabic => localizedValues['arabic'][locale.languageCode]; - String get registrLocation => - localizedValues['locations-register'][locale.languageCode]; + String get registrLocation => localizedValues['locations-register'][locale.languageCode]; String get ksa => localizedValues['ksa'][locale.languageCode]; @@ -381,1243 +479,3020 @@ class TranslationBase { String get family => localizedValues['family'][locale.languageCode]; - String get myFamilyFiles => - localizedValues['family-title'][locale.languageCode]; + String get myFamilyFiles => localizedValues['family-title'][locale.languageCode]; + String get myFamily => localizedValues['myFamily'][locale.languageCode]; String get oxygenation => localizedValues['oxygenation'][locale.languageCode]; - String get respirationRate => - localizedValues['respirationRate'][locale.languageCode]; - String get bodyMeasurements => - localizedValues['bodyMeasurements'][locale.languageCode]; + String get respirationRate => localizedValues['respirationRate'][locale.languageCode]; + + String get bodyMeasurements => localizedValues['bodyMeasurements'][locale.languageCode]; + String get height => localizedValues['height'][locale.languageCode]; + + String get unit => localizedValues['unit'][locale.languageCode]; + String get heightUnit => localizedValues['heightUnit'][locale.languageCode]; + String get weightUnit => localizedValues['weightUnit'][locale.languageCode]; + String get temperature => localizedValues['temperature'][locale.languageCode]; String get pulse => localizedValues['pulse'][locale.languageCode]; String get respiration => localizedValues['respiration'][locale.languageCode]; - String get bloodPressure => - localizedValues['bloodPressure'][locale.languageCode]; + String get bloodPressure => localizedValues['bloodPressure'][locale.languageCode]; + String get painScale => localizedValues['painScale'][locale.languageCode]; + String get heart => localizedValues['heart'][locale.languageCode]; String get weight => localizedValues['weight'][locale.languageCode]; String get request => localizedValues['request'][locale.languageCode]; + String get memberName => localizedValues['member-name'][locale.languageCode]; + String get switchUser => localizedValues['switch-login'][locale.languageCode]; - String get removeMember => - localizedValues['remove-membe'][locale.languageCode]; + + String get removeMember => localizedValues['remove-member'][locale.languageCode]; + String get allowView => localizedValues['allow-view'][locale.languageCode]; + String get rejectView => localizedValues['reject-view'][locale.languageCode]; + String get deleteView => localizedValues['delete-view'][locale.languageCode]; + String get approvals => localizedValues['approvals'][locale.languageCode]; + String get approvalNo => localizedValues['approvalNo'][locale.languageCode]; + String get companyName => localizedValues['companyName'][locale.languageCode]; + String get receiptOn => localizedValues['receiptOn'][locale.languageCode]; + + String get expiryOn => localizedValues['expiryOn'][locale.languageCode]; + String get expiryDate => localizedValues['expiryDate'][locale.languageCode]; - String get procedureName => - localizedValues['procedureName'][locale.languageCode]; - String get procedureStatus => - localizedValues['procedureStatus'][locale.languageCode]; + + String get expiryPoints => localizedValues['expiryPoints'][locale.languageCode]; + + String get procedureName => localizedValues['procedureName'][locale.languageCode]; + + String get procedure => localizedValues['procedure'][locale.languageCode]; + + String get procedureStatus => localizedValues['procedureStatus'][locale.languageCode]; + String get usageStatus => localizedValues['usageStatus'][locale.languageCode]; + String get unusedCount => localizedValues['unusedCount'][locale.languageCode]; - String get totalApproval => - localizedValues['totalApproval'][locale.languageCode]; + + String get totalApproval => localizedValues['totalApproval'][locale.languageCode]; + String get category => localizedValues['category'][locale.languageCode]; - String get expirationDate => - localizedValues['expirationDate'][locale.languageCode]; + + String get expirationDate => localizedValues['expirationDate'][locale.languageCode]; + String get patientCard => localizedValues['patientCard'][locale.languageCode]; - String get policyNumber => - localizedValues['policyNumber'][locale.languageCode]; + + String get policyNumber => localizedValues['policyNumber'][locale.languageCode]; + String get seeDetails => localizedValues['seeDetails'][locale.languageCode]; - String get insuranceCards => - localizedValues['insuranceCards'][locale.languageCode]; + + String get insuranceCards => localizedValues['insuranceCards'][locale.languageCode]; + String get requestType => localizedValues['requestType'][locale.languageCode]; - String get addFamilyMember => - localizedValues['add-new-member'][locale.languageCode]; - String get removeFamilyMember => - localizedValues['remove-family-member'][locale.languageCode]; - - String get myMedicalFile => - localizedValues['MyMedicalFile'][locale.languageCode]; - String get myMedicalFileSubTitle => - localizedValues['myMedicalFileSubTitle'][locale.languageCode]; + + String get addFamilyMember => localizedValues['add-new-member'][locale.languageCode]; + + String get removeFamilyMember => localizedValues['remove-family-member'][locale.languageCode]; + + String get myMedicalFile => localizedValues['MyMedicalFile'][locale.languageCode]; + + String get myMedicalFileSubTitle => localizedValues['myMedicalFileSubTitle'][locale.languageCode]; + String get viewMore => localizedValues['viewMore'][locale.languageCode]; - String get homeHealthCareService => - localizedValues['homeHealthCareService'][locale.languageCode]; - String get onlinePharmacy => - localizedValues['OnlinePharmacy'][locale.languageCode]; - String get emergencyService => - localizedValues['EmergencyService'][locale.languageCode]; - String get onlinePaymentService => - localizedValues['OnlinePaymentService'][locale.languageCode]; - String get offersAndPackages => - localizedValues['OffersAndPackages'][locale.languageCode]; - String get comprehensiveMedicalCheckup => - localizedValues['ComprehensiveMedicalCheckup'][locale.languageCode]; + + String get homeHealthCareService => localizedValues['homeHealthCareService'][locale.languageCode]; + + String get onlinePharmacy => localizedValues['OnlinePharmacy'][locale.languageCode]; + + String get emergencyService => localizedValues['EmergencyService'][locale.languageCode]; + + String get onlinePaymentService => localizedValues['OnlinePaymentService'][locale.languageCode]; + + String get offersAndPackages => localizedValues['OffersAndPackages'][locale.languageCode]; + + String get comprehensiveMedicalCheckup => localizedValues['ComprehensiveMedicalCheckup'][locale.languageCode]; + String get hMGService => localizedValues['HMGService'][locale.languageCode]; - String get viewAllHabibMedicalService => - localizedValues['ViewAllHabibMedicalService'][locale.languageCode]; + + String get viewAllHabibMedicalService => localizedValues['ViewAllHabibMedicalService'][locale.languageCode]; + String get viewAll => localizedValues['viewAll'][locale.languageCode]; + String get view => localizedValues['view'][locale.languageCode]; + String get contactUs => localizedValues['ContactUs'][locale.languageCode]; - String get viewAllWaysReachUs => - localizedValues['ViewAllWaysReachUs'][locale.languageCode]; - String get medicalProfile => - localizedValues['medicalProfile'][locale.languageCode]; + + String get contactUsLocation => localizedValues['contactUsLocation'][locale.languageCode]; + + String get contactUsTime => localizedValues['contactUsTime'][locale.languageCode]; + + String get viewAllWaysReachUs => localizedValues['ViewAllWaysReachUs'][locale.languageCode]; + + String get medicalProfile => localizedValues['medicalProfile'][locale.languageCode]; + String get parking => localizedValues['parking'][locale.languageCode]; - String get alhabiServices => - localizedValues['alhabiServices'][locale.languageCode]; - String get parkingTitle => - localizedValues['parkingTitle'][locale.languageCode]; + + String get alhabiServices => localizedValues['alhabiServices'][locale.languageCode]; + + String get parkingTitle => localizedValues['parkingTitle'][locale.languageCode]; + String get readBarcode => localizedValues['readBarcode'][locale.languageCode]; + String get showMyPark => localizedValues['showMyPark'][locale.languageCode]; + String get clearMyData => localizedValues['clearMyData'][locale.languageCode]; + String get floor => localizedValues['floor'][locale.languageCode]; + String get gate => localizedValues['gate'][locale.languageCode]; + String get building => localizedValues['building'][locale.languageCode]; + String get branch => localizedValues['branch'][locale.languageCode]; - String get emergencyServices => - localizedValues['emergencyServices'][locale.languageCode]; + + String get emergencyServices => localizedValues['emergencyServices'][locale.languageCode]; + String get nearester => localizedValues['nearester'][locale.languageCode]; + String get locationa => localizedValues['locationa'][locale.languageCode]; - String get ambulancerequest => - localizedValues['ambulancerequest'][locale.languageCode]; + + String get callNow => localizedValues['call_now'][locale.languageCode]; + + String get ambulancerequest => localizedValues['ambulancerequest'][locale.languageCode]; + String get requestA => localizedValues['requestA'][locale.languageCode]; - String get consultation => - localizedValues['consultation'][locale.languageCode]; + + String get consultation => localizedValues['consultation'][locale.languageCode]; + String get logs => localizedValues['logs'][locale.languageCode]; - String get textToSpeech => - localizedValues['textToSpeech'][locale.languageCode]; - - String get myAppointments => - localizedValues['MyAppointments'][locale.languageCode]; - String get noBookedAppointments => - localizedValues['NoBookedAppointments'][locale.languageCode]; - String get noConfirmedAppointments => - localizedValues['NoConfirmedAppointments'][locale.languageCode]; - String get noArrivedAppointments => - localizedValues['noArrivedAppointments'][locale.languageCode]; - String get myAppointmentsList => - localizedValues['MyAppointmentsList'][locale.languageCode]; + + String get textToSpeech => localizedValues['textToSpeech'][locale.languageCode]; + + String get myAppointments => localizedValues['MyAppointments'][locale.languageCode]; + + String get noBookedAppointments => localizedValues['NoBookedAppointments'][locale.languageCode]; + + String get noConfirmedAppointments => localizedValues['NoConfirmedAppointments'][locale.languageCode]; + + String get noArrivedAppointments => localizedValues['noArrivedAppointments'][locale.languageCode]; + + String get myAppointmentsList => localizedValues['MyAppointmentsList'][locale.languageCode]; + String get radiology => localizedValues['Radiology'][locale.languageCode]; - String get radiologySubtitle => - localizedValues['RadiologySubtitle'][locale.languageCode]; + + String get radiologySubtitle => localizedValues['RadiologySubtitle'][locale.languageCode]; + String get lab => localizedValues['Lab'][locale.languageCode]; + String get labSubtitle => localizedValues['LabSubtitle'][locale.languageCode]; + String get medicines => localizedValues['Medicines'][locale.languageCode]; - String get medicinesSubtitle => - localizedValues['MedicinesSubtitle'][locale.languageCode]; + + String get medicinesSubtitle => localizedValues['MedicinesSubtitle'][locale.languageCode]; + String get vitalSigns => localizedValues['VitalSigns'][locale.languageCode]; - String get vitalSignsSubtitle => - localizedValues['VitalSignsSubTitle'][locale.languageCode]; + + String get vitalSignsSubtitle => localizedValues['VitalSignsSubTitle'][locale.languageCode]; + String get myMedical => localizedValues['MyMedical'][locale.languageCode]; - String get myMedicalSubtitle => - localizedValues['MyMedicalSubtitle'][locale.languageCode]; + + String get myMedicalSubtitle => localizedValues['MyMedicalSubtitle'][locale.languageCode]; + String get myDoctor => localizedValues['MyDoctor'][locale.languageCode]; - String get myDoctorSubtitle => - localizedValues['MyDoctorSubtitle'][locale.languageCode]; + + String get myDoctorSubtitle => localizedValues['MyDoctorSubtitle'][locale.languageCode]; + String get eye => localizedValues['Eye'][locale.languageCode]; + String get eyeSubtitle => localizedValues['EyeSubtitle'][locale.languageCode]; + String get insurance => localizedValues['Insurance'][locale.languageCode]; - String get insuranceSubtitle => - localizedValues['InsuranceSubtitle'][locale.languageCode]; - String get updateInsurance => - localizedValues['UpdateInsurance'][locale.languageCode]; - String get updateInsuranceSubtitle => - localizedValues['UpdateInsuranceSubtitle'][locale.languageCode]; - String get insuranceApproval => - localizedValues['InsuranceApproval'][locale.languageCode]; - String get insuranceApprovalSubtitle => - localizedValues['InsuranceApprovalSubtitle'][locale.languageCode]; + + String get insuranceSubtitle => localizedValues['InsuranceSubtitle'][locale.languageCode]; + + String get updateInsurance => localizedValues['UpdateInsurance'][locale.languageCode]; + + String get updateInsuranceSubtitle => localizedValues['UpdateInsuranceSubtitle'][locale.languageCode]; + + String get insuranceApproval => localizedValues['InsuranceApproval'][locale.languageCode]; + + String get insuranceApprovalSubtitle => localizedValues['InsuranceApprovalSubtitle'][locale.languageCode]; + String get allergies => localizedValues['Allergies'][locale.languageCode]; - String get allergiesSubtitle => - localizedValues['AllergiesSubtitle'][locale.languageCode]; + + String get allergiesSubtitle => localizedValues['AllergiesSubtitle'][locale.languageCode]; + String get myVaccines => localizedValues['MyVaccines'][locale.languageCode]; - String get myVaccinesSubtitle => - localizedValues['MyVaccinesSubtitle'][locale.languageCode]; + + String get myVaccinesSubtitle => localizedValues['MyVaccinesSubtitle'][locale.languageCode]; + String get medical => localizedValues['Medical'][locale.languageCode]; - String get medicalSubtitle => - localizedValues['MedicalSubtitle'][locale.languageCode]; + + String get medicalSubtitle => localizedValues['MedicalSubtitle'][locale.languageCode]; + String get monthly => localizedValues['Monthly'][locale.languageCode]; - String get monthlySubtitle => - localizedValues['MonthlySubtitle'][locale.languageCode]; + + String get monthlySubtitle => localizedValues['MonthlySubtitle'][locale.languageCode]; + String get sick => localizedValues['Sick'][locale.languageCode]; - String get sickSubtitle => - localizedValues['SickSubtitle'][locale.languageCode]; + + String get sickSubtitle => localizedValues['SickSubtitle'][locale.languageCode]; + String get myBalance => localizedValues['MyBalance'][locale.languageCode]; - String get myBalanceSubtitle => - localizedValues['MyBalanceSubtitle'][locale.languageCode]; + + String get myBalanceSubtitle => localizedValues['MyBalanceSubtitle'][locale.languageCode]; + String get patientCall => localizedValues['PatientCall'][locale.languageCode]; - String get patientCallSubtitle => - localizedValues['PatientCallSubtitle'][locale.languageCode]; - String get smartWatches => - localizedValues['SmartWatches'][locale.languageCode]; - String get smartWatchesSubtitle => - localizedValues['SmartWatchesSubtitle'][locale.languageCode]; + + String get patientCallSubtitle => localizedValues['PatientCallSubtitle'][locale.languageCode]; + + String get smartWatches => localizedValues['SmartWatches'][locale.languageCode]; + + String get smartWatchesSubtitle => localizedValues['SmartWatchesSubtitle'][locale.languageCode]; + String get myTrackers => localizedValues['MyTrackers'][locale.languageCode]; - String get myTrackersSubtitle => - localizedValues['MyTrackersSubtitle'][locale.languageCode]; + + String get myTrackersSubtitle => localizedValues['MyTrackersSubtitle'][locale.languageCode]; + String get askYour => localizedValues['AskYour'][locale.languageCode]; - String get askYourSubtitle => - localizedValues['AskYourSubtitle'][locale.languageCode]; + + String get askYourSubtitle => localizedValues['AskYourSubtitle'][locale.languageCode]; + String get internet => localizedValues['Internet'][locale.languageCode]; - String get internetSubtitle => - localizedValues['InternetSubtitle'][locale.languageCode]; + + String get internetSubtitle => localizedValues['InternetSubtitle'][locale.languageCode]; + String get chatbot => localizedValues['Chatbot'][locale.languageCode]; - String get chatbotSubtitle => - localizedValues['ChatbotSubtitle'][locale.languageCode]; + + String get chatbotSubtitle => localizedValues['ChatbotSubtitle'][locale.languageCode]; + String get timeLine => localizedValues['TimeLine'][locale.languageCode]; + String get labOrders => localizedValues['LabOrders'][locale.languageCode]; + String get billNo => localizedValues['BillNo'][locale.languageCode]; - String get prescriptions => - localizedValues['Prescriptions'][locale.languageCode]; + + String get prescriptions => localizedValues['Prescriptions'][locale.languageCode]; + String get history => localizedValues['History'][locale.languageCode]; + String get orderNo => localizedValues['OrderNo'][locale.languageCode]; - String get trackDeliveryDriver => - localizedValues['trackDeliveryDriver'][locale.languageCode]; - String get orderDetails => - localizedValues['OrderDetails'][locale.languageCode]; + + String get trackDeliveryDriver => localizedValues['trackDeliveryDriver'][locale.languageCode]; + + String get orderDetails => localizedValues['OrderDetails'][locale.languageCode]; + String get vitalSign => localizedValues['VitalSign'][locale.languageCode]; - String get monthlyReports => - localizedValues['MonthlyReports'][locale.languageCode]; - String get locationDialogMessage => - localizedValues['locationDialogMessage'][locale.languageCode]; - String get userViewRequest => - localizedValues['user-view-requester'][locale.languageCode]; + String get monthlyReports => localizedValues['MonthlyReports'][locale.languageCode]; + + String get locationDialogMessage => localizedValues['locationDialogMessage'][locale.languageCode]; + + String get userViewRequest => localizedValues['user-view-requester'][locale.languageCode]; + String get userView => localizedValues['user-view'][locale.languageCode]; - String get sentRequest => - localizedValues['sent-requests'][locale.languageCode]; + + String get sentRequest => localizedValues['sent-requests'][locale.languageCode]; + String get km => localizedValues['km'][locale.languageCode]; - String get patientHealthSummaryReport => - localizedValues['PatientHealthSummaryReport'][locale.languageCode]; - String get toViewTheTermsAndConditions => - localizedValues['ToViewTheTermsAndConditions'][locale.languageCode]; + + String get km_ => localizedValues['km_'][locale.languageCode]; + + String get patientHealthSummaryReport => localizedValues['PatientHealthSummaryReport'][locale.languageCode]; + + String get toViewTheTermsAndConditions => localizedValues['ToViewTheTermsAndConditions'][locale.languageCode]; + String get clickHere => localizedValues['ClickHere'][locale.languageCode]; - String get iAgreeToTheTermsAndConditions => - localizedValues['IAgreeToTheTermsAndConditions'][locale.languageCode]; - String get iAgreeToTheTermsAndConditionsSubtitle => - localizedValues['IAgreeToTheTermsAndConditionsSubtitle'] - [locale.languageCode]; + + String get iAgreeToTheTermsAndConditions => localizedValues['IAgreeToTheTermsAndConditions'][locale.languageCode]; + + String get iAgreeToTheTermsAndConditionsSubtitle => localizedValues['IAgreeToTheTermsAndConditionsSubtitle'][locale.languageCode]; + String get save => localizedValues['Save'][locale.languageCode]; - String get userAgreement => - localizedValues['UserAgreement'][locale.languageCode]; - String get updateSuccessfully => - localizedValues['UpdateSuccessfully'][locale.languageCode]; - String get emailSentSuccessfully => - localizedValues['EmailSentSuccessfully'][locale.languageCode]; - String get EmailSentError => - localizedValues['EmailSentError'][locale.languageCode]; - String get checkVaccineAvailability => - localizedValues['CHECK_VACCINE_AVAILABILITY'][locale.languageCode]; - String get myVaccinesAvailability => - localizedValues['MyVaccinesAvailability'][locale.languageCode]; - String get paymentService => - localizedValues['PaymentService'][locale.languageCode]; - String get paymentOnline => - localizedValues['PaymentOnline'][locale.languageCode]; - String get onlineCheckIn => - localizedValues['OnlineCheckIn'][locale.languageCode]; + + String get agreeTo => localizedValues['agreeTo'][locale.languageCode]; + + String get termsConditoins => localizedValues['termsConditoins'][locale.languageCode]; + + String get userAgreement => localizedValues['UserAgreement'][locale.languageCode]; + + String get updateSuccessfully => localizedValues['UpdateSuccessfully'][locale.languageCode]; + + String get emailSentSuccessfully => localizedValues['EmailSentSuccessfully'][locale.languageCode]; + + String get EmailSentError => localizedValues['EmailSentError'][locale.languageCode]; + + String get checkVaccineAvailability => localizedValues['CHECK_VACCINE_AVAILABILITY'][locale.languageCode]; + + String get myVaccinesAvailability => localizedValues['MyVaccinesAvailability'][locale.languageCode]; + + String get paymentService => localizedValues['PaymentService'][locale.languageCode]; + + String get paymentOnline => localizedValues['PaymentOnline'][locale.languageCode]; + + String get onlineCheckIn => localizedValues['OnlineCheckIn'][locale.languageCode]; + String get myBalances => localizedValues['MyBalances'][locale.languageCode]; - String get balanceAmount => - localizedValues['BalanceAmount'][locale.languageCode]; - String get totalBalance => - localizedValues['TotalBalance'][locale.languageCode]; - String get createAdvancedPayment => - localizedValues['CreateAdvancedPayment'][locale.languageCode]; - String get advancePayment => - localizedValues['AdvancePayment'][locale.languageCode]; - String get advancePaymentLabel => - localizedValues['AdvancePaymentLabel'][locale.languageCode]; + + String get myWallet => localizedValues['MyWallet'][locale.languageCode]; + + String get balanceAmount => localizedValues['BalanceAmount'][locale.languageCode]; + + String get totalBalance => localizedValues['TotalBalance'][locale.languageCode]; + + String get createAdvancedPayment => localizedValues['CreateAdvancedPayment'][locale.languageCode]; + + String get advancePayment => localizedValues['AdvancePayment'][locale.languageCode]; + + String get advancePaymentLabel => localizedValues['AdvancePaymentLabel'][locale.languageCode]; + + String get referralRequesterInformation => localizedValues['referralRequesterInformation'][locale.languageCode]; + String get fileNumber => localizedValues['FileNumber'][locale.languageCode]; + + String get enterfileNumber => localizedValues['enterfileNumber'][locale.languageCode]; + + String get complaintNumber => localizedValues['complaintNumber'][locale.languageCode]; + + String get identificationNumber => localizedValues['identificationNumber'][locale.languageCode]; + String get amount => localizedValues['Amount'][locale.languageCode]; - String get depositorEmail => - localizedValues['DepositorEmail'][locale.languageCode]; + + String get depositorEmail => localizedValues['DepositorEmail'][locale.languageCode]; + String get notes => localizedValues['Notes'][locale.languageCode]; - String get selectPatientName => - localizedValues['SelectPatientName'][locale.languageCode]; - String get selectFamilyPatientName => - localizedValues['SelectFamilyPatientName'][locale.languageCode]; - String get selectHospital => - localizedValues['SelectHospital'][locale.languageCode]; + + String get selectPatientName => localizedValues['SelectPatientName'][locale.languageCode]; + + String get selectFamilyPatientName => localizedValues['SelectFamilyPatientName'][locale.languageCode]; + + String get selectHospital => localizedValues['SelectHospital'][locale.languageCode]; + String get selectCity => localizedValues['selectCity'][locale.languageCode]; + + String get city => localizedValues['city'][locale.languageCode]; + + String get distance => localizedValues['distance'][locale.languageCode]; + String get myAccount => localizedValues['MyAccount'][locale.languageCode]; - String get otherAccount => - localizedValues['OtherAccount'][locale.languageCode]; - String get selectBeneficiary => - localizedValues['SelectBeneficiary'][locale.languageCode]; - String get confirmThePayment => - localizedValues['ConfirmThePayment'][locale.languageCode]; - String get depositorName => - localizedValues['DepositorName'][locale.languageCode]; - String get mobileNumber => - localizedValues['MobileNumber'][locale.languageCode]; + + String get otherAccount => localizedValues['OtherAccount'][locale.languageCode]; + + String get selectBeneficiary => localizedValues['SelectBeneficiary'][locale.languageCode]; + + String get confirmThePayment => localizedValues['ConfirmThePayment'][locale.languageCode]; + + String get changePayment => localizedValues['changePayment'][locale.languageCode]; + + String get depositorName => localizedValues['DepositorName'][locale.languageCode]; + + String get mobileNumber => localizedValues['MobileNumber'][locale.languageCode]; + + String get phoneNumber => localizedValues['phone-number'][locale.languageCode]; + + String get country => localizedValues['country'][locale.languageCode]; + String get ok => localizedValues['Ok'][locale.languageCode]; - String get waterConsumedInWeek => - localizedValues['WaterConsumedInWeek'][locale.languageCode]; - String get waterConsumedInMonth => - localizedValues['WaterConsumedInMonth'][locale.languageCode]; - String get theVerificationCodeExpiresIn => - localizedValues['TheVerificationCodeExpiresIn'][locale.languageCode]; - String get pleaseEnterTheVerificationCode => - localizedValues['PleaseEnterTheVerificationCode'][locale.languageCode]; - String get eyeMeasurements => - localizedValues['EyeMeasurements'][locale.languageCode]; - String get measurements => - localizedValues['Measurements'][locale.languageCode]; + + String get averageWaitingTime => localizedValues['averageWaitingTime'][locale.languageCode]; + + String get waterConsumedInWeek => localizedValues['WaterConsumedInWeek'][locale.languageCode]; + + String get waterConsumedInMonth => localizedValues['WaterConsumedInMonth'][locale.languageCode]; + + String get theVerificationCodeExpiresIn => localizedValues['TheVerificationCodeExpiresIn'][locale.languageCode]; + + String get pleaseEnterTheVerificationCode => localizedValues['PleaseEnterTheVerificationCode'][locale.languageCode]; + + String get eyeMeasurements => localizedValues['EyeMeasurements'][locale.languageCode]; + + String get measurements => localizedValues['Measurements'][locale.languageCode]; + String get classes => localizedValues['Classes'][locale.languageCode]; + String get contactLens => localizedValues['ContactLens'][locale.languageCode]; + String get rightEye => localizedValues['RightEye'][locale.languageCode]; + String get sphere => localizedValues['Sphere'][locale.languageCode]; + String get cylinder => localizedValues['Cylinder'][locale.languageCode]; + String get axis => localizedValues['Axis'][locale.languageCode]; + String get prism => localizedValues['Prism'][locale.languageCode]; + String get va => localizedValues['VA'][locale.languageCode]; + String get leftEye => localizedValues['LeftEye'][locale.languageCode]; + String get brand => localizedValues['Brand'][locale.languageCode]; + String get power => localizedValues['Power'][locale.languageCode]; + String get diameter => localizedValues['Diameter'][locale.languageCode]; + String get remarks => localizedValues['Remarks'][locale.languageCode]; - String get activeMedications => - localizedValues['ActiveMedications'][locale.languageCode]; + + String get activeMedications => localizedValues['ActiveMedications'][locale.languageCode]; + String get expDate => localizedValues['ExpDate'][locale.languageCode]; + String get route => localizedValues['Route'][locale.languageCode]; + String get frequency => localizedValues['Frequency'][locale.languageCode]; - String get dailyQuantity => - localizedValues['DailyQuantity'][locale.languageCode]; + + String get dailyQuantity => localizedValues['DailyQuantity'][locale.languageCode]; + String get addReminder => localizedValues['AddReminder'][locale.languageCode]; + String get reminderDes => localizedValues['reminderDes'][locale.languageCode]; + String get startDay => localizedValues['StartDay'][locale.languageCode]; + String get endDay => localizedValues['EndDay'][locale.languageCode]; + String get days => localizedValues['Days'][locale.languageCode]; - String get scheduleTime => - localizedValues['ScheduleTime'][locale.languageCode]; + + String get scheduleTime => localizedValues['ScheduleTime'][locale.languageCode]; + String get askDoctor => localizedValues['AskDoctor'][locale.languageCode]; - String get doctorResponses => - localizedValues['DoctorResponses'][locale.languageCode]; + + String get doctorResponses => localizedValues['DoctorResponses'][locale.languageCode]; + String get newDes => localizedValues['New'][locale.languageCode]; + String get all => localizedValues['All'][locale.languageCode]; - String get questionHere => - localizedValues['QuestionHere'][locale.languageCode]; - String get viewDoctorResponses => - localizedValues['ViewDoctorResponses'][locale.languageCode]; - String get serviceInformationButton => - localizedValues['ServiceInformationButton'][locale.languageCode]; - String get serviceInformationTitle => - localizedValues['ServiceInformationTitle'][locale.languageCode]; + + String get questionHere => localizedValues['QuestionHere'][locale.languageCode]; + + String get viewDoctorResponses => localizedValues['ViewDoctorResponses'][locale.languageCode]; + + String get serviceInformationButton => localizedValues['ServiceInformationButton'][locale.languageCode]; + + String get serviceInformationTitle => localizedValues['ServiceInformationTitle'][locale.languageCode]; + String get infoLab => localizedValues['info-lab'][locale.languageCode]; - String get infoRadiology => - localizedValues['info-radiology'][locale.languageCode]; + + String get infoRadiology => localizedValues['info-radiology'][locale.languageCode]; + String get orders => localizedValues['orders'][locale.languageCode]; + String get lakum => localizedValues['lakum'][locale.languageCode]; + + String get lakumMsg => localizedValues['lakumMsg'][locale.languageCode]; + + String get lakumPoint => localizedValues['lakumPoint'][locale.languageCode]; + + String get MEMBERSINCE => localizedValues['MEMBERSINCE'][locale.languageCode]; + + String get IDENTIFICATION => localizedValues['IDENTIFICATION'][locale.languageCode]; + + String get lakumMobile => localizedValues['lakumMobile'][locale.languageCode]; + + String get Waitinggained => localizedValues['Waitinggained'][locale.languageCode]; + + String get Expired => localizedValues['Expired'][locale.languageCode]; + + String get WillBeExpired => localizedValues['WillBeExpired'][locale.languageCode]; + + String get RIYAL => localizedValues['RIYAL'][locale.languageCode]; + + String get LakumPoint => localizedValues['LakumPoint'][locale.languageCode]; + + String get ActivateLAKUMAccount => localizedValues['ActivateLAKUMAccount'][locale.languageCode]; + String get wishlist => localizedValues['wishlist'][locale.languageCode]; + + String get brands => localizedValues['brands'][locale.languageCode]; + + String get products => localizedValues['products'][locale.languageCode]; + String get reviews => localizedValues['reviews'][locale.languageCode]; - String get myPrescriptions => - localizedValues['myPrescriptions'][locale.languageCode]; - String get medicationRefill => - localizedValues['medicationRefill'][locale.languageCode]; - String get pillReminder => - localizedValues['pillReminder'][locale.languageCode]; - String get shippingAddresses => - localizedValues['shippingAddresses'][locale.languageCode]; + + String get productDetails => localizedValues['productDetails'][locale.languageCode]; + + String get noReviewsAvailable => localizedValues['noReviewsAvailable'][locale.languageCode]; + + String get noLocationAvailable => localizedValues['noLocationAvailable'][locale.languageCode]; + + String get myPrescriptions => localizedValues['myPrescriptions'][locale.languageCode]; + + String get medicationRefill => localizedValues['medicationRefill'][locale.languageCode]; + + String get pillReminder => localizedValues['pillReminder'][locale.languageCode]; + + String get shippingAddresses => localizedValues['shippingAddresses'][locale.languageCode]; + String get reachUs => localizedValues['reachUs'][locale.languageCode]; - String get ourLocations => - localizedValues['ourLocations'][locale.languageCode]; + + String get ourLocations => localizedValues['ourLocations'][locale.languageCode]; + String get edit => localizedValues['edit'][locale.languageCode]; + + String get whatsApp => localizedValues['whatsApp'][locale.languageCode]; + + String get phone => localizedValues['phone'][locale.languageCode]; + String get delete => localizedValues['delete'][locale.languageCode]; + String get addAddress => localizedValues['addAddress'][locale.languageCode]; - String get addNewAddress => - localizedValues['addNewAddress'][locale.languageCode]; + + String get deleteAddress => localizedValues['deleteAddress'][locale.languageCode]; + + String get deletedAddress => localizedValues['deletedAddres'][locale.languageCode]; + + String get addNewAddress => localizedValues['addNewAddress'][locale.languageCode]; + String get order => localizedValues['order'][locale.languageCode]; + String get delivered => localizedValues['delivered'][locale.languageCode]; + String get processing => localizedValues['processing'][locale.languageCode]; + String get pending => localizedValues['pending'][locale.languageCode]; + String get cancelled => localizedValues['cancelled'][locale.languageCode]; + String get writeReview => localizedValues['writeReview'][locale.languageCode]; + String get shareReview => localizedValues['shareReview'][locale.languageCode]; - String get backMyAccount => - localizedValues['backMyAccount'][locale.languageCode]; - String get reviewSuccessful => - localizedValues['reviewSuccessful'][locale.languageCode]; - String get reviewShared => - localizedValues['reviewShared'][locale.languageCode]; - String get reviewComment => - localizedValues['reviewComment'][locale.languageCode]; - String get shippedMethod => - localizedValues['shippedMethod'][locale.languageCode]; + + String get backMyAccount => localizedValues['backMyAccount'][locale.languageCode]; + + String get reviewSuccessful => localizedValues['reviewSuccessful'][locale.languageCode]; + + String get reviewShared => localizedValues['reviewShared'][locale.languageCode]; + + String get reviewComment => localizedValues['reviewComment'][locale.languageCode]; + + String get shippedMethod => localizedValues['shippedMethod'][locale.languageCode]; + String get orderDetail => localizedValues['orderDetail'][locale.languageCode]; + String get deliveryDriverTrack => localizedValues['DeliveryDriverTrack'][locale.languageCode]; + String get deliveryLocation => localizedValues['DeliveryLocation'][locale.languageCode]; + String get driver => localizedValues['Driver'][locale.languageCode]; + String get subtotal => localizedValues['subtotal'][locale.languageCode]; + String get shipping => localizedValues['shipping'][locale.languageCode]; + String get shipBy => localizedValues['shipBy'][locale.languageCode]; + String get lakumPoints => localizedValues['lakumPoints'][locale.languageCode]; + String get use => localizedValues['use'][locale.languageCode]; + String get proceedPay => localizedValues['proceedPay'][locale.languageCode]; + String get vat => localizedValues['vat'][locale.languageCode]; - String get inclusiveVat => - localizedValues['inclusiveVat'][locale.languageCode]; + + String get inclusiveVat => localizedValues['inclusiveVat'][locale.languageCode]; + String get items => localizedValues['items'][locale.languageCode]; + String get checkOut => localizedValues['checkOut'][locale.languageCode]; + String get total => localizedValues['total'][locale.languageCode]; + String get sar => localizedValues['sar'][locale.languageCode]; + + String get aed => localizedValues['aed'][locale.languageCode]; + String get payOnline => localizedValues['payOnline'][locale.languageCode]; + String get cancelOrder => localizedValues['cancelOrder'][locale.languageCode]; - String get confirmAddress => - localizedValues['confirmAddress'][locale.languageCode]; - String get confirmLocation => - localizedValues['confirmLocation'][locale.languageCode]; - String get confirmDeleteMsg => - localizedValues['confirmDeleteMsg'][locale.languageCode]; - String get confirmDelete => - localizedValues['confirmDelete'][locale.languageCode]; - String get confirmCancellation => - localizedValues['confirmCancellation'][locale.languageCode]; - String get serviceInformation => - localizedValues['ServiceInformation'][locale.languageCode]; - String get homeHealthCare => - localizedValues['HomeHealthCare'][locale.languageCode]; - String get HHCNotAuthMsg => - localizedValues['HHCNotAuthMsg'][locale.languageCode]; - String get homeHealthCareText => - localizedValues['HomeHealthCareText'][locale.languageCode]; - String get loginRegister => - localizedValues['LoginRegister'][locale.languageCode]; + + String get confirmAddress => localizedValues['confirmAddress'][locale.languageCode]; + + String get confirmLocation => localizedValues['confirmLocation'][locale.languageCode]; + + String get confirmDeleteMsg => localizedValues['confirmDeleteMsg'][locale.languageCode]; + + String get confirmDelete => localizedValues['confirmDelete'][locale.languageCode]; + + String get confirmCancellation => localizedValues['confirmCancellation'][locale.languageCode]; + + String get serviceInformation => localizedValues['ServiceInformation'][locale.languageCode]; + + String get homeHealthCare => localizedValues['HomeHealthCare'][locale.languageCode]; + + String get HHCNotAuthMsg => localizedValues['HHCNotAuthMsg'][locale.languageCode]; + + String get homeHealthCareText => localizedValues['HomeHealthCareText'][locale.languageCode]; + + String get loginRegister => localizedValues['LoginRegister'][locale.languageCode]; + String get orderLog => localizedValues['OrderLog'][locale.languageCode]; // String get infoLab => localizedValues['info-lab'][locale.languageCode]; // String get infoRadiology => String get orderNumber => localizedValues['orderNumber'][locale.languageCode]; + String get orderDate => localizedValues['orderDate'][locale.languageCode]; + String get itemsNo => localizedValues['itemsNo'][locale.languageCode]; + String get noOrder => localizedValues['noOrder'][locale.languageCode]; - String get offersAndPromotions => - localizedValues['offersAndPromotions'][locale.languageCode]; + String get noResult => localizedValues['noResult'][locale.languageCode]; + + String get offersAndPromotions => localizedValues['offersAndPromotions'][locale.languageCode]; + + String get offers => localizedValues['offers'][locale.languageCode]; + String get review => localizedValues['review'][locale.languageCode]; - String get deliveredOrder => - localizedValues['deliveredOrder'][locale.languageCode]; - String get pendingOrder => - localizedValues['pendingOrder'][locale.languageCode]; - String get processingOrder => - localizedValues['processingOrder'][locale.languageCode]; - String get cancelledOrder => - localizedValues['cancelledOrder'][locale.languageCode]; + + String get deliveredOrder => localizedValues['deliveredOrder'][locale.languageCode]; + + String get pendingOrder => localizedValues['pendingOrder'][locale.languageCode]; + + String get processingOrder => localizedValues['processingOrder'][locale.languageCode]; + + String get cancelledOrder => localizedValues['cancelledOrder'][locale.languageCode]; + String get compare => localizedValues['compare'][locale.languageCode]; - String get medicationsRefill => - localizedValues['medicationsRefill'][locale.languageCode]; - String get myPrescription => - localizedValues['myPrescription'][locale.languageCode]; + + String get medicationsRefill => localizedValues['medicationsRefill'][locale.languageCode]; + + String get myPrescription => localizedValues['myPrescription'][locale.languageCode]; + String get quantity => localizedValues['quantity'][locale.languageCode]; - String get conditionsHMG => - localizedValues['conditionsHMG'][locale.languageCode]; + + String get productQuantity => localizedValues['productQuantity'][locale.languageCode]; + + String get conditionsHMG => localizedValues['conditionsHMG'][locale.languageCode]; + String get conditions => localizedValues['conditions'][locale.languageCode]; // pharmacy module - String get searchAndScanMedication => - localizedValues['searchAndScanMedication'][locale.languageCode]; - String get shopByBrands => - localizedValues['shopByBrands'][locale.languageCode]; - String get recentlyViewed => - localizedValues['recentlyViewed'][locale.languageCode]; + String get searchAndScanMedication => localizedValues['searchAndScanMedication'][locale.languageCode]; + + String get shopByBrands => localizedValues['shopByBrands'][locale.languageCode]; + + String get recentlyViewed => localizedValues['recentlyViewed'][locale.languageCode]; + String get bestSellers => localizedValues['bestSellers'][locale.languageCode]; + String get recommended => localizedValues['recommended'][locale.languageCode]; - String get deleteAllItems => - localizedValues['deleteAllItems'][locale.languageCode]; - String get selectAddress => - localizedValues['selectAddress'][locale.languageCode]; - String get shippingAddress => - localizedValues['shippingAddress'][locale.languageCode]; - String get changeAddress => - localizedValues['changeAddress'][locale.languageCode]; - String get selectPaymentOption => - localizedValues['selectPaymentOption'][locale.languageCode]; - String get changeMethod => - localizedValues['changeMethod'][locale.languageCode]; + + String get deleteAllItems => localizedValues['deleteAllItems'][locale.languageCode]; + + String get selectAddress => localizedValues['selectAddress'][locale.languageCode]; + + String get shippingAddress => localizedValues['shippingAddress'][locale.languageCode]; + + String get changeAddress => localizedValues['changeAddress'][locale.languageCode]; + + String get selectPaymentOption => localizedValues['selectPaymentOption'][locale.languageCode]; + + String get changeMethod => localizedValues['changeMethod'][locale.languageCode]; + String get reviewOrder => localizedValues['reviewOrder'][locale.languageCode]; - String get orderSummary => - localizedValues['orderSummary'][locale.languageCode]; + + String get orderSummary => localizedValues['orderSummary'][locale.languageCode]; + String get active => localizedValues['active'][locale.languageCode]; + String get inactive => localizedValues['inactive'][locale.languageCode]; + String get balance => localizedValues['balance'][locale.languageCode]; + String get gained => localizedValues['gained'][locale.languageCode]; + String get consumed => localizedValues['consumed'][locale.languageCode]; + String get transferred => localizedValues['transferred'][locale.languageCode]; - String get checkBeneficiary => - localizedValues['checkBeneficiary'][locale.languageCode]; - String get beneficiaryName => - localizedValues['beneficiaryName'][locale.languageCode]; - String get accountActivation => - localizedValues['accountActivation'][locale.languageCode]; - - String get lakumTransfer => - localizedValues['lakumTransfer'][locale.languageCode]; + + String get checkBeneficiary => localizedValues['checkBeneficiary'][locale.languageCode]; + + String get beneficiaryName => localizedValues['beneficiaryName'][locale.languageCode]; + + String get accountActivation => localizedValues['accountActivation'][locale.languageCode]; + + String get nonRecommended => localizedValues['nonRecommended'][locale.languageCode]; + + String get lakumTransfer => localizedValues['lakumTransfer'][locale.languageCode]; + String get acceptLbl => localizedValues['acceptLbl'][locale.languageCode]; - String get termsService => - localizedValues['TermsService'][locale.languageCode]; + String get termsService => localizedValues['TermsService'][locale.languageCode]; + String get beforeUsing => localizedValues['Beforeusing'][locale.languageCode]; + String get accept => localizedValues['accept'][locale.languageCode]; - String get dataSafeInfo => - localizedValues['data-safe-info'][locale.languageCode]; + + String get dataSafeInfo => localizedValues['data-safe-info'][locale.languageCode]; + String get dataSafe => localizedValues['data-safe'][locale.languageCode]; - String get informational => - localizedValues['informational'][locale.languageCode]; - String get checkDiagnosis => - localizedValues['check-diagnosis'][locale.languageCode]; + + String get informational => localizedValues['informational'][locale.languageCode]; + + String get checkDiagnosis => localizedValues['check-diagnosis'][locale.languageCode]; + String get remeberthat => localizedValues['remeberthat'][locale.languageCode]; - String get notUseInEmbergency => - localizedValues['not-use-in-emerbency'][locale.languageCode]; - String get notUseInEmbergencyDetails => - localizedValues['not-use-in-emerbency-details'][locale.languageCode]; - String get notUseInEmbergencyCall => - localizedValues['not-use-in-emerbency-details-call'][locale.languageCode]; - String get selectGender => - localizedValues['select-gender'][locale.languageCode]; + + String get notUseInEmbergency => localizedValues['not-use-in-emerbency'][locale.languageCode]; + + String get notUseInEmbergencyDetails => localizedValues['not-use-in-emerbency-details'][locale.languageCode]; + + String get notUseInEmbergencyCall => localizedValues['not-use-in-emerbency-details-call'][locale.languageCode]; + + String get selectGender => localizedValues['select-gender'][locale.languageCode]; + String get iAma => localizedValues['i-am-a'][locale.languageCode]; + String get selectAge => localizedValues['select-age'][locale.languageCode]; + String get iAm => localizedValues['i-am'][locale.languageCode]; + String get yearOld => localizedValues['years-old'][locale.languageCode]; + String get categorise => localizedValues['categorise'][locale.languageCode]; + + String get refine => localizedValues['refine'][locale.languageCode]; + + String get subGroup => localizedValues['subGroup'][locale.languageCode]; + + String get max => localizedValues['max'][locale.languageCode]; + + String get min => localizedValues['min'][locale.languageCode]; + + String get compeleteOrderMsg => localizedValues['compeleteOrderMsg'][locale.languageCode]; + + String get addToCompareMsg => localizedValues['addToCompareMsg'][locale.languageCode]; + + String get itInListMsg => localizedValues['itInListMsg'][locale.languageCode]; + + String get compareListFull => localizedValues['compareListFull'][locale.languageCode]; + + String get addQuantity => localizedValues['addQuantity'][locale.languageCode]; + + String get addToCartMsg => localizedValues['addToCartMsg'][locale.languageCode]; + + String get addToWishlistMsg => localizedValues['addToWishlistMsg'][locale.languageCode]; + + String get notifyMeMsg => localizedValues['notifyMeMsg'][locale.languageCode]; + + String get removeFromWishlistMsg => localizedValues['removeFromWishlistMsg'][locale.languageCode]; + + String get apply => localizedValues['apply'][locale.languageCode]; + + String get reset => localizedValues['reset'][locale.languageCode]; + + String get viewCategorise => localizedValues['viewCategorise'][locale.languageCode]; + + String get viewSubCategorise => localizedValues['viewSubCategorise'][locale.languageCode]; + String get cart => localizedValues['cart'][locale.languageCode]; + String get wishList => localizedValues['wishList'][locale.languageCode]; - String get searchProductHere => - localizedValues['searchProductHere'][locale.languageCode]; + + String get Alhabibapp => localizedValues['Alhabibapp'][locale.languageCode]; + + String get searchProductHere => localizedValues['searchProductHere'][locale.languageCode]; + String get email => localizedValues['email'][locale.languageCode]; + String get book => localizedValues['Book'][locale.languageCode]; - String get appointmentLabel => - localizedValues['AppointmentLabel'][locale.languageCode]; + + String get appointmentLabel => localizedValues['AppointmentLabel'][locale.languageCode]; + String get bloodType => localizedValues['BloodType'][locale.languageCode]; - String get loginToUseService => - localizedValues['loginToUseService'][locale.languageCode]; - String get maritalStatus => - localizedValues['marital-status'][locale.languageCode]; + String get loginToUseService => localizedValues['loginToUseService'][locale.languageCode]; + + String get maritalStatus => localizedValues['marital-status'][locale.languageCode]; + String get general => localizedValues['general'][locale.languageCode]; + String get profile => localizedValues['profile'][locale.languageCode]; - String get notifications => - localizedValues['notifications'][locale.languageCode]; - String get notificationDetails => - localizedValues['notificationDetails'][locale.languageCode]; - List get infoMyDoctorPoints => - localizedValues['info-my-doctor-points'][locale.languageCode]; - String get infoMyDoctor => - localizedValues['info-my-doctor'][locale.languageCode]; - String get infoPrescriptions => - localizedValues['info-prescriptions'][locale.languageCode]; - List get infoPrescriptionsPoints => - localizedValues['info-my-prescription-points'][locale.languageCode]; - - String get infoInsuranceCards => - localizedValues['info-insurance-cards'][locale.languageCode]; - List get infoInsuranceCardsPoints => - localizedValues['info-insurance-cards-points'][locale.languageCode]; - - String get infoAllergies => - localizedValues['info-allergies'][locale.languageCode]; + + String get notifications => localizedValues['notifications'][locale.languageCode]; + + String get notificationDetails => localizedValues['notificationDetails'][locale.languageCode]; + + List get infoMyDoctorPoints => localizedValues['info-my-doctor-points'][locale.languageCode]; + + String get infoMyDoctor => localizedValues['info-my-doctor'][locale.languageCode]; + + String get infoPrescriptions => localizedValues['info-prescriptions'][locale.languageCode]; + + List get infoPrescriptionsPoints => localizedValues['info-my-prescription-points'][locale.languageCode]; + + String get infoInsuranceCards => localizedValues['info-insurance-cards'][locale.languageCode]; + + List get infoInsuranceCardsPoints => localizedValues['info-insurance-cards-points'][locale.languageCode]; + + String get infoAllergies => localizedValues['info-allergies'][locale.languageCode]; String get sickLeaves => localizedValues['sick-leaves'][locale.languageCode]; - String get infoSickLeaves => - localizedValues['info-sick-leaves'][locale.languageCode]; - List get infoSickLeavePoints => - localizedValues['info-sick-leave-points'][locale.languageCode]; - - String get infoApprovals => - localizedValues['info-approvals'][locale.languageCode]; - List get infoApprovalPoints => - localizedValues['info-approval-points'][locale.languageCode]; - - String get monthReport => - localizedValues['month-report'][locale.languageCode]; - String get infoMonthReport => - localizedValues['info-month-report'][locale.languageCode]; - String get languageSetting => - localizedValues['language-setting'][locale.languageCode]; + + String get infoSickLeaves => localizedValues['info-sick-leaves'][locale.languageCode]; + + List get infoSickLeavePoints => localizedValues['info-sick-leave-points'][locale.languageCode]; + + String get infoApprovals => localizedValues['info-approvals'][locale.languageCode]; + + List get infoApprovalPoints => localizedValues['info-approval-points'][locale.languageCode]; + + String get monthReport => localizedValues['month-report'][locale.languageCode]; + + String get infoMonthReport => localizedValues['info-month-report'][locale.languageCode]; + + String get languageSetting => localizedValues['language-setting'][locale.languageCode]; + String get alert => localizedValues['alert'][locale.languageCode]; + String get emailAlert => localizedValues['email-alert'][locale.languageCode]; + String get smsAlert => localizedValues['sms-alert'][locale.languageCode]; - String get contactInfo => - localizedValues['contact-info'][locale.languageCode]; + + String get contactInfo => localizedValues['contact-info'][locale.languageCode]; + String get emergencyName => localizedValues['emrg-name'][locale.languageCode]; - String get emergencyContact => - localizedValues['emrg-no'][locale.languageCode]; + + String get emergencyContact => localizedValues['emrg-no'][locale.languageCode]; + String get modes => localizedValues['modes'][locale.languageCode]; + String get vibration => localizedValues['vibration'][locale.languageCode]; + String get blindMode => localizedValues['blind-modes'][locale.languageCode]; - String get invertTheme => - localizedValues['invert-theme'][locale.languageCode]; + + String get invertTheme => localizedValues['invert-theme'][locale.languageCode]; + String get offTheme => localizedValues['off-theme'][locale.languageCode]; + String get dimTheme => localizedValues['dim-theme'][locale.languageCode]; + String get bwTheme => localizedValues['bw-theme'][locale.languageCode]; String get permissions => localizedValues['permissions'][locale.languageCode]; - String get cameraPermission => - localizedValues['camera-permission'][locale.languageCode]; - String get locationPermission => - localizedValues['location-permission'][locale.languageCode]; - String get accessibility => - localizedValues['accessibility'][locale.languageCode]; - String get selectClinic => - localizedValues['selectClinic'][locale.languageCode]; + + String get cameraPermission => localizedValues['camera-permission'][locale.languageCode]; + + String get locationPermission => localizedValues['location-permission'][locale.languageCode]; + + String get accessibility => localizedValues['accessibility'][locale.languageCode]; + + String get selectClinic => localizedValues['selectClinic'][locale.languageCode]; + + String get selectProject => localizedValues['selectProject'][locale.languageCode]; String get orderStatus => localizedValues['orderStatus'][locale.languageCode]; + String get findUs => localizedValues['FindUs'][locale.languageCode]; + String get feedback => localizedValues['Feedback'][locale.languageCode]; + String get liveChat => localizedValues['LiveChat'][locale.languageCode]; + String get service => localizedValues['Service'][locale.languageCode]; - String get hMGServiceLabel => - localizedValues['HMGServiceLabel'][locale.languageCode]; - String get healthWeatherIndicators => - localizedValues['HealthWeatherIndicators'][locale.languageCode]; - String get healthTipsBasedOnCurrentWeather => - localizedValues['HealthTipsBasedOnCurrentWeather'][locale.languageCode]; + + String get hMGServiceLabel => localizedValues['HMGServiceLabel'][locale.languageCode]; + + String get healthWeatherIndicators => localizedValues['HealthWeatherIndicators'][locale.languageCode]; + + String get healthTipsBasedOnCurrentWeather => localizedValues['HealthTipsBasedOnCurrentWeather'][locale.languageCode]; + String get moreDetails => localizedValues['MoreDetails'][locale.languageCode]; + String get sendCopy => localizedValues['SendCopy'][locale.languageCode]; + String get resendOrder => localizedValues['ResendOrder'][locale.languageCode]; + String get ports => localizedValues['Ports'][locale.languageCode]; + String get way => localizedValues['Way'][locale.languageCode]; + String get average => localizedValues['Average'][locale.languageCode]; + String get dailyDoses => localizedValues['DailyDoses'][locale.languageCode]; + String get period => localizedValues['Period'][locale.languageCode]; + String get duration => localizedValues['duration'][locale.languageCode]; + String get cm => localizedValues['cm'][locale.languageCode]; + String get kg => localizedValues['kg'][locale.languageCode]; + String get lb => localizedValues['lb'][locale.languageCode]; + String get birth_date => localizedValues['birth_date'][locale.languageCode]; + + String get dateOfBirth => localizedValues['date_of_birth'][locale.languageCode]; + String get mass => localizedValues['mass'][locale.languageCode]; + String get tempC => localizedValues['temp-c'][locale.languageCode]; + String get bpm => localizedValues['bpm'][locale.languageCode]; - String get respirationSigns => - localizedValues['respiration-signs'][locale.languageCode]; + + String get respirationSigns => localizedValues['respiration-signs'][locale.languageCode]; + String get sysDias => localizedValues['sys-dias'][locale.languageCode]; + String get body => localizedValues['body'][locale.languageCode]; + + String get bodyString => localizedValues['body_string'][locale.languageCode]; + + String get bikini => localizedValues['bikini'][locale.languageCode]; + + String get totalMinutes => localizedValues['totalMinutes'][locale.languageCode]; + + String get face => localizedValues['face'][locale.languageCode]; + + String get retouch => localizedValues['retouch'][locale.languageCode]; + String get feedbackTitle => localizedValues['feedback'][locale.languageCode]; + String get send => localizedValues['send'][locale.languageCode]; + String get status => localizedValues['status'][locale.languageCode]; + String get likeToHear => localizedValues['like-to-hear'][locale.languageCode]; + String get subject => localizedValues['subject'][locale.languageCode]; + String get message => localizedValues['message'][locale.languageCode]; - String get emptySubject => - localizedValues['empty-subject'][locale.languageCode]; - String get emptyMessage => - localizedValues['empty-message'][locale.languageCode]; - String get selectAttachment => - localizedValues['select-attachment'][locale.languageCode]; - String get complainAppo => - localizedValues['complain-appo'][locale.languageCode]; - String get complainWithoutAppo => - localizedValues['complain-without-appo'][locale.languageCode]; + + String get emptySubject => localizedValues['empty-subject'][locale.languageCode]; + + String get emptyMessage => localizedValues['empty-message'][locale.languageCode]; + + String get selectAttachment => localizedValues['select-attachment'][locale.languageCode]; + + String get complainAppo => localizedValues['complain-appo'][locale.languageCode]; + + String get complainWithoutAppo => localizedValues['complain-without-appo'][locale.languageCode]; + String get question => localizedValues['question'][locale.languageCode]; - String get messageType => - localizedValues['message-type'][locale.languageCode]; + + String get messageType => localizedValues['message-type'][locale.languageCode]; + String get compliment => localizedValues['compliment'][locale.languageCode]; + String get suggestion => localizedValues['suggestion'][locale.languageCode]; - String get yourFeedback => - localizedValues['your-feedback'][locale.languageCode]; + + String get yourFeedback => localizedValues['your-feedback'][locale.languageCode]; + String get selectPart => localizedValues['select-part'][locale.languageCode]; + String get number => localizedValues['number'][locale.languageCode]; - String get notClassified => - localizedValues['not-classified'][locale.languageCode]; - String get searchItemError => - localizedValues['searchItemError'][locale.languageCode]; + + String get notClassified => localizedValues['not-classified'][locale.languageCode]; + + String get searchItemError => localizedValues['searchItemError'][locale.languageCode]; + String get youCanFind => localizedValues['YouCanFind'][locale.languageCode]; - String get itemInSearch => - localizedValues['ItemInSearch'][locale.languageCode]; - String get bloodDonation => - localizedValues['blood-donation'][locale.languageCode]; - String get bloodInstruction => - localizedValues['blood-instruction'][locale.languageCode]; - String get bloodTermsNcondition => - localizedValues['view-terms'][locale.languageCode]; - String get wantToConnectWithHmgNetwork => - localizedValues['wantConnectHmgNetwork'][locale.languageCode]; - String get failedToAccessHmgServices => - localizedValues['failedToAccessHmgServices'][locale.languageCode]; - String get enablingWifi => - localizedValues['enablingWifi'][locale.languageCode]; - String get offerAndPackages => - localizedValues['offerAndPackages'][locale.languageCode]; + + String get itemInSearch => localizedValues['ItemInSearch'][locale.languageCode]; + + String get bloodDonation => localizedValues['blood-donation'][locale.languageCode]; + + String get bloodDonationInfo => localizedValues['blood-donation-info'][locale.languageCode]; + + String get bloodInstruction => localizedValues['blood-instruction'][locale.languageCode]; + + String get bloodTermsNcondition => localizedValues['view-terms'][locale.languageCode]; + + String get wantToConnectWithHmgNetwork => localizedValues['wantConnectHmgNetwork'][locale.languageCode]; + + String get failedToAccessHmgServices => localizedValues['failedToAccessHmgServices'][locale.languageCode]; + + String get enablingWifi => localizedValues['enablingWifi'][locale.languageCode]; + + String get offerAndPackages => localizedValues['offerAndPackages'][locale.languageCode]; + + String get orderHistory => localizedValues['orderHistory'][locale.languageCode]; + + String get offerAndPackagesDetails => localizedValues['offerAndPackagesDetails'][locale.languageCode]; String get invoiceNo => localizedValues['InvoiceNo'][locale.languageCode]; - String get specialResult => - localizedValues['SpecialResult'][locale.languageCode]; - String get generalResult => - localizedValues['GeneralResult'][locale.languageCode]; - String get showMoreBtn => - localizedValues['show-more-btn'][locale.languageCode]; + + String get invoiceDate => localizedValues['InvoiceDate'][locale.languageCode]; + + String get specialResult => localizedValues['SpecialResult'][locale.languageCode]; + + String get generalResult => localizedValues['GeneralResult'][locale.languageCode]; + + String get showMoreBtn => localizedValues['show-more-btn'][locale.languageCode]; + + String get viewFlowChart => localizedValues['view_flow_chart'][locale.languageCode]; + String get value => localizedValues['value'][locale.languageCode]; + String get range => localizedValues['range'][locale.languageCode]; + String get outpatient => localizedValues['out-patient'][locale.languageCode]; + String get inPatient => localizedValues['in-patient'][locale.languageCode]; + String get liveCare => localizedValues['liveCare'][locale.languageCode]; + String get report => localizedValues['report'][locale.languageCode]; + String get openRad => localizedValues['open-rad'][locale.languageCode]; + String get sendCopyRad => localizedValues['send-copy'][locale.languageCode]; + String get appoSurvey => localizedValues['appoSurvey'][locale.languageCode]; + String get vaccination => localizedValues['vaccination'][locale.languageCode]; - String get welcomeBackV => - localizedValues['welcomeBack'][locale.languageCode]; - String get instructions => - localizedValues['instructions'][locale.languageCode]; - String get updateEmail => - localizedValues['update-email'][locale.languageCode]; - String get updatedEmail => - localizedValues['updated-email'][locale.languageCode]; - String get viewListChildren => - localizedValues['view-list-children'][locale.languageCode]; + + String get welcomeBackV => localizedValues['welcomeBack'][locale.languageCode]; + + String get instructions => localizedValues['instructions'][locale.languageCode]; + + String get updateEmail => localizedValues['update-email'][locale.languageCode]; + + String get updatedEmail => localizedValues['updated-email'][locale.languageCode]; + + String get viewListChildren => localizedValues['view-list-children'][locale.languageCode]; + String get addChild => localizedValues['add-child'][locale.languageCode]; + String get childName => localizedValues['child-name'][locale.languageCode]; + String get childDob => localizedValues['childDob'][locale.languageCode]; - String get deletedChildMes => - localizedValues['deleted-child-mes'][locale.languageCode]; + + String get deletedChildMes => localizedValues['deleted-child-mes'][locale.languageCode]; + String get visit => localizedValues['visit'][locale.languageCode]; - String get descriptionVaccination => - localizedValues['description-vaccination'][locale.languageCode]; + + String get descriptionVaccination => localizedValues['description-vaccination'][locale.languageCode]; + String get dueDate => localizedValues['due-date'][locale.languageCode]; + String get validEmail => localizedValues['valid-email'][locale.languageCode]; - String get confirmSend => - localizedValues['confirm-send'][locale.languageCode]; - String get emailSuccess => - localizedValues['email-success'][locale.languageCode]; - String get deletedChild => - localizedValues['deleted-child'][locale.languageCode]; - String get addInstructions => - localizedValues['add-instructions'][locale.languageCode]; + + String get confirmSend => localizedValues['confirm-send'][locale.languageCode]; + + String get emailSuccess => localizedValues['email-success'][locale.languageCode]; + + String get deletedChild => localizedValues['deleted-child'][locale.languageCode]; + + String get addInstructions => localizedValues['add-instructions'][locale.languageCode]; + String get addedChild => localizedValues['added-child'][locale.languageCode]; + String get appUpdate => localizedValues['appUpdate'][locale.languageCode]; - String get ereferralSaveSuccess => - localizedValues['ereferralSaveSuccess'][locale.languageCode]; + + String get ereferralSaveSuccess => localizedValues['ereferralSaveSuccess'][locale.languageCode]; + String get labResults => localizedValues['labResults'][locale.languageCode]; - String get doctorRating => - localizedValues['doctorRating'][locale.languageCode]; + + String get doctorRating => localizedValues['doctorRating'][locale.languageCode]; + String get good => localizedValues['good'][locale.languageCode]; + String get v_good => localizedValues['v-good'][locale.languageCode]; + String get excellent => localizedValues['excellent'][locale.languageCode]; - String get below_average => - localizedValues['below-average'][locale.languageCode]; + + String get below_average => localizedValues['below-average'][locale.languageCode]; + String get infoSigns => localizedValues['info-signs'][locale.languageCode]; - String get infoAdvancePayment => - localizedValues['info-advance-payment'][locale.languageCode]; - String get infoMyBalance => - localizedValues['info-my-balance'][locale.languageCode]; + + String get infoAdvancePayment => localizedValues['info-advance-payment'][locale.languageCode]; + + String get infoMyBalance => localizedValues['info-my-balance'][locale.languageCode]; + String get erContant => localizedValues['er-contant'][locale.languageCode]; + String get er => localizedValues['er'][locale.languageCode]; - String get transportationService => - localizedValues['transportation-Service'][locale.languageCode]; - String get infoAmbulance => - localizedValues['info-ambulance'][locale.languageCode]; - String get transportHeading => - localizedValues['RRT-transport-heading'][locale.languageCode]; - String get directionHeading => - localizedValues['RRT-direction-heading'][locale.languageCode]; + + String get transportationService => localizedValues['transportation-Service'][locale.languageCode]; + + String get infoAmbulance => localizedValues['info-ambulance'][locale.languageCode]; + + String get transportHeading => localizedValues['RRT-transport-heading'][locale.languageCode]; + + String get directionHeading => localizedValues['RRT-direction-heading'][locale.languageCode]; + String get toHospital => localizedValues['to-hospital'][locale.languageCode]; - String get fromHospital => - localizedValues['from-hospital'][locale.languageCode]; + + String get fromHospital => localizedValues['from-hospital'][locale.languageCode]; + String get oneDirec => localizedValues['one-direc'][locale.languageCode]; + String get twoDirec => localizedValues['two-direc'][locale.languageCode]; - String get pickupLocation => - localizedValues['pickup-location'][locale.languageCode]; + + String get pickupLocation => localizedValues['pickup-location'][locale.languageCode]; + String get pickupSpot => localizedValues['pickup-spot'][locale.languageCode]; + String get insideHome => localizedValues['inside-home'][locale.languageCode]; + String get haveAppo => localizedValues['have-appo'][locale.languageCode]; - String get dropoffLocation => - localizedValues['dropoff-location'][locale.languageCode]; + + String get dropoffLocation => localizedValues['dropoff-location'][locale.languageCode]; + String get selectAll => localizedValues['select-all'][locale.languageCode]; + + String get select => localizedValues['select'][locale.languageCode]; + String get selectMap => localizedValues['select-map'][locale.languageCode]; - String get noAppointment => - localizedValues['no-appointment'][locale.languageCode]; - String get patientShareB => - localizedValues['patient-share'][locale.languageCode]; - String get patientShareTax => - localizedValues['patient-share-tax'][locale.languageCode]; - String get patientShareTotal => - localizedValues['patient-share-total'][locale.languageCode]; - String get selectAmbulate => - localizedValues['select-ambulate'][locale.languageCode]; + + String get noAppointment => localizedValues['no-appointment'][locale.languageCode]; + + String get patientShareB => localizedValues['patient-share'][locale.languageCode]; + + String get patientShareTax => localizedValues['patient-share-tax'][locale.languageCode]; + + String get patientShareTotal => localizedValues['patient-share-total'][locale.languageCode]; + + String get selectAmbulate => localizedValues['select-ambulate'][locale.languageCode]; + String get wheelchair => localizedValues['wheelchair'][locale.languageCode]; + String get walker => localizedValues['walker'][locale.languageCode]; + String get stretcher => localizedValues['stretcher'][locale.languageCode]; + String get none => localizedValues['none'][locale.languageCode]; + String get RRTSummary => localizedValues['RRT-Summary'][locale.languageCode]; + + String get rapidResponseTeam => localizedValues['Rapid-Response-Team'][locale.languageCode]; + + String get rrtDDetails => localizedValues['RRTDDetails'][locale.languageCode]; + + String get approximateServiceFee => localizedValues['ApproximateServiceFee'][locale.languageCode]; + + String get amountBeforeTax => localizedValues['AmountBeforeTax'][locale.languageCode]; + + String get taxAmount => localizedValues['TaxAmount'][locale.languageCode]; + + String get totalAmountPayable => localizedValues['TotalAmountPayable'][locale.languageCode]; + + String get somethingWentWrongTryLater => localizedValues['somethingWentWrongTryLater'][locale.languageCode]; + + String get youCanPayByTheFollowingOptions => localizedValues['YouCanPayByTheFollowingOptions'][locale.languageCode]; + + String get rrtUserAgreementTitle => localizedValues['rrtUserAgreementTitle'][locale.languageCode]; + + String get rrtUserAgreementP1 => localizedValues['rrtUserAgreementP1'][locale.languageCode]; + + String get rrtUserAgreementP2 => localizedValues['rrtUserAgreementP2'][locale.languageCode]; + + String get rrtUserAgreementP3 => localizedValues['rrtUserAgreementP3'][locale.languageCode]; + + String get rrtOrderSuccessMessage => localizedValues['rrtOrderSuccessMessage'][locale.languageCode]; + String get billAmount => localizedValues['bill-amount'][locale.languageCode]; - String get transportMethod => - localizedValues['transport-method'][locale.languageCode]; + + String get transportMethod => localizedValues['transport-method'][locale.languageCode]; + String get directions => localizedValues['directions'][locale.languageCode]; - String get infoMyAppointments => - localizedValues['info-my-appointments'][locale.languageCode]; + String get infoMyAppointments => localizedValues['info-my-appointments'][locale.languageCode]; + String get infoTodo => localizedValues['info-todo'][locale.languageCode]; + String get familyInfo => localizedValues['family-info'][locale.languageCode]; - String get profileUpdate => - localizedValues['update-succ'][locale.languageCode]; - String get dentalComplaints => - localizedValues['dental-complains'][locale.languageCode]; - String get emptyResult => - localizedValues['empty-result'][locale.languageCode]; - - String get noBookedAppo => - localizedValues['no-booked-appointment'][locale.languageCode]; - String get noConfirmedAppo => - localizedValues['no-confirmed-appointment'][locale.languageCode]; - String get noArrivedAppo => - localizedValues['no-arrived-appointment'][locale.languageCode]; - String get upcomingEmpty => - localizedValues['upcoming-empty'][locale.languageCode]; - String get upcomingTimeLeft => - localizedValues['upcoming-timeLeft'][locale.languageCode]; - - String get covidTestAllServices => - localizedValues['covid-test-all-services'][locale.languageCode]; + + String get profileUpdate => localizedValues['update-succ'][locale.languageCode]; + + String get dentalComplaints => localizedValues['dental-complains'][locale.languageCode]; + + String get emptyResult => localizedValues['empty-result'][locale.languageCode]; + + String get noBookedAppo => localizedValues['no-booked-appointment'][locale.languageCode]; + + String get noConfirmedAppo => localizedValues['no-confirmed-appointment'][locale.languageCode]; + + String get noArrivedAppo => localizedValues['no-arrived-appointment'][locale.languageCode]; + + String get upcomingEmpty => localizedValues['upcoming-empty'][locale.languageCode]; + + String get upcomingTimeLeft => localizedValues['upcoming-timeLeft'][locale.languageCode]; + + String get covidTestAllServices => localizedValues['covid-test-all-services'][locale.languageCode]; + String get pharmacy => localizedValues['pharmacy'][locale.languageCode]; + String get ereferral => localizedValues['ereferral'][locale.languageCode]; - String get childVaccine => - localizedValues['child-vaccine'][locale.languageCode]; + + String get childVaccine => localizedValues['child-vaccine'][locale.languageCode]; + String get calculators => localizedValues['calculators'][locale.languageCode]; + String get converters => localizedValues['converters'][locale.languageCode]; + String get h2o => localizedValues['h2o'][locale.languageCode]; - String get waterTracker => - localizedValues['waterTracker'][locale.languageCode]; + + String get waterTracker => localizedValues['waterTracker'][locale.languageCode]; + String get ft => localizedValues['ft'][locale.languageCode]; + String get vTour => localizedValues['v-tour'][locale.languageCode]; + String get hmgNews => localizedValues['hmg-news'][locale.languageCode]; + String get bloodD => localizedValues['blood-d'][locale.languageCode]; - String get symptomCheckerTitle => - localizedValues['symptomCheckerTitle'][locale.languageCode]; + + String get symptomCheckerTitle => localizedValues['symptomCheckerTitle'][locale.languageCode]; + String get latestNews => localizedValues['latest-news'][locale.languageCode]; - String get ourLocation => - localizedValues['our-location'][locale.languageCode]; + + String get ourLocation => localizedValues['our-location'][locale.languageCode]; + String get pharmacies => localizedValues['pharmacies'][locale.languageCode]; + String get hospitals => localizedValues['hospitals'][locale.languageCode]; + String get wallet => localizedValues['wallet'][locale.languageCode]; + String get hmg => localizedValues['hmg'][locale.languageCode]; + String get requested => localizedValues['requested'][locale.languageCode]; + String get ready => localizedValues['ready'][locale.languageCode]; + String get completed => localizedValues['completed'][locale.languageCode]; - String get requestMedicalReport => - localizedValues['request-medical-report'][locale.languageCode]; + + String get requestMedicalReport => localizedValues['request-medical-report'][locale.languageCode]; + String get insurCards => localizedValues['insur-cards'][locale.languageCode]; + String get labResult => localizedValues['labResult'][locale.languageCode]; + String get details => localizedValues['details'][locale.languageCode]; + + String get graphDetails => localizedValues['graph-details'][locale.languageCode]; + String get age => localizedValues['age'][locale.languageCode]; - String get activeInsurence => - localizedValues['active-insurence'][locale.languageCode]; + + String get activeInsurence => localizedValues['active-insurence'][locale.languageCode]; + String get notActive => localizedValues['not-active'][locale.languageCode]; + String get cardDetail => localizedValues['card-detail'][locale.languageCode]; + String get dr => localizedValues['Dr'][locale.languageCode]; + String get sendSuc => localizedValues['sendSuc'][locale.languageCode]; - String get instructionsPharmacies => - localizedValues['instructions-pharmacies'][locale.languageCode]; - String get selectHospitalDec => - localizedValues['select-hospital'][locale.languageCode]; + + String get instructionsPharmacies => localizedValues['instructions-pharmacies'][locale.languageCode]; + + String get selectHospitalDec => localizedValues['select-hospital'][locale.languageCode]; String get start => localizedValues['start'][locale.languageCode]; + String get infoChat => localizedValues['info-chat'][locale.languageCode]; String get noRecords => localizedValues['empty'][locale.languageCode]; + String get lastVisit => localizedValues['last-visit'][locale.languageCode]; + String get tapTitle => localizedValues['tap-title'][locale.languageCode]; + String get later => localizedValues['later'][locale.languageCode]; - String get lastAppointment => - localizedValues['last-appointment'][locale.languageCode]; + String get lastAppointment => localizedValues['last-appointment'][locale.languageCode]; + String get rateClinic => localizedValues['rate-clinic'][locale.languageCode]; + String get fetchData => localizedValues['fetch-data'][locale.languageCode]; - String get sendConfEmail => - localizedValues['send-email'][locale.languageCode]; - String get noDataAvailable => - localizedValues['noDataAvailable'][locale.languageCode]; + String get sendConfEmail => localizedValues['send-email'][locale.languageCode]; + + String get noDataAvailable => localizedValues['noDataAvailable'][locale.languageCode]; + String get theName => localizedValues['thename'][locale.languageCode]; - String get noSearchResult => - localizedValues['noSearchResult'][locale.languageCode]; - String get selectFileSouse => - localizedValues['selectFileSouse'][locale.languageCode]; + + String get noSearchResult => localizedValues['noSearchResult'][locale.languageCode]; + + String get selectFileSouse => localizedValues['selectFileSouse'][locale.languageCode]; + String get rate => localizedValues['rate'][locale.languageCode]; - String get bookedSuccess => - localizedValues['booked-success'][locale.languageCode]; - String get appoReminder30 => - localizedValues['appo-reminder-select-option-30'][locale.languageCode]; - String get appoReminder60 => - localizedValues['appo-reminder-select-option-60'][locale.languageCode]; - String get appoReminder90 => - localizedValues['appo-reminder-select-option-90'][locale.languageCode]; - String get appoReminder120 => - localizedValues['appo-reminder-select-option-120'][locale.languageCode]; + + String get bookedSuccess => localizedValues['booked-success'][locale.languageCode]; + + String get appoReminder30 => localizedValues['appo-reminder-select-option-30'][locale.languageCode]; + + String get appoReminder60 => localizedValues['appo-reminder-select-option-60'][locale.languageCode]; + + String get appoReminder90 => localizedValues['appo-reminder-select-option-90'][locale.languageCode]; + + String get appoReminder120 => localizedValues['appo-reminder-select-option-120'][locale.languageCode]; + String get gallery => localizedValues['gallery'][locale.languageCode]; + String get camera => localizedValues['camera'][locale.languageCode]; + String get medReport => localizedValues['med-report'][locale.languageCode]; - String get newMedReport => - localizedValues['new-med-report'][locale.languageCode]; - String get requestReport => - localizedValues['requestReport'][locale.languageCode]; - String get confirmMsgReport => - localizedValues['confirm-msg-report'][locale.languageCode]; - String get successSendReport => - localizedValues['successSendReport'][locale.languageCode]; + + String get newMedReport => localizedValues['new-med-report'][locale.languageCode]; + + String get requestReport => localizedValues['requestReport'][locale.languageCode]; + + String get confirmMsgReport => localizedValues['confirm-msg-report'][locale.languageCode]; + + String get successSendReport => localizedValues['successSendReport'][locale.languageCode]; + String get pulseTitle => localizedValues['pulseTitle'][locale.languageCode]; - String get systolicLng => - localizedValues['systolic-lng'][locale.languageCode]; - String get diastolicLng => - localizedValues['diastolic-lng'][locale.languageCode]; - String get policyHolder => - localizedValues['policy-holder'][locale.languageCode]; + + String get systolicLng => localizedValues['systolic-lng'][locale.languageCode]; + + String get diastolicLng => localizedValues['diastolic-lng'][locale.languageCode]; + + String get policyHolder => localizedValues['policy-holder'][locale.languageCode]; + String get policyNo => localizedValues['policy-no'][locale.languageCode]; - String get expiryDateTitle => - localizedValues['expiry-date'][locale.languageCode]; + + String get expiryDateTitle => localizedValues['expiry-date'][locale.languageCode]; + String get classTitle => localizedValues['class'][locale.languageCode]; + String get approval => localizedValues['approval'][locale.languageCode]; + String get agree => localizedValues['agree'][locale.languageCode]; + String get disagree => localizedValues['disagree'][locale.languageCode]; - String get requestSent => - localizedValues['request-sent'][locale.languageCode]; - String get attachInsuraceImage => - localizedValues['attach-insurace-image'][locale.languageCode]; - String get infoInsurCards => - localizedValues['info-insur-cards'][locale.languageCode]; + + String get requestSent => localizedValues['request-sent'][locale.languageCode]; + + String get attachInsuraceImage => localizedValues['attach-insurace-image'][locale.languageCode]; + + String get infoInsurCards => localizedValues['info-insur-cards'][locale.languageCode]; + String get scanNow => localizedValues['scan-now'][locale.languageCode]; - String get pharmacyServiceTermsCondition => - localizedValues['pharmacyServiceTermsCondition'][locale.languageCode]; - String get recordDeleted => - localizedValues['recordDeleted'][locale.languageCode]; + String get pharmacyServiceTermsCondition => localizedValues['pharmacyServiceTermsCondition'][locale.languageCode]; + + String get recordDeleted => localizedValues['recordDeleted'][locale.languageCode]; + + String get referralStatus => localizedValues['referralStatus'][locale.languageCode]; + + String get referralDate => localizedValues['referralDate'][locale.languageCode]; - String get referralStatus => - localizedValues['referralStatus'][locale.languageCode]; - String get referralDate => - localizedValues['referralDate'][locale.languageCode]; String get patientName => localizedValues['patientName'][locale.languageCode]; - String get referralNumber => - localizedValues['referralNumber'][locale.languageCode]; + + String get referralNumber => localizedValues['referralNumber'][locale.languageCode]; + + String get needPrescription => localizedValues['needPrescription'][locale.languageCode]; + + String get outOfStockMsg => localizedValues['outOfStockMsg'][locale.languageCode]; + + String get productOutOfStock => localizedValues['productOutOfStock'][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]; + String get pickupDate => localizedValues['pickupDate'][locale.languageCode]; + String get serviceName => localizedValues['serviceName'][locale.languageCode]; - String get orderLocation => - localizedValues['orderLocation'][locale.languageCode]; - String get selectService => - localizedValues['selectService'][locale.languageCode]; - String get coveredService => - localizedValues['coveredService'][locale.languageCode]; - String get selectedService => - localizedValues['selectedService'][locale.languageCode]; - String get cancelOrderMsg => - localizedValues['cancelOrderMsg'][locale.languageCode]; - String get processDoneSuccessfully => - localizedValues['processDoneSuccessfully'][locale.languageCode]; - String get selectHomeHealthCareServices => - localizedValues['selectHomeHealthCareServices'][locale.languageCode]; + + String get orderLocation => localizedValues['orderLocation'][locale.languageCode]; + + String get selectService => localizedValues['selectService'][locale.languageCode]; + + String get coveredService => localizedValues['coveredService'][locale.languageCode]; + + String get selectedService => localizedValues['selectedService'][locale.languageCode]; + + String get cancelOrderMsg => localizedValues['cancelOrderMsg'][locale.languageCode]; + + String get processDoneSuccessfully => localizedValues['processDoneSuccessfully'][locale.languageCode]; + + String get selectHomeHealthCareServices => localizedValues['selectHomeHealthCareServices'][locale.languageCode]; + String get help => localizedValues['help'][locale.languageCode]; - String get habibRobotText => - localizedValues['habibRobotText'][locale.languageCode]; + + String get habibRobotText => localizedValues['habibRobotText'][locale.languageCode]; String get topBrands => localizedValues['topBrands'][locale.languageCode]; + String get notifyMe => localizedValues['notifyMe'][locale.languageCode]; - String get specification => - localizedValues['specification'][locale.languageCode]; - String get availability => - localizedValues['availability'][locale.languageCode]; - String get quantitySize => - localizedValues['quantitySize'][locale.languageCode]; + + String get specification => localizedValues['specification'][locale.languageCode]; + + String get availability => localizedValues['availability'][locale.languageCode]; + + 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 buyNow => localizedValues['buyNow'][locale.languageCode]; - String get quantityShortcut => - localizedValues['quantityShortcut'][locale.languageCode]; + + String get quantityShortcut => localizedValues['quantityShortcut'][locale.languageCode]; + + String get noData => localizedValues['noData'][locale.languageCode]; + + String get no_data => localizedValues['no_data'][locale.languageCode]; String get year => localizedValues['Year'][locale.languageCode]; + + String get years => localizedValues['years'][locale.languageCode]; + String get month => localizedValues['Month'][locale.languageCode]; + + String get enterDetailBelow => localizedValues['enter_detail_below'][locale.languageCode]; + String get point => localizedValues['point'][locale.languageCode]; + String get riyal => localizedValues['riyal'][locale.languageCode]; - String get termOfService => - localizedValues['termOfService'][locale.languageCode]; - String get shoppingCart => - localizedValues['shoppingCart'][locale.languageCode]; + + String get termOfService => localizedValues['termOfService'][locale.languageCode]; + + String get shoppingCart => localizedValues['shoppingCart'][locale.languageCode]; + String get covidTest => localizedValues['covidTest'][locale.languageCode]; + String get driveThru => localizedValues['driveThru'][locale.languageCode]; - String get NearestErDesc => - localizedValues['NearestErDesc'][locale.languageCode]; + + String get NearestErDesc => localizedValues['NearestErDesc'][locale.languageCode]; + String get NearestEr => localizedValues['NearestEr'][locale.languageCode]; + String get infoCMC => localizedValues['infoCMC'][locale.languageCode]; - String get instructionAgree => - localizedValues['instructionAgree'][locale.languageCode]; + + String get instructionAgree => localizedValues['instructionAgree'][locale.languageCode]; + String get reqId => localizedValues['reqId'][locale.languageCode]; - String get ordersLog => - localizedValues['RRT-orders-log'][locale.languageCode]; + + String get ordersLog => localizedValues['RRT-orders-log'][locale.languageCode]; + String get bloodSugar => localizedValues['blood-sugar'][locale.languageCode]; + String get myTracker => localizedValues['my-tracker'][locale.languageCode]; + String get weekly => localizedValues['weekly'][locale.languageCode]; + String get monthlyT => localizedValues['monthly'][locale.languageCode]; + String get yearly => localizedValues['yearly'][locale.languageCode]; + String get measured => localizedValues['measured'][locale.languageCode]; + String get sugarAdd => localizedValues['sugar-add'][locale.languageCode]; + String get other => localizedValues['other'][locale.languageCode]; - String get measureUnit => - localizedValues['measure-unit'][locale.languageCode]; - String get measureTime => - localizedValues['measure-time'][locale.languageCode]; + + String get measureUnit => localizedValues['measure-unit'][locale.languageCode]; + + String get measureTime => localizedValues['measure-time'][locale.languageCode]; + String get update => localizedValues['update'][locale.languageCode]; - String get covid19_driveThrueTest => - localizedValues['covid19_driveThrueTest'][locale.languageCode]; + + String get covid19_driveThrueTest => localizedValues['covid19_driveThrueTest'][locale.languageCode]; + String get eReferral => localizedValues['E-Referral'][locale.languageCode]; - String get msg_email_address_up_to_date => - localizedValues["msg_email_address_up_to_date"][locale.languageCode]; - String get updateEmailMsg => - localizedValues["update-email-msg"][locale.languageCode]; + String get msg_email_address_up_to_date => localizedValues["msg_email_address_up_to_date"][locale.languageCode]; - String get addNewChild => - localizedValues["add-new-child"][locale.languageCode]; - String get sendChildEmailMsg => - localizedValues["send-child-email-msg"][locale.languageCode]; - String get vaccinationAddChildMsg => - localizedValues["vaccination-add-child-msg"][locale.languageCode]; - String get childAddedSuccessfully => - localizedValues["child_added_successfully"][locale.languageCode]; + String get updateEmailMsg => localizedValues["update-email-msg"][locale.languageCode]; + + String get addNewChild => localizedValues["add-new-child"][locale.languageCode]; + + String get sendChildEmailMsg => localizedValues["send-child-email-msg"][locale.languageCode]; + + String get vaccinationAddChildMsg => localizedValues["vaccination-add-child-msg"][locale.languageCode]; + + String get childAddedSuccessfully => localizedValues["child_added_successfully"][locale.languageCode]; String get sugar => localizedValues["sugar"][locale.languageCode]; - String get bloodCholesterol => - localizedValues["bloodCholesterol"][locale.languageCode]; + + String get bloodCholesterol => localizedValues["bloodCholesterol"][locale.languageCode]; + String get cholesterol => localizedValues["cholesterol"][locale.languageCode]; - String get triglycerides => - localizedValues["triglycerides"][locale.languageCode]; + + String get triglycerides => localizedValues["triglycerides"][locale.languageCode]; + String get fatInBlood => localizedValues["fatInBlood"][locale.languageCode]; + String get calculate => localizedValues["calculate"][locale.languageCode]; - String get enterReadingValue => - localizedValues["enterReadingValue"][locale.languageCode]; - String get convertBloodSugarStatement => - localizedValues["convertBloodSugarStatement"][locale.languageCode]; + + String get enterReadingValue => localizedValues["enterReadingValue"][locale.languageCode]; + + String get convertBloodSugarStatement => localizedValues["convertBloodSugarStatement"][locale.languageCode]; + String get convertFrom => localizedValues["convertFrom"][locale.languageCode]; + String get result => localizedValues["result"][locale.languageCode]; + String get sort => localizedValues["sort"][locale.languageCode]; - String get bloodSugarConversion => - localizedValues["bloodSugarConversion"][locale.languageCode]; - String get convertCholesterolStatement => - localizedValues["convertCholesterolStatement"][locale.languageCode]; - String get triglyceridesConvertStatement => - localizedValues["triglyceridesConvertStatement"][locale.languageCode]; - String get bloodDEnterDesc => - localizedValues["bloodD-enter-desc"][locale.languageCode]; - String get viewTermsConditions => - localizedValues["viewTermsConditions"][locale.languageCode]; - String get generalHealth => - localizedValues["generalHealth"][locale.languageCode]; + + String get bloodSugarConversion => localizedValues["bloodSugarConversion"][locale.languageCode]; + + String get convertCholesterolStatement => localizedValues["convertCholesterolStatement"][locale.languageCode]; + + String get triglyceridesConvertStatement => localizedValues["triglyceridesConvertStatement"][locale.languageCode]; + + String get bloodDEnterDesc => localizedValues["bloodD-enter-desc"][locale.languageCode]; + + String get viewTermsConditions => localizedValues["viewTermsConditions"][locale.languageCode]; + + String get generalHealth => localizedValues["generalHealth"][locale.languageCode]; + String get womanHealth => localizedValues["womanHealth"][locale.languageCode]; + String get bmi => localizedValues["bmi"][locale.languageCode]; + String get calcHealth => localizedValues["calc-health"][locale.languageCode]; + String get calories => localizedValues["calories"][locale.languageCode]; + String get bmr => localizedValues["bmr"][locale.languageCode]; + String get idealBody => localizedValues["idealBody"][locale.languageCode]; + String get bodyWord => localizedValues["body_word"][locale.languageCode]; + String get fat => localizedValues["fat"][locale.languageCode]; - String get carbohydrate => - localizedValues["carbohydrate"][locale.languageCode]; + + String get carbohydrate => localizedValues["carbohydrate"][locale.languageCode]; + String get proteinFat => localizedValues["proteinFat"][locale.languageCode]; + String get ovulation => localizedValues["ovulation"][locale.languageCode]; + String get delivery => localizedValues["delivery"][locale.languageCode]; + String get bmiCalcDesc => localizedValues["bmiCalcDesc"][locale.languageCode]; + String get selectUnit => localizedValues["selectUnit"][locale.languageCode]; + String get feet => localizedValues["feet"][locale.languageCode]; + String get pound => localizedValues["pound"][locale.languageCode]; - String get seeListOfDoctor => - localizedValues["seeListOfDoctor"][locale.languageCode]; + + String get seeListOfDoctor => localizedValues["seeListOfDoctor"][locale.languageCode]; + String get obese => localizedValues["obese"][locale.languageCode]; + String get overWeight => localizedValues["overWeight"][locale.languageCode]; + String get healthy => localizedValues["healthy"][locale.languageCode]; + String get underWeight => localizedValues["underWeight"][locale.languageCode]; - String get bmiCalcMsgObese => - localizedValues["bmiCalcMsgObese"][locale.languageCode]; - String get bmiCalcMsgOverweight => - localizedValues["bmiCalcMsgOverweight"][locale.languageCode]; - String get bmiCalcMsgHealthy => - localizedValues["bmiCalcMsgHealthy"][locale.languageCode]; - String get bmiCalcMsgUnderWeight => - localizedValues["bmiCalcMsgUnderWeight"][locale.languageCode]; + + String get bmiCalcMsgObese => localizedValues["bmiCalcMsgObese"][locale.languageCode]; + + String get bmiCalcMsgOverweight => localizedValues["bmiCalcMsgOverweight"][locale.languageCode]; + + String get bmiCalcMsgHealthy => localizedValues["bmiCalcMsgHealthy"][locale.languageCode]; + + String get bmiCalcMsgUnderWeight => localizedValues["bmiCalcMsgUnderWeight"][locale.languageCode]; + String get bariatrics => localizedValues["bariatrics"][locale.languageCode]; - String get bariatricsHeaderMsg => - localizedValues["bariatricsHeaderMsg"][locale.languageCode]; + + String get bariatricsHeaderMsg => localizedValues["bariatricsHeaderMsg"][locale.languageCode]; + String get continues => localizedValues["continue"][locale.languageCode]; + String get skip => localizedValues["skip"][locale.languageCode]; - String get calorieCalcDesc => - localizedValues["calorieCalcDesc"][locale.languageCode]; - String get age11_120Years => - localizedValues["age11_120_years"][locale.languageCode]; + + String get offersdiscount => localizedValues["offersdiscount"][locale.languageCode]; + + String get explore => localizedValues["explore"][locale.languageCode]; + + String get calorieCalcDesc => localizedValues["calorieCalcDesc"][locale.languageCode]; + + String get age11_120Years => localizedValues["age11_120_years"][locale.languageCode]; + String get walkinAppo => localizedValues["WalkinAppo"][locale.languageCode]; + String get videoAppo => localizedValues["videoAppo"][locale.languageCode]; + String get weightAdd => localizedValues["weight-add"][locale.languageCode]; - String get systolicAdd => - localizedValues["systolic-add"][locale.languageCode]; - String get diastolicAdd => - localizedValues["systolic-add"][locale.languageCode]; + + String get appointments => localizedValues['appointments'][locale.languageCode]; + + String get all2 => localizedValues['all2'][locale.languageCode]; + + String get systolicAdd => localizedValues["systolic-add"][locale.languageCode]; + + String get diastolicAdd => localizedValues["diastolic-add"][locale.languageCode]; + String get cmcHeading => localizedValues["cmc-heading"][locale.languageCode]; - String get selectLocation => - localizedValues["select-location"][locale.languageCode]; - String get resultHeader => - localizedValues["result-header"][locale.languageCode]; + + String get selectLocation => localizedValues["select-location"][locale.languageCode]; + + String get resultHeader => localizedValues["result-header"][locale.languageCode]; + String get covidInfo => localizedValues["covid-info"][locale.languageCode]; + String get selectAppo => localizedValues["select-appo"][locale.languageCode]; - String get covidAlertHeader => - localizedValues["covid-alert-header"][locale.languageCode]; - String get covidAlertInfo => - localizedValues["covid-alert-info"][locale.languageCode]; - String get covidAlertMins => - localizedValues["covid-alert-mins"][locale.languageCode]; + + String get covidAlertHeader => localizedValues["covid-alert-header"][locale.languageCode]; + + String get covidAlertInfo => localizedValues["covid-alert-info"][locale.languageCode]; + + String get covidAlertMins => localizedValues["covid-alert-mins"][locale.languageCode]; + String get back => localizedValues["back"][locale.languageCode]; - String get getDirections => - localizedValues["get-directions"][locale.languageCode]; - String get selectedLocation => - localizedValues["selected-location"][locale.languageCode]; + + String get getDirections => localizedValues["get-directions"][locale.languageCode]; + + String get selectedLocation => localizedValues["selected-location"][locale.languageCode]; + String get testFee => localizedValues["test-fee"][locale.languageCode]; + String get payOptions => localizedValues["pay-options"][locale.languageCode]; - String get livecareService => - localizedValues["livecare-service"][locale.languageCode]; - String get livecareServiceDesc => - localizedValues["livecare-service-desc"][locale.languageCode]; - String get whyLivecare => - localizedValues["why-livecare"][locale.languageCode]; - String get livecarePoint1 => - localizedValues["livecare-point-1"][locale.languageCode]; - String get docVirtualAppoIns4 => - localizedValues["doc-virtual-appo-ins4"][locale.languageCode]; - String get docVirtualAppoIns5 => - localizedValues["doc-virtual-appo-ins5"][locale.languageCode]; - String get livecareSummary => - localizedValues["livecare-summary"][locale.languageCode]; - - String get livecareOption1 => - localizedValues["livecare-option-1"][locale.languageCode]; - String get livecareOption2 => - localizedValues["livecare-option-2"][locale.languageCode]; - String get livecareOption3 => - localizedValues["livecare-option-3"][locale.languageCode]; - String get livecareOption4 => - localizedValues["livecare-option-4"][locale.languageCode]; + + String get livecareService => localizedValues["livecare-service"][locale.languageCode]; + + String get livecareServiceDesc => localizedValues["livecare-service-desc"][locale.languageCode]; + + String get whyLivecare => localizedValues["why-livecare"][locale.languageCode]; + + String get livecarePoint1 => localizedValues["livecare-point-1"][locale.languageCode]; + + String get docVirtualAppoIns4 => localizedValues["doc-virtual-appo-ins4"][locale.languageCode]; + + String get docVirtualAppoIns5 => localizedValues["doc-virtual-appo-ins5"][locale.languageCode]; + + String get livecareSummary => localizedValues["livecare-summary"][locale.languageCode]; + + String get livecareOption1 => localizedValues["livecare-option-1"][locale.languageCode]; + + String get livecareOption2 => localizedValues["livecare-option-2"][locale.languageCode]; + + String get livecareOption3 => localizedValues["livecare-option-3"][locale.languageCode]; + + String get livecareOption4 => localizedValues["livecare-option-4"][locale.languageCode]; + + String get noAppointmentAvailable => localizedValues["noAppointmentAvailable"][locale.languageCode]; String get today => localizedValues["today"][locale.languageCode]; + String get week => localizedValues["week"][locale.languageCode]; - String get h2oAmountOfWater => - localizedValues["h2o-amount-of-water"][locale.languageCode]; + + String get h2oAmountOfWater => localizedValues["h2o-amount-of-water"][locale.languageCode]; + String get updateUser => localizedValues["update-user"][locale.languageCode]; + String get editname => localizedValues["editname"][locale.languageCode]; - String get activityLevel => - localizedValues["activity-level"][locale.languageCode]; + + String get activityLevel => localizedValues["activity-level"][locale.languageCode]; + String get success => localizedValues["success"][locale.languageCode]; - String get enterNameHere => - localizedValues["enterNameHere"][locale.languageCode]; - String get lightActive => - localizedValues["light-active"][locale.languageCode]; + + String get enterNameHere => localizedValues["enterNameHere"][locale.languageCode]; + + String get lightActive => localizedValues["light-active"][locale.languageCode]; + String get modActive => localizedValues["mod-active"][locale.languageCode]; - String get reminderLabel => - localizedValues["reminder-label"][locale.languageCode]; - String get reminderTimesLabel => - localizedValues["reminder-times-label"][locale.languageCode]; + + String get reminderLabel => localizedValues["reminder-label"][locale.languageCode]; + + String get reminderTimesLabel => localizedValues["reminder-times-label"][locale.languageCode]; + String get times => localizedValues["times"][locale.languageCode]; - String get WaterCalculate => - localizedValues["WaterCalculate"][locale.languageCode]; + + String get WaterCalculate => localizedValues["WaterCalculate"][locale.languageCode]; + String get notifTitle => localizedValues["notif-title"][locale.languageCode]; + String get notifText => localizedValues["notif-text"][locale.languageCode]; + String get custom => localizedValues["custom"][locale.languageCode]; + String get undo => localizedValues["undo"][locale.languageCode]; + String get drinking => localizedValues["drinking"][locale.languageCode]; + String get remaining => localizedValues["remaining"][locale.languageCode]; + + String get addCustomAmount => localizedValues["addCustomAmount"][locale.languageCode]; + + String get left => localizedValues["left"][locale.languageCode]; + String get taken => localizedValues["taken"][locale.languageCode]; + String get ml => localizedValues["ml"][locale.languageCode]; + + String get mililitre => localizedValues["mililitre"][locale.languageCode]; + + String get litre => localizedValues["litre"][locale.languageCode]; + String get l => localizedValues["l"][locale.languageCode]; - String get customLabel => - localizedValues["custom-label"][locale.languageCode]; - String get customLabelInLitres => - localizedValues["custom-label-in-litres"][locale.languageCode]; - String get customLabelInMililitres => - localizedValues["custom-label-in-mililitres"][locale.languageCode]; + String get customLabel => localizedValues["custom-label"][locale.languageCode]; + + String get customLabelInLitres => localizedValues["custom-label-in-litres"][locale.languageCode]; + + String get customLabelInMililitres => localizedValues["custom-label-in-mililitres"][locale.languageCode]; + String get amount_ => localizedValues["amount"][locale.languageCode]; - String get targetReach => - localizedValues["target-reach"][locale.languageCode]; + + String get targetReach => localizedValues["target-reach"][locale.languageCode]; + String get weekHeader => localizedValues["week-header"][locale.languageCode]; - String get monthHeader => - localizedValues["month-header"][locale.languageCode]; - String get notifPermissionTitle => - localizedValues["notif-permission-title"][locale.languageCode]; - String get notifPermissionMsg => - localizedValues["notif-permission-msg"][locale.languageCode]; - String get verification_message_code => - localizedValues["verification_message_code"][locale.languageCode]; + + String get monthHeader => localizedValues["month-header"][locale.languageCode]; + + String get notifPermissionTitle => localizedValues["notif-permission-title"][locale.languageCode]; + + String get notifPermissionMsg => localizedValues["notif-permission-msg"][locale.languageCode]; + + String get verification_message_code => localizedValues["verification_message_code"][locale.languageCode]; + String get sms_code => localizedValues["sms_code"][locale.languageCode]; - String get code_failure => - localizedValues["code_failure"][locale.languageCode]; + + String get code_failure => localizedValues["code_failure"][locale.languageCode]; + String get resend => localizedValues["resend"][locale.languageCode]; - String get submitncontinue => - localizedValues["submitncontinue"][locale.languageCode]; - String get areyousure => localizedValues["areyousure"][locale.languageCode]; + String get submitncontinue => localizedValues["submitncontinue"][locale.languageCode]; + + String get areyousure => localizedValues["areyousure"][locale.languageCode]; // Offer And Packahes - String get subT=> localizedValues['OffersAndPackages'][locale.languageCode]; + String get subT => localizedValues['OffersAndPackages'][locale.languageCode]; + String get totalWithColonRight => localizedValues['totalWithColonRight'][locale.languageCode]; - String get preferredunit => - localizedValues["preferredunit"][locale.languageCode]; + String get preferredunit => localizedValues["preferredunit"][locale.languageCode]; + String get trySaying => localizedValues["try-saying"][locale.languageCode]; - String get enterIdentificationNumber => - localizedValues["enterIdentificationNumber"][locale.languageCode]; - String get accountActivationDesc => - localizedValues["accountActivationDesc"][locale.languageCode]; - String get pointsToTransfer => - localizedValues["pointsToTransfer"][locale.languageCode]; - String get enterBeneficiaryAccountNo => - localizedValues["enterBeneficiaryAccountNo"][locale.languageCode]; - String get confirmPrescription => - localizedValues["confirm-prescription"][locale.languageCode]; - String get youAlreadyHaveOrder => - localizedValues["you-already-have-order"][locale.languageCode]; - String get orderOverview => - localizedValues["order-overview"][locale.languageCode]; - String get shippingAddresss => - localizedValues["shipping-address"][locale.languageCode]; + + String get shippingAddresss => localizedValues["shipping-address"][locale.languageCode]; + String get covidAlert => localizedValues["covid-alert"][locale.languageCode]; - String get pharmacyRelogin => - localizedValues["pharmacy-relogin"][locale.languageCode]; - String get onlineCheckInAgreement => - localizedValues["onlineCheckInAgreement"][locale.languageCode]; - String get chiefComplaints => - localizedValues["chiefComplaints"][locale.languageCode]; - String get errorChiefComplaints => - localizedValues["errorChiefComplaints"][locale.languageCode]; - String get expectedArrivalTime => - localizedValues["expectedArrivalTime"][locale.languageCode]; - String get errorExpectedArrivalTime => - localizedValues["errorExpectedArrivalTimes"][locale.languageCode]; - String get anicllaryOrders => - localizedValues["ancillary-orders"][locale.languageCode]; + + String get pharmacyRelogin => localizedValues["pharmacy-relogin"][locale.languageCode]; + + String get onlineCheckInAgreement => localizedValues["onlineCheckInAgreement"][locale.languageCode]; + + String get chiefComplaints => localizedValues["chiefComplaints"][locale.languageCode]; + + String get errorChiefComplaints => localizedValues["errorChiefComplaints"][locale.languageCode]; + + String get expectedArrivalTime => localizedValues["expectedArrivalTime"][locale.languageCode]; + + String get errorExpectedArrivalTime => localizedValues["errorExpectedArrivalTimes"][locale.languageCode]; + + String get anicllaryOrders => localizedValues["ancillary-orders"][locale.languageCode]; + String get mrn => localizedValues["MRN"][locale.languageCode]; - String get appointmentDate => - localizedValues["appointment-date"][locale.languageCode]; - String get appointmentNo => - localizedValues["appointment-no"][locale.languageCode]; - String get insuranceID => - localizedValues["insurance-id"][locale.languageCode]; + + String get appointmentDate => localizedValues["appointment-date"][locale.languageCode]; + + String get appointmentNo => localizedValues["appointment-no"][locale.languageCode]; + + String get insuranceID => localizedValues["insurance-id"][locale.languageCode]; + String get enterFile => localizedValues["enter-file"][locale.languageCode]; -} -class TranslationBaseDelegate extends LocalizationsDelegate { - const TranslationBaseDelegate(); + String get selectRelationship => localizedValues["selectRelationship"][locale.languageCode]; - @override - bool isSupported(Locale locale) => ['en', 'ar'].contains(locale.languageCode); + String get requesterRelationship => localizedValues["requesterRelationship"][locale.languageCode]; - @override - Future load(Locale locale) { - return SynchronousFuture(TranslationBase(locale)); - } + String get newReferral => localizedValues["newReferral"][locale.languageCode]; - @override - bool shouldReload(TranslationBaseDelegate old) => false; + String get searchForReferrals => localizedValues["searchForReferrals"][locale.languageCode]; + + String get covidSelectProcedure => localizedValues["covid-select-procedure"][locale.languageCode]; + + String get onlineConsultation => localizedValues["online-consultation"][locale.languageCode]; + + String get expectedWaiting => localizedValues["expected-weiting"][locale.languageCode]; + + String get erConsultFee => localizedValues["er-consult-fee"][locale.languageCode]; + + String get insuredPatient => localizedValues["insured-patient"][locale.languageCode]; + + String get iAcceptTerms => localizedValues["i-accept-terms"][locale.languageCode]; + + String get upComingPayOption => localizedValues["upcoming-pay-options"][locale.languageCode]; + + String get pleaseAcceptTerms => localizedValues["please-accept-terms"][locale.languageCode]; + + String get pleaseSelectAllQuestionToContinue => localizedValues["pleaseSelectAllQuestionToContinue"][locale.languageCode]; + + String get type => localizedValues["type"][locale.languageCode]; + + String get eReferralInfo => localizedValues["info-ereferral"][locale.languageCode]; + + String get erConsultation => localizedValues["er-consultation"][locale.languageCode]; + + String get thisItemIsNotAvailable => localizedValues["thisItemIsNotAvailable"][locale.languageCode]; + + String get beforeAfterImages => localizedValues["beforeAfterImages"][locale.languageCode]; + + String get myInvoice => localizedValues["my-invoice"][locale.languageCode]; + + String get invoicesList => localizedValues["invoice-list"][locale.languageCode]; + + String get clinicAcceptLivecare => localizedValues["clinic-accept-livecare"][locale.languageCode]; + + String get livecareModalTop => localizedValues["livecareModal-top"][locale.languageCode]; + + String get empty => localizedValues["empty"][locale.languageCode]; + + String get schedule => localizedValues["schedule"][locale.languageCode]; + + String get livecarePoint2 => localizedValues["livecare-point-2"][locale.languageCode]; + + String get livecarePoint3 => localizedValues["livecare-point-3"][locale.languageCode]; + + String get livecarePoint4 => localizedValues["livecare-point-4"][locale.languageCode]; + + String get livecarePoint5 => localizedValues["livecare-point-5"][locale.languageCode]; + + String get bookImmediateLivecare => localizedValues["book-immediate-livecare"][locale.languageCode]; + + String get bookVideoLivecare2 => localizedValues["book-video-livecare-2"][locale.languageCode]; + + String get noThankyou => localizedValues["no-thankyou"][locale.languageCode]; + + String get visitClinic => localizedValues["visit-clinic"][locale.languageCode]; + + String get generateCovidCertificate => localizedValues["generate-covid-certificate"][locale.languageCode]; + + String get isReportOutsideKsa => localizedValues["is-report-outside-ksa"][locale.languageCode]; + + String get passportNumber => localizedValues["passport-number"][locale.languageCode]; + + String get enterPassportNumber => localizedValues["enter-passport-number"][locale.languageCode]; + + String get validPassportNumber => localizedValues["valid-passport-number"][locale.languageCode]; + + String get continuePlan => localizedValues["continue-plan"][locale.languageCode]; + + String get dentalProcedureList => localizedValues["dental-procedure-list"][locale.languageCode]; + + String get aboutApp => localizedValues["about-app"][locale.languageCode]; + + String get aboutPointsLength => localizedValues["about-points"]['length'][locale.languageCode]; + + String get timeNeeded => localizedValues["time-needed"][locale.languageCode]; + + String get totalTimeNeeded => localizedValues["total-time-needed"][locale.languageCode]; + + String get infoEye => localizedValues["info-eye"][locale.languageCode]; + + String get infoVaccines => localizedValues["info-vaccines"][locale.languageCode]; + + String get infoTrackers => localizedValues["info-trackers"][locale.languageCode]; + + String get infoHealthData => localizedValues["info-health-data"][locale.languageCode]; + + String get infoAskDoc => localizedValues["info-ask-doc"][locale.languageCode]; + + String get infoAutoWifi => localizedValues["info-auto-wifi"][locale.languageCode]; + + String get autoWifi => localizedValues["auto-wifi"][locale.languageCode]; + + String get childVaccineInfo => localizedValues["child-vaccine-info"][locale.languageCode]; + + String get h2oInfo => localizedValues["h2o-info"][locale.languageCode]; + + String get sysdias => localizedValues["sys/dias"][locale.languageCode]; + + String get arm => localizedValues["arm"][locale.languageCode]; + + String get removeMeasure => localizedValues["remove-measure"][locale.languageCode]; + + String get selectArm => localizedValues["select-arm"][locale.languageCode]; + + String get askDocEmpty => localizedValues["ask-doc-empty"][locale.languageCode]; + + String get onlineClinics => localizedValues["online-clinics"][locale.languageCode]; + + String get offlineClinics => localizedValues["offline-clinics"][locale.languageCode]; + + String get clinicSchedule => localizedValues["clinic-schedule"][locale.languageCode]; + + String get discount => localizedValues["discount"][locale.languageCode]; + + String get totalVAT => localizedValues["total-VAT"][locale.languageCode]; + + String get paid => localizedValues["paid"][locale.languageCode]; + + String get dentalInsurance => localizedValues["dental-insurance"][locale.languageCode]; + + String get drivethruAppo => localizedValues["drivethru-appo"][locale.languageCode]; + + String get upcomingQRNFC => localizedValues["upcoming-QR-NFC"][locale.languageCode]; + + String get ovulationDesc => localizedValues["ovulation-desc"][locale.languageCode]; + + String get cycleLabel => localizedValues["cycle-label"][locale.languageCode]; + + String get lutealLabel => localizedValues["luteal-label"][locale.languageCode]; + + String get pregnancyTitle => localizedValues["pregnancy-title"][locale.languageCode]; + + String get pregnancyDesc => localizedValues["pregnancy-desc"][locale.languageCode]; + + String get pregnancyDateLabel => localizedValues["pregnancy-date-label"][locale.languageCode]; + + String get ovulationPeriod => localizedValues["ovulation-period"][locale.languageCode]; + + String get from => localizedValues["from"][locale.languageCode]; + + String get to => localizedValues["to"][locale.languageCode]; + + String get conceive => localizedValues["conceive"][locale.languageCode]; + + String get firstTri => localizedValues["firstTri"][locale.languageCode]; + + String get secondTri => localizedValues["secondTri"][locale.languageCode]; + + String get thirdTri => localizedValues["thirdTri"][locale.languageCode]; + + String get seeDoctorsList => localizedValues["seeDoctorsList"][locale.languageCode]; + + String get covidQuestionnaire => localizedValues["covidQuestionnaire"][locale.languageCode]; + + String get covidBookAppo => localizedValues["covidBookAppo"][locale.languageCode]; + + String get emptySchedule => localizedValues["emptySchedule"][locale.languageCode]; + + String get serviceNotAvailable => localizedValues["serviceNotAvailable"][locale.languageCode]; + + String get doctorScheduleNot => localizedValues["doctorScheduleNot"][locale.languageCode]; + + String get RRTRequestSuccess => localizedValues["RRTRequestSuccess"][locale.languageCode]; + + String get rateDoctorAppo => localizedValues["rateDoctorAppo"][locale.languageCode]; + + String get invoice => localizedValues["invoice"][locale.languageCode]; + + String get requestedDate => localizedValues["requestedDate"][locale.languageCode]; + + String get callDuration => localizedValues["callDuration"][locale.languageCode]; + + String get alreadyRated => localizedValues["alreadyRated"][locale.languageCode]; + + String get insuranceCompany => localizedValues["insuranceCompany"][locale.languageCode]; + + String get referralDetails => localizedValues["referralDetails"][locale.languageCode]; + + String get preferredBranch => localizedValues["preferredBranch"][locale.languageCode]; + + String get selectPreferredBranch => localizedValues["selectPreferredBranch"][locale.languageCode]; + + String get patientLocated => localizedValues["patientLocated"][locale.languageCode]; + + String get otherInfo => localizedValues["otherInfo"][locale.languageCode]; + + String get medicalReport => localizedValues["medicalReport"][locale.languageCode]; + + String get insuredPatientReferral => localizedValues["insuredPatient"][locale.languageCode]; + + String get rateDoctor => localizedValues["rateDoctor"][locale.languageCode]; + + String get rateAppointment => localizedValues["rateAppointment"][locale.languageCode]; + + String get noInsuranceCardAttached => localizedValues["noInsuranceCardAttached"][locale.languageCode]; + + String get bodyMassIndex => localizedValues["bodyMassIndex"][locale.languageCode]; + + String get extremeObese => localizedValues["extremeObese"][locale.languageCode]; + + String get respirationBPM => localizedValues["respirationBPM"][locale.languageCode]; + + String get noSlotsError => localizedValues["noSlotsError"][locale.languageCode]; + + String get selectSlot => localizedValues["selectSlot"][locale.languageCode]; + + String get selectLanguage => localizedValues["selectLanguage"][locale.languageCode]; + + String get recAlert => localizedValues["recAlert"][locale.languageCode]; + + String get modesBelow => localizedValues["modesBelow"][locale.languageCode]; + + String get prefferedMode => localizedValues["prefferedMode"][locale.languageCode]; + + String get permissionsBellow => localizedValues["permissionsBellow"][locale.languageCode]; + + String get invoiceDetails => localizedValues["invoiceDetails"][locale.languageCode]; + + String get appoDetails => localizedValues["appoDetails"][locale.languageCode]; + + String get appoPaymentConfirm => localizedValues["appoPaymentConfirm"][locale.languageCode]; + + String get selectSearchCriteria => localizedValues["selectSearchCriteria"][locale.languageCode]; + + String get enterComplainNumber => localizedValues["enterComplainNumber"][locale.languageCode]; + + String get cancelAppointment => localizedValues["cancelAppointment"][locale.languageCode]; + + String get updateInsurCards => localizedValues["updateInsurCards"][locale.languageCode]; + + String get patientAge => localizedValues["patientAge"][locale.languageCode]; + + String get searchCriteria => localizedValues["searchCriteria"][locale.languageCode]; + + String get RequesterInfo => localizedValues["RequesterInfo"][locale.languageCode]; + + String get PatientInfo => localizedValues["PatientInfo"][locale.languageCode]; + + String get OtherInfo => localizedValues["OtherInfo"][locale.languageCode]; + + String get inPrgress => localizedValues["inPrgress"][locale.languageCode]; + + String get locked => localizedValues["locked"][locale.languageCode]; + + String get personalInfo => localizedValues['personalInfo'][locale.languageCode]; + + String get onlinePayment => localizedValues["onlinePayment"][locale.languageCode]; + + String get onlinePaymentSubtitle => localizedValues["onlinePaymentSubtitle"][locale.languageCode]; + + String get cmcTitle => localizedValues["cmcTitle"][locale.languageCode]; + + String get cmcSubtitle => localizedValues["cmcSubtitle"][locale.languageCode]; + + String get emergencyTitle => localizedValues["emergencyTitle"][locale.languageCode]; + + String get emergencySubtitle => localizedValues["emergencySubtitle"][locale.languageCode]; + + String get ereferralTitle => localizedValues["ereferralTitle"][locale.languageCode]; + + String get ereferralSubtitle => localizedValues["ereferralSubtitle"][locale.languageCode]; + + String get medicalFileTitle => localizedValues["medicalFileTitle"][locale.languageCode]; + + String get My_File_Details => localizedValues["My_File_Details"][locale.languageCode]; + + String get Ecommerce => localizedValues["Ecommerce"][locale.languageCode]; + + String get Family_Files => localizedValues["Family_Files"][locale.languageCode]; + + String get My_Child => localizedValues["My_Child"][locale.languageCode]; + + String get Vaccines => localizedValues["Vaccines"][locale.languageCode]; + + String get Todo => localizedValues["Todo"][locale.languageCode]; + + String get list => localizedValues["List"][locale.languageCode]; + + String get Blood => localizedValues["Blood"][locale.languageCode]; + + String get Donation => localizedValues["Donation"][locale.languageCode]; + + String get Health => localizedValues["Health"][locale.languageCode]; + + String get Calculator => localizedValues["Calculator"][locale.languageCode]; + + String get Converter => localizedValues["Converter"][locale.languageCode]; + + String get Smart => localizedValues["Smart"][locale.languageCode]; + + String get Watches => localizedValues["Watches"][locale.languageCode]; + + String get Parking => localizedValues["Parking"][locale.languageCode]; + + String get Details => localizedValues["Details"][locale.languageCode]; + + String get Virtual => localizedValues["Virtual"][locale.languageCode]; + + String get News => localizedValues["News"][locale.languageCode]; + + 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 enterDetails => localizedValues["enterDetails"][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]; + + String get syncHealthData => localizedValues["syncHealthData"][locale.languageCode]; + + 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]; + + 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]; + + 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]; + + String get tamaraInstPlan => localizedValues["tamaraInstPlan"][locale.languageCode]; + + 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]; + + String get cholesTitle => localizedValues["cholesTitle"][locale.languageCode]; + + String get laserClinic => localizedValues["laserClinic"][locale.languageCode]; + + String get noImage => localizedValues["noImage"][locale.languageCode]; + + String get signoutMessage => localizedValues["signoutMessage"][locale.languageCode]; + + String get RRTTitle => localizedValues["RRTTitle"][locale.languageCode]; + + String get RRTSubTitle => localizedValues["RRTSubTitle"][locale.languageCode]; + + String get transportation => localizedValues["transportation"][locale.languageCode]; + + String get browseOffers => localizedValues["browseOffers"][locale.languageCode]; + + String get browseOffersByProject => localizedValues["browseOffersByProject"][locale.languageCode]; + + String get myCart => localizedValues["myCart"][locale.languageCode]; + + String get neck => localizedValues["neck"][locale.languageCode]; + + String get waist => localizedValues["waist"][locale.languageCode]; + + String get hip => localizedValues["hip"][locale.languageCode]; + + String get carbsProtin => localizedValues["carbsProtin"][locale.languageCode]; + + String get inactiveAct => localizedValues["inactiveAct"][locale.languageCode]; + + String get light => localizedValues["light"][locale.languageCode]; + + String get moderate => localizedValues["moderate"][locale.languageCode]; + + String get very => localizedValues["very"][locale.languageCode]; + + String get superAct => localizedValues["super"][locale.languageCode]; + + String get resultCalories => localizedValues["resultCalories"][locale.languageCode]; + + String get bmrDesc => localizedValues["bmrDesc"][locale.languageCode]; + + String get idealWeightDesc => localizedValues["idealWeightDesc"][locale.languageCode]; + + String get bodyFrame => localizedValues["bodyFrame"][locale.languageCode]; + + String get bodyFrameSmall => localizedValues["bodyFrameSmall"][locale.languageCode]; + + String get bodyFrameMedium => localizedValues["bodyFrameMedium"][locale.languageCode]; + + String get bodyFrameLarge => localizedValues["bodyFrameLarge"][locale.languageCode]; + + String get bodyFatDesc => localizedValues["bodyFatDesc"][locale.languageCode]; + + String get essential => localizedValues["essential"][locale.languageCode]; + + String get athlete => localizedValues["athlete"][locale.languageCode]; + + String get fitness => localizedValues["fitness"][locale.languageCode]; + + String get acceptable => localizedValues["acceptable"][locale.languageCode]; + + String get obeseBodyFat => localizedValues["obeseBodyFat"][locale.languageCode]; + + String get invalid => localizedValues["invalid"][locale.languageCode]; + + String get more => localizedValues["more"][locale.languageCode]; + + String get less => localizedValues["less"][locale.languageCode]; + + String get carbProteinDesc => localizedValues["carbProteinDesc"][locale.languageCode]; + + String get calDay => localizedValues["calDay"][locale.languageCode]; + + String get notSure => localizedValues["notSure"][locale.languageCode]; + + String get selectDiet => localizedValues["selectDiet"][locale.languageCode]; + + String get dietVeryLow => localizedValues["dietVeryLow"][locale.languageCode]; + + String get dietLow => localizedValues["dietLow"][locale.languageCode]; + + String get dietModerate => localizedValues["dietModerate"][locale.languageCode]; + + String get dietUSDA => localizedValues["dietUSDA"][locale.languageCode]; + + String get dietZone => localizedValues["dietZone"][locale.languageCode]; + + String get useFullInfo => localizedValues["usefulInfo"][locale.languageCode]; + + String get babyAge => localizedValues["babyAge"][locale.languageCode]; + + String get babyAgeAvail => localizedValues["babyAgeAvail"][locale.languageCode]; + + String get deliveryDue => localizedValues["deliveryDue"][locale.languageCode]; + + String get almostInactive => localizedValues["almostInactive"][locale.languageCode]; + + String get lightActive1 => localizedValues["lightActive1"][locale.languageCode]; + + String get veryActive => localizedValues["veryActive"][locale.languageCode]; + + String get superActive => localizedValues["superActive"][locale.languageCode]; + + String get dailyIntake => localizedValues["dailyIntake"][locale.languageCode]; + + String get calculateAmount => localizedValues["calculateAmount"][locale.languageCode]; + + String get bodyWillBurn => localizedValues["bodyWillBurn"][locale.languageCode]; + + String get caloriesEachDay => localizedValues["caloriesEachDay"][locale.languageCode]; + + String get maintainWeight => localizedValues["maintainWeight"][locale.languageCode]; + + String get mediumFinger => localizedValues["mediumFinger"][locale.languageCode]; + + String get smallFinger => localizedValues["smallFinger"][locale.languageCode]; + + String get largeFinger => localizedValues["largeFinger"][locale.languageCode]; + + String get idealBodyWeight => localizedValues["idealBodyWeight"][locale.languageCode]; + + String get bodyFrameSize => localizedValues["bodyFrameSize"][locale.languageCode]; + + String get idealWeightRange => localizedValues["idealWeightRange"][locale.languageCode]; + + String get currentWeightPerfect => localizedValues["currentWeightPerfect"][locale.languageCode]; + + String get littleBitWeightMore => localizedValues["littleBitWeightMore"][locale.languageCode]; + + String get consultWithDoctor => localizedValues["consultWithDoctor"][locale.languageCode]; + + String get excessiveObesity => localizedValues["excessiveObesity"][locale.languageCode]; + + String get mayWish => localizedValues["mayWish"][locale.languageCode]; + + String get underObese => localizedValues["underObese"][locale.languageCode]; + + String get crossedLimits => localizedValues["crossedLimits"][locale.languageCode]; + + String get lowLimits => localizedValues["lowLimits"][locale.languageCode]; + + String get estimates => localizedValues["estimates"][locale.languageCode]; + + String get submitReview => localizedValues["submitReview"][locale.languageCode]; + + String get Protein => localizedValues["Protein"][locale.languageCode]; + + String get Cals => localizedValues["Cals"][locale.languageCode]; + + String get gramsPerDay => localizedValues["gramsPerDay"][locale.languageCode]; + + String get gr => localizedValues["gr"][locale.languageCode]; + + String get gramsPerMeal => localizedValues["gramsPerMeal"][locale.languageCode]; + + String get cancelReminder => localizedValues["CancelReminder"][locale.languageCode]; + + String get reminderCancelSuccess => localizedValues["reminderCancelSuccess"][locale.languageCode]; + + String get syncSuccess => localizedValues["syncSuccess"][locale.languageCode]; + + String get useLakumPoints => localizedValues["useLakumPoints"][locale.languageCode]; + + String get points => localizedValues["points"][locale.languageCode]; + + String get availableBalance => localizedValues["availableBalance"][locale.languageCode]; + + String get ordersDashboard => localizedValues["ordersDashboard"][locale.languageCode]; + + String get requestedDateLiveCare => localizedValues["requestedDateLiveCare"][locale.languageCode]; + + String get yourTurn => localizedValues["yourTurn"][locale.languageCode]; + + String get patients => localizedValues["patients"][locale.languageCode]; + + String get group => localizedValues["group"][locale.languageCode]; + + String get ancillaryOrdersPaymentConfirm => localizedValues["ancillaryOrdersPaymentConfirm"][locale.languageCode]; + + String get covidTestTodo => localizedValues["covidTestTodo"][locale.languageCode]; + + String get successRegister => localizedValues["successRegister"][locale.languageCode]; + + String get pharmacyLiveCare => localizedValues["pharmacyLiveCare"][locale.languageCode]; + + String get ancillaryOrderPaymentSuccess => localizedValues["ancillaryOrderPaymentSuccess"][locale.languageCode]; + + String get connectTitle => localizedValues["connectTitle"][locale.languageCode]; + + String get connectSubtitle => localizedValues["connectSubtitle"][locale.languageCode]; + + String get declineLbl => localizedValues["declineLbl"][locale.languageCode]; + + String get covidConsent => localizedValues["covidConsent"][locale.languageCode]; + + String get covidConsentHeader => localizedValues["covidConsentHeader"][locale.languageCode]; + + String get drawOverAppsPermission => localizedValues["drawOverAppsPermission"][locale.languageCode]; + + String get selectTamaraPlan => localizedValues["selectTamaraPlan"][locale.languageCode]; + + String get installments => localizedValues["installments"][locale.languageCode]; + + String get cameraPermissionDialog => localizedValues["cameraPermissionDialog"][locale.languageCode]; + + String get galleryPermission => localizedValues["galleryPermission"][locale.languageCode]; + + String get locationPermissionDialog => localizedValues["locationPermissionDialog"][locale.languageCode]; + + String get calendarPermission => localizedValues["calendarPermission"][locale.languageCode]; + + String get recordAudioPermission => localizedValues["recordAudioPermission"][locale.languageCode]; + + String get wifiPermission => localizedValues["wifiPermission"][locale.languageCode]; + + String get physicalActivityPermission => localizedValues["physicalActivityPermission"][locale.languageCode]; + + String get bluetoothPermission => localizedValues["bluetoothPermission"][locale.languageCode]; + + String get privacyPolicy => localizedValues["privacyPolicy"][locale.languageCode]; + + String get termsConditions => localizedValues["termsConditions"][locale.languageCode]; + + String get liveCarePermissions => localizedValues["liveCarePermissions"][locale.languageCode]; + + String get prescriptionDeliveryError => localizedValues["prescriptionDeliveryError"][locale.languageCode]; + + String get lakumUnhold => localizedValues["lakumUnhold"][locale.languageCode]; + + String get lakumDiscontinue => localizedValues["lakumDiscontinue"][locale.languageCode]; + + String get lakumSuccess => localizedValues["lakumSuccess"][locale.languageCode]; + + String get deleteAccount => localizedValues["deleteAccount"][locale.languageCode]; + + String get deactivateAccount => localizedValues["deactivateAccount"][locale.languageCode]; + + String get accountDeactivated => localizedValues["accountDeactivated"][locale.languageCode]; + + String get accountDeactivatedMsg => localizedValues["accountDeactivatedMsg"][locale.languageCode]; + + String get updateInsuranceManually => localizedValues["updateInsuranceManually"][locale.languageCode]; + + String get enterInsuranceDetails => localizedValues["enterInsuranceDetails"][locale.languageCode]; + + String get cardHolderName => localizedValues["cardHolderName"][locale.languageCode]; + + String get membershipNo => localizedValues["membershipNo"][locale.languageCode]; + + String get insurancePolicyNo => localizedValues["policyNo"][locale.languageCode]; + + String get insuranceClassName => localizedValues["insuranceClassName"][locale.languageCode]; + + String get NFCNotSupported => localizedValues["NFCNotSupported"][locale.languageCode]; + + String get paymentOnly => localizedValues["paymentOnly"][locale.languageCode]; + + String get pendingOnly => localizedValues["pendingOnly"][locale.languageCode]; + + String get insuranceRequestSubmit => localizedValues["insuranceRequestSubmit"][locale.languageCode]; + + String get enterWorkplaceName => localizedValues["enter-workplace-name"][locale.languageCode]; + + String get workplaceName => localizedValues["workplaceName"][locale.languageCode]; + + String get needApproval => localizedValues["needApproval"][locale.languageCode]; + + String get callLiveCareSupport => localizedValues["callLiveCareSupport"][locale.languageCode]; + + String get pendingActivation => localizedValues["pendingActivation"][locale.languageCode]; + + String get awaitingApproval => localizedValues["awaitingApproval"][locale.languageCode]; + + String get liveCareSupportContact => localizedValues["liveCareSupportContact"][locale.languageCode]; + + String get scanNFC => localizedValues["scanNFC"][locale.languageCode]; + + String get pharmaLiveCare => localizedValues["pharmaLiveCare"][locale.languageCode]; + + String get pharmaLiveCare1 => localizedValues["pharmaLiveCare1"][locale.languageCode]; + + String get pharmaLiveCareDesc1 => localizedValues["pharmaLiveCareDesc1"][locale.languageCode]; + + String get wherePharmaLiveCare => localizedValues["wherePharmaLiveCare"][locale.languageCode]; + + String get pharmaLiveCareDesc2 => localizedValues["pharmaLiveCareDesc2"][locale.languageCode]; + + String get howPharmaLiveCare => localizedValues["howPharmaLiveCare"][locale.languageCode]; + + String get pharmaLiveCareDesc3 => localizedValues["pharmaLiveCareDesc3"][locale.languageCode]; + + String get pharmaLiveCareScanQR => localizedValues["pharmaLiveCareScanQR"][locale.languageCode]; + + String get pharmaLiveCareScanQR1 => localizedValues["pharmaLiveCareScanQR1"][locale.languageCode]; + + String get pharmaLiveCareMakePayment => localizedValues["pharmaLiveCareMakePayment"][locale.languageCode]; + + String get pharmaLiveCareMakePayment1 => localizedValues["pharmaLiveCareMakePayment1"][locale.languageCode]; + + String get pharmaLiveCareJoinConsultation => localizedValues["pharmaLiveCareJoinConsultation"][locale.languageCode]; + + String get pharmaLiveCareJoinConsultation1 => localizedValues["pharmaLiveCareJoinConsultation1"][locale.languageCode]; + + String get emergencyServicesSubtitle => localizedValues["emergencyServicesSubtitle"][locale.languageCode]; + + String get rateDoctorResponse => localizedValues["rateDoctorResponse"][locale.languageCode]; + + String get comments => localizedValues["comments"][locale.languageCode]; + + String get rateDoctorResponseHeading => localizedValues["rateDoctorResponseHeading"][locale.languageCode]; + + String get updateInsuranceManuallyDialog => localizedValues["updateInsuranceManuallyDialog"][locale.languageCode]; + + String get viewReport => localizedValues["viewReport"][locale.languageCode]; + + String get sickLeaveAdmittedPatient => localizedValues["sickLeaveAdmittedPatient"][locale.languageCode]; + + String get InPatient => localizedValues["InPatient"][locale.languageCode]; + + String get inPatientServices => localizedValues["InPatientServices"][locale.languageCode]; + + String get InPatientServicesHeader => localizedValues["InPatientServicesHeader"][locale.languageCode]; + + String get admissionGeneral => localizedValues["admissionGeneral"][locale.languageCode]; + + String get consent => localizedValues["consent"][locale.languageCode]; + + String get generalInstructionsTitle => localizedValues["generalInstructionsTitle"][locale.languageCode]; + + String get generalInstructionsSubTitle => localizedValues["generalInstructionsSubTitle"][locale.languageCode]; + + String get medicalInstructionsTitle => localizedValues["medicalInstructionsTitle"][locale.languageCode]; + + String get medicalInstructionsSubTitle => localizedValues["medicalInstructionsSubTitle"][locale.languageCode]; + + String get mealPlanTitle => localizedValues["mealPlanTitle"][locale.languageCode]; + + String get mealPlanSubTitle => localizedValues["mealPlanSubTitle"][locale.languageCode]; + + String get birthNotificationTitle => localizedValues["birthNotificationTitle"][locale.languageCode]; + + String get birthNotificationSubTitle => localizedValues["birthNotificationSubTitle"][locale.languageCode]; + + String get admissionNoticeTitle => localizedValues["admissionNoticeTitle"][locale.languageCode]; + + String get admissionNoticeSubTitle => localizedValues["admissionNoticeSubTitle"][locale.languageCode]; + + String get mothersMRN => localizedValues["mothersMRN"][locale.languageCode]; + + String get mothersName => localizedValues["mothersName"][locale.languageCode]; + + String get fathersNameEN => localizedValues["fathersNameEN"][locale.languageCode]; + + String get fathersNameAR => localizedValues["fathersNameAR"][locale.languageCode]; + + String get babysNameEN => localizedValues["babysNameEN"][locale.languageCode]; + + String get babysNameAR => localizedValues["babysNameAR"][locale.languageCode]; + + String get contactNumber => localizedValues["contactNumber"][locale.languageCode]; + + String get scanID => localizedValues["scanID"][locale.languageCode]; + + String get birthNotificationNotes1 => localizedValues["birthNotificationNotes1"][locale.languageCode]; + + String get birthNotificationNotes2 => localizedValues["birthNotificationNotes2"][locale.languageCode]; + + String get birthNotificationNotes3 => localizedValues["birthNotificationNotes3"][locale.languageCode]; + + String get placeOrder => localizedValues["placeOrder"][locale.languageCode]; + + String get isFasting => localizedValues["isFasting"][locale.languageCode]; + + String get noGeneralInstructions => localizedValues["noGeneralInstructions"][locale.languageCode]; + + String get noMedicalInstructions => localizedValues["noMedicalInstructions"][locale.languageCode]; + + String get medicalInstructions => localizedValues["medicalInstructions"][locale.languageCode]; + + String get generalInstructions => localizedValues["generalInstructions"][locale.languageCode]; + + String get copyLink => localizedValues["copyLink"][locale.languageCode]; + + String get copyLinkTxt => localizedValues["copyLinkTxt"][locale.languageCode]; + + String get paymentLinkCopied => localizedValues["paymentLinkCopied"][locale.languageCode]; + + String get proErrorMessage => localizedValues["proErrorMessage"][locale.languageCode]; + + String get admissionNo => localizedValues["admissionNo"][locale.languageCode]; + + String get admissionReqNo => localizedValues["admissionReqNo"][locale.languageCode]; + + String get dischargeDate => localizedValues["dischargeDate"][locale.languageCode]; + + String get selectAdmissionText => localizedValues["selectAdmissionText"][locale.languageCode]; + + String get onlyAdmitted => localizedValues["onlyAdmitted"][locale.languageCode]; + + String get assistYou => localizedValues["assistYou"][locale.languageCode]; + + String get receive => localizedValues["receive"][locale.languageCode]; + + String get PRO => localizedValues["PRO"][locale.languageCode]; + + String get patientRelationOffice => localizedValues["patientRelationOffice"][locale.languageCode]; + + String get roomNo => localizedValues["roomNo"][locale.languageCode]; + + String get generalConsent => localizedValues["generalConsent"][locale.languageCode]; + + String get generalConsent1 => localizedValues["generalConsent1"][locale.languageCode]; + + String get hospitalRules => localizedValues["hospitalRules"][locale.languageCode]; + + String get generalConsent2 => localizedValues["generalConsent2"][locale.languageCode]; + + String get communicationConsent => localizedValues["communicationConsent"][locale.languageCode]; + + String get generalConsent3 => localizedValues["generalConsent3"][locale.languageCode]; + + String get releaseConsent => localizedValues["releaseConsent"][locale.languageCode]; + + String get generalConsent4 => localizedValues["generalConsent4"][locale.languageCode]; + + String get generalConsent5 => localizedValues["generalConsent5"][locale.languageCode]; + + String get valuables => localizedValues["valuables"][locale.languageCode]; + + String get generalConsent6 => localizedValues["generalConsent6"][locale.languageCode]; + + String get financialConsent => localizedValues["financialConsent"][locale.languageCode]; + + String get generalConsent7 => localizedValues["generalConsent7"][locale.languageCode]; + + String get dataSharingConsent => localizedValues["dataSharingConsent"][locale.languageCode]; + + String get generalConsent8 => localizedValues["generalConsent8"][locale.languageCode]; + + String get permissionLeaveConsent => localizedValues["permissionLeaveConsent"][locale.languageCode]; + + String get generalConsent9 => localizedValues["generalConsent9"][locale.languageCode]; + + String get observeConsent => localizedValues["observeConsent"][locale.languageCode]; + + String get generalConsent10 => localizedValues["generalConsent10"][locale.languageCode]; + + String get noGuaranteeConsent => localizedValues["noGuaranteeConsent"][locale.languageCode]; + + String get generalConsent11 => localizedValues["generalConsent11"][locale.languageCode]; + + String get disputeConsent => localizedValues["disputeConsent"][locale.languageCode]; + + String get generalConsent12 => localizedValues["generalConsent12"][locale.languageCode]; + + String get patientsRightsConsent => localizedValues["patientsRightsConsent"][locale.languageCode]; + + String get generalConsent13 => localizedValues["generalConsent13"][locale.languageCode]; + + String get acknowledgementConsent => localizedValues["acknowledgementConsent"][locale.languageCode]; + + String get generalConsent14 => localizedValues["generalConsent14"][locale.languageCode]; + + String get invalidEligibility => localizedValues["invalidEligibility"][locale.languageCode]; + + String get invalidInsurance => localizedValues["invalidInsurance"][locale.languageCode]; + + String get continueCash => localizedValues["continueCash"][locale.languageCode]; + + String get updateInsuranceText => localizedValues["updateInsurance"][locale.languageCode]; + + String get downloadReport => localizedValues["downloadReport"][locale.languageCode]; + + String get habibCallCenter => localizedValues["habibCallCenter"][locale.languageCode]; + + String get cashAmountUpdateInsurance => localizedValues["cashAmountUpdateInsurance"][locale.languageCode]; + + String get validInsurance => localizedValues["validInsurance"][locale.languageCode]; + + String get contactRRT => localizedValues["contactRRT"][locale.languageCode]; + + String get checkInViaLocation => localizedValues["checkInViaLocation"][locale.languageCode]; + + String get locationCheckInError => localizedValues["locationCheckInError"][locale.languageCode]; + + String get upcoming => localizedValues["upcoming"][locale.languageCode]; + + String get noUpcomingAppointment => localizedValues["noUpcomingAppointment"][locale.languageCode]; + + String get locationTimeoutError => localizedValues["locationTimeoutError"][locale.languageCode]; + + String get loadMore => localizedValues["loadMore"][locale.languageCode]; + + String get selectHospitalBloodDonation => localizedValues["selectHospitalBloodDonation"][locale.languageCode]; + + String get wecare => localizedValues["wecare"][locale.languageCode]; + + String get myinstructions => localizedValues["myinstructions"][locale.languageCode]; + + String get clinicLocation => localizedValues["clinicLocation"][locale.languageCode]; + + String get waitingAppointment => localizedValues["waitingAppointment"][locale.languageCode]; + + String get whatWaitingAppointment => localizedValues["whatWaitingAppointment"][locale.languageCode]; + + String get waitingAppointmentText1 => localizedValues["waitingAppointmentText1"][locale.languageCode]; + + String get waitingAppointmentText2 => localizedValues["waitingAppointmentText2"][locale.languageCode]; + + String get waitingAppointmentText3 => localizedValues["waitingAppointmentText3"][locale.languageCode]; + + String get waitingAppointmentVerificationMethod => localizedValues["waitingAppointmentVerificationMethod"][locale.languageCode]; + + String get howToUseVerificationMethod => localizedValues["howToUseVerificationMethod"][locale.languageCode]; + + String get addToWaitingList => localizedValues["addToWaitingList"][locale.languageCode]; + + String get searchClinic => localizedValues["searchClinic"][locale.languageCode]; + + String get enterMobileNumber => localizedValues["enterMobileNumber"][locale.languageCode]; + + String get videoCall => localizedValues["videoCall"][locale.languageCode]; + + String get audioCall => localizedValues["audioCall"][locale.languageCode]; + + String get phoneCall => localizedValues["phoneCall"][locale.languageCode]; + + String get selectCallType => localizedValues["selectCallType"][locale.languageCode]; + + String get selectedCallType => localizedValues["selectedCallType"][locale.languageCode]; + + String get selectBranch => localizedValues["selectBranch"][locale.languageCode]; + + String get searchByBranch => localizedValues["searchByBranch"][locale.languageCode]; + + String get existingPackage => localizedValues["existingPackage"][locale.languageCode]; + + String get continueOrbookNew => localizedValues["continueOrbookNew"][locale.languageCode]; + + String get newAppointment => localizedValues["newAppointment"][locale.languageCode]; + + String get proceedPackage => localizedValues["proceedPackage"][locale.languageCode]; + + String get hospitalNavigationTitle => localizedValues["hospitalNavigationTitle"][locale.languageCode]; + + String get hospitalNavigationSubtitle => localizedValues["hospitalNavigationSubtitle"][locale.languageCode]; + + String get workplaceNameAr => localizedValues["workplaceNameAr"][locale.languageCode]; + + String get occupationNameEn => localizedValues["occupationNameEn"][locale.languageCode]; + + String get occupationNameAr => localizedValues["occupationNameAr"][locale.languageCode]; + + String get continueAgreeTerms => localizedValues["continueAgreeTerms"][locale.languageCode]; + + String get agreeText => localizedValues["agreeText"][locale.languageCode]; + + String get ERCheckInSuccess => localizedValues["ERCheckInSuccess"][locale.languageCode]; + + String get generalConsentTitle => localizedValues["generalConsentTitle"][locale.languageCode]; + + String get generalConsentSubTitle => localizedValues["generalConsentSubTitle"][locale.languageCode]; + + String get incorrectNationalId => localizedValues["incorrectNationalId"][locale.languageCode]; + + String get resultStatus => localizedValues["resultStatus"][locale.languageCode]; + + String get labResultFlag => localizedValues["labResultFlag"][locale.languageCode]; + + String get selectOccupation => localizedValues["selectOccupation"][locale.languageCode]; + + String get selectOccupationError => localizedValues["selectOccupationError"][locale.languageCode]; + + String get whatIsOnlineCheckIn => localizedValues["whatIsOnlineCheckIn"][locale.languageCode]; + + String get EROnlineCheckInDesc1 => localizedValues["EROnlineCheckInDesc1"][locale.languageCode]; + + String get EROnlineCheckInHow => localizedValues["EROnlineCheckInHow"][locale.languageCode]; + + String get EROnlineCheckInTapOn => localizedValues["EROnlineCheckInTapOn"][locale.languageCode]; + + String get EROnlineCheckInTapOnCheckIn => localizedValues["EROnlineCheckInTapOnCheckIn"][locale.languageCode]; + + String get EROnlineCheckInHoldPhone => localizedValues["EROnlineCheckInHoldPhone"][locale.languageCode]; + + String get EROnlineCheckInHoldPhoneInstruction => localizedValues["EROnlineCheckInHoldPhoneInstruction"][locale.languageCode]; + + String get EROnlineCheckInWaitTurn => localizedValues["EROnlineCheckInWaitTurn"][locale.languageCode]; + + String get EROnlineCheckInWaitTurnInstruction => localizedValues["EROnlineCheckInWaitTurnInstruction"][locale.languageCode]; + + String get download => localizedValues["download"][locale.languageCode]; + + String get share => localizedValues["share"][locale.languageCode]; + String get selectRegion => localizedValues["selectRegion"][locale.languageCode]; + String get selectFacitlity => localizedValues["selectFacitlity"][locale.languageCode]; + String get selectDoctor => localizedValues["selectDoctor"][locale.languageCode]; + String get hmgHospital => localizedValues["hmgHospital"][locale.languageCode]; + String get hmcHospital => localizedValues["hmcHospital"][locale.languageCode]; + + String get hmcHospitalCountSingle => + localizedValues["hmcHospitalCountSingle"][locale.languageCode]; + + String get hmgHospitalCountSingle => + localizedValues["hmgHospitalCountSingle"][locale.languageCode]; + + String get hmcHospitalCountPlural => + localizedValues["hmcHospitalCountPlural"][locale.languageCode]; + + String get hmgHospitalCountPlural => + localizedValues["hmgHospitalCountPlural"][locale.languageCode]; + String get nearest => localizedValues["nearest"][locale.languageCode]; + + String get kilometerUnit => + localizedValues["kilometerUnit"][locale.languageCode]; + + String HospitalString(num value) { + if (value == 1 || value == 0) + return localizedValues["hmgHospitalCountSingle"][locale + .languageCode]; else + return localizedValues["hmgHospitalCountPlural"][locale.languageCode]; + } + + String MedicalCenterString(num value) { + if (value == 1 || value == 0) + return localizedValues["hmcHospitalCountSingle"][locale + .languageCode]; else + return localizedValues["hmcHospitalCountPlural"][locale.languageCode]; + } + + String get termsHeading => localizedValues["termsHeading"][locale.languageCode]; + String get termsConditions1 => localizedValues["termsConditions1"][locale.languageCode]; + String get termsConditions2 => localizedValues["termsConditions2"][locale.languageCode]; + String get termsConditions3 => localizedValues["termsConditions3"][locale.languageCode]; + String get termsConditions4 => localizedValues["termsConditions4"][locale.languageCode]; + String get termsConditions5 => localizedValues["termsConditions5"][locale.languageCode]; + String get termsHeading2 => localizedValues["termsHeading2"][locale.languageCode]; + String get termsConditions6 => localizedValues["termsConditions6"][locale.languageCode]; + String get termsHeading3 => localizedValues["termsHeading3"][locale.languageCode]; + String get termsConditions7 => localizedValues["termsConditions7"][locale.languageCode]; + String get termsConditions8 => localizedValues["termsConditions8"][locale.languageCode]; + String get termsConditions9 => localizedValues["termsConditions9"][locale.languageCode]; + String get termsConditions10 => localizedValues["termsConditions10"][locale.languageCode]; + String get termsConditions11 => localizedValues["termsConditions11"][locale.languageCode]; + String get termsConditions12 => localizedValues["termsConditions12"][locale.languageCode]; + String get termsConditions12a => localizedValues["termsConditions12a"][locale.languageCode]; + String get termsConditions12b => localizedValues["termsConditions12b"][locale.languageCode]; + String get termsConditions12c => localizedValues["termsConditions12c"][locale.languageCode]; + String get termsConditions13 => localizedValues["termsConditions13"][locale.languageCode]; + String get termsConditions14 => localizedValues["termsConditions14"][locale.languageCode]; + String get termsConditions14a => localizedValues["termsConditions14a"][locale.languageCode]; + String get termsConditions14b => localizedValues["termsConditions14b"][locale.languageCode]; + String get termsHeading4 => localizedValues["termsHeading4"][locale.languageCode]; + String get termsConditions15 => localizedValues["termsConditions15"][locale.languageCode]; + String get termsConditions16 => localizedValues["termsConditions16"][locale.languageCode]; + String get termsConditions16a => localizedValues["termsConditions16a"][locale.languageCode]; + String get termsConditions16b => localizedValues["termsConditions16b"][locale.languageCode]; + String get termsConditions17 => localizedValues["termsConditions17"][locale.languageCode]; + String get termsConditions18 => localizedValues["termsConditions18"][locale.languageCode]; + String get termsConditions19 => localizedValues["termsConditions19"][locale.languageCode]; + String get termsConditions19a => localizedValues["termsConditions19a"][locale.languageCode]; + String get termsConditions19b => localizedValues["termsConditions19b"][locale.languageCode]; + String get termsHeading5 => localizedValues["termsHeading5"][locale.languageCode]; + String get termsConditions20 => localizedValues["termsConditions20"][locale.languageCode]; + String get termsConditions21 => localizedValues["termsConditions21"][locale.languageCode]; + String get termsHeading6 => localizedValues["termsHeading6"][locale.languageCode]; + String get termsConditions22 => localizedValues["termsConditions22"][locale.languageCode]; + String get termsConditions23 => localizedValues["termsConditions23"][locale.languageCode]; + String get termsConditions24 => localizedValues["termsConditions24"][locale.languageCode]; + String get termsHeading7 => localizedValues["termsHeading7"][locale.languageCode]; + String get termsConditions25 => localizedValues["termsConditions25"][locale.languageCode]; + String get termsConditions25a => localizedValues["termsConditions25a"][locale.languageCode]; + String get termsConditions25b => localizedValues["termsConditions20"][locale.languageCode]; + String get termsConditions25c => localizedValues["termsConditions25b"][locale.languageCode]; + String get termsConditions26 => localizedValues["termsConditions26"][locale.languageCode]; + String get termsConditions27 => localizedValues["termsConditions27"][locale.languageCode]; + String get termsConditions28 => localizedValues["termsConditions28"][locale.languageCode]; + String get termsConditions29 => localizedValues["termsConditions29"][locale.languageCode]; + String get termsConditions30 => localizedValues["termsConditions30"][locale.languageCode]; + String get termsConditions31 => localizedValues["termsConditions31"][locale.languageCode]; + String get termsConditions32 => localizedValues["termsConditions32"][locale.languageCode]; + String get termsHeading8 => localizedValues["termsHeading8"][locale.languageCode]; + String get termsConditions33 => localizedValues["termsConditions33"][locale.languageCode]; + String get termsConditions33a => localizedValues["termsConditions33a"][locale.languageCode]; + String get termsConditions33b => localizedValues["termsConditions33b"][locale.languageCode]; + String get termsConditions34 => localizedValues["termsConditions34"][locale.languageCode]; + String get termsConditions34a => localizedValues["termsConditions34a"][locale.languageCode]; + String get termsConditions34b => localizedValues["termsConditions34b"][locale.languageCode]; + String get termsConditions34c => localizedValues["termsConditions34c"][locale.languageCode]; + String get termsConditions34d => localizedValues["termsConditions34d"][locale.languageCode]; + String get termsConditions34e => localizedValues["termsConditions34e"][locale.languageCode]; + String get termsConditions35 => localizedValues["termsConditions35"][locale.languageCode]; + String get termsConditions35a => localizedValues["termsConditions35a"][locale.languageCode]; + String get termsConditions35b => localizedValues["termsConditions35b"][locale.languageCode]; + String get termsConditions35c => localizedValues["termsConditions35c"][locale.languageCode]; + String get termsConditions35d => localizedValues["termsConditions35d"][locale.languageCode]; + String get termsConditions35e => localizedValues["termsConditions35e"][locale.languageCode]; + String get termsConditions36 => localizedValues["termsConditions36"][locale.languageCode]; + String get termsConditions37 => localizedValues["termsConditions37"][locale.languageCode]; + String get termsConditions38 => localizedValues["termsConditions38"][locale.languageCode]; + String get termsConditions39 => localizedValues["termsConditions39"][locale.languageCode]; + String get termsConditions39a => localizedValues["termsConditions39a"][locale.languageCode]; + String get termsConditions39b => localizedValues["termsConditions39b"][locale.languageCode]; + String get termsConditions39c => localizedValues["termsConditions39c"][locale.languageCode]; + String get termsConditions39d => localizedValues["termsConditions39d"][locale.languageCode]; + String get termsHeading9 => localizedValues["termsHeading9"][locale.languageCode]; + String get termsConditions40 => localizedValues["termsConditions40"][locale.languageCode]; + String get termsConditions41 => localizedValues["termsConditions41"][locale.languageCode]; + String get termsHeading10 => localizedValues["termsHeading10"][locale.languageCode]; + String get termsConditions42 => localizedValues["termsConditions42"][locale.languageCode]; + String get termsConditions43 => localizedValues["termsConditions43"][locale.languageCode]; + String get termsHeading11 => localizedValues["termsHeading11"][locale.languageCode]; + String get termsConditions44 => localizedValues["termsConditions44"][locale.languageCode]; + String get termsHeading12 => localizedValues["termsHeading12"][locale.languageCode]; + String get termsConditions45 => localizedValues["termsConditions45"][locale.languageCode]; + String get termsConditionsRead => localizedValues["termsConditionsRead"][locale.languageCode]; + String get liveCareTermsHeading => localizedValues["liveCareTermsHeading"][locale.languageCode]; + String get liveCareTermsIntroHeading => localizedValues["liveCareTermsIntroHeading"][locale.languageCode]; + String get liveCareTermsConditions1 => localizedValues["liveCareTermsConditions1"][locale.languageCode]; + String get liveCareTermsConditions2 => localizedValues["liveCareTermsConditions2"][locale.languageCode]; + String get liveCareTermsHeading2 => localizedValues["liveCareTermsHeading2"][locale.languageCode]; + String get liveCareTermsConditions3 => localizedValues["liveCareTermsConditions3"][locale.languageCode]; + String get liveCareTermsConditions3a => localizedValues["liveCareTermsConditions3a"][locale.languageCode]; + String get liveCareTermsConditions3b => localizedValues["liveCareTermsConditions3b"][locale.languageCode]; + String get liveCareTermsConditions3c => localizedValues["liveCareTermsConditions3c"][locale.languageCode]; + String get liveCareTermsConditions3d => localizedValues["liveCareTermsConditions3d"][locale.languageCode]; + String get liveCareTermsConditions4 => localizedValues["liveCareTermsConditions4"][locale.languageCode]; + String get liveCareTermsConditions5 => localizedValues["liveCareTermsConditions5"][locale.languageCode]; + String get liveCareTermsConditions6 => localizedValues["liveCareTermsConditions6"][locale.languageCode]; + String get liveCareTermsHeading3 => localizedValues["liveCareTermsHeading3"][locale.languageCode]; + String get liveCareTermsConditions7 => localizedValues["liveCareTermsConditions7"][locale.languageCode]; + String get liveCareTermsConditions8 => localizedValues["liveCareTermsConditions8"][locale.languageCode]; + String get liveCareTermsConditions9 => localizedValues["liveCareTermsConditions9"][locale.languageCode]; + String get liveCareTermsConditions10 => localizedValues["liveCareTermsConditions10"][locale.languageCode]; + String get liveCareTermsConditions11 => localizedValues["liveCareTermsConditions11"][locale.languageCode]; + String get liveCareTermsConditions12 => localizedValues["liveCareTermsConditions12"][locale.languageCode]; + String get liveCareTermsConditions13 => localizedValues["liveCareTermsConditions13"][locale.languageCode]; + String get liveCareTermsHeading4 => localizedValues["liveCareTermsHeading4"][locale.languageCode]; + String get liveCareTermsConditions14 => localizedValues["liveCareTermsConditions14"][locale.languageCode]; + String get liveCareTermsConditions15 => localizedValues["liveCareTermsConditions15"][locale.languageCode]; + String get liveCareTermsConditions16 => localizedValues["liveCareTermsConditions16"][locale.languageCode]; + String get liveCareTermsHeading5 => localizedValues["liveCareTermsHeading5"][locale.languageCode]; + String get liveCareTermsConditions17 => localizedValues["liveCareTermsConditions17"][locale.languageCode]; + + String get liveCareTermsConditions18 => localizedValues["liveCareTermsConditions18"][locale.languageCode]; + String get liveCareTermsConditions19 => localizedValues["liveCareTermsConditions19"][locale.languageCode]; + String get liveCareTermsConditions19a => localizedValues["liveCareTermsConditions19a"][locale.languageCode]; + String get liveCareTermsConditions19b => localizedValues["liveCareTermsConditions19b"][locale.languageCode]; + String get liveCareTermsConditions19c => localizedValues["liveCareTermsConditions19c"][locale.languageCode]; + String get liveCareTermsConditions19d => localizedValues["liveCareTermsConditions19d"][locale.languageCode]; + String get liveCareTermsConditions19e => localizedValues["liveCareTermsConditions19e"][locale.languageCode]; + String get liveCareTermsConditions20 => localizedValues["liveCareTermsConditions20"][locale.languageCode]; + String get liveCareTermsHeading6 => localizedValues["liveCareTermsHeading6"][locale.languageCode]; + String get liveCareTermsConditions21 => localizedValues["liveCareTermsConditions21"][locale.languageCode]; + String get liveCareTermsConditions22 => localizedValues["liveCareTermsConditions22"][locale.languageCode]; + String get liveCareTermsConditions23 => localizedValues["liveCareTermsConditions23"][locale.languageCode]; + String get liveCareTermsHeading7 => localizedValues["liveCareTermsHeading7"][locale.languageCode]; + String get liveCareTermsConditions24 => localizedValues["liveCareTermsConditions24"][locale.languageCode]; + String get liveCareTermsConditions25 => localizedValues["liveCareTermsConditions25"][locale.languageCode]; + String get liveCareTermsConditions26 => localizedValues["liveCareTermsConditions26"][locale.languageCode]; + String get liveCareTermsConditions27 => localizedValues["liveCareTermsConditions27"][locale.languageCode]; + String get liveCareTermsConditions28 => localizedValues["liveCareTermsConditions28"][locale.languageCode]; + String get liveCareTermsConditions29 => localizedValues["liveCareTermsConditions29"][locale.languageCode]; + String get liveCareTermsConditions30 => localizedValues["liveCareTermsConditions30"][locale.languageCode]; + + String get liveCareTermsHeading8 => localizedValues["liveCareTermsHeading8"][locale.languageCode]; + String get liveCareTermsConditions31 => localizedValues["liveCareTermsConditions31"][locale.languageCode]; + String get liveCareTermsHeading9 => localizedValues["liveCareTermsHeading9"][locale.languageCode]; + String get liveCareTermsConditions32 => localizedValues["liveCareTermsConditions32"][locale.languageCode]; + String get liveCareTermsConditions33 => localizedValues["liveCareTermsConditions33"][locale.languageCode]; + String get liveCareTermsConditions34 => localizedValues["liveCareTermsConditions34"][locale.languageCode]; + String get liveCareTermsConditions35 => localizedValues["liveCareTermsConditions35"][locale.languageCode]; + String get liveCareTermsHeading10 => localizedValues["liveCareTermsHeading10"][locale.languageCode]; + String get liveCareTermsConditions36 => localizedValues["liveCareTermsConditions36"][locale.languageCode]; + String get liveCareTermsHeading11 => localizedValues["liveCareTermsHeading11"][locale.languageCode]; + String get liveCareTermsConditions37 => localizedValues["liveCareTermsConditions37"][locale.languageCode]; + String get liveCareTermsConditions38 => localizedValues["liveCareTermsConditions38"][locale.languageCode]; + String get liveCareTermsHeading12 => localizedValues["liveCareTermsHeading12"][locale.languageCode]; + String get liveCareTermsConditions39 => localizedValues["liveCareTermsConditions39"][locale.languageCode]; + String get liveCareTermsConditions40 => localizedValues["liveCareTermsConditions40"][locale.languageCode]; + String get liveCareTermsConditions41 => localizedValues["liveCareTermsConditions41"][locale.languageCode]; + String get liveCareTermsHeading13 => localizedValues["liveCareTermsHeading13"][locale.languageCode]; + String get liveCareTermsConditions42 => localizedValues["liveCareTermsConditions42"][locale.languageCode]; + String get liveCareTermsHeading14 => localizedValues["liveCareTermsHeading14"][locale.languageCode]; + String get liveCareTermsConditions43 => localizedValues["liveCareTermsConditions43"][locale.languageCode]; + String get liveCareTermsConditions43a => localizedValues["liveCareTermsConditions43a"][locale.languageCode]; + String get liveCareTermsConditions43b => localizedValues["liveCareTermsConditions43b"][locale.languageCode]; + String get liveCareTermsConditions43c => localizedValues["liveCareTermsConditions43c"][locale.languageCode]; + String get liveCareTermsConditions43d => localizedValues["liveCareTermsConditions43d"][locale.languageCode]; + String get liveCareTermsConditions43e => localizedValues["liveCareTermsConditions43e"][locale.languageCode]; + String get liveCareTermsConditions43f => localizedValues["liveCareTermsConditions43f"][locale.languageCode]; + String get liveCareTermsConditions43g => localizedValues["liveCareTermsConditions43g"][locale.languageCode]; + String get liveCareTermsHeading15 => localizedValues["liveCareTermsHeading15"][locale.languageCode]; + String get liveCareTermsConditions44 => localizedValues["liveCareTermsConditions44"][locale.languageCode]; + String get liveCareTermsConditions45 => localizedValues["liveCareTermsConditions45"][locale.languageCode]; + String get liveCareTermsConditions46 => localizedValues["liveCareTermsConditions46"][locale.languageCode]; + String get liveCareTermsHeading16 => localizedValues["liveCareTermsHeading16"][locale.languageCode]; + String get liveCareTermsConditions47 => localizedValues["liveCareTermsConditions47"][locale.languageCode]; + String get liveCareTermsConditions48 => localizedValues["liveCareTermsConditions48"][locale.languageCode]; + String get clickPrivacyPolicy => localizedValues["clickPrivacyPolicy"][locale.languageCode]; + + +} + +class TranslationBaseDelegate extends LocalizationsDelegate { + const TranslationBaseDelegate(); + + @override + bool isSupported(Locale locale) => ['en', 'ar'].contains(locale.languageCode); + + @override + Future load(Locale locale) { + return SynchronousFuture(TranslationBase(locale)); + } + + @override + bool shouldReload(TranslationBaseDelegate old) => false; +} + +extension xTranslationBase on TranslationBase { + isArabic() => locale.languageCode == "ar"; } diff --git a/lib/uitl/utils.dart b/lib/uitl/utils.dart index 67e5c6b9..77059a65 100644 --- a/lib/uitl/utils.dart +++ b/lib/uitl/utils.dart @@ -3,24 +3,33 @@ import 'dart:core'; import 'dart:io'; import 'dart:typed_data'; -import 'package:badges/badges.dart'; +import 'package:auto_size_text/auto_size_text.dart'; +import 'package:badges/badges.dart' as badge_import; import 'package:cached_network_image/cached_network_image.dart'; -import 'package:connectivity/connectivity.dart'; +import 'package:connectivity_plus/connectivity_plus.dart'; +import 'package:crypto/crypto.dart' as crypto; +import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/model/privilege/ProjectDetailListModel.dart'; +import 'package:diplomaticquarterapp/core/service/client/base_app_client.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/extensions/string_extensions.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; +import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/ancillary-orders/ancillaryOrders.dart'; import 'package:diplomaticquarterapp/pages/MyAppointments/MyAppointments.dart'; import 'package:diplomaticquarterapp/pages/insurance/insurance_approval_screen.dart'; import 'package:diplomaticquarterapp/pages/insurance/insurance_card_screen.dart'; import 'package:diplomaticquarterapp/pages/insurance/insurance_update_screen.dart'; +import 'package:diplomaticquarterapp/pages/landing/landing_page_pharmcy.dart'; import 'package:diplomaticquarterapp/pages/medical/active_medications/ActiveMedicationsPage.dart'; import 'package:diplomaticquarterapp/pages/medical/allergies_page.dart'; import 'package:diplomaticquarterapp/pages/medical/ask_doctor/ask_doctor_home_page.dart'; import 'package:diplomaticquarterapp/pages/medical/balance/my_balance_page.dart'; +import 'package:diplomaticquarterapp/pages/medical/dental_instructions_page.dart'; import 'package:diplomaticquarterapp/pages/medical/doctor/doctor_home_page.dart'; import 'package:diplomaticquarterapp/pages/medical/eye/EyeMeasurementsPage.dart'; import 'package:diplomaticquarterapp/pages/medical/labs/labs_home_page.dart'; -import 'package:diplomaticquarterapp/pages/medical/medical_profile_page.dart'; +import 'package:diplomaticquarterapp/pages/medical/my_invoices/my_invoice_page.dart'; import 'package:diplomaticquarterapp/pages/medical/my_trackers/my_trackers.dart'; import 'package:diplomaticquarterapp/pages/medical/patient_sick_leave_page.dart'; import 'package:diplomaticquarterapp/pages/medical/prescriptions/prescriptions_home_page.dart'; @@ -30,28 +39,61 @@ import 'package:diplomaticquarterapp/pages/medical/reports/report_home_page.dart import 'package:diplomaticquarterapp/pages/medical/smart_watch_health_data/smart_watch_instructions.dart'; import 'package:diplomaticquarterapp/pages/medical/vital_sign/vital_sign_details_screen.dart'; import 'package:diplomaticquarterapp/pages/vaccine/my_vaccines_screen.dart'; -import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/widgets/data_display/medical/medical_profile_item.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/alert_dialog.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/covid_consent_dialog.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_hms_gms_availability/flutter_hms_gms_availability.dart'; +import 'package:google_api_availability/google_api_availability.dart'; +import 'dart:math' show asin, cos, pi, pow, sin, sqrt; + +// import 'package:flutter_hms_gms_availability/flutter_hms_gms_availability.dart'; +import 'package:provider/provider.dart'; import 'package:url_launcher/url_launcher.dart'; + import '../Constants.dart'; +import '../locator.dart'; import 'app_shared_preferences.dart'; import 'app_toast.dart'; import 'gif_loader_dialog_utils.dart'; +import 'navigation_service.dart'; AppSharedPreferences sharedPref = new AppSharedPreferences(); class Utils { // static ProgressDialog pr; + static var navigationProjectsList = [ + { + "Desciption": "Sahafa Hospital", + "DesciptionN": "مستشفى الصحافة", + "ID": 130, + "LegalName": "Sahafa Hospital", + "LegalNameN": "مستشفى الصحافة", + "Name": "Sahafa Hospital", + "NameN": "مستشفى الصحافة", + "PhoneNumber": "+966115222222", + "SetupID": "013311", + "DistanceInKilometers": 0, + "HasVida3": false, + "IsActive": true, + "IsHmg": true, + "IsVidaPlus": false, + "Latitude": "24.8113774", + "Longitude": "46.6239813", + "MainProjectID": 130, + "ProjectOutSA": false, + "UsingInDoctorApp": false + } + ]; + ///show custom Error Toast /// [message] to show for user - static showErrorToast([String message]) { + static showErrorToast([String? message]) { String localMsg = generateContactAdminMessage(); if (message != null) { localMsg = message.toString(); @@ -60,11 +102,11 @@ class Utils { } /// Check The Internet Connection - static Future checkConnection() async { - ConnectivityResult connectivityResult = - await (Connectivity().checkConnectivity()); - if ((connectivityResult == ConnectivityResult.mobile) || - (connectivityResult == ConnectivityResult.wifi)) { + static Future checkConnection({bool bypassConnectionCheck = false}) async { + if (bypassConnectionCheck) return true; + //return true; + ConnectivityResult connectivityResult = await (Connectivity().checkConnectivity()); + if ((connectivityResult == ConnectivityResult.mobile) || (connectivityResult == ConnectivityResult.wifi)) { return true; } else { return false; @@ -85,6 +127,17 @@ class Utils { FocusScope.of(context).unfocus(); } + static showPermissionConsentDialog(BuildContext context, String message, VoidCallback? onTap) { + showDialog( + context: context, + builder: (cxt) => CovidConsentDialog( + okTitle: TranslationBase.of(context).acceptLbl, + title: TranslationBase.of(context).covidConsentHeader, + message: message, + onTap: onTap!, + )); + } + bool isSAUDIIDValid(String id, type) { if (type == 1) { if (id == null) { @@ -127,32 +180,24 @@ class Utils { } } - static String getAppointmentTransID(int projectID, int clinicID, int appoNo) { - return projectID.toString() + - '-' + - clinicID.toString() + - '-' + - appoNo.toString(); + static String getAppointmentTransID(int projectID, int clinicID, int appoNo, {bool isAddMilliseconds = true}) { + String currentMillis = DateTime.now().millisecondsSinceEpoch.toString(); + return projectID.toString() + '-' + clinicID.toString() + '-' + appoNo.toString() + (isAddMilliseconds ? '-' + currentMillis.substring(currentMillis.length - 5, currentMillis.length) : ""); } static String getAdvancePaymentTransID(int projectID, int fileNumber) { - return projectID.toString() + - '-' + - fileNumber.toString() + - '-' + - DateTime.now().millisecondsSinceEpoch.toString(); + return projectID.toString() + '-' + fileNumber.toString() + '-' + DateTime.now().millisecondsSinceEpoch.toString(); } - bool validateIDBox(String value, type) { - Pattern pattern = loginIDPattern(type); //r'^\d+(?:\.\d+)?$'; - - RegExp regex = new RegExp(pattern); + bool validateIDBox(String value, int type) { + String pattern = loginIDPattern(type); // Get the pattern based on type + RegExp regex = RegExp(pattern); return regex.hasMatch(value); } - String loginIDPattern(loginType) { - var length = loginType == 1 ? 10 : 7; - return "([0-9]{" + length.toString() + "})"; + String loginIDPattern(int loginType) { + var length = loginType == 1 ? 10 : 1; + return "([0-9]{" + length.toString() + "}\$)"; } static showProgressDialog(context, [String message = "Loading..."]) async { @@ -189,6 +234,8 @@ class Utils { String newNumber = ""; if (number.startsWith('0')) { newNumber = number.substring(1); + } else { + newNumber = number; } return newNumber; } @@ -198,381 +245,740 @@ class Utils { } static validEmail(email) { - return RegExp( - r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+") - .hasMatch(email); - } - - static List myMedicalList( - {ProjectViewModel projectViewModel, - BuildContext context, - bool isLogin, - count}) { - List medical = List(); - if (projectViewModel.havePrivilege(5)) { - medical.add(InkWell( - onTap: () { - Navigator.push( - context, - FadePage( - page: MyAppointments(), - ), - ); - }, - child: isLogin - ? Stack(children: [ - MedicalProfileItem( - title: TranslationBase.of(context).myAppointments, - imagePath: 'my_appointment_icon.png', - subTitle: TranslationBase.of(context).myAppointmentsList, - hasBadge: true, - ), - Positioned( - right: 0.0, - child: Badge( - toAnimate: false, - position: BadgePosition.topEnd(), - shape: BadgeShape.circle, - badgeColor: secondaryColor.withOpacity(1.0), - borderRadius: BorderRadius.circular(8), - badgeContent: Container( - padding: EdgeInsets.all(2.0), - child: Text(count.toString(), - style: - TextStyle(color: Colors.white, fontSize: 16.0)), - ), - ), - ), - ]) - : MedicalProfileItem( - title: TranslationBase.of(context).myAppointments, - imagePath: 'my_appointment_icon.png', - subTitle: TranslationBase.of(context).myAppointmentsList, - hasBadge: true, + return RegExp(r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+").hasMatch(email); + } + + static List myMedicalList({ProjectViewModel? projectViewModel, BuildContext? context, bool? isLogin, count, Function? onWeCareClick}) { + List medical = []; + + medical.add(InkWell( + onTap: () => projectViewModel.havePrivilege(5) ? Navigator.push(context, FadePage(page: MyAppointments())) : null, + child: isLogin! + ? Stack(children: [ + Container( + width: double.infinity, + height: double.infinity, + child: MedicalProfileItem( + title: TranslationBase.of(context!).myAppointments, + imagePath: 'appointment_list.svg', + subTitle: TranslationBase.of(context).myAppointmentsList, + hasBadge: true, + isEnable: projectViewModel!.havePrivilege(5)), ), - )); - } + projectViewModel.isArabic + ? !projectViewModel.user.isFamily + ? Positioned( + left: 8, + top: 4, + child: badge_import.Badge( + badgeAnimation: badge_import.BadgeAnimation.fade(toAnimate: false), + badgeStyle: badge_import.BadgeStyle( + elevation: 0, + shape: badge_import.BadgeShape.circle, + badgeColor: secondaryColor!.withOpacity(1.0), + borderRadius: BorderRadius.circular(8), + ), + position: badge_import.BadgePosition.topEnd(), + badgeContent: Container( + padding: EdgeInsets.all(2.0), + child: Text(count.toString(), style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 12.0)), + ), + ), + ) + : Container() + : !projectViewModel.user!.isFamily + ? Positioned( + right: 8, + top: 4, + child: badge_import.Badge( + position: badge_import.BadgePosition.topEnd(), + badgeAnimation: badge_import.BadgeAnimation.fade(toAnimate: false), + badgeStyle: badge_import.BadgeStyle( + elevation: 0, + shape: badge_import.BadgeShape.circle, + badgeColor: secondaryColor!.withOpacity(1.0), + borderRadius: BorderRadius.circular(8), + ), + badgeContent: Container( + padding: EdgeInsets.all(2.0), + child: Text(count.toString(), style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 12.0)), + ), + ), + ) + : Container(), + ]) + : MedicalProfileItem( + title: TranslationBase.of(context!).myAppointments, + imagePath: 'appointment_list.svg', + subTitle: TranslationBase.of(context!).myAppointmentsList, + hasBadge: true, + isEnable: projectViewModel!.havePrivilege(5), + ), + )); + if (projectViewModel.havePrivilege(10)) { medical.add(InkWell( onTap: () => Navigator.push(context, FadePage(page: LabsHomePage())), child: MedicalProfileItem( title: TranslationBase.of(context).lab, - imagePath: 'lab_result_icon.png', + imagePath: 'lab_result.svg', subTitle: TranslationBase.of(context).labSubtitle, ), )); } - if (projectViewModel.havePrivilege(7)) { - medical.add(InkWell( - onTap: () => - Navigator.push(context, FadePage(page: RadiologyHomePage())), - child: MedicalProfileItem( - title: TranslationBase.of(context).radiology, - imagePath: 'radiology_icon.png', - subTitle: TranslationBase.of(context).radiologySubtitle, - ), - )); - } + medical.add(InkWell( + onTap: () => projectViewModel.havePrivilege(7) ? Navigator.push(context, FadePage(page: RadiologyHomePage())) : null, + child: MedicalProfileItem( + title: TranslationBase.of(context).radiology, + imagePath: 'radiology.svg', + subTitle: TranslationBase.of(context).radiologySubtitle, + isEnable: projectViewModel.havePrivilege(7), + ), + )); - if (projectViewModel.havePrivilege(12)) { - medical.add(InkWell( - onTap: () { - Navigator.push( - context, - FadePage( - page: HomePrescriptionsPage(), - ), - ); - }, - child: MedicalProfileItem( - title: TranslationBase.of(context).medicines, - imagePath: 'prescription_icon.png', - subTitle: TranslationBase.of(context).medicinesSubtitle, - ), - )); - } + medical.add(InkWell( + onTap: () => projectViewModel.havePrivilege(12) ? Navigator.push(context, FadePage(page: HomePrescriptionsPage())) : null, + child: MedicalProfileItem( + title: TranslationBase.of(context).medicines, + imagePath: 'medicine_prescription.svg', + subTitle: TranslationBase.of(context).medicinesSubtitle, + isEnable: projectViewModel.havePrivilege(12), + ), + )); - if (projectViewModel.havePrivilege(25)) { - medical.add(InkWell( - onTap: () => Navigator.push( - context, - FadePage( - page: VitalSignDetailsScreen(), - ), - ), - child: MedicalProfileItem( - title: TranslationBase.of(context).vitalSigns, - imagePath: 'vital_signs.png', - subTitle: TranslationBase.of(context).vitalSignsSubtitle, - ), - )); - } + medical.add(InkWell( + onTap: () => projectViewModel.havePrivilege(25) + ? Navigator.push( + context, + FadePage(page: VitalSignDetailsScreen()), + ) + : null, + child: MedicalProfileItem( + title: TranslationBase.of(context).vitalSigns, + imagePath: 'vital_signs.svg', + subTitle: TranslationBase.of(context).vitalSignsSubtitle, + isEnable: projectViewModel.havePrivilege(25), + ), + )); - if (projectViewModel.havePrivilege(48)) { - medical.add(InkWell( - onTap: () => - Navigator.push(context, FadePage(page: ActiveMedicationsPage())), - child: MedicalProfileItem( - title: TranslationBase.of(context).myMedical, - imagePath: 'active_medications.png', - subTitle: TranslationBase.of(context).myMedicalSubtitle, - ), - )); - } + medical.add(InkWell( + onTap: () { + if (projectViewModel.havePrivilege(48)) Navigator.push(context, FadePage(page: ActiveMedicationsPage())); + }, + child: MedicalProfileItem( + title: TranslationBase.of(context).myMedical, + imagePath: 'active_medication.svg', + subTitle: TranslationBase.of(context).myMedicalSubtitle, + isEnable: projectViewModel.havePrivilege(48), + ), + )); - if (projectViewModel.havePrivilege(6)) { - medical.add(InkWell( - onTap: () { - Navigator.push( - context, - FadePage( - page: DoctorHomePage(), - ), - ); - }, - child: MedicalProfileItem( - title: TranslationBase.of(context).myDoctor, - imagePath: 'doctor_icon.png', - subTitle: TranslationBase.of(context).myDoctorSubtitle, - ), - )); - } + medical.add(InkWell( + onTap: () => projectViewModel.havePrivilege(6) + ? Navigator.push( + context, + FadePage( + page: DoctorHomePage(), + ), + ) + : null, + child: + MedicalProfileItem(title: TranslationBase.of(context).myDoctor, imagePath: 'my_doc.svg', subTitle: TranslationBase.of(context).myDoctorSubtitle, isEnable: projectViewModel.havePrivilege(6)), + )); + + medical.add(InkWell( + onTap: () => projectViewModel.havePrivilege(14) ? Navigator.push(context, FadePage(page: MyInvoices())) : null, + child: MedicalProfileItem( + title: TranslationBase.of(context).invoicesList, + imagePath: 'invoice_list.svg', + subTitle: TranslationBase.of(context).myInvoice, + isEnable: projectViewModel.havePrivilege(14), + ), + )); + + medical.add(InkWell( + onTap: () => projectViewModel.havePrivilege(85) ? Navigator.push(context, FadePage(page: AnicllaryOrders())) : null, + // onTap: () => Navigator.push(context, FadePage(page: AnicllaryOrders())), + child: MedicalProfileItem( + title: TranslationBase.of(context).anicllaryOrders, + imagePath: 'ancillary.svg', + isPngImage: false, + subTitle: TranslationBase.of(context).myInvoice, + isEnable: projectViewModel.havePrivilege(85), + ), + )); + + medical.add(InkWell( + onTap: () => onWeCareClick!(), + child: MedicalProfileItem( + title: TranslationBase.of(context).wecare, + imagePath: 'assets/images/new-design/virtual_tour_icon.png', + isPngImage: true, + subTitle: TranslationBase.of(context).service, + isEnable: projectViewModel.havePrivilege(105), + ), + )); + + medical.add(InkWell( + onTap: () { + Navigator.push(context, FadePage(page: DentalInstructionsPage())); + }, + child: MedicalProfileItem( + title: TranslationBase.of(context).myinstructions, + imagePath: 'medical_instructions.svg', + isPngImage: false, + subTitle: TranslationBase.of(context).service, + isEnable: projectViewModel.havePrivilege(106), + ), + )); + + medical.add(InkWell( + onTap: () => projectViewModel.havePrivilege(14) ? Navigator.push(context, FadePage(page: EyeMeasurementsPage())) : null, + child: MedicalProfileItem( + title: TranslationBase.of(context).eye, + imagePath: 'eye_measurement.svg', + subTitle: TranslationBase.of(context).eyeSubtitle, + isEnable: projectViewModel.havePrivilege(14), + ), + )); + + medical.add(InkWell( + onTap: () => projectViewModel.havePrivilege(22) + ? Navigator.push( + context, + FadePage( + page: InsuranceCard( + appointmentNo: 0, + ))) + : null, + child: MedicalProfileItem( + title: TranslationBase.of(context).insurance, + imagePath: 'insurance_card.svg', + subTitle: TranslationBase.of(context).insuranceSubtitle, + isEnable: projectViewModel.havePrivilege(22), + ), + )); - if (projectViewModel.havePrivilege(14)) { - medical.add(InkWell( - onTap: () { - Navigator.push(context, FadePage(page: EyeMeasurementsPage())); - }, - child: MedicalProfileItem( - title: TranslationBase.of(context).eye, - imagePath: 'eye_measurement_icon.png', - subTitle: TranslationBase.of(context).eyeSubtitle, - ), - )); - } - if (projectViewModel.havePrivilege(22)) { - medical.add(InkWell( - onTap: () { - Navigator.push(context, FadePage(page: InsuranceCard())); - }, - child: MedicalProfileItem( - title: TranslationBase.of(context).insurance, - imagePath: 'insurance_card_icon.png', - subTitle: TranslationBase.of(context).insuranceSubtitle, - ), - )); - } medical.add(InkWell( onTap: () { Navigator.push(context, FadePage(page: InsuranceUpdate())); }, child: MedicalProfileItem( title: TranslationBase.of(context).updateInsurance, - imagePath: 'insurance_update_icon_.png', + imagePath: 'insurance_card.svg', subTitle: TranslationBase.of(context).updateInsuranceSubtitle, ), )); - if (projectViewModel.havePrivilege(18)) { - medical.add(InkWell( - onTap: () { - Navigator.push(context, FadePage(page: InsuranceApproval())); - }, - child: MedicalProfileItem( - title: TranslationBase.of(context).insuranceApproval, - imagePath: 'insurance_approvals_icon.png', - subTitle: TranslationBase.of(context).insuranceApprovalSubtitle, - ), - )); - } + medical.add(InkWell( + onTap: () => projectViewModel.havePrivilege(18) + ? Navigator.push( + context, + FadePage( + page: InsuranceApproval( + appointmentNo: 0, + ))) + : null, + child: MedicalProfileItem( + title: TranslationBase.of(context).insuranceApproval, + imagePath: 'insurance_approval.svg', + subTitle: TranslationBase.of(context).insuranceApprovalSubtitle, + isEnable: projectViewModel.havePrivilege(18), + ), + )); - if (projectViewModel.havePrivilege(23)) { - medical.add(InkWell( - onTap: () => Navigator.push(context, FadePage(page: AllergiesPage())), - child: MedicalProfileItem( - title: TranslationBase.of(context).allergies, - imagePath: 'my_allergies_icon.png', - subTitle: TranslationBase.of(context).allergiesSubtitle, - ), - )); - } + medical.add(InkWell( + onTap: () => projectViewModel.havePrivilege(23) ? Navigator.push(context, FadePage(page: AllergiesPage())) : null, + child: MedicalProfileItem( + title: TranslationBase.of(context).allergies, + imagePath: 'allergies_diagnosed.svg', + subTitle: TranslationBase.of(context).allergiesSubtitle, + isEnable: projectViewModel.havePrivilege(23), + ), + )); - if (projectViewModel.havePrivilege(26)) { - medical.add(InkWell( - onTap: () { - Navigator.push(context, FadePage(page: MyVaccines())); - }, - child: MedicalProfileItem( - title: TranslationBase.of(context).myVaccines, - imagePath: 'my_vaccines_icon.png', - subTitle: TranslationBase.of(context).myVaccinesSubtitle, - ), - )); - } - if (projectViewModel.havePrivilege(20)) - medical.add(InkWell( - onTap: () { - Navigator.push(context, FadePage(page: HomeReportPage())); - }, - child: MedicalProfileItem( - title: TranslationBase.of(context).medical, - imagePath: 'medical_reports_icon.png', - subTitle: TranslationBase.of(context).medicalSubtitle, - ), - )); + medical.add(InkWell( + onTap: () => projectViewModel.havePrivilege(26) ? Navigator.push(context, FadePage(page: MyVaccines())) : null, + child: MedicalProfileItem( + title: TranslationBase.of(context).myVaccines, + imagePath: 'vaccine_list.svg', + subTitle: TranslationBase.of(context).myVaccinesSubtitle, + isEnable: projectViewModel.havePrivilege(26), + ), + )); - if (projectViewModel.havePrivilege(19)) { - medical.add(InkWell( - onTap: () { - Navigator.push(context, FadePage(page: MonthlyReportsPage())); - }, - child: MedicalProfileItem( - title: TranslationBase.of(context).monthly, - imagePath: 'monthly_reports_icon.png', - subTitle: TranslationBase.of(context).monthlySubtitle, - ), - )); - } + medical.add(InkWell( + onTap: () => projectViewModel.havePrivilege(20) ? Navigator.push(context, FadePage(page: HomeReportPage())) : null, + child: MedicalProfileItem( + title: TranslationBase.of(context).medical, + imagePath: 'medical_report.svg', + subTitle: TranslationBase.of(context).medicalSubtitle, + isEnable: projectViewModel.havePrivilege(20), + ), + )); - if (projectViewModel.havePrivilege(16)) { - medical.add(InkWell( - onTap: () { - Navigator.push(context, FadePage(page: PatientSickLeavePage())); - }, - child: MedicalProfileItem( - title: TranslationBase.of(context).sick, - imagePath: 'sick_leaves_icons.png', - subTitle: TranslationBase.of(context).sickSubtitle, - ), - )); - } + medical.add(InkWell( + onTap: () => projectViewModel.havePrivilege(19) ? Navigator.push(context, FadePage(page: MonthlyReportsPage())) : null, + child: MedicalProfileItem( + title: TranslationBase.of(context).monthly, + imagePath: 'monthly_report.svg', + subTitle: TranslationBase.of(context).monthlySubtitle, + isEnable: projectViewModel.havePrivilege(19), + ), + )); + + medical.add(InkWell( + onTap: () => projectViewModel.havePrivilege(16) ? Navigator.push(context, FadePage(page: PatientSickLeavePage())) : null, + child: MedicalProfileItem( + title: TranslationBase.of(context).sick, + imagePath: 'sick_leave.svg', + subTitle: TranslationBase.of(context).sickSubtitle, + isEnable: projectViewModel.havePrivilege(16), + ), + )); + + medical.add(InkWell( + onTap: () => projectViewModel.havePrivilege(47) ? Navigator.push(context, FadePage(page: MyBalancePage())) : null, + child: MedicalProfileItem( + title: TranslationBase.of(context).myBalance, + imagePath: 'balance_credit.svg', + subTitle: TranslationBase.of(context).myBalanceSubtitle, + isEnable: projectViewModel.havePrivilege(47), + ), + )); + + // medical.add(MedicalProfileItem( + // title: TranslationBase.of(context).patientCall, + // imagePath: 'medical_history_icon.png', + // subTitle: TranslationBase.of(context).patientCallSubtitle, + // isEnable: projectViewModel.havePrivilege(61), + // )); + + medical.add(InkWell( + onTap: () => projectViewModel.havePrivilege(24) ? Navigator.push(context, FadePage(page: MyTrackers())) : null, + child: MedicalProfileItem( + title: TranslationBase.of(context).myTrackers, + imagePath: 'tracker.svg', + subTitle: TranslationBase.of(context).myTrackersSubtitle, + isEnable: projectViewModel.havePrivilege(24), + ), + )); + + medical.add(InkWell( + onTap: () => projectViewModel.havePrivilege(30) ? Navigator.push(context, FadePage(page: SmartWatchInstructions())) : null, + child: MedicalProfileItem( + title: TranslationBase.of(context).smartWatchesSubtitle, + imagePath: 'smart_watch.svg', + subTitle: TranslationBase.of(context).smartWatches, + isEnable: projectViewModel.havePrivilege(30), + ), + )); - if (projectViewModel.havePrivilege(47)) { + medical.add(InkWell( + onTap: () => projectViewModel.havePrivilege(28) ? Navigator.push(context, FadePage(page: AskDoctorHomPage())) : null, + child: MedicalProfileItem( + title: TranslationBase.of(context).askYourSubtitle, imagePath: 'ask_doctor.svg', subTitle: TranslationBase.of(context).askYour, isEnable: projectViewModel.havePrivilege(28)), + )); + + if (projectViewModel.havePrivilege(32) || true) { medical.add(InkWell( onTap: () { - Navigator.push(context, FadePage(page: MyBalancePage())); + if (Platform.isAndroid) { + showPermissionConsentDialog(context, TranslationBase.of(context).wifiPermission, () { + connectWifi(projectViewModel, context); + }); + } else { + connectWifi(projectViewModel, context); + } }, child: MedicalProfileItem( - title: TranslationBase.of(context).myBalance, - imagePath: 'check-in.png', - subTitle: TranslationBase.of(context).myBalanceSubtitle, + title: TranslationBase.of(context).internet, + imagePath: 'internet_connection.svg', + subTitle: TranslationBase.of(context).internetSubtitle, ), )); } - if (projectViewModel.havePrivilege(61)) { - medical.add(MedicalProfileItem( - title: TranslationBase.of(context).patientCall, - imagePath: 'medical_history_icon.png', - subTitle: TranslationBase.of(context).patientCallSubtitle, - )); + medical.add(InkWell( + onTap: () => projectViewModel.havePrivilege(40) ? launch('whatsapp://send?phone=18885521858&text=') : null, + child: MedicalProfileItem( + title: TranslationBase.of(context).chatbot, + imagePath: 'chatbot.svg', + subTitle: TranslationBase.of(context).chatbotSubtitle, + isEnable: projectViewModel.havePrivilege(40), + ), + )); + + return medical; + } + + static getPatientWifiCredentials(String patientID, Function(String username, String password) successCallback) { + final body = {"PatientID": patientID}; + locator().post(WIFI_CREDENTIALS, body: body, onSuccess: (dynamic response, int statusCode) { + print(response); + var data = response["Hmg_SMS_Get_By_ProjectID_And_PatientIDList"]; + if (data is List && data.first != null) { + final username = data.first['UserName']; + final password = data.first['Password']; + if (username != null && password != null && username.isNotEmpty && password.isNotEmpty) { + successCallback(username, password); + } + } + }, onFailure: (String error, int statusCode) { + print(error); + }, bypassConnectionCheck: true); + } + + static connectWifi(ProjectViewModel projectViewModel, BuildContext context) { + final String GUEST_SSID = "HMG-MobileApp"; + final String PATIENT_SSID = "GUEST-POC"; + userData().then((userData_) { + if (projectViewModel.isLogin && userData_ != null || true) { + String patientID = userData_.patientID.toString(); + GifLoaderDialogUtils.showMyDialog(context); + // projectViewModel.platformBridge().connectHMGInternetWifi(patientID).then((value) => {GifLoaderDialogUtils.hideDialog(context)}).catchError((err) { + // print(err.toString()); + // }); + projectViewModel.platformBridge().connectHMGGuestWifi(GUEST_SSID).then((value) async { + if (value == 0) { + GifLoaderDialogUtils.hideDialog(context); + } else { + getPatientWifiCredentials(patientID, (username, password) async { + final result = await projectViewModel.platformBridge().connectHMGInternetWifi(PATIENT_SSID, username, password).catchError((err) => print(err.toString())); + GifLoaderDialogUtils.hideDialog(context); + if (result == 1) { + // Success + } + }); + } + }).catchError((e) { + GifLoaderDialogUtils.hideDialog(context); + }); + } else { + AlertDialogBox( + context: context, + confirmMessage: "Please login with your account first to use this feature", + okText: "OK", + okFunction: () { + AlertDialogBox.closeAlertDialog(context); + }).showAlertDialog(context); + } + }); + } + + static List myMedicalListHomePage({ProjectViewModel? projectViewModel, BuildContext? context, bool? isLogin, count}) { + List medical = []; + + medical.add(InkWell( + onTap: () => projectViewModel.havePrivilege(5) ? Navigator.push(context!, FadePage(page: MyAppointments())) : null, + child: isLogin! + ? Stack(children: [ + MedicalProfileItem( + title: TranslationBase.of(context!).myAppointments, + imagePath: 'appointment_list.svg', + subTitle: TranslationBase.of(context!).myAppointmentsList, + hasBadge: true, + isEnable: projectViewModel!.havePrivilege(5)), + projectViewModel.isArabic! + ? !projectViewModel.isLoginChild + ? Positioned( + left: 8, + top: 4, + child: badge_import.Badge( + position: badge_import.BadgePosition.topEnd(), + badgeAnimation: badge_import.BadgeAnimation.fade(toAnimate: false), + badgeStyle: badge_import.BadgeStyle( + elevation: 0, + shape: badge_import.BadgeShape.circle, + badgeColor: secondaryColor!.withOpacity(1.0), + borderRadius: BorderRadius.circular(8), + ), + badgeContent: Container( + padding: EdgeInsets.all(2.0), + child: Text(count.toString(), style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 12.0)), + ), + ), + ) + : Container() + : !projectViewModel.isLoginChild + ? Positioned( + right: 8, + top: 4, + child: badge_import.Badge( + badgeAnimation: badge_import.BadgeAnimation.fade(toAnimate: false), + badgeStyle: badge_import.BadgeStyle( + elevation: 0, + shape: badge_import.BadgeShape.circle, + badgeColor: secondaryColor!.withOpacity(1.0), + borderRadius: BorderRadius.circular(8), + ), + position: badge_import.BadgePosition.topEnd(), + badgeContent: Container( + padding: EdgeInsets.all(2.0), + child: Text(count.toString(), style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 12.0)), + ), + ), + ) + : Container(), + ]) + : MedicalProfileItem( + title: TranslationBase.of(context!).myAppointments, + imagePath: 'appointment_list.svg', + subTitle: TranslationBase.of(context!).myAppointmentsList, + hasBadge: true, + isEnable: projectViewModel!.havePrivilege(5), + ), + )); + + medical.add(InkWell( + onTap: () => projectViewModel.havePrivilege(10) ? Navigator.push(context, FadePage(page: LabsHomePage())) : null, + child: MedicalProfileItem( + title: TranslationBase.of(context).lab, + imagePath: 'lab_result.svg', + subTitle: TranslationBase.of(context).labSubtitle, + isEnable: projectViewModel.havePrivilege(10), + ), + )); + + medical.add(InkWell( + onTap: () => projectViewModel.havePrivilege(7) ? Navigator.push(context, FadePage(page: RadiologyHomePage())) : null, + child: MedicalProfileItem( + title: TranslationBase.of(context).radiology, + imagePath: 'radiology.svg', + subTitle: TranslationBase.of(context).radiologySubtitle, + isEnable: projectViewModel.havePrivilege(7), + ), + )); + + medical.add(InkWell( + onTap: () => projectViewModel.havePrivilege(12) ? Navigator.push(context, FadePage(page: HomePrescriptionsPage())) : null, + child: MedicalProfileItem( + title: TranslationBase.of(context).medicines, + imagePath: 'medicine_prescription.svg', + subTitle: TranslationBase.of(context).medicinesSubtitle, + isEnable: projectViewModel.havePrivilege(12), + ), + )); + + medical.add(InkWell( + onTap: () => projectViewModel.havePrivilege(6) + ? Navigator.push( + context, + FadePage( + page: DoctorHomePage(), + ), + ) + : null, + child: + MedicalProfileItem(title: TranslationBase.of(context).myDoctor, imagePath: 'my_doc.svg', subTitle: TranslationBase.of(context).myDoctorSubtitle, isEnable: projectViewModel.havePrivilege(6)), + )); + + return medical; + } + + static Widget loadNetworkImage({required String url, BoxFit fitting = BoxFit.cover}) { + return CachedNetworkImage( + placeholderFadeInDuration: Duration(milliseconds: 250), + fit: fitting, + imageUrl: url, + placeholder: (context, url) => Container(child: Center(child: CircularProgressIndicator())), + errorWidget: (context, url, error) { + return Icon( + Icons.error, + color: Colors.red, + size: 50, + ); + }); + } + + static bool route(Route route, {required Type equalsTo}) { + if ((route is FadePage)) { + return route.page.runtimeType == equalsTo; } + return route.runtimeType == equalsTo; + } - if (projectViewModel.havePrivilege(24)) { - medical.add(InkWell( - onTap: () { - Navigator.push(context, FadePage(page: MyTrackers())); - }, - child: MedicalProfileItem( - title: TranslationBase.of(context).myTrackers, - imagePath: 'my_tracker_icon.png', - subTitle: TranslationBase.of(context).myTrackersSubtitle, + static navigateToCartPage() { + Navigator.pushAndRemoveUntil(locator()!.navigatorKey!.currentContext!, MaterialPageRoute(builder: (context) => LandingPagePharmacy(currentTab: 3)), (Route r) => false); + } + + static Widget tableColumnTitle(String text, {bool showDivider = true}) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox(height: 6), + Text( + text, + maxLines: 1, + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.48, height: 18 / 12), ), - )); - } - if (projectViewModel.havePrivilege(30)) - medical.add(InkWell( - onTap: () { - Navigator.push(context, FadePage(page: SmartWatchInstructions())); - }, - child: MedicalProfileItem( - title: TranslationBase.of(context).smartWatches, - imagePath: 'smartwatch_icon.png', - subTitle: TranslationBase.of(context).smartWatchesSubtitle, + SizedBox(height: 5), + if (showDivider) + Divider( + height: 1, + color: Color(0xff2E303A), + thickness: 1, + ) + ], + ); + } + + static Widget tableColumnValue(String text, {bool isLast = false, bool isCapitable = true, bool isHighLow = false, bool isCurrency = false, required ProjectViewModel mProjectViewModel}) { + ProjectViewModel projectViewModel = mProjectViewModel ?? Provider.of(AppGlobal.context); + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox(height: 12), + Row( + children: [ + Expanded( + child: Text( + isCapitable && !projectViewModel.isArabic ? text.toLowerCase().capitalizeFirstofEach : text, + maxLines: 2, + overflow: TextOverflow.ellipsis, + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: isHighLow ? CustomColors.accentColor : Color(0xff575757), letterSpacing: -0.4, height: 16 / 10), + ), + ), + isCurrency ? getSaudiRiyalSymbol() : Container(), + ], ), - )); + SizedBox(height: 12), + if (!isLast) + Divider( + height: 1, + color: Color(0xffEFEFEF), + thickness: 1, + ) + ], + ); + } - if (projectViewModel.havePrivilege(28)) { - medical.add(InkWell( - onTap: () { - Navigator.push(context, FadePage(page: AskDoctorHomPage())); - }, - child: MedicalProfileItem( - title: TranslationBase.of(context).askYour, - imagePath: 'ask_doctor_icon.png', - subTitle: TranslationBase.of(context).askYourSubtitle, + static Widget tableColumnValueWithFlowChart(String text, String flowChartText, {bool isLast = false, bool isCapitable = true, ProjectViewModel? mProjectViewModel}) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox(height: 12), + Text( + text, + maxLines: 2, + overflow: TextOverflow.ellipsis, + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff575757), letterSpacing: -0.4, height: 16 / 10), ), - )); - } - if (projectViewModel.havePrivilege(32) || true) { - medical.add(InkWell( - onTap: () { - userData().then((userData_) { - if (projectViewModel.isLogin && userData_ != null) { - String patientID = userData_.patientID.toString(); - GifLoaderDialogUtils.showMyDialog(context); - projectViewModel - .platformBridge() - .connectHMGInternetWifi(patientID) - .then((value) => {GifLoaderDialogUtils.hideDialog(context)}); - } else { - AlertDialogBox( - context: context, - confirmMessage: - "Please login with your account first to use this feature", - okText: "OK", - okFunction: () { - AlertDialogBox.closeAlertDialog(context); - }).showAlertDialog(context); - } - }); - }, - child: MedicalProfileItem( - title: TranslationBase.of(context).internet, - imagePath: 'insurance_card_icon.png', - subTitle: TranslationBase.of(context).internetSubtitle, + SizedBox(height: 8), + AutoSizeText( + flowChartText, + maxLines: 1, + minFontSize: 6, + style: TextStyle(decoration: TextDecoration.underline, fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xffD02127), letterSpacing: -0.48, height: 18 / 12), ), - )); - } + SizedBox(height: 12), + if (!isLast) + Divider( + height: 1, + color: Color(0xffEFEFEF), + thickness: 1, + ) + ], + ); + } - if (projectViewModel.havePrivilege(40)) { - medical.add(InkWell( - onTap: () { - launch('whatsapp://send?phone=18885521858&text='); - }, - child: MedicalProfileItem( - title: TranslationBase.of(context).chatbot, - imagePath: 'insurance_approvals_icon.png', - subTitle: TranslationBase.of(context).chatbotSubtitle, - ), - )); + static Future isGoogleServicesAvailable() async { + GooglePlayServicesAvailability availability = await GoogleApiAvailability.instance.checkGooglePlayServicesAvailability(); + String status = availability.toString().split('.').last; + if (status == "success") { + return true; } + return false; + } - return medical; + static double distance(double lat1, double lon1, double lat2, double lon2) { + const r = 6372.8; // Earth radius in kilometers + + final dLat = _toRadians(lat2 - lat1); + final dLon = _toRadians(lon2 - lon1); + final lat1Radians = _toRadians(lat1); + final lat2Radians = _toRadians(lat2); + + final a = _haversin(dLat) + cos(lat1Radians) * cos(lat2Radians) * _haversin(dLon); + final c = 2 * asin(sqrt(a)); + + return r * c; } - static Widget loadNetworkImage({@required String url, BoxFit fitting = BoxFit.cover}){ - return CachedNetworkImage( - placeholderFadeInDuration: Duration(milliseconds: 250), - fit: fitting, - imageUrl: url, - placeholder: (context, url) => Container( - child: Center( - child: CircularProgressIndicator() + static double _toRadians(double degrees) => degrees * pi / 180; + + static num _haversin(double radians) => pow(sin(radians / 2), 2); + + static Widget tableColumnValueWithUnderLine(String text, {bool isLast = false, bool isCapitable = true}) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox(height: 14), + AutoSizeText( + isCapitable ? text.toLowerCase().capitalizeFirstofEach : text, + maxLines: 1, + minFontSize: 6, + style: TextStyle(decoration: TextDecoration.underline, fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xffD02127), letterSpacing: -0.48, height: 18 / 12), + ), + SizedBox(height: 10), + if (!isLast) + Divider( + height: 1, + color: Color(0xffEFEFEF), + thickness: 1, ) - ), - errorWidget: (context, url, error){ - return Icon(Icons.error, color: Colors.red, size: 50,); - } + ], ); } -} + static String generateMd5Hash(String input) { + return crypto.md5.convert(utf8.encode(input)).toString(); + } + static bool isVidaPlusProject(ProjectViewModel projectViewModel, int projectID) { + bool isVidaPlus = false; + projectViewModel.vidaPlusProjectList.forEach((element) { + if (element.projectID == projectID) { + isVidaPlus = true; + } + }); + return isVidaPlus; + } + + static bool isHMCProject(ProjectViewModel projectViewModel, int projectID) { + bool isHMCProject = false; + projectViewModel.hMCProjectListModel.forEach((element) { + if (element.projectID == projectID) { + isHMCProject = true; + } + }); + return isHMCProject; + } + static ProjectDetailListModel getProjectDetailObj(ProjectViewModel projectViewModel, int projectID) { + ProjectDetailListModel projectDetailListModel = ProjectDetailListModel(); + projectViewModel.projectDetailListModel.forEach((element) { + if (element.projectID == projectID) { + projectDetailListModel = element; + } + }); + return projectDetailListModel; + } + + static Widget getSaudiRiyalSymbol({double fontSize = 16}) { + return Text(" SAR ", style: TextStyle(fontFamily: "SaudiRiyal", fontSize: fontSize)); + } + +//static String generateSignature() {} +} -Widget applyShadow({ Color color = Colors.grey, double shadowOpacity = 0.5, double spreadRadius = 2, double blurRadius = 7, Offset offset = const Offset(2, 2), @required Widget child}){ +Widget applyShadow({Color color = Colors.grey, double shadowOpacity = 0.5, double spreadRadius = 2, double blurRadius = 7, Offset offset = const Offset(2, 2), required Widget child}) { return Container( decoration: BoxDecoration( boxShadow: [ @@ -588,10 +994,8 @@ Widget applyShadow({ Color color = Colors.grey, double shadowOpacity = 0.5, doub ); } - Future userData() async { - var userData = AuthenticatedUser.fromJson( - await AppSharedPreferences().getObject(MAIN_USER)); + var userData = AuthenticatedUser.fromJson(await AppSharedPreferences().getObject(MAIN_USER)); return userData; } @@ -603,19 +1007,63 @@ extension IndexedIterable on Iterable { } } -openAppStore({String androidPackageName, String iOSAppID}) async{ - if(Platform.isAndroid){ +openAppStore({String? androidPackageName, String? iOSAppID, bool isHuawei = false}) async { + if (Platform.isAndroid) { assert(!(androidPackageName == null), "Should have valid value in androidPackageName parameter"); - if((await FlutterHmsGmsAvailability.isGmsAvailable)) - launch("market://details?id=com.ejada.hmg"); - if((await FlutterHmsGmsAvailability.isHmsAvailable)) - launch("appmarket://details?id=com.ejada.hmg"); - - }else if(Platform.isIOS){ + if (isHuawei) { + launchUrl(Uri.parse("appmarket://details?id=com.ejada.hmg")); + } else { + launchUrl(Uri.parse("market://details?id=com.ejada.hmg")); + } + } else if (Platform.isIOS) { assert((iOSAppID == null), "Should have valid value in iOSAppID parameter"); - launch("https://itunes.apple.com/kr/app/apple-store/$iOSAppID)"); + launchUrl(Uri.parse("https://itunes.apple.com/kr/app/apple-store/$iOSAppID)")); + } +} + +String labelFrom({required String className}) { + RegExp exp = RegExp(r'(?<=[a-z])[A-Z]'); + + String result = className.replaceAllMapped(exp, (m) { + var str = m.group(0); + if (str != null) { + return ('_' + str); + } + return ""; + }); + + if (result.isEmpty) return className; + + result = result.replaceAll("_", " "); + return result; +} + +extension StringExtension on String { + String capitalize() { + return this.splitMapJoin(RegExp(r'\w+'), onMatch: (m) => '${m.group(0)}'.substring(0, 1).toUpperCase() + '${m.group(0)}'.substring(1).toLowerCase(), onNonMatch: (n) => ' '); } } + +extension TextToRichTextWithIcon on Text { + RichText toRichTextWithIcon() { + // Create the base TextSpan with the text data and style from the Text widget + return RichText( + text: TextSpan( + style: this.style, // Inherit the text style + children: [ + WidgetSpan( + child: Text(" SAR ", style: TextStyle(fontFamily: "SaudiRiyal")), + ), + TextSpan( + text: this.data, // Add the original text + style: this.style, // Inherit the text style + ), + ], + ), + ); + } +} + /* userBoard.asMap().map((i, element) => MapEntry(i, Stack( GestureDetector(onTap: () { diff --git a/lib/uitl/utils_new.dart b/lib/uitl/utils_new.dart new file mode 100644 index 00000000..696a778d --- /dev/null +++ b/lib/uitl/utils_new.dart @@ -0,0 +1,601 @@ +import 'dart:ui'; + +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +Decoration appGradient = BoxDecoration( + gradient: LinearGradient( + colors: [ + Color(0xFFFDCA46F), + Color(0xFFFA47E5D), + ], + begin: Alignment.centerLeft, + end: Alignment.centerRight, + ), +); + +Color getColorFromHex(String hexColor) { + hexColor = hexColor.toUpperCase().replaceAll('#', ''); + + if (hexColor.length == 6) { + hexColor = 'FF' + hexColor; + } + + return Color(int.parse(hexColor, radix: 16)); +} + +Widget getPaymentMethods() { + return Container( + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Image.asset("assets/images/new/payment/Mada.png", width: 40, height: 40), + Image.asset("assets/images/new/payment/tamara_en.png", width: 40, height: 40), + Image.asset("assets/images/new/payment/visa.png", width: 40, height: 40), + Image.asset("assets/images/new/payment/Mastercard.png", width: 50, height: 40), + Image.asset("assets/images/new/payment/Apple_Pay.png", width: 40, height: 40), + ], + ), + ); +} + +Widget getNoDataWidget(BuildContext context) { + return Container( + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SvgPicture.asset('assets/images/new/not_found.svg', width: 110.0, height: 110.0), + Container(margin: EdgeInsets.only(top: 15.0), child: Text(TranslationBase.of(context).noResultFound, style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Color(0xFFBABABA)))), + ], + ), + ), + ); +} + +spacerVertical(double v) { + return Container( + height: v, + width: double.infinity, + ); +} + +spacerHorizontal(double v) { + return Container( + height: v, + width: v, + ); +} + +spacer() { + return SizedBox( + height: 8, + ); +} + +Future navigateTo(context, page) async { + return await Navigator.push(context, MaterialPageRoute(builder: (context) => page)); +} + +// Future navigateToReplace(context, page) async { +// Navigator.pushReplacement(context, FadeRouteBuilder(page: page)); +// } + +InputDecoration txtField(String label) { + return new InputDecoration( + border: InputBorder.none, + focusedBorder: InputBorder.none, + enabledBorder: InputBorder.none, + errorBorder: InputBorder.none, + hintText: label, + hintStyle: TextStyle(color: Colors.grey), + disabledBorder: InputBorder.none, + contentPadding: EdgeInsets.only(left: 15, right: 15), + ); +} + +InputDecoration txtField3(String label) { + return new InputDecoration( + border: InputBorder.none, + focusedBorder: InputBorder.none, + enabledBorder: InputBorder.none, + errorBorder: InputBorder.none, + hintText: label, + disabledBorder: InputBorder.none, + counterText: "", + contentPadding: EdgeInsets.only(left: 5, right: 5), + ); +} + +InputDecoration txtFieldSearch(String label) { + return new InputDecoration( + border: InputBorder.none, + suffixIcon: Icon(Icons.clear), + disabledBorder: InputBorder.none, + contentPadding: EdgeInsets.only(left: 15, right: 15), + ); +} + +Widget circularAviator( + double s, { + Color? bcColor, + Color? brColor, + Color? iconColor, + double? borderWidth, + IconData? icon, + double elevation = 4, +}) { + return Card( + shape: cardRadiusNew(2000), + color: Colors.transparent, + elevation: elevation, + child: Container( + width: s, + height: s, + decoration: containerColorRadiusBorderWidth( + bcColor == null ? Colors.grey[200]! : bcColor, + 2000, + brColor == null ? Colors.blueGrey[800]! : brColor, + borderWidth == null ? 2 : borderWidth, + ), + child: Icon( + icon == null ? Icons.person : icon, + size: s / 1.7, + color: iconColor == null ? Colors.grey[800] : iconColor, + ), + ), + ); +} + +Widget circularImage(String im, double width, double height) { + return new Container( + width: 190.0, + height: 190.0, + decoration: new BoxDecoration( + shape: BoxShape.circle, + image: new DecorationImage( + fit: BoxFit.fill, + image: new AssetImage(im), + ), + ), + ); +} + +circularImage2(String im, double width, double height) { + return new Container( + width: width, + height: height, + decoration: new BoxDecoration( + shape: BoxShape.circle, + image: new DecorationImage( + fit: BoxFit.fill, + image: new AssetImage(im), + ), + ), + ); +} + +Widget mDivider(Color color) { + return Divider( + // width: double.infinity, + height: 1, + color: color, + ); +} + +Widget mFlex(int f) { + return Flexible( + flex: f, + child: Container(), + ); +} + +mOverlay(double op) { + return Opacity( + opacity: op, + child: Container( + color: Colors.black, + width: double.infinity, + height: double.infinity, + ), + ); +} + +Widget mHeight(double h) { + return Container( + height: h, + ); +} + +Widget mWidth(double w) { + return Container( + width: w, + ); +} + +RoundedRectangleBorder buttonShape() { + return RoundedRectangleBorder( + borderRadius: BorderRadius.circular(14.0), + ); +} + +Decoration containerRadiusWithGradient(double radius, {Color? color1, Color? color2}) { + return BoxDecoration( + borderRadius: BorderRadius.circular(radius), + gradient: LinearGradient( + colors: [ + color1 ?? Color(0xFFF71787E), + color2 ?? Color(0xFFF2B353E), + ], + begin: Alignment.centerLeft, + end: Alignment.centerRight, + ), + ); +} + +Decoration containerBottomRightRadiusWithGradient(double radius, {Color? darkColor, Color? lightColor}) { + return BoxDecoration( + borderRadius: BorderRadius.only(bottomRight: Radius.circular(radius)), + gradient: LinearGradient( + colors: [ + darkColor == null ? Color(0xFFF2B353E) : darkColor, + lightColor == null ? Color(0xFFF71787E) : lightColor, + ], + begin: Alignment.topCenter, + end: Alignment.bottomRight, + ), + ); +} + +Decoration containerBottomRightRadiusWithGradientForAr(double radius, {Color? darkColor, Color? lightColor}) { + return BoxDecoration( + borderRadius: BorderRadius.only(bottomLeft: Radius.circular(radius)), + gradient: LinearGradient( + colors: [ + lightColor == null ? Color(0xFFF71787E) : lightColor, + darkColor == null ? Color(0xFFF2B353E) : darkColor, + ], + begin: Alignment.topCenter, + end: Alignment.bottomRight, + ), + ); +} + +Decoration containerRadiusWithGradientServices( + double radius, { + Color? darkColor, + Color? lightColor, + bool isProduct = false, + bool prescriptionRequired = false, + bool isEnglish = true, +}) { + return BoxDecoration( + borderRadius: !isProduct || !prescriptionRequired + ? BorderRadius.all(Radius.circular(radius)) + : isEnglish + ? BorderRadius.only( + topLeft: Radius.circular(26), + ) + : BorderRadius.only( + topRight: Radius.circular(26), + ), + gradient: LinearGradient( + colors: [ + darkColor == null ? Color(0xFF2B353E) : darkColor, + lightColor == null ? Color(0xFF71787E) : lightColor, + ], + begin: Alignment.centerRight, + end: Alignment.topLeft, + ), + ); +} + +Decoration containerBottomRightRadiusWithGradientBorder(double radius, {Color? darkColor, Color? lightColor, Color borderColor = Colors.transparent, double w = 0}) { + return BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(radius)), + border: Border.all( + width: w, // + color: borderColor // <--- border width here + ), + gradient: LinearGradient( + colors: [ + darkColor == null ? Color(0xFFF2B353E) : darkColor, + lightColor == null ? Color(0xFFF71787E) : lightColor, + ], + begin: Alignment.topCenter, + end: Alignment.bottomRight, + ), + ); +} + +Decoration containerRadius(Color background, double radius) { + return BoxDecoration( + color: background, + boxShadow: [ + BoxShadow( + color: Color(0xff000000).withOpacity(.05), + blurRadius: 27, + offset: Offset(0, -3), + ), + ], + border: Border.all( + width: 1, // + color: background // <--- border width here + ), + borderRadius: BorderRadius.circular(radius), + ); +} + +Decoration containerColorRadiusBorder(Color background, double radius, Color color) { + return BoxDecoration( + color: background, + border: Border.all( + width: 1, // + color: color // <--- border width here + ), + borderRadius: BorderRadius.circular(radius), + ); +} + +Decoration containerColorRadiusBorderWidth(Color background, double radius, Color color, double w) { + return BoxDecoration( + color: background, + border: Border.all( + width: w, // + color: color // <--- border width here + ), + borderRadius: BorderRadius.circular(radius), + ); +} + +Decoration containerColorRadiusBorderWidthCircular(Color background, double radius, Color color, double w) { + return BoxDecoration( + color: background, + border: Border.all( + width: w, // + color: color // <--- border width here + ), + // borderRadius: BorderRadius.circular(radius), + shape: BoxShape.circle, + ); +} + +Decoration containerColorRadiusRight(Color background, double radius) { + return BoxDecoration( + color: background, + borderRadius: BorderRadius.only(topRight: Radius.circular(radius), bottomRight: Radius.circular(radius)), + ); +} + +Decoration containerColorRadiusLeft(Color background, double radius) { + return BoxDecoration( + color: background, + borderRadius: BorderRadius.only(topLeft: Radius.circular(radius), bottomLeft: Radius.circular(radius)), + ); +} + +Decoration containerColorRadiusRightBorder(Color background, double radius, double w) { + return BoxDecoration( + color: background, + border: Border.all( + width: w, // + color: Colors.white // <--- border width here + ), + borderRadius: BorderRadius.only(topRight: Radius.circular(radius), bottomRight: Radius.circular(radius)), + ); +} + +Decoration containerColorRadiusRightBorderc(Color background, double radius, double w, Color borderColor) { + return BoxDecoration( + color: background, + border: Border.all( + width: w, // + color: borderColor // <--- border width here + ), + borderRadius: BorderRadius.circular(radius), + ); +} + +Decoration containerColorRadiusTop(Color color, double radius) { + return BoxDecoration( + color: color, + borderRadius: BorderRadius.only( + topLeft: Radius.circular(radius), + topRight: Radius.circular(radius), + ), + ); +} + +Decoration containerColorRadiusBottom(Color color, double radius) { + return BoxDecoration( + color: color, + borderRadius: BorderRadius.only( + bottomLeft: Radius.circular(radius), + bottomRight: Radius.circular(radius), + ), + ); +} + +Decoration containerColorRadiusLeftBorder(Color background, double radius, double w) { + return BoxDecoration( + color: background, + border: Border.all( + width: w, // + color: Colors.white // <--- border width here + ), + borderRadius: BorderRadius.only(topLeft: Radius.circular(radius), bottomLeft: Radius.circular(radius)), + ); +} + +BoxDecoration cardRadius(double radius, {Color? color, double? elevation}) { + return BoxDecoration( + shape: BoxShape.rectangle, + color: color ?? Colors.white, + borderRadius: BorderRadius.all( + Radius.circular(radius), + ), + boxShadow: [ + BoxShadow( + color: Color(0xff000000).withOpacity(.05), + //spreadRadius: 5, + blurRadius: elevation ?? 27, + offset: Offset(-2, 3), + ), + ], + ); +} + +OutlinedBorder cardRadiusNew(double radius) { + return RoundedRectangleBorder( + side: BorderSide(color: Colors.transparent, width: 0), + borderRadius: BorderRadius.all(Radius.circular(radius)), + ); +} + +ShapeBorder cardRadiusTop(double radius) { + return RoundedRectangleBorder( + side: BorderSide(color: Colors.transparent, width: 0), + borderRadius: BorderRadius.only(topLeft: Radius.circular(radius), topRight: Radius.circular(radius)), + ); +} + +ShapeBorder cardRadiusTop2(double radius) { + return RoundedRectangleBorder( + borderRadius: BorderRadius.only(topLeft: Radius.circular(radius), topRight: Radius.circular(radius)), + ); +} + +ShapeBorder cardRadiusBottom(double radius) { + return RoundedRectangleBorder( + borderRadius: BorderRadius.only(bottomLeft: Radius.circular(radius), bottomRight: Radius.circular(radius)), + ); +} + +ShapeBorder cardRadiusWithoutBorder(double radius) { + return RoundedRectangleBorder( + side: BorderSide(color: Colors.transparent, width: 1), + borderRadius: BorderRadius.circular(radius), + ); +} + +ShapeBorder cardRadiusWithBorder(double radius) { + return RoundedRectangleBorder( + side: BorderSide(color: Colors.grey, width: 1), + borderRadius: BorderRadius.circular(radius), + ); +} + +ShapeBorder cardRadiusBorder(double radius, double w) { + return RoundedRectangleBorder( + side: BorderSide(color: Colors.transparent, width: w), + borderRadius: BorderRadius.circular(radius), + ); +} + +// String properRound(double val, int places) { +// double mod = pow(10.0, places); +// double result = ((val * mod).round().toDouble() / mod); +// return result.toString(); +// } +// +// double properRoundDouble(double val, int places) { +// double mod = pow(10.0, places); +// double result = ((val * mod).round().toDouble() / mod); +// return result; +// } +//var cardShape = RoundedRectangleBorder( +// side: BorderSide(color: Colors.white70, width: 1), +// borderRadius: BorderRadius.circular(10), +//); + +//await Navigator.of(context).push(new MaterialPageRoute( +//builder: (BuildContext context) { +//return AdminTeamAvaluatePage(widget.competitionID, data); +//}, +//)); +//setState(() {}); + +Color getColor(String selectedColor) { + try { + if ("black" == selectedColor) { + return Colors.black; + } else if ("red" == selectedColor) { + return Colors.red; + } else if ("blueAccent" == selectedColor) { + return Colors.blueAccent; + } else if ("blue" == selectedColor) { + return Colors.blue; + } else if ("blueGrey" == selectedColor) { + return Colors.blueGrey; + } else if ("yellow" == selectedColor) { + return Colors.yellow; + } else if ("black54" == selectedColor) { + return Colors.black54; + } else if ("green" == selectedColor) { + return Colors.green; + } else if ("orange" == selectedColor) { + return Colors.orange; + } else if ("deepOrange" == selectedColor) { + return Colors.deepOrange; + } else { + return Colors.black; + } + } catch (e) { + return Colors.black; + } +} + +TextAlign getTextAlign(String textAlign) { + try { + if (textAlign == "left") { + return TextAlign.left; + } else if (textAlign == "right") { + return TextAlign.right; + } else if (textAlign == "center") { + return TextAlign.center; + } else if (textAlign == "justify") { + return TextAlign.justify; + } else { + return TextAlign.left; + } + } catch (e) { + print("fffff " + e.toString()); + return TextAlign.left; + } +} + +FontWeight getFontWeight(String fontWeight) { + if (fontWeight == null) { + return FontWeight.normal; + } else if (fontWeight == "bold") { + return FontWeight.bold; + } else { + return FontWeight.normal; + } +} + +FontStyle getFontStyle(String fontStyle) { + try { + if (fontStyle == null) { + return FontStyle.normal; + } else if (fontStyle == "italian") { + return FontStyle.italic; + } else { + return FontStyle.normal; + } + } catch (e) { + return FontStyle.normal; + } +} + +bool timeCalculator(int startHour, int startMint, int endHour, int endMint) { + DateTime now = DateTime.now(); + DateTime startDate = DateTime(now.year, now.month, now.day, startHour, startHour); + DateTime endDate = DateTime(now.year, now.month, now.day, endHour, endMint); + if (startDate.isBefore(now) && endDate.isAfter(now)) + return true; + else + return false; +} diff --git a/lib/uitl/whatsapp_method_channel.dart b/lib/uitl/whatsapp_method_channel.dart new file mode 100644 index 00000000..068e123e --- /dev/null +++ b/lib/uitl/whatsapp_method_channel.dart @@ -0,0 +1,34 @@ +import 'dart:async'; + +import 'package:flutter/services.dart'; + +class WhatsappMethodChannel { + static const MethodChannel _channel = MethodChannel('whats_app_otp'); + + FutureOr handleHandShake() async { + try { + await _channel.invokeMethod("performHandShake"); + + } on PlatformException catch (e) { + print("Failed to launch PenguinIn: '${e.message}'."); + } + } + + Future isWhatsAppInstalled() async { + try { + return await _channel.invokeMethod("isWhatsAppInstalled"); + } catch (e) { + return false; + } + } + + Future startListening() async { + try{ + String code = await _channel.invokeMethod("startListening"); + print("the code in flutter is ${code}"); + return code; + }catch(e){ + return ""; + } + } +} \ No newline at end of file diff --git a/lib/vital_signs/vital_sign.dart b/lib/vital_signs/vital_sign.dart new file mode 100644 index 00000000..01fbcec8 --- /dev/null +++ b/lib/vital_signs/vital_sign.dart @@ -0,0 +1,70 @@ +// import 'package:flutter/material.dart'; +// import 'package:vital_sign_camera/vital_sign_camera.dart'; +// +// class VitalSigns extends StatefulWidget { +// const VitalSigns({super.key}); +// +// @override +// State createState() => _VitalSignState(); +// } +// +// class _VitalSignState extends State { +// late final VitalSignCameraController _vitalSignCameraController; +// late Future cameraDevice; +// +// @override +// void initState() { +// super.initState(); +// cameraDevice = getFrontCamera(); +// } +// +// double? _heartRate; +// +// Future getFrontCamera() async { +// if (CameraPermissionStatus.authorized != await requestCameraPermission()) { +// return null; +// } +// return queryCameraDevice(CameraPosition.front); +// } +// +// @override +// Widget build(BuildContext context) { +// return Scaffold( +// body: Stack(children: [ +// VitalSignCamera( +// onCreated: _onVitalSignCameraCreated, +// isActive: true, +// userInfo: UserInfo( +// age: 30, gender: Gender.male, userId: '__YOUR_USER_ID__'), +// config: VitalSignCameraConfig(apiKey: '__YOUR_API_KEY__'), +// device: cameraDevice, +// onVideoFrameProcessed: _onVideoFrameProcessed), +// Center( +// child: Column( +// mainAxisAlignment: MainAxisAlignment.center, +// children: [ +// ElevatedButton( +// onPressed: () { +// setState(() { +// _vitalSignCameraController.startScanning(); +// }); +// }, +// child: const Text('start')), +// Text('Heart rate: $_heartRate'), +// ], +// ), +// ), +// ]), +// ); +// } +// +// void _onVideoFrameProcessed(VideoFrameProcessedEvent event) { +// // setState(() { +// // _heartRate = event.healthResult?.health?.vitalSigns.heartRate; +// // }); +// } +// +// void _onVitalSignCameraCreated(VitalSignCameraController controller) { +// _vitalSignCameraController = controller; +// } +// } \ No newline at end of file diff --git a/lib/widgets/AnimatedTextFields.dart b/lib/widgets/AnimatedTextFields.dart index b4ad5f65..3719f3c9 100644 --- a/lib/widgets/AnimatedTextFields.dart +++ b/lib/widgets/AnimatedTextFields.dart @@ -24,9 +24,9 @@ Interval _getInternalInterval( class AnimatedTextFormField extends StatefulWidget { AnimatedTextFormField({ - Key key, + Key? key, this.interval = const Interval(0.0, 1.0), - @required this.width, + required this.width, this.loadingController, this.inertiaController, this.inertiaDirection, @@ -47,35 +47,35 @@ class AnimatedTextFormField extends StatefulWidget { super(key: key); final Interval interval; - final AnimationController loadingController; - final AnimationController inertiaController; + final AnimationController? loadingController; + final AnimationController? inertiaController; final double width; final bool enabled; - final String labelText; - final Widget prefixIcon; - final Widget suffixIcon; - final TextInputType keyboardType; - final TextInputAction textInputAction; + final String? labelText; + final Widget? prefixIcon; + final Widget? suffixIcon; + final TextInputType? keyboardType; + final TextInputAction? textInputAction; final bool obscureText; - final TextEditingController controller; - final FocusNode focusNode; - final FormFieldValidator validator; - final ValueChanged onFieldSubmitted; - final FormFieldSetter onSaved; - final TextFieldInertiaDirection inertiaDirection; + final TextEditingController? controller; + final FocusNode? focusNode; + final FormFieldValidator? validator; + final ValueChanged? onFieldSubmitted; + final FormFieldSetter? onSaved; + final TextFieldInertiaDirection? inertiaDirection; @override _AnimatedTextFormFieldState createState() => _AnimatedTextFormFieldState(); } class _AnimatedTextFormFieldState extends State { - Animation scaleAnimation; - Animation sizeAnimation; - Animation suffixIconOpacityAnimation; + late Animation scaleAnimation; + late Animation sizeAnimation; + late Animation suffixIconOpacityAnimation; - Animation fieldTranslateAnimation; - Animation iconRotationAnimation; - Animation iconTranslateAnimation; + late Animation fieldTranslateAnimation; + late Animation iconRotationAnimation; + late Animation iconTranslateAnimation; @override void initState() { @@ -140,7 +140,7 @@ class _AnimatedTextFormFieldState extends State { begin: 48.0, end: widget.width, ).animate(CurvedAnimation( - parent: loadingController, + parent: loadingController!, curve: _getInternalInterval( .2, 1.0, interval.begin, interval.end, Curves.linearToEaseOut), reverseCurve: Curves.easeInExpo, @@ -194,13 +194,13 @@ class _AnimatedTextFormFieldState extends State { borderSide: new BorderSide(), ), labelText: widget.labelText, - prefixIcon: _buildInertiaAnimation(widget.prefixIcon), + prefixIcon: _buildInertiaAnimation(widget.prefixIcon!), suffixIcon: _buildInertiaAnimation(widget.loadingController != null ? FadeTransition( - opacity: suffixIconOpacityAnimation, - child: widget.suffixIcon, + opacity: suffixIconOpacityAnimation!, + child: widget.suffixIcon!, ) - : widget.suffixIcon), + : widget.suffixIcon!), ); } @@ -251,9 +251,9 @@ class _AnimatedTextFormFieldState extends State { class AnimatedPasswordTextFormField extends StatefulWidget { AnimatedPasswordTextFormField({ - Key key, + Key? key, this.interval = const Interval(0.0, 1.0), - @required this.animatedWidth, + required this.animatedWidth, this.loadingController, this.inertiaController, this.inertiaDirection, @@ -271,19 +271,19 @@ class AnimatedPasswordTextFormField extends StatefulWidget { super(key: key); final Interval interval; - final AnimationController loadingController; - final AnimationController inertiaController; + final AnimationController? loadingController; + final AnimationController? inertiaController; final double animatedWidth; final bool enabled; - final String labelText; - final TextInputType keyboardType; - final TextInputAction textInputAction; - final TextEditingController controller; - final FocusNode focusNode; - final FormFieldValidator validator; - final ValueChanged onFieldSubmitted; - final FormFieldSetter onSaved; - final TextFieldInertiaDirection inertiaDirection; + final String? labelText; + final TextInputType? keyboardType; + final TextInputAction? textInputAction; + final TextEditingController? controller; + final FocusNode? focusNode; + final FormFieldValidator? validator; + final ValueChanged? onFieldSubmitted; + final FormFieldSetter? onSaved; + final TextFieldInertiaDirection? inertiaDirection; @override _AnimatedPasswordTextFormFieldState createState() => diff --git a/lib/widgets/CounterView.dart b/lib/widgets/CounterView.dart index 6ba77c15..039ba757 100644 --- a/lib/widgets/CounterView.dart +++ b/lib/widgets/CounterView.dart @@ -11,11 +11,11 @@ class StepperView extends StatefulWidget { final int initialNumber; final int maxNumber; final int minNumber; - final StepperCallbackFuture counterCallback; - final Function increaseCallback; - final Function decreaseCallback; + final StepperCallbackFuture? counterCallback; + final Function? increaseCallback; + final Function? decreaseCallback; - StepperView({this.initialNumber = 1, this.minNumber = 1, this.maxNumber, @required this.counterCallback, this.increaseCallback, this.decreaseCallback, this.height = 25, @required this.foregroundColor, @required this.backgroundColor, this.buttonPadding = 1}){ + StepperView({this.initialNumber = 1, this.minNumber = 1, required this.maxNumber, @required this.counterCallback, this.increaseCallback, this.decreaseCallback, this.height = 25, required this.foregroundColor, required this.backgroundColor, this.buttonPadding = 1}){ assert((this.initialNumber >= this.minNumber && this.initialNumber <= this.maxNumber)); } @override @@ -23,15 +23,15 @@ class StepperView extends StatefulWidget { } class _StepperViewState extends State { - int _currentCount; - StepperCallbackFuture _counterCallback; - Function _increaseCallback; - Function _decreaseCallback; + late int _currentCount; + late StepperCallbackFuture _counterCallback; + late Function _increaseCallback; + late Function _decreaseCallback; @override void initState() { _currentCount = widget.initialNumber ?? 1; - _counterCallback = widget.counterCallback; + _counterCallback = widget.counterCallback!; _increaseCallback = widget.increaseCallback ?? () {}; _decreaseCallback = widget.decreaseCallback ?? () {}; super.initState(); @@ -52,7 +52,7 @@ class _StepperViewState extends State { mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ _createDecrementButton( - (_currentCount > widget.minNumber) ? () => _decrement() : null, + ((_currentCount > widget.minNumber) ? () => _decrement() : null) as VoidCallback, ), Container( width: 25, @@ -69,7 +69,7 @@ class _StepperViewState extends State { ) ), _createIncrementButton( - (_currentCount < widget.maxNumber) ? () => _increment() : null + ((_currentCount < widget.maxNumber) ? () => _increment() : null) as VoidCallback ), ], ), @@ -77,7 +77,7 @@ class _StepperViewState extends State { } void _increment() async{ - doInc({@required bool can}){ + doInc({required bool can}){ if(can) setState(() { _currentCount++; @@ -98,7 +98,7 @@ class _StepperViewState extends State { } void _decrement() async{ - doDec({@required bool can}){ + doDec({required bool can}){ if(can) setState(() { _currentCount--; @@ -117,7 +117,7 @@ class _StepperViewState extends State { } } - Widget _createIncrementButton(Function onPressed,) { + Widget _createIncrementButton(VoidCallback onPressed,) { return Stack( children: [ RawMaterialButton( @@ -152,7 +152,7 @@ class _StepperViewState extends State { ); } - Widget _createDecrementButton(Function onPressed) { + Widget _createDecrementButton(VoidCallback onPressed) { return Stack( children: [ RawMaterialButton( diff --git a/lib/widgets/Loader/gif_loader_container.dart b/lib/widgets/Loader/gif_loader_container.dart index b7a20339..ccc986c7 100644 --- a/lib/widgets/Loader/gif_loader_container.dart +++ b/lib/widgets/Loader/gif_loader_container.dart @@ -1,43 +1,53 @@ import 'package:flutter/cupertino.dart'; -import 'package:flutter_gifimage/flutter_gifimage.dart'; +import 'package:gif_view/gif_view.dart'; class GifLoaderContainer extends StatefulWidget { + bool barrierDismissible; + + GifLoaderContainer({this.barrierDismissible = true}); + @override _GifLoaderContainerState createState() => _GifLoaderContainerState(); } -class _GifLoaderContainerState extends State - with TickerProviderStateMixin { - GifController controller1; +class _GifLoaderContainerState extends State with TickerProviderStateMixin { + late GifController controller; @override void initState() { - controller1 = GifController(vsync: this); + controller = GifController(); WidgetsBinding.instance.addPostFrameCallback((_) { - controller1.repeat( - min: 0, max: 11, period: Duration(milliseconds: 750), reverse: true); + try { + controller = GifController(autoPlay: true, onFinish: () {}, loop: true); + // controller.repeat(min: 0, max: 11, period: Duration(milliseconds: 750), reverse: true); + } catch (ex) {} }); super.initState(); } @override void dispose() { - controller1.dispose(); + controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { - return Center( - //progress-loading.gif + return WillPopScope( + onWillPop: () async { + return widget.barrierDismissible; + }, + child: Center( + //progress-loading.gif child: Container( // margin: EdgeInsets.only(bottom: 40), - child: GifImage( - controller: controller1, - image: AssetImage( - "assets/images/progress-loading-red.gif"), //NetworkImage("http://img.mp.itc.cn/upload/20161107/5cad975eee9e4b45ae9d3c1238ccf91e.jpg"), + child: GifView( + controller: controller, + image: AssetImage("assets/images/progress-loading-red.gif"), //NetworkImage("http://img.mp.itc.cn/upload/20161107/5cad975eee9e4b45ae9d3c1238ccf91e.jpg"), ), - )); + ), + ), + ); } -} \ No newline at end of file +} diff --git a/lib/widgets/LoadingButton.dart b/lib/widgets/LoadingButton.dart index 46983903..6a497198 100644 --- a/lib/widgets/LoadingButton.dart +++ b/lib/widgets/LoadingButton.dart @@ -1,26 +1,25 @@ +import 'dart:math'; + import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; -import 'dart:math'; - -import 'data_display/text.dart'; class AnimatedButton extends StatefulWidget { AnimatedButton({ - Key key, - @required this.text, - @required this.onPressed, - @required this.controller, + Key? key, + required this.text, + required this.onPressed, + required this.controller, this.textColor, - this.loadingColor, + required this.loadingColor, this.color, }) : super(key: key); final String text; - final Color color; - final Color textColor; + final Color? color; + final Color? textColor; final Color loadingColor; - final Function onPressed; + final VoidCallback? onPressed; final AnimationController controller; @override @@ -29,18 +28,18 @@ class AnimatedButton extends StatefulWidget { class _AnimatedButtonState extends State with SingleTickerProviderStateMixin { - Animation _sizeAnimation; - Animation _textOpacityAnimation; - Animation _buttonOpacityAnimation; - Animation _ringThicknessAnimation; - Animation _ringOpacityAnimation; - Animation _colorAnimation; + late Animation _sizeAnimation; + late Animation _textOpacityAnimation; + late Animation _buttonOpacityAnimation; + late Animation _ringThicknessAnimation; + late Animation _ringOpacityAnimation; + late Animation _colorAnimation; var _isLoading = false; var _hover = false; var _width = 120.0; - Color _color; - Color _loadingColor; + late Color _color; + late Color _loadingColor; static const _height = 40.0; static const _loadingCircleRadius = _height / 2; @@ -62,21 +61,21 @@ class _AnimatedButtonState extends State _buttonOpacityAnimation = Tween(begin: 1.0, end: 0.0).animate(CurvedAnimation( - parent: widget.controller, - curve: Threshold(.65), - )); + parent: widget.controller, + curve: Threshold(.65), + )); _ringThicknessAnimation = Tween(begin: _loadingCircleRadius, end: _loadingCircleThickness) .animate(CurvedAnimation( - parent: widget.controller, - curve: Interval(.65, .85), - )); + parent: widget.controller, + curve: Interval(.65, .85), + )); _ringOpacityAnimation = Tween(begin: 1.0, end: 0.0).animate(CurvedAnimation( - parent: widget.controller, - curve: Interval(.85, 1.0), - )); + parent: widget.controller, + curve: Interval(.85, 1.0), + )); widget.controller.addStatusListener(handleStatusChanged); } @@ -92,10 +91,11 @@ class _AnimatedButtonState extends State final theme = Theme.of(context); final buttonTheme = theme.floatingActionButtonTheme; - _color = widget.color ?? buttonTheme.backgroundColor; - _loadingColor = widget.loadingColor ?? theme.accentColor; + _color = (widget.color ?? buttonTheme.backgroundColor)!; + _loadingColor = widget.loadingColor ?? theme.colorScheme.secondary; _colorAnimation = ColorTween( + begin: _color, end: _loadingColor, ).animate( @@ -138,14 +138,15 @@ class _AnimatedButtonState extends State /// sets width and size animation void _updateWidth() { final theme = Theme.of(context); - final fontSize = theme.textTheme.button.fontSize; + // final fontSize = theme.textTheme.button!.fontSize; + final fontSize = 12.0; final renderParagraph = RenderParagraph( TextSpan( text: widget.text, style: TextStyle( fontSize: fontSize, - fontWeight: theme.textTheme.button.fontWeight, - letterSpacing: theme.textTheme.button.letterSpacing, + fontWeight: FontWeight.normal, + letterSpacing: 0.6, ), ), textDirection: TextDirection.ltr, @@ -156,12 +157,14 @@ class _AnimatedButtonState extends State // text width based on fontSize, plus 45.0 for padding var textWidth = - renderParagraph.getMinIntrinsicWidth(fontSize).ceilToDouble() + 45.0; + renderParagraph.getMinIntrinsicWidth(fontSize!).ceilToDouble() + 45.0; // button width is min 120.0 and max 240.0 _width = textWidth > 120.0 && textWidth < 240.0 ? textWidth - : textWidth >= 240.0 ? 240.0 : 120.0; + : textWidth >= 240.0 + ? 240.0 + : 120.0; _sizeAnimation = Tween(begin: 1.0, end: _height / _width) .animate(CurvedAnimation( @@ -191,17 +194,18 @@ class _AnimatedButtonState extends State animation: _colorAnimation, builder: (context, child) => Material( shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(_height/2) - ), + borderRadius: BorderRadius.circular(_height / 2)), color: _colorAnimation.value, child: child, shadowColor: _color, - elevation: !_isLoading - ? (_hover ? buttonTheme.highlightElevation : buttonTheme.elevation) - : 0, + elevation: (_isLoading == false) + ? (_hover == true + ? buttonTheme.highlightElevation ?? 0.0 + : buttonTheme.elevation ?? 0.0) + : 0.0, ), child: InkWell( - onTap: !_isLoading ? widget.onPressed : null, + onTap: !_isLoading ? widget!.onPressed : null, splashColor: buttonTheme.splashColor, customBorder: buttonTheme.shape, onHighlightChanged: (value) => setState(() => _hover = value), @@ -233,7 +237,7 @@ class _AnimatedButtonState extends State child: AnimatedBuilder( animation: _ringThicknessAnimation, builder: (context, child) => Ring( - color: widget.loadingColor, + color: widget!.loadingColor, size: _height, thickness: _ringThicknessAnimation.value, ), @@ -257,8 +261,8 @@ class _AnimatedButtonState extends State class Ring extends StatelessWidget { Ring({ - Key key, - this.color, + Key? key, + required this.color, this.size = 40.0, this.thickness = 2.0, this.value = 1.0, @@ -279,23 +283,22 @@ class Ring extends StatelessWidget { child: thickness == 0 ? null : CircularProgressIndicator( - valueColor: AlwaysStoppedAnimation(color), - strokeWidth: thickness, - value: value, - ), + valueColor: AlwaysStoppedAnimation(color), + strokeWidth: thickness, + value: value, + ), ); } } - enum AnimatedTextRotation { up, down } /// https://medium.com/flutter-community/flutter-challenge-3d-bottom-navigation-bar-48952a5fd996 class AnimatedText extends StatefulWidget { AnimatedText({ - Key key, - @required this.text, - this.style, + Key? key, + required this.text, + required this.style, this.textRotation = AnimatedTextRotation.up, }) : super(key: key); @@ -314,12 +317,11 @@ class _AnimatedTextState extends State var _layoutHeight = 0.0; final _textKey = GlobalKey(); - Animation _animation; - AnimationController _controller; + late Animation _animation; + late AnimationController _controller; double get radius => _layoutHeight / 2; - @override void initState() { super.initState(); @@ -337,7 +339,7 @@ class _AnimatedTextState extends State _oldText = widget.text; WidgetsBinding.instance.addPostFrameCallback((_) { - setState(() => _layoutHeight = getWidgetSize(_textKey)?.height); + setState(() => _layoutHeight = getWidgetSize(_textKey)!.height); }); } @@ -370,7 +372,7 @@ class _AnimatedTextState extends State if (kIsWeb) { return Matrix4.identity(); } - return Matrix4.identity()..setEntry(3, 2, .006); + return Matrix4.identity()..setEntry(3, 2, .006); } Matrix4 _getFrontSideUp(double value) { @@ -452,12 +454,14 @@ class _AnimatedTextState extends State ); } - // Helpers double toRadian(double degree) => degree * pi / 180; - double lerp(double start, double end, double percent) => (start + percent * (end - start)); - Size getWidgetSize(GlobalKey key) { - final RenderBox renderBox = key.currentContext?.findRenderObject(); - return renderBox?.size; + + double lerp(double start, double end, double percent) => + (start + percent * (end - start)); + + Size? getWidgetSize(GlobalKey key) { + return key.currentContext!.size; + //return renderBox?.size; } -} \ No newline at end of file +} diff --git a/lib/widgets/TextFieldInertiaDirection.java b/lib/widgets/TextFieldInertiaDirection.java index 627bf406..daaa0229 100644 --- a/lib/widgets/TextFieldInertiaDirection.java +++ b/lib/widgets/TextFieldInertiaDirection.java @@ -1,8 +1,6 @@ -import 'dart:math'; - -import 'package:flutter/gestures.dart'; -import 'package:flutter/material.dart'; -import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +'dart:math'; + 'package:flutter/gestures.dart'; + 'package:flutter/material.dart'; 'package:font_awesome_flutter/font_awesome_flutter.dart'; enum TextFieldInertiaDirection { left, diff --git a/lib/widgets/app_map/google_huawei_map.dart b/lib/widgets/app_map/google_huawei_map.dart new file mode 100644 index 00000000..fdd7c739 --- /dev/null +++ b/lib/widgets/app_map/google_huawei_map.dart @@ -0,0 +1,119 @@ +import 'dart:async'; +import 'dart:io'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:google_maps_flutter/google_maps_flutter.dart' as googlemap; + +// import 'package:flutter_hms_gms_availability/flutter_hms_gms_availability.dart'; +import 'package:huawei_hmsavailability/huawei_hmsavailability.dart'; +import 'package:huawei_map/huawei_map.dart' as hmsMap; + +class AppMap extends StatefulWidget { + late dynamic onCameraMove; + late Map initialCamera; + + AppMapState? _state; + Function? onMapCreated; + Function? onCameraIdle; + + AppMap(this.initialCamera, + {required this.onCameraMove, this.onMapCreated, this.onCameraIdle}); + + @override + State createState() => _state = AppMapState(); + + moveTo({required googlemap.CameraPosition cameraPostion}) { + if (_state!.isHuawei) { + final cameraJson = cameraPostion.toMap(); + final camera = hmsMap.CameraPosition.fromMap(cameraJson); + _state?._huaweiMapController + .animateCamera(hmsMap.CameraUpdate.newCameraPosition(camera)); + } else { + _state?.googleMapController.animateCamera( + googlemap.CameraUpdate.newCameraPosition( + cameraPostion as googlemap.CameraPosition)); + } + } +} + +class AppMapState extends State { + bool isHuawei = false; + + Completer _googleMapControllerComp = + Completer(); + late googlemap.GoogleMapController googleMapController; + + Completer _huaweiMapControllerComp = Completer(); + late hmsMap.HuaweiMapController _huaweiMapController; + + late HmsApiAvailability hmsApiAvailability; + + checkIsHuawei() async { + await hmsApiAvailability.isHMSAvailable().then((value) { + isHuawei = value == 0 ? true : false; + hmsMap.HuaweiMapInitializer.initializeMap(); + }); + print(isHuawei); + setState(() {}); + } + + @override + void initState() { + hmsApiAvailability = HmsApiAvailability(); + if (Platform.isAndroid) checkIsHuawei(); + super.initState(); + } + + @override + Widget build(BuildContext context) { + if (isHuawei == null) return CircularProgressIndicator(); + return map(); + } + + Widget map() => isHuawei ? huaweiMap() : googleMap(); + + Widget googleMap() { + return googlemap.GoogleMap( + mapType: googlemap.MapType.normal, + zoomControlsEnabled: true, + myLocationButtonEnabled: true, + myLocationEnabled: true, + initialCameraPosition: + googlemap.CameraPosition.fromMap!(widget.initialCamera)!, + onCameraMove: (camera) { + widget.onCameraMove; + }, + onMapCreated: (googlemap.GoogleMapController controller) { + googleMapController = controller; + _googleMapControllerComp.complete(controller); + widget.onMapCreated!(); + }, + onCameraIdle: () { + print("onCameraIdle"); + widget.onCameraIdle; + }, + ); + } + + Widget huaweiMap() { + return hmsMap.HuaweiMap( + mapType: hmsMap.MapType.normal, + zoomControlsEnabled: false, + myLocationButtonEnabled: true, + myLocationEnabled: true, + initialCameraPosition: + hmsMap.CameraPosition.fromMap(widget.initialCamera), + onCameraMove: (camera) => widget.onCameraMove!, + onMapCreated: (controller) { + _huaweiMapController = controller; + _huaweiMapControllerComp.complete(controller); + widget.onMapCreated!(); + }, + onCameraIdle: () { + print("onCameraIdle"); + widget.onCameraIdle!(); + }, + ); + } +} diff --git a/lib/widgets/avatar/large_avatar.dart b/lib/widgets/avatar/large_avatar.dart index fcfcaa94..e7919aa4 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,42 +14,50 @@ 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, 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 String? name; + final Color red = Colors.red; + final String? url; final bool disableProfileView; + final bool isAppointmentAvatar; final double radius; final double width; final double height; - final GestureTapCallback onTap; + final GestureTapCallback? onTap; Widget _getAvatar() { - if (url != null && url.isNotEmpty && Uri.parse(url).isAbsolute) { + if (url != null && url!.isNotEmpty && Uri.parse(url!).isAbsolute) { 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 && !isAppointmentAvatar) + Container( + child: Icon( + Icons.search, + size: 18, + color: Colors.white, + ), + padding: EdgeInsets.all(6), + decoration: containerRadius(Colors.black.withOpacity(0.3), 200), + ) + ], ), ), ); } else return Center( child: Texts( - name[0].toUpperCase(), + name == null? "" : name![0].toUpperCase(), color: Colors.white, fontSize: 18, )); @@ -55,22 +66,28 @@ class LargeAvatar extends StatelessWidget { @override Widget build(BuildContext context) { return InkWell( - onTap: disableProfileView ? null : onTap, + onTap: disableProfileView + ? null + : isAppointmentAvatar + ? onTap + : () { + showZoomImageDialog(context, url?.trim() ?? ""); + }, child: Container( decoration: BoxDecoration( - gradient: LinearGradient( - begin: Alignment(-1, -1), - end: Alignment(1, 1), - colors: [ - Colors.grey[100], - Colors.grey[800], - ]), - boxShadow: [ - BoxShadow( - color: Color.fromRGBO(0, 0, 0, 0.08), - offset: Offset(0.0, 5.0), - blurRadius: 16.0) - ], + // gradient: LinearGradient( + // begin: Alignment(-1, -1), + // end: Alignment(1, 1), + // colors: [ + // Colors.grey[100], + // Colors.grey[800], + // ]), + // boxShadow: [ + // BoxShadow( + // color: Color.fromRGBO(0, 0, 0, 0.08), + // offset: Offset(0.0, 5.0), + // blurRadius: 16.0) + // ], borderRadius: BorderRadius.all(Radius.circular(radius)), ), width: width, diff --git a/lib/widgets/bottom_navigation/bottom_nav_bar.dart b/lib/widgets/bottom_navigation/bottom_nav_bar.dart index f33e9dd5..c5bd76a3 100644 --- a/lib/widgets/bottom_navigation/bottom_nav_bar.dart +++ b/lib/widgets/bottom_navigation/bottom_nav_bar.dart @@ -1,27 +1,22 @@ -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/Appointments/toDoCountProviderModel.dart'; import 'package:diplomaticquarterapp/pages/BookAppointment/BookingOptions.dart'; import 'package:diplomaticquarterapp/pages/ToDoList/ToDo.dart'; -import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/services/robo_search/event_provider.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; -import 'package:eva_icons_flutter/eva_icons_flutter.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:diplomaticquarterapp/services/robo_search/event_provider.dart'; import 'package:provider/provider.dart'; import '../../d_q_icons_icons.dart'; import 'bottom_navigation_item.dart'; -import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; -import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; class BottomNavBar extends StatefulWidget { - final ValueChanged changeIndex; - final int index; - BottomNavBar({Key key, this.changeIndex, this.index}) : super(key: key); + final ValueChanged? changeIndex; + final int? index; + final bool showHomeIcon; + BottomNavBar({Key? key, this.changeIndex, this.index, this.showHomeIcon = false}) : super(key: key); @override _BottomNavBarState createState() => _BottomNavBarState(); @@ -29,11 +24,11 @@ class BottomNavBar extends StatefulWidget { class _BottomNavBarState extends State { int _index = 0; - ToDoCountProviderModel model; + ToDoCountProviderModel? model; var event = RobotProvider(); _changeIndex(int index) async { - widget.changeIndex(index); - if (_index == 0) { + widget.changeIndex!(index); + if (index == 5) { event.setValue({'isRobotVisible': 'true'}); } } @@ -55,47 +50,54 @@ class _BottomNavBarState extends State { mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ BottomNavigationItem( - icon: DQIcons.my_medical_file, - activeIcon: DQIcons.my_medical_file, + icon: "assets/images/new/bottom_nav/my_file.svg", + activeIcon: "assets/images/new/bottom_nav/my_file.svg", changeIndex: _changeIndex, index: widget.index, currentIndex: 1, - name: TranslationBase.of(context).medicalProfile, + name: TranslationBase.of(context).medicalFile, ), BottomNavigationItem( - icon: DQIcons.family, - activeIcon: DQIcons.family, + icon: "assets/images/new/bottom_nav/family_files.svg", + activeIcon: "assets/images/new/bottom_nav/family_files.svg", changeIndex: _changeIndex, index: widget.index, currentIndex: 3, name: TranslationBase.of(context).myFamily, + isDisabled: projectViewModel.isLoginChild, ), if (widget.index == 0) - Expanded( - child: SizedBox( - height: 50, - child: Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - SizedBox(height: 22), - ], - ), - ), - ), + (widget.showHomeIcon) + ? BottomNavigationItem( + icon: "assets/images/new/bottom_nav/home.svg", + activeIcon: "assets/images/new/bottom_nav/home.svg", + changeIndex: _changeIndex, + index: widget.index, + currentIndex: 2, + name: TranslationBase.of(context).home, + ) + : Expanded(child: SizedBox()), if (widget.index != 0 && projectViewModel.havePrivilege(34)) BottomNavigationItem( - icon: EvaIcons.calendar, - activeIcon: EvaIcons.calendar, + icon: "assets/images/new/bottom_nav/home.svg", + activeIcon: "assets/images/new/bottom_nav/home.svg", changeIndex: _changeIndex, - index: _index, - currentIndex: 2, - name: TranslationBase.of(context).bookAppo, + index: widget.index, + currentIndex: 0, + name: TranslationBase.of(context).home, ), - if (widget.index == 0 && projectViewModel.havePrivilege(34)) + // BottomNavigationItem( + // icon: EvaIcons.calendar, + // activeIcon: EvaIcons.calendar, + // changeIndex: _changeIndex, + // index: _index, + // currentIndex: 2, + // name: TranslationBase.of(context).bookAppo, + // ), + if (/*widget.index == 0 && */ projectViewModel.havePrivilege(34)) BottomNavigationItem( - icon: EvaIcons.calendar, - activeIcon: EvaIcons.calendar, + icon: "assets/images/new/bottom_nav/todo.svg", + activeIcon: "assets/images/new/bottom_nav/todo.svg", changeIndex: _changeIndex, index: widget.index, currentIndex: 4, @@ -103,11 +105,11 @@ class _BottomNavBarState extends State { ), if (projectViewModel.havePrivilege(77)) BottomNavigationItem( - icon: DQIcons.roboticon, - activeIcon: DQIcons.roboticon, + icon: "assets/images/new/bottom_nav/help.svg", + activeIcon: "assets/images/new/bottom_nav/help.svg", changeIndex: _changeIndex, index: widget.index, - currentIndex: 0, + currentIndex: 5, name: TranslationBase.of(context).help, ) ], diff --git a/lib/widgets/bottom_navigation/bottom_navigation_item.dart b/lib/widgets/bottom_navigation/bottom_navigation_item.dart index 9a3bbafe..22c27384 100644 --- a/lib/widgets/bottom_navigation/bottom_navigation_item.dart +++ b/lib/widgets/bottom_navigation/bottom_navigation_item.dart @@ -1,37 +1,35 @@ -import 'package:badges/badges.dart'; +import 'package:badges/badges.dart' as badge_import; 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/Appointments/toDoCountProviderModel.dart'; -import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; import 'package:provider/provider.dart'; import '../../Constants.dart'; class BottomNavigationItem extends StatelessWidget { - final IconData icon; - final IconData activeIcon; - final ValueChanged changeIndex; - final int index; - final int currentIndex; - final String name; + final String? icon; + final String? activeIcon; + final ValueChanged? changeIndex; + final int? index; + final int? currentIndex; + final String? name; + final bool? isDisabled; - AuthenticatedUserObject authenticatedUserObject = - locator(); + late ToDoCountProviderModel toDoProvider; - BottomNavigationItem( - {this.icon, - this.activeIcon, - this.changeIndex, - this.index, - this.currentIndex, - this.name}); + AuthenticatedUserObject authenticatedUserObject = locator(); + + BottomNavigationItem({this.icon, this.activeIcon, this.changeIndex, this.index, this.currentIndex, this.name, this.isDisabled = false}); @override Widget build(BuildContext context) { - var model = Provider.of(context); + toDoProvider = Provider.of(context); + ProjectViewModel projectViewModel = Provider.of(context); return Expanded( child: SizedBox( // height: 72.0, @@ -40,21 +38,23 @@ class BottomNavigationItem extends StatelessWidget { child: InkWell( highlightColor: Colors.transparent, splashColor: Colors.transparent, - onTap: () => changeIndex(currentIndex), + onTap: () { + if (!isDisabled!) changeIndex!(currentIndex!); + }, child: currentIndex != 4 ? Column( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, children: [ SizedBox( - height: 15, + height: 10, ), - Container( - child: Icon(currentIndex == index ? activeIcon : icon, - color: currentIndex == index - ? secondaryColor - : Colors.grey, - size: 22.0), + icon == "assets/images/new/bottom_nav/help.svg" ? Container( + child: SvgPicture.asset(icon!, height: 20, width: 20, fit: BoxFit.cover), + ) : Container( + child: SvgPicture.asset(icon!, height: 20, width: 20, fit: BoxFit.cover, color: currentIndex == index + ? Color(0xff333c45) + : Color(0xff989898)), ), SizedBox( height: 2, @@ -63,8 +63,10 @@ class BottomNavigationItem extends StatelessWidget { name, textAlign: TextAlign.center, color: currentIndex == index - ? secondaryColor - : Colors.grey, + ? Color(0xff333c45) + : isDisabled! + ? Colors.grey[300] + : Colors.grey, fontSize: 11, ), SizedBox( @@ -72,41 +74,22 @@ class BottomNavigationItem extends StatelessWidget { ), ], ) - : (authenticatedUserObject.isLogin && model.isShowBadge) + : (authenticatedUserObject.isLogin && toDoProvider.isShowBadge) ? Stack( alignment: AlignmentDirectional.center, children: [ - Positioned( - right: 18.0, - bottom: 28.0, - child: Badge( - toAnimate: false, - position: BadgePosition.topEnd(), - shape: BadgeShape.circle, - badgeColor: secondaryColor.withOpacity(1.0), - borderRadius: BorderRadius.circular(8), - badgeContent: Container( - padding: EdgeInsets.all(2.0), - child: Text(model.count.toString(), - style: TextStyle( - color: Colors.white, fontSize: 14.0)), - ), - ), - ), Column( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, children: [ SizedBox( - height: 15, + height: 11, ), Container( - child: Icon( - currentIndex == index ? activeIcon : icon, - color: currentIndex == index - ? secondaryColor - : Theme.of(context).dividerColor, - size: 22.0), + child: SvgPicture.asset(icon!, height: 20, width: 20, fit: BoxFit.cover, color: currentIndex == index + ? Color(0xff333c45) + : Color(0xff989898)), + // Icon(currentIndex == index ? activeIcon : icon, color: currentIndex == index ? secondaryColor : Theme.of(context).dividerColor, size: 22.0), ), SizedBox( height: 2, @@ -114,9 +97,7 @@ class BottomNavigationItem extends StatelessWidget { Texts( name, textAlign: TextAlign.center, - color: currentIndex == index - ? Theme.of(context).primaryColor - : Colors.grey, + color: currentIndex == index ? Color(0xff333c45) : Colors.grey, fontSize: 11, ), SizedBox( @@ -124,6 +105,27 @@ class BottomNavigationItem extends StatelessWidget { ), ], ), + Positioned( + right: 18.0, + bottom: 27.0, + child: badge_import.Badge( + badgeStyle: badge_import.BadgeStyle( + shape: badge_import.BadgeShape.circle, + badgeColor: secondaryColor!.withOpacity(1.0), + borderRadius: BorderRadius.circular(8) + ), + // toAnimate: false, + badgeAnimation: badge_import.BadgeAnimation.fade(toAnimate: false), + position: badge_import.BadgePosition.topEnd(), + // shape: badge_import.BadgeShape.circle, + // badgeColor: secondaryColor!.withOpacity(1.0), + // borderRadius: BorderRadius.circular(8), + badgeContent: Container( + padding: EdgeInsets.all(2.0), + child: Text((toDoProvider.count! + toDoProvider.ancillaryCount!).toString(), style: TextStyle(color: Colors.white, fontSize: 14.0)), + ), + ), + ), ], ) : Column( @@ -131,15 +133,10 @@ class BottomNavigationItem extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ SizedBox( - height: 15, + height: 10, ), Container( - child: Icon( - currentIndex == index ? activeIcon : icon, - color: currentIndex == index - ? secondaryColor - : Theme.of(context).dividerColor, - size: 22.0), + child: SvgPicture.asset(icon!, height: 20, width: 20, fit: BoxFit.cover), ), SizedBox( height: 2, @@ -148,8 +145,10 @@ class BottomNavigationItem extends StatelessWidget { name, textAlign: TextAlign.center, color: currentIndex == index - ? secondaryColor - : Colors.grey, + ? Color(0xff333c45) + : isDisabled! + ? Colors.grey[300] + : Colors.grey, fontSize: 11, ), SizedBox( diff --git a/lib/widgets/bottom_options/BottomSheet.dart b/lib/widgets/bottom_options/BottomSheet.dart index 7bbadd8c..135a9731 100644 --- a/lib/widgets/bottom_options/BottomSheet.dart +++ b/lib/widgets/bottom_options/BottomSheet.dart @@ -1,14 +1,22 @@ import 'dart:convert'; import 'dart:io'; +import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/services/permission/permission_service.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; -import 'package:feather_icons_flutter/feather_icons_flutter.dart'; + +// import 'package:feather_icons_flutter/feather_icons_flutter.dart'; import 'package:flutter/material.dart'; import 'package:image_picker/image_picker.dart'; class ImageOptions { - static showImageOptions(BuildContext context, Function(String,File) image,) { + static showImageOptions( + BuildContext context, + Function(String, File) image, + ) { showModalBottomSheet( backgroundColor: Colors.transparent, context: context, @@ -20,37 +28,41 @@ class ImageOptions { ), _BottomSheetItem( title: TranslationBase.of(context).gallery, - icon: FeatherIcons.image, + icon: Icons.image, onTap: () async { - File _image = - await ImagePicker.pickImage(source: ImageSource.gallery); - String fileName = _image.path; - final bytes = File(fileName).readAsBytesSync(); - String base64Encode = base64.encode(bytes); - if (base64Encode != null) { - image(base64Encode,_image); + if (Platform.isAndroid) { + galleryImageAndroid(image); + } else { + File _image = File((await ImagePicker.platform.pickImage(source: ImageSource.gallery, imageQuality: 20))!.path); + String fileName = _image.path; + final bytes = File(fileName).readAsBytesSync(); + String base64Encode = base64.encode(bytes); + if (base64Encode != null) { + image(base64Encode, _image); + } } }, ), _BottomSheetItem( title: TranslationBase.of(context).camera, - icon: FeatherIcons.camera, + icon: Icons.camera_alt, onTap: () async { - File _image = - await ImagePicker.pickImage(source: ImageSource.camera); - String fileName = _image.path; - final bytes = File(fileName).readAsBytesSync(); - String base64Encode = base64.encode(bytes); - if (base64Encode != null) { - image(base64Encode,_image); + if (Platform.isAndroid) { + cameraImageAndroid(image); + } else { + File _image = File((await ImagePicker.platform.pickImage(source: ImageSource.camera, imageQuality: 20))!.path); + String fileName = _image.path; + final bytes = File(fileName).readAsBytesSync(); + String base64Encode = base64.encode(bytes); + if (base64Encode != null) { + image(base64Encode, _image); + } } }, ), _BottomSheetItem( title: TranslationBase.of(context).cancel, - onTap: (){ - - }, + onTap: () {}, ) ], ); @@ -58,28 +70,67 @@ class ImageOptions { } } +galleryImageAndroid(Function(String, File) image) async { + if (await PermissionService.isExternalStorageEnabled()) { + File _image = File((await ImagePicker.platform.pickImage(source: ImageSource.gallery, imageQuality: 20))!.path); + String fileName = _image.path; + final bytes = File(fileName).readAsBytesSync(); + String base64Encode = base64.encode(bytes); + if (base64Encode != null) { + image(base64Encode, _image); + } + } else { + Utils.showPermissionConsentDialog(AppGlobal.context, TranslationBase.of(AppGlobal.context).galleryPermission, () async { + File _image = File((await ImagePicker.platform.pickImage(source: ImageSource.gallery, imageQuality: 20))!.path); + String fileName = _image.path; + final bytes = File(fileName).readAsBytesSync(); + String base64Encode = base64.encode(bytes); + if (base64Encode != null) { + image(base64Encode, _image); + } + }); + } +} + +cameraImageAndroid(Function(String, File) image) async { + if (await PermissionService.isCameraEnabled()) { + File _image = File((await ImagePicker.platform.pickImage(source: ImageSource.camera, imageQuality: 20))!.path); + String fileName = _image.path; + final bytes = File(fileName).readAsBytesSync(); + String base64Encode = base64.encode(bytes); + if (base64Encode != null) { + image(base64Encode, _image); + } + } else { + Utils.showPermissionConsentDialog(AppGlobal.context, TranslationBase.of(AppGlobal.context).cameraPermissionDialog, () async { + File _image = File((await ImagePicker.platform.pickImage(source: ImageSource.camera, imageQuality: 20))!.path); + String fileName = _image.path; + final bytes = File(fileName).readAsBytesSync(); + String base64Encode = base64.encode(bytes); + if (base64Encode != null) { + image(base64Encode, _image); + } + }); + } +} + class _BottomSheet extends StatelessWidget { final List children; - _BottomSheet({Key key, @required this.children}) : super(key: key); + _BottomSheet({Key? key, required this.children}) : super(key: key); @override Widget build(BuildContext context) { return Container( padding: EdgeInsets.symmetric(vertical: 12.0), - decoration: BoxDecoration( - color: Theme.of(context).backgroundColor, - borderRadius: BorderRadius.only( - topLeft: Radius.circular(16.0), topRight: Radius.circular(16.0))), + decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.only(topLeft: Radius.circular(16.0), topRight: Radius.circular(16.0))), child: SafeArea( top: false, child: Column( mainAxisSize: MainAxisSize.min, children: [ Container( - decoration: BoxDecoration( - color: Theme.of(context).dividerColor, - borderRadius: BorderRadius.circular(3.0)), + decoration: BoxDecoration(color: Theme.of(context).dividerColor, borderRadius: BorderRadius.circular(3.0)), width: 40.0, height: 6.0, ), @@ -92,18 +143,12 @@ class _BottomSheet extends StatelessWidget { } class _BottomSheetItem extends StatelessWidget { - final Function onTap; - final IconData icon; + final Function? onTap; + final IconData? icon; final String title; final ITEM_COLOR color; - _BottomSheetItem( - {Key key, - this.onTap, - @required this.title, - this.icon, - this.color = ITEM_COLOR.primary}) - : super(key: key); + _BottomSheetItem({Key? key, this.onTap, required this.title, this.icon, this.color = ITEM_COLOR.primary}) : super(key: key); @override Widget build(BuildContext context) { @@ -111,7 +156,7 @@ class _BottomSheetItem extends StatelessWidget { onTap: () { if (onTap != null) { Navigator.pop(context); - onTap(); + onTap!(); } }, child: Padding( @@ -121,18 +166,14 @@ class _BottomSheetItem extends StatelessWidget { if (icon != null) Icon( icon, - color: color == ITEM_COLOR.error - ? Theme.of(context).errorColor - : Theme.of(context).primaryColor, + color: color == ITEM_COLOR.error ? CustomColors.accentColor : Theme.of(context).primaryColor, size: 18.0, ), if (icon != null) SizedBox(width: 24.0), Texts( title ?? "", style: "bodyText2", - color: color == ITEM_COLOR.error - ? Theme.of(context).errorColor - : null, + color: color == ITEM_COLOR.error ? CustomColors.accentColor : null, ), ], ), diff --git a/lib/widgets/bottom_options/bottom_sheet.dart b/lib/widgets/bottom_options/bottom_sheet.dart new file mode 100644 index 00000000..c59c565e --- /dev/null +++ b/lib/widgets/bottom_options/bottom_sheet.dart @@ -0,0 +1,89 @@ +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:flutter/material.dart'; + +void showMyBottomSheet(BuildContext context, {required Widget child, required VoidCallback callBackFunc, String? type}) { + showModalBottomSheet( + context: context, + isScrollControlled: true, + backgroundColor: Colors.transparent, + builder: (BuildContext context) { + return Container( + constraints: BoxConstraints( + maxHeight: type =='CONTINUE_ACTION' ? MediaQuery.of(context).size.height *.75 : double.infinity,), + decoration: const BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only( + topRight: Radius.circular(25), + topLeft: Radius.circular(25), + ), + ), + padding: MediaQuery.of(context).viewInsets, + clipBehavior: Clip.antiAlias, + child:SingleChildScrollView(child: Column( + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + mHeight(13), + Container( + height: 6, + width: 60, + decoration: const BoxDecoration( + color: Color(0xff9A9A9A), + borderRadius: BorderRadius.all( + Radius.circular(20), + ), + ), + ), + mHeight(8), + child, + ], + )), + ); + }, + ).then((value) { + // print("BACK FROM DELEGATE!!!!"); + // print("value: $value"); + if (value == "delegate_reload") { + callBackFunc(); + } + }); +} + +class BottomSheetItem extends StatelessWidget { + final Function onTap; + final IconData icon; + final String title; + final Color color; + + const BottomSheetItem({Key? key, required this.onTap, required this.title, required this.icon, this.color = Colors.black}) : super(key: key); + + @override + Widget build(BuildContext context) { + return InkWell( + onTap: () { + if (onTap != null) { + Navigator.pop(context); + onTap(); + } + }, + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 18.0, vertical: 18.0), + child: Row( + children: [ + if (icon != null) + Icon( + icon, + color: color, + size: 18.0, + ), + if (icon != null) SizedBox(width: 24.0), + Text( + title ?? "", + style: TextStyle(color: color), + ), + ], + ), + ), + ); + } +} diff --git a/lib/widgets/buttons/BottomButton.dart b/lib/widgets/buttons/BottomButton.dart index 3e85aa1e..1746ee13 100644 --- a/lib/widgets/buttons/BottomButton.dart +++ b/lib/widgets/buttons/BottomButton.dart @@ -1,3 +1,4 @@ +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:flutter/material.dart'; @@ -14,27 +15,16 @@ import 'package:flutter/material.dart'; class BottomButton extends StatelessWidget { final bool loading; final bool disabled; - final String label; - final Widget icon; - final Color color; - final Color textColor; - final Color borderColor; - final Function onTap; - final Widget child; + final String? label; + final Widget? icon; + final Color? color; + final Color? textColor; + final Color? borderColor; + final Function? onTap; + final Widget? child; final bool disabledPadding; - BottomButton( - {Key key, - this.loading = false, - this.disabled = false, - this.label, - this.icon, - this.color, - this.textColor, - this.disabledPadding = false, - this.borderColor, - this.onTap, - this.child}) + BottomButton({Key? key, this.loading = false, this.disabled = false, this.label, this.icon, this.color, this.textColor, this.disabledPadding = false, this.borderColor, this.onTap, this.child}) : super(key: key); @override @@ -44,17 +34,7 @@ class BottomButton extends StatelessWidget { children: [ Container( decoration: BoxDecoration( - gradient: LinearGradient( - begin: Alignment.bottomCenter, - end: Alignment.topCenter, - stops: [ - 0.0, - 0.9 - ], - colors: [ - Theme.of(context).backgroundColor, - Theme.of(context).backgroundColor.withOpacity(0) - ]), + gradient: LinearGradient(begin: Alignment.bottomCenter, end: Alignment.topCenter, stops: [0.0, 0.9], colors: [CustomColors.white, CustomColors.white.withOpacity(0)]), ), alignment: Alignment.center, child: SafeArea( @@ -63,46 +43,19 @@ class BottomButton extends StatelessWidget { mainAxisSize: MainAxisSize.min, children: [ Container( - margin: child != null - ? EdgeInsets.only( - left: 14.0, right: 14.0, top: 14.0, bottom: 14) - : EdgeInsets.only( - left: 30.0, right: 30.0, top: 14.0, bottom: 14), + margin: child != null ? EdgeInsets.only(left: 14.0, right: 14.0, top: 14.0, bottom: 14) : EdgeInsets.only(left: 30.0, right: 30.0, top: 14.0, bottom: 14), decoration: BoxDecoration( - color: child != null - ? Theme.of(context).backgroundColor - : null, - border: child != null - ? Border.all( - color: Theme.of(context).dividerColor, width: 2.0) - : Border.all(color: Colors.transparent, width: 0.0), - borderRadius: child != null - ? BorderRadius.circular(16.0) - : BorderRadius.circular(0.0), - boxShadow: child != null - ? [ - BoxShadow( - color: Color.fromRGBO(0, 0, 0, 0.04), - spreadRadius: -0.0, - offset: Offset(0, 4.0), - blurRadius: 18.0) - ] - : []), + color: child != null ? CustomColors.white : null, + border: child != null ? Border.all(color: Theme.of(context).dividerColor, width: 2.0) : Border.all(color: Colors.transparent, width: 0.0), + borderRadius: child != null ? BorderRadius.circular(16.0) : BorderRadius.circular(0.0), + boxShadow: child != null ? [BoxShadow(color: Color.fromRGBO(0, 0, 0, 0.04), spreadRadius: -0.0, offset: Offset(0, 4.0), blurRadius: 18.0)] : []), child: Column( children: [ if (child != null) Padding( padding: disabledPadding - ? EdgeInsets.only( - left: 0.0, - right: 0.0, - top: 14.0, - bottom: label != null ? 0.0 : 14) - : EdgeInsets.only( - left: 18.0, - right: 18.0, - top: 14.0, - bottom: label != null ? 0.0 : 14), + ? EdgeInsets.only(left: 0.0, right: 0.0, top: 14.0, bottom: label != null ? 0.0 : 14) + : EdgeInsets.only(left: 18.0, right: 18.0, top: 14.0, bottom: label != null ? 0.0 : 14), child: child, ), if (child != null) @@ -114,18 +67,15 @@ class BottomButton extends StatelessWidget { label == null ? SizedBox(height: 50.0) : Padding( - padding: child != null - ? EdgeInsets.only( - bottom: 16.0, left: 16.0, right: 16.0) - : EdgeInsets.zero, + padding: child != null ? EdgeInsets.only(bottom: 16.0, left: 16.0, right: 16.0) : EdgeInsets.zero, child: SecondaryButton( borderColor: borderColor, onTap: () { - if (onTap != null) onTap(); + if (onTap != null) onTap!(); }, loading: loading, disabled: disabled, - label: label, + label: label!, icon: icon, color: color, textColor: textColor), @@ -135,8 +85,7 @@ class BottomButton extends StatelessWidget { ), if (label == null && child == null) Padding( - padding: EdgeInsets.only( - left: 30.0, right: 30.0, top: 14.0, bottom: 14), + padding: EdgeInsets.only(left: 30.0, right: 30.0, top: 14.0, bottom: 14), ), ], ), diff --git a/lib/widgets/buttons/GestureIconButton.dart b/lib/widgets/buttons/GestureIconButton.dart index 841d7ea6..5ad13362 100644 --- a/lib/widgets/buttons/GestureIconButton.dart +++ b/lib/widgets/buttons/GestureIconButton.dart @@ -3,17 +3,17 @@ import 'package:flutter/material.dart'; class GestureIconButton extends StatefulWidget { GestureIconButton( - this.label, - this.icon, { - Key key, - this.onTap, - this.backgroundColor, - }) : super(key: key); + this.label, + this.icon, { + Key? key, + this.onTap, + this.backgroundColor, + }) : super(key: key); final String label; final Widget icon; - final VoidCallback onTap; - final Color backgroundColor; + final VoidCallback? onTap; + final Color? backgroundColor; @override _GestureIconButtonState createState() => _GestureIconButtonState(); @@ -25,45 +25,48 @@ class _GestureIconButtonState extends State { @override Widget build(BuildContext context) { return GestureDetector( - onLongPressStart: (_) => - setState(() => _buttonLongPress = !_buttonLongPress), - onLongPressEnd: (_) => - setState(() => _buttonLongPress = !_buttonLongPress), - child: Wrap( - children: [ - Container( - decoration: BoxDecoration( - border: Border.all( - color: widget.backgroundColor != null - ? widget.backgroundColor - : Colors.grey[200], + onTap: (){ + setState(() { + _buttonLongPress = !_buttonLongPress; + }); + widget.onTap!(); + + }, + // onLongPressStart: (_) => + // setState(() => _buttonLongPress = !_buttonLongPress), + // onLongPressEnd: (_) => + // setState(() => _buttonLongPress = !_buttonLongPress), + child: Container( + decoration: BoxDecoration( + border: Border.all( + color: widget.backgroundColor! != null + ? widget.backgroundColor! + : Colors.grey[200]!, + ), + color: widget.backgroundColor != null + ? widget.backgroundColor + : Colors.grey.shade200, + borderRadius: BorderRadius.all(Radius.circular(8))), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Container( + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: const EdgeInsets.only(right: 8.0), + child: widget.icon, ), - color: widget.backgroundColor != null - ? widget.backgroundColor - : Colors.grey.shade200, - borderRadius: BorderRadius.all(Radius.circular(8))), - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Container( - child: Expanded( - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Padding( - padding: const EdgeInsets.only(right: 8.0), - child: widget.icon, - ), - Texts( - widget.label, - color: _buttonLongPress ? Colors.white : Colors.black, - ), - ], - ), + Texts( + widget.label, + fontWeight: FontWeight.bold, + fontSize: 13.6, + color: _buttonLongPress ? Colors.white : Colors.black, ), - ), + ], ), ), - ], + ), ), ); } diff --git a/lib/widgets/buttons/borderedButton.dart b/lib/widgets/buttons/borderedButton.dart index b0bbdaf0..85c7e78a 100644 --- a/lib/widgets/buttons/borderedButton.dart +++ b/lib/widgets/buttons/borderedButton.dart @@ -2,12 +2,12 @@ import 'package:diplomaticquarterapp/config/size_config.dart'; import 'package:flutter/material.dart'; class BorderedButton extends StatelessWidget { - final String text; - final Function handler; - final Color textColor; + final String? text; + final Function? handler; + final Color? textColor; final bool hasBorder; - final Color borderColor; - final Color backgroundColor; + final Color? borderColor; + final Color? backgroundColor; final double vPadding; final double hPadding; final double radius; @@ -16,8 +16,8 @@ class BorderedButton extends StatelessWidget { final double rPadding; final double bPadding; final double fontSize; - final Widget icon; - final FontWeight fontWeight; + final Widget? icon; + final FontWeight? fontWeight; final bool hasShadow; BorderedButton( @@ -44,7 +44,7 @@ class BorderedButton extends StatelessWidget { Widget build(BuildContext context) { return GestureDetector( onTap: () { - handler(); + handler!(); }, child: Container( decoration: BoxDecoration( @@ -52,7 +52,7 @@ class BorderedButton extends StatelessWidget { color: backgroundColor ?? Colors.white, borderRadius: BorderRadius.circular(radius), border: Border.fromBorderSide(BorderSide( - color: hasBorder ? borderColor : Colors.white, + color: hasBorder! ? borderColor! : Colors.white, width: 0.8, )), boxShadow: [ @@ -67,7 +67,7 @@ class BorderedButton extends StatelessWidget { child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - icon != null ? icon : Container(), + icon != null ? icon! : Container(), Container( padding: (hPadding > 0 || vPadding > 0) ? EdgeInsets.symmetric( @@ -75,11 +75,11 @@ class BorderedButton extends StatelessWidget { : EdgeInsets.fromLTRB( lPadding, tPadding, rPadding, bPadding), child: Text( - text, + text!, textAlign: TextAlign.center, style: TextStyle( fontSize: fontSize == 0 - ? SizeConfig.textMultiplier * 1.6 + ? SizeConfig.textMultiplier! * 1.6 : fontSize, fontWeight: fontWeight != null ? fontWeight : FontWeight.normal, diff --git a/lib/widgets/buttons/button.dart b/lib/widgets/buttons/button.dart index 331ce4b6..723a8590 100644 --- a/lib/widgets/buttons/button.dart +++ b/lib/widgets/buttons/button.dart @@ -1,8 +1,6 @@ import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/services/permission/permission_service.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:hexcolor/hexcolor.dart'; import 'package:provider/provider.dart'; /// Button widget @@ -12,22 +10,14 @@ import 'package:provider/provider.dart'; /// [loading] show the progress indicator /// [elevation] color elevation value class Button extends StatefulWidget { - Button( - {Key key, - this.label: "", - this.icon, - this.onTap, - this.backgroundColor, - this.loading: false, - this.elevation: true, this.disabled=false}) - : super(key: key); + Button({Key? key, this.label= "", this.icon, this.onTap, this.backgroundColor, this.loading= false, this.elevation= true, this.disabled = false}) : super(key: key); final String label; - final Widget icon; - final VoidCallback onTap; + final Widget? icon; + final VoidCallback? onTap; final bool loading; final bool elevation; - final Color backgroundColor; + final Color? backgroundColor; final bool disabled; @override @@ -36,23 +26,17 @@ class Button extends StatefulWidget { class _ButtonState extends State